Replace new -> tm_new and delete -> tm_delete
[texmacs.git] / src / src / Texmacs / Window / tm_dialogue.cpp
blob5983f158659a65d5061ea3ad2b53dec94263dffa
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"
15 #include "file.hpp"
16 #include "analyze.hpp"
17 #include "message.hpp"
18 #include "dictionary.hpp"
20 /******************************************************************************
21 * Dialogues
22 ******************************************************************************/
24 class dialogue_command_rep: public command_rep {
25 server_rep* sv;
26 object fun;
27 int nr_args;
29 public:
30 dialogue_command_rep (server_rep* sv2, object fun2, int nr_args2):
31 sv (sv2), fun (fun2), nr_args (nr_args2) {}
32 void apply ();
33 ostream& print (ostream& out) {
34 return out << "Dialogue"; }
37 void
38 dialogue_command_rep::apply () {
39 int i;
40 object cmd = null_object ();
41 object learn= null_object ();
42 for (i=nr_args-1; i>=0; i--) {
43 string s_arg;
44 sv->dialogue_inquire (i, s_arg);
45 if (s_arg == "#f") {
46 exec_delayed (scheme_cmd ("(dialogue-end)"));
47 return;
49 object arg= string_to_object (s_arg);
50 learn= cons (cons (object (as_string (i)), arg), learn);
51 cmd= cons (arg, cmd);
52 //call ("learn-interactive-arg", fun, object (i), arg);
54 call ("learn-interactive", fun, learn);
55 cmd= cons (fun, cmd);
56 exec_delayed (scheme_cmd ("(dialogue-end)"));
57 exec_delayed (scheme_cmd (cmd));
60 command
61 dialogue_command (server_rep* sv, object fun, int nr_args) {
62 return tm_new<dialogue_command_rep> (sv, fun, nr_args);
65 void
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);
71 dialogue_wid= wid;
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);
79 ox += (dx - ex) >> 1;
80 oy -= (dy - ey) >> 1;
81 set_position (dialogue_win, ox, oy);
82 set_visibility (dialogue_win, true);
86 void
87 tm_frame_rep::dialogue_inquire (int i, string& arg) {
88 if (i == 0) arg= get_string_input (dialogue_wid);
89 else {
90 widget field_i= get_form_field (dialogue_wid, i);
91 arg= get_string_input (field_i);
95 void
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 ();
105 static int
106 gcd (int i, int j) {
107 if (i<j) return gcd (j, i);
108 if (j==0) return i;
109 return gcd (j, i%j);
112 void
113 tm_frame_rep::choose_file (object fun, string title, string type) {
114 string magn;
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;
120 int den = dpi;
121 int g = gcd (num, den);
122 num /= g; den /= g;
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 != "")) {
133 url u= tail (name);
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 ******************************************************************************/
155 static string
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);
162 return "Input:";
165 static string
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);
170 return "string";
173 static array<string>
174 get_proposals (scheme_tree p, int i) {
175 array<string> a;
176 if (is_tuple (p[i]) && N(p[i]) >= 2) {
177 int j, n= N(p[i]);
178 for (j=2; j<n; j++)
179 if (is_atomic (p[i][j]) && is_quoted (p[i][j]->label))
180 a << scm_unquote (p[i][j]->label);
182 return a;
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
193 public:
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)) {}
197 void apply ();
198 ostream& print (ostream& out) {
199 return out << "interactive command " << p; }
202 void
203 interactive_command_rep::apply () {
204 if ((i>0) && (s[i-1] == "#f")) return;
205 if (i == N(p)) {
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");
217 else {
218 s[i]= string ("");
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);
223 i++;
227 void
228 tm_frame_rep::interactive (object fun, scheme_tree p) {
229 if (!is_tuple (p))
230 fatal_error ("tuple expected", "edit_interface_rep::interactive");
231 if (get_preference ("interactive questions") == "popup") {
232 int i, n= N(p);
233 array<string> prompts (n);
234 for (i=0; i<n; i++)
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));
251 else {
252 if (get_window () -> get_interactive_mode ()) beep ();
253 else {
254 command interactive_cmd=
255 tm_new<interactive_command_rep> (this, get_window (), fun, p);
256 interactive_cmd ();