gfio: add support for graph tooltips
[fio.git] / gfio.c
diff --git a/gfio.c b/gfio.c
index c25a264031473412a7db298f1a29062205e42957..76bbbf5c340b985fd19e78f5fa55b7a66dfbb37e 100644 (file)
--- a/gfio.c
+++ b/gfio.c
@@ -496,15 +496,15 @@ static void update_button_states(struct gui *ui, struct gui_entry *ge)
        if (w)
                gtk_widget_set_sensitive(w, connect_state);
 
-       w = gtk_ui_manager_get_widget(ui->uimanager, "/MainMenu/JobMenu/Edit Job");
+       w = gtk_ui_manager_get_widget(ui->uimanager, "/MainMenu/JobMenu/Edit job");
        if (w)
                gtk_widget_set_sensitive(w, edit_state);
 
-       w = gtk_ui_manager_get_widget(ui->uimanager, "/MainMenu/JobMenu/Send Job");
+       w = gtk_ui_manager_get_widget(ui->uimanager, "/MainMenu/JobMenu/Send job");
        if (w)
                gtk_widget_set_sensitive(w, send_state);
 
-       w = gtk_ui_manager_get_widget(ui->uimanager, "/MainMenu/JobMenu/Start Job");
+       w = gtk_ui_manager_get_widget(ui->uimanager, "/MainMenu/JobMenu/Start job");
        if (w)
                gtk_widget_set_sensitive(w, start_state);
 }
@@ -1307,12 +1307,39 @@ static void draw_graph(struct graph *g, cairo_t *cr)
        cairo_stroke(cr);
 }
 
+static gboolean graph_tooltip(GtkWidget *w, gint x, gint y,
+                             gboolean keyboard_mode, GtkTooltip *tooltip,
+                             gpointer data)
+{
+       struct gfio_graphs *g = data;
+       const char *text = NULL;
+
+       if (graph_contains_xy(g->iops_graph, x, y))
+               text = graph_find_tooltip(g->iops_graph, x, y);
+       else if (graph_contains_xy(g->bandwidth_graph, x, y))
+               text = graph_find_tooltip(g->bandwidth_graph, x, y);
+
+       if (text) {
+               gtk_tooltip_set_text(tooltip, text);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static int on_expose_drawing_area(GtkWidget *w, GdkEvent *event, gpointer p)
 {
        struct gfio_graphs *g = p;
        cairo_t *cr;
 
        cr = gdk_cairo_create(w->window);
+
+       if (graph_has_tooltips(g->iops_graph) ||
+           graph_has_tooltips(g->bandwidth_graph)) {
+               g_object_set(w, "has-tooltip", TRUE, NULL);
+               g_signal_connect(w, "query-tooltip", G_CALLBACK(graph_tooltip), g);
+       }
+
        cairo_set_source_rgb(cr, 0, 0, 0);
        draw_graph(g->iops_graph, cr);
        draw_graph(g->bandwidth_graph, cr);
@@ -1393,10 +1420,10 @@ static void gfio_update_client_eta(struct fio_client *client, struct jobs_eta *j
                gtk_entry_set_text(GTK_ENTRY(ge->eta.write_bw), rate_str[1]);
                gtk_entry_set_text(GTK_ENTRY(ge->eta.write_iops), iops_str[1]);
 
-               graph_add_xy_data(ge->graphs.iops_graph, "Read IOPS", je->elapsed_sec, je->iops[0]);
-               graph_add_xy_data(ge->graphs.iops_graph, "Write IOPS", je->elapsed_sec, je->iops[1]);
-               graph_add_xy_data(ge->graphs.bandwidth_graph, "Read Bandwidth", je->elapsed_sec, je->rate[0]);
-               graph_add_xy_data(ge->graphs.bandwidth_graph, "Write Bandwidth", je->elapsed_sec, je->rate[1]);
+               graph_add_xy_data(ge->graphs.iops_graph, "Read IOPS", je->elapsed_sec, je->iops[0], iops_str[0]);
+               graph_add_xy_data(ge->graphs.iops_graph, "Write IOPS", je->elapsed_sec, je->iops[1], iops_str[1]);
+               graph_add_xy_data(ge->graphs.bandwidth_graph, "Read Bandwidth", je->elapsed_sec, je->rate[0], rate_str[0]);
+               graph_add_xy_data(ge->graphs.bandwidth_graph, "Write Bandwidth", je->elapsed_sec, je->rate[1], rate_str[1]);
 
                free(rate_str[0]);
                free(rate_str[1]);
@@ -1481,10 +1508,10 @@ static void gfio_update_all_eta(struct jobs_eta *je)
                gtk_entry_set_text(GTK_ENTRY(ui->eta.write_bw), rate_str[1]);
                gtk_entry_set_text(GTK_ENTRY(ui->eta.write_iops), iops_str[1]);
 
-               graph_add_xy_data(ui->graphs.iops_graph, "Read IOPS", je->elapsed_sec, je->iops[0]);
-               graph_add_xy_data(ui->graphs.iops_graph, "Write IOPS", je->elapsed_sec, je->iops[1]);
-               graph_add_xy_data(ui->graphs.bandwidth_graph, "Read Bandwidth", je->elapsed_sec, je->rate[0]);
-               graph_add_xy_data(ui->graphs.bandwidth_graph, "Write Bandwidth", je->elapsed_sec, je->rate[1]);
+               graph_add_xy_data(ui->graphs.iops_graph, "Read IOPS", je->elapsed_sec, je->iops[0], iops_str[0]);
+               graph_add_xy_data(ui->graphs.iops_graph, "Write IOPS", je->elapsed_sec, je->iops[1], iops_str[1]);
+               graph_add_xy_data(ui->graphs.bandwidth_graph, "Read Bandwidth", je->elapsed_sec, je->rate[0], rate_str[0]);
+               graph_add_xy_data(ui->graphs.bandwidth_graph, "Write Bandwidth", je->elapsed_sec, je->rate[1], rate_str[1]);
 
                free(rate_str[0]);
                free(rate_str[1]);
@@ -1738,8 +1765,8 @@ static void start_job_clicked(__attribute__((unused)) GtkWidget *widget,
        struct gui_entry *ge = data;
        struct gfio_client *gc = ge->client;
 
-       gtk_widget_set_sensitive(ge->button[START_JOB_BUTTON], 0);
-       fio_start_client(gc->client);
+       if (gc)
+               fio_start_client(gc->client);
 }
 
 static void file_open(GtkWidget *w, gpointer data);
@@ -1753,7 +1780,7 @@ static void connect_clicked(GtkWidget *widget, gpointer data)
                int ret;
 
                if (!ge->nr_job_files)
-                       file_open(widget, data);
+                       file_open(widget, ge->ui);
                if (!ge->nr_job_files)
                        return;
 
@@ -2065,7 +2092,7 @@ static void file_new(GtkWidget *w, gpointer data)
  * Return the 'ge' corresponding to the tab. If the active tab is the
  * main tab, open a new tab.
  */
-static struct gui_entry *get_ge_from_page(unsigned int cur_page)
+static struct gui_entry *get_ge_from_page(gint cur_page)
 {
        struct flist_head *entry;
        struct gui_entry *ge;
@@ -2111,7 +2138,12 @@ static void file_close(GtkWidget *w, gpointer data)
                return;
        }
 
-       show_info_dialog(ui, "Error", "The main page view cannot be closed\n");
+       if (!flist_empty(&ui->list)) {
+               show_info_dialog(ui, "Error", "The main page view cannot be closed\n");
+               return;
+       }
+
+               gtk_main_quit();
 }
 
 static void file_open(GtkWidget *w, gpointer data)