Newer
Older
/*****************************************************************************\
* common.c - common functions used by tabs in sview
*****************************************************************************
* Copyright (C) 2004-2007 The Regents of the University of California.
* Copyright (C) 2008-2009 Lawrence Livermore National Security.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@llnl.gov>
*

Moe Jette
committed
* CODE-OCEC-09-009. All rights reserved.

Danny Auble
committed
*
* This file is part of SLURM, a resource management program.
* For details, see <http://www.schedmd.com/slurmdocs/>.

Moe Jette
committed
* Please also read the included file: DISCLAIMER.

Danny Auble
committed
*
* SLURM is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.

Danny Auble
committed
*
* SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.

Danny Auble
committed
*
* You should have received a copy of the GNU General Public License along
* with SLURM; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#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;

Danny Auble
committed
GtkTreeView *treeview;
} treedata_t;

Danny Auble
committed
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_inx 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)
{
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++) {
if ((g_topo_info_msg_ptr->topo_array[i].nodes == NULL) ||
(g_topo_info_msg_ptr->topo_array[i].nodes[0] == '\0'))
continue;
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");
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
}
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)
{
each_t *each = userdata;
(each->display_data->set_menu)(each->tree_view, NULL, path,
FULL_CLICKED);
popup_pos.x = popup_pos.slider + popup_pos.cntr * 10;
popup_pos.y = popup_pos.cntr * 22;
popup_pos.cntr++;
if (popup_pos.cntr > 10) {
popup_pos.cntr = 1;
popup_pos.slider += 100;
}

Danny Auble
committed
/* 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)
{
menu_right_pressed = true;
return true;
}
return false;
}
static gboolean _menu_button_released(GtkWidget *widget, GdkEventButton *event,
gpointer extra)
{
return true;
menu_right_pressed = false;
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;
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);
break;
case GTK_RESPONSE_DELETE_EVENT: // exit
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;
}
return;
}
static int _sort_iter_compare_func_char(GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer userdata)
{
int sortcol = GPOINTER_TO_INT(userdata);
int ret = 0;
gchar *name1 = NULL, *name2 = NULL;

Danny Auble
committed
gtk_tree_model_get(model, a, sortcol, &name1, -1);
gtk_tree_model_get(model, b, sortcol, &name2, -1);

Danny Auble
committed
if (!name1 && !name2)
goto cleanup; /* both equal => ret = 0 */
else if (!name1 || !name2) {
ret = (name1 == NULL) ? -1 : 1;

Danny Auble
committed
} else {

Danny Auble
committed
/* sort like a human would
meaning snowflake2 would be greater than
snowflake12 */
len1 = strlen(name1);
len2 = strlen(name2);
while ((ret < len1) && (!g_ascii_isdigit(name1[ret])))
if (ret < len1) {
if (!g_ascii_strncasecmp(name1, name2, ret)) {
if (len1 > len2)
}
cleanup:
g_free(name1);
g_free(name2);

Danny Auble
committed
return ret;
}
static int _sort_iter_compare_func_int(GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer userdata)
{
int sortcol = GPOINTER_TO_INT(userdata);
int ret = 0;
gint int1, int2;
gtk_tree_model_get(model, a, sortcol, &int1, -1);
gtk_tree_model_get(model, b, sortcol, &int2, -1);

Danny Auble
committed
if (int1 != int2)
ret = (int1 > int2) ? 1 : -1;

Danny Auble
committed
return ret;
}
static int _sort_iter_compare_func_nodes(GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer userdata)
{
int sortcol = GPOINTER_TO_INT(userdata);
int ret = 0;
gchar *name1 = NULL, *name2 = NULL;

Danny Auble
committed
gtk_tree_model_get(model, a, sortcol, &name1, -1);
gtk_tree_model_get(model, b, sortcol, &name2, -1);

Danny Auble
committed
if (!name1 && !name2)
goto cleanup; /* both equal => ret = 0 */
else if (!name1 || !name2)
ret = (name1 == NULL) ? -1 : 1;
uint64_t int1=0, int2=0, tmp_int;
int spot=0;
/* If this is in a mixed state we need to get them all */
while (name1[spot]) {
while (name1[spot]
&& !g_ascii_isdigit(name1[spot])) {
break;
tmp_int = atoi(name1+spot);
while (name1[spot] && g_ascii_isdigit(name1[spot])) {

Danny Auble
committed
if (!name1[spot]) {
} else if (name1[spot] == 'K')
tmp_int *= 1048576;
tmp_int *= 1073741824;
int1 += tmp_int;
}
while (name2[spot]) {
while (name2[spot]
&& !g_ascii_isdigit(name2[spot])) {
break;
tmp_int = atoi(name2+spot);
while (name2[spot] && g_ascii_isdigit(name2[spot])) {
if (!name2[spot]) {
} else if (name2[spot] == 'K')
tmp_int *= 1048576;
tmp_int *= 1073741824;
int2 += tmp_int;
}
if (int1 != int2)

Danny Auble
committed
ret = (int1 > int2) ? 1 : -1;
}
cleanup:
g_free(name1);
g_free(name2);

Danny Auble
committed
return ret;
}
/* Translate a three-digit alpha-numeric value into it's
* base 36 equivalent number */
static int _xlate_bp_coord(const char *name)
{
int i, rc = 0;
for (i=0; i<cluster_dims; i++) {
rc *= 36;
rc += select_char2coord(name[i]);
}
return rc;
}

Danny Auble
committed
/* Make a BlueGene node name into a numeric representation of
* its location.
* Value is low_node_coordinate * 1,000 + I/O node (999 if none)
* with use of base 36 for the node coordinate:
* (e.g. bg123[4] -> 1,371,004
* bg[234x235] -> 2,704,999
* bglZZZ -> 46,655,999
*/
static int _bp_coordinate(const char *name)
{
int i, io_val = 999, low_val = -1;
for (i=0; name[i]; i++) {
if (name[i] == '[') {
i++;
if (low_val < 0)
low_val = _xlate_bp_coord(name+i);
else
io_val = atoi(name+i);
break;
} else if ((low_val < 0) &&
((name[i] >= '0' && (name[i] <= '9')) ||
(name[i] >= 'A' && (name[i] <= 'Z')))) {
low_val = _xlate_bp_coord(name+i);
i += 2;
}
if (low_val < 0)
return low_val;
return ((low_val * 1000) + io_val);
static int _sort_iter_compare_func_bp_list(GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer userdata)
{
int sortcol = GPOINTER_TO_INT(userdata);
int ret = 0;
gchar *name1 = NULL, *name2 = NULL;

Danny Auble
committed
gtk_tree_model_get(model, a, sortcol, &name1, -1);
gtk_tree_model_get(model, b, sortcol, &name2, -1);

Danny Auble
committed
if (!name1 && !name2)
goto cleanup; /* both equal => ret = 0 */
else if (!name1 || !name2)
ret = (name1 == NULL) ? -1 : 1;
/* Sort in numeric order based upon coordinates */
ret = _bp_coordinate(name1) - _bp_coordinate(name2);
}
cleanup:
g_free(name1);
g_free(name2);

Danny Auble
committed
return ret;
}
static void _editing_started(GtkCellRenderer *cell,
GtkCellEditable *editable,
const gchar *path,
gpointer data)
{
g_static_mutex_lock(&sview_mutex);
}
static void _editing_canceled(GtkCellRenderer *cell,
gpointer data)
{
g_static_mutex_unlock(&sview_mutex);
}

Danny Auble
committed
gtk_statusbar_remove(GTK_STATUSBAR(main_statusbar),

Danny Auble
committed
//gdk_flush();

Danny Auble
committed
return NULL;
static void _cell_data_func(GtkTreeViewColumn *col,
GtkCellRenderer *renderer,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
GdkPixbuf *pixbuf = NULL;
uint32_t color;
g_object_get(renderer, "pixbuf", &pixbuf, NULL);
return;
gtk_tree_model_get(model, iter,
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(renderer),
"column")),
&color_char, -1);
color_char2 = color_char+1;
color = strtoul(color_char2, (char **)&color_char2, 16);
/* we need to shift over 2 spots for the alpha */
gdk_pixbuf_fill(pixbuf, color << 8);
/* This only has to be done once, but I can't find any way to
* set something to only make it happen once. It only takes
* 3-5 usecs to do it so I didn't worry about it doing it
* multiple times. If you can figure out how to make this
* happen only once please fix, but the pointers for the col,
* renderer, and pixbuf are all the same. You could put in
* some think in the tree_model, but that seemed a bit more
* cumbersome. - da
*/
}

Danny Auble
committed
static void _add_col_to_treeview(GtkTreeView *tree_view,
display_data_t *display_data, int color_column)
GtkTreeViewColumn *col;
GtkListStore *model;
/* Since some systems have different default columns (some
* which aren't displayed on all types of clusters only add a
* column if there is a name for it. */
if (!display_data->name && (display_data->extra != EDIT_COLOR))
return;
col = gtk_tree_view_column_new();
model = (display_data->create_model)(display_data->id);
if (model && display_data->extra != EDIT_NONE) {
g_object_set(renderer,
"model", model,
"text-column", 0,

Danny Auble
committed
"has-entry", 1,
"editable", TRUE,
NULL);
} else if (display_data->extra == EDIT_TEXTBOX) {
renderer = gtk_cell_renderer_text_new();
g_object_set(renderer,
"editable", TRUE,
NULL);
} else if (display_data->extra == EDIT_COLOR) {
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false,
8, 10, 20);
renderer = gtk_cell_renderer_pixbuf_new();
g_object_set(renderer, "pixbuf", pixbuf, NULL);
g_object_unref(pixbuf);
renderer = gtk_cell_renderer_text_new();

Danny Auble
committed
gtk_tree_view_column_pack_start(col, renderer, TRUE);

Danny Auble
committed
g_object_set_data(G_OBJECT(renderer), "column",

Danny Auble
committed
gtk_tree_view_column_set_cell_data_func(
col, renderer, _cell_data_func,
NULL, NULL);
g_signal_connect(renderer, "editing-started",
G_CALLBACK(_editing_started), NULL);
g_signal_connect(renderer, "editing-canceled",
G_CALLBACK(_editing_canceled), NULL);
g_signal_connect(renderer, "edited",
G_CALLBACK(display_data->admin_edit),
gtk_tree_view_get_model(tree_view));
gtk_tree_view_column_add_attribute(col, renderer,
"text", display_data->id);
gtk_tree_view_column_set_expand(col, true);
gtk_tree_view_column_set_reorderable(col, true);
gtk_tree_view_column_set_resizable(col, true);
gtk_tree_view_column_set_sort_column_id(col, display_data->id);
gtk_tree_view_column_set_title(col, display_data->name);

Danny Auble
committed
}
}

Danny Auble
committed
static void _toggle_state_changed(GtkCheckMenuItem *menuitem,
display_data_t *display_data)
{
display_data->show = FALSE;
else
display_data->show = TRUE;
toggled = TRUE;
refresh_main(NULL, NULL);
}

Danny Auble
committed
static void _popup_state_changed(GtkCheckMenuItem *menuitem,
display_data_t *display_data)
{
popup_info_t *popup_win = (popup_info_t *) display_data->user_data;
display_data->show = FALSE;
else
display_data->show = TRUE;
popup_win->toggled = 1;
(display_data->refresh)(NULL, display_data->user_data);
}
static void _selected_page(GtkMenuItem *menuitem, display_data_t *display_data)
{
treedata_t *treedata = (treedata_t *)display_data->user_data;
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:
each.pfunc = &popup_all_part;
break;
case JOB_PAGE:
each.pfunc = &popup_all_job;
break;
case NODE_PAGE:
each.pfunc = &popup_all_node;
break;

Danny Auble
committed
case BLOCK_PAGE:
break;

Danny Auble
committed
case RESV_PAGE:
each.pfunc = &popup_all_resv;

Moe Jette
committed
case FRONT_END_PAGE:
each.pfunc = &popup_all_front_end;
break;
case ADMIN_PAGE:
switch(display_data->id) {
case JOB_PAGE:

Danny Auble
committed
admin_job(treedata->model, &treedata->iter,

Danny Auble
committed
display_data->name,treedata->treeview);
break;
case PART_PAGE:
select_admin_partitions(treedata->model,
&treedata->iter,
display_data,
treedata->treeview);
break;
case BLOCK_PAGE:
select_admin_block(treedata->model, &treedata->iter,
display_data, treedata->treeview);
case FRONT_END_PAGE:
select_admin_front_end(treedata->model,
&treedata->iter,
display_data,
treedata->treeview);
break;
select_admin_resv(treedata->model, &treedata->iter,
display_data, treedata->treeview);
select_admin_nodes(treedata->model, &treedata->iter,
display_data, NO_VAL,
treedata->treeview);
break;
default:
g_print("common admin got %d %d\n",
display_data->extra,
display_data->id);
}
break;
default:
g_print("common got %d %d\n", display_data->extra,
display_data->id);
}
gtk_tree_selection_selected_foreach(
gtk_tree_view_get_selection(treedata->treeview),
_foreach_popup_all, &each);
xfree(treedata);
}
extern char * replspace (char *str)
int pntr = 0;
while (str[pntr]) {
if (str[pntr] == ' ')
str[pntr] = '_';
pntr++;
}
return str;
}
extern char * replus (char *str)
{
int pntr = 0;
while (str[pntr]) {
if (str[pntr] == '_')
str[pntr] = ' ';
pntr++;
return str;
}
extern char *delstr(char *str, char *orig)
{
static char buffer[150];
char *p;
if (!(p = strstr(str, orig)))
return NULL;
strncpy(buffer, str, p-str);
strncpy(buffer+(p-str-1), p+strlen(orig), strlen(str)-(p-str));
buffer[strlen(str) - strlen(orig)] = '\0';
if (_DEBUG)
g_print("delstr: new string <%s>\n", buffer);
return buffer;
}
extern void free_switch_nodes_maps(
switch_record_bitmaps_t *sw_nodes_bitmaps_ptr)
if (!sw_nodes_bitmaps_ptr->node_bitmap)
break;
bit_free(sw_nodes_bitmaps_ptr->node_bitmap);
if (sw_nodes_bitmaps_ptr->node_bitmap)
xfree(sw_nodes_bitmaps_ptr->nodes);
}
g_switch_nodes_maps = NULL;
}
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("...............build_nodes_bitmap............%s\n",
node_names);
my_bitmap = (bitstr_t *) bit_alloc(g_node_info_ptr->record_count);
fatal("bit_alloc malloc failure");
}
*bitmap = my_bitmap;
error("build_nodes_bitmap: node_names is NULL");
return EINVAL;
}
if (!(host_list = hostlist_create(node_names))) {
error("build_nodes_bitmap: 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);
free(this_node_name);
if (node_inx == -1)
}
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 && 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_topo_info_msg_ptr->record_count == 0) {
slurm_free_topo_info_msg(g_topo_info_msg_ptr);
g_topo_info_msg_ptr = NULL;
return SLURM_ERROR;
}
if (g_switch_nodes_maps)
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)
continue;
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)) {
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);
GtkTreeIter iter;
int line = 0;

Danny Auble
committed
g_error("error getting the model from the tree_view");
return -1;
}

Danny Auble
committed
if (!gtk_tree_model_get_iter(model, &iter, path)) {
g_error("get row, error getting iter from model");
return -1;

Danny Auble
committed
}
gtk_tree_model_get(model, &iter, POS_LOC, &line, -1);
return line;
}
extern int find_col(display_data_t *display_data, int type)
{
int i = 0;
while (display_data++) {
if (display_data->id == -1)
return i;
i++;
}
return -1;
}
extern const char *find_col_name(display_data_t *display_data, int type)
{
while (display_data++) {
if (display_data->id == -1)
return display_data->name;
}
return NULL;
}
extern void *get_pointer(GtkTreeView *tree_view, GtkTreePath *path, int loc)
{
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
GtkTreeIter iter;
void *ptr = NULL;

Danny Auble
committed
g_error("error getting the model from the tree_view");
return ptr;
}

Danny Auble
committed
if (!gtk_tree_model_get_iter(model, &iter, path)) {
g_error("get pointer, error getting iter from model");

Danny Auble
committed
}
gtk_tree_model_get(model, &iter, loc, &ptr, -1);
return ptr;
}
extern void make_fields_menu(popup_info_t *popup_win, GtkMenu *menu,
display_data_t *display_data, int count)
{
GtkWidget *menuitem = NULL;
display_data_t *first_display_data = display_data;
int i = 0;
/* we don't want to display anything on the full info page */
if (popup_win && popup_win->spec_info->type == INFO_PAGE)
return;
g_signal_connect(G_OBJECT(menu), "button-press-event",
G_CALLBACK(_menu_button_pressed),
NULL);
g_signal_connect(G_OBJECT(menu), "button-release-event",
G_CALLBACK(_menu_button_released),
NULL);
for(i=0; i<count; i++) {

Danny Auble
committed
menuitem = gtk_check_menu_item_new_with_label(

Danny Auble
committed
display_data->name);
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(menuitem),
display_data->show);
display_data->user_data = popup_win;
g_signal_connect(
menuitem, "toggled",

Danny Auble
committed
G_CALLBACK(_popup_state_changed),
display_data);
} else {
g_signal_connect(
menuitem, "toggled",

Danny Auble
committed
G_CALLBACK(_toggle_state_changed),
display_data);
}
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
break;
}
display_data = first_display_data;
}
}
extern void set_page_opts(int page, display_data_t *display_data,
ListIterator itr = NULL;
char *col_name = NULL;
page_opts = &working_sview_config.page_opts[page];
if (!page_opts->col_list) {
page_opts->def_col_list = 1;
page_opts->col_list = list_create(slurm_destroy_char);
slurm_addto_char_list(page_opts->col_list, initial_opts);
}
page_opts->display_data = display_data;
itr = list_iterator_create(page_opts->col_list);
while ((col_name = list_next(itr))) {
replus(col_name);
if (strstr(col_name, "list")) {
if (cluster_flags & CLUSTER_FLAG_BG)
xstrsubstitute(col_name, "node", "bp");
else
xstrsubstitute(col_name, "bp", "node");
}
while (display_data++) {
if (display_data->id == -1)
break;
if (!display_data->name)
continue;
if (!strcasecmp(col_name, display_data->name)) {
display_data->show = TRUE;
break;
}
}
display_data = page_opts->display_data;
extern void make_options_menu(GtkTreeView *tree_view, GtkTreePath *path,
GtkMenu *menu, display_data_t *display_data)
{
GtkWidget *menuitem = NULL;
treedata_t *treedata = xmalloc(sizeof(treedata_t));
treedata->model = gtk_tree_view_get_model(tree_view);

Danny Auble
committed
treedata->treeview = tree_view;
g_signal_connect(G_OBJECT(menu), "button-press-event",
G_CALLBACK(_menu_button_pressed),
NULL);
g_signal_connect(G_OBJECT(menu), "button-release-event",
G_CALLBACK(_menu_button_released),
NULL);
if (!gtk_tree_model_get_iter(treedata->model, &treedata->iter, path)) {
g_error("make menus error getting iter from model\n");
return;

Danny Auble
committed
}

Danny Auble
committed
/* check selection list */
global_row_count = gtk_tree_selection_count_selected_rows(

Danny Auble
committed
gtk_tree_view_get_selection(tree_view));