diff --git a/src/sview/block_info.c b/src/sview/block_info.c index 0120407322aafbd12ff9d6ccff67f492ae4dfaab..1f7472926b071c75c0c816bbe5c68dd7a9a9535f 100644 --- a/src/sview/block_info.c +++ b/src/sview/block_info.c @@ -184,7 +184,7 @@ static void _block_list_del(void *object) xfree(block_ptr->imageramdisk); /* don't xfree(block_ptr->bp_inx); it isn't copied like the chars and is freed in the api - */ + */ xfree(block_ptr); } @@ -274,7 +274,7 @@ static void _layout_block_record(GtkTreeView *treeview, add_display_treestore_line(update, treestore, &iter, find_col_name(display_data_block, SORTID_JOB), - tmp_cnt); + tmp_cnt); if(cluster_flags & CLUSTER_FLAG_BGL) { add_display_treestore_line(update, treestore, &iter, find_col_name(display_data_block, @@ -692,9 +692,9 @@ finished: extern void refresh_block(GtkAction *action, gpointer user_data) { popup_info_t *popup_win = (popup_info_t *)user_data; - xassert(popup_win != NULL); - xassert(popup_win->spec_info != NULL); - xassert(popup_win->spec_info->title != NULL); + xassert(popup_win); + xassert(popup_win->spec_info); + xassert(popup_win->spec_info->title); popup_win->force_refresh = 1; specific_info_block(popup_win); } @@ -716,8 +716,8 @@ extern int get_new_info_block(block_info_msg_t **block_ptr, int force) error_code = SLURM_SUCCESS; *block_ptr = g_block_info_ptr; if(changed) - return SLURM_SUCCESS; - return error_code; + error_code = SLURM_SUCCESS; + goto end_it; } last = now; if (g_block_info_ptr) { @@ -732,8 +732,8 @@ extern int get_new_info_block(block_info_msg_t **block_ptr, int force) changed = 0; } } else { - error_code = slurm_load_block_info((time_t) NULL, - &new_bg_ptr); + new_bg_ptr = NULL; + error_code = slurm_load_block_info((time_t) NULL, &new_bg_ptr); changed = 1; } @@ -744,6 +744,7 @@ extern int get_new_info_block(block_info_msg_t **block_ptr, int force) *block_ptr = g_block_info_ptr; } +end_it: return error_code; } @@ -817,7 +818,7 @@ extern int update_state_block(GtkDialog *dialog, == SLURM_SUCCESS) { snprintf(tmp_char, sizeof(tmp_char), "Block %s updated successfully", - blockid); + blockid); } else { snprintf(tmp_char, sizeof(tmp_char), "Problem updating block %s.", @@ -918,14 +919,14 @@ extern void get_info_block(GtkTable *table, display_data_t *display_data) display_widget = NULL; part_info_ptr = NULL; block_ptr = NULL; - return; + goto reset_curs; } if(display_data) local_display_data = display_data; if(!table) { display_data_block->set_menu = local_display_data->set_menu; - return; + goto reset_curs; } if(display_widget && toggled) { @@ -981,12 +982,12 @@ extern void get_info_block(GtkTable *table, display_data_t *display_data) display_it: if(!part_info_ptr || !block_ptr) - return; + goto reset_curs; block_list = _create_block_list(part_info_ptr, block_ptr, changed); if(!block_list) - return; + goto reset_curs; /* set up the grid */ if(display_widget && GTK_IS_TREE_VIEW(display_widget) @@ -1013,6 +1014,16 @@ display_it: } } list_iterator_destroy(itr); + change_grid_color(grid_button_list, -1, -1, + MAKE_WHITE, true, 0); + } else + highlight_grid(GTK_TREE_VIEW(display_widget), + SORTID_NODE_INX, SORTID_COLOR_INX, + grid_button_list); + + if(working_sview_config.grid_speedup) { + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); } if(view == ERROR_VIEW && display_widget) { @@ -1033,24 +1044,15 @@ display_it: SORTID_CNT, SORTID_NODELIST, SORTID_COLOR); } - if(path) - highlight_grid(GTK_TREE_VIEW(display_widget), - SORTID_NODE_INX, SORTID_COLOR_INX, - grid_button_list); - else - change_grid_color(grid_button_list, -1, -1, - MAKE_WHITE, true, 0); - if(working_sview_config.grid_speedup) { - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); - } - view = INFO_VIEW; _update_info_block(block_list, GTK_TREE_VIEW(display_widget)); end_it: toggled = FALSE; force_refresh = FALSE; +reset_curs: + if (main_window && main_window->window) + gdk_window_set_cursor(main_window->window, NULL); return; } diff --git a/src/sview/common.c b/src/sview/common.c index 14bcb459e5dcabcae5edb830dd99c61a1192af7a..fa093bacdab8654046a921b1c871a92793284b59 100644 --- a/src/sview/common.c +++ b/src/sview/common.c @@ -29,25 +29,130 @@ #include "src/sview/sview.h" #include "src/common/parse_time.h" +#include <gdk/gdkkeysyms.h> + +#define TOPO_DEBUG 0 +#define _DEBUG 0 static bool menu_right_pressed = false; typedef struct { + display_data_t *display_data; + void (*pfunc)(GtkTreeModel*, GtkTreeIter*, int); + GtkTreeView *tree_view; +} each_t; + +typedef struct { + GtkTreeIter iter; GtkTreeModel *model; GtkTreeView *treeview; - GtkTreeIter iter; } treedata_t; -static const int KEY_UP = 111; -static const int KEY_DOWN = 116; -static const int KEY_ENTER = 36; -static const int KEY_CONTROL = 16777253; static gboolean control_key_in_effect = FALSE; +static gboolean enter_key_in_effect = FALSE; + + + +static int _find_node_inx (char *name) +{ + int i; + + if ((name == NULL) || (name[0] == '\0')) { + info("find_node_record passed NULL name"); + return -1; + } + + + for (i = 0; i < g_node_info_ptr->record_count; i++) { + if (!strcmp (name, g_node_info_ptr->node_array[i].name)) { + return i; + } + } + + return -1; +} + + +static void _display_topology(void) +{ + int i, match, match_cnt = 0; + hostset_t hs; + int one_liner = 1; + + if (TOPO_DEBUG) + g_print("_display_topology, record_count = %d\n", + g_topo_info_msg_ptr->record_count); + for (i=0; i<g_topo_info_msg_ptr->record_count; i++) { +// g_print("topo_info_msg->topo_array[i]->switches = %s" +// " nodes = %s \n", +// topo_info_msg->topo_array[i].switches, +// topo_info_msg->topo_array[i].nodes); + + if ((g_topo_info_msg_ptr->topo_array[i].nodes == NULL) || + (g_topo_info_msg_ptr->topo_array[i].nodes[0] == '\0')) + continue; +// g_print("\nfor switch = %s\n", +// topo_info_msg->topo_array[i].name); +// print_node_list(topo_info_msg->topo_array[i].nodes); + if (g_topo_info_msg_ptr->topo_array[i].level == 0) { + hs = hostset_create(g_topo_info_msg_ptr-> + topo_array[i].nodes); + if (hs == NULL) + fatal("hostset_create: memory " + "allocation failure"); +// match = hostset_within(hs, active_node); + } + + hostset_destroy(hs); + if (!match) + continue; + match_cnt++; + slurm_print_topo_record(stdout, + &g_topo_info_msg_ptr->topo_array[i], + one_liner); + if (match_cnt == 0) { + g_print("Topology information contains no switch or " + "node named %s", + g_topo_info_msg_ptr->topo_array[i].nodes); + } + } +} + + + +static void _foreach_popup_all(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer userdata) +{ + + each_t *each = userdata; + each->pfunc(model, iter, each->display_data->id); +} + +static void _foreach_full_info(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer userdata) +{ + + /*throttle this until safe to + * open up .. some mutex locking snafu + * in the cancel .. OR just drop the cancel.. + */ +// if (list_count(popup_list) < 9) { + each_t *each = userdata; + (each->display_data->set_menu)( + each->tree_view, NULL, path, FULL_CLICKED); +// } + +} + /* These next 2 functions are here to make it so we don't magically * click on something before we really want to in a menu. */ static gboolean _menu_button_pressed(GtkWidget *widget, GdkEventButton *event, - gpointer extra) + gpointer extra) { if(event->button == 3) { menu_right_pressed = true; @@ -65,9 +170,38 @@ static gboolean _menu_button_released(GtkWidget *widget, GdkEventButton *event, return false; } +static gboolean _frame_callback(GtkWindow *window, + GdkEvent *event, gpointer data) +{ + + if (event->expose.send_event == 0) { + default_sview_config.fi_popup_width = event->configure.width; + default_sview_config.fi_popup_height = event->configure.height; + working_sview_config.fi_popup_width = event->configure.width; + working_sview_config.fi_popup_height = event->configure.height; + + ListIterator itr = list_iterator_create(popup_list); + popup_info_t *popup_win = NULL; + + while((popup_win = list_next(itr))) { + gtk_window_resize(GTK_WINDOW(popup_win->popup), + working_sview_config.fi_popup_width, + working_sview_config.fi_popup_height); + } + list_iterator_destroy(itr); + } + + + return FALSE; +} + + + + static void _handle_response(GtkDialog *dialog, gint response_id, popup_info_t *popup_win) { + switch(response_id) { case GTK_RESPONSE_OK: //refresh (popup_win->display_data->refresh)(NULL, popup_win); @@ -76,6 +210,9 @@ static void _handle_response(GtkDialog *dialog, gint response_id, case GTK_RESPONSE_CLOSE: // close delete_popup(NULL, NULL, popup_win->spec_info->title); break; + case GTK_RESPONSE_CANCEL: // cancel + delete_popups(); + break; default: g_print("handle unknown response %d\n", response_id); break; @@ -96,10 +233,9 @@ static int _sort_iter_compare_func_char(GtkTreeModel *model, gtk_tree_model_get(model, a, sortcol, &name1, -1); gtk_tree_model_get(model, b, sortcol, &name2, -1); - if (name1 == NULL || name2 == NULL) { - if (name1 == NULL && name2 == NULL) - goto cleanup; /* both equal => ret = 0 */ - + if (!name1 && !name2) + goto cleanup; /* both equal => ret = 0 */ + else if (!name1 || !name2) { ret = (name1 == NULL) ? -1 : 1; } else { /* sort like a human would @@ -115,16 +251,12 @@ static int _sort_iter_compare_func_char(GtkTreeModel *model, ret = 1; else if(len1 < len2) ret = -1; - else { + else ret = g_ascii_strcasecmp(name1, name2); - } - } else { + } else ret = g_ascii_strcasecmp(name1, name2); - } - - } else { + } else ret = g_ascii_strcasecmp(name1, name2); - } } cleanup: g_free(name1); @@ -163,12 +295,11 @@ static int _sort_iter_compare_func_nodes(GtkTreeModel *model, gtk_tree_model_get(model, a, sortcol, &name1, -1); gtk_tree_model_get(model, b, sortcol, &name2, -1); - if (name1 == NULL || name2 == NULL) { - if (name1 == NULL && name2 == NULL) - goto cleanup; /* both equal => ret = 0 */ - + if (!name1 && !name2) + goto cleanup; /* both equal => ret = 0 */ + else if (!name1 || !name2) ret = (name1 == NULL) ? -1 : 1; - } else { + else { uint64_t int1=0, int2=0, tmp_int; int spot=0; /* If this is in a mixed state we need to get them all */ @@ -273,12 +404,11 @@ static int _sort_iter_compare_func_bp_list(GtkTreeModel *model, gtk_tree_model_get(model, a, sortcol, &name1, -1); gtk_tree_model_get(model, b, sortcol, &name2, -1); - if ((name1 == NULL) || (name2 == NULL)) { - if ((name1 == NULL) && (name2 == NULL)) - goto cleanup; /* both equal => ret = 0 */ - + if (!name1 && !name2) + goto cleanup; /* both equal => ret = 0 */ + else if (!name1 || !name2) ret = (name1 == NULL) ? -1 : 1; - } else { + else { /* Sort in numeric order based upon coordinates */ ret = _bp_coordinate(name1) - _bp_coordinate(name2); } @@ -299,7 +429,7 @@ static void _editing_started(GtkCellRenderer *cell, } static void _editing_canceled(GtkCellRenderer *cell, - gpointer data) + gpointer data) { g_static_mutex_unlock(&sview_mutex); } @@ -439,19 +569,21 @@ static void _popup_state_changed(GtkCheckMenuItem *menuitem, static void _selected_page(GtkMenuItem *menuitem, display_data_t *display_data) { treedata_t *treedata = (treedata_t *)display_data->user_data; - - switch(display_data->extra) { + each_t each; + memset(&each, 0, sizeof(each_t)); + each.tree_view = treedata->treeview; + each.display_data = display_data; + global_row_count = gtk_tree_selection_count_selected_rows( + gtk_tree_view_get_selection(treedata->treeview)); + switch(display_data->extra & EXTRA_BASE) { case PART_PAGE: - popup_all_part(treedata->model, &treedata->iter, - display_data->id); + each.pfunc = &popup_all_part; break; case JOB_PAGE: - popup_all_job(treedata->model, &treedata->iter, - display_data->id); + each.pfunc = &popup_all_job; break; case NODE_PAGE: - popup_all_node(treedata->model, &treedata->iter, - display_data->id); + each.pfunc = &popup_all_node; break; case BLOCK_PAGE: popup_all_block(treedata->model, &treedata->iter, @@ -468,8 +600,10 @@ static void _selected_page(GtkMenuItem *menuitem, display_data_t *display_data) display_data->name,treedata->treeview); break; case PART_PAGE: - admin_part(treedata->model, &treedata->iter, - display_data->name); + select_admin_partitions(treedata->model, + &treedata->iter, + display_data, + treedata->treeview); break; case BLOCK_PAGE: admin_block(treedata->model, &treedata->iter, @@ -480,8 +614,9 @@ static void _selected_page(GtkMenuItem *menuitem, display_data_t *display_data) display_data->name); break; case NODE_PAGE: - admin_node(treedata->model, &treedata->iter, - display_data->name); + select_admin_nodes(treedata->model, &treedata->iter, + display_data, NO_VAL, + treedata->treeview); break; default: g_print("common admin got %d %d\n", @@ -493,9 +628,131 @@ static void _selected_page(GtkMenuItem *menuitem, display_data_t *display_data) g_print("common got %d %d\n", display_data->extra, display_data->id); } + if(each.pfunc) + gtk_tree_selection_selected_foreach( + gtk_tree_view_get_selection(treedata->treeview), + _foreach_popup_all, &each); xfree(treedata); } +extern void slurm_free_switch_nodes_maps(switch_record_bitmaps_t + * g_switch_nodes_maps) +{ + + if(g_switch_nodes_maps) { + xfree(g_switch_nodes_maps->node_bitmap); + xfree(g_switch_nodes_maps->nodes); + xfree(g_switch_nodes_maps); + } + +} + +extern int build_nodes_bitmap(char *node_names, bitstr_t **bitmap) + +{ + char *this_node_name; + bitstr_t *my_bitmap; + hostlist_t host_list; + int node_inx = -1; + + if (TOPO_DEBUG) + g_print("..............._node_names2bitmap............%s\n", + node_names); + my_bitmap = (bitstr_t *) bit_alloc(g_node_info_ptr->record_count); + if (my_bitmap == NULL) { + fatal("bit_alloc malloc failure"); + } + *bitmap = my_bitmap; + + if (node_names == NULL) { + error("_node_name2bitmap: node_names is NULL"); + return EINVAL; + } + + if ( (host_list = hostlist_create(node_names)) == NULL) { + error("_node_name2bitmap: hostlist_create(%s) error", + node_names); + return EINVAL; + } + + /*spin hostlist and map nodes into a bitmap*/ + while ( (this_node_name = hostlist_shift(host_list)) ) { + node_inx = _find_node_inx(this_node_name); //topo + if (node_inx != -1) { + bit_set(my_bitmap, + (bitoff_t) (node_inx)); + } else { + continue; + } + free (this_node_name); + } + hostlist_destroy(host_list); + + return SLURM_SUCCESS; +} + + +extern int get_topo_conf(void) +{ + int i; + switch_record_bitmaps_t sw_nodes_bitmaps; + switch_record_bitmaps_t *sw_nodes_bitmaps_ptr; + if (TOPO_DEBUG) + g_print("get_topo_conf\n"); + + + if ((g_topo_info_msg_ptr == NULL) && + slurm_load_topo(&g_topo_info_msg_ptr)) { + slurm_perror ("slurm_load_topo error"); + if (TOPO_DEBUG) + g_print("get_topo_conf error !!\n"); + return SLURM_ERROR; + } + + if (g_switch_nodes_maps) + slurm_free_switch_nodes_maps(g_switch_nodes_maps); + + g_switch_nodes_maps = xmalloc(sizeof + (sw_nodes_bitmaps) + * g_topo_info_msg_ptr->record_count); + sw_nodes_bitmaps_ptr = g_switch_nodes_maps; + + if (TOPO_DEBUG) + g_print("_display_topology, record_count = %d\n", + g_topo_info_msg_ptr->record_count); + for (i=0; i<g_topo_info_msg_ptr->record_count; + i++, sw_nodes_bitmaps_ptr++) { + if (g_topo_info_msg_ptr->topo_array[i].nodes) { + if (TOPO_DEBUG) + g_print("ptr->nodes = %s \n", + g_topo_info_msg_ptr-> + topo_array[i].nodes); + if (build_nodes_bitmap( + g_topo_info_msg_ptr->topo_array[i].nodes, + &sw_nodes_bitmaps_ptr->node_bitmap)) { + fatal("Invalid node name (%s) in switch " + "config (%s)", + g_topo_info_msg_ptr->topo_array[i].nodes, + g_topo_info_msg_ptr->topo_array[i].name); + if (TOPO_DEBUG) + g_print("Invalid node name (%s) " + "in switch %s \n", + g_topo_info_msg_ptr-> + topo_array[i].nodes, + g_topo_info_msg_ptr-> + topo_array[i].name); + } + } + } + + if (TOPO_DEBUG) + _display_topology(); + + return SLURM_SUCCESS; +} + + + extern int get_row_number(GtkTreeView *tree_view, GtkTreePath *path) { GtkTreeModel *model = gtk_tree_view_get_model(tree_view); @@ -621,7 +878,7 @@ extern void make_options_menu(GtkTreeView *tree_view, GtkTreePath *path, treedata_t *treedata = xmalloc(sizeof(treedata_t)); treedata->model = gtk_tree_view_get_model(tree_view); treedata->treeview = tree_view; - gint row_count=0; + g_signal_connect(G_OBJECT(menu), "button-press-event", G_CALLBACK(_menu_button_pressed), NULL); @@ -635,7 +892,7 @@ extern void make_options_menu(GtkTreeView *tree_view, GtkTreePath *path, } /* check selection list */ - row_count=gtk_tree_selection_count_selected_rows( + global_row_count = gtk_tree_selection_count_selected_rows( gtk_tree_view_get_selection(tree_view)); if(display_data->user_data) @@ -652,26 +909,28 @@ extern void make_options_menu(GtkTreeView *tree_view, GtkTreePath *path, menuitem = gtk_menu_item_new_with_label(display_data->name); /* do not show FULL Info,etc. as an option for multiple * selections */ - if (global_multi_count > 0 || row_count > 1) { - /*determine how much of the popup items to include*/ - if (!strcmp(display_data->name,"Full Info") - || !strcmp(display_data->name,"Edit Job") - || !strcmp(display_data->name,"Nodes") - || !strcmp(display_data->name,"Partition") - || !strcmp(display_data->name,"Reservation")) { - } else { - g_signal_connect(menuitem, "activate", - G_CALLBACK(_selected_page), - display_data); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), - menuitem); - } - } else { - g_signal_connect(menuitem, "activate", - G_CALLBACK(_selected_page), - display_data); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - } +// if (global_row_count > 1) { +// /*determine how much of the popup items to include*/ +// /*(this could made be tab specific via a new +// * display field if necessary)*/ +// if (!strcmp(display_data->name,"Full Info") +// || !strcmp(display_data->name,"Edit Job") +// || !strcmp(display_data->name,"Nodes") +// || !strcmp(display_data->name,"Partition") +// || !strcmp(display_data->name,"Reservation")) { +// } else { +// g_signal_connect(menuitem, "activate", +// G_CALLBACK(_selected_page), +// display_data); +// gtk_menu_shell_append(GTK_MENU_SHELL(menu), +// menuitem); +// } +// } else { + g_signal_connect(menuitem, "activate", + G_CALLBACK(_selected_page), + display_data); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); +// } } } @@ -776,7 +1035,9 @@ extern GtkTreeView *create_treeview(display_data_t *local, List *button_list) g_signal_connect(G_OBJECT(tree_view), "key_release_event", G_CALLBACK(key_released), signal_params); - + g_signal_connect(G_OBJECT(tree_view), "key_press_event", + G_CALLBACK(key_pressed), + signal_params); g_signal_connect(G_OBJECT(tree_view), "row-activated", G_CALLBACK(row_activated), signal_params); @@ -932,10 +1193,14 @@ extern gboolean right_button_pressed(GtkTreeView *tree_view, display_data_t *display_data = signal_params->display_data; if(type == ROW_CLICKED) { + if (_DEBUG) + g_print("right_button_pressed:global_row_count : %d\n", + global_row_count); + /* These next 2 functions are there to keep the keyboard in sync */ if(!(event->state & GDK_CONTROL_MASK) - && (global_multi_count > 0)) + && (!(global_row_count > 0))) gtk_tree_view_set_cursor(tree_view, path, NULL, false); gtk_widget_grab_focus(GTK_WIDGET(tree_view)); @@ -948,7 +1213,7 @@ extern gboolean right_button_pressed(GtkTreeView *tree_view, (display_data->set_menu)(tree_view, menu, path, type); gtk_widget_show_all(GTK_WIDGET(menu)); gtk_menu_popup(menu, NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, + event ? event->button : 0, gdk_event_get_time((GdkEvent*)event)); return true; } @@ -973,7 +1238,6 @@ extern gboolean left_button_pressed(GtkTreeView *tree_view, gtk_widget_grab_focus(GTK_WIDGET(tree_view)); /*give keyboard focus*/ - /* highlight the nodes from this row */ (display_data->set_menu)(tree_view, *signal_params->button_list, path, ROW_LEFT_CLICKED); @@ -1006,49 +1270,67 @@ extern gboolean row_activated(GtkTreeView *tree_view, GtkTreePath *path, (display_data->set_menu)(tree_view, *signal_params->button_list, path, ROW_LEFT_CLICKED); /* display the full info */ - (display_data->set_menu)(tree_view, NULL, path, FULL_CLICKED); + if(!enter_key_in_effect) + (display_data->set_menu)(tree_view, NULL, path, FULL_CLICKED); + enter_key_in_effect = FALSE; return false; } -extern gboolean key_pressed(GtkTreeView *tree_view, GdkEventButton *event, +extern gboolean key_pressed(GtkTreeView *tree_view, + GdkEventKey *event, const signal_params_t *signal_params) { - if((event->state == KEY_CONTROL)) + GtkTreePath *path = NULL; + GtkTreeViewColumn *column; + GtkTreeSelection *selection = NULL; + + control_key_in_effect = FALSE; + enter_key_in_effect = FALSE; + + if((event->keyval == GDK_Control_L) || + (event->keyval == GDK_Control_R)) control_key_in_effect = TRUE; + else if (event->keyval == GDK_Return) { + gtk_tree_view_get_cursor(GTK_TREE_VIEW(tree_view), + &path, &column); + selection = gtk_tree_view_get_selection(tree_view); + each_t each; + memset(&each, 0, sizeof(each_t)); + each.tree_view = tree_view; + each.display_data = signal_params->display_data; + global_row_count = gtk_tree_selection_count_selected_rows( + gtk_tree_view_get_selection(tree_view)); + + gtk_tree_selection_selected_foreach( + gtk_tree_view_get_selection(tree_view), + _foreach_full_info, &each); + /*prevent row_activation from + * performing a redundant 'full info'*/ + enter_key_in_effect = TRUE; + + } return FALSE; }/*key_pressed ^^^*/ -extern gboolean key_released(GtkTreeView *tree_view, GdkEventButton *event, +extern gboolean key_released(GtkTreeView *tree_view, + GdkEventKey *event, const signal_params_t *signal_params) { GtkTreePath *path = NULL; GtkTreeViewColumn *column; GtkTreeSelection *selection = NULL; - /*GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model(tree_view);*/ - - - int row_count = 0; - /*go use row-click logic and monitor state there*/ - if (!(event->state == KEY_UP) && !(event->state == KEY_DOWN)) { - return FALSE; - } + if ((event->keyval != GDK_Up) && + (event->keyval != GDK_Down) && + (event->keyval != GDK_Return)) + return TRUE; - /*set path based on current cursor*/ gtk_tree_view_get_cursor(GTK_TREE_VIEW(tree_view), &path, &column); - /*gtk_tree_model_get_iter(model, &iter, path);*/ - /*pull the current selection object*/ selection = gtk_tree_view_get_selection(tree_view); - /*path = gtk_tree_path_new_from_indices(5,-1); - gtk_tree_path_next (path); */ - - row_count=gtk_tree_selection_count_selected_rows( - gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view))); gtk_tree_selection_select_path(selection, path); gtk_tree_path_free(path); return TRUE; @@ -1065,6 +1347,7 @@ extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event, GtkTreePath *last_path = NULL; GtkTreeSelection *selection = NULL; gboolean did_something = FALSE; + gboolean selected_in_current_mix = FALSE; if(!gtk_tree_view_get_path_at_pos(tree_view, (gint) event->x, @@ -1078,11 +1361,8 @@ extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event, * selection before OR we are stacking selections via * the ctrl key do nothing here. */ if(gtk_tree_selection_count_selected_rows(selection)){ - if(!(event->state & GDK_CONTROL_MASK)) { + if(!(event->state & GDK_CONTROL_MASK)) gtk_tree_selection_unselect_all(selection); - //reset selections counter. - global_multi_count = 0; - } refresh_main(NULL, NULL); return TRUE; } @@ -1091,42 +1371,39 @@ extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event, /* make the selection (highlight) here */ selection = gtk_tree_view_get_selection(tree_view); - - /*if shift is down then pull a range out*/ - if((event->state & GDK_SHIFT_MASK)) { - if (last_event_x != 0) { - if(gtk_tree_view_get_path_at_pos(tree_view, - (gint) last_event_x, - (gint) last_event_y, - &last_path, NULL, - NULL, NULL)) { - if (last_path != NULL) { - gtk_tree_selection_select_range( - selection, last_path, path); - gtk_tree_path_free(last_path); + global_row_count = + gtk_tree_selection_count_selected_rows(selection); + + /*flag this for rightclick to unselect on*/ + selected_in_current_mix = + gtk_tree_selection_path_is_selected(selection, + path); + + if(event->button != 3) { + /*if Lshift is down then pull a range out*/ + if((event->state & GDK_SHIFT_MASK)) { + if (last_event_x != 0) { + if(gtk_tree_view_get_path_at_pos( + tree_view, + (gint) last_event_x, + (gint) last_event_y, + &last_path, NULL, NULL, NULL)) { + if (last_path) { + gtk_tree_selection_select_range( + selection, last_path, + path); + gtk_tree_path_free(last_path); + } } + } else { + /*ignore shift and pull single row anyway*/ + gtk_tree_selection_select_path(selection, + path); } - } else { - /*ignore shift and pull single row anyway*/ - gtk_tree_selection_select_path(selection, path); - } - } /*shift down^^*/ - else { - /* Only select path if control key is not held in order to - * establish anchor*/ - if(!(event->state & GDK_CONTROL_MASK)) - gtk_tree_selection_select_path(selection, path); - else { - if (!gtk_tree_selection_count_selected_rows( - gtk_tree_view_get_selection( - GTK_TREE_VIEW(tree_view)))) { - gtk_tree_selection_select_path(selection, path); - } - } - } /*ctrl down ^^^*/ + } /*shift down^^*/ + } last_event_x = event->x; /*save THIS x*/ last_event_y = event->y; /*save THIS y*/ - global_multi_count++; if(event->x <= 20) { /* When you try to resize a column this event happens @@ -1142,17 +1419,27 @@ extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event, && !(event->state & GDK_SHIFT_MASK)) { /* unselect current on naked left clicks..*/ gtk_tree_selection_unselect_all(selection); - global_multi_count = 0; //reset selections counter. } did_something = left_button_pressed( tree_view, path, signal_params, event); } else if(event->button == 3) { /* right click */ - if(!(event->state & GDK_CONTROL_MASK)) - global_multi_count = 0; //reset selections counter. - - right_button_pressed(tree_view, path, event, - signal_params, ROW_CLICKED); + if(!selected_in_current_mix) { + if(!(event->state & GDK_CONTROL_MASK)){ + gtk_tree_selection_unselect_all(selection); + } + gtk_tree_selection_select_path(selection, path); + } + global_row_count = + gtk_tree_selection_count_selected_rows(selection); + if (_DEBUG) + g_print("row_clicked:global_row_count2 : %d \n", + global_row_count); + /*prevent rc processing if under contol/shift*/ + if(!(event->state & GDK_CONTROL_MASK) + && !(event->state & GDK_SHIFT_MASK)) + right_button_pressed(tree_view, path, event, + signal_params, ROW_CLICKED); did_something = TRUE; } else if(!working_sview_config.admin_mode) did_something = TRUE; @@ -1173,9 +1460,9 @@ extern popup_info_t *create_popup_info(int type, int dest_type, char *title) GtkScrolledWindow *window = NULL; GtkBin *bin = NULL; GtkViewport *view = NULL; - GtkWidget *popup = NULL; GtkWidget *label = NULL; GtkWidget *table = NULL; + GtkWidget *close_btn = NULL; popup_info_t *popup_win = xmalloc(sizeof(popup_info_t)); list_push(popup_list, popup_win); @@ -1196,9 +1483,13 @@ extern popup_info_t *create_popup_info(int type, int dest_type, char *title) GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_REFRESH, GTK_RESPONSE_OK, - GTK_STOCK_CLOSE, - GTK_RESPONSE_CLOSE, NULL); + close_btn = gtk_dialog_add_button(GTK_DIALOG(popup_win->popup), + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); + gtk_window_set_focus(GTK_WINDOW(popup_win->popup), close_btn); + gtk_dialog_add_button(GTK_DIALOG(popup_win->popup), + "Close All Popups", GTK_RESPONSE_CANCEL); + popup_win->show_grid = 1; popup_win->toggled = 0; @@ -1206,9 +1497,9 @@ extern popup_info_t *create_popup_info(int type, int dest_type, char *title) popup_win->type = dest_type; popup_win->not_found = false; gtk_window_set_default_size(GTK_WINDOW(popup_win->popup), - 600, 400); + working_sview_config.fi_popup_width, + working_sview_config.fi_popup_height); gtk_window_set_transient_for(GTK_WINDOW(popup_win->popup), NULL); - popup = popup_win->popup; popup_win->event_box = gtk_event_box_new(); label = gtk_label_new(popup_win->spec_info->title); @@ -1223,7 +1514,7 @@ extern popup_info_t *create_popup_info(int type, int dest_type, char *title) GTK_EVENT_BOX(popup_win->event_box), FALSE); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox), + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup_win->popup)->vbox), popup_win->event_box, FALSE, FALSE, 0); window = create_scrolled_window(); @@ -1251,7 +1542,7 @@ extern popup_info_t *create_popup_info(int type, int dest_type, char *title) gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(window), 1, 2, 0, 1); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox), + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup_win->popup)->vbox), table, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(popup_win->popup), "delete_event", @@ -1260,7 +1551,9 @@ extern popup_info_t *create_popup_info(int type, int dest_type, char *title) g_signal_connect(G_OBJECT(popup_win->popup), "response", G_CALLBACK(_handle_response), popup_win); - + g_signal_connect(G_OBJECT(popup_win->popup), "configure-event", + G_CALLBACK(_frame_callback), + popup_win); gtk_widget_show_all(popup_win->popup); return popup_win; } @@ -1291,7 +1584,7 @@ extern void redo_popup(GtkWidget *widget, GdkEventButton *event, gtk_widget_show_all(GTK_WIDGET(menu)); gtk_menu_popup(menu, NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, + event ? event->button : 0, gdk_event_get_time((GdkEvent*)event)); } } @@ -1330,9 +1623,7 @@ extern void destroy_popup_info(void *arg) if(popup_win) { *popup_win->running = 0; - //g_print("locking destroy_popup_info\n"); g_static_mutex_lock(&sview_mutex); - //g_print("locked\n"); /* these are all childern of each other so must be freed in this order */ if(popup_win->grid_button_list) { @@ -1394,10 +1685,27 @@ extern gboolean delete_popup(GtkWidget *widget, GtkWidget *event, char *title) return FALSE; } +extern gboolean delete_popups() +{ + ListIterator itr = list_iterator_create(popup_list); + popup_info_t *popup_win = NULL; + + while((popup_win = list_next(itr))) { + list_remove(itr); + destroy_popup_info(popup_win); + } + list_iterator_destroy(itr); + + return FALSE; +} + extern void *popup_thr(popup_info_t *popup_win) { void (*specifc_info) (popup_info_t *popup_win) = NULL; int running = 1; + if (_DEBUG) + g_print("popup_thr:global_row_count = %d \n", + global_row_count); switch(popup_win->type) { case PART_PAGE: specifc_info = specific_info_part; @@ -1423,7 +1731,6 @@ extern void *popup_thr(popup_info_t *popup_win) popup_win->running = &running; /* when popup is killed toggled will be set to -1 */ while(running) { - //g_print("locking popup_thr\n"); g_static_mutex_lock(&sview_mutex); //g_print("locked popup_thr\n"); gdk_threads_enter(); @@ -1764,9 +2071,6 @@ found: extern void sview_widget_modify_bg(GtkWidget *widget, GtkStateType state, const GdkColor color) { -/* DEF_TIMERS; */ - -/* START_TIMER; */ if(working_sview_config.grid_speedup) { /* For some reason, QT Themes have a very slow call to for * gtk_widget_modify_bg as of 7-6-09. @@ -1785,39 +2089,6 @@ extern void sview_widget_modify_bg(GtkWidget *widget, GtkStateType state, gtk_widget_reset_rc_styles (widget); } else gtk_widget_modify_bg(widget, state, &color); - -/* END_TIMER; */ -/* g_print("got %s\n", TIME_STR); */ - -/* START_TIMER; */ -/* GtkRcStyle *rc_style = gtk_widget_get_modifier_style (grid_button->button); */ -/* END_TIMER; */ -/* g_print("%d 1 took %s\n", grid_button->inx, TIME_STR); */ - -/* grid_button->button-> */ -/* style->bg[GTK_STATE_NORMAL] = color; */ -/* /\* grid_button->button-> *\/ */ -/* /\* style->style->flags[GTK_STATE_NORMAL] = color; *\/ */ -/* START_TIMER; */ -/* rc_style->bg[GTK_STATE_NORMAL] = color; */ -/* rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_BG; */ -/* /\* g_object_set_qdata (G_OBJECT(grid_button->button), *\/ */ -/* /\* quark_rc_style, *\/ */ -/* /\* rc_style); *\/ */ -/* END_TIMER; */ -/* g_print("%d 2 took %s\n", grid_button->inx, TIME_STR); */ -/* START_TIMER; */ -/* gtk_widget_reset_rc_styles (grid_button->button); */ -/* /\* gtk_widget_set_sensitive(grid_button->button, 0); *\/ */ -/* /\* gtk_widget_set_sensitive(grid_button->button, 1); *\/ */ - -/* /\* gtk_widget_hide_all(grid_button->button); *\/ */ -/* /\* gtk_widget_show_all(grid_button->button); *\/ */ -/* /\* gtk_widget_modify_bg(grid_button->button, *\/ */ -/* /\* GTK_STATE_NORMAL, &color); *\/ */ -/* END_TIMER; */ -/* g_print("%d 3 took %s\n", grid_button->inx, TIME_STR); */ - } extern void sview_radio_action_set_current_value(GtkRadioAction *action, diff --git a/src/sview/config_info.c b/src/sview/config_info.c index 57c92ffce6371f730afd738ee80955402025bd69..ca8d0226cd564bf0d0a80356241bb8d4fa1ce64e 100644 --- a/src/sview/config_info.c +++ b/src/sview/config_info.c @@ -53,14 +53,17 @@ extern int get_new_info_config(slurm_ctl_conf_info_msg_t **info_ptr) error_code = SLURM_NO_CHANGE_IN_DATA; new_ctl_ptr = g_ctl_info_ptr; } - } else + } else { + new_ctl_ptr = NULL; error_code = slurm_load_ctl_conf((time_t) NULL, &new_ctl_ptr); + } g_ctl_info_ptr = new_ctl_ptr; if(g_ctl_info_ptr && (*info_ptr != g_ctl_info_ptr)) error_code = SLURM_SUCCESS; *info_ptr = new_ctl_ptr; + return error_code; } diff --git a/src/sview/defaults.c b/src/sview/defaults.c index 352c494e14521a18a1616c5d3fc091770a289fbd..b0d8bf7792d0857bc320a975ab13b52ab32c4c5d 100644 --- a/src/sview/defaults.c +++ b/src/sview/defaults.c @@ -420,7 +420,7 @@ static void _local_display_admin_edit(GtkTable *table, default: break; } - return; + return; } else /* others can't be altered by the user */ return; label = gtk_label_new(display_data->name); @@ -466,6 +466,7 @@ static void _init_sview_conf() default_sview_config.show_hidden = 0; default_sview_config.admin_mode = FALSE; default_sview_config.grid_speedup = 0; + default_sview_config.grid_topological = FALSE; default_sview_config.ruled_treeview = FALSE; default_sview_config.show_grid = TRUE; default_sview_config.default_page = JOB_PAGE; @@ -489,6 +490,7 @@ extern int load_defaults() {"DefaultPage", S_P_STRING}, {"GridHorizontal", S_P_UINT32}, {"GridSpeedUp", S_P_BOOLEAN}, + {"GridTopo", S_P_BOOLEAN}, {"GridVertical", S_P_UINT32}, {"GridXWidth", S_P_UINT32}, {"RefreshDelay", S_P_UINT16}, @@ -497,6 +499,11 @@ extern int load_defaults() {"ShowHidden", S_P_BOOLEAN}, {"TabPosition", S_P_STRING}, {"VisiblePages", S_P_STRING}, + {"MainWidth", S_P_UINT32}, + {"MainHeight", S_P_UINT32}, + {"FullInfoPopupWidth", S_P_UINT32}, + {"FullInfoPopupHeight", S_P_UINT32}, + {"ExcludedPartitions", S_P_STRING}, {NULL} }; char *pathname = NULL; @@ -526,7 +533,7 @@ extern int load_defaults() hashtbl = s_p_hashtbl_create(sview_conf_options); if(s_p_parse_file(hashtbl, &hash_val, pathname) == SLURM_ERROR) - fatal("something wrong with opening/reading conf file"); + error("something wrong with opening/reading conf file"); s_p_get_boolean(&default_sview_config.admin_mode, "AdminMode", hashtbl); if (s_p_get_string(&tmp_str, "DefaultPage", hashtbl)) { @@ -546,6 +553,10 @@ extern int load_defaults() "GridHorizontal", hashtbl); s_p_get_boolean(&default_sview_config.grid_speedup, "GridSpeedup", hashtbl); + s_p_get_boolean(&default_sview_config.grid_topological, + "GridTopo", hashtbl); + if (default_sview_config.grid_topological == 0) + default_sview_config.grid_topological = FALSE; s_p_get_uint32(&default_sview_config.grid_vert, "GridVertical", hashtbl); s_p_get_uint32(&default_sview_config.grid_x_width, @@ -558,6 +569,22 @@ extern int load_defaults() "ShowGrid", hashtbl); s_p_get_boolean(&default_sview_config.show_hidden, "ShowHidden", hashtbl); + s_p_get_uint32(&default_sview_config.main_width, + "MainWidth", hashtbl); + s_p_get_uint32(&default_sview_config.main_height, + "MainHeight", hashtbl); + s_p_get_uint32(&default_sview_config.fi_popup_width, + "FullInfoPopupWidth", hashtbl); + s_p_get_uint32(&default_sview_config.fi_popup_height, + "FullInfoPopupHeight", hashtbl); + s_p_get_string(&excluded_partitions, + "ExcludedPartitions", hashtbl); + if (default_sview_config.main_width == 0) { + default_sview_config.main_width=1000; + default_sview_config.main_height=450; + default_sview_config.fi_popup_width=600; + default_sview_config.fi_popup_height=400; + } if (s_p_get_string(&tmp_str, "TabPosition", hashtbl)) { if (slurm_strcasestr(tmp_str, "top")) default_sview_config.tab_pos = GTK_POS_TOP; @@ -586,6 +613,10 @@ extern int load_defaults() default_sview_config.page_visible[NODE_PAGE] = 1; xfree(tmp_str); } + if (!s_p_get_string(&excluded_partitions, "ExcludedPartitions", + hashtbl)) + excluded_partitions = xstrdup("-"); + s_p_hashtbl_destroy(hashtbl); end_it: @@ -649,6 +680,13 @@ extern int save_defaults() "YES" : "NO"); rc = _write_to_file(fd, tmp_str); xfree(tmp_str); + if(rc != SLURM_SUCCESS) + goto end_it; + tmp_str = xstrdup_printf("GridTopo=%s\n", + default_sview_config.grid_topological ? + "YES" : "NO"); + rc = _write_to_file(fd, tmp_str); + xfree(tmp_str); if(rc != SLURM_SUCCESS) goto end_it; tmp_str = xstrdup_printf("GridVertical=%u\n", @@ -667,6 +705,36 @@ extern int save_defaults() default_sview_config.refresh_delay); rc = _write_to_file(fd, tmp_str); xfree(tmp_str); + if(rc != SLURM_SUCCESS) + goto end_it; + tmp_str = xstrdup_printf("MainWidth=%u\n", + default_sview_config.main_width); + rc = _write_to_file(fd, tmp_str); + xfree(tmp_str); + if(rc != SLURM_SUCCESS) + goto end_it; + tmp_str = xstrdup_printf("MainHeight=%u\n", + default_sview_config.main_height); + rc = _write_to_file(fd, tmp_str); + xfree(tmp_str); + if(rc != SLURM_SUCCESS) + goto end_it; + tmp_str = xstrdup_printf("FullInfoPopupWidth=%u\n", + default_sview_config.fi_popup_width); + rc = _write_to_file(fd, tmp_str); + xfree(tmp_str); + if(rc != SLURM_SUCCESS) + goto end_it; + tmp_str = xstrdup_printf("FullInfoPopupHeight=%u\n", + default_sview_config.fi_popup_height); + rc = _write_to_file(fd, tmp_str); + xfree(tmp_str); + if(rc != SLURM_SUCCESS) + goto end_it; + tmp_str = xstrdup_printf("ExcludedPartitions=%s\n", + excluded_partitions); + rc = _write_to_file(fd, tmp_str); + xfree(tmp_str); if(rc != SLURM_SUCCESS) goto end_it; tmp_str = xstrdup_printf("RuledTables=%s\n", diff --git a/src/sview/grid.c b/src/sview/grid.c index 37722f8ede2bc64be693db3b80c872c3b8800cde..54b02711ec66659470ff3e6f6c5c436f03e09632 100644 --- a/src/sview/grid.c +++ b/src/sview/grid.c @@ -38,7 +38,7 @@ \*****************************************************************************/ #include "sview.h" #include "src/plugins/select/bluegene/plugin/bluegene.h" - +#define TOPO_DEBUG 0 List grid_button_list = NULL; List blinking_button_list = NULL; List multi_button_list = NULL; @@ -313,7 +313,6 @@ static bool _change_button_color(grid_button_t *grid_button, bool changed = 0; xassert(grid_button); - if(only_change_unused && grid_button->used) return 0; @@ -360,10 +359,11 @@ static bool _change_button_color(grid_button_t *grid_button, return changed; } -static void selected_foreach_func(GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer userdata) + +static void _each_highlightd(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer userdata) { ListIterator itr = NULL; grid_button_t *grid_button = NULL; @@ -397,25 +397,28 @@ static void selected_foreach_func(GtkTreeModel *model, /*For multiple selections, need to retain all selected. *(previously this assumed only one selected). */ +// -how to add base of displayed button ? +// -need to get initial start indx (e.g. 100) from its partition +// get_nodes_partitioned_base.? +// OR +// just highlite always by active partition.. if((node_inx[j] < 0) || (grid_button->inx < node_inx[j]) - || (grid_button->inx > node_inx[j+1])) { + || (grid_button->inx > node_inx[j+1])) continue; - } if(_change_button_color(grid_button, color_inx, sview_colors[color_inx], - color, 0, 0)) { + color, 0, 0)) changed = 1; - } - if(GTK_WIDGET_STATE(grid_button->button) != GTK_STATE_NORMAL) { + + if(GTK_WIDGET_STATE(grid_button->button) != GTK_STATE_NORMAL) gtk_widget_set_state(grid_button->button, GTK_STATE_NORMAL); - } - if(grid_button->inx == node_inx[j+1]) { + if(grid_button->inx == node_inx[j+1]) j+=2; - } + } @@ -429,6 +432,44 @@ static void selected_foreach_func(GtkTreeModel *model, } + +static void _each_highlight_selected(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer userdata) +{ + grid_button_t *grid_button = NULL; + int node_inx = 0; + grid_foreach_t *grid_foreach = userdata; + ListIterator itr = NULL; + + xassert(grid_foreach); + + gtk_tree_model_get(model, iter, grid_foreach->node_inx_id, + &node_inx, -1); + + if (node_inx < 0 || !grid_foreach->button_list) + return; + itr = list_iterator_create(grid_foreach->button_list); + while((grid_button = list_next(itr))) { + /*For multiple selections, need to retain all selected. + *(previously this assumed only one selected). + */ + if (grid_button->inx != node_inx) + continue; + else if (GTK_WIDGET_STATE(grid_button->button) + != GTK_STATE_NORMAL) { + gtk_widget_set_state(grid_button->button, + GTK_STATE_NORMAL); + } + break; + } + list_iterator_destroy(itr); + return; + +} + + static int _block_in_node(int *bp_inx, int inx) { int j=0; @@ -439,6 +480,179 @@ static int _block_in_node(int *bp_inx, int inx) return 0; } +static int _add_button_to_list(node_info_t *node_ptr, + GtkTable *table, List button_list, + int *coord_x, int *coord_y, int *inx, + int default_y_offset, int table_y) +{ + grid_button_t *grid_button = NULL; + + if(cluster_dims == 4) { + /* FIXME: */ + return SLURM_ERROR; + } else if(cluster_dims == 3) { + int i = strlen(node_ptr->name); + int x=0, y=0, z=0, y_offset=0; + /* On 3D system we need to translate a + 3D space to a 2D space and make it + appear 3D. So we get the coords of + each node in xyz format and apply + an x and y offset to get a coord_x + and coord_y. This is not needed + for linear systems since they can + be laid out in any fashion + */ + if (i < 4) { + g_error("bad node name %s\n", node_ptr->name); + return SLURM_ERROR; + } else { + x = _coord(node_ptr->name[i-3]); + y = _coord(node_ptr->name[i-2]); + z = _coord(node_ptr->name[i-1]); + } + (*coord_x) = (x + (DIM_SIZE[Z] - 1)) - z; + y_offset = default_y_offset - (DIM_SIZE[Z] * y); + (*coord_y) = (y_offset - y) + z; + } + + grid_button = xmalloc(sizeof(grid_button_t)); + grid_button->color_inx = MAKE_INIT; + grid_button->inx = (*inx)++; + grid_button->table = table; + grid_button->table_x = (*coord_x); + grid_button->table_y = (*coord_y); + grid_button->button = gtk_button_new(); + grid_button->node_name = xstrdup(node_ptr->name); + + gtk_widget_set_size_request(grid_button->button, 10, 10); + _add_button_signals(grid_button); + list_append(button_list, grid_button); + + gtk_table_attach(table, grid_button->button, + (*coord_x), ((*coord_x)+1), + (*coord_y), ((*coord_y)+1), + GTK_SHRINK, GTK_SHRINK, + 1, 1); + + /* gtk_container_add(GTK_CONTAINER(grid_button->frame), */ +/* grid_button->button); */ +/* gtk_frame_set_shadow_type(GTK_FRAME(grid_button->frame), */ +/* GTK_SHADOW_ETCHED_OUT); */ + if(cluster_dims < 3) { + /* On linear systems we just up the + x_coord until we hit the side of + the table and then incrememnt the + coord_y. We add space inbetween + each 10th row. + */ + (*coord_x)++; + if((*coord_x) == working_sview_config.grid_x_width) { + (*coord_x) = 0; + (*coord_y)++; + if(!((*coord_y) % working_sview_config.grid_vert)) + gtk_table_set_row_spacing( + table, (*coord_y)-1, 5); + } + + if((*coord_y) == table_y) + return SLURM_ERROR; + + if((*coord_x) && !((*coord_x) % working_sview_config.grid_hori)) + gtk_table_set_col_spacing(table, (*coord_x)-1, 5); + } + return SLURM_SUCCESS; +} + +static int _grid_table_by_switch(GtkTable *table, List button_list, + int *coord_x, int *coord_y, + int default_y_offset, int table_y) +{ + int rc = SLURM_SUCCESS; +// GdkColor switch_color; +// int color_assignment = 2; + int i = 0; + switch_record_bitmaps_t *sw_nodes_bitmaps_ptr = g_switch_nodes_maps; + int inx=0; + + for (i=0; i<g_topo_info_msg_ptr->record_count; i++, + sw_nodes_bitmaps_ptr++) { + int j = 0, first, last; + if (g_topo_info_msg_ptr->topo_array[i].level) + continue; +// if (color_assignment > switch_colors_cnt) { +// color_assignment=2; +// } +// gdk_color_parse(switch_colors[color_assignment], +// &switch_color); + first = bit_ffs(sw_nodes_bitmaps_ptr->node_bitmap); + if (first == -1) + continue; + last = bit_fls(sw_nodes_bitmaps_ptr->node_bitmap); + for (j = first; j <= last; j++) { +// if (!(g_node_info_ptr->node_array[j].node_state == +// NODE_STATE_ALLOCATED)) +// continue; + if (TOPO_DEBUG) + g_print("allocated node = %s button# %d\n", + g_node_info_ptr->node_array[j].name, + j); + + if((rc = _add_button_to_list( + &g_node_info_ptr->node_array[j], + table, button_list, coord_x, coord_y, &inx, + default_y_offset, table_y)) + != SLURM_SUCCESS) + break; + } + } + /* This is needed to get the correct width of the grid + window. If it is not given then we get a really narrow + window. */ + gtk_table_set_row_spacing(table, (*coord_y)-1, 1); + + return rc; + +} + +static int _grid_table_by_list(GtkTable *table, + List button_list, List node_list, + int *coord_x, int *coord_y, + int default_y_offset, int table_y) +{ + sview_node_info_t *sview_node_info_ptr = NULL; + static partition_info_msg_t *part_info_ptr = NULL; + int inx = 0, rc = SLURM_SUCCESS; + + ListIterator itr = list_iterator_create(node_list); + while((sview_node_info_ptr = list_next(itr))) { + if (strcmp(excluded_partitions, "-")) { + int rc = get_new_info_part( + &part_info_ptr, force_refresh); + if((rc == SLURM_NO_CHANGE_IN_DATA) + || (rc == SLURM_SUCCESS)) + if(!check_part_includes_node( + part_info_ptr, inx)) { + inx++; + continue; + } + } + if((rc = _add_button_to_list( + sview_node_info_ptr->node_ptr, + table, button_list, coord_x, coord_y, &inx, + default_y_offset, table_y)) != SLURM_SUCCESS) + break; + } + list_iterator_destroy(itr); + + /* This is needed to get the correct width of the grid + window. If it is not given then we get a really narrow + window. */ + gtk_table_set_row_spacing(table, (*coord_y)-1, 1); + + + return rc; +} + /* static void _destroy_grid_foreach(void *arg) */ /* { */ /* grid_foreach_t *grid_foreach = (grid_foreach_t *)arg; */ @@ -600,7 +814,7 @@ extern void highlight_grid(GtkTreeView *tree_view, grid_button_t *grid_button = NULL; grid_foreach_t grid_foreach; - if(!button_list) + if(!button_list || !tree_view) return; /*first clear all grid buttons*/ @@ -612,8 +826,8 @@ extern void highlight_grid(GtkTreeView *tree_view, gtk_widget_set_state(grid_button->button, GTK_STATE_ACTIVE); } - continue; } + list_iterator_destroy(itr); /* for each currently selected row,go back & ensure the * corresponding grid button is highlighted */ @@ -621,9 +835,19 @@ extern void highlight_grid(GtkTreeView *tree_view, grid_foreach.node_inx_id = node_inx_id; grid_foreach.color_inx_id = color_inx_id; grid_foreach.button_list = button_list; - gtk_tree_selection_selected_foreach( - gtk_tree_view_get_selection(tree_view), - selected_foreach_func, &grid_foreach); + if(grid_foreach.color_inx_id != (int)NO_VAL) + gtk_tree_selection_selected_foreach( + gtk_tree_view_get_selection(tree_view), + _each_highlightd, &grid_foreach); + else + gtk_tree_selection_selected_foreach( + gtk_tree_view_get_selection(tree_view), + _each_highlight_selected, &grid_foreach); + if(working_sview_config.grid_speedup) { + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); + } + return; } @@ -869,9 +1093,13 @@ extern void put_buttons_in_table(GtkTable *table, List button_list) grid_button_t *grid_button = NULL; ListIterator itr = NULL; int node_count = list_count(button_list); - list_sort(button_list, (ListCmpF) _sort_button_inx); + if(node_count == 0) { + g_print("put_buttons_in_table: no nodes selected\n"); + return; + } + if(cluster_dims == 4) { /* FIXME: */ return; @@ -892,7 +1120,6 @@ extern void put_buttons_in_table(GtkTable *table, List button_list) table_y = node_count/working_sview_config.grid_x_width; table_y++; } - //g_print("the table size is y=%d x=%d\n", table_y, working_sview_config.grid_x_width); gtk_table_resize(table, table_y, working_sview_config.grid_x_width); itr = list_iterator_create(button_list); while((grid_button = list_next(itr))) { @@ -970,6 +1197,10 @@ extern int update_grid_table(GtkTable *table, List button_list, List node_list) table_y = (DIM_SIZE[Z] * DIM_SIZE[Y]) + DIM_SIZE[Y]; } else { node_count = list_count(node_list); + if(node_count == 0) { + g_print("put_buttons_in_table: no nodes selected\n"); + return SLURM_ERROR; + } if(!working_sview_config.grid_x_width) { if(node_count < 50) { working_sview_config.grid_x_width = 1; @@ -1105,7 +1336,7 @@ extern int get_system_stats(GtkTable *table) ba_init(node_info_ptr, 0); - node_list = create_node_info_list(node_info_ptr, changed); + node_list = create_node_info_list(node_info_ptr, changed, FALSE); if(grid_button_list) update_grid_table(main_grid_table, grid_button_list, node_list); @@ -1121,12 +1352,9 @@ extern int get_system_stats(GtkTable *table) extern int setup_grid_table(GtkTable *table, List button_list, List node_list) { - int error_code = SLURM_SUCCESS; - int coord_x=0, coord_y=0, inx=0, table_y = 0; - grid_button_t *grid_button = NULL; + int rc = SLURM_SUCCESS; + int coord_x=0, coord_y=0, table_y = 0; int node_count = 0; - ListIterator itr = NULL; - sview_node_info_t *sview_node_info_ptr = NULL; int default_y_offset = 0; if(cluster_dims == 4) { @@ -1149,8 +1377,7 @@ extern int setup_grid_table(GtkTable *table, List button_list, List node_list) working_sview_config.grid_x_width = 20; } } - table_y = node_count/working_sview_config.grid_x_width; - table_y++; + table_y = (node_count/working_sview_config.grid_x_width) + 1; } if(!node_list) { @@ -1158,102 +1385,26 @@ extern int setup_grid_table(GtkTable *table, List button_list, List node_list) return SLURM_ERROR; } - gtk_table_resize(table, table_y, working_sview_config.grid_x_width); - itr = list_iterator_create(node_list); - while((sview_node_info_ptr = list_next(itr))) { - if(cluster_dims == 4) { - /* FIXME: */ - return SLURM_ERROR; - } else if(cluster_dims == 3) { - int i = strlen(sview_node_info_ptr->node_ptr->name); - int x=0, y=0, z=0, y_offset=0; - /* On 3D system we need to translate a - 3D space to a 2D space and make it - appear 3D. So we get the coords of - each node in xyz format and apply - an x and y offset to get a coord_x - and coord_y. This is not needed - for linear systems since they can - be laid out in any fashion - */ - if (i < 4) { - g_error("bad node name %s\n", - sview_node_info_ptr->node_ptr->name); - goto end_it; - } else { - x = _coord(sview_node_info_ptr-> - node_ptr->name[i-3]); - y = _coord(sview_node_info_ptr-> - node_ptr->name[i-2]); - z = _coord(sview_node_info_ptr-> - node_ptr->name[i-1]); - } - coord_x = (x + (DIM_SIZE[Z] - 1)) - z; - y_offset = default_y_offset - (DIM_SIZE[Z] * y); - coord_y = (y_offset - y) + z; - } - - grid_button = xmalloc(sizeof(grid_button_t)); - grid_button->color_inx = MAKE_INIT; - grid_button->inx = inx++; - grid_button->table = table; - grid_button->table_x = coord_x; - grid_button->table_y = coord_y; -/* grid_button->frame = gtk_frame_new(NULL); */ - grid_button->button = gtk_button_new(); - grid_button->node_name = - xstrdup(sview_node_info_ptr->node_ptr->name); - - gtk_widget_set_size_request(grid_button->button, 10, 10); - _add_button_signals(grid_button); - list_append(button_list, grid_button); - - gtk_table_attach(table, grid_button->button, - coord_x, (coord_x+1), - coord_y, (coord_y+1), - GTK_SHRINK, GTK_SHRINK, - 1, 1); - - /* gtk_container_add(GTK_CONTAINER(grid_button->frame), */ -/* grid_button->button); */ -/* gtk_frame_set_shadow_type(GTK_FRAME(grid_button->frame), */ -/* GTK_SHADOW_ETCHED_OUT); */ - if(cluster_dims < 3) { - /* On linear systems we just up the - x_coord until we hit the side of - the table and then incrememnt the - coord_y. We add space inbetween - each 10th row. - */ - coord_x++; - if(coord_x - == working_sview_config.grid_x_width) { - coord_x = 0; - coord_y++; - if(!(coord_y % working_sview_config.grid_vert)) - gtk_table_set_row_spacing( - table, coord_y-1, 5); - } - - if(coord_y == table_y) - break; - - if(coord_x && !(coord_x%working_sview_config.grid_hori)) - gtk_table_set_col_spacing( - table, coord_x-1, 5); - } + if(node_count == 0) { + g_print("setup_grid_table: no nodes selected\n"); + return SLURM_ERROR; } - /* This is needed to get the correct width of the grid - window. If it is not given then we get a really narrow - window. */ - gtk_table_set_row_spacing(table, coord_y-1, 1); + gtk_table_resize(table, table_y, working_sview_config.grid_x_width); + + if (default_sview_config.grid_topological && + (g_topo_info_msg_ptr != NULL)) + rc = _grid_table_by_switch(table, button_list, + &coord_x, &coord_y, + default_y_offset, table_y); + else + rc = _grid_table_by_list(table, button_list, node_list, + &coord_x, &coord_y, + default_y_offset, table_y); -end_it: - list_iterator_destroy(itr); list_sort(button_list, (ListCmpF) _sort_button_inx); - return error_code; + return rc; } extern void sview_init_grid(bool reset_highlight) @@ -1287,11 +1438,11 @@ extern void sview_init_grid(bool reset_highlight) while((grid_button = list_next(itr))) { if (grid_button->inx != i) continue; - grid_button->used = false; grid_button->state = node_ptr->node_state; gtk_widget_set_state(grid_button->button, GTK_STATE_NORMAL); - + change_grid_color(grid_button_list, i, i, i, true, 0); + grid_button->used = false; break; } if(!grid_button && !tried_again) { diff --git a/src/sview/job_info.c b/src/sview/job_info.c index 1ec2decb68011ceec561b4954e50b3b258831ce3..cea2063fd594094ceaf4eae0270790423687a3af 100644 --- a/src/sview/job_info.c +++ b/src/sview/job_info.c @@ -64,8 +64,6 @@ typedef struct { char *type; } jobs_foreach_common_t; - - enum { EDIT_SIGNAL = 1, EDIT_SIGNAL_USER, @@ -469,22 +467,6 @@ static void _destroy_jobs_foreach(void *object) } } -/* static void _destroy_jobs_foreach_common(void *object) */ -/* { */ -/* jobs_foreach_common_t *jobs_foreach = (jobs_foreach_common_t *)object; */ - -/* if (jobs_foreach) { */ -/* if(jobs_foreach->entry) { */ -/* gtk_widget_destroy(jobs_foreach->entry); */ -/* jobs_foreach->entry = NULL; */ -/* } */ -/* /\* job_msg is freed elsewhere *\/ */ -/* //slurm_free_job_desc_msg(jobs_foreach->job_msg); */ -/* xfree(jobs_foreach->type); */ -/* xfree(jobs_foreach); */ -/* } */ -/* } */ - /* translate name name to number */ static uint16_t _xlate_signal_name(const char *signal_name) { @@ -554,7 +536,7 @@ static int _cancel_job_id (uint32_t job_id, uint16_t signal) } static int _cancel_step_id(uint32_t job_id, uint32_t step_id, - uint16_t signal) + uint16_t signal) { int error_code = SLURM_SUCCESS, i; char *temp = NULL; @@ -891,7 +873,7 @@ static const char *_set_job_msg(job_desc_msg_t *job_msg, const char *new_text, for (j=0; j<SYSTEM_DIMENSIONS; j++) geo[j] = (uint16_t) NO_VAL; for (j=0; j<SYSTEM_DIMENSIONS; j++) { - if (token == NULL) { + if (!token) { //error("insufficient dimensions in " // "Geometry"); goto return_error; @@ -906,7 +888,7 @@ static const char *_set_job_msg(job_desc_msg_t *job_msg, const char *new_text, token = strtok_r(geometry_tmp, delimiter, &next_ptr); } - if (token != NULL) { + if (token) { //error("too many dimensions in Geometry"); goto return_error; } @@ -2460,6 +2442,8 @@ static List _create_job_info_list(job_info_msg_t *job_info_ptr, for(i=0; i<job_info_ptr->record_count; i++) { job_ptr = &(job_info_ptr->job_array[i]); + if (strstr(excluded_partitions, job_ptr->partition)) + continue; sview_job_info_ptr = xmalloc(sizeof(sview_job_info_t)); sview_job_info_ptr->job_ptr = job_ptr; sview_job_info_ptr->step_list = list_create(NULL); @@ -2636,9 +2620,9 @@ finished: extern void refresh_job(GtkAction *action, gpointer user_data) { popup_info_t *popup_win = (popup_info_t *)user_data; - xassert(popup_win != NULL); - xassert(popup_win->spec_info != NULL); - xassert(popup_win->spec_info->title != NULL); + xassert(popup_win); + xassert(popup_win->spec_info); + xassert(popup_win->spec_info->title); popup_win->force_refresh = 1; specific_info_job(popup_win); } @@ -2660,8 +2644,8 @@ extern int get_new_info_job(job_info_msg_t **info_ptr, error_code = SLURM_SUCCESS; *info_ptr = g_job_info_ptr; if(changed) - return SLURM_SUCCESS; - return error_code; + error_code = SLURM_SUCCESS; + goto end_it; } last = now; @@ -2681,6 +2665,7 @@ extern int get_new_info_job(job_info_msg_t **info_ptr, changed = 0; } } else { + new_job_ptr = NULL; error_code = slurm_load_jobs((time_t) NULL, &new_job_ptr, show_flags); changed = 1; @@ -2693,6 +2678,7 @@ extern int get_new_info_job(job_info_msg_t **info_ptr, error_code = SLURM_SUCCESS; *info_ptr = g_job_info_ptr; +end_it: return error_code; } @@ -2712,8 +2698,8 @@ extern int get_new_info_job_step(job_step_info_response_msg_t **info_ptr, error_code = SLURM_SUCCESS; *info_ptr = g_step_info_ptr; if(changed) - return SLURM_SUCCESS; - return error_code; + error_code = SLURM_SUCCESS; + goto end_it; } last = now; @@ -2734,6 +2720,7 @@ extern int get_new_info_job_step(job_step_info_response_msg_t **info_ptr, changed = 0; } } else { + new_step_ptr = NULL; error_code = slurm_get_job_steps((time_t) NULL, NO_VAL, NO_VAL, &new_step_ptr, show_flags); changed = 1; @@ -2745,6 +2732,7 @@ extern int get_new_info_job_step(job_step_info_response_msg_t **info_ptr, error_code = SLURM_SUCCESS; *info_ptr = g_step_info_ptr; +end_it: return error_code; } @@ -3011,7 +2999,7 @@ display_it: info_list = _create_job_info_list(job_info_ptr, step_info_ptr, changed, 0); if(!info_list) - return; + goto reset_curs; /* set up the grid */ if(display_widget && GTK_IS_TREE_VIEW(display_widget) @@ -3038,6 +3026,16 @@ display_it: } } list_iterator_destroy(itr); + change_grid_color(grid_button_list, -1, -1, + MAKE_WHITE, true, 0); + } else + highlight_grid(GTK_TREE_VIEW(display_widget), + SORTID_NODE_INX, SORTID_COLOR_INX, + grid_button_list); + + if(working_sview_config.grid_speedup) { + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); } if(view == ERROR_VIEW && display_widget) { @@ -3049,8 +3047,8 @@ display_it: &grid_button_list); /*set multiple capability here*/ gtk_tree_selection_set_mode( - gtk_tree_view_get_selection(tree_view), - GTK_SELECTION_MULTIPLE); + gtk_tree_view_get_selection(tree_view), + GTK_SELECTION_MULTIPLE); display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(tree_view), @@ -3062,34 +3060,15 @@ display_it: SORTID_CNT, SORTID_TIME_SUBMIT, SORTID_COLOR); } - if(gtk_tree_selection_count_selected_rows( - gtk_tree_view_get_selection( - GTK_TREE_VIEW(display_widget)))) { - GtkTreeViewColumn *focus_column = NULL; - /* highlight the correct nodes from the last selection */ - gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget), - &path, &focus_column); - } - - if(path) - highlight_grid(GTK_TREE_VIEW(display_widget), - SORTID_NODE_INX, SORTID_COLOR_INX, - grid_button_list); - else - change_grid_color(grid_button_list, -1, -1, - MAKE_WHITE, true, 0); - - if(working_sview_config.grid_speedup) { - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); - } - view = INFO_VIEW; _update_info_job(info_list, GTK_TREE_VIEW(display_widget)); end_it: toggled = FALSE; force_refresh = FALSE; +reset_curs: + if (main_window && main_window->window) + gdk_window_set_cursor(main_window->window, NULL); return; } @@ -3183,7 +3162,10 @@ display_it: if(spec_info->type != INFO_PAGE && !spec_info->display_widget) { tree_view = create_treeview(local_display_data, &popup_win->grid_button_list); - + /*set multiple capability here*/ + gtk_tree_selection_set_mode( + gtk_tree_view_get_selection(tree_view), + GTK_SELECTION_MULTIPLE); spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); gtk_table_attach_defaults(popup_win->table, @@ -3546,90 +3528,89 @@ static void process_foreach_list (jobs_foreach_common_t *jobs_foreach_common) state = job_foreach->state; switch(jobs_foreach_common->edit_type) { - case EDIT_SIGNAL: - /* fall through to the cancel now the signal - * is set (Default is SIGKILL from above for - * just a regular cancel). - */ - case EDIT_CANCEL: - if(stepid == NO_VAL) - global_error_code = - _cancel_job_id(jobid, signal); - else - global_error_code = - _cancel_step_id(jobid, - stepid, signal); - break; - case EDIT_REQUEUE: - response = slurm_requeue(jobid); - - if(response) { - /* stop rest of jobs */ - global_error_code = response; - tmp_char_ptr = g_strdup_printf( - "Error %d happened trying " - "to requeue job %u.", - response, jobid); - display_edit_note(tmp_char_ptr); - g_free(tmp_char_ptr); - } - - break; - case EDIT_SUSPEND: - //note: derive state from job_foreach.. - if(state == JOB_SUSPENDED) - response = slurm_resume(jobid); - else - response = slurm_suspend(jobid); - if(response) { - /* stop rest of jobs */ - global_error_code = 1; - tmp_char_ptr = g_strdup_printf( - "Error happened trying to " - "SUSPEND/RESUME job %u.", - jobid); - display_edit_note(tmp_char_ptr); - g_free(tmp_char_ptr); - } - break; - case EDIT_EDIT: - /* note: this case only applies to - single jobs, but still gets - processed here */ - if(got_edit_signal) - goto end_it; - - if(global_edit_error) - tmp_char_ptr = global_edit_error_msg; - else if(!global_send_update_msg) { - tmp_char_ptr = g_strdup_printf( - "No change detected."); - } else if(slurm_update_job( - jobs_foreach_common->job_msg) - == SLURM_SUCCESS) { - tmp_char_ptr = g_strdup_printf( - "Job %u updated successfully", - jobid); - } else if(errno == ESLURM_DISABLED) { - tmp_char_ptr = g_strdup_printf( - "Can't edit that part of " - "non-pending job %u.", - jobid); - } else { - tmp_char_ptr = g_strdup_printf( - "Problem updating job %u.", - jobid); - } + case EDIT_SIGNAL: + /* fall through to the cancel now the signal + * is set (Default is SIGKILL from above for + * just a regular cancel). + */ + case EDIT_CANCEL: + if(stepid == NO_VAL) + global_error_code = + _cancel_job_id(jobid, signal); + else + global_error_code = + _cancel_step_id(jobid, + stepid, signal); + break; + case EDIT_REQUEUE: + response = slurm_requeue(jobid); + + if(response) { + /* stop rest of jobs */ + global_error_code = response; + tmp_char_ptr = g_strdup_printf( + "Error happened trying " + "to requeue job %u: %s", + jobid, slurm_strerror(response)); display_edit_note(tmp_char_ptr); g_free(tmp_char_ptr); - break; - default: - break; + } + break; + case EDIT_SUSPEND: + //note: derive state from job_foreach.. + if(state == JOB_SUSPENDED) + response = slurm_resume(jobid); + else + response = slurm_suspend(jobid); + if(!response) { + /* stop rest of jobs */ + global_error_code = response; + tmp_char_ptr = g_strdup_printf( + "Error happened trying to " + "SUSPEND/RESUME job %u.", + jobid); + display_edit_note(tmp_char_ptr); + g_free(tmp_char_ptr); + } + break; + case EDIT_EDIT: + /* note: this case only applies to + single jobs, but still gets + processed here */ + if(got_edit_signal) + goto end_it; + + if(global_edit_error) + tmp_char_ptr = global_edit_error_msg; + else if(!global_send_update_msg) { + tmp_char_ptr = g_strdup_printf( + "No change detected."); + } else if(slurm_update_job( + jobs_foreach_common->job_msg) + == SLURM_SUCCESS) { + tmp_char_ptr = g_strdup_printf( + "Job %u updated successfully", + jobid); + } else if(errno == ESLURM_DISABLED) { + tmp_char_ptr = g_strdup_printf( + "Can't edit that part of " + "non-pending job %u.", + jobid); + } else { + tmp_char_ptr = g_strdup_printf( + "Problem updating job %u.", + jobid); + } + display_edit_note(tmp_char_ptr); + g_free(tmp_char_ptr); + break; + default: + break; }/*end switch*/ } /*spin thru selected jobs*/ - if(global_edit_error) + if(global_edit_error || global_error_code) goto end_it; switch(jobs_foreach_common->edit_type) { @@ -3668,7 +3649,6 @@ static void process_foreach_list (jobs_foreach_common_t *jobs_foreach_common) end_it: xfree(stacked_job_list); - gdk_window_set_cursor(main_window->window, standard_cursor); } /*process_foreach_list ^^^*/ @@ -3711,7 +3691,6 @@ static void selected_foreach_build_list(GtkTreeModel *model, xstrfmtcat(stacked_job_list, "%u", jobid); else xstrfmtcat(stacked_job_list, "%u.%u", jobid, stepid); - //g_print("got '%s'\n", stacked_job_list); } /*selected_foreach_build_list ^^^*/ @@ -3720,10 +3699,8 @@ extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, { int jobid = NO_VAL; int stepid = NO_VAL; - int state = 0; int response = 0; char tmp_char[255]; - char *tmp_char_ptr = NULL; int edit_type = 0; int row_count=0; job_desc_msg_t *job_msg = xmalloc(sizeof(job_desc_msg_t)); @@ -3768,44 +3745,25 @@ extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, gtk_window_set_default(GTK_WINDOW(popup), label); gtk_dialog_add_button(GTK_DIALOG(popup), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - if (row_count > 1) { - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to requeue these jobs?"); - } else { - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to requeue job %u?", jobid); - } + snprintf(tmp_char, sizeof(tmp_char), + "Are you sure you want to requeue these job(s)?"); label = gtk_label_new(tmp_char); edit_type = EDIT_REQUEUE; } else if(!strcasecmp("Cancel", type)) { - gdk_window_set_cursor(main_window->window, in_process_cursor); label = gtk_dialog_add_button(GTK_DIALOG(popup), GTK_STOCK_YES, GTK_RESPONSE_OK); gtk_window_set_default(GTK_WINDOW(popup), label); gtk_dialog_add_button(GTK_DIALOG(popup), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - if (row_count > 1) { - if(stepid != NO_VAL) - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to cancel " - "these job steps?"); - else - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to cancel " - "these jobs?"); - } else { - if(stepid != NO_VAL) - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to cancel " - "job %u.%u?", - jobid, stepid); - else - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to cancel job " - "%u?", - jobid); - } + if(stepid != NO_VAL) + snprintf(tmp_char, sizeof(tmp_char), + "Are you sure you want to cancel " + "these job step(s)?"); + else + snprintf(tmp_char, sizeof(tmp_char), + "Are you sure you want to cancel " + "these job(s)?"); label = gtk_label_new(tmp_char); edit_type = EDIT_CANCEL; } else if(!strcasecmp("Suspend/Resume", type)) { @@ -3815,31 +3773,14 @@ extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, gtk_dialog_add_button(GTK_DIALOG(popup), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - gtk_tree_model_get(model, iter, SORTID_STATE_NUM, &state, -1); - if(state == JOB_SUSPENDED) - tmp_char_ptr = "resume"; - else - tmp_char_ptr = "suspend"; - if (row_count > 1) { - if(stepid != NO_VAL) - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to toggle " - "suspend/resume on these " - "job steps?"); - else - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to toggle " - "suspend/resume on these jobs?"); - } else { if(stepid != NO_VAL) snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to %s job %u.%u?", - tmp_char_ptr, jobid, stepid); + "Are you sure you want to toggle " + "suspend/resume on these job steps?"); else snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to %s job %u?", - tmp_char_ptr, jobid); - } + "Are you sure you want to toggle " + "suspend/resume on these jobs?"); label = gtk_label_new(tmp_char); edit_type = EDIT_SUSPEND; } else { @@ -3869,8 +3810,6 @@ extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, if (response == GTK_RESPONSE_OK) { jobs_foreach_common_t job_foreach_common; - /* switch to whirlwind cursor while busy*/ - gdk_window_set_cursor(main_window->window, in_process_cursor); global_error_code = SLURM_SUCCESS; /* setup params that applies to ALL selections */ memset(&job_foreach_common, 0, sizeof(jobs_foreach_common_t)); @@ -3895,7 +3834,6 @@ extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, list_destroy(foreach_list); }/*response OK ^^*/ /* switch back to standard cursor*/ - gdk_window_set_cursor(main_window->window,standard_cursor); global_entry_changed = 0; slurm_free_job_desc_msg(job_msg); diff --git a/src/sview/node_info.c b/src/sview/node_info.c index 0e8aeb0d2cf4a391c3f7e7ccd63946627cd5fe32..57d016b170f4dd7103fdfe3ca7c123db2e0e1fc9 100644 --- a/src/sview/node_info.c +++ b/src/sview/node_info.c @@ -31,6 +31,7 @@ #include "src/sview/sview.h" #define _DEBUG 0 +#define ECLIPSE_RT 0 int cpus_per_node = 1; int g_node_scaling = 1; @@ -60,6 +61,13 @@ enum { SORTID_CNT }; + + +typedef struct { + int node_col; + char *nodelist; +} process_node_t; + static display_data_t display_data_node[] = { {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE, refresh_node, create_model_node, admin_edit_node}, @@ -117,8 +125,8 @@ static display_data_t options_data_node[] = { #else {G_TYPE_STRING, NODE_PAGE, "Drain Node", TRUE, ADMIN_PAGE}, {G_TYPE_STRING, NODE_PAGE, "Resume Node", TRUE, ADMIN_PAGE}, - {G_TYPE_STRING, NODE_PAGE, "Put Node Down", TRUE, ADMIN_PAGE}, - {G_TYPE_STRING, NODE_PAGE, "Make Node Idle", TRUE, ADMIN_PAGE}, + {G_TYPE_STRING, NODE_PAGE, "Put Node(s) Down", TRUE, ADMIN_PAGE}, + {G_TYPE_STRING, NODE_PAGE, "Make Node(s) Idle", TRUE, ADMIN_PAGE}, #endif {G_TYPE_STRING, NODE_PAGE, "Update Features", TRUE, ADMIN_PAGE}, {G_TYPE_STRING, NODE_PAGE, "Update Gres", TRUE, ADMIN_PAGE}, @@ -442,7 +450,7 @@ static void _node_info_list_del(void *object) } } -void _display_info_node(List info_list, popup_info_t *popup_win) +static void _display_info_node(List info_list, popup_info_t *popup_win) { specific_info_t *spec_info = popup_win->spec_info; char *name = (char *)spec_info->search_info->gchar_data; @@ -513,22 +521,59 @@ finished: return; } +static void _selected_page(GtkMenuItem *menuitem, + display_data_t *display_data) +{ + switch(display_data->extra) { + case NODE_PAGE: + popup_all_node_name(display_data->user_data, display_data->id); + break; + case ADMIN_PAGE: + admin_node_name(display_data->user_data, + NULL, display_data->name); + break; + default: + g_print("node got %d %d\n", display_data->extra, + display_data->id); + } + +} + +static void _process_each_node(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer userdata) +{ + char *name = NULL; + process_node_t *process_node = userdata; + + gtk_tree_model_get(model, iter, process_node->node_col, &name, -1); + if(process_node->nodelist) + xstrfmtcat(process_node->nodelist, ",%s", name); + else + process_node->nodelist = xstrdup(name); + g_free(name); +} +/*process_each_node ^^^*/ + + + extern void refresh_node(GtkAction *action, gpointer user_data) { popup_info_t *popup_win = (popup_info_t *)user_data; - xassert(popup_win != NULL); - xassert(popup_win->spec_info != NULL); - xassert(popup_win->spec_info->title != NULL); + xassert(popup_win); + xassert(popup_win->spec_info); + xassert(popup_win->spec_info->title); popup_win->force_refresh = 1; specific_info_node(popup_win); } /* don't destroy the list from this function */ -extern List create_node_info_list(node_info_msg_t *node_info_ptr, int changed) +extern List create_node_info_list(node_info_msg_t *node_info_ptr, + int changed, bool by_partition) { static List info_list = NULL; int i = 0; sview_node_info_t *sview_node_info_ptr = NULL; + static partition_info_msg_t *part_info_ptr = NULL; node_info_t *node_ptr = NULL; char user[32], time_str[32]; @@ -548,12 +593,24 @@ extern List create_node_info_list(node_info_msg_t *node_info_ptr, int changed) for (i=0; i<node_info_ptr->record_count; i++) { node_ptr = &(node_info_ptr->node_array[i]); if (!node_ptr->name || (node_ptr->name[0] == '\0')) - continue; /* bad node */ - + continue; + if (by_partition) { + /*constrain list to included partitions' nodes*/ + if (strcmp(excluded_partitions, "-")) { + int rc = get_new_info_part( + &part_info_ptr, force_refresh); + if(rc == SLURM_NO_CHANGE_IN_DATA || + rc == SLURM_SUCCESS) + if(!check_part_includes_node( + part_info_ptr, i)) + continue; + } + } sview_node_info_ptr = xmalloc(sizeof(sview_node_info_t)); list_append(info_list, sview_node_info_ptr); sview_node_info_ptr->node_ptr = node_ptr; sview_node_info_ptr->pos = i; + if(node_ptr->reason && (node_ptr->reason_uid != NO_VAL) && node_ptr->reason_time) { struct passwd *pw = NULL; @@ -602,8 +659,8 @@ extern int get_new_info_node(node_info_msg_t **info_ptr, int force) error_code = SLURM_SUCCESS; *info_ptr = g_node_info_ptr; if(changed) - return SLURM_SUCCESS; - return error_code; + error_code = SLURM_SUCCESS; + goto end_it; } last = now; @@ -623,6 +680,7 @@ extern int get_new_info_node(node_info_msg_t **info_ptr, int force) changed = 0; } } else { + new_node_ptr = NULL; error_code = slurm_load_node((time_t) NULL, &new_node_ptr, show_flags); changed = 1; @@ -680,7 +738,8 @@ extern int get_new_info_node(node_info_msg_t **info_ptr, int force) /* don't worry about mixed since the whole node is being drained. */ } else if ((alloc_cpus && err_cpus) || - (idle_cpus && (idle_cpus != node_ptr->cpus))) { + (idle_cpus && + (idle_cpus != node_ptr->cpus))) { node_ptr->node_state &= NODE_STATE_FLAGS; if(err_cpus) node_ptr->node_state @@ -709,6 +768,11 @@ extern int get_new_info_node(node_info_msg_t **info_ptr, int force) } *info_ptr = g_node_info_ptr; + if (!g_topo_info_msg_ptr && + default_sview_config.grid_topological) { + get_topo_conf(); /*pull in topology NOW*/ + } +end_it: return error_code; } @@ -724,9 +788,15 @@ extern int update_features_node(GtkDialog *dialog, const char *nodelist, int no_dialog = 0; int rc = SLURM_SUCCESS; + + if (_DEBUG) + g_print("update_features_node:global_row_count: %d " + "node_names %s\n", + global_row_count, nodelist); if(!dialog) { snprintf(tmp_char, sizeof(tmp_char), - "Update Features for Node(s) %s?", nodelist); + "Update Features for Node(s) %s?", + nodelist); dialog = GTK_DIALOG( gtk_dialog_new_with_buttons( @@ -743,10 +813,8 @@ extern int update_features_node(GtkDialog *dialog, const char *nodelist, gtk_dialog_add_button(dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + slurm_init_update_node_msg(node_msg); node_msg->node_names = xstrdup(nodelist); - node_msg->features = NULL; - node_msg->reason = NULL; - node_msg->node_state = (uint16_t) NO_VAL; snprintf(tmp_char, sizeof(tmp_char), "Features for Node(s) %s?", nodelist); @@ -774,18 +842,17 @@ extern int update_features_node(GtkDialog *dialog, const char *nodelist, g_free(edit); goto end_it; } - if(slurm_update_node(node_msg) - == SLURM_SUCCESS) { + if((rc = slurm_update_node(node_msg) == SLURM_SUCCESS)) { edit = g_strdup_printf( - "Nodes %s updated successfully.", + "Node(s) %s updated successfully.", nodelist); display_edit_note(edit); g_free(edit); } else { edit = g_strdup_printf( - "Problem updating nodes %s.", - nodelist); + "Problem updating node(s) %s: %s", + nodelist, slurm_strerror(rc)); display_edit_note(edit); g_free(edit); } @@ -811,9 +878,14 @@ extern int update_gres_node(GtkDialog *dialog, const char *nodelist, int no_dialog = 0; int rc = SLURM_SUCCESS; + if (_DEBUG) + g_print("update_gres_node:global_row_count:" + " %d node_names %s\n", + global_row_count, nodelist); if(!dialog) { snprintf(tmp_char, sizeof(tmp_char), - "Update Gres for Node(s) %s?", nodelist); + "Update Gres for Node(s) %s?", + nodelist); dialog = GTK_DIALOG( gtk_dialog_new_with_buttons( @@ -824,22 +896,17 @@ extern int update_gres_node(GtkDialog *dialog, const char *nodelist, NULL)); no_dialog = 1; } - label = gtk_dialog_add_button(dialog, - GTK_STOCK_YES, GTK_RESPONSE_OK); + label = gtk_dialog_add_button(dialog, GTK_STOCK_YES, GTK_RESPONSE_OK); gtk_window_set_default(GTK_WINDOW(dialog), label); - gtk_dialog_add_button(dialog, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + slurm_init_update_node_msg(node_msg); node_msg->node_names = xstrdup(nodelist); - node_msg->gres = NULL; - node_msg->reason = NULL; - node_msg->node_state = (uint16_t) NO_VAL; - snprintf(tmp_char, sizeof(tmp_char), - "Gres for Node(s) %s?", nodelist); + snprintf(tmp_char, sizeof(tmp_char), "Gres for Node(s) %s?", nodelist); + label = gtk_label_new(tmp_char); - gtk_box_pack_start(GTK_BOX(dialog->vbox), - label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(dialog->vbox), label, FALSE, FALSE, 0); entry = create_entry(); if(!entry) @@ -853,26 +920,23 @@ extern int update_gres_node(GtkDialog *dialog, const char *nodelist, response = gtk_dialog_run(dialog); if (response == GTK_RESPONSE_OK) { - node_msg->gres = - xstrdup(gtk_entry_get_text(GTK_ENTRY(entry))); + node_msg->gres = xstrdup(gtk_entry_get_text(GTK_ENTRY(entry))); if(!node_msg->gres) { edit = g_strdup_printf("No gres given."); display_edit_note(edit); g_free(edit); goto end_it; } - if(slurm_update_node(node_msg) - == SLURM_SUCCESS) { + if((rc = slurm_update_node(node_msg)) == SLURM_SUCCESS) { edit = g_strdup_printf( "Nodes %s updated successfully.", nodelist); display_edit_note(edit); g_free(edit); - } else { edit = g_strdup_printf( - "Problem updating nodes %s.", - nodelist); + "Problem updating nodes %s: %s", + nodelist, slurm_strerror(rc)); display_edit_note(edit); g_free(edit); } @@ -909,20 +973,16 @@ extern int update_state_node(GtkDialog *dialog, NULL)); no_dialog = 1; } - label = gtk_dialog_add_button(dialog, - GTK_STOCK_YES, GTK_RESPONSE_OK); + label = gtk_dialog_add_button(dialog, GTK_STOCK_YES, GTK_RESPONSE_OK); gtk_window_set_default(GTK_WINDOW(dialog), label); - gtk_dialog_add_button(dialog, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - node_msg->features = NULL; - node_msg->gres = NULL; - node_msg->reason = NULL; + slurm_init_update_node_msg(node_msg); node_msg->node_names = xstrdup(nodelist); if(!strncasecmp("drain", type, 5)) { - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to drain nodes %s?\n\n" + snprintf(tmp_char, sizeof(tmp_char), + "Are you sure you want to drain node(s) %s?\n\n" "Please put reason.", nodelist); entry = create_entry(); @@ -930,7 +990,7 @@ extern int update_state_node(GtkDialog *dialog, state = NODE_STATE_DRAIN; } else if(!strncasecmp("resume", type, 5)) { snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to resume nodes %s?", + "Are you sure you want to resume node(s) %s?", nodelist); label = gtk_label_new(tmp_char); state = NODE_RESUME; @@ -945,7 +1005,7 @@ extern int update_state_node(GtkDialog *dialog, if(!strcmp(lower, type)) { snprintf(tmp_char, sizeof(tmp_char), "Are you sure you want to set " - "nodes %s to %s?", + "node(s) %s to %s?", nodelist, lower); label = gtk_label_new(tmp_char); state = i; @@ -960,8 +1020,7 @@ extern int update_state_node(GtkDialog *dialog, node_msg->node_state = (uint16_t)state; gtk_box_pack_start(GTK_BOX(dialog->vbox), label, FALSE, FALSE, 0); if(entry) - gtk_box_pack_start(GTK_BOX(dialog->vbox), - entry, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(dialog->vbox), entry, TRUE, TRUE, 0); gtk_widget_show_all(GTK_WIDGET(dialog)); i = gtk_dialog_run(dialog); if (i == GTK_RESPONSE_OK) { @@ -975,23 +1034,21 @@ extern int update_state_node(GtkDialog *dialog, g_free(lower); goto end_it; } - if (uid_from_string(getlogin(), &node_msg->reason_uid) - < 0) { + if (uid_from_string(getlogin(), + &node_msg->reason_uid) < 0) node_msg->reason_uid = getuid(); - } + } - if(slurm_update_node(node_msg) - == SLURM_SUCCESS) { + if((rc = slurm_update_node(node_msg)) == SLURM_SUCCESS) { lower = g_strdup_printf( "Nodes %s updated successfully.", nodelist); display_edit_note(lower); g_free(lower); - } else { lower = g_strdup_printf( - "Problem updating nodes %s.", - nodelist); + "Problem updating nodes %s: %s", + nodelist, slurm_strerror(rc)); display_edit_note(lower); g_free(lower); } @@ -1012,7 +1069,7 @@ extern GtkListStore *create_model_node(int type) int i=0; switch(type) { - case SORTID_STATE: + case SORTID_STATE: model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); gtk_list_store_append(model, &iter); @@ -1093,20 +1150,21 @@ extern void get_info_node(GtkTable *table, display_data_t *display_data) int i = 0; sview_node_info_t *sview_node_info_ptr = NULL; ListIterator itr = NULL; + GtkTreePath *path = NULL; /* reset */ if(!table && !display_data) { if(display_widget) gtk_widget_destroy(display_widget); display_widget = NULL; - return; + goto reset_curs; } if(display_data) local_display_data = display_data; if(!table) { display_data_node->set_menu = local_display_data->set_menu; - return; + goto reset_curs; } if(display_widget && toggled) { gtk_widget_destroy(display_widget); @@ -1134,19 +1192,33 @@ extern void get_info_node(GtkTable *table, display_data_t *display_data) goto end_it; } display_it: - info_list = create_node_info_list(node_info_ptr, changed); + + info_list = create_node_info_list(node_info_ptr, changed, TRUE); if(!info_list) - return; + goto reset_curs; i=0; /* set up the grid */ - itr = list_iterator_create(info_list); - while ((sview_node_info_ptr = list_next(itr))) { - change_grid_color(grid_button_list, i, i, i, true, 0); - i++; + if(display_widget && GTK_IS_TREE_VIEW(display_widget) + && gtk_tree_selection_count_selected_rows( + gtk_tree_view_get_selection( + GTK_TREE_VIEW(display_widget)))) { + GtkTreeViewColumn *focus_column = NULL; + /* highlight the correct nodes from the last selection */ + gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget), + &path, &focus_column); } - list_iterator_destroy(itr); - change_grid_color(grid_button_list, -1, -1, MAKE_WHITE, true, 0); + if(!path) { + itr = list_iterator_create(info_list); + while ((sview_node_info_ptr = list_next(itr))) { + change_grid_color(grid_button_list, i, i, i, true, 0); + i++; + } + list_iterator_destroy(itr); + } else + highlight_grid(GTK_TREE_VIEW(display_widget), + SORTID_POS, (int)NO_VAL, grid_button_list); + if(working_sview_config.grid_speedup) { gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); @@ -1159,7 +1231,10 @@ display_it: if(!display_widget) { tree_view = create_treeview(local_display_data, &grid_button_list); - + /*set multiple capability here*/ + gtk_tree_selection_set_mode( + gtk_tree_view_get_selection(tree_view), + GTK_SELECTION_MULTIPLE); display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(tree_view), @@ -1175,6 +1250,9 @@ display_it: end_it: toggled = FALSE; force_refresh = 1; +reset_curs: + if (main_window && main_window->window) + gdk_window_set_cursor(main_window->window, NULL); return; } @@ -1230,7 +1308,7 @@ extern void specific_info_node(popup_info_t *popup_win) return; } display_it: - info_list = create_node_info_list(node_info_ptr, changed); + info_list = create_node_info_list(node_info_ptr, changed, TRUE); if(!info_list) return; @@ -1242,7 +1320,10 @@ display_it: if(spec_info->type != INFO_PAGE && !spec_info->display_widget) { tree_view = create_treeview(local_display_data, &popup_win->grid_button_list); - + /*set multiple capability here*/ + gtk_tree_selection_set_mode( + gtk_tree_view_get_selection(tree_view), + GTK_SELECTION_MULTIPLE); spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); gtk_table_attach_defaults(popup_win->table, @@ -1380,13 +1461,11 @@ extern void set_menus_node(void *arg, void *arg2, GtkTreePath *path, int type) { GtkTreeModel *model = gtk_tree_view_get_model(tree_view); GtkTreeIter iter; - int node_inx = 0; if (!gtk_tree_model_get_iter(model, &iter, path)) { g_error("error getting iter from model\n"); break; } - gtk_tree_model_get(model, &iter, SORTID_POS, &node_inx, -1); - highlight_grid_range(node_inx, node_inx, button_list); + highlight_grid(tree_view, SORTID_POS, (int)NO_VAL, button_list); break; } case FULL_CLICKED: @@ -1416,6 +1495,8 @@ extern void popup_all_node(GtkTreeModel *model, GtkTreeIter *iter, int id) char *name = NULL; gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1); + if(_DEBUG) + g_print("popup_all_node: name = %s\n", name); popup_all_node_name(name, id); /* this name gets g_strdup'ed in the previous function */ g_free(name); @@ -1484,24 +1565,6 @@ extern void popup_all_node_name(char *name, int id) gtk_window_present(GTK_WINDOW(popup_win->popup)); } -static void _selected_page(GtkMenuItem *menuitem, - display_data_t *display_data) -{ - switch(display_data->extra) { - case NODE_PAGE: - popup_all_node_name(display_data->user_data, display_data->id); - break; - case ADMIN_PAGE: - admin_node_name(display_data->user_data, - NULL, display_data->name); - break; - default: - g_print("node got %d %d\n", display_data->extra, - display_data->id); - } - -} - extern void admin_menu_node_name(char *name, GdkEventButton *event) { GtkMenu *menu = GTK_MENU(gtk_menu_new()); @@ -1523,33 +1586,56 @@ extern void admin_menu_node_name(char *name, GdkEventButton *event) } gtk_widget_show_all(GTK_WIDGET(menu)); gtk_menu_popup(menu, NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, + event ? event->button : 0, gdk_event_get_time((GdkEvent*)event)); } -extern void admin_node(GtkTreeModel *model, GtkTreeIter *iter, char *type) +extern void select_admin_nodes(GtkTreeModel *model, + GtkTreeIter *iter, + display_data_t *display_data, + uint32_t node_col, + GtkTreeView *treeview) { - char *name = NULL; - char *old_value = NULL; - - gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1); - if(!strcasecmp("Update Features", type)) { /* get old features */ - gtk_tree_model_get(model, iter, SORTID_FEATURES, - &old_value, -1); - } else if(!strcasecmp("Update Gres", type)) { /* get old gres */ - gtk_tree_model_get(model, iter, SORTID_GRES, - &old_value, -1); - } - - admin_node_name(name, old_value, type); + if(treeview) { + char *old_value = NULL; + char tmp[1024]; + hostlist_t hl = NULL; + process_node_t process_node; + memset(&process_node, 0, sizeof(process_node_t)); + if(node_col == NO_VAL) + process_node.node_col = SORTID_NAME; + else + process_node.node_col = node_col; + + gtk_tree_selection_selected_foreach( + gtk_tree_view_get_selection(treeview), + _process_each_node, &process_node); + hl = hostlist_create(process_node.nodelist); + hostlist_uniq(hl); + hostlist_sort(hl); + xfree(process_node.nodelist); + hostlist_ranged_string(hl, sizeof(tmp), tmp); + process_node.nodelist = xstrdup(tmp); + hostlist_destroy(hl); + + if(!strcasecmp("Update Features", display_data->name)) { + /* get old features */ + gtk_tree_model_get(model, iter, SORTID_FEATURES, + &old_value, -1); + } else if(!strcasecmp("Update Gres", display_data->name)) { + /* get old gres */ + gtk_tree_model_get(model, iter, SORTID_GRES, + &old_value, -1); + } + admin_node_name(process_node.nodelist, old_value, + display_data->name); + xfree(process_node.nodelist); + if(old_value) + g_free(old_value); - if(name) - g_free(name); - if(old_value) - g_free(old_value); - return; -} + } +} /*select_admin_nodes ^^^*/ extern void admin_node_name(char *name, char *old_value, char *type) { @@ -1560,7 +1646,10 @@ extern void admin_node_name(char *name, char *old_value, char *type) NULL); gtk_window_set_transient_for(GTK_WINDOW(popup), NULL); - if(!strcasecmp("Update Features", type)) { /* update features */ + if(!strcasecmp("Update Features", type) + || !strcasecmp("Update Node Features", type) + || !strcasecmp("Update Base Partition Features", + type)) { /* update features */ update_features_node(GTK_DIALOG(popup), name, old_value); } else if(!strcasecmp("Update Gres", type)) { /* update gres */ update_gres_node(GTK_DIALOG(popup), name, old_value); diff --git a/src/sview/part_info.c b/src/sview/part_info.c index 7effd656e2b127ca98b5c6be0cb3ab849ce85d17..96fd63d20576eba5cf23b213675d051be7e601f7 100644 --- a/src/sview/part_info.c +++ b/src/sview/part_info.c @@ -182,20 +182,27 @@ static display_data_t options_data_part[] = { {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE}, {G_TYPE_STRING, INFO_PAGE, "Full Info", TRUE, PART_PAGE}, #ifdef HAVE_BG - {G_TYPE_STRING, PART_PAGE, "Drain Base Partitions", TRUE, ADMIN_PAGE}, - {G_TYPE_STRING, PART_PAGE, "Resume Base Partitions", TRUE, ADMIN_PAGE}, + {G_TYPE_STRING, PART_PAGE, "Drain Base Partitions", + TRUE, ADMIN_PAGE | EXTRA_NODES}, + {G_TYPE_STRING, PART_PAGE, "Resume Base Partitions", + TRUE, ADMIN_PAGE | EXTRA_NODES}, {G_TYPE_STRING, PART_PAGE, "Put Base Partitions Down", - TRUE, ADMIN_PAGE}, + TRUE, ADMIN_PAGE | EXTRA_NODES}, {G_TYPE_STRING, PART_PAGE, "Make Base Partitions Idle", - TRUE, ADMIN_PAGE}, + TRUE, ADMIN_PAGE | EXTRA_NODES}, {G_TYPE_STRING, PART_PAGE, "Update Base Partition Features", - TRUE, ADMIN_PAGE}, + TRUE, ADMIN_PAGE | EXTRA_NODES}, #else - {G_TYPE_STRING, PART_PAGE, "Drain Nodes", TRUE, ADMIN_PAGE}, - {G_TYPE_STRING, PART_PAGE, "Resume Nodes", TRUE, ADMIN_PAGE}, - {G_TYPE_STRING, PART_PAGE, "Put Nodes Down", TRUE, ADMIN_PAGE}, - {G_TYPE_STRING, PART_PAGE, "Make Nodes Idle", TRUE, ADMIN_PAGE}, - {G_TYPE_STRING, PART_PAGE, "Update Node Features", TRUE, ADMIN_PAGE}, + {G_TYPE_STRING, PART_PAGE, "Drain Nodes", + TRUE, ADMIN_PAGE | EXTRA_NODES}, + {G_TYPE_STRING, PART_PAGE, "Resume Nodes", + TRUE, ADMIN_PAGE | EXTRA_NODES}, + {G_TYPE_STRING, PART_PAGE, "Put Nodes Down", + TRUE, ADMIN_PAGE | EXTRA_NODES}, + {G_TYPE_STRING, PART_PAGE, "Make Nodes Idle", + TRUE, ADMIN_PAGE | EXTRA_NODES}, + {G_TYPE_STRING, PART_PAGE, "Update Node Features", + TRUE, ADMIN_PAGE | EXTRA_NODES}, #endif {G_TYPE_STRING, PART_PAGE, "Change Part State", TRUE, ADMIN_PAGE}, @@ -855,8 +862,8 @@ static void _layout_part_record(GtkTreeView *treeview, break; case SORTID_JOB_SIZE: _build_min_max_32_string(time_buf, sizeof(time_buf), - part_ptr->min_nodes, - part_ptr->max_nodes, true); + part_ptr->min_nodes, + part_ptr->max_nodes, true); temp_char = time_buf; break; case SORTID_MEM: @@ -1039,8 +1046,8 @@ static void _update_part_record(sview_part_info_t *sview_part_info, gtk_tree_store_set(treestore, iter, SORTID_TIMELIMIT, time_buf, -1); _build_min_max_32_string(time_buf, sizeof(time_buf), - part_ptr->min_nodes, - part_ptr->max_nodes, true); + part_ptr->min_nodes, + part_ptr->max_nodes, true); gtk_tree_store_set(treestore, iter, SORTID_JOB_SIZE, time_buf, -1); tmp_uint16 = part_ptr->preempt_mode; @@ -1477,7 +1484,7 @@ static int _insert_sview_part_sub(sview_part_info_t *sview_part_info, if(!sview_part_sub) { if((sview_part_sub = _create_sview_part_sub( - part_ptr, node_ptr, node_scaling))) + part_ptr, node_ptr, node_scaling))) list_push(sview_part_info->sub_list, sview_part_sub); } @@ -1560,7 +1567,10 @@ static List _create_part_info_list(partition_info_msg_t *part_info_ptr, for (i=0; i<part_info_ptr->record_count; i++) { part_ptr = &(part_info_ptr->partition_array[i]); - + /*dont include configured excludes*/ + if (strstr(excluded_partitions, + part_info_ptr->partition_array[i].name)) + continue; sview_part_info = _create_sview_part_info(part_ptr); list_append(info_list, sview_part_info); sview_part_info->color_inx = i % sview_colors_cnt; @@ -1588,7 +1598,7 @@ static List _create_part_info_list(partition_info_msg_t *part_info_ptr, return info_list; } -void _display_info_part(List info_list, popup_info_t *popup_win) +static void _display_info_part(List info_list, popup_info_t *popup_win) { specific_info_t *spec_info = popup_win->spec_info; char *name = (char *)spec_info->search_info->gchar_data; @@ -1670,12 +1680,66 @@ finished: return; } +static void _process_each_partition(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer userdata) +{ + char *type = userdata; + if (_DEBUG) + g_print("process_each_partition: global_multi_error = %d\n", + global_multi_error); + + if (!global_multi_error) { + admin_part(model, iter, type); + } +} +/*process_each_partition ^^^*/ + +extern bool check_part_includes_node(partition_info_msg_t *part_info_ptr, + int node_dx) +{ + partition_info_t *part_ptr = NULL; + bool rc = FALSE; + int i, j2; + + for (i=0; i<part_info_ptr->record_count; i++) { + /*dont include configured excludes*/ + if (strstr(excluded_partitions, + part_info_ptr->partition_array[i].name)) + continue; + part_ptr = &(part_info_ptr->partition_array[i]); + j2 = 0; + while(part_ptr->node_inx[j2] >= 0) { + if (_DEBUG) { + g_print("node_dx = %d ", node_dx); + g_print("part_node_inx[j2] = %d ", + part_ptr->node_inx[j2]); + g_print("part_node_inx[j2+1] = %d \n", + part_ptr->node_inx[j2+1]); + } + if (node_dx >= part_ptr->node_inx[j2] && + node_dx <= part_ptr->node_inx[j2+1]) { + rc = TRUE; + if (_DEBUG) + g_print("hit!!\n"); + } + break; + j2 += 2; + } + if (rc) + break; + } + return rc; +} + + extern void refresh_part(GtkAction *action, gpointer user_data) { popup_info_t *popup_win = (popup_info_t *)user_data; - xassert(popup_win != NULL); - xassert(popup_win->spec_info != NULL); - xassert(popup_win->spec_info->title != NULL); + xassert(popup_win); + xassert(popup_win->spec_info); + xassert(popup_win->spec_info->title); popup_win->force_refresh = 1; specific_info_part(popup_win); } @@ -1696,8 +1760,8 @@ extern int get_new_info_part(partition_info_msg_t **part_ptr, int force) error_code = SLURM_SUCCESS; *part_ptr = g_part_info_ptr; if(changed) - return SLURM_SUCCESS; - return error_code; + error_code = SLURM_SUCCESS; + goto end_it; } last = now; @@ -1715,9 +1779,10 @@ extern int get_new_info_part(partition_info_msg_t **part_ptr, int force) } else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) { error_code = SLURM_NO_CHANGE_IN_DATA; new_part_ptr = g_part_info_ptr; - changed = 0; + changed = 0; } } else { + new_part_ptr = NULL; error_code = slurm_load_partitions((time_t) NULL, &new_part_ptr, show_flags); changed = 1; @@ -1730,6 +1795,7 @@ extern int get_new_info_part(partition_info_msg_t **part_ptr, int force) error_code = SLURM_SUCCESS; *part_ptr = new_part_ptr; +end_it: return error_code; } @@ -1971,14 +2037,14 @@ extern void get_info_part(GtkTable *table, display_data_t *display_data) display_widget = NULL; part_info_ptr = NULL; node_info_ptr = NULL; - return; + goto reset_curs; } if(display_data) local_display_data = display_data; if(!table) { display_data_part->set_menu = local_display_data->set_menu; - return; + goto reset_curs; } if(display_widget && toggled) { gtk_widget_destroy(display_widget); @@ -1996,7 +2062,7 @@ extern void get_info_part(GtkTable *table, display_data_t *display_data) gtk_widget_destroy(display_widget); view = ERROR_VIEW; snprintf(error_char, 100, "slurm_load_partitions: %s", - slurm_strerror(slurm_get_errno())); + slurm_strerror(slurm_get_errno())); label = gtk_label_new(error_char); display_widget = gtk_widget_ref(GTK_WIDGET(label)); gtk_table_attach_defaults(table, label, 0, 1, 0, 1); @@ -2017,7 +2083,7 @@ extern void get_info_part(GtkTable *table, display_data_t *display_data) gtk_widget_destroy(display_widget); view = ERROR_VIEW; snprintf(error_char, 100, "slurm_load_node: %s", - slurm_strerror(slurm_get_errno())); + slurm_strerror(slurm_get_errno())); label = gtk_label_new(error_char); display_widget = gtk_widget_ref(GTK_WIDGET(label)); gtk_table_attach_defaults(table, label, 0, 1, 0, 1); @@ -2031,7 +2097,7 @@ display_it: node_info_ptr, changed); if(!info_list) - return; + goto reset_curs; /* set up the grid */ if(display_widget && GTK_IS_TREE_VIEW(display_widget) @@ -2058,8 +2124,19 @@ display_it: } } list_iterator_destroy(itr); + change_grid_color(grid_button_list, -1, -1, + MAKE_WHITE, true, 0); + } else + highlight_grid(GTK_TREE_VIEW(display_widget), + SORTID_NODE_INX, SORTID_COLOR_INX, + grid_button_list); + + if(working_sview_config.grid_speedup) { + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); } + if(view == ERROR_VIEW && display_widget) { gtk_widget_destroy(display_widget); display_widget = NULL; @@ -2067,7 +2144,10 @@ display_it: if(!display_widget) { tree_view = create_treeview(local_display_data, &grid_button_list); - + /*set multiple capability here*/ + gtk_tree_selection_set_mode( + gtk_tree_view_get_selection(tree_view), + GTK_SELECTION_MULTIPLE); display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); gtk_table_attach_defaults(table, GTK_WIDGET(tree_view), @@ -2079,25 +2159,15 @@ display_it: SORTID_CNT, SORTID_NAME, SORTID_COLOR); } - if(path) - highlight_grid(GTK_TREE_VIEW(display_widget), - SORTID_NODE_INX, SORTID_COLOR_INX, - grid_button_list); - else - change_grid_color(grid_button_list, -1, -1, - MAKE_WHITE, true, 0); - if(working_sview_config.grid_speedup) { - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); - } - view = INFO_VIEW; _update_info_part(info_list, GTK_TREE_VIEW(display_widget)); end_it: toggled = FALSE; force_refresh = FALSE; - - return; +reset_curs: + if (main_window && main_window->window) + gdk_window_set_cursor(main_window->window, NULL); + return; } extern void specific_info_part(popup_info_t *popup_win) @@ -2164,7 +2234,7 @@ extern void specific_info_part(popup_info_t *popup_win) gtk_widget_destroy(spec_info->display_widget); spec_info->view = ERROR_VIEW; snprintf(error_char, 100, "slurm_load_node: %s", - slurm_strerror(slurm_get_errno())); + slurm_strerror(slurm_get_errno())); label = gtk_label_new(error_char); spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(label)); gtk_table_attach_defaults(popup_win->table, label, 0, 1, 0, 1); @@ -2188,6 +2258,10 @@ display_it: if(spec_info->type != INFO_PAGE && !spec_info->display_widget) { tree_view = create_treeview(local_display_data, &popup_win->grid_button_list); + /*set multiple capability here*/ + gtk_tree_selection_set_mode( + gtk_tree_view_get_selection(tree_view), + GTK_SELECTION_MULTIPLE); spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); @@ -2469,15 +2543,34 @@ extern void popup_all_part(GtkTreeModel *model, GtkTreeIter *iter, int id) } } +extern void select_admin_partitions(GtkTreeModel *model, + GtkTreeIter *iter, + display_data_t *display_data, + GtkTreeView *treeview) +{ + if(treeview) { + if(display_data->extra & EXTRA_NODES) { + select_admin_nodes(model, iter, display_data, + SORTID_NODELIST, treeview); + return; + } + global_multi_error = FALSE; + gtk_tree_selection_selected_foreach( + gtk_tree_view_get_selection(treeview), + _process_each_partition, display_data->name); + } +} /*select_admin_partitions ^^^*/ + + extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type) { - update_part_msg_t *part_msg = xmalloc(sizeof(update_part_msg_t)); - char *partid = NULL; char *nodelist = NULL; - char tmp_char[100]; - char *temp = NULL; + char *partid = NULL; + update_part_msg_t *part_msg = xmalloc(sizeof(update_part_msg_t)); int edit_type = 0; int response = 0; + char tmp_char[100]; + char *temp = NULL; GtkWidget *label = NULL; GtkWidget *entry = NULL; GtkWidget *popup = gtk_dialog_new_with_buttons( @@ -2573,19 +2666,21 @@ extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type) response = gtk_dialog_run (GTK_DIALOG(popup)); if (response == GTK_RESPONSE_OK) { + int rc; if(global_edit_error) temp = global_edit_error_msg; else if(!global_send_update_msg) { temp = g_strdup_printf("No change detected."); - } else if(slurm_update_partition(part_msg) + } else if((rc = slurm_update_partition(part_msg)) == SLURM_SUCCESS) { temp = g_strdup_printf( "Partition %s updated successfully", partid); } else { temp = g_strdup_printf( - "Problem updating partition %s.", - partid); + "Problem updating partition %s: %s", + partid, slurm_strerror(rc)); + global_multi_error = TRUE; } display_edit_note(temp); g_free(temp); diff --git a/src/sview/popups.c b/src/sview/popups.c index 14bc883c99f06b5ceb712042c476b1e4e2cfb2ac..4a18904cd651ee46aa66a00569be3de78ae34e84 100644 --- a/src/sview/popups.c +++ b/src/sview/popups.c @@ -260,7 +260,7 @@ static void _layout_conf_ctl(GtkTreeStore *treestore, add_display_treestore_line(update, treestore, &iter, "", NULL); add_display_treestore_line_with_font(update, treestore, &iter, - select_title, NULL, "bold"); + select_title, NULL, "bold"); itr = list_iterator_create( (List)slurm_ctl_conf_ptr->select_conf_key_pairs); while((key_pair = list_next(itr))) { diff --git a/src/sview/resv_info.c b/src/sview/resv_info.c index 3a5341a0ce01f66dd9127e0253399969912d0920..906289f1b8a1eb3c65131e8cedefbe21087794a8 100644 --- a/src/sview/resv_info.c +++ b/src/sview/resv_info.c @@ -523,7 +523,7 @@ static void _update_resv_record(sview_resv_info_t *sview_resv_info_ptr, SORTID_ACCOUNTS, resv_ptr->accounts, -1); secs2time_str((uint32_t)difftime(resv_ptr->end_time, - resv_ptr->start_time), + resv_ptr->start_time), tmp_char, sizeof(tmp_char)); gtk_tree_store_set(treestore, iter, SORTID_DURATION, tmp_char, -1); @@ -782,9 +782,9 @@ finished: extern void refresh_resv(GtkAction *action, gpointer user_data) { popup_info_t *popup_win = (popup_info_t *)user_data; - xassert(popup_win != NULL); - xassert(popup_win->spec_info != NULL); - xassert(popup_win->spec_info->title != NULL); + xassert(popup_win); + xassert(popup_win->spec_info); + xassert(popup_win->spec_info->title); popup_win->force_refresh = 1; specific_info_resv(popup_win); } @@ -804,8 +804,8 @@ extern int get_new_info_resv(reserve_info_msg_t **info_ptr, error_code = SLURM_SUCCESS; *info_ptr = g_resv_info_ptr; if(changed) - return SLURM_SUCCESS; - return error_code; + error_code = SLURM_SUCCESS; + goto end_it; } last = now; if (g_resv_info_ptr) { @@ -820,6 +820,7 @@ extern int get_new_info_resv(reserve_info_msg_t **info_ptr, changed = 0; } } else { + new_resv_ptr = NULL; error_code = slurm_load_reservations((time_t) NULL, &new_resv_ptr); changed = 1; @@ -831,6 +832,7 @@ extern int get_new_info_resv(reserve_info_msg_t **info_ptr, error_code = SLURM_SUCCESS; *info_ptr = g_resv_info_ptr; +end_it: return error_code; } @@ -958,14 +960,14 @@ extern void get_info_resv(GtkTable *table, display_data_t *display_data) gtk_widget_destroy(display_widget); display_widget = NULL; resv_info_ptr = NULL; - return; + goto reset_curs; } if(display_data) local_display_data = display_data; if(!table) { display_data_resv->set_menu = local_display_data->set_menu; - return; + goto reset_curs; } if(display_widget && toggled) { gtk_widget_destroy(display_widget); @@ -994,7 +996,7 @@ extern void get_info_resv(GtkTable *table, display_data_t *display_data) display_it: info_list = _create_resv_info_list(resv_info_ptr, changed); if(!info_list) - return; + goto reset_curs; /* set up the grid */ if(display_widget && GTK_IS_TREE_VIEW(display_widget) && gtk_tree_selection_count_selected_rows( @@ -1024,6 +1026,16 @@ display_it: } } list_iterator_destroy(itr); + change_grid_color(grid_button_list, -1, -1, + MAKE_WHITE, true, 0); + } else + highlight_grid(GTK_TREE_VIEW(display_widget), + SORTID_NODE_INX, SORTID_COLOR_INX, + grid_button_list); + + if(working_sview_config.grid_speedup) { + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); + gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); } if(view == ERROR_VIEW && display_widget) { @@ -1045,24 +1057,14 @@ display_it: SORTID_CNT, SORTID_TIME_START, SORTID_COLOR); } - if(path) - highlight_grid(GTK_TREE_VIEW(display_widget), - SORTID_NODE_INX, SORTID_COLOR_INX, - grid_button_list); - else - change_grid_color(grid_button_list, -1, -1, - MAKE_WHITE, true, 0); - if(working_sview_config.grid_speedup) { - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 0); - gtk_widget_set_sensitive(GTK_WIDGET(main_grid_table), 1); - } - view = INFO_VIEW; _update_info_resv(info_list, GTK_TREE_VIEW(display_widget)); end_it: toggled = FALSE; force_refresh = FALSE; - +reset_curs: + if (main_window && main_window->window) + gdk_window_set_cursor(main_window->window, NULL); return; } @@ -1200,12 +1202,12 @@ display_it: list_push(send_resv_list, sview_resv_info_ptr); j=0; while(resv_ptr->node_inx[j] >= 0) { - change_grid_color( - popup_win->grid_button_list, - resv_ptr->node_inx[j], - resv_ptr->node_inx[j+1], - sview_resv_info_ptr->color_inx, - true, 0); + change_grid_color( + popup_win->grid_button_list, + resv_ptr->node_inx[j], + resv_ptr->node_inx[j+1], + sview_resv_info_ptr->color_inx, + true, 0); j += 2; } } @@ -1391,10 +1393,10 @@ extern void admin_resv(GtkTreeModel *model, GtkTreeIter *iter, char *type) gtk_dialog_add_button(GTK_DIALOG(popup), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - snprintf(tmp_char, sizeof(tmp_char), - "Are you sure you want to remove " - "reservation %s?", - resvid); + snprintf(tmp_char, sizeof(tmp_char), + "Are you sure you want to remove " + "reservation %s?", + resvid); label = gtk_label_new(tmp_char); edit_type = EDIT_REMOVE; } else { diff --git a/src/sview/sview.c b/src/sview/sview.c index 52b2b3bf19b245e419ab70f5579c3f059a783d5e..43ddd1034c8ec9f83c5e0d9b1b59b0a3b9994587 100644 --- a/src/sview/sview.c +++ b/src/sview/sview.c @@ -63,10 +63,10 @@ bool global_entry_changed = 0; bool global_send_update_msg = 0; bool global_edit_error = 0; int global_error_code = 0; -int global_multi_count = 0; +int global_row_count = 0; +bool global_multi_error = 0; gint last_event_x = 0; gint last_event_y = 0; -GdkCursor* standard_cursor; GdkCursor* in_process_cursor; gchar *global_edit_error_msg = NULL; GtkWidget *main_notebook = NULL; @@ -80,6 +80,8 @@ GCond *grid_cond = NULL; uint32_t cluster_flags; int cluster_dims; List cluster_list = NULL; +switch_record_bitmaps_t *g_switch_nodes_maps = NULL; +char *excluded_partitions = NULL; block_info_msg_t *g_block_info_ptr = NULL; job_info_msg_t *g_job_info_ptr = NULL; @@ -88,6 +90,7 @@ partition_info_msg_t *g_part_info_ptr = NULL; reserve_info_msg_t *g_resv_info_ptr = NULL; slurm_ctl_conf_info_msg_t *g_ctl_info_ptr = NULL; job_step_info_response_msg_t *g_step_info_ptr = NULL; +topo_info_response_msg_t *g_topo_info_msg_ptr = NULL; static GtkActionGroup *admin_action_group = NULL; static GtkActionGroup *menu_action_group = NULL; @@ -260,6 +263,11 @@ static void _page_switched(GtkNotebook *notebook, GError *error = NULL; static int started_grid_init = 0; + + /*set spinning cursor while loading*/ + if (main_window->window && (page_num != TAB_PAGE)) + gdk_window_set_cursor(main_window->window, in_process_cursor); + /* make sure we aren't adding the page, and really asking for info */ if(adding) return; @@ -460,10 +468,25 @@ static void _init_pages() } } +static void _persist_dynamics() +{ + + gint g_x; + gint g_y; + + gtk_window_get_size(GTK_WINDOW(main_window), &g_x, &g_y); + + default_sview_config.main_width = g_x; + default_sview_config.main_height = g_y; + + save_defaults(); +} + static gboolean _delete(GtkWidget *widget, GtkWidget *event, gpointer data) { + _persist_dynamics(); fini = 1; gtk_main_quit(); ba_fini(); @@ -719,12 +742,12 @@ static GtkWidget *_get_menubar_menu(GtkWidget *window, GtkWidget *notebook) G_N_ELEMENTS(entries), window); //if(cluster_flags & CLUSTER_FLAG_BG) - gtk_action_group_add_actions(menu_action_group, bg_entries, - G_N_ELEMENTS(bg_entries), window); - //else - gtk_action_group_add_actions(menu_action_group, nonbg_entries, - G_N_ELEMENTS(nonbg_entries), - window); + gtk_action_group_add_actions(menu_action_group, bg_entries, + G_N_ELEMENTS(bg_entries), window); + //else + gtk_action_group_add_actions(menu_action_group, nonbg_entries, + G_N_ELEMENTS(nonbg_entries), + window); gtk_action_group_add_radio_actions(menu_action_group, radio_entries, G_N_ELEMENTS(radio_entries), @@ -891,6 +914,8 @@ extern void _change_cluster_main(GtkComboBox *combo, gpointer extra) g_ctl_info_ptr = NULL; slurm_free_job_step_info_response_msg(g_step_info_ptr); g_step_info_ptr = NULL; + slurm_free_topo_info_msg(g_topo_info_msg_ptr); + g_topo_info_msg_ptr = NULL; /* set up working_cluster_rec */ if(cluster_dims > 1) { @@ -971,7 +996,10 @@ extern void _change_cluster_main(GtkComboBox *combo, gpointer extra) list_flush(popup_list); if(signal_params_list) list_flush(signal_params_list); - + if(signal_params_list) + list_flush(signal_params_list); + if (g_switch_nodes_maps) + slurm_free_switch_nodes_maps(g_switch_nodes_maps); /* change the node tab name if needed */ #ifdef GTK2_USE_GET_FOCUS node_tab = gtk_notebook_get_nth_page( @@ -1203,7 +1231,9 @@ int main(int argc, char *argv[]) G_CALLBACK(_delete), NULL); gtk_window_set_title(GTK_WINDOW(main_window), "Sview"); - gtk_window_set_default_size(GTK_WINDOW(main_window), 1000, 450); + gtk_window_set_default_size(GTK_WINDOW(main_window), + working_sview_config.main_width, + working_sview_config.main_height); gtk_container_set_border_width( GTK_CONTAINER(GTK_DIALOG(main_window)->vbox), 1); /* Create the main notebook, place the position of the tabs */ @@ -1244,12 +1274,11 @@ int main(int argc, char *argv[]) gtk_table_attach_defaults(GTK_TABLE(table), main_notebook, 1, 2, 0, 1); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(main_window)->vbox), - table, TRUE, TRUE, 0); + table, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(main_window)->vbox), - main_statusbar, FALSE, FALSE, 0); + main_statusbar, FALSE, FALSE, 0); in_process_cursor = gdk_cursor_new(GDK_WATCH); - standard_cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW); for(i=0; i<PAGE_CNT; i++) { if(main_display_data[i].id == -1) diff --git a/src/sview/sview.h b/src/sview/sview.h index 24745bf0bdbb91b6bf1fffedc23c02bc92689a7a..3cfecc5508aafa3b07f1514d5db3bdaf7bfcc543 100644 --- a/src/sview/sview.h +++ b/src/sview/sview.h @@ -97,6 +97,10 @@ #define MAKE_BLACK -2 #define MAKE_WHITE -1 +#define EXTRA_BASE 0x0000ffff +#define EXTRA_FLAGS 0xffff0000 +#define EXTRA_NODES 0x00010000 + enum { JOB_PAGE, PART_PAGE, RESV_PAGE, @@ -150,6 +154,10 @@ typedef enum { SEARCH_JOB_ID = 1, SEARCH_RESERVATION_NAME, } sview_search_type_t; +typedef struct { + char *nodes; + bitstr_t *node_bitmap; +} switch_record_bitmaps_t; /* Input parameters */ typedef struct { @@ -159,10 +167,15 @@ typedef struct { bool grid_speedup; uint32_t grid_vert; uint32_t grid_x_width; + uint32_t main_width; + uint32_t main_height; + uint32_t fi_popup_width; + uint32_t fi_popup_height; GtkWidget *page_check_widget[PAGE_CNT]; bool page_visible[PAGE_CNT]; uint16_t refresh_delay; bool show_grid; + bool grid_topological; bool show_hidden; bool ruled_treeview; GtkToggleAction *action_admin; @@ -182,7 +195,7 @@ struct display_data { int id; char *name; bool show; - int extra; + uint32_t extra; void (*refresh) (GtkAction *action, gpointer user_data); GtkListStore *(*create_model)(int type); void (*admin_edit) (GtkCellRendererText *cell, @@ -284,6 +297,7 @@ extern List signal_params_list; extern bool global_entry_changed; extern bool global_send_update_msg; extern bool global_edit_error; +extern bool global_multi_error; extern int global_error_code; extern gchar *global_edit_error_msg; extern GtkWidget *main_notebook; @@ -291,11 +305,10 @@ extern GtkWidget *main_statusbar; extern GtkWidget *main_window; extern GtkTable *main_grid_table; extern GStaticMutex sview_mutex; -extern int global_multi_count; +extern int global_row_count; extern gint last_event_x; extern gint last_event_y; extern GdkCursor* in_process_cursor; -extern GdkCursor* standard_cursor; extern int cpus_per_node; extern int g_node_scaling; extern char *sview_colors[]; @@ -303,7 +316,6 @@ extern int sview_colors_cnt; extern uint32_t cluster_flags; extern int cluster_dims; extern List cluster_list; - extern block_info_msg_t *g_block_info_ptr; extern job_info_msg_t *g_job_info_ptr; extern node_info_msg_t *g_node_info_ptr; @@ -311,6 +323,9 @@ extern partition_info_msg_t *g_part_info_ptr; extern reserve_info_msg_t *g_resv_info_ptr; extern slurm_ctl_conf_info_msg_t *g_ctl_info_ptr; extern job_step_info_response_msg_t *g_step_info_ptr; +extern topo_info_response_msg_t *g_topo_info_msg_ptr; +extern switch_record_bitmaps_t *g_switch_nodes_maps; + extern void init_grid(node_info_msg_t *node_info_ptr); extern int set_grid(int start, int end, int count); @@ -366,6 +381,8 @@ extern void setup_popup_grid_list(popup_info_t *popup_win); extern void post_setup_popup_grid_list(popup_info_t *popup_win); // part_info.c +extern bool check_part_includes_node(partition_info_msg_t *part_info_ptr, + int node_dx); extern void refresh_part(GtkAction *action, gpointer user_data); extern GtkListStore *create_model_part(int type); extern void admin_edit_part(GtkCellRendererText *cell, @@ -377,8 +394,12 @@ extern void get_info_part(GtkTable *table, display_data_t *display_data); extern void specific_info_part(popup_info_t *popup_win); extern void set_menus_part(void *arg, void *arg2, GtkTreePath *path, int type); extern void popup_all_part(GtkTreeModel *model, GtkTreeIter *iter, int id); +extern void select_admin_partitions(GtkTreeModel *model, GtkTreeIter *iter, + display_data_t *display_data, + GtkTreeView *treeview); extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type); extern void cluster_change_part(); +extern char *excluded_partitions; // block_info.c extern void refresh_block(GtkAction *action, gpointer user_data); @@ -411,18 +432,23 @@ extern void get_info_job(GtkTable *table, display_data_t *display_data); extern void specific_info_job(popup_info_t *popup_win); extern void set_menus_job(void *arg, void *arg2, GtkTreePath *path, int type); extern void popup_all_job(GtkTreeModel *model, GtkTreeIter *iter, int id); -extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, char *type,GtkTreeView *treeview); +extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, char *type, + GtkTreeView *treeview); extern void cluster_change_job(); // node_info.c extern void refresh_node(GtkAction *action, gpointer user_data); /* don't destroy the list from this function */ -extern List create_node_info_list(node_info_msg_t *node_info_ptr, int changed); +extern List create_node_info_list(node_info_msg_t *node_info_ptr, + int changed, bool by_partition); extern int update_features_node(GtkDialog *dialog, const char *nodelist, const char *old_features); extern int update_state_node(GtkDialog *dialog, const char *nodelist, const char *type); extern GtkListStore *create_model_node(int type); +extern void select_admin_nodes(GtkTreeModel *model, GtkTreeIter *iter, + display_data_t *display_data, uint32_t node_col, + GtkTreeView *treeview); extern void admin_edit_node(GtkCellRendererText *cell, const char *path_string, const char *new_text, @@ -463,6 +489,9 @@ extern void set_menus_submit(void *arg, void *arg2, extern int get_new_info_config(slurm_ctl_conf_info_msg_t **info_ptr); // common.c +extern void slurm_free_switch_nodes_maps(switch_record_bitmaps_t + * g_switch_nodes_maps); +extern int get_topo_conf(void); extern int get_row_number(GtkTreeView *tree_view, GtkTreePath *path); extern int find_col(display_data_t *display_data, int type); extern const char *find_col_name(display_data_t *display_data, int type); @@ -487,18 +516,19 @@ extern gboolean right_button_pressed(GtkTreeView *tree_view, GtkTreePath *path, int type); extern gboolean left_button_pressed(GtkTreeView *tree_view, GtkTreePath *path, - const signal_params_t *signal_params,GdkEventButton *event); + const signal_params_t *signal_params, + GdkEventButton *event); extern gboolean row_activated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, const signal_params_t *signal_params); extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event, const signal_params_t *signal_params); -extern gboolean key_pressed(GtkTreeView *tree_view, GdkEventButton *event, +extern gboolean key_pressed(GtkTreeView *tree_view, GdkEventKey *event, const signal_params_t *signal_params); extern gboolean focus_in(GtkTreeView *tree_view, GdkEventButton *event, - const signal_params_t *signal_params); -extern gboolean key_released(GtkTreeView *tree_view, GdkEventButton *event, - const signal_params_t *signal_params); + const signal_params_t *signal_params); +extern gboolean key_released(GtkTreeView *tree_view, GdkEventKey *event, + const signal_params_t *signal_params); extern popup_info_t *create_popup_info(int type, int dest_type, char *title); extern void setup_popup_info(popup_info_t *popup_win, display_data_t *display_data, @@ -512,6 +542,7 @@ extern void destroy_popup_info(void *arg); extern void destroy_signal_params(void *arg); extern gboolean delete_popup(GtkWidget *widget, GtkWidget *event, char *title); +extern gboolean delete_popups(); 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,