494 lines
13 KiB
Objective-C
494 lines
13 KiB
Objective-C
/*
|
|
* mooscript-zenity.c
|
|
*
|
|
* Copyright (C) 2004-2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 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 <gtk/gtk.h>
|
|
|
|
|
|
#define CHECK_GTK(ctx) \
|
|
G_STMT_START { \
|
|
if (!gtk_init_check (NULL, NULL)) \
|
|
return [ctx formatError: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar: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 [MSCFunc newVar:choose_file_save_func];
|
|
}
|
|
|
|
/* -*- objc -*- */
|