1
2 /******************************************************************************
3 * MODULE : editor.cpp
4 * DESCRIPTION: routines for the editor
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 ******************************************************************************/
11
12 #include "edit_main.hpp"
13 #include "tm_buffer.hpp"
14 #include "file.hpp"
15 #include "sys_utils.hpp"
16 #include "printer.hpp"
17 #include "convert.hpp"
18 #include "connect.hpp"
19 #include "typesetter.hpp"
20 #include "drd_std.hpp"
21 #include "message.hpp"
22 #include <setjmp.h>
23
24 #ifdef EXPERIMENTAL
25 #include "../../Style/Memorizer/clean_copy.hpp"
26 #endif
27
28 #ifdef PDF_RENDERER
29 //#include "Pdf/pdf_renderer.hpp"
30 #include "Pdf/pdf_hummus_renderer.hpp"
31 #endif
32
33 #ifdef USE_GS
34 #include "Ghostscript/gs_utilities.hpp"
35 #endif
36
37 #ifdef QTTEXMACS
38 #include "Qt/qt_gui.hpp"
39 #include "Qt/qt_utilities.hpp"
40 #endif
41
42 #if defined (QTTEXMACS) && (defined (__MINGW__) || defined (__MINGW32__))
43 #include "Qt/WINPrint.hpp"
44 #endif
45 /******************************************************************************
46 * Constructors and destructor
47 ******************************************************************************/
48
editor_rep()49 editor_rep::editor_rep ():
50 simple_widget_rep (), cvw (NULL), mvw (NULL),
51 drd (buf->buf->title, std_drd), et (the_et), rp (buf->rp) {}
52
editor_rep(server_rep * sv2,tm_buffer buf2)53 editor_rep::editor_rep (server_rep* sv2, tm_buffer buf2):
54 simple_widget_rep (), sv (sv2), cvw (NULL), mvw (NULL), buf (buf2),
55 drd (buf->buf->title, std_drd), et (the_et), rp (buf2->rp) {}
56
edit_main_rep(server_rep * sv,tm_buffer buf)57 edit_main_rep::edit_main_rep (server_rep* sv, tm_buffer buf):
58 editor_rep (sv, buf), props (UNKNOWN), ed_obs (edit_observer (this))
59 {
60 #ifdef EXPERIMENTAL
61 cct= copy (subtree (et, rp));
62 copy_ip (subtree (et, rp), cct);
63 #endif
64 attach_observer (subtree (et, rp), ed_obs);
65 notify_change (THE_TREE);
66 tp= correct_cursor (et, rp * 0);
67 }
68
~edit_main_rep()69 edit_main_rep::~edit_main_rep () {
70 detach_observer (subtree (et, rp), ed_obs);
71 #ifdef EXPERIMENTAL
72 mem= memorizer ();
73 #endif
74 }
75
76 editor
new_editor(server_rep * sv,tm_buffer buf)77 new_editor (server_rep* sv, tm_buffer buf) {
78 return tm_new<edit_main_rep> (sv, buf);
79 }
80
81 /******************************************************************************
82 * Properties
83 ******************************************************************************/
84
85 void
set_property(scheme_tree what,scheme_tree val)86 edit_main_rep::set_property (scheme_tree what, scheme_tree val) {
87 props (what)= val;
88 }
89
90 void
set_bool_property(string what,bool val)91 edit_main_rep::set_bool_property (string what, bool val) {
92 props (what)= (val? string ("true"): string ("false"));
93 }
94
95 void
set_int_property(string what,int val)96 edit_main_rep::set_int_property (string what, int val) {
97 props (what)= as_tree (val);
98 }
99
100 void
set_string_property(string what,string val)101 edit_main_rep::set_string_property (string what, string val) {
102 props (what)= val;
103 }
104
105 scheme_tree
get_property(scheme_tree what)106 edit_main_rep::get_property (scheme_tree what) {
107 return props [what];
108 }
109
110 bool
get_bool_property(string what)111 edit_main_rep::get_bool_property (string what) {
112 return as_bool (props [what]);
113 }
114
115 int
get_int_property(string what)116 edit_main_rep::get_int_property (string what) {
117 return as_int (props [what]);
118 }
119
120 string
get_string_property(string what)121 edit_main_rep::get_string_property (string what) {
122 return as_string (props [what]);
123 }
124
125 /******************************************************************************
126 * Global routines
127 ******************************************************************************/
128
129 void
clear_buffer()130 edit_main_rep::clear_buffer () {
131 assign (rp, tree (DOCUMENT, tree ("")));
132 }
133
134 void
new_window()135 edit_main_rep::new_window () {
136 }
137
138 void
clone_window()139 edit_main_rep::clone_window () {
140 }
141
142 void
tex_buffer()143 edit_main_rep::tex_buffer () {
144 }
145
146 url
get_name()147 edit_main_rep::get_name () {
148 return buf->buf->name;
149 }
150
151 void
focus_on_this_editor()152 edit_main_rep::focus_on_this_editor () {
153 focus_on_editor (this);
154 }
155
156 void
notify_page_change()157 edit_main_rep::notify_page_change () {
158 if (is_attached (this)) send_invalidate_all (this);
159 }
160
161 string
get_metadata(string kind)162 edit_main_rep::get_metadata (string kind) {
163 string var= "global-" * kind;
164 string val= get_init_string (var);
165 if (val != "") return val;
166 val= search_metadata (subtree (et, rp), kind);
167 if (val != "") return val;
168 if (kind == "title") return as_string (tail (get_name ()));
169 #ifndef __MINGW32__
170 if (kind == "author" &&
171 !is_none (resolve_in_path ("finger")) &&
172 !is_none (resolve_in_path ("sed"))) {
173 string val= var_eval_system ("finger `whoami` | sed -e '/Name/!d' -e 's/.*Name: //'");
174 if (N(val) > 1) return utf8_to_cork (val);
175 }
176 #endif
177 return "";
178 }
179
180 /******************************************************************************
181 * Printing
182 ******************************************************************************/
183
184 string printing_dpi ("600");
185 string printing_cmd ("lpr");
186 string printing_on ("a4");
187
188 bool
use_pdf()189 use_pdf () {
190 #ifdef PDF_RENDERER
191 return get_preference ("native pdf", "on") == "on";
192 #else
193 return false;
194 #endif
195 }
196
197 bool
use_ps()198 use_ps () {
199 #ifdef PDF_RENDERER
200 return get_preference ("native postscript", "on") == "on";
201 #else
202 return true;
203 #endif
204 }
205
206 void
print(url name,bool conform,int first,int last)207 edit_main_rep::print (url name, bool conform, int first, int last) {
208 bool ps = (suffix (name) == "ps");
209 bool pdf = (suffix (name) == "pdf");
210 url orig= resolve (name, "");
211
212 #ifdef USE_GS
213 if (!use_pdf () && pdf)
214 name= url_temp (".ps");
215 if (!use_ps () && ps)
216 name= url_temp (".pdf");
217 #endif
218
219 string medium = env->get_string (PAGE_MEDIUM);
220 if (conform && (medium != "paper")) conform= false;
221 // FIXME: better command for conform printing
222
223 // Set environment variables for printing
224
225 typeset_prepare ();
226 env->write (DPI, printing_dpi);
227 env->write (PAGE_SHOW_HF, "true");
228 env->write (PAGE_SCREEN_MARGIN, "false");
229 if (!conform) {
230 env->write (PAGE_MEDIUM, "paper");
231 env->write (PAGE_PRINTED, "true");
232 }
233
234 // Typeset pages for printing
235
236 box the_box= typeset_as_document (env, subtree (et, rp), reverse (rp));
237
238 // Determine parameters for printer
239
240 string page_type = env->get_string (PAGE_TYPE);
241 double w = env->page_width;
242 double h = env->page_height;
243 double cm = env->as_length (string ("1cm"));
244 bool landsc = env->page_landscape;
245 int dpi = as_int (printing_dpi);
246 int start = max (0, first-1);
247 int end = min (N(the_box[0]), last);
248 int pages = end-start;
249 if (conform) {
250 page_type= "user";
251 SI bw= the_box[0][0]->w();
252 SI bh= the_box[0][0]->h();
253 string bws= as_string (bw) * "tmpt";
254 string bhs= as_string (bh) * "tmpt";
255 w= env->as_length (bws);
256 h= env->as_length (bhs);
257 }
258
259 // Print pages
260 renderer ren;
261 #ifdef PDF_RENDERER
262 if (use_pdf () && (pdf || !use_ps ()))
263 ren= pdf_hummus_renderer (name, dpi, pages, page_type, landsc, w/cm, h/cm);
264 else
265 ren= printer (name, dpi, pages, page_type, landsc, w/cm, h/cm);
266 #else
267 ren= printer (name, dpi, pages, page_type, landsc, w/cm, h/cm);
268 #endif
269
270 if (ren->is_started ()) {
271 int i;
272 ren->set_metadata ("title", get_metadata ("title"));
273 ren->set_metadata ("author", get_metadata ("author"));
274 ren->set_metadata ("subject", get_metadata ("subject"));
275 for (i=start; i<end; i++) {
276 tree bg= env->read (BG_COLOR);
277 ren->set_background (bg);
278 if (bg != "white")
279 ren->clear_pattern (0, (SI) -h, (SI) w, 0);
280
281 rectangles rs;
282 the_box[0]->sx(i)= 0;
283 the_box[0]->sy(i)= 0;
284 the_box[0][i]->redraw (ren, path (0), rs);
285 if (i<end-1) ren->next_page ();
286 }
287 }
288 tm_delete (ren);
289
290 #ifdef USE_GS
291 if (!use_pdf () && pdf) {
292 gs_to_pdf (name, orig, landsc, h/cm, w/cm);
293 ::remove (name);
294 }
295 if (!use_ps () && ps) {
296 gs_to_ps (name, orig, landsc, h/cm, w/cm);
297 ::remove (name);
298 }
299 if (ps || pdf)
300 if (get_preference ("texmacs->pdf:check", "off") == "on") {
301 system_wait ("Checking exported file for correctness", "please wait");
302 gs_check (orig);
303 }
304 #endif
305 }
306
307 void
print_to_file(url name,string first,string last)308 edit_main_rep::print_to_file (url name, string first, string last) {
309 print (name, false, as_int (first), as_int (last));
310 set_message ("Done printing", "print to file");
311 }
312
313 void
print_buffer(string first,string last)314 edit_main_rep::print_buffer (string first, string last) {
315 url target;
316 #if defined (QTTEXMACS) && (defined (__MINGW__) || defined (__MINGW32__))
317 {
318 target= url_temp (".pdf");
319 WINPrint wprt(to_qstring(as_string(target)),env->page_landscape);
320 if(wprt.doit) print (target, false,wprt.first_page,wprt.last_page);
321 }
322 #else
323 target= url_temp (".ps");
324 print (target, false, as_int (first), as_int (last));
325 system (printing_cmd, target); // Send the document to the printer
326 set_message ("Done printing", "print buffer");
327 #endif
328 ::remove (target);
329 }
330
331 #ifdef THISISTHEPREVIOUSCODE_IJUSTLEFTITHEREINCASE
332 void
print_buffer(string first,string last)333 edit_main_rep::print_buffer (string first, string last) {
334 // in Qt this is the main entry point to the printing subsystem.
335 // the other routines (print_to_file, ...) are overriden since all fine tuning
336 // is made here via the Qt print dialog
337 bool to_file, landscape;
338 url name = url_none();
339 string printer;
340 string paper_type;
341 if (qt_print (to_file, landscape, printer, name, first, last, paper_type)) {
342 if (!to_file) name = url_temp (".ps");
343 print (name, false, as_int (first), as_int (last));
344 if (!to_file) {
345 string cmd = printing_cmd * " -P" * printer;
346 system (cmd, name);
347 ::remove (name);
348 }
349 }
350 }
351 #endif
352
353 void
export_ps(url name,string first,string last)354 edit_main_rep::export_ps (url name, string first, string last) {
355 print (name, true, as_int (first), as_int (last));
356 }
357
358 array<int>
print_snippet(url name,tree t)359 edit_main_rep::print_snippet (url name, tree t) {
360 bool ps= suffix (name) == "ps" || suffix (name) == "eps";
361 typeset_prepare ();
362 int dpi= as_int (printing_dpi);
363 //if (!ps) t= tree (WITH, MAGNIFICATION, "2", PAGE_WIDTH, "40cm", t);
364 if (!ps) t= tree (WITH, MAGNIFICATION, "1.6", PAGE_WIDTH, "40cm", t);
365 box b= typeset_as_box (env, t, path ());
366 if (b->x4 - b->x3 >= 5*PIXEL && b->y4 - b->y3 >= 5*PIXEL) {
367 if (ps) make_eps (name, b, dpi);
368 else {
369 url temp= url_temp (".eps");
370 make_eps (temp, b, dpi);
371 ::remove (name);
372 system ("convert", temp, name);
373 if (!exists (name))
374 cout << "TeXmacs] warning, failed to create image " << name << "\n";
375 ::remove (temp);
376 }
377 }
378 array<int> a;
379 a << b->x3 << b->y3 << b->x4 << b->y4;
380 return a;
381 }
382
383 bool
graphics_file_to_clipboard(url name)384 edit_main_rep::graphics_file_to_clipboard (url name) {
385 #ifdef QTTEXMACS
386 the_gui->put_graphics_on_clipboard (name);
387 return true;
388 #else
389 return false;
390 #endif
391 }
392
393 /******************************************************************************
394 * Evaluation of expressions
395 ******************************************************************************/
396
397 void
footer_eval(string s)398 edit_main_rep::footer_eval (string s) {
399 // s= unslash (s); // FIXME: dirty fix; should not be necessary
400 s= tm_decode (s);
401 string r= object_to_string (eval (s));
402 set_message (verbatim (r), "evaluate expression");
403 }
404
405 tree
the_line()406 edit_main_rep::the_line () {
407 path p= search_parent_upwards (DOCUMENT);
408 return copy (subtree (et, p));
409 }
410
411 tree
the_root()412 edit_main_rep::the_root () {
413 return et;
414 }
415
416 tree
the_buffer()417 edit_main_rep::the_buffer () {
418 return subtree (et, rp);
419 }
420
421 tree
the_subtree(path p)422 edit_main_rep::the_subtree (path p) {
423 return subtree (et, p);
424 }
425
426 path
the_buffer_path()427 edit_main_rep::the_buffer_path () {
428 return copy (rp);
429 }
430
431 path
the_path()432 edit_main_rep::the_path () {
433 return copy (tp);
434 }
435
436 path
the_shifted_path()437 edit_main_rep::the_shifted_path () {
438 return shift (et, tp, 1);
439 }
440
441 /******************************************************************************
442 * Miscellaneous
443 ******************************************************************************/
444
445 void
show_tree()446 edit_main_rep::show_tree () {
447 stretched_print (et, true);
448 // cout << et << "\n";
449 }
450
451 void
show_env()452 edit_main_rep::show_env () {
453 cout << env << "\n";
454 }
455
456 void
show_path()457 edit_main_rep::show_path () {
458 cout << tp << "\n";
459 }
460
461 void
show_cursor()462 edit_main_rep::show_cursor () {
463 cout << "Principal cursor: "
464 << cu->ox << ", " << cu->oy << " [" << cu->delta << "]\n";
465 cout << "Ghost cursor : "
466 << mv->ox << ", " << mv->oy << " [" << mv->delta << "]\n";
467 }
468
469 void
show_selection()470 edit_main_rep::show_selection () {
471 selection sel; selection_get (sel);
472 cout << "physical selection: " << cur_sel << "\n";
473 cout << "logical selection: " << sel->start << " --- " << sel->end << "\n";
474 }
475
476 void
show_meminfo()477 edit_main_rep::show_meminfo () {
478 mem_info ();
479 }
480
481 void
edit_special()482 edit_main_rep::edit_special () {
483 }
484
485 #ifdef UNCOMMENTED
486 void test_commute ();
487 void test_invert ();
488 #endif
489
490 void
edit_test()491 edit_main_rep::edit_test () {
492 cout << "Test !\n";
493 #ifdef UNCOMMENTED
494 test_commute();
495 test_invert();
496 #endif
497 }
498