blob: c220a52cce8af22a3713021415606d54cc99cc91 [file] [log] [blame]
/*
* Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program 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; version 2 of the License (not later!)
*
* This program 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <ctype.h>
#include "trace-compat.h"
#include "trace-cmd.h"
#include "trace-gui.h"
#define DIALOG_WIDTH 500
#define DIALOG_HEIGHT 550
static GtkWidget *statusbar;
static GtkWidget *statuspix;
static GString *statusstr;
static GtkWidget *parent_window;
void pr_stat(char *fmt, ...)
{
GString *str;
va_list ap;
if (!statusstr) {
statusstr = g_string_new("");
if (!statusstr)
die("Allocating status string");
}
str = g_string_new("");
va_start(ap, fmt);
g_string_vprintf(str, fmt, ap);
va_end(ap);
g_string_append_printf(statusstr, "%s\n", str->str);
if (statusbar) {
gtk_statusbar_push(GTK_STATUSBAR(statusbar), 1, str->str);
gtk_widget_show(statuspix);
}
g_string_free(str, TRUE);
}
/**
* trace_dialog_register_window - register window for warning dialogs
* @window: parent window to use for other dialogs
*
* The warning messages do not have a way to pass the window to
* the function, since these functions are also used by the command
* line interface. This allows an application to give the warning
* messages a window to use.
*/
void trace_dialog_register_window(GtkWidget *window)
{
parent_window = window;
}
void warning(char *fmt, ...)
{
GString *str;
va_list ap;
if (!parent_window) {
va_start(ap, fmt);
__vwarning(fmt, ap);
va_end(ap);
return;
}
str = g_string_new("");
va_start(ap, fmt);
g_string_vprintf(str, fmt, ap);
va_end(ap);
g_string_append(str, "\n");
if (errno)
g_string_prepend(str, strerror(errno));
errno = 0;
trace_dialog(GTK_WINDOW(parent_window), TRACE_GUI_WARNING,
str->str);
g_string_free(str, TRUE);
}
static void
status_display_clicked (gpointer data)
{
GtkWidget *dialog;
GtkWidget *scrollwin;
GtkWidget *viewport;
GtkWidget *textview;
GtkTextBuffer *buffer;
dialog = gtk_dialog_new_with_buttons("Status",
NULL,
GTK_DIALOG_MODAL,
"OK",
GTK_RESPONSE_ACCEPT,
NULL);
scrollwin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrollwin, TRUE, TRUE, 0);
gtk_widget_show(scrollwin);
viewport = gtk_viewport_new(NULL, NULL);
gtk_widget_show(viewport);
gtk_container_add(GTK_CONTAINER(scrollwin), viewport);
textview = gtk_text_view_new();
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
gtk_text_buffer_set_text(buffer, statusstr->str, -1);
gtk_container_add(GTK_CONTAINER(viewport), textview);
gtk_widget_show(textview);
gtk_widget_set_size_request(GTK_WIDGET(dialog),
DIALOG_WIDTH, DIALOG_HEIGHT);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
static gboolean
do_status_popup(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
static GtkWidget *menu;
static GtkWidget *menu_status_display;
if (!menu) {
menu = gtk_menu_new();
menu_status_display = gtk_menu_item_new_with_label("Display Status");
gtk_widget_show(menu_status_display);
gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_status_display);
g_signal_connect_swapped (G_OBJECT (menu_status_display), "activate",
G_CALLBACK (status_display_clicked),
data);
}
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3,
gtk_get_current_event_time());
return TRUE;
}
static gboolean
button_press_status(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
if (event->button == 1)
return do_status_popup(widget, event, data);
return FALSE;
}
GtkWidget *trace_status_bar_new(void)
{
GtkWidget *eventbox;
statusbar = gtk_statusbar_new();
statuspix = gtk_image_new_from_stock(GTK_STOCK_INFO,
GTK_ICON_SIZE_SMALL_TOOLBAR);
eventbox = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(eventbox), statuspix);
gtk_widget_show(eventbox);
gtk_box_pack_end(GTK_BOX(statusbar), eventbox, FALSE, FALSE, 0);
if (statusstr)
gtk_widget_show(statuspix);
gtk_signal_connect(GTK_OBJECT(eventbox), "button_press_event",
(GtkSignalFunc) button_press_status, NULL);
return statusbar;
}
void trace_show_help(GtkWidget *window, const gchar *link, GError **error)
{
#if GTK_VERSION < CALC_GTK_VERSION(2,14,0)
trace_dialog(GTK_WINDOW(window), TRACE_GUI_WARNING,
"This version of GTK+ does not implement gtk_show_uri.\n"
"Please upgrade your GTK and recompile");
#else
gtk_show_uri(gtk_widget_get_screen(GTK_WIDGET(window)),
link,
GDK_CURRENT_TIME,
error);
#endif
}
void trace_dialog(GtkWindow *parent, enum trace_dialog_type type,
gchar *message, ...)
{
GtkWidget *dialog;
GtkMessageType mtype;
gchar *str;
va_list ap;
switch (type) {
case TRACE_GUI_INFO:
mtype = GTK_MESSAGE_INFO;
break;
case TRACE_GUI_WARNING:
mtype = GTK_MESSAGE_WARNING;
break;
case TRACE_GUI_ERROR:
mtype = GTK_MESSAGE_ERROR;
break;
}
va_start(ap, message);
str = g_strdup_vprintf(message, ap);
va_end(ap);
dialog = gtk_message_dialog_new(parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
mtype,
GTK_BUTTONS_CLOSE,
"%s", str);
g_free(str);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
gchar *trace_get_file_dialog(const gchar *title)
{
GtkWidget *dialog;
gchar *filename = NULL;
dialog = gtk_file_chooser_dialog_new(title,
NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
gtk_widget_destroy(dialog);
return filename;
}