00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00024 #include <gtk/gtk.h>
00025 #include <stdlib.h>
00026 #include <unistd.h>
00027
00028 #include "application-data.h"
00029 #include "frame-common.h"
00030 #include "frame-private.h"
00031 #include "frame-utilities.h"
00032 #include "frame-new-dialog.h"
00033 #include "frame-private.h"
00034 #include "gedit-spinner.h"
00035 #include "machine.h"
00036 #include "time-period.h"
00037
00038
00039 GtkWidget *frame_get_info_bar (frame_t *frame)
00040 {
00041 g_return_val_if_fail (frame != NULL, NULL);
00042
00043 GtkWidget *info_bar = NULL;
00044 GList *children = NULL;
00045 GList *iter = NULL;
00046
00047 children = gtk_container_get_children (GTK_CONTAINER (gtk_builder_get_object (frame->builder, "root_box")));
00048 if (children) {
00049 iter = children;
00050 do {
00051 if (GTK_IS_INFO_BAR (iter->data)) {
00052 info_bar = iter->data;
00053 iter = NULL;
00054 }
00055 } while ((iter = g_list_next (iter)) != NULL);
00056 }
00057 g_list_free (children);
00058
00059 return info_bar;
00060 }
00061
00062
00063
00064 void frame_display_error_message (frame_t *frame, frame_error_t type, const gchar *message, ...)
00065 {
00066 GList *children = NULL;
00067 gchar *buffer = NULL;
00068 gchar *final = NULL;
00069 GtkWidget *info_bar = frame_get_info_bar (frame);
00070 va_list args;
00071
00072 va_start (args, message);
00073 buffer = g_strdup_vprintf (message, args);
00074 final = g_strdup_printf ("<b>Error</b>\n\n%s", buffer);
00075 va_end (args);
00076
00077
00078 frame->last_err = type;
00079
00080 gtk_widget_set_size_request (info_bar, frame_get_width (frame), frame_get_height (frame));
00081 gtk_widget_hide ((GtkWidget *) gtk_builder_get_object (frame->builder, "drawing_area"));
00082
00083
00084 children = gtk_container_get_children (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar))));
00085 if (children) {
00086 gtk_label_set_markup (GTK_LABEL (children->data), final);
00087 g_list_free (children);
00088 }
00089
00090 gtk_widget_set_tooltip_markup (info_bar, buffer);
00091 gtk_widget_show (info_bar);
00092 g_free (buffer);
00093 g_free (final);
00094 }
00095
00096
00097
00106 static void frame_func_button_clicked (GtkButton *button, gpointer user_data)
00107 {
00108 frame_t *f = (frame_t *) user_data;
00109 GtkWidget *menu = (GtkWidget *) gtk_builder_get_object (f->builder, "func_menu");
00110
00111 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
00112 }
00113
00114
00115
00116 static void frame_detach_menu (GtkWidget *button, GtkMenu *menu)
00117 {}
00118
00119
00120
00121 double frame_get_height (frame_t *f)
00122 {
00123 switch (f->size) {
00124 case NORMAL:
00125 return FRAME_HEIGHT_NORMAL;
00126 break;
00127 case LARGE:
00128 return FRAME_HEIGHT_LARGE;
00129 break;
00130 case FULL:
00131 case LAST_SIZE_RATIO_T:
00132 return 1.0f;
00133 }
00134 return 1.0f;
00135 }
00136
00137
00138
00139 double frame_get_width (frame_t *f)
00140 {
00141 switch (f->size) {
00142 case NORMAL:
00143 return FRAME_WIDTH_NORMAL;
00144 break;
00145 case LARGE:
00146 return FRAME_WIDTH_LARGE;
00147 break;
00148 case FULL:
00149 case LAST_SIZE_RATIO_T:
00150 return 1.0f;
00151 }
00152 return 1.0f;
00153 }
00154
00155
00156
00157 gboolean frame_get_coordinates (frame_t *frame, GtkWidget *table, guint *left, guint *top)
00158 {
00159 GtkWidget *framewidget = frame_get_root_widget (frame);
00160 GValue val = {0,};
00161
00162 if (gtk_widget_get_parent (framewidget) != table)
00163 return FALSE;
00164
00165 g_value_init (&val, G_TYPE_UINT);
00166 gtk_container_child_get_property (GTK_CONTAINER (table), framewidget, "left-attach", &val);
00167 *left = g_value_get_uint (&val);
00168 g_value_unset (&val);
00169
00170 g_value_init (&val, G_TYPE_UINT);
00171 gtk_container_child_get_property (GTK_CONTAINER (table), framewidget, "top-attach", &val);
00172 *top = g_value_get_uint (&val);
00173 g_value_unset (&val);
00174
00175 return TRUE;
00176 }
00177
00178
00179
00180 void frame_request_redraw (frame_t *f)
00181 {
00182 GtkWidget *area = (GtkWidget *) gtk_builder_get_object (f->builder, "drawing_area");
00183
00184 if (!f->hidden)
00185 gtk_widget_queue_draw (area);
00186 }
00187
00188
00189
00190 void frame_request_content_refresh (frame_t *f)
00191 {
00192 if (!f->hidden) {
00193 f->computing_requested = TRUE;
00194 g_cond_signal (f->cond);
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 static void _frame_unset_error (GtkInfoBar *info_bar, gint response_id, gpointer user_data)
00212 {
00213 frame_t *frame = user_data;
00214
00215 frame->last_err = ERROR_NONE;
00216 gtk_widget_hide (GTK_WIDGET (info_bar));
00217
00218
00219
00220 gtk_widget_show ((GtkWidget *) gtk_builder_get_object (frame->builder, "drawing_area"));
00221 }
00222
00223
00224
00225 void frame_unset_error (frame_t *frame)
00226 {
00227 g_return_if_fail (frame != NULL);
00228
00229 _frame_unset_error (GTK_INFO_BAR (frame_get_info_bar (frame)), GTK_RESPONSE_OK, frame);
00230 }
00231
00232
00233
00234 int frame_initialise (frame_t *f,
00235 size_ratio_t size,
00236 machine_t *display_machine,
00237 time_period_t *pref_period)
00238 {
00239 synema_instance_t *inst = synema_instance ();
00240 gchar *framepath = NULL;
00241 gchar *label_text = NULL;
00242 GError *err = NULL;
00243 GList *func_list = NULL;
00244 GList *machines_list = NULL;
00245 GList *time_list = NULL;
00246 GList *time_list_iter = NULL;
00247 GList *func_list_iter = NULL;
00248 GtkCellRenderer *renderer = NULL;
00249 GtkListStore *store = NULL;
00250 GtkTreeIter iter;
00251 GtkWidget *area = NULL;
00252 GtkWidget *content_area = NULL;
00253 GtkWidget *childmenu = NULL;
00254 GtkWidget *func_btn = NULL;
00255 GtkWidget *func_menu = NULL;
00256 GtkWidget *info_bar = NULL;
00257 GtkWidget *label = NULL;
00258 GtkWidget *machine = NULL;
00259 GtkWidget *period = NULL;
00260 GtkWidget *root_box = NULL;
00261 GtkWidget *size_btn = NULL;
00262 GtkWidget *topbox = NULL;
00263
00264
00265
00266 f->builder = gtk_builder_new ();
00267 framepath = g_strdup_printf ("%s/frame.ui", inst->data_dir);
00268 gtk_builder_add_from_file (f->builder, framepath, &err);
00269 g_free (framepath);
00270 if (err) {
00271 g_warning ("frame_initialise: %s", err->message);
00272 g_clear_error (&err);
00273 return -1;
00274 }
00275
00276
00277
00278 f->size = size;
00279 f->display_machine = display_machine;
00280 f->id = 0;
00281
00282
00283
00284 label = (GtkWidget *) gtk_builder_get_object (f->builder, "frame_label");
00285 label_text = g_strdup_printf ("<b>%s</b>", f->get_display_name(f));
00286 gtk_label_set_markup (GTK_LABEL (label), label_text);
00287 g_free (label_text);
00288
00289
00290 period = (GtkWidget *) gtk_builder_get_object (f->builder, "display_period");
00291
00292 renderer = gtk_cell_renderer_text_new ();
00293 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (period), renderer, FALSE);
00294 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (period),
00295 renderer,
00296 "text",
00297 0,
00298 NULL);
00299
00300 store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX(period)));
00301 time_list = f->build_time_periods ();
00302
00303
00304 f->display_period.type = 0;
00305 f->display_period.value = 0;
00306
00307 if (time_list != NULL) {
00308 time_list_iter = time_list;
00309 do {
00310 time_period_t *p = time_list_iter->data;
00311 char *name = time_period_get_display_name (p, TRUE);
00312
00313 gtk_list_store_append (store, &iter);
00314 gtk_list_store_set (store, &iter, 0, name, 1, p->type, 2, p->value, -1);
00315
00316 if (time_period_cmp (p, pref_period) == 0) {
00317 time_period_copy (p, &(f->display_period));
00318 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(period), &iter);
00319 }
00320
00321 time_period_free (p);
00322 g_free (name);
00323 } while ((time_list_iter = g_list_next (time_list_iter)) != NULL);
00324 }
00325
00326 if (gtk_combo_box_get_active (GTK_COMBO_BOX(period)) == -1)
00327 gtk_combo_box_set_active (GTK_COMBO_BOX(period), 0);
00328
00329 g_list_free (time_list);
00330
00331 g_signal_connect (period, "changed",
00332 G_CALLBACK (frame_time_period_changed),
00333 (gpointer) f);
00334
00335
00336
00337 machine = (GtkWidget *) gtk_builder_get_object (f->builder, "display_machine");
00338
00339 renderer = gtk_cell_renderer_text_new ();
00340 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (machine), renderer, FALSE);
00341 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (machine),
00342 renderer,
00343 "text",
00344 0,
00345 NULL);
00346
00347 machines_list = machine_get_list_for_plugin (f->type, TRUE);
00348 frame_populate_machine_combo (machine, machines_list, f->display_machine);
00349 g_list_free (machines_list);
00350
00351 g_signal_connect (machine, "changed",
00352 G_CALLBACK (frame_machine_changed),
00353 (gpointer) f);
00354
00355
00356
00357 func_btn = (GtkWidget *) gtk_builder_get_object (f->builder, "func_button");
00358 func_menu = (GtkWidget *) gtk_builder_get_object (f->builder, "func_menu");
00359
00360
00361
00362
00363
00364
00365 func_list = f->build_func_list ();
00366
00367 if (func_list != NULL) {
00368 func_list_iter = func_list;
00369 gtk_menu_attach_to_widget (GTK_MENU (func_menu), func_btn, frame_detach_menu);
00370
00371 g_signal_connect (func_btn, "clicked",
00372 G_CALLBACK (frame_func_button_clicked),
00373 (gpointer) f);
00374
00375 do {
00376 func_list_t *fn = func_list_iter->data;
00377 GtkWidget *item = NULL;
00378
00379 switch (fn->type) {
00380 case FUNCTION:
00381 item = gtk_menu_item_new_with_label (fn->name);
00382
00383 g_signal_connect (item, "activate",
00384 G_CALLBACK (fn->data.func),
00385 (gpointer) f);
00386
00387 gtk_menu_shell_append (GTK_MENU_SHELL (func_menu), item);
00388 gtk_widget_show (item);
00389 break;
00390 case SEPARATOR:
00391 item = gtk_separator_menu_item_new ();
00392 gtk_menu_shell_append (GTK_MENU_SHELL (func_menu), item);
00393 gtk_widget_show (item);
00394 break;
00395 case SUBMENU:
00396 item = gtk_menu_item_new_with_label (fn->name);
00397 gtk_menu_shell_append (GTK_MENU_SHELL (func_menu), item);
00398
00399 childmenu = func_list_t_setup_submenu (fn, f);
00400 gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), childmenu);
00401
00402 gtk_widget_show (item);
00403 break;
00404 }
00405 func_list_t_free (fn);
00406 } while ((func_list_iter = g_list_next (func_list_iter)) != NULL);
00407
00408 g_list_free (func_list);
00409
00410 } else {
00411 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (func_btn)), func_btn);
00412 }
00413
00414
00415
00416 area = (GtkWidget *) gtk_builder_get_object (f->builder, "drawing_area");
00417 gtk_widget_set_size_request (area, frame_get_width (f),
00418 frame_get_height (f));
00419
00420
00421
00422 frame_update_size_button (f);
00423 size_btn = (GtkWidget *) gtk_builder_get_object (f->builder, "size_toggle");
00424 g_signal_connect (size_btn, "clicked",
00425 G_CALLBACK (frame_size_changed_event),
00426 (gpointer) f);
00427
00428
00429
00430
00431 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
00432 gtk_widget_add_events (area, GDK_BUTTON_RELEASE_MASK);
00433 g_signal_connect (area, "button_press_event",
00434 G_CALLBACK (frame_button_event),
00435 (gpointer) f);
00436 g_signal_connect (area, "button_release_event",
00437 G_CALLBACK (frame_button_event),
00438 (gpointer) f);
00439
00440
00441
00442 g_signal_connect (area, "expose_event",
00443 G_CALLBACK (frame_expose_handler),
00444 (gpointer) f);
00445
00446
00447
00448 g_signal_connect (gtk_builder_get_object (f->builder, "close_button"),
00449 "clicked",
00450 G_CALLBACK (frame_on_exit),
00451 (gpointer) f);
00452
00453
00454
00455 f->signal_box = frame_signals_new ();
00456 g_object_ref_sink (f->signal_box);
00457
00458
00459
00460 f->spinner_stop_src = 0;
00461 f->spinner_start_src = 0;
00462 f->computing_spinner = gedit_spinner_new ();
00463 gedit_spinner_set_size (GEDIT_SPINNER (f->computing_spinner), GTK_ICON_SIZE_BUTTON);
00464 topbox = (GtkWidget *) gtk_builder_get_object (f->builder, "top_box");
00465 gtk_box_pack_start (GTK_BOX (topbox), f->computing_spinner, FALSE, FALSE, 0);
00466 gtk_box_reorder_child (GTK_BOX (topbox), f->computing_spinner, 0);
00467 gtk_widget_show (f->computing_spinner);
00468
00469
00470
00471 f->mutex = g_mutex_new ();
00472 f->cond = g_cond_new ();
00473 f->compute = TRUE;
00474 f->computing_thread = g_thread_create (frame_computing_thread,
00475 (gpointer) f,
00476 TRUE,
00477 &err);
00478 if (err) {
00479 g_error ("frame_initialise::g_thread_create: %s", err->message);
00480 g_clear_error (&err);
00481 return -1;
00482 }
00483
00484
00485 f->avg_refresh_time = 0;
00486 f->avg_refresh_timeout = 0;
00487
00488
00489
00490 f->parent = NULL;
00491 f->hidden = TRUE;
00492 f->hidden_item = NULL;
00493
00494
00495
00496 f->last_err = ERROR_NONE;
00497 info_bar = gtk_info_bar_new ();
00498 gtk_widget_set_no_show_all (info_bar, TRUE);
00499
00500 label = gtk_label_new ("");
00501 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
00502 gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
00503 gtk_widget_set_size_request (label, frame_get_width (f) - 100, -1);
00504 gtk_misc_set_alignment (GTK_MISC (label), 0.1, 0.0);
00505 gtk_widget_show (label);
00506
00507 content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
00508 gtk_container_add (GTK_CONTAINER (content_area), label);
00509
00510 gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), GTK_STOCK_CLOSE, GTK_RESPONSE_OK);
00511 gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_ERROR);
00512
00513 g_signal_connect (info_bar, "response", G_CALLBACK (_frame_unset_error), f);
00514
00515 root_box = (GtkWidget *) gtk_builder_get_object (f->builder, "root_box");
00516 gtk_box_pack_start_defaults (GTK_BOX (root_box), info_bar);
00517 gtk_box_reorder_child (GTK_BOX (root_box), info_bar, 1);
00518
00519
00520
00521 return f->init_private (f);
00522 }
00523
00524
00525
00526 GtkWidget *frame_get_root_widget (frame_t *f)
00527 {
00528 return (GtkWidget *) gtk_builder_get_object (f->builder, "frame_widget");
00529 }
00530
00531
00532
00533 char *frame_get_absolute_reports_path (frame_t *f, const char *relpath, const char *machine)
00534 {
00535 g_return_val_if_fail (f != NULL, NULL);
00536
00537 synema_instance_t *inst = synema_instance ();
00538
00539 if (relpath)
00540 return g_strdup_printf ("%s/%s/"REPORTS_DIR"/%s/%s",
00541 inst->machines_dir,
00542 (machine) ? machine : machine_get_folder_name (f->display_machine),
00543 f->type,
00544 relpath);
00545 else
00546 return g_strdup_printf ("%s/%s/"REPORTS_DIR"/%s",
00547 inst->machines_dir,
00548 (machine) ? machine : machine_get_folder_name (f->display_machine),
00549 f->type);
00550 }
00551
00552
00553
00554 char *frame_get_absolute_data_path (frame_t *f, const char *relpath)
00555 {
00556 g_return_val_if_fail (f != NULL, NULL);
00557
00558 synema_instance_t *inst = synema_instance ();
00559
00560 if (relpath)
00561 return g_strdup_printf ("%s/"PLUGINS_DIR"/%s/%s", inst->data_dir, f->type, relpath);
00562 else
00563 return g_strdup_printf ("%s/"PLUGINS_DIR"/%s", inst->data_dir, f->type);
00564 }
00565
00566
00567
00568 char *frame_get_absolute_tmp_path (frame_t *f, const char *relpath)
00569 {
00570 g_return_val_if_fail (f != NULL, NULL);
00571
00572 synema_instance_t *inst = synema_instance ();
00573
00574 if (relpath)
00575 return g_strdup_printf ("%s/frame_%u/%s", inst->tmp_dir, f->id, relpath);
00576 else
00577 return g_strdup_printf ("%s/frame_%u", inst->tmp_dir, f->id);
00578 }