2 /******************************************************************************
3 * MODULE : tm_dialogue.cpp
4 * DESCRIPTION: Dialogues
5 * COPYRIGHT : (C) 1999 Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
12 #include "tm_frame.hpp"
13 #include "tm_window.hpp"
14 #include "convert.hpp"
16 #include "analyze.hpp"
17 #include "message.hpp"
18 #include "dictionary.hpp"
20 /******************************************************************************
22 ******************************************************************************/
24 class dialogue_command_rep
: public command_rep
{
30 dialogue_command_rep (server_rep
* sv2
, object fun2
, int nr_args2
):
31 sv (sv2
), fun (fun2
), nr_args (nr_args2
) {}
33 ostream
& print (ostream
& out
) {
34 return out
<< "Dialogue"; }
38 dialogue_command_rep::apply () {
40 object cmd
= null_object ();
41 object learn
= null_object ();
42 for (i
=nr_args
-1; i
>=0; i
--) {
44 sv
->dialogue_inquire (i
, s_arg
);
46 exec_delayed (scheme_cmd ("(dialogue-end)"));
49 object arg
= string_to_object (s_arg
);
50 learn
= cons (cons (object (as_string (i
)), arg
), learn
);
52 //call ("learn-interactive-arg", fun, object (i), arg);
54 call ("learn-interactive", fun
, learn
);
56 exec_delayed (scheme_cmd ("(dialogue-end)"));
57 exec_delayed (scheme_cmd (cmd
));
61 dialogue_command (server_rep
* sv
, object fun
, int nr_args
) {
62 return tm_new
<dialogue_command_rep
> (sv
, fun
, nr_args
);
66 tm_frame_rep::dialogue_start (string name
, widget wid
) {
67 if (is_nil (dialogue_win
)) {
68 string lan
= get_output_language ();
69 if (lan
== "russian") lan
= "english";
70 name
= translate (name
, "english", lan
);
72 dialogue_win
= plain_window_widget (dialogue_wid
, name
);
74 widget win
= get_window () -> win
;
75 SI ox
, oy
, dx
, dy
, ex
= 0, ey
= 0;
76 get_position (win
, ox
, oy
);
77 get_size (win
, dx
, dy
);
78 get_size (dialogue_win
, ex
, ey
);
81 set_position (dialogue_win
, ox
, oy
);
82 set_visibility (dialogue_win
, true);
87 tm_frame_rep::dialogue_inquire (int i
, string
& arg
) {
88 if (i
== 0) arg
= get_string_input (dialogue_wid
);
90 widget field_i
= get_form_field (dialogue_wid
, i
);
91 arg
= get_string_input (field_i
);
96 tm_frame_rep::dialogue_end () {
97 if (!is_nil (dialogue_win
)) {
98 set_visibility (dialogue_win
, false);
99 destroy_window_widget (dialogue_win
);
100 dialogue_win
= widget ();
101 dialogue_wid
= widget ();
107 if (i
<j
) return gcd (j
, i
);
113 tm_frame_rep::choose_file (object fun
, string title
, string type
) {
115 if (type
== "image") {
116 editor ed
= get_editor ();
117 int dpi
= as_int (ed
->get_env_string (DPI
));
118 int sfactor
= get_window () -> get_shrinking_factor ();
119 int num
= 75*sfactor
;
121 int g
= gcd (num
, den
);
123 if (num
!= 1) magn
<< "*" << as_string (num
);
124 if (den
!= 1) magn
<< "/" << as_string (den
);
127 url name
= get_name_buffer ();
128 command cb
= dialogue_command (get_server(), fun
, 1);
129 widget wid
= file_chooser_widget (cb
, type
, magn
);
130 if (!is_scratch (name
)) {
131 set_directory (wid
, as_string (head (name
)));
132 if ((type
!= "image") && (type
!= "")) {
134 string old_suf
= suffix (u
);
135 string new_suf
= format_to_suffix (type
);
136 if ((suffix_to_format (suffix (u
)) != type
) &&
137 (old_suf
!= "") && (new_suf
!= ""))
139 u
= unglue (u
, N(old_suf
) + 1);
140 u
= glue (u
, "." * new_suf
);
142 set_file (wid
, as_string (u
));
145 else set_directory (wid
, ".");
146 dialogue_start (title
, wid
);
147 if (type
== "directory") send_keyboard_focus (get_directory (dialogue_wid
));
148 else send_keyboard_focus (get_file (dialogue_wid
));
151 /******************************************************************************
152 * Interactive commands
153 ******************************************************************************/
156 get_prompt (scheme_tree p
, int i
) {
157 if (is_atomic (p
[i
]) && is_quoted (p
[i
]->label
))
158 return scm_unquote (p
[i
]->label
);
159 else if (is_tuple (p
[i
]) && N(p
[i
])>0 &&
160 is_atomic (p
[i
][0]) && is_quoted (p
[i
][0]->label
))
161 return scm_unquote (p
[i
][0]->label
);
166 get_type (scheme_tree p
, int i
) {
167 if (is_tuple (p
[i
]) && N(p
[i
])>1 &&
168 is_atomic (p
[i
][1]) && is_quoted (p
[i
][1]->label
))
169 return scm_unquote (p
[i
][1]->label
);
174 get_proposals (scheme_tree p
, int i
) {
176 if (is_tuple (p
[i
]) && N(p
[i
]) >= 2) {
179 if (is_atomic (p
[i
][j
]) && is_quoted (p
[i
][j
]->label
))
180 a
<< scm_unquote (p
[i
][j
]->label
);
185 class interactive_command_rep
: public command_rep
{
186 server_rep
* sv
; // the underlying server
187 tm_window win
; // the underlying TeXmacs window
188 object fun
; // the function which is applied to the arguments
189 scheme_tree p
; // the interactive arguments
190 int i
; // counter where we are
191 array
<string
> s
; // feedback from interaction with user
194 interactive_command_rep (
195 server_rep
* sv2
, tm_window win2
, object fun2
, scheme_tree p2
):
196 sv (sv2
), win (win2
), fun (fun2
), p (p2
), i (0), s (N(p
)) {}
198 ostream
& print (ostream
& out
) {
199 return out
<< "interactive command " << p
; }
203 interactive_command_rep::apply () {
204 if ((i
>0) && (s
[i
-1] == "#f")) return;
206 object learn
= null_object ();
207 array
<object
> params (N(p
));
208 for (i
=N(p
)-1; i
>=0; i
--) {
209 params
[i
]= string_to_object (s
[i
]);
210 learn
= cons (cons (object (as_string (i
)), params
[i
]), learn
);
212 call ("learn-interactive", fun
, learn
);
213 string ret
= object_to_string (call (fun
, params
));
214 if (ret
!= "" && ret
!= "<unspecified>" && ret
!= "#<unspecified>")
215 sv
->set_message (ret
, "interactive command");
219 string prompt
= get_prompt (p
, i
);
220 string type
= get_type (p
, i
);
221 array
<string
> proposals
= get_proposals (p
, i
);
222 win
->interactive (prompt
, type
, proposals
, s
[i
], this);
228 tm_frame_rep::interactive (object fun
, scheme_tree p
) {
230 fatal_error ("tuple expected", "edit_interface_rep::interactive");
231 if (get_preference ("interactive questions") == "popup") {
233 array
<string
> prompts (n
);
235 prompts
[i
]= get_prompt (p
, i
);
236 command cb
= dialogue_command (get_server(), fun
, n
);
237 widget wid
= inputs_list_widget (cb
, prompts
);
238 for (i
=0; i
<n
; i
++) {
239 widget input_wid
= get_form_field (wid
, i
);
240 set_input_type (input_wid
, get_type (p
, i
));
241 array
<string
> proposals
= get_proposals (p
, i
);
242 int j
, k
= N(proposals
);
243 if (k
> 0) set_string_input (input_wid
, proposals
[0]);
244 for (j
=0; j
<k
; j
++) add_input_proposal (input_wid
, proposals
[j
]);
246 string title
= "Enter data";
247 if (ends (prompts
[0], "?")) title
= "Question";
248 dialogue_start (title
, wid
);
249 send_keyboard_focus (get_form_field (dialogue_wid
, 0));
252 if (get_window () -> get_interactive_mode ()) beep ();
254 command interactive_cmd
=
255 tm_new
<interactive_command_rep
> (this, get_window (), fun
, p
);