1 /* Dialog boxes for Python. */
11 #include "bfu/inpfield.h"
12 #include "bfu/msgbox.h"
13 #include "intl/gettext/libintl.h"
14 #include "scripting/python/core.h"
15 #include "session/session.h"
16 #include "util/error.h"
17 #include "util/memlist.h"
18 #include "util/memory.h"
19 #include "util/string.h"
21 /* Python interface for displaying information to the user. */
23 static char python_info_box_doc
[] =
24 PYTHON_DOCSTRING("info_box(text[, title]) -> None\n\
26 Display information to the user in a dialog box.\n\
30 text -- The text to be displayed in the dialog box. This argument can\n\
31 be a string or any object that has a string representation as\n\
32 returned by str(object).\n\
34 Optional arguments:\n\
36 title -- A string containing a title for the dialog box. By default\n\
37 the string \"Info\" is used.\n");
40 python_info_box(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
42 /* [gettext_accelerator_context(python_info_box)] */
43 unsigned char *title
= N_("Info");
44 PyObject
*object
, *string_object
;
46 static char *kwlist
[] = {"text", "title", NULL
};
49 PyErr_SetString(python_elinks_err
, "No session");
53 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|s:info_box", kwlist
,
59 PyErr_SetString(python_elinks_err
, N_("Internal error"));
64 * Get a string representation of the object, then copy that string's
67 string_object
= PyObject_Str(object
);
68 if (!string_object
) return NULL
;
69 text
= (unsigned char *) PyString_AS_STRING(string_object
);
71 Py_DECREF(string_object
);
75 Py_DECREF(string_object
);
76 if (!text
) goto mem_error
;
78 title
= stracpy(title
);
79 if (!title
) goto free_text
;
81 (void) msg_box(python_ses
->tab
->term
, getml(title
, (void *) NULL
),
82 MSGBOX_NO_INTL
| MSGBOX_SCROLLABLE
| MSGBOX_FREE_TEXT
,
86 MSG_BOX_BUTTON(N_("~OK"), NULL
, B_ENTER
| B_ESC
));
95 return PyErr_NoMemory();
98 struct python_input_callback_hop
{
104 * C wrapper that invokes Python callbacks for input_dialog() OK button.
106 * This is also used indirectly for the Cancel button, with a NULL @text
107 * argument. See invoke_input_cancel_callback() below.
111 invoke_input_ok_callback(void *data
, unsigned char *text
)
113 struct python_input_callback_hop
*hop
= data
;
114 struct session
*saved_python_ses
= python_ses
;
117 assert(hop
&& hop
->callback
);
118 if_assert_failed
return;
120 python_ses
= hop
->ses
;
122 /* If @text is NULL, the "s" format will create a None reference. */
123 result
= PyObject_CallFunction(hop
->callback
, "s", text
);
127 alert_python_error();
129 Py_DECREF(hop
->callback
);
132 python_ses
= saved_python_ses
;
135 /* C wrapper that invokes Python callbacks for input_dialog() cancel button. */
138 invoke_input_cancel_callback(void *data
)
140 invoke_input_ok_callback(data
, NULL
);
143 /* Python interface for getting input from the user. */
145 static char python_input_box_doc
[] =
147 "input_box(prompt, callback, title=\"User dialog\", initial=\"\") -> None\n\
149 Display a dialog box to prompt for user input.\n\
153 prompt -- A string containing a prompt for the dialog box.\n\
154 callback -- A callable object to be called after the dialog is\n\
155 finished. It will be called with a single argument, which\n\
156 will be either a string provided by the user or else None\n\
157 if the user canceled the dialog.\n\
159 Optional keyword arguments:\n\
161 title -- A string containing a title for the dialog box. By default\n\
162 the string \"User dialog\" is used.\n\
163 initial -- A string containing an initial value for the text entry\n\
164 field. By default the entry field is initially empty.\n");
167 python_input_box(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
169 unsigned char *prompt
;
171 unsigned char *title
= N_("User dialog");
172 unsigned char *initial
= NULL
;
173 struct python_input_callback_hop
*hop
;
174 static char *kwlist
[] = {"prompt", "callback", "title", "initial", NULL
};
177 PyErr_SetString(python_elinks_err
, "No session");
181 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sO|ss:input_box",
182 kwlist
, &prompt
, &callback
, &title
,
186 assert(prompt
&& callback
&& title
);
188 PyErr_SetString(python_elinks_err
, N_("Internal error"));
192 prompt
= stracpy(prompt
);
193 if (!prompt
) goto mem_error
;
195 title
= stracpy(title
);
196 if (!title
) goto free_prompt
;
199 initial
= stracpy(initial
);
200 if (!initial
) goto free_title
;
203 hop
= mem_alloc(sizeof(*hop
));
204 if (!hop
) goto free_initial
;
205 hop
->ses
= python_ses
;
206 hop
->callback
= callback
;
209 input_dialog(python_ses
->tab
->term
,
210 getml(prompt
, (void *) title
, (void *) initial
, (void *) NULL
),
213 MAX_STR_LEN
, initial
, 0, 0, NULL
,
214 invoke_input_ok_callback
,
215 invoke_input_cancel_callback
);
221 mem_free_if(initial
);
230 return PyErr_NoMemory();
233 static PyMethodDef dialogs_methods
[] = {
234 {"info_box", (PyCFunction
) python_info_box
,
235 METH_VARARGS
| METH_KEYWORDS
,
236 python_info_box_doc
},
238 {"input_box", (PyCFunction
) python_input_box
,
239 METH_VARARGS
| METH_KEYWORDS
,
240 python_input_box_doc
},
242 {NULL
, NULL
, 0, NULL
}
246 python_init_dialogs_interface(PyObject
*dict
, PyObject
*name
)
248 return add_python_methods(dict
, name
, dialogs_methods
);