/* * mooscript-zenity.c * * Copyright (C) 2004-2006 by Yevgen Muntyan * * 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; either version 2 of the License, or * (at your option) any later version. * * See COPYING file that comes with this distribution. */ #include "mooscript-zenity.h" #include "mooscript-context.h" #include "mooutils/moodialogs.h" #include "mooutils/moohistorycombo.h" #include #define CHECK_GTK(ctx) \ G_STMT_START { \ if (!gtk_init_check (NULL, NULL)) \ return ms_context_format_error (ctx, MS_ERROR_RUNTIME, \ "could not open display"); \ } G_STMT_END static MSValue* entry_func (MSValue **args, guint n_args, MSContext *ctx) { char *dialog_text = NULL, *entry_text = NULL; gboolean hide_text = FALSE; int response; GtkWidget *dialog, *entry; MSValue *result; CHECK_GTK (ctx); if (n_args > 0 && !ms_value_is_none (args[0])) entry_text = ms_value_print (args[0]); if (n_args > 1 && !ms_value_is_none (args[1])) dialog_text = ms_value_print (args[1]); if (n_args > 2 && !ms_value_is_none (args[2])) hide_text = ms_value_get_bool (args[2]); dialog = gtk_dialog_new_with_buttons (NULL, ctx->window, GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); if (dialog_text) { GtkWidget *label; label = gtk_label_new (dialog_text); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, FALSE, FALSE, 0); } entry = gtk_entry_new (); gtk_widget_show (entry); gtk_entry_set_visibility (GTK_ENTRY (entry), !hide_text); gtk_entry_set_text (GTK_ENTRY (entry), entry_text ? entry_text : ""); gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), entry, FALSE, FALSE, 0); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) result = ms_value_string (gtk_entry_get_text (GTK_ENTRY (entry))); else result = ms_value_none (); gtk_widget_destroy (dialog); g_free (dialog_text); g_free (entry_text); return result; } MSFunc * ms_zenity_entry (void) { return ms_cfunc_new_var (entry_func); } static MSValue* history_entry_func (MSValue **args, guint n_args, MSContext *ctx) { char *dialog_text = NULL, *entry_text = NULL, *user_id = NULL; int response; GtkWidget *dialog, *entry; MSValue *result; CHECK_GTK (ctx); if (n_args > 0 && !ms_value_is_none (args[0])) entry_text = ms_value_print (args[0]); if (n_args > 1 && !ms_value_is_none (args[1])) user_id = ms_value_print (args[1]); if (n_args > 2 && !ms_value_is_none (args[2])) dialog_text = ms_value_print (args[2]); dialog = gtk_dialog_new_with_buttons (NULL, ctx->window, GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); if (dialog_text) { GtkWidget *label; label = gtk_label_new (dialog_text); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, FALSE, FALSE, 0); } entry = moo_history_combo_new (user_id); moo_combo_set_use_button (MOO_COMBO (entry), FALSE); gtk_widget_show (entry); moo_combo_entry_set_text (MOO_COMBO (entry), entry_text ? entry_text : ""); moo_combo_entry_set_activates_default (MOO_COMBO (entry), TRUE); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), entry, FALSE, FALSE, 0); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { const char *text = moo_combo_entry_get_text (MOO_COMBO (entry)); if (text[0]) { moo_history_combo_commit (MOO_HISTORY_COMBO (entry)); result = ms_value_string (text); } else { result = ms_value_none (); } } else { result = ms_value_none (); } gtk_widget_destroy (dialog); g_free (dialog_text); g_free (entry_text); g_free (user_id); return result; } MSFunc * ms_zenity_history_entry (void) { return ms_cfunc_new_var (history_entry_func); } static MSValue* text_func (MSValue **args, guint n_args, MSContext *ctx) { char *dialog_text = NULL, *text = NULL; int response; GtkWidget *dialog, *textview, *swin; GtkTextBuffer *buffer; MSValue *result; CHECK_GTK (ctx); if (n_args > 0) text = ms_value_print (args[0]); if (n_args > 1) dialog_text = ms_value_print (args[1]); dialog = gtk_dialog_new_with_buttons (NULL, ctx->window, GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); if (dialog_text) { GtkWidget *label; label = gtk_label_new (dialog_text); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, FALSE, FALSE, 0); } swin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_ETCHED_IN); textview = gtk_text_view_new (); gtk_container_add (GTK_CONTAINER (swin), textview); gtk_widget_show_all (swin); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); gtk_text_buffer_set_text (buffer, text ? text : "", -1); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), swin, FALSE, FALSE, 0); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { GtkTextIter start, end; char *content; gtk_text_buffer_get_bounds (buffer, &start, &end); content = gtk_text_buffer_get_slice (buffer, &start, &end, TRUE); result = ms_value_take_string (content); } else { result = ms_value_none (); } gtk_widget_destroy (dialog); g_free (dialog_text); g_free (text); if (!gtk_main_level ()) while (gtk_events_pending ()) gtk_main_iteration (); return result; } MSFunc* ms_zenity_text (void) { return ms_cfunc_new_var (text_func); } static MSValue* message_dialog (MSValue **args, guint n_args, MSContext *ctx, GtkMessageType type, gboolean question) { char *dialog_text = NULL; GtkWidget *dialog; int response; CHECK_GTK (ctx); if (n_args > 0) dialog_text = ms_value_print (args[0]); dialog = gtk_message_dialog_new (ctx->window, GTK_DIALOG_MODAL, type, GTK_BUTTONS_NONE, "%s", dialog_text ? dialog_text : ""); if (question) { gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); } else { gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); } response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); if (!gtk_main_level ()) while (gtk_events_pending ()) gtk_main_iteration (); g_free (dialog_text); if (!question) return ms_value_none (); else if (response == GTK_RESPONSE_OK) return ms_value_true (); else return ms_value_false (); } static MSValue* info_func (MSValue **args, guint n_args, MSContext *ctx) { return message_dialog (args, n_args, ctx, GTK_MESSAGE_INFO, FALSE); } MSFunc * ms_zenity_info (void) { return ms_cfunc_new_var (info_func); } static MSValue* error_func (MSValue **args, guint n_args, MSContext *ctx) { return message_dialog (args, n_args, ctx, GTK_MESSAGE_ERROR, FALSE); } MSFunc * ms_zenity_error (void) { return ms_cfunc_new_var (error_func); } static MSValue* question_func (MSValue **args, guint n_args, MSContext *ctx) { return message_dialog (args, n_args, ctx, GTK_MESSAGE_QUESTION, TRUE); } MSFunc * ms_zenity_question (void) { return ms_cfunc_new_var (question_func); } static MSValue* warning_func (MSValue **args, guint n_args, MSContext *ctx) { return message_dialog (args, n_args, ctx, GTK_MESSAGE_WARNING, TRUE); } MSFunc * ms_zenity_warning (void) { return ms_cfunc_new_var (warning_func); } static MSValue* file_selector_func (MSValue **args, guint n_args, MSContext *ctx, MooFileDialogType type, gboolean multiple) { MooFileDialog *dialog; MSValue *ret; char *start = NULL, *title = NULL; CHECK_GTK (ctx); if (n_args > 0) title = ms_value_print (args[0]); if (n_args > 1) start = ms_value_print (args[1]); dialog = moo_file_dialog_new (type, ctx->window, multiple, title, start, NULL); g_free (title); g_free (start); if (!moo_file_dialog_run (dialog)) { g_object_unref (dialog); return ms_value_none (); } if (!multiple) { ret = ms_value_string (moo_file_dialog_get_filename (dialog)); } else { GSList *names, *l; guint n_names, i; names = moo_file_dialog_get_filenames (dialog); n_names = g_slist_length (names); ret = ms_value_list (n_names); for (i = 0, l = names; i < n_names; ++i, l = l->next) { MSValue *n = ms_value_take_string (l->data); ms_value_list_set_elm (ret, i, n); ms_value_unref (n); } g_slist_free (names); } g_object_unref (dialog); return ret; } static MSValue* choose_file_func (MSValue **args, guint n_args, MSContext *ctx) { return file_selector_func (args, n_args, ctx, MOO_FILE_DIALOG_OPEN, FALSE); } MSFunc* ms_zenity_choose_file (void) { return ms_cfunc_new_var (choose_file_func); } static MSValue* choose_files_func (MSValue **args, guint n_args, MSContext *ctx) { return file_selector_func (args, n_args, ctx, MOO_FILE_DIALOG_OPEN, TRUE); } MSFunc* ms_zenity_choose_files (void) { return ms_cfunc_new_var (choose_files_func); } static MSValue* choose_dir_func (MSValue **args, guint n_args, MSContext *ctx) { return file_selector_func (args, n_args, ctx, MOO_FILE_DIALOG_OPEN_DIR, FALSE); } MSFunc* ms_zenity_choose_dir (void) { return ms_cfunc_new_var (choose_dir_func); } static MSValue* choose_file_save_func (MSValue **args, guint n_args, MSContext *ctx) { return file_selector_func (args, n_args, ctx, MOO_FILE_DIALOG_SAVE, FALSE); } MSFunc* ms_zenity_choose_file_save (void) { return ms_cfunc_new_var (choose_file_save_func); }