From 05a770fa731d54c7d2c6ac3f3cbde2f8409d9154 Mon Sep 17 00:00:00 2001
From: Danny Auble <da@llnl.gov>
Date: Fri, 25 Aug 2006 22:09:29 +0000
Subject: [PATCH] search works now

---
 src/sview/block_info.c |  34 +++-------
 src/sview/common.c     |  72 +++++++++++++++++---
 src/sview/job_info.c   |  51 ++++++--------
 src/sview/node_info.c  |  11 +--
 src/sview/part_info.c  |  20 +++---
 src/sview/sview.c      | 149 +++++++++++++++++++++++++++++++++++++++--
 src/sview/sview.h      |   8 ++-
 7 files changed, 254 insertions(+), 91 deletions(-)

diff --git a/src/sview/block_info.c b/src/sview/block_info.c
index fc388fff90d..16557e38cb4 100644
--- a/src/sview/block_info.c
+++ b/src/sview/block_info.c
@@ -429,20 +429,6 @@ static void _update_info_block(List block_list,
 		return;
 	}
 
-	if(spec_info) {
-		switch(spec_info->type) {
-		case NODE_PAGE:
-			hostlist = hostlist_create((char *)spec_info->data);
-			host = hostlist_shift(hostlist);
-			hostlist_destroy(hostlist);
-			if(host == NULL) {
-				g_print("nodelist was empty");
-				return;
-			}		
-			break;
-		}
-	}
-
 	/* get the iter, or find out the list is empty goto add */
 	if (gtk_tree_model_get_iter(model, &iter, path)) {
 		/* make sure all the partitions are still here */
@@ -502,9 +488,16 @@ static void _update_info_block(List block_list,
 					continue;
 				break;
 			case NODE_PAGE:
-				if(!block_ptr->nodes || !host)
+				if(!block_ptr->nodes)
 					continue;
-				
+
+				hostlist = hostlist_create(
+					(char *)spec_info->data);
+				host = hostlist_shift(hostlist);
+				hostlist_destroy(hostlist);
+				if(!host) 
+					continue;
+
 				hostlist = hostlist_create(block_ptr->nodes);
 				found = 0;
 				while((host2 = hostlist_shift(hostlist))) { 
@@ -519,6 +512,7 @@ static void _update_info_block(List block_list,
 				if(!found)
 					continue;
 				break;
+			case BLOCK_PAGE:
 			case JOB_PAGE:
 				if(strcmp(block_ptr->bg_block_name, 
 					  (char *)spec_info->data)) 
@@ -701,12 +695,6 @@ finished:
 	return;
 }
 	
-void *_popup_thr_block(void *arg)
-{
-	popup_thr(arg);		
-	return NULL;
-}
-
 extern void refresh_block(GtkAction *action, gpointer user_data)
 {
 	popup_info_t *popup_win = (popup_info_t *)user_data;
@@ -1066,7 +1054,7 @@ extern void popup_all_block(GtkTreeModel *model, GtkTreeIter *iter, int id)
 	}
 
 	
-	if (!g_thread_create(_popup_thr_block, popup_win, FALSE, &error))
+	if (!g_thread_create((gpointer)popup_thr, popup_win, FALSE, &error))
 	{
 		g_printerr ("Failed to create part popup thread: %s\n", 
 			    error->message);
diff --git a/src/sview/common.c b/src/sview/common.c
index 33d35640577..f2ce2467090 100644
--- a/src/sview/common.c
+++ b/src/sview/common.c
@@ -40,8 +40,9 @@ static int _sort_iter_compare_func_char(GtkTreeModel *model,
 {
 	int sortcol = GPOINTER_TO_INT(userdata);
 	int ret = 0;
+	int len1 = 0, len2 = 0;
 	gchar *name1 = NULL, *name2 = NULL;
-
+	
 	gtk_tree_model_get(model, a, sortcol, &name1, -1);
 	gtk_tree_model_get(model, b, sortcol, &name2, -1);
 	
@@ -54,7 +55,29 @@ static int _sort_iter_compare_func_char(GtkTreeModel *model,
 	}
 	else
 	{
-		ret = g_utf8_collate(name1,name2);
+		/* sort like a human would 
+		   meaning snowflake2 would be greater than
+		   snowflake12 */
+		len1 = strlen(name1);
+		len2 = strlen(name2);
+		while((ret < len1) && (!g_ascii_isdigit(name1[ret]))) 
+			ret++;
+		if(ret < len1) {
+			if(!g_ascii_strncasecmp(name1, name2, ret)) {
+				if(len1 > len2)
+					ret = 1;
+				else if(len1 < len2)
+					ret = -1;
+				else {
+					ret = g_ascii_strcasecmp(name1, name2);
+				}
+			} else {
+				ret = g_ascii_strcasecmp(name1, name2);
+			}
+			
+		} else {
+			ret = g_ascii_strcasecmp(name1, name2);
+		}
 	}
 cleanup:
 	g_free(name1);
@@ -88,10 +111,10 @@ static void _add_col_to_treeview(GtkTreeView *tree_view,
 	GtkCellRenderer     *renderer;
 	renderer = gtk_cell_renderer_text_new();
 	col = gtk_tree_view_column_new();	
-	gtk_tree_view_column_pack_start (col, renderer, TRUE);
-	gtk_tree_view_column_add_attribute (col, renderer, 
-					    "text", display_data->id);
-	gtk_tree_view_column_set_title (col, display_data->name);
+	gtk_tree_view_column_pack_start(col, renderer, TRUE);
+	gtk_tree_view_column_add_attribute(col, renderer, 
+					   "text", display_data->id);
+	gtk_tree_view_column_set_title(col, display_data->name);
 	gtk_tree_view_column_set_reorderable(col, true);
 	gtk_tree_view_column_set_resizable(col, true);
 	gtk_tree_view_column_set_expand(col, true);
@@ -391,11 +414,11 @@ extern GtkTreeStore *create_treestore(GtkTreeView *tree_view,
 				break;
 			case G_TYPE_STRING:
 				gtk_tree_sortable_set_sort_func(
-				GTK_TREE_SORTABLE(treestore), 
-				i, 
-				_sort_iter_compare_func_char,
-				GINT_TO_POINTER(i), 
-				NULL); 
+					GTK_TREE_SORTABLE(treestore), 
+					i, 
+					_sort_iter_compare_func_char,
+					GINT_TO_POINTER(i), 
+					NULL); 
 				break;
 			default:
 				g_print("unknown type %d",
@@ -699,3 +722,30 @@ extern void remove_old(GtkTreeModel *model, int updated)
 	gtk_tree_path_free(path);
 }
 
+extern GtkWidget *create_pulldown_combo(display_data_t *display_data,
+					int count)
+{
+	GtkListStore *store = NULL;
+	GtkWidget *combo = NULL;
+	GtkTreeIter iter;
+	GtkCellRenderer *renderer = NULL;
+	int i=0;
+	
+	store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
+	for(i=0; i<count; i++) {
+		if(display_data[i].id == -1)
+			break;
+		gtk_list_store_append(store, &iter);
+		gtk_list_store_set(store, &iter, 0, display_data[i].id,
+				   1, display_data[i].name, -1);
+	}
+	combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+	g_object_unref(store);	
+	renderer = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
+	gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer,
+				      "text", 1);
+	
+	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+	return combo;
+}
diff --git a/src/sview/job_info.c b/src/sview/job_info.c
index 854081d7bec..141c3ecbf24 100644
--- a/src/sview/job_info.c
+++ b/src/sview/job_info.c
@@ -33,12 +33,6 @@
 #define _DEBUG 0
 DEF_TIMERS;
 
-typedef struct {
-	int jobid;
-	int stepid;
-} job_step_num_t;
-
-
 enum { 
 	SORTID_POS = POS_LOC,
 	SORTID_JOBID, 
@@ -449,22 +443,8 @@ static void _update_info_job(job_info_msg_t *job_info_ptr,
 	char *host = NULL, *host2 = NULL;
 	hostlist_t hostlist = NULL;
 	int found = 0;
-	
-	if(spec_info) {
-		switch(spec_info->type) {
-		case NODE_PAGE:
-			hostlist = hostlist_create(
-				(char *)spec_info->data);	
-			host = hostlist_shift(hostlist);
-			hostlist_destroy(hostlist);
-			if(host == NULL) {
-				g_print("nodelist was empty\n");
-				return;
-			
-			}
-			break;
-		}
-	}
+	job_step_num_t *job_step = NULL;
+
 	/* make sure all the jobs are still here */
 	if (gtk_tree_model_get_iter(model, &iter, path)) {
 		while(1) {
@@ -527,6 +507,12 @@ static void _update_info_job(job_info_msg_t *job_info_ptr,
 
 		if(spec_info) {
 			switch(spec_info->type) {
+			case JOB_PAGE:
+				job_step = (job_step_num_t *)spec_info->data;
+				if(job.job_id != job_step->jobid) {
+					continue;
+				}
+				break;	
 			case PART_PAGE:
 				if(strcmp((char *)spec_info->data,
 					  job.partition))
@@ -542,9 +528,16 @@ static void _update_info_job(job_info_msg_t *job_info_ptr,
 					continue;
 				break;
 			case NODE_PAGE:
-				if(!job.nodes || !host)
+				if(!job.nodes)
 					continue;
-				
+
+				hostlist = hostlist_create(
+					(char *)spec_info->data);	
+				host = hostlist_shift(hostlist);
+				hostlist_destroy(hostlist);
+				if(!host)
+					continue;
+
 				hostlist = hostlist_create(job.nodes);	
 				found = 0;
 				while((host2 = hostlist_shift(hostlist))) { 
@@ -562,7 +555,7 @@ static void _update_info_job(job_info_msg_t *job_info_ptr,
 			default:
 				continue;
 			}
-		}		
+		}	
 		_append_job_record(&job, step_info_ptr, GTK_TREE_STORE(model), 
 				   &iter, line);
 	found:
@@ -656,12 +649,6 @@ finished:
 	return;
 }
 
-void *_popup_thr_job(void *arg)
-{
-	popup_thr(arg);		
-	return NULL;
-}
-
 extern void refresh_job(GtkAction *action, gpointer user_data)
 {
 	popup_info_t *popup_win = (popup_info_t *)user_data;
@@ -1080,7 +1067,7 @@ extern void popup_all_job(GtkTreeModel *model, GtkTreeIter *iter, int id)
 	default:
 		g_print("jobs got %d\n", id);
 	}
-	if (!g_thread_create(_popup_thr_job, popup_win, FALSE, &error))
+	if (!g_thread_create((gpointer)popup_thr, popup_win, FALSE, &error))
 	{
 		g_printerr ("Failed to create part popup thread: %s\n", 
 			    error->message);
diff --git a/src/sview/node_info.c b/src/sview/node_info.c
index 588d37116b3..7681ddf67c3 100644
--- a/src/sview/node_info.c
+++ b/src/sview/node_info.c
@@ -41,7 +41,6 @@ enum {
 	SORTID_WEIGHT, 
 	SORTID_FEATURES, 
 	SORTID_REASON,
-	SORTID_POINTER, 
 	SORTID_UPDATED, 
 	SORTID_CNT
 };
@@ -56,7 +55,6 @@ static display_data_t display_data_node[] = {
 	{G_TYPE_INT, SORTID_WEIGHT,"Weight", FALSE, -1, refresh_node},
 	{G_TYPE_STRING, SORTID_FEATURES, "Features", FALSE, -1, refresh_node},
 	{G_TYPE_STRING, SORTID_REASON, "Reason", FALSE, -1, refresh_node},
-	{G_TYPE_POINTER, SORTID_POINTER, NULL, FALSE, -1, refresh_node},
 	{G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_node},
 	{G_TYPE_NONE, -1, NULL, FALSE, -1}
 };
@@ -79,7 +77,6 @@ static void _update_node_record(node_info_t *node_ptr,
 {
 	char tmp_cnt[7];
 
-	gtk_tree_store_set(treestore, iter, SORTID_POINTER, node_ptr, -1);
 	gtk_tree_store_set(treestore, iter, SORTID_NAME, node_ptr->name, -1);
 	gtk_tree_store_set(treestore, iter, SORTID_STATE, 
 			   node_state_string(node_ptr->node_state), -1);
@@ -253,12 +250,6 @@ finished:
 	return;
 }
 
-void *_popup_thr_node(void *arg)
-{
-	popup_thr(arg);		
-	return NULL;
-}
-
 extern void refresh_node(GtkAction *action, gpointer user_data)
 {
 	popup_info_t *popup_win = (popup_info_t *)user_data;
@@ -519,7 +510,7 @@ extern void popup_all_node(GtkTreeModel *model, GtkTreeIter *iter, int id)
 		popup_win = create_popup_info(NODE_PAGE, id, title);
 	popup_win->spec_info->data = name;
 	
-	if (!g_thread_create(_popup_thr_node, popup_win, FALSE, &error))
+	if (!g_thread_create((gpointer)popup_thr, popup_win, FALSE, &error))
 	{
 		g_printerr ("Failed to create part popup thread: %s\n", 
 			    error->message);
diff --git a/src/sview/part_info.c b/src/sview/part_info.c
index 486b45d7d52..dfdcde7e862 100644
--- a/src/sview/part_info.c
+++ b/src/sview/part_info.c
@@ -485,9 +485,16 @@ static void _update_info_part(List info_list,
 		if(spec_info) {
 			switch(spec_info->type) {
 			case NODE_PAGE:
-				if(!part_ptr->nodes || !host)
+				if(!part_ptr->nodes)
 					continue;
-				
+
+				hostlist = hostlist_create(
+					(char *)spec_info->data);
+				host = hostlist_shift(hostlist);
+				hostlist_destroy(hostlist);
+				if(!host) 
+					continue;
+			
 				hostlist = hostlist_create(part_ptr->nodes);
 				found = 0;
 				while((host2 = hostlist_shift(hostlist))) { 
@@ -502,6 +509,7 @@ static void _update_info_part(List info_list,
 				if(!found)
 					continue;
 				break;
+			case PART_PAGE:
 			case BLOCK_PAGE:
 			case JOB_PAGE:
 				if(strcmp(part_ptr->name, 
@@ -829,12 +837,6 @@ finished:
 	return;
 }
 
-void *_popup_thr_part(void *arg)
-{
-	popup_thr(arg);		
-	return NULL;
-}
-
 extern void refresh_part(GtkAction *action, gpointer user_data)
 {
 	popup_info_t *popup_win = (popup_info_t *)user_data;
@@ -1185,7 +1187,7 @@ extern void popup_all_part(GtkTreeModel *model, GtkTreeIter *iter, int id)
 	default:
 		g_print("part got %d\n", id);
 	}
-	if (!g_thread_create(_popup_thr_part, popup_win, FALSE, &error))
+	if (!g_thread_create((gpointer)popup_thr, popup_win, FALSE, &error))
 	{
 		g_printerr ("Failed to create part popup thread: %s\n", 
 			    error->message);
diff --git a/src/sview/sview.c b/src/sview/sview.c
index 4eb9ba267d0..b9f90ed372f 100644
--- a/src/sview/sview.c
+++ b/src/sview/sview.c
@@ -186,7 +186,7 @@ static void _set_admin_mode(GtkToggleAction *action)
 static void _change_refresh(GtkToggleAction *action, gpointer user_data)
 {
 	GtkWidget *table = gtk_table_new(1, 2, FALSE);
-	GtkWidget *label = gtk_label_new_with_mnemonic("Interval in Seconds ");
+	GtkWidget *label = gtk_label_new("Interval in Seconds ");
 	GtkObject *adjustment = gtk_adjustment_new(global_sleep_time,
 						   1, 10000,
 						   5, 60,
@@ -360,12 +360,129 @@ static GtkWidget *_get_menubar_menu(GtkWidget *window, GtkWidget *notebook)
 	/* Finally, return the actual menu bar created by the item factory. */
 	return gtk_ui_manager_get_widget (ui_manager, "/MainMenu");
 }
+void *_popup_thr_main(void *arg)
+{
+	popup_thr(arg);		
+	return NULL;
+}
+
+
+/* Creates a tree model containing the completions */
+void _search_entry(GtkEntry *entry, GtkComboBox *combo)
+{
+	GtkTreeModel *model = NULL;
+	GtkTreeIter iter;
+	int id;
+	char *data = xstrdup(gtk_entry_get_text(entry));
+	char title[100];
+	ListIterator itr = NULL;
+	popup_info_t *popup_win = NULL;
+	GError *error = NULL;
+	job_step_num_t *job_step = NULL;
+
+	gtk_entry_set_text(entry, "");
+
+	if(!strlen(data)) {
+		g_print("nothing given to search for.\n");
+		return;
+	}
+	if(!gtk_combo_box_get_active_iter(combo, &iter)) {
+		g_print("nothing selected\n");
+		return;
+	}
+	model = gtk_combo_box_get_model(combo);
+	if(!model) {
+		g_print("nothing selected\n");
+		return;
+	}
+	
+	gtk_tree_model_get(model, &iter, 0, &id, -1);
+	
+	switch(id) {
+	case JOB_PAGE:
+		snprintf(title, 100, "Job %s info", data);
+		break;
+	case PART_PAGE:
+		snprintf(title, 100, "Partition %s info", data);
+		break;
+	case BLOCK_PAGE:
+		snprintf(title, 100, "BG Block %s info", data);
+		break;
+	case NODE_PAGE:
+#ifdef HAVE_BG
+		snprintf(title, 100, 
+			 "Base partition(s) %s info", data);
+#else
+		snprintf(title, 100, "Node(s) %s info", data);
+#endif
+		break;
+	default:
+		g_print("unknown selection %s\n", data);
+		break;
+	}
+
+	itr = list_iterator_create(popup_list);
+	while((popup_win = list_next(itr))) {
+		if(popup_win->spec_info)
+			if(!strcmp(popup_win->spec_info->title, title)) {
+				break;
+			} 
+	}
+	list_iterator_destroy(itr);
+
+	if(!popup_win) {
+		popup_win = create_popup_info(id, id, title);
+	}
+
+	switch(id) {
+	case JOB_PAGE:
+		id = atoi(data);
+		xfree(data);
+		job_step = g_malloc(sizeof(job_step_num_t));
+		job_step->jobid = id;
+		job_step->stepid = NO_VAL;
+		popup_win->spec_info->data = job_step;
+		break;
+	case PART_PAGE:
+	case BLOCK_PAGE:
+	case NODE_PAGE:
+		popup_win->spec_info->data = data;
+		break;
+	default:
+		g_print("unknown selection %d\n", id);
+		return;
+	}
+	if (!g_thread_create((gpointer)popup_thr, popup_win, FALSE, &error))
+	{
+		g_printerr ("Failed to create main popup thread: %s\n", 
+			    error->message);
+		return;
+	}
+	return;
+}
+
 
 int main(int argc, char *argv[])
 {
-	GtkWidget *window;
-	GtkWidget *menubar;
+	GtkWidget *window = NULL;
+	GtkWidget *menubar = NULL;
+	GtkWidget *table = NULL;
+	GtkWidget *label = NULL;
+	GtkWidget *combo = NULL;
+	GtkWidget *entry = NULL;
+	
 	int i=0;
+	display_data_t pulldown_display_data[] = {
+		{G_TYPE_NONE, JOB_PAGE, "Job", TRUE, -1},
+		{G_TYPE_NONE, PART_PAGE, "Partition", TRUE, -1},
+#ifdef HAVE_BG
+		{G_TYPE_NONE, BLOCK_PAGE, "BG Block", TRUE, -1},
+		{G_TYPE_NONE, NODE_PAGE, "Base Partitions", TRUE, -1},	
+#else
+		{G_TYPE_NONE, NODE_PAGE, "Node", TRUE, -1},
+#endif
+		{G_TYPE_NONE, -1, NULL, FALSE, -1}
+	};
 	
 	_init_pages();
 	g_thread_init(NULL);
@@ -387,10 +504,32 @@ int main(int argc, char *argv[])
 	g_signal_connect(G_OBJECT(main_notebook), "switch_page",
 			 G_CALLBACK(_page_switched),
 			 NULL);
-	
+	table = gtk_table_new(1, 4, FALSE);
+	gtk_table_set_homogeneous(GTK_TABLE(table), FALSE);
+	gtk_container_set_border_width(GTK_CONTAINER(table), 1);	
 	/* Create a menu */
 	menubar = _get_menubar_menu(window, main_notebook);
+	gtk_table_attach_defaults(GTK_TABLE(table), menubar, 0, 1, 0, 1);
+
+	label = gtk_label_new("Search ");
+	gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1,
+			 GTK_SHRINK, GTK_EXPAND | GTK_FILL,
+			 0, 0);
+	
+	combo = create_pulldown_combo(pulldown_display_data, PAGE_CNT);
+	gtk_table_attach(GTK_TABLE(table), combo, 2, 3, 0, 1,
+			 GTK_SHRINK, GTK_EXPAND | GTK_FILL,
+			 0, 0);
 	
+	entry = gtk_entry_new ();
+	gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 0, 1,
+			 GTK_SHRINK, GTK_EXPAND | GTK_FILL,
+			 0, 0);
+	
+	g_signal_connect(G_OBJECT(entry), "activate",
+			 G_CALLBACK(_search_entry),
+			 combo);
+	  
 	gtk_notebook_popup_enable(GTK_NOTEBOOK(main_notebook));
 	gtk_notebook_set_scrollable(GTK_NOTEBOOK(main_notebook), TRUE);
 	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_notebook), GTK_POS_TOP);
@@ -400,7 +539,7 @@ int main(int argc, char *argv[])
 					  FALSE);
 	/* Pack it all together */
 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox),
-			   menubar, FALSE, FALSE, 0);
+			   table, FALSE, FALSE, 0);
 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), 
 			   main_notebook, TRUE, TRUE, 0);	
 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox),
diff --git a/src/sview/sview.h b/src/sview/sview.h
index 212da56898c..a8c307921b8 100644
--- a/src/sview/sview.h
+++ b/src/sview/sview.h
@@ -154,6 +154,11 @@ struct popup_info {
 	display_data_t *display_data;
 };
 
+typedef struct {
+	int jobid;
+	int stepid;
+} job_step_num_t;
+
 extern sview_parameters_t params;
 extern int text_line_cnt;
 
@@ -255,5 +260,6 @@ extern void destroy_popup_info(void *arg);
 extern gboolean delete_popup(GtkWidget *widget, GtkWidget *event, char *title);
 extern void *popup_thr(popup_info_t *popup_win);
 extern void remove_old(GtkTreeModel *model, int updated);
-
+extern GtkWidget *create_pulldown_combo(display_data_t *display_data,
+					int count);
 #endif
-- 
GitLab