1 | // |
---|
2 | // "$Id$" |
---|
3 | // |
---|
4 | // FLUID main entry for the Fast Light Tool Kit (FLTK). |
---|
5 | // |
---|
6 | // Copyright 1998-2007 by Bill Spitzak and others. |
---|
7 | // |
---|
8 | // This library is free software; you can redistribute it and/or |
---|
9 | // modify it under the terms of the GNU Library General Public |
---|
10 | // License as published by the Free Software Foundation; either |
---|
11 | // version 2 of the License, or (at your option) any later version. |
---|
12 | // |
---|
13 | // This library is distributed in the hope that it will be useful, |
---|
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
16 | // Library General Public License for more details. |
---|
17 | // |
---|
18 | // You should have received a copy of the GNU Library General Public |
---|
19 | // License along with this library; if not, write to the Free Software |
---|
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
---|
21 | // USA. |
---|
22 | // |
---|
23 | // Please report all bugs and problems on the following page: |
---|
24 | // |
---|
25 | // http://www.fltk.org/str.php |
---|
26 | // |
---|
27 | |
---|
28 | #include <FL/Fl.H> |
---|
29 | #include <FL/Fl_Double_Window.H> |
---|
30 | #include <FL/Fl_Box.H> |
---|
31 | #include <FL/Fl_Button.H> |
---|
32 | #include <FL/Fl_File_Icon.H> |
---|
33 | #include <FL/Fl_Help_Dialog.H> |
---|
34 | #include <FL/Fl_Hold_Browser.H> |
---|
35 | #include <FL/Fl_Menu_Bar.H> |
---|
36 | #include <FL/Fl_Input.H> |
---|
37 | #include <FL/fl_ask.H> |
---|
38 | #include <FL/fl_draw.H> |
---|
39 | #include <FL/Fl_File_Chooser.H> |
---|
40 | #include <FL/fl_message.H> |
---|
41 | #include <FL/filename.H> |
---|
42 | #include <stdio.h> |
---|
43 | #include <stdlib.h> |
---|
44 | #include <errno.h> |
---|
45 | #include <sys/stat.h> |
---|
46 | #include <time.h> // time(), localtime(), etc. |
---|
47 | |
---|
48 | #include "../src/flstring.h" |
---|
49 | #include "alignment_panel.h" |
---|
50 | #include "function_panel.h" |
---|
51 | #include "template_panel.h" |
---|
52 | #if !defined(WIN32) || defined(__CYGWIN__) |
---|
53 | # include "print_panel.cxx" |
---|
54 | #endif // !WIN32 || __CYGWIN__ |
---|
55 | |
---|
56 | #if defined(WIN32) && !defined(__CYGWIN__) |
---|
57 | # include <direct.h> |
---|
58 | # include <windows.h> |
---|
59 | # include <io.h> |
---|
60 | # include <commdlg.h> |
---|
61 | # include <FL/x.H> |
---|
62 | # ifndef __WATCOMC__ |
---|
63 | // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs |
---|
64 | // on Windows, which is supposed to be POSIX compliant... |
---|
65 | # define access _access |
---|
66 | # define chdir _chdir |
---|
67 | # define getcwd _getcwd |
---|
68 | # endif // !__WATCOMC__ |
---|
69 | #else |
---|
70 | # include <unistd.h> |
---|
71 | #endif |
---|
72 | #ifdef __EMX__ |
---|
73 | # include <X11/Xlibint.h> |
---|
74 | #endif |
---|
75 | |
---|
76 | #include "about_panel.h" |
---|
77 | #include "undo.h" |
---|
78 | |
---|
79 | #include "Fl_Type.h" |
---|
80 | |
---|
81 | extern "C" |
---|
82 | { |
---|
83 | #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) |
---|
84 | # include <zlib.h> |
---|
85 | # ifdef HAVE_PNG_H |
---|
86 | # include <png.h> |
---|
87 | # else |
---|
88 | # include <libpng/png.h> |
---|
89 | # endif // HAVE_PNG_H |
---|
90 | #endif // HAVE_LIBPNG && HAVE_LIBZ |
---|
91 | } |
---|
92 | |
---|
93 | static Fl_Help_Dialog *help_dialog = 0; |
---|
94 | |
---|
95 | Fl_Preferences fluid_prefs(Fl_Preferences::USER, "fltk.org", "fluid"); |
---|
96 | int gridx = 5; |
---|
97 | int gridy = 5; |
---|
98 | int snap = 1; |
---|
99 | int show_guides = 1; |
---|
100 | |
---|
101 | // File history info... |
---|
102 | char absolute_history[10][1024]; |
---|
103 | char relative_history[10][1024]; |
---|
104 | |
---|
105 | void load_history(); |
---|
106 | void update_history(const char *); |
---|
107 | |
---|
108 | // Shell command support... |
---|
109 | void show_shell_window(); |
---|
110 | |
---|
111 | //////////////////////////////////////////////////////////////// |
---|
112 | |
---|
113 | static const char *filename; |
---|
114 | void set_filename(const char *c); |
---|
115 | void set_modflag(int mf); |
---|
116 | int modflag; |
---|
117 | |
---|
118 | static char* pwd; |
---|
119 | static char in_source_dir; |
---|
120 | void goto_source_dir() { |
---|
121 | if (in_source_dir) return; |
---|
122 | if (!filename || !*filename) return; |
---|
123 | const char *p = fl_filename_name(filename); |
---|
124 | if (p <= filename) return; // it is in the current directory |
---|
125 | char buffer[1024]; |
---|
126 | strlcpy(buffer, filename, sizeof(buffer)); |
---|
127 | int n = p-filename; if (n>1) n--; buffer[n] = 0; |
---|
128 | if (!pwd) { |
---|
129 | pwd = getcwd(0,1024); |
---|
130 | if (!pwd) {fprintf(stderr,"getwd : %s\n",strerror(errno)); return;} |
---|
131 | } |
---|
132 | if (chdir(buffer)<0) {fprintf(stderr, "Can't chdir to %s : %s\n", |
---|
133 | buffer, strerror(errno)); return;} |
---|
134 | in_source_dir = 1; |
---|
135 | } |
---|
136 | |
---|
137 | void leave_source_dir() { |
---|
138 | if (!in_source_dir) return; |
---|
139 | if (chdir(pwd)<0) {fprintf(stderr, "Can't chdir to %s : %s\n", |
---|
140 | pwd, strerror(errno));} |
---|
141 | in_source_dir = 0; |
---|
142 | } |
---|
143 | |
---|
144 | char position_window(Fl_Window *w, const char *prefsName, int Visible, int X, int Y, int W=0, int H=0 ) { |
---|
145 | Fl_Preferences pos(fluid_prefs, prefsName); |
---|
146 | if (prevpos_button->value()) { |
---|
147 | pos.get("x", X, X); |
---|
148 | pos.get("y", Y, Y); |
---|
149 | if ( W!=0 ) { |
---|
150 | pos.get("w", W, W); |
---|
151 | pos.get("h", H, H); |
---|
152 | w->resize( X, Y, W, H ); |
---|
153 | } |
---|
154 | else |
---|
155 | w->position( X, Y ); |
---|
156 | } |
---|
157 | pos.get("visible", Visible, Visible); |
---|
158 | return Visible; |
---|
159 | } |
---|
160 | |
---|
161 | void save_position(Fl_Window *w, const char *prefsName) { |
---|
162 | Fl_Preferences pos(fluid_prefs, prefsName); |
---|
163 | pos.set("x", w->x()); |
---|
164 | pos.set("y", w->y()); |
---|
165 | pos.set("w", w->w()); |
---|
166 | pos.set("h", w->h()); |
---|
167 | pos.set("visible", (int)(w->shown() && w->visible())); |
---|
168 | } |
---|
169 | |
---|
170 | Fl_Window *main_window; |
---|
171 | Fl_Menu_Bar *main_menubar; |
---|
172 | |
---|
173 | static char* cutfname(int which = 0) { |
---|
174 | static char name[2][1024]; |
---|
175 | static char beenhere = 0; |
---|
176 | |
---|
177 | if (!beenhere) { |
---|
178 | beenhere = 1; |
---|
179 | fluid_prefs.getUserdataPath(name[0], sizeof(name[0])); |
---|
180 | strlcat(name[0], "cut_buffer", sizeof(name[0])); |
---|
181 | fluid_prefs.getUserdataPath(name[1], sizeof(name[1])); |
---|
182 | strlcat(name[1], "dup_buffer", sizeof(name[1])); |
---|
183 | } |
---|
184 | |
---|
185 | return name[which]; |
---|
186 | } |
---|
187 | |
---|
188 | void save_cb(Fl_Widget *, void *v) { |
---|
189 | const char *c = filename; |
---|
190 | if (v || !c || !*c) { |
---|
191 | fl_file_chooser_ok_label("Save"); |
---|
192 | c=fl_file_chooser("Save To:", "FLUID Files (*.f[ld])", c); |
---|
193 | fl_file_chooser_ok_label(NULL); |
---|
194 | if (!c) return; |
---|
195 | |
---|
196 | if (!access(c, 0)) { |
---|
197 | const char *basename; |
---|
198 | if ((basename = strrchr(c, '/')) != NULL) |
---|
199 | basename ++; |
---|
200 | #if defined(WIN32) || defined(__EMX__) |
---|
201 | if ((basename = strrchr(c, '\\')) != NULL) |
---|
202 | basename ++; |
---|
203 | #endif // WIN32 || __EMX__ |
---|
204 | else |
---|
205 | basename = c; |
---|
206 | |
---|
207 | if (fl_choice("The file \"%s\" already exists.\n" |
---|
208 | "Do you want to replace it?", "Cancel", |
---|
209 | "Replace", NULL, basename) == 0) return; |
---|
210 | } |
---|
211 | |
---|
212 | if (v != (void *)2) set_filename(c); |
---|
213 | } |
---|
214 | if (!write_file(c)) { |
---|
215 | fl_alert("Error writing %s: %s", c, strerror(errno)); |
---|
216 | return; |
---|
217 | } |
---|
218 | |
---|
219 | if (v != (void *)2) { |
---|
220 | set_modflag(0); |
---|
221 | undo_save = undo_current; |
---|
222 | } |
---|
223 | } |
---|
224 | |
---|
225 | void save_template_cb(Fl_Widget *, void *) { |
---|
226 | // Setup the template panel... |
---|
227 | if (!template_panel) make_template_panel(); |
---|
228 | |
---|
229 | template_clear(); |
---|
230 | template_browser->add("New Template"); |
---|
231 | template_load(); |
---|
232 | |
---|
233 | template_name->show(); |
---|
234 | template_name->value(""); |
---|
235 | |
---|
236 | template_instance->hide(); |
---|
237 | |
---|
238 | template_delete->show(); |
---|
239 | template_delete->deactivate(); |
---|
240 | |
---|
241 | template_submit->label("Save"); |
---|
242 | template_submit->deactivate(); |
---|
243 | |
---|
244 | template_panel->label("Save Template"); |
---|
245 | |
---|
246 | // Show the panel and wait for the user to do something... |
---|
247 | template_panel->show(); |
---|
248 | while (template_panel->shown()) Fl::wait(); |
---|
249 | |
---|
250 | // Get the template name, return if it is empty... |
---|
251 | const char *c = template_name->value(); |
---|
252 | if (!c || !*c) return; |
---|
253 | |
---|
254 | // Convert template name to filename_with_underscores |
---|
255 | char safename[1024], *safeptr; |
---|
256 | strlcpy(safename, c, sizeof(safename)); |
---|
257 | for (safeptr = safename; *safeptr; safeptr ++) { |
---|
258 | if (isspace(*safeptr)) *safeptr = '_'; |
---|
259 | } |
---|
260 | |
---|
261 | // Find the templates directory... |
---|
262 | char filename[1024]; |
---|
263 | fluid_prefs.getUserdataPath(filename, sizeof(filename)); |
---|
264 | |
---|
265 | strlcat(filename, "templates", sizeof(filename)); |
---|
266 | #if defined(WIN32) && !defined(__CYGWIN__) |
---|
267 | if (access(filename, 0)) mkdir(filename); |
---|
268 | #else |
---|
269 | if (access(filename, 0)) mkdir(filename, 0777); |
---|
270 | #endif // WIN32 && !__CYGWIN__ |
---|
271 | |
---|
272 | strlcat(filename, "/", sizeof(filename)); |
---|
273 | strlcat(filename, safename, sizeof(filename)); |
---|
274 | |
---|
275 | char *ext = filename + strlen(filename); |
---|
276 | if (ext >= (filename + sizeof(filename) - 5)) { |
---|
277 | fl_alert("The template name \"%s\" is too long!", c); |
---|
278 | return; |
---|
279 | } |
---|
280 | |
---|
281 | // Save the .fl file... |
---|
282 | strcpy(ext, ".fl"); |
---|
283 | |
---|
284 | if (!access(filename, 0)) { |
---|
285 | if (fl_choice("The template \"%s\" already exists.\n" |
---|
286 | "Do you want to replace it?", "Cancel", |
---|
287 | "Replace", NULL, c) == 0) return; |
---|
288 | } |
---|
289 | |
---|
290 | if (!write_file(filename)) { |
---|
291 | fl_alert("Error writing %s: %s", filename, strerror(errno)); |
---|
292 | return; |
---|
293 | } |
---|
294 | |
---|
295 | #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) |
---|
296 | // Get the screenshot, if any... |
---|
297 | Fl_Type *t; |
---|
298 | |
---|
299 | for (t = Fl_Type::first; t; t = t->next) { |
---|
300 | // Find the first window... |
---|
301 | if (t->is_window()) break; |
---|
302 | } |
---|
303 | |
---|
304 | if (!t) return; |
---|
305 | |
---|
306 | // Grab a screenshot... |
---|
307 | Fl_Window_Type *wt = (Fl_Window_Type *)t; |
---|
308 | uchar *pixels; |
---|
309 | int w, h; |
---|
310 | |
---|
311 | if ((pixels = wt->read_image(w, h)) == NULL) return; |
---|
312 | |
---|
313 | // Save to a PNG file... |
---|
314 | strcpy(ext, ".png"); |
---|
315 | |
---|
316 | FILE *fp; |
---|
317 | |
---|
318 | if ((fp = fopen(filename, "wb")) == NULL) { |
---|
319 | delete[] pixels; |
---|
320 | fl_alert("Error writing %s: %s", filename, strerror(errno)); |
---|
321 | return; |
---|
322 | } |
---|
323 | |
---|
324 | png_structp pptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); |
---|
325 | png_infop iptr = png_create_info_struct(pptr); |
---|
326 | png_bytep ptr = (png_bytep)pixels; |
---|
327 | |
---|
328 | png_init_io(pptr, fp); |
---|
329 | png_set_IHDR(pptr, iptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, |
---|
330 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); |
---|
331 | png_set_sRGB(pptr, iptr, PNG_sRGB_INTENT_PERCEPTUAL); |
---|
332 | |
---|
333 | png_write_info(pptr, iptr); |
---|
334 | |
---|
335 | for (int i = h; i > 0; i --, ptr += w * 3) { |
---|
336 | png_write_row(pptr, ptr); |
---|
337 | } |
---|
338 | |
---|
339 | png_write_end(pptr, iptr); |
---|
340 | png_destroy_write_struct(&pptr, &iptr); |
---|
341 | |
---|
342 | fclose(fp); |
---|
343 | |
---|
344 | # if 0 // The original PPM output code... |
---|
345 | strcpy(ext, ".ppm"); |
---|
346 | fp = fopen(filename, "wb"); |
---|
347 | fprintf(fp, "P6\n%d %d 255\n", w, h); |
---|
348 | fwrite(pixels, w * h, 3, fp); |
---|
349 | fclose(fp); |
---|
350 | # endif // 0 |
---|
351 | |
---|
352 | delete[] pixels; |
---|
353 | #endif // HAVE_LIBPNG && HAVE_LIBZ |
---|
354 | } |
---|
355 | |
---|
356 | void revert_cb(Fl_Widget *,void *) { |
---|
357 | if (modflag) { |
---|
358 | if (!fl_choice("This user interface has been changed. Really revert?", |
---|
359 | "Cancel", "Revert", NULL)) return; |
---|
360 | } |
---|
361 | undo_suspend(); |
---|
362 | if (!read_file(filename, 0)) { |
---|
363 | undo_resume(); |
---|
364 | fl_message("Can't read %s: %s", filename, strerror(errno)); |
---|
365 | return; |
---|
366 | } |
---|
367 | undo_resume(); |
---|
368 | set_modflag(0); |
---|
369 | undo_clear(); |
---|
370 | } |
---|
371 | |
---|
372 | void exit_cb(Fl_Widget *,void *) { |
---|
373 | if (modflag) |
---|
374 | switch (fl_choice("Do you want to save changes to this user\n" |
---|
375 | "interface before exiting?", "Cancel", |
---|
376 | "Save", "Don't Save")) |
---|
377 | { |
---|
378 | case 0 : /* Cancel */ |
---|
379 | return; |
---|
380 | case 1 : /* Save */ |
---|
381 | save_cb(NULL, NULL); |
---|
382 | if (modflag) return; // Didn't save! |
---|
383 | } |
---|
384 | |
---|
385 | save_position(main_window,"main_window_pos"); |
---|
386 | |
---|
387 | if (widgetbin_panel) { |
---|
388 | save_position(widgetbin_panel,"widgetbin_pos"); |
---|
389 | delete widgetbin_panel; |
---|
390 | } |
---|
391 | if (sourceview_panel) { |
---|
392 | Fl_Preferences svp(fluid_prefs, "sourceview"); |
---|
393 | svp.set("autorefresh", sv_autorefresh->value()); |
---|
394 | svp.set("autoposition", sv_autoposition->value()); |
---|
395 | svp.set("tab", sv_tab->find(sv_tab->value())); |
---|
396 | save_position(sourceview_panel,"sourceview_pos"); |
---|
397 | delete sourceview_panel; |
---|
398 | } |
---|
399 | if (about_panel) |
---|
400 | delete about_panel; |
---|
401 | if (help_dialog) |
---|
402 | delete help_dialog; |
---|
403 | |
---|
404 | undo_clear(); |
---|
405 | |
---|
406 | exit(0); |
---|
407 | } |
---|
408 | |
---|
409 | #ifdef __APPLE__ |
---|
410 | # include <FL/x.H> |
---|
411 | |
---|
412 | void |
---|
413 | apple_open_cb(const char *c) { |
---|
414 | if (modflag) { |
---|
415 | switch (fl_choice("Do you want to save changes to this user\n" |
---|
416 | "interface before opening another one?", "Don't Save", |
---|
417 | "Save", "Cancel")) |
---|
418 | { |
---|
419 | case 0 : /* Cancel */ |
---|
420 | return; |
---|
421 | case 1 : /* Save */ |
---|
422 | save_cb(NULL, NULL); |
---|
423 | if (modflag) return; // Didn't save! |
---|
424 | } |
---|
425 | } |
---|
426 | const char *oldfilename; |
---|
427 | oldfilename = filename; |
---|
428 | filename = NULL; |
---|
429 | set_filename(c); |
---|
430 | undo_suspend(); |
---|
431 | if (!read_file(c, 0)) { |
---|
432 | undo_resume(); |
---|
433 | fl_message("Can't read %s: %s", c, strerror(errno)); |
---|
434 | free((void *)filename); |
---|
435 | filename = oldfilename; |
---|
436 | if (main_window) main_window->label(filename); |
---|
437 | return; |
---|
438 | } |
---|
439 | |
---|
440 | // Loaded a file; free the old filename... |
---|
441 | set_modflag(0); |
---|
442 | undo_resume(); |
---|
443 | undo_clear(); |
---|
444 | if (oldfilename) free((void *)oldfilename); |
---|
445 | } |
---|
446 | #endif // __APPLE__ |
---|
447 | |
---|
448 | void open_cb(Fl_Widget *, void *v) { |
---|
449 | if (!v && modflag) { |
---|
450 | switch (fl_choice("Do you want to save changes to this user\n" |
---|
451 | "interface before opening another one?", "Cancel", |
---|
452 | "Save", "Don't Save")) |
---|
453 | { |
---|
454 | case 0 : /* Cancel */ |
---|
455 | return; |
---|
456 | case 1 : /* Save */ |
---|
457 | save_cb(NULL, NULL); |
---|
458 | if (modflag) return; // Didn't save! |
---|
459 | } |
---|
460 | } |
---|
461 | const char *c; |
---|
462 | const char *oldfilename; |
---|
463 | fl_file_chooser_ok_label("Open"); |
---|
464 | c = fl_file_chooser("Open:", "FLUID Files (*.f[ld])", filename); |
---|
465 | fl_file_chooser_ok_label(NULL); |
---|
466 | if (!c) return; |
---|
467 | oldfilename = filename; |
---|
468 | filename = NULL; |
---|
469 | set_filename(c); |
---|
470 | if (v != 0) undo_checkpoint(); |
---|
471 | undo_suspend(); |
---|
472 | if (!read_file(c, v!=0)) { |
---|
473 | undo_resume(); |
---|
474 | fl_message("Can't read %s: %s", c, strerror(errno)); |
---|
475 | free((void *)filename); |
---|
476 | filename = oldfilename; |
---|
477 | if (main_window) set_modflag(modflag); |
---|
478 | return; |
---|
479 | } |
---|
480 | undo_resume(); |
---|
481 | if (v) { |
---|
482 | // Inserting a file; restore the original filename... |
---|
483 | free((void *)filename); |
---|
484 | filename = oldfilename; |
---|
485 | set_modflag(1); |
---|
486 | } else { |
---|
487 | // Loaded a file; free the old filename... |
---|
488 | set_modflag(0); |
---|
489 | undo_clear(); |
---|
490 | if (oldfilename) free((void *)oldfilename); |
---|
491 | } |
---|
492 | } |
---|
493 | |
---|
494 | void open_history_cb(Fl_Widget *, void *v) { |
---|
495 | if (modflag) { |
---|
496 | switch (fl_choice("Do you want to save changes to this user\n" |
---|
497 | "interface before opening another one?", "Cancel", |
---|
498 | "Save", "Don't Save")) |
---|
499 | { |
---|
500 | case 0 : /* Cancel */ |
---|
501 | return; |
---|
502 | case 1 : /* Save */ |
---|
503 | save_cb(NULL, NULL); |
---|
504 | if (modflag) return; // Didn't save! |
---|
505 | } |
---|
506 | } |
---|
507 | const char *oldfilename = filename; |
---|
508 | filename = NULL; |
---|
509 | set_filename((char *)v); |
---|
510 | undo_suspend(); |
---|
511 | if (!read_file(filename, 0)) { |
---|
512 | undo_resume(); |
---|
513 | undo_clear(); |
---|
514 | fl_message("Can't read %s: %s", filename, strerror(errno)); |
---|
515 | free((void *)filename); |
---|
516 | filename = oldfilename; |
---|
517 | if (main_window) main_window->label(filename); |
---|
518 | return; |
---|
519 | } |
---|
520 | set_modflag(0); |
---|
521 | undo_resume(); |
---|
522 | undo_clear(); |
---|
523 | if (oldfilename) free((void *)oldfilename); |
---|
524 | } |
---|
525 | |
---|
526 | void new_cb(Fl_Widget *, void *v) { |
---|
527 | // Check if the current file has been modified... |
---|
528 | if (!v && modflag) { |
---|
529 | // Yes, ask the user what to do... |
---|
530 | switch (fl_choice("Do you want to save changes to this user\n" |
---|
531 | "interface before creating a new one?", "Cancel", |
---|
532 | "Save", "Don't Save")) |
---|
533 | { |
---|
534 | case 0 : /* Cancel */ |
---|
535 | return; |
---|
536 | case 1 : /* Save */ |
---|
537 | save_cb(NULL, NULL); |
---|
538 | if (modflag) return; // Didn't save! |
---|
539 | } |
---|
540 | } |
---|
541 | |
---|
542 | // Setup the template panel... |
---|
543 | if (!template_panel) make_template_panel(); |
---|
544 | |
---|
545 | template_clear(); |
---|
546 | template_browser->add("Blank"); |
---|
547 | template_load(); |
---|
548 | |
---|
549 | template_name->hide(); |
---|
550 | template_name->value(""); |
---|
551 | |
---|
552 | template_instance->show(); |
---|
553 | template_instance->deactivate(); |
---|
554 | template_instance->value(""); |
---|
555 | |
---|
556 | template_delete->hide(); |
---|
557 | |
---|
558 | template_submit->label("New"); |
---|
559 | template_submit->deactivate(); |
---|
560 | |
---|
561 | template_panel->label("New"); |
---|
562 | |
---|
563 | // Show the panel and wait for the user to do something... |
---|
564 | template_panel->show(); |
---|
565 | while (template_panel->shown()) Fl::wait(); |
---|
566 | |
---|
567 | // See if the user chose anything... |
---|
568 | int item = template_browser->value(); |
---|
569 | if (item < 1) return; |
---|
570 | |
---|
571 | // Clear the current data... |
---|
572 | delete_all(); |
---|
573 | set_filename(NULL); |
---|
574 | |
---|
575 | // Load the template, if any... |
---|
576 | const char *tname = (const char *)template_browser->data(item); |
---|
577 | |
---|
578 | if (tname) { |
---|
579 | // Grab the instance name... |
---|
580 | const char *iname = template_instance->value(); |
---|
581 | |
---|
582 | if (iname && *iname) { |
---|
583 | // Copy the template to a temp file, then read it in... |
---|
584 | char line[1024], *ptr, *next; |
---|
585 | FILE *infile, *outfile; |
---|
586 | |
---|
587 | if ((infile = fopen(tname, "r")) == NULL) { |
---|
588 | fl_alert("Error reading template file \"%s\":\n%s", tname, |
---|
589 | strerror(errno)); |
---|
590 | set_modflag(0); |
---|
591 | undo_clear(); |
---|
592 | return; |
---|
593 | } |
---|
594 | |
---|
595 | if ((outfile = fopen(cutfname(1), "w")) == NULL) { |
---|
596 | fl_alert("Error writing buffer file \"%s\":\n%s", cutfname(1), |
---|
597 | strerror(errno)); |
---|
598 | fclose(infile); |
---|
599 | set_modflag(0); |
---|
600 | undo_clear(); |
---|
601 | return; |
---|
602 | } |
---|
603 | |
---|
604 | while (fgets(line, sizeof(line), infile)) { |
---|
605 | // Replace @INSTANCE@ with the instance name... |
---|
606 | for (ptr = line; (next = strstr(ptr, "@INSTANCE@")) != NULL; ptr = next + 10) { |
---|
607 | fwrite(ptr, next - ptr, 1, outfile); |
---|
608 | fputs(iname, outfile); |
---|
609 | } |
---|
610 | |
---|
611 | fputs(ptr, outfile); |
---|
612 | } |
---|
613 | |
---|
614 | fclose(infile); |
---|
615 | fclose(outfile); |
---|
616 | |
---|
617 | undo_suspend(); |
---|
618 | read_file(cutfname(1), 0); |
---|
619 | unlink(cutfname(1)); |
---|
620 | undo_resume(); |
---|
621 | } else { |
---|
622 | // No instance name, so read the template without replacements... |
---|
623 | undo_suspend(); |
---|
624 | read_file(tname, 0); |
---|
625 | undo_resume(); |
---|
626 | } |
---|
627 | } |
---|
628 | |
---|
629 | set_modflag(0); |
---|
630 | undo_clear(); |
---|
631 | } |
---|
632 | |
---|
633 | int compile_only = 0; |
---|
634 | int compile_strings = 0; |
---|
635 | int header_file_set = 0; |
---|
636 | int code_file_set = 0; |
---|
637 | const char* header_file_name = ".h"; |
---|
638 | const char* code_file_name = ".cxx"; |
---|
639 | int i18n_type = 0; |
---|
640 | const char* i18n_include = ""; |
---|
641 | const char* i18n_function = ""; |
---|
642 | const char* i18n_file = ""; |
---|
643 | const char* i18n_set = ""; |
---|
644 | char i18n_program[1024] = ""; |
---|
645 | |
---|
646 | void write_cb(Fl_Widget *, void *) { |
---|
647 | if (!filename) { |
---|
648 | save_cb(0,0); |
---|
649 | if (!filename) return; |
---|
650 | } |
---|
651 | char cname[1024]; |
---|
652 | char hname[1024]; |
---|
653 | strlcpy(i18n_program, fl_filename_name(filename), sizeof(i18n_program)); |
---|
654 | fl_filename_setext(i18n_program, sizeof(i18n_program), ""); |
---|
655 | if (*code_file_name == '.' && strchr(code_file_name, '/') == NULL) { |
---|
656 | strlcpy(cname, fl_filename_name(filename), sizeof(cname)); |
---|
657 | fl_filename_setext(cname, sizeof(cname), code_file_name); |
---|
658 | } else { |
---|
659 | strlcpy(cname, code_file_name, sizeof(hname)); |
---|
660 | } |
---|
661 | if (*header_file_name == '.' && strchr(header_file_name, '/') == NULL) { |
---|
662 | strlcpy(hname, fl_filename_name(filename), sizeof(hname)); |
---|
663 | fl_filename_setext(hname, sizeof(hname), header_file_name); |
---|
664 | } else { |
---|
665 | strlcpy(hname, header_file_name, sizeof(hname)); |
---|
666 | } |
---|
667 | if (!compile_only) goto_source_dir(); |
---|
668 | int x = write_code(cname,hname); |
---|
669 | if (!compile_only) leave_source_dir(); |
---|
670 | strlcat(cname, " and ", sizeof(cname)); |
---|
671 | strlcat(cname, hname, sizeof(cname)); |
---|
672 | if (compile_only) { |
---|
673 | if (!x) {fprintf(stderr,"%s : %s\n",cname,strerror(errno)); exit(1);} |
---|
674 | } else { |
---|
675 | if (!x) { |
---|
676 | fl_message("Can't write %s: %s", cname, strerror(errno)); |
---|
677 | } else if (completion_button->value()) { |
---|
678 | fl_message("Wrote %s", cname); |
---|
679 | } |
---|
680 | } |
---|
681 | } |
---|
682 | |
---|
683 | void write_strings_cb(Fl_Widget *, void *) { |
---|
684 | static const char *exts[] = { ".txt", ".po", ".msg" }; |
---|
685 | if (!filename) { |
---|
686 | save_cb(0,0); |
---|
687 | if (!filename) return; |
---|
688 | } |
---|
689 | char sname[1024]; |
---|
690 | strlcpy(sname, fl_filename_name(filename), sizeof(sname)); |
---|
691 | fl_filename_setext(sname, sizeof(sname), exts[i18n_type]); |
---|
692 | if (!compile_only) goto_source_dir(); |
---|
693 | int x = write_strings(sname); |
---|
694 | if (!compile_only) leave_source_dir(); |
---|
695 | if (compile_only) { |
---|
696 | if (x) {fprintf(stderr,"%s : %s\n",sname,strerror(errno)); exit(1);} |
---|
697 | } else { |
---|
698 | if (x) { |
---|
699 | fl_message("Can't write %s: %s", sname, strerror(errno)); |
---|
700 | } else if (completion_button->value()) { |
---|
701 | fl_message("Wrote %s", sname); |
---|
702 | } |
---|
703 | } |
---|
704 | } |
---|
705 | |
---|
706 | void openwidget_cb(Fl_Widget *, void *) { |
---|
707 | if (!Fl_Type::current) { |
---|
708 | fl_message("Please select a widget"); |
---|
709 | return; |
---|
710 | } |
---|
711 | Fl_Type::current->open(); |
---|
712 | } |
---|
713 | |
---|
714 | void toggle_overlays(Fl_Widget *,void *); |
---|
715 | |
---|
716 | void select_all_cb(Fl_Widget *,void *); |
---|
717 | void select_none_cb(Fl_Widget *,void *); |
---|
718 | |
---|
719 | void group_cb(Fl_Widget *, void *); |
---|
720 | |
---|
721 | void ungroup_cb(Fl_Widget *, void *); |
---|
722 | |
---|
723 | extern int pasteoffset; |
---|
724 | static int ipasteoffset; |
---|
725 | |
---|
726 | void copy_cb(Fl_Widget*, void*) { |
---|
727 | if (!Fl_Type::current) { |
---|
728 | fl_beep(); |
---|
729 | return; |
---|
730 | } |
---|
731 | ipasteoffset = 10; |
---|
732 | if (!write_file(cutfname(),1)) { |
---|
733 | fl_message("Can't write %s: %s", cutfname(), strerror(errno)); |
---|
734 | return; |
---|
735 | } |
---|
736 | } |
---|
737 | |
---|
738 | extern void select_only(Fl_Type *); |
---|
739 | void cut_cb(Fl_Widget *, void *) { |
---|
740 | if (!Fl_Type::current) { |
---|
741 | fl_beep(); |
---|
742 | return; |
---|
743 | } |
---|
744 | if (!write_file(cutfname(),1)) { |
---|
745 | fl_message("Can't write %s: %s", cutfname(), strerror(errno)); |
---|
746 | return; |
---|
747 | } |
---|
748 | undo_checkpoint(); |
---|
749 | set_modflag(1); |
---|
750 | ipasteoffset = 0; |
---|
751 | Fl_Type *p = Fl_Type::current->parent; |
---|
752 | while (p && p->selected) p = p->parent; |
---|
753 | delete_all(1); |
---|
754 | if (p) select_only(p); |
---|
755 | } |
---|
756 | |
---|
757 | void delete_cb(Fl_Widget *, void *) { |
---|
758 | if (!Fl_Type::current) { |
---|
759 | fl_beep(); |
---|
760 | return; |
---|
761 | } |
---|
762 | undo_checkpoint(); |
---|
763 | set_modflag(1); |
---|
764 | ipasteoffset = 0; |
---|
765 | Fl_Type *p = Fl_Type::current->parent; |
---|
766 | while (p && p->selected) p = p->parent; |
---|
767 | delete_all(1); |
---|
768 | if (p) select_only(p); |
---|
769 | } |
---|
770 | |
---|
771 | extern int force_parent; |
---|
772 | |
---|
773 | void paste_cb(Fl_Widget*, void*) { |
---|
774 | //if (ipasteoffset) force_parent = 1; |
---|
775 | pasteoffset = ipasteoffset; |
---|
776 | if (gridx>1) pasteoffset = ((pasteoffset-1)/gridx+1)*gridx; |
---|
777 | if (gridy>1) pasteoffset = ((pasteoffset-1)/gridy+1)*gridy; |
---|
778 | undo_checkpoint(); |
---|
779 | undo_suspend(); |
---|
780 | if (!read_file(cutfname(), 1)) { |
---|
781 | fl_message("Can't read %s: %s", cutfname(), strerror(errno)); |
---|
782 | } |
---|
783 | undo_resume(); |
---|
784 | pasteoffset = 0; |
---|
785 | ipasteoffset += 10; |
---|
786 | force_parent = 0; |
---|
787 | } |
---|
788 | |
---|
789 | // Duplicate the selected widgets... |
---|
790 | void duplicate_cb(Fl_Widget*, void*) { |
---|
791 | if (!Fl_Type::current) { |
---|
792 | fl_beep(); |
---|
793 | return; |
---|
794 | } |
---|
795 | |
---|
796 | if (!write_file(cutfname(1),1)) { |
---|
797 | fl_message("Can't write %s: %s", cutfname(1), strerror(errno)); |
---|
798 | return; |
---|
799 | } |
---|
800 | |
---|
801 | pasteoffset = 0; |
---|
802 | force_parent = 1; |
---|
803 | |
---|
804 | undo_checkpoint(); |
---|
805 | undo_suspend(); |
---|
806 | if (!read_file(cutfname(1), 1)) { |
---|
807 | fl_message("Can't read %s: %s", cutfname(1), strerror(errno)); |
---|
808 | } |
---|
809 | unlink(cutfname(1)); |
---|
810 | undo_resume(); |
---|
811 | |
---|
812 | force_parent = 0; |
---|
813 | } |
---|
814 | |
---|
815 | void earlier_cb(Fl_Widget*,void*); |
---|
816 | |
---|
817 | void later_cb(Fl_Widget*,void*); |
---|
818 | |
---|
819 | Fl_Type *sort(Fl_Type *parent); |
---|
820 | |
---|
821 | static void sort_cb(Fl_Widget *,void *) { |
---|
822 | sort((Fl_Type*)0); |
---|
823 | } |
---|
824 | |
---|
825 | void show_project_cb(Fl_Widget *, void *); |
---|
826 | void show_grid_cb(Fl_Widget *, void *); |
---|
827 | void show_settings_cb(Fl_Widget *, void *); |
---|
828 | |
---|
829 | void align_widget_cb(Fl_Widget *, long); |
---|
830 | void widget_size_cb(Fl_Widget *, long); |
---|
831 | |
---|
832 | void about_cb(Fl_Widget *, void *) { |
---|
833 | if (!about_panel) make_about_panel(); |
---|
834 | about_panel->show(); |
---|
835 | } |
---|
836 | |
---|
837 | void show_help(const char *name) { |
---|
838 | const char *docdir; |
---|
839 | char helpname[1024]; |
---|
840 | |
---|
841 | if (!help_dialog) help_dialog = new Fl_Help_Dialog(); |
---|
842 | |
---|
843 | if ((docdir = getenv("FLTK_DOCDIR")) == NULL) { |
---|
844 | #ifdef __EMX__ |
---|
845 | // Doesn't make sense to have a hardcoded fallback |
---|
846 | static char fltk_docdir[1024]; |
---|
847 | |
---|
848 | strlcpy(fltk_docdir, __XOS2RedirRoot("/XFree86/lib/X11/fltk/doc"), |
---|
849 | sizeof(fltk_docdir)); |
---|
850 | |
---|
851 | docdir = fltk_docdir; |
---|
852 | #else |
---|
853 | docdir = FLTK_DOCDIR; |
---|
854 | #endif // __EMX__ |
---|
855 | } |
---|
856 | snprintf(helpname, sizeof(helpname), "%s/%s", docdir, name); |
---|
857 | |
---|
858 | help_dialog->load(helpname); |
---|
859 | help_dialog->show(); |
---|
860 | } |
---|
861 | |
---|
862 | void help_cb(Fl_Widget *, void *) { |
---|
863 | show_help("fluid.html"); |
---|
864 | } |
---|
865 | |
---|
866 | void manual_cb(Fl_Widget *, void *) { |
---|
867 | show_help("index.html"); |
---|
868 | } |
---|
869 | |
---|
870 | |
---|
871 | //////////////////////////////////////////////////////////////// |
---|
872 | |
---|
873 | #if defined(WIN32) && !defined(__CYGWIN__) |
---|
874 | // Draw a shaded box... |
---|
875 | static void win_box(int x, int y, int w, int h) { |
---|
876 | fl_color(0xc0, 0xc0, 0xc0); |
---|
877 | fl_rectf(x, y, w, h); |
---|
878 | fl_color(0, 0, 0); |
---|
879 | fl_rect(x, y, w, h); |
---|
880 | fl_color(0xf0, 0xf0, 0xf0); |
---|
881 | fl_rectf(x + 1, y + 1, 4, h - 2); |
---|
882 | fl_rectf(x + 1, y + 1, w - 2, 4); |
---|
883 | fl_color(0x90, 0x90, 0x90); |
---|
884 | fl_rectf(x + w - 5, y + 1, 4, h - 2); |
---|
885 | fl_rectf(x + 1, y + h - 5, w - 2, 4); |
---|
886 | } |
---|
887 | |
---|
888 | // Load and show the print dialog... |
---|
889 | void print_menu_cb(Fl_Widget *, void *) { |
---|
890 | PRINTDLG dialog; // Print dialog |
---|
891 | DOCINFO docinfo; // Document info |
---|
892 | int first, last; // First and last page |
---|
893 | int page; // Current page |
---|
894 | int winpage; // Current window page |
---|
895 | int num_pages; // Number of pages |
---|
896 | Fl_Type *t; // Current widget |
---|
897 | int num_windows; // Number of windows |
---|
898 | Fl_Window_Type *windows[1000]; // Windows to print |
---|
899 | |
---|
900 | |
---|
901 | // Show print dialog... |
---|
902 | for (t = Fl_Type::first, num_pages = 0; t; t = t->next) { |
---|
903 | if (t->is_window()) num_pages ++; |
---|
904 | } |
---|
905 | |
---|
906 | memset(&dialog, 0, sizeof(dialog)); |
---|
907 | dialog.lStructSize = sizeof(dialog); |
---|
908 | dialog.hwndOwner = fl_xid(main_window); |
---|
909 | dialog.Flags = PD_ALLPAGES | |
---|
910 | PD_RETURNDC; |
---|
911 | dialog.nFromPage = 1; |
---|
912 | dialog.nToPage = num_pages; |
---|
913 | dialog.nMinPage = 1; |
---|
914 | dialog.nMaxPage = num_pages; |
---|
915 | dialog.nCopies = 1; |
---|
916 | |
---|
917 | if (!PrintDlg(&dialog)) return; |
---|
918 | |
---|
919 | // Get the base filename... |
---|
920 | const char *basename = strrchr(filename, '/'); |
---|
921 | if (basename) basename ++; |
---|
922 | else basename = filename; |
---|
923 | |
---|
924 | // Do the print job... |
---|
925 | memset(&docinfo, 0, sizeof(docinfo)); |
---|
926 | docinfo.cbSize = sizeof(docinfo); |
---|
927 | docinfo.lpszDocName = basename; |
---|
928 | |
---|
929 | StartDoc(dialog.hDC, &docinfo); |
---|
930 | |
---|
931 | // Figure out how many pages we'll have to print... |
---|
932 | if (dialog.Flags & PD_PAGENUMS) { |
---|
933 | // Get from and to page numbers... |
---|
934 | first = dialog.nFromPage; |
---|
935 | last = dialog.nToPage; |
---|
936 | |
---|
937 | if (first > last) { |
---|
938 | // Swap first/last page |
---|
939 | page = first; |
---|
940 | first = last; |
---|
941 | last = page; |
---|
942 | } |
---|
943 | } else { |
---|
944 | // Print everything... |
---|
945 | first = 1; |
---|
946 | last = dialog.nMaxPage; |
---|
947 | } |
---|
948 | |
---|
949 | for (t = Fl_Type::first, num_windows = 0, winpage = 0; t; t = t->next) { |
---|
950 | if (t->is_window()) { |
---|
951 | winpage ++; |
---|
952 | windows[num_windows] = (Fl_Window_Type *)t; |
---|
953 | num_windows ++; |
---|
954 | #if 0 |
---|
955 | if (dialog.Flags & PD_ALLPAGES) num_windows ++; |
---|
956 | else if ((dialog.Flags & PD_PAGENUMS) && winpage >= first && |
---|
957 | winpage <= last) num_windows ++; |
---|
958 | else if ((dialog.Flags & PD_SELECTION) && t->selected) num_windows ++; |
---|
959 | #endif // 0 |
---|
960 | } |
---|
961 | } |
---|
962 | |
---|
963 | num_pages = num_windows; |
---|
964 | |
---|
965 | // Figure out the page size and margins... |
---|
966 | int width, length; // Size of page |
---|
967 | int xdpi, ydpi; // Output resolution |
---|
968 | char buffer[1024]; |
---|
969 | |
---|
970 | width = GetDeviceCaps(dialog.hDC, HORZRES); |
---|
971 | length = GetDeviceCaps(dialog.hDC, VERTRES); |
---|
972 | xdpi = GetDeviceCaps(dialog.hDC, LOGPIXELSX); |
---|
973 | ydpi = GetDeviceCaps(dialog.hDC, LOGPIXELSY); |
---|
974 | |
---|
975 | // fl_message("width=%d, length=%d, xdpi=%d, ydpi=%d, num_windows=%d\n", |
---|
976 | // width, length, xdpi, ydpi, num_windows); |
---|
977 | |
---|
978 | HDC save_dc = fl_gc; |
---|
979 | HWND save_win = fl_window; |
---|
980 | int fontsize = 14 * ydpi / 72; |
---|
981 | |
---|
982 | fl_gc = dialog.hDC; |
---|
983 | fl_window = (HWND)dialog.hDC; |
---|
984 | fl_push_no_clip(); |
---|
985 | |
---|
986 | // Get the time and date... |
---|
987 | time_t curtime = time(NULL); |
---|
988 | struct tm *curdate = localtime(&curtime); |
---|
989 | char date[1024]; |
---|
990 | |
---|
991 | strftime(date, sizeof(date), "%c", curdate); |
---|
992 | |
---|
993 | // Print each of the windows... |
---|
994 | for (winpage = 0; winpage < num_windows; winpage ++) { |
---|
995 | // Draw header... |
---|
996 | StartPage(dialog.hDC); |
---|
997 | |
---|
998 | fl_font(FL_HELVETICA_BOLD, fontsize); |
---|
999 | fl_color(0, 0, 0); |
---|
1000 | |
---|
1001 | fl_draw(basename, 0, fontsize); |
---|
1002 | |
---|
1003 | fl_draw(date, (width - (int)fl_width(date)) / 2, fontsize); |
---|
1004 | |
---|
1005 | sprintf(buffer, "%d/%d", winpage + 1, num_windows); |
---|
1006 | fl_draw(buffer, width - (int)fl_width(buffer), fontsize); |
---|
1007 | |
---|
1008 | // Get window image... |
---|
1009 | uchar *pixels; // Window image data |
---|
1010 | int w, h; // Window image dimensions |
---|
1011 | int ww, hh; // Scaled size |
---|
1012 | int ulx, uly; // Upper-lefthand corner |
---|
1013 | Fl_Window *win; // Window widget |
---|
1014 | BITMAPINFO info; // Bitmap information |
---|
1015 | |
---|
1016 | win = (Fl_Window *)(windows[winpage]->o); |
---|
1017 | pixels = windows[winpage]->read_image(w, h); |
---|
1018 | |
---|
1019 | // Swap colors: FLTK uses R-G-B --> Windows GDI uses B-G-R |
---|
1020 | |
---|
1021 | { uchar *p = pixels; |
---|
1022 | for (int i=0; i<w*h; i++, p+=3) { |
---|
1023 | uchar temp = p[0]; p[0] = p[2]; p[2] = temp; |
---|
1024 | } |
---|
1025 | } |
---|
1026 | |
---|
1027 | // Figure out the window size, first at 100 PPI and then scaled |
---|
1028 | // down if that is too big... |
---|
1029 | ww = w * xdpi / 100; |
---|
1030 | hh = h * ydpi / 100; |
---|
1031 | |
---|
1032 | if (ww > width) { |
---|
1033 | ww = width; |
---|
1034 | hh = h * ww * ydpi / xdpi / w; |
---|
1035 | } |
---|
1036 | |
---|
1037 | if (hh > (length - ydpi / 2)) { |
---|
1038 | hh = length - ydpi / 2; |
---|
1039 | ww = w * hh / h; |
---|
1040 | } |
---|
1041 | |
---|
1042 | // Position the window in the center... |
---|
1043 | ulx = (width - ww) / 2; |
---|
1044 | uly = (length - hh) / 2; |
---|
1045 | |
---|
1046 | // fl_message("winpage=%d, ulx=%d, uly=%d, ww=%d, hh=%d", |
---|
1047 | // winpage, ulx, uly, ww, hh); |
---|
1048 | |
---|
1049 | // Draw a simulated window border... |
---|
1050 | int xborder = 4 * ww / w; |
---|
1051 | int yborder = 4 * hh / h; |
---|
1052 | |
---|
1053 | win_box(ulx - xborder, uly - 5 * yborder, |
---|
1054 | ww + 2 * xborder, hh + 6 * yborder); |
---|
1055 | |
---|
1056 | fl_color(0, 0, 255); |
---|
1057 | fl_rectf(ulx, uly - 4 * yborder, ww, 4 * yborder); |
---|
1058 | |
---|
1059 | fl_font(FL_HELVETICA_BOLD, 2 * yborder); |
---|
1060 | fl_color(255, 255, 255); |
---|
1061 | fl_draw(win->label() ? win->label() : "Window", |
---|
1062 | ulx + xborder, uly - 3 * yborder); |
---|
1063 | |
---|
1064 | int x = ulx + ww - 4 * xborder; |
---|
1065 | |
---|
1066 | win_box(x, uly - 4 * yborder, 4 * xborder, 4 * yborder); |
---|
1067 | fl_color(0, 0, 0); |
---|
1068 | fl_line(x + xborder, uly - yborder, |
---|
1069 | x + 3 * xborder, uly - 3 * yborder); |
---|
1070 | fl_line(x + xborder, uly - 3 * yborder, |
---|
1071 | x + 3 * xborder, uly - yborder); |
---|
1072 | x -= 4 * xborder; |
---|
1073 | |
---|
1074 | if (win->resizable()) { |
---|
1075 | win_box(x, uly - 4 * yborder, 4 * xborder, 4 * yborder); |
---|
1076 | fl_color(0, 0, 0); |
---|
1077 | fl_rect(x + xborder, uly - 3 * yborder, 2 * xborder, 2 * yborder); |
---|
1078 | x -= 4 * xborder; |
---|
1079 | } |
---|
1080 | |
---|
1081 | if (!win->modal()) { |
---|
1082 | win_box(x, uly - 4 * yborder, 4 * xborder, 4 * yborder); |
---|
1083 | fl_color(0, 0, 0); |
---|
1084 | fl_line(x + xborder, uly - yborder, x + 3 * xborder, uly - yborder); |
---|
1085 | x -= 4 * xborder; |
---|
1086 | } |
---|
1087 | |
---|
1088 | // Color image... |
---|
1089 | memset(&info, 0, sizeof(info)); |
---|
1090 | info.bmiHeader.biSize = sizeof(info); |
---|
1091 | info.bmiHeader.biWidth = w; |
---|
1092 | info.bmiHeader.biHeight = 1; |
---|
1093 | info.bmiHeader.biPlanes = 1; |
---|
1094 | info.bmiHeader.biBitCount = 24; |
---|
1095 | info.bmiHeader.biCompression = BI_RGB; |
---|
1096 | |
---|
1097 | for (int y = 0; y < h; y ++) { |
---|
1098 | StretchDIBits(dialog.hDC, ulx, uly + y * hh / h, ww, (hh + h - 1) / h, 0, 0, w, 1, |
---|
1099 | pixels + y * w * 3, &info, DIB_RGB_COLORS, SRCCOPY); |
---|
1100 | } |
---|
1101 | |
---|
1102 | delete[] pixels; |
---|
1103 | |
---|
1104 | // Show the page... |
---|
1105 | EndPage(dialog.hDC); |
---|
1106 | } |
---|
1107 | |
---|
1108 | // Finish up... |
---|
1109 | EndDoc(dialog.hDC); |
---|
1110 | |
---|
1111 | fl_gc = save_dc; |
---|
1112 | fl_window = save_win; |
---|
1113 | fl_pop_clip(); |
---|
1114 | |
---|
1115 | // Free the print DC and return... |
---|
1116 | DeleteDC(dialog.hDC); |
---|
1117 | } |
---|
1118 | #else |
---|
1119 | // Load and show the print dialog... |
---|
1120 | void print_menu_cb(Fl_Widget *, void *) { |
---|
1121 | if (!print_panel) make_print_panel(); |
---|
1122 | |
---|
1123 | print_load(); |
---|
1124 | |
---|
1125 | print_selection->deactivate(); |
---|
1126 | |
---|
1127 | for (Fl_Type *t = Fl_Type::first; t; t = t->next) { |
---|
1128 | if (t->selected && t->is_window()) { |
---|
1129 | print_selection->activate(); |
---|
1130 | break; |
---|
1131 | } |
---|
1132 | } |
---|
1133 | |
---|
1134 | print_all->setonly(); |
---|
1135 | print_all->do_callback(); |
---|
1136 | |
---|
1137 | print_panel->show(); |
---|
1138 | } |
---|
1139 | |
---|
1140 | // Quote a string for PostScript printing |
---|
1141 | static const char *ps_string(const char *s) { |
---|
1142 | char *bufptr; |
---|
1143 | static char buffer[2048]; |
---|
1144 | |
---|
1145 | |
---|
1146 | if (!s) { |
---|
1147 | buffer[0] = '\0'; |
---|
1148 | } else { |
---|
1149 | for (bufptr = buffer; bufptr < (buffer + sizeof(buffer) - 3) && *s;) { |
---|
1150 | if (*s == '(' || *s == ')' || *s == '\\') *bufptr++ = '\\'; |
---|
1151 | *bufptr++ = *s++; |
---|
1152 | } |
---|
1153 | |
---|
1154 | *bufptr = '\0'; |
---|
1155 | } |
---|
1156 | |
---|
1157 | return (buffer); |
---|
1158 | } |
---|
1159 | |
---|
1160 | // Actually print... |
---|
1161 | void print_cb(Fl_Return_Button *, void *) { |
---|
1162 | FILE *outfile; // Output file or pipe to print command |
---|
1163 | char command[1024]; // Print command |
---|
1164 | int copies; // Collated copies |
---|
1165 | int first, last; // First and last page |
---|
1166 | int page; // Current page |
---|
1167 | int winpage; // Current window page |
---|
1168 | int num_pages; // Number of pages |
---|
1169 | Fl_Type *t; // Current widget |
---|
1170 | int num_windows; // Number of windows |
---|
1171 | Fl_Window_Type *windows[1000]; // Windows to print |
---|
1172 | |
---|
1173 | // Show progress, deactivate controls... |
---|
1174 | print_panel_controls->deactivate(); |
---|
1175 | print_progress->show(); |
---|
1176 | |
---|
1177 | // Figure out how many pages we'll have to print... |
---|
1178 | if (print_collate_button->value()) copies = (int)print_copies->value(); |
---|
1179 | else copies = 1; |
---|
1180 | |
---|
1181 | if (print_pages->value()) { |
---|
1182 | // Get from and to page numbers... |
---|
1183 | if ((first = atoi(print_from->value())) < 1) first = 1; |
---|
1184 | if ((last = atoi(print_to->value())) < 1) last = 1000; |
---|
1185 | |
---|
1186 | if (first > last) { |
---|
1187 | // Swap first/last page |
---|
1188 | page = first; |
---|
1189 | first = last; |
---|
1190 | last = page; |
---|
1191 | } |
---|
1192 | } else { |
---|
1193 | // Print everything... |
---|
1194 | first = 1; |
---|
1195 | last = 1000; |
---|
1196 | } |
---|
1197 | |
---|
1198 | for (t = Fl_Type::first, num_windows = 0, winpage = 0; t; t = t->next) { |
---|
1199 | if (t->is_window()) { |
---|
1200 | winpage ++; |
---|
1201 | windows[num_windows] = (Fl_Window_Type *)t; |
---|
1202 | |
---|
1203 | if (print_all->value()) num_windows ++; |
---|
1204 | else if (print_pages->value() && winpage >= first && |
---|
1205 | winpage <= last) num_windows ++; |
---|
1206 | else if (print_selection->value() && t->selected) num_windows ++; |
---|
1207 | } |
---|
1208 | } |
---|
1209 | |
---|
1210 | num_pages = num_windows * copies; |
---|
1211 | |
---|
1212 | print_progress->minimum(0); |
---|
1213 | print_progress->maximum(num_pages); |
---|
1214 | print_progress->value(0); |
---|
1215 | Fl::check(); |
---|
1216 | |
---|
1217 | // Get the base filename... |
---|
1218 | const char *basename = strrchr(filename, '/'); |
---|
1219 | if (basename) basename ++; |
---|
1220 | else basename = filename; |
---|
1221 | |
---|
1222 | // Open the print stream... |
---|
1223 | if (print_choice->value()) { |
---|
1224 | // Pipe the output into the lp command... |
---|
1225 | const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); |
---|
1226 | |
---|
1227 | snprintf(command, sizeof(command), "lp -s -d %s -n %.0f -t '%s' -o media=%s", |
---|
1228 | printer, print_collate_button->value() ? 1.0 : print_copies->value(), |
---|
1229 | basename, print_page_size->text(print_page_size->value())); |
---|
1230 | outfile = popen(command, "w"); |
---|
1231 | } else { |
---|
1232 | // Print to file... |
---|
1233 | fl_file_chooser_ok_label("Print"); |
---|
1234 | const char *outname = fl_file_chooser("Print To", "PostScript (*.ps)", NULL, 1); |
---|
1235 | fl_file_chooser_ok_label(NULL); |
---|
1236 | |
---|
1237 | if (outname && !access(outname, 0)) { |
---|
1238 | if (fl_choice("The file \"%s\" already exists.\n" |
---|
1239 | "Do you want to replace it?", "Cancel", |
---|
1240 | "Replace", NULL, outname) == 0) outname = NULL; |
---|
1241 | } |
---|
1242 | |
---|
1243 | if (outname) outfile = fopen(outname, "w"); |
---|
1244 | else outfile = NULL; |
---|
1245 | } |
---|
1246 | |
---|
1247 | if (outfile) { |
---|
1248 | // Figure out the page size and margins... |
---|
1249 | int width, length; // Size of page |
---|
1250 | int left, bottom, // Bottom lefthand corner |
---|
1251 | right, top; // Top righthand corner |
---|
1252 | |
---|
1253 | if (print_page_size->value()) { |
---|
1254 | // A4 |
---|
1255 | width = 595; |
---|
1256 | length = 842; |
---|
1257 | } else { |
---|
1258 | // Letter |
---|
1259 | width = 612; |
---|
1260 | length = 792; |
---|
1261 | } |
---|
1262 | |
---|
1263 | int output_mode; |
---|
1264 | for (output_mode = 0; output_mode < 4; output_mode ++) { |
---|
1265 | if (print_output_mode[output_mode]->value()) break; |
---|
1266 | } |
---|
1267 | |
---|
1268 | if (output_mode & 1) { |
---|
1269 | // Landscape |
---|
1270 | left = 36; |
---|
1271 | bottom = 18; |
---|
1272 | right = length - 36; |
---|
1273 | top = width - 18; |
---|
1274 | } else { |
---|
1275 | // Portrait |
---|
1276 | left = 18; |
---|
1277 | bottom = 36; |
---|
1278 | right = width - 18; |
---|
1279 | top = length - 36; |
---|
1280 | } |
---|
1281 | |
---|
1282 | // Get the time and date... |
---|
1283 | time_t curtime = time(NULL); |
---|
1284 | struct tm *curdate = localtime(&curtime); |
---|
1285 | char date[1024]; |
---|
1286 | |
---|
1287 | strftime(date, sizeof(date), "%c", curdate); |
---|
1288 | |
---|
1289 | // Write the prolog... |
---|
1290 | fprintf(outfile, |
---|
1291 | "%%!PS-Adobe-3.0\n" |
---|
1292 | "%%%%BoundingBox: 18 36 %d %d\n" |
---|
1293 | "%%%%Pages: %d\n" |
---|
1294 | "%%%%LanguageLevel: 1\n" |
---|
1295 | "%%%%DocumentData: Clean7Bit\n" |
---|
1296 | "%%%%DocumentNeededResources: font Helvetica-Bold\n" |
---|
1297 | "%%%%Creator: FLUID %.4f\n" |
---|
1298 | "%%%%CreationDate: %s\n" |
---|
1299 | "%%%%Title: (%s)\n" |
---|
1300 | "%%%%EndComments\n" |
---|
1301 | "%%%%BeginProlog\n" |
---|
1302 | "%%languagelevel 1 eq {\n" |
---|
1303 | " /rectfill {\n" |
---|
1304 | " newpath 4 2 roll moveto dup 0 exch rlineto exch 0 rlineto\n" |
---|
1305 | " neg 0 exch rlineto closepath fill\n" |
---|
1306 | " } bind def\n" |
---|
1307 | " /rectstroke {\n" |
---|
1308 | " newpath 4 2 roll moveto dup 0 exch rlineto exch 0 rlineto\n" |
---|
1309 | " neg 0 exch rlineto closepath stroke\n" |
---|
1310 | " } bind def\n" |
---|
1311 | "%%} if\n" |
---|
1312 | "%%%%EndProlog\n" |
---|
1313 | "%%%%BeginSetup\n" |
---|
1314 | "%%%%BeginFeature: *PageSize %s\n" |
---|
1315 | "languagelevel 1 ne {\n" |
---|
1316 | " <</PageSize[%d %d]/ImagingBBox null>>setpagedevice\n" |
---|
1317 | "} {\n" |
---|
1318 | " %s\n" |
---|
1319 | "} ifelse\n" |
---|
1320 | "%%%%EndFeature\n" |
---|
1321 | "%%%%EndSetup\n", |
---|
1322 | width - 18, length - 36, |
---|
1323 | num_pages, |
---|
1324 | FL_VERSION, |
---|
1325 | date, |
---|
1326 | basename, |
---|
1327 | print_page_size->text(print_page_size->value()), |
---|
1328 | width, length, |
---|
1329 | print_page_size->value() ? "a4tray" : "lettertray"); |
---|
1330 | |
---|
1331 | // Print each of the windows... |
---|
1332 | char progress[255]; // Progress text |
---|
1333 | int copy; // Current copy |
---|
1334 | |
---|
1335 | for (copy = 0, page = 0; copy < copies; copy ++) { |
---|
1336 | for (winpage = 0; winpage < num_pages; winpage ++) { |
---|
1337 | // Start next page... |
---|
1338 | page ++; |
---|
1339 | sprintf(progress, "Printing page %d/%d...", page, num_pages); |
---|
1340 | print_progress->value(page); |
---|
1341 | print_progress->label(progress); |
---|
1342 | Fl::check(); |
---|
1343 | |
---|
1344 | // Add common page stuff... |
---|
1345 | fprintf(outfile, |
---|
1346 | "%%%%Page: %d %d\n" |
---|
1347 | "gsave\n", |
---|
1348 | page, page); |
---|
1349 | |
---|
1350 | if (output_mode & 1) { |
---|
1351 | // Landscape... |
---|
1352 | fprintf(outfile, "%d 0 translate 90 rotate\n", width); |
---|
1353 | } |
---|
1354 | |
---|
1355 | // Draw header... |
---|
1356 | fprintf(outfile, |
---|
1357 | "0 setgray\n" |
---|
1358 | "/Helvetica-Bold findfont 14 scalefont setfont\n" |
---|
1359 | "%d %d moveto (%s) show\n" |
---|
1360 | "%.1f %d moveto (%s) dup stringwidth pop -0.5 mul 0 rmoveto show\n" |
---|
1361 | "%d %d moveto (%d/%d) dup stringwidth pop neg 0 rmoveto show\n", |
---|
1362 | left, top - 15, ps_string(basename), |
---|
1363 | 0.5 * (left + right), top - 15, date, |
---|
1364 | right, top - 15, winpage + 1, num_windows); |
---|
1365 | |
---|
1366 | // Get window image... |
---|
1367 | uchar *pixels; // Window image data |
---|
1368 | int w, h; // Window image dimensions |
---|
1369 | float ww, hh; // Scaled size |
---|
1370 | float border; // Width of 1 pixel |
---|
1371 | float llx, lly, // Lower-lefthand corner |
---|
1372 | urx, ury; // Upper-righthand corner |
---|
1373 | Fl_Window *win; // Window widget |
---|
1374 | |
---|
1375 | win = (Fl_Window *)(windows[winpage]->o); |
---|
1376 | pixels = windows[winpage]->read_image(w, h); |
---|
1377 | |
---|
1378 | // Figure out the window size, first at 100 PPI and then scaled |
---|
1379 | // down if that is too big... |
---|
1380 | ww = w * 72.0 / 100.0; |
---|
1381 | hh = h * 72.0 / 100.0; |
---|
1382 | |
---|
1383 | if (ww > (right - left)) { |
---|
1384 | ww = right - left; |
---|
1385 | hh = h * ww / w; |
---|
1386 | } |
---|
1387 | |
---|
1388 | if (hh > (top - bottom - 36)) { |
---|
1389 | hh = top - bottom; |
---|
1390 | ww = w * hh / h; |
---|
1391 | } |
---|
1392 | |
---|
1393 | border = ww / w; |
---|
1394 | |
---|
1395 | // Position the window in the center... |
---|
1396 | llx = 0.5 * (right - left - ww); |
---|
1397 | lly = 0.5 * (top - bottom - hh); |
---|
1398 | urx = 0.5 * (right - left + ww); |
---|
1399 | ury = 0.5 * (top - bottom + hh); |
---|
1400 | |
---|
1401 | // Draw a simulated window border... |
---|
1402 | fprintf(outfile, |
---|
1403 | "0.75 setgray\n" // Gray background |
---|
1404 | "newpath %.2f %.2f %.2f 180 90 arcn\n" // Top left |
---|
1405 | "%.2f %.2f %.2f 90 0 arcn\n" // Top right |
---|
1406 | "%.2f %.2f %.2f 0 -90 arcn\n" // Bottom right |
---|
1407 | "%.2f %.2f %.2f -90 -180 arcn\n" // Bottom left |
---|
1408 | "closepath gsave fill grestore\n" // Fill |
---|
1409 | "0 setlinewidth 0 setgray stroke\n", // Outline |
---|
1410 | llx, ury + 12 * border, 4 * border, |
---|
1411 | urx, ury + 12 * border, 4 * border, |
---|
1412 | urx, lly, 4 * border, |
---|
1413 | llx, lly, 4 * border); |
---|
1414 | |
---|
1415 | // Title bar... |
---|
1416 | if (output_mode & 2) { |
---|
1417 | fputs("0.25 setgray\n", outfile); |
---|
1418 | } else { |
---|
1419 | fputs("0.1 0.2 0.6 setrgbcolor\n", outfile); |
---|
1420 | } |
---|
1421 | |
---|
1422 | fprintf(outfile, "%.2f %.2f %.2f %.2f rectfill\n", |
---|
1423 | llx + 12 * border, ury, |
---|
1424 | ww - (24 + 16 * (!win->modal() || win->resizable()) + |
---|
1425 | 16 * (!win->modal() && win->resizable())) * border, |
---|
1426 | 16 * border); |
---|
1427 | |
---|
1428 | if (win->resizable()) { |
---|
1429 | fprintf(outfile, |
---|
1430 | "%.2f %.2f %.2f -90 -180 arcn\n" // Bottom left |
---|
1431 | "0 %.2f rlineto %.2f 0 rlineto 0 -%.2f rlineto closepath fill\n" |
---|
1432 | "%.2f %.2f %.2f 0 -90 arcn\n" // Bottom right |
---|
1433 | "-%.2f 0 rlineto 0 %.2f rlineto %.2f 0 rlineto closepath fill\n", |
---|
1434 | llx, lly, 4 * border, |
---|
1435 | 12 * border, 16 * border, 16 * border, |
---|
1436 | urx, lly, 4 * border, |
---|
1437 | 12 * border, 16 * border, 16 * border); |
---|
1438 | } |
---|
1439 | |
---|
1440 | // Inside outline and button shading... |
---|
1441 | fprintf(outfile, |
---|
1442 | "%.2f setlinewidth 0.5 setgray\n" |
---|
1443 | "%.2f %.2f %.2f %.2f rectstroke\n" |
---|
1444 | "%.2f %.2f moveto 0 %.2f rlineto\n" |
---|
1445 | "%.2f %.2f moveto 0 %.2f rlineto\n", |
---|
1446 | border, |
---|
1447 | llx - 0.5 * border, lly - 0.5 * border, ww + border, hh + border, |
---|
1448 | llx + 12 * border, ury, 16 * border, |
---|
1449 | urx - 12 * border, ury, 16 * border); |
---|
1450 | |
---|
1451 | if (!win->modal() || win->resizable()) { |
---|
1452 | fprintf(outfile, "%.2f %.2f moveto 0 %.2f rlineto\n", |
---|
1453 | urx - 28 * border, ury, 16 * border); |
---|
1454 | } |
---|
1455 | |
---|
1456 | if (!win->modal() && win->resizable()) { |
---|
1457 | fprintf(outfile, "%.2f %.2f moveto 0 %.2f rlineto\n", |
---|
1458 | urx - 44 * border, ury, 16 * border); |
---|
1459 | } |
---|
1460 | |
---|
1461 | fprintf(outfile, "%.2f %.2f moveto %.2f 0 rlineto stroke\n", |
---|
1462 | llx - 3.5 * border, ury + 0.5 * border, ww + 7 * border); |
---|
1463 | |
---|
1464 | // Button icons... |
---|
1465 | fprintf(outfile, |
---|
1466 | "%.2f setlinewidth 0 setgray\n" |
---|
1467 | "%.2f %.2f moveto %.2f -%.2f rlineto %.2f %.2f rlineto\n" |
---|
1468 | "%.2f %.2f moveto -%.2f -%.2f rlineto 0 %.2f rmoveto %.2f -%.2f rlineto\n", |
---|
1469 | 2 * border, |
---|
1470 | llx, ury + 10 * border, 4 * border, 4 * border, 4 * border, 4 * border, |
---|
1471 | urx, ury + 12 * border, 8 * border, 8 * border, 8 * border, 8 * border, 8 * border); |
---|
1472 | |
---|
1473 | float x = urx - 16 * border; |
---|
1474 | |
---|
1475 | if (win->resizable()) { |
---|
1476 | // Maximize button |
---|
1477 | fprintf(outfile, |
---|
1478 | "%.2f %.2f moveto -%.2f 0 rlineto 0 -%.2f rlineto " |
---|
1479 | "%.2f 0 rlineto 0 %.2f rlineto\n", |
---|
1480 | x, ury + 12 * border, 8 * border, 8 * border, |
---|
1481 | 8 * border, 8 * border); |
---|
1482 | |
---|
1483 | x -= 16 * border; |
---|
1484 | } |
---|
1485 | |
---|
1486 | if (!win->modal()) { |
---|
1487 | // Minimize button |
---|
1488 | fprintf(outfile, |
---|
1489 | "%.2f %.2f moveto -%.2f 0 rlineto\n", |
---|
1490 | x, ury + 4 * border, 8 * border); |
---|
1491 | } |
---|
1492 | |
---|
1493 | fputs("stroke\n", outfile); |
---|
1494 | |
---|
1495 | if (win->label()) { |
---|
1496 | // Add window title... |
---|
1497 | fprintf(outfile, |
---|
1498 | "1 setgray\n" |
---|
1499 | "/Helvetica-Bold findfont %.2f scalefont setfont\n" |
---|
1500 | "(%s) %.2f %.2f moveto show\n", |
---|
1501 | 12 * border, |
---|
1502 | ps_string(win->label()), llx + 16 * border, ury + 4 * border); |
---|
1503 | } |
---|
1504 | |
---|
1505 | fprintf(outfile, |
---|
1506 | "gsave\n" |
---|
1507 | "%.2f %.2f translate %.2f %.2f scale\n", |
---|
1508 | llx, ury - border, border, border); |
---|
1509 | |
---|
1510 | if (output_mode & 2) { |
---|
1511 | // Grayscale image... |
---|
1512 | fprintf(outfile, |
---|
1513 | "/imgdata %d string def\n" |
---|
1514 | "%d %d 8[1 0 0 -1 0 1] " |
---|
1515 | "{currentfile imgdata readhexstring pop} image\n", |
---|
1516 | w, |
---|
1517 | w, h); |
---|
1518 | |
---|
1519 | uchar *ptr = pixels; |
---|
1520 | int i, count = w * h; |
---|
1521 | |
---|
1522 | for (i = 0; i < count; i ++, ptr += 3) { |
---|
1523 | fprintf(outfile, "%02X", |
---|
1524 | (31 * ptr[0] + 61 * ptr[1] + 8 * ptr[2]) / 100); |
---|
1525 | if (!(i % 40)) putc('\n', outfile); |
---|
1526 | } |
---|
1527 | } else { |
---|
1528 | // Color image... |
---|
1529 | fprintf(outfile, |
---|
1530 | "/imgdata %d string def\n" |
---|
1531 | "%d %d 8[1 0 0 -1 0 1] " |
---|
1532 | "{currentfile imgdata readhexstring pop} false 3 colorimage\n", |
---|
1533 | w * 3, |
---|
1534 | w, h); |
---|
1535 | |
---|
1536 | uchar *ptr = pixels; |
---|
1537 | int i, count = w * h; |
---|
1538 | |
---|
1539 | for (i = 0; i < count; i ++, ptr += 3) { |
---|
1540 | fprintf(outfile, "%02X%02X%02X", ptr[0], ptr[1], ptr[2]); |
---|
1541 | if (!(i % 13)) putc('\n', outfile); |
---|
1542 | } |
---|
1543 | } |
---|
1544 | |
---|
1545 | fputs("\ngrestore\n", outfile); |
---|
1546 | |
---|
1547 | delete[] pixels; |
---|
1548 | |
---|
1549 | // Show the page... |
---|
1550 | fputs("grestore showpage\n", outfile); |
---|
1551 | } |
---|
1552 | } |
---|
1553 | |
---|
1554 | // Finish up... |
---|
1555 | fputs("%%EOF\n", outfile); |
---|
1556 | |
---|
1557 | if (print_choice->value()) pclose(outfile); |
---|
1558 | else fclose(outfile); |
---|
1559 | } else { |
---|
1560 | // Unable to print... |
---|
1561 | fl_alert("Error printing: %s", strerror(errno)); |
---|
1562 | } |
---|
1563 | |
---|
1564 | // Hide progress, activate controls, hide print panel... |
---|
1565 | print_panel_controls->activate(); |
---|
1566 | print_progress->hide(); |
---|
1567 | print_panel->hide(); |
---|
1568 | } |
---|
1569 | #endif // WIN32 && !__CYGWIN__ |
---|
1570 | |
---|
1571 | //////////////////////////////////////////////////////////////// |
---|
1572 | |
---|
1573 | extern Fl_Menu_Item New_Menu[]; |
---|
1574 | |
---|
1575 | void toggle_widgetbin_cb(Fl_Widget *, void *); |
---|
1576 | void toggle_sourceview_cb(Fl_Double_Window *, void *); |
---|
1577 | |
---|
1578 | Fl_Menu_Item Main_Menu[] = { |
---|
1579 | {"&File",0,0,0,FL_SUBMENU}, |
---|
1580 | {"&New...", FL_COMMAND+'n', new_cb, 0}, |
---|
1581 | {"&Open...", FL_COMMAND+'o', open_cb, 0}, |
---|
1582 | {"&Insert...", FL_COMMAND+'i', open_cb, (void*)1, FL_MENU_DIVIDER}, |
---|
1583 | #define SAVE_ITEM 4 |
---|
1584 | {"&Save", FL_COMMAND+'s', save_cb, 0}, |
---|
1585 | {"Save &As...", FL_COMMAND+FL_SHIFT+'s', save_cb, (void*)1}, |
---|
1586 | {"Sa&ve A Copy...", 0, save_cb, (void*)2}, |
---|
1587 | {"Save &Template...", 0, save_template_cb}, |
---|
1588 | {"&Revert...", 0, revert_cb, 0, FL_MENU_DIVIDER}, |
---|
1589 | {"&Print...", FL_COMMAND+'p', print_menu_cb}, |
---|
1590 | {"Write &Code...", FL_COMMAND+FL_SHIFT+'c', write_cb, 0}, |
---|
1591 | {"&Write Strings...", FL_COMMAND+FL_SHIFT+'w', write_strings_cb, 0, FL_MENU_DIVIDER}, |
---|
1592 | #define HISTORY_ITEM 12 |
---|
1593 | {relative_history[0], FL_COMMAND+'0', open_history_cb, absolute_history[0]}, |
---|
1594 | {relative_history[1], FL_COMMAND+'1', open_history_cb, absolute_history[1]}, |
---|
1595 | {relative_history[2], FL_COMMAND+'2', open_history_cb, absolute_history[2]}, |
---|
1596 | {relative_history[3], FL_COMMAND+'3', open_history_cb, absolute_history[3]}, |
---|
1597 | {relative_history[4], FL_COMMAND+'4', open_history_cb, absolute_history[4]}, |
---|
1598 | {relative_history[5], FL_COMMAND+'5', open_history_cb, absolute_history[5]}, |
---|
1599 | {relative_history[6], FL_COMMAND+'6', open_history_cb, absolute_history[6]}, |
---|
1600 | {relative_history[7], FL_COMMAND+'7', open_history_cb, absolute_history[7]}, |
---|
1601 | {relative_history[8], FL_COMMAND+'8', open_history_cb, absolute_history[8]}, |
---|
1602 | {relative_history[9], FL_COMMAND+'9', open_history_cb, absolute_history[9], FL_MENU_DIVIDER}, |
---|
1603 | {"&Quit", FL_COMMAND+'q', exit_cb}, |
---|
1604 | {0}, |
---|
1605 | {"&Edit",0,0,0,FL_SUBMENU}, |
---|
1606 | {"&Undo", FL_COMMAND+'z', undo_cb}, |
---|
1607 | {"&Redo", FL_COMMAND+FL_SHIFT+'z', redo_cb, 0, FL_MENU_DIVIDER}, |
---|
1608 | {"C&ut", FL_COMMAND+'x', cut_cb}, |
---|
1609 | {"&Copy", FL_COMMAND+'c', copy_cb}, |
---|
1610 | {"&Paste", FL_COMMAND+'v', paste_cb}, |
---|
1611 | {"Dup&licate", FL_COMMAND+'u', duplicate_cb}, |
---|
1612 | {"&Delete", FL_Delete, delete_cb, 0, FL_MENU_DIVIDER}, |
---|
1613 | {"Select &All", FL_COMMAND+'a', select_all_cb}, |
---|
1614 | {"Select &None", FL_COMMAND+FL_SHIFT+'a', select_none_cb, 0, FL_MENU_DIVIDER}, |
---|
1615 | {"Pr&operties...", FL_F+1, openwidget_cb}, |
---|
1616 | {"&Sort",0,sort_cb}, |
---|
1617 | {"&Earlier", FL_F+2, earlier_cb}, |
---|
1618 | {"&Later", FL_F+3, later_cb}, |
---|
1619 | {"&Group", FL_F+7, group_cb}, |
---|
1620 | {"Ung&roup", FL_F+8, ungroup_cb,0, FL_MENU_DIVIDER}, |
---|
1621 | {"Hide O&verlays",FL_COMMAND+FL_SHIFT+'o',toggle_overlays}, |
---|
1622 | #define WIDGETBIN_ITEM 41 |
---|
1623 | {"Show Widget &Bin...",FL_ALT+'b',toggle_widgetbin_cb}, |
---|
1624 | #define SOURCEVIEW_ITEM 42 |
---|
1625 | {"Show Source Code...",FL_ALT+FL_SHIFT+'s', (Fl_Callback*)toggle_sourceview_cb, 0, FL_MENU_DIVIDER}, |
---|
1626 | {"Pro&ject Settings...",FL_ALT+'p',show_project_cb}, |
---|
1627 | {"GU&I Settings...",FL_ALT+FL_SHIFT+'p',show_settings_cb}, |
---|
1628 | {0}, |
---|
1629 | {"&New", 0, 0, (void *)New_Menu, FL_SUBMENU_POINTER}, |
---|
1630 | {"&Layout",0,0,0,FL_SUBMENU}, |
---|
1631 | {"&Align",0,0,0,FL_SUBMENU}, |
---|
1632 | {"&Left",0,(Fl_Callback *)align_widget_cb,(void*)10}, |
---|
1633 | {"&Center",0,(Fl_Callback *)align_widget_cb,(void*)11}, |
---|
1634 | {"&Right",0,(Fl_Callback *)align_widget_cb,(void*)12}, |
---|
1635 | {"&Top",0,(Fl_Callback *)align_widget_cb,(void*)13}, |
---|
1636 | {"&Middle",0,(Fl_Callback *)align_widget_cb,(void*)14}, |
---|
1637 | {"&Bottom",0,(Fl_Callback *)align_widget_cb,(void*)15}, |
---|
1638 | {0}, |
---|
1639 | {"&Space Evenly",0,0,0,FL_SUBMENU}, |
---|
1640 | {"&Across",0,(Fl_Callback *)align_widget_cb,(void*)20}, |
---|
1641 | {"&Down",0,(Fl_Callback *)align_widget_cb,(void*)21}, |
---|
1642 | {0}, |
---|
1643 | {"&Make Same Size",0,0,0,FL_SUBMENU}, |
---|
1644 | {"&Width",0,(Fl_Callback *)align_widget_cb,(void*)30}, |
---|
1645 | {"&Height",0,(Fl_Callback *)align_widget_cb,(void*)31}, |
---|
1646 | {"&Both",0,(Fl_Callback *)align_widget_cb,(void*)32}, |
---|
1647 | {0}, |
---|
1648 | {"&Center In Group",0,0,0,FL_SUBMENU}, |
---|
1649 | {"&Horizontal",0,(Fl_Callback *)align_widget_cb,(void*)40}, |
---|
1650 | {"&Vertical",0,(Fl_Callback *)align_widget_cb,(void*)41}, |
---|
1651 | {0}, |
---|
1652 | {"Set &Widget Size",0,0,0,FL_SUBMENU|FL_MENU_DIVIDER}, |
---|
1653 | {"&Tiny",FL_ALT+'1',(Fl_Callback *)widget_size_cb,(void*)8,0,FL_NORMAL_LABEL,FL_HELVETICA,8}, |
---|
1654 | {"&Small",FL_ALT+'2',(Fl_Callback *)widget_size_cb,(void*)11,0,FL_NORMAL_LABEL,FL_HELVETICA,11}, |
---|
1655 | {"&Normal",FL_ALT+'3',(Fl_Callback *)widget_size_cb,(void*)14,0,FL_NORMAL_LABEL,FL_HELVETICA,14}, |
---|
1656 | {"&Medium",FL_ALT+'4',(Fl_Callback *)widget_size_cb,(void*)18,0,FL_NORMAL_LABEL,FL_HELVETICA,18}, |
---|
1657 | {"&Large",FL_ALT+'5',(Fl_Callback *)widget_size_cb,(void*)24,0,FL_NORMAL_LABEL,FL_HELVETICA,24}, |
---|
1658 | {"&Huge",FL_ALT+'6',(Fl_Callback *)widget_size_cb,(void*)32,0,FL_NORMAL_LABEL,FL_HELVETICA,32}, |
---|
1659 | {0}, |
---|
1660 | {"&Grid and Size Settings...",FL_COMMAND+'g',show_grid_cb}, |
---|
1661 | {0}, |
---|
1662 | {"&Shell",0,0,0,FL_SUBMENU}, |
---|
1663 | {"Execute &Command...",FL_ALT+'x',(Fl_Callback *)show_shell_window}, |
---|
1664 | {"Execute &Again...",FL_ALT+'g',(Fl_Callback *)do_shell_command}, |
---|
1665 | {0}, |
---|
1666 | {"&Help",0,0,0,FL_SUBMENU}, |
---|
1667 | {"&About FLUID...",0,about_cb}, |
---|
1668 | {"&On FLUID...",0,help_cb}, |
---|
1669 | {"&Manual...",0,manual_cb}, |
---|
1670 | {0}, |
---|
1671 | {0}}; |
---|
1672 | |
---|
1673 | #define BROWSERWIDTH 300 |
---|
1674 | #define BROWSERHEIGHT 500 |
---|
1675 | #define WINWIDTH 300 |
---|
1676 | #define MENUHEIGHT 25 |
---|
1677 | #define WINHEIGHT (BROWSERHEIGHT+MENUHEIGHT) |
---|
1678 | |
---|
1679 | extern void fill_in_New_Menu(); |
---|
1680 | |
---|
1681 | void scheme_cb(Fl_Choice *, void *) { |
---|
1682 | if (compile_only) |
---|
1683 | return; |
---|
1684 | |
---|
1685 | switch (scheme_choice->value()) { |
---|
1686 | case 0 : // Default |
---|
1687 | Fl::scheme(NULL); |
---|
1688 | break; |
---|
1689 | case 1 : // None |
---|
1690 | Fl::scheme("none"); |
---|
1691 | break; |
---|
1692 | case 2 : // Plastic |
---|
1693 | Fl::scheme("plastic"); |
---|
1694 | break; |
---|
1695 | case 3 : // GTK+ |
---|
1696 | Fl::scheme("gtk+"); |
---|
1697 | break; |
---|
1698 | } |
---|
1699 | |
---|
1700 | fluid_prefs.set("scheme", scheme_choice->value()); |
---|
1701 | } |
---|
1702 | |
---|
1703 | void toggle_widgetbin_cb(Fl_Widget *, void *) { |
---|
1704 | if (!widgetbin_panel) { |
---|
1705 | make_widgetbin(); |
---|
1706 | widgetbin_panel->callback(toggle_widgetbin_cb); |
---|
1707 | if (!position_window(widgetbin_panel,"widgetbin_pos", 1, 320, 30)) return; |
---|
1708 | } |
---|
1709 | |
---|
1710 | if (widgetbin_panel->visible()) { |
---|
1711 | widgetbin_panel->hide(); |
---|
1712 | Main_Menu[WIDGETBIN_ITEM].label("Show Widget &Bin..."); |
---|
1713 | } else { |
---|
1714 | widgetbin_panel->show(); |
---|
1715 | Main_Menu[WIDGETBIN_ITEM].label("Hide Widget &Bin"); |
---|
1716 | } |
---|
1717 | } |
---|
1718 | |
---|
1719 | |
---|
1720 | void toggle_sourceview_cb(Fl_Double_Window *, void *) { |
---|
1721 | if (!sourceview_panel) { |
---|
1722 | make_sourceview(); |
---|
1723 | sourceview_panel->callback((Fl_Callback*)toggle_sourceview_cb); |
---|
1724 | Fl_Preferences svp(fluid_prefs, "sourceview"); |
---|
1725 | int autorefresh; |
---|
1726 | svp.get("autorefresh", autorefresh, 1); |
---|
1727 | sv_autorefresh->value(autorefresh); |
---|
1728 | int autoposition; |
---|
1729 | svp.get("autoposition", autoposition, 1); |
---|
1730 | sv_autoposition->value(autoposition); |
---|
1731 | int tab; |
---|
1732 | svp.get("tab", tab, 0); |
---|
1733 | if (tab>=0 && tab<sv_tab->children()) sv_tab->value(sv_tab->child(tab)); |
---|
1734 | if (!position_window(sourceview_panel,"sourceview_pos", 0, 320, 120, 550, 500)) return; |
---|
1735 | } |
---|
1736 | |
---|
1737 | if (sourceview_panel->visible()) { |
---|
1738 | sourceview_panel->hide(); |
---|
1739 | Main_Menu[SOURCEVIEW_ITEM].label("Show Source Code..."); |
---|
1740 | } else { |
---|
1741 | sourceview_panel->show(); |
---|
1742 | Main_Menu[SOURCEVIEW_ITEM].label("Hide Source Code..."); |
---|
1743 | update_sourceview_cb(0,0); |
---|
1744 | } |
---|
1745 | } |
---|
1746 | |
---|
1747 | void toggle_sourceview_b_cb(Fl_Button*, void *) { |
---|
1748 | toggle_sourceview_cb(0,0); |
---|
1749 | } |
---|
1750 | |
---|
1751 | void make_main_window() { |
---|
1752 | fluid_prefs.get("snap", snap, 1); |
---|
1753 | fluid_prefs.get("gridx", gridx, 5); |
---|
1754 | fluid_prefs.get("gridy", gridy, 5); |
---|
1755 | fluid_prefs.get("show_guides", show_guides, 0); |
---|
1756 | fluid_prefs.get("widget_size", Fl_Widget_Type::default_size, 14); |
---|
1757 | |
---|
1758 | load_history(); |
---|
1759 | |
---|
1760 | make_layout_window(); |
---|
1761 | make_settings_window(); |
---|
1762 | make_shell_window(); |
---|
1763 | |
---|
1764 | if (!main_window) { |
---|
1765 | Fl_Widget *o; |
---|
1766 | main_window = new Fl_Double_Window(WINWIDTH,WINHEIGHT,"fluid"); |
---|
1767 | main_window->box(FL_NO_BOX); |
---|
1768 | o = make_widget_browser(0,MENUHEIGHT,BROWSERWIDTH,BROWSERHEIGHT); |
---|
1769 | o->box(FL_FLAT_BOX); |
---|
1770 | o->tooltip("Double-click to view or change an item."); |
---|
1771 | main_window->resizable(o); |
---|
1772 | main_menubar = new Fl_Menu_Bar(0,0,BROWSERWIDTH,MENUHEIGHT); |
---|
1773 | main_menubar->menu(Main_Menu); |
---|
1774 | main_menubar->global(); |
---|
1775 | fill_in_New_Menu(); |
---|
1776 | main_window->end(); |
---|
1777 | } |
---|
1778 | } |
---|
1779 | |
---|
1780 | // Load file history from preferences... |
---|
1781 | void load_history() { |
---|
1782 | int i; // Looping var |
---|
1783 | int max_files; |
---|
1784 | |
---|
1785 | |
---|
1786 | fluid_prefs.get("recent_files", max_files, 5); |
---|
1787 | if (max_files > 10) max_files = 10; |
---|
1788 | |
---|
1789 | for (i = 0; i < max_files; i ++) { |
---|
1790 | fluid_prefs.get( Fl_Preferences::Name("file%d", i), absolute_history[i], "", sizeof(absolute_history[i])); |
---|
1791 | if (absolute_history[i][0]) { |
---|
1792 | // Make a relative version of the filename for the menu... |
---|
1793 | fl_filename_relative(relative_history[i], sizeof(relative_history[i]), |
---|
1794 | absolute_history[i]); |
---|
1795 | |
---|
1796 | if (i == 9) Main_Menu[i + HISTORY_ITEM].flags = FL_MENU_DIVIDER; |
---|
1797 | else Main_Menu[i + HISTORY_ITEM].flags = 0; |
---|
1798 | } else break; |
---|
1799 | } |
---|
1800 | |
---|
1801 | for (; i < 10; i ++) { |
---|
1802 | if (i) Main_Menu[i + HISTORY_ITEM - 1].flags |= FL_MENU_DIVIDER; |
---|
1803 | Main_Menu[i + HISTORY_ITEM].hide(); |
---|
1804 | } |
---|
1805 | } |
---|
1806 | |
---|
1807 | // Update file history from preferences... |
---|
1808 | void update_history(const char *flname) { |
---|
1809 | int i; // Looping var |
---|
1810 | char absolute[1024]; |
---|
1811 | int max_files; |
---|
1812 | |
---|
1813 | |
---|
1814 | fluid_prefs.get("recent_files", max_files, 5); |
---|
1815 | if (max_files > 10) max_files = 10; |
---|
1816 | |
---|
1817 | fl_filename_absolute(absolute, sizeof(absolute), flname); |
---|
1818 | |
---|
1819 | for (i = 0; i < max_files; i ++) |
---|
1820 | #if defined(WIN32) || defined(__APPLE__) |
---|
1821 | if (!strcasecmp(absolute, absolute_history[i])) break; |
---|
1822 | #else |
---|
1823 | if (!strcmp(absolute, absolute_history[i])) break; |
---|
1824 | #endif // WIN32 || __APPLE__ |
---|
1825 | |
---|
1826 | if (i == 0) return; |
---|
1827 | |
---|
1828 | if (i >= max_files) i = max_files - 1; |
---|
1829 | |
---|
1830 | // Move the other flnames down in the list... |
---|
1831 | memmove(absolute_history + 1, absolute_history, |
---|
1832 | i * sizeof(absolute_history[0])); |
---|
1833 | memmove(relative_history + 1, relative_history, |
---|
1834 | i * sizeof(relative_history[0])); |
---|
1835 | |
---|
1836 | // Put the new file at the top... |
---|
1837 | strlcpy(absolute_history[0], absolute, sizeof(absolute_history[0])); |
---|
1838 | |
---|
1839 | fl_filename_relative(relative_history[0], sizeof(relative_history[0]), |
---|
1840 | absolute_history[0]); |
---|
1841 | |
---|
1842 | // Update the menu items as needed... |
---|
1843 | for (i = 0; i < max_files; i ++) { |
---|
1844 | fluid_prefs.set( Fl_Preferences::Name("file%d", i), absolute_history[i]); |
---|
1845 | if (absolute_history[i][0]) { |
---|
1846 | if (i == 9) Main_Menu[i + HISTORY_ITEM].flags = FL_MENU_DIVIDER; |
---|
1847 | else Main_Menu[i + HISTORY_ITEM].flags = 0; |
---|
1848 | } else break; |
---|
1849 | } |
---|
1850 | |
---|
1851 | for (; i < 10; i ++) { |
---|
1852 | fluid_prefs.set( Fl_Preferences::Name("file%d", i), ""); |
---|
1853 | if (i) Main_Menu[i + HISTORY_ITEM - 1].flags |= FL_MENU_DIVIDER; |
---|
1854 | Main_Menu[i + HISTORY_ITEM].hide(); |
---|
1855 | } |
---|
1856 | } |
---|
1857 | |
---|
1858 | // Shell command support... |
---|
1859 | #if (!defined(WIN32) || defined(__CYGWIN__)) && !defined(__MWERKS__) |
---|
1860 | // Support the full piped shell command... |
---|
1861 | static FILE *shell_pipe = 0; |
---|
1862 | |
---|
1863 | void |
---|
1864 | shell_pipe_cb(int, void*) { |
---|
1865 | char line[1024]; // Line from command output... |
---|
1866 | |
---|
1867 | if (fgets(line, sizeof(line), shell_pipe) != NULL) { |
---|
1868 | // Add the line to the output list... |
---|
1869 | shell_run_buffer->append(line); |
---|
1870 | } else { |
---|
1871 | // End of file; tell the parent... |
---|
1872 | Fl::remove_fd(fileno(shell_pipe)); |
---|
1873 | |
---|
1874 | pclose(shell_pipe); |
---|
1875 | shell_pipe = NULL; |
---|
1876 | shell_run_buffer->append("... END SHELL COMMAND ...\n"); |
---|
1877 | } |
---|
1878 | |
---|
1879 | shell_run_display->scroll(shell_run_display->count_lines(0, |
---|
1880 | shell_run_buffer->length(), 1), 0); |
---|
1881 | } |
---|
1882 | |
---|
1883 | void |
---|
1884 | do_shell_command(Fl_Return_Button*, void*) { |
---|
1885 | const char *command; // Command to run |
---|
1886 | |
---|
1887 | |
---|
1888 | shell_window->hide(); |
---|
1889 | |
---|
1890 | if (shell_pipe) { |
---|
1891 | fl_alert("Previous shell command still running!"); |
---|
1892 | return; |
---|
1893 | } |
---|
1894 | |
---|
1895 | if ((command = shell_command_input->value()) == NULL || !*command) { |
---|
1896 | fl_alert("No shell command entered!"); |
---|
1897 | return; |
---|
1898 | } |
---|
1899 | |
---|
1900 | if (shell_savefl_button->value()) { |
---|
1901 | save_cb(0, 0); |
---|
1902 | } |
---|
1903 | |
---|
1904 | if (shell_writecode_button->value()) { |
---|
1905 | compile_only = 1; |
---|
1906 | write_cb(0, 0); |
---|
1907 | compile_only = 0; |
---|
1908 | } |
---|
1909 | |
---|
1910 | if (shell_writemsgs_button->value()) { |
---|
1911 | compile_only = 1; |
---|
1912 | write_strings_cb(0, 0); |
---|
1913 | compile_only = 0; |
---|
1914 | } |
---|
1915 | |
---|
1916 | // Show the output window and clear things... |
---|
1917 | shell_run_buffer->text(""); |
---|
1918 | shell_run_buffer->append(command); |
---|
1919 | shell_run_buffer->append("\n"); |
---|
1920 | shell_run_window->label("Shell Command Running..."); |
---|
1921 | |
---|
1922 | if ((shell_pipe = popen((char *)command, "r")) == NULL) { |
---|
1923 | fl_alert("Unable to run shell command: %s", strerror(errno)); |
---|
1924 | return; |
---|
1925 | } |
---|
1926 | |
---|
1927 | shell_run_button->deactivate(); |
---|
1928 | shell_run_window->hotspot(shell_run_display); |
---|
1929 | shell_run_window->show(); |
---|
1930 | |
---|
1931 | Fl::add_fd(fileno(shell_pipe), shell_pipe_cb); |
---|
1932 | |
---|
1933 | while (shell_pipe) Fl::wait(); |
---|
1934 | |
---|
1935 | shell_run_button->activate(); |
---|
1936 | shell_run_window->label("Shell Command Complete"); |
---|
1937 | fl_beep(); |
---|
1938 | |
---|
1939 | while (shell_run_window->shown()) Fl::wait(); |
---|
1940 | } |
---|
1941 | #else |
---|
1942 | // Just do basic shell command stuff, no status window... |
---|
1943 | void |
---|
1944 | do_shell_command(Fl_Return_Button*, void*) { |
---|
1945 | const char *command; // Command to run |
---|
1946 | int status; // Status from command... |
---|
1947 | |
---|
1948 | |
---|
1949 | shell_window->hide(); |
---|
1950 | |
---|
1951 | if ((command = shell_command_input->value()) == NULL || !*command) { |
---|
1952 | fl_alert("No shell command entered!"); |
---|
1953 | return; |
---|
1954 | } |
---|
1955 | |
---|
1956 | if (shell_savefl_button->value()) { |
---|
1957 | save_cb(0, 0); |
---|
1958 | } |
---|
1959 | |
---|
1960 | if (shell_writecode_button->value()) { |
---|
1961 | compile_only = 1; |
---|
1962 | write_cb(0, 0); |
---|
1963 | compile_only = 0; |
---|
1964 | } |
---|
1965 | |
---|
1966 | if (shell_writemsgs_button->value()) { |
---|
1967 | compile_only = 1; |
---|
1968 | write_strings_cb(0, 0); |
---|
1969 | compile_only = 0; |
---|
1970 | } |
---|
1971 | |
---|
1972 | if ((status = system(command)) != 0) { |
---|
1973 | fl_alert("Shell command returned status %d!", status); |
---|
1974 | } else if (completion_button->value()) { |
---|
1975 | fl_message("Shell command completed successfully!"); |
---|
1976 | } |
---|
1977 | } |
---|
1978 | #endif // (!WIN32 || __CYGWIN__) && !__MWERKS__ |
---|
1979 | |
---|
1980 | |
---|
1981 | void |
---|
1982 | show_shell_window() { |
---|
1983 | shell_window->hotspot(shell_command_input); |
---|
1984 | shell_window->show(); |
---|
1985 | } |
---|
1986 | |
---|
1987 | void set_filename(const char *c) { |
---|
1988 | if (filename) free((void *)filename); |
---|
1989 | filename = c ? strdup(c) : NULL; |
---|
1990 | |
---|
1991 | if (filename) update_history(filename); |
---|
1992 | |
---|
1993 | set_modflag(modflag); |
---|
1994 | } |
---|
1995 | |
---|
1996 | // |
---|
1997 | // The Source View system offers an immediate preview of the code |
---|
1998 | // files that will be generated by FLUID. It also marks the code |
---|
1999 | // generated for the last selected item in the header and the source |
---|
2000 | // file. |
---|
2001 | // |
---|
2002 | // Can we patent this? ;-) - Matt, mm@matthiasm.com |
---|
2003 | // |
---|
2004 | |
---|
2005 | // |
---|
2006 | // Update the header and source code highlighting depending on the |
---|
2007 | // currently selected object |
---|
2008 | // |
---|
2009 | void update_sourceview_position() |
---|
2010 | { |
---|
2011 | if (!sourceview_panel || !sourceview_panel->visible()) |
---|
2012 | return; |
---|
2013 | if (sv_autoposition->value()==0) |
---|
2014 | return; |
---|
2015 | if (sourceview_panel && sourceview_panel->visible() && Fl_Type::current) { |
---|
2016 | int pos0, pos1; |
---|
2017 | if (sv_source->visible_r()) { |
---|
2018 | pos0 = Fl_Type::current->code_line; |
---|
2019 | pos1 = Fl_Type::current->code_line_end; |
---|
2020 | if (pos0>=0) { |
---|
2021 | if (pos1<pos0) |
---|
2022 | pos1 = pos0; |
---|
2023 | sv_source->buffer()->highlight(pos0, pos1); |
---|
2024 | int line = sv_source->buffer()->count_lines(0, pos0); |
---|
2025 | sv_source->scroll(line, 0); |
---|
2026 | } |
---|
2027 | } |
---|
2028 | if (sv_header->visible_r()) { |
---|
2029 | pos0 = Fl_Type::current->header_line; |
---|
2030 | pos1 = Fl_Type::current->header_line_end; |
---|
2031 | if (pos0>=0) { |
---|
2032 | if (pos1<pos0) |
---|
2033 | pos1 = pos0; |
---|
2034 | sv_header->buffer()->highlight(pos0, pos1); |
---|
2035 | int line = sv_header->buffer()->count_lines(0, pos0); |
---|
2036 | sv_header->scroll(line, 0); |
---|
2037 | } |
---|
2038 | } |
---|
2039 | } |
---|
2040 | } |
---|
2041 | |
---|
2042 | void update_sourceview_position_cb(Fl_Tabs*, void*) |
---|
2043 | { |
---|
2044 | update_sourceview_position(); |
---|
2045 | } |
---|
2046 | |
---|
2047 | static char *sv_source_filename = 0; |
---|
2048 | static char *sv_header_filename = 0; |
---|
2049 | |
---|
2050 | // |
---|
2051 | // Generate a header and source file in a temporary directory and |
---|
2052 | // load those into the Code Viewer widgets. |
---|
2053 | // |
---|
2054 | void update_sourceview_cb(Fl_Button*, void*) |
---|
2055 | { |
---|
2056 | if (!sourceview_panel || !sourceview_panel->visible()) |
---|
2057 | return; |
---|
2058 | // generate space for the source and header file filenames |
---|
2059 | if (!sv_source_filename) { |
---|
2060 | sv_source_filename = (char*)malloc(FL_PATH_MAX); |
---|
2061 | fluid_prefs.getUserdataPath(sv_source_filename, FL_PATH_MAX); |
---|
2062 | strlcat(sv_source_filename, "source_view_tmp.cxx", FL_PATH_MAX); |
---|
2063 | } |
---|
2064 | if (!sv_header_filename) { |
---|
2065 | sv_header_filename = (char*)malloc(FL_PATH_MAX); |
---|
2066 | fluid_prefs.getUserdataPath(sv_header_filename, FL_PATH_MAX); |
---|
2067 | strlcat(sv_header_filename, "source_view_tmp.h", FL_PATH_MAX); |
---|
2068 | } |
---|
2069 | |
---|
2070 | strlcpy(i18n_program, fl_filename_name(sv_source_filename), sizeof(i18n_program)); |
---|
2071 | fl_filename_setext(i18n_program, sizeof(i18n_program), ""); |
---|
2072 | const char *code_file_name_bak = code_file_name; |
---|
2073 | code_file_name = sv_source_filename; |
---|
2074 | const char *header_file_name_bak = header_file_name; |
---|
2075 | header_file_name = sv_header_filename; |
---|
2076 | |
---|
2077 | // generate the code and load the files |
---|
2078 | write_sourceview = 1; |
---|
2079 | // generate files |
---|
2080 | if (write_code(sv_source_filename, sv_header_filename)) |
---|
2081 | { |
---|
2082 | // load file into source editor |
---|
2083 | int pos = sv_source->top_line(); |
---|
2084 | sv_source->buffer()->loadfile(sv_source_filename); |
---|
2085 | sv_source->scroll(pos, 0); |
---|
2086 | // load file into header editor |
---|
2087 | pos = sv_header->top_line(); |
---|
2088 | sv_header->buffer()->loadfile(sv_header_filename); |
---|
2089 | sv_header->scroll(pos, 0); |
---|
2090 | // update the source code highlighting |
---|
2091 | update_sourceview_position(); |
---|
2092 | } |
---|
2093 | write_sourceview = 0; |
---|
2094 | |
---|
2095 | code_file_name = code_file_name_bak; |
---|
2096 | header_file_name = header_file_name_bak; |
---|
2097 | } |
---|
2098 | |
---|
2099 | void update_sourceview_timer(void*) |
---|
2100 | { |
---|
2101 | update_sourceview_cb(0,0); |
---|
2102 | } |
---|
2103 | |
---|
2104 | // Set the "modified" flag and update the title of the main window... |
---|
2105 | void set_modflag(int mf) { |
---|
2106 | const char *basename; |
---|
2107 | static char title[1024]; |
---|
2108 | |
---|
2109 | modflag = mf; |
---|
2110 | |
---|
2111 | if (main_window) { |
---|
2112 | if (!filename) basename = "Untitled.fl"; |
---|
2113 | else if ((basename = strrchr(filename, '/')) != NULL) basename ++; |
---|
2114 | #if defined(WIN32) || defined(__EMX__) |
---|
2115 | else if ((basename = strrchr(filename, '\\')) != NULL) basename ++; |
---|
2116 | #endif // WIN32 || __EMX__ |
---|
2117 | else basename = filename; |
---|
2118 | |
---|
2119 | if (modflag) { |
---|
2120 | snprintf(title, sizeof(title), "%s (modified)", basename); |
---|
2121 | main_window->label(title); |
---|
2122 | } else main_window->label(basename); |
---|
2123 | } |
---|
2124 | // if the UI was modified in any way, update the Source View panel |
---|
2125 | if (sourceview_panel && sourceview_panel->visible() && sv_autorefresh->value()) |
---|
2126 | { |
---|
2127 | // we will only update ealiest 0.5 seconds after the last change, and only |
---|
2128 | // if no other change was made, so dragging a widget will not generate any |
---|
2129 | // CPU load |
---|
2130 | Fl::remove_timeout(update_sourceview_timer, 0); |
---|
2131 | Fl::add_timeout(0.5, update_sourceview_timer, 0); |
---|
2132 | } |
---|
2133 | |
---|
2134 | // Enable/disable the Save menu item... |
---|
2135 | if (modflag) Main_Menu[SAVE_ITEM].activate(); |
---|
2136 | else Main_Menu[SAVE_ITEM].deactivate(); |
---|
2137 | } |
---|
2138 | |
---|
2139 | //////////////////////////////////////////////////////////////// |
---|
2140 | |
---|
2141 | static int arg(int argc, char** argv, int& i) { |
---|
2142 | if (argv[i][1] == 'c' && !argv[i][2]) {compile_only = 1; i++; return 1;} |
---|
2143 | if (argv[i][1] == 'c' && argv[i][2] == 's' && !argv[i][3]) {compile_only = 1; compile_strings = 1; i++; return 1;} |
---|
2144 | if (argv[i][1] == 'o' && !argv[i][2] && i+1 < argc) { |
---|
2145 | code_file_name = argv[i+1]; |
---|
2146 | code_file_set = 1; |
---|
2147 | i += 2; |
---|
2148 | return 2; |
---|
2149 | } |
---|
2150 | if (argv[i][1] == 'h' && !argv[i][2]) { |
---|
2151 | header_file_name = argv[i+1]; |
---|
2152 | header_file_set = 1; |
---|
2153 | i += 2; |
---|
2154 | return 2; |
---|
2155 | } |
---|
2156 | return 0; |
---|
2157 | } |
---|
2158 | |
---|
2159 | #if ! (defined(WIN32) && !defined (__CYGWIN__)) |
---|
2160 | |
---|
2161 | int quit_flag = 0; |
---|
2162 | #include <signal.h> |
---|
2163 | #ifdef _sigargs |
---|
2164 | #define SIGARG _sigargs |
---|
2165 | #else |
---|
2166 | #ifdef __sigargs |
---|
2167 | #define SIGARG __sigargs |
---|
2168 | #else |
---|
2169 | #define SIGARG int // you may need to fix this for older systems |
---|
2170 | #endif |
---|
2171 | #endif |
---|
2172 | |
---|
2173 | extern "C" { |
---|
2174 | static void sigint(SIGARG) { |
---|
2175 | signal(SIGINT,sigint); |
---|
2176 | quit_flag = 1; |
---|
2177 | } |
---|
2178 | } |
---|
2179 | #endif |
---|
2180 | |
---|
2181 | int main(int argc,char **argv) { |
---|
2182 | int i = 1; |
---|
2183 | if (!Fl::args(argc,argv,i,arg) || i < argc-1) { |
---|
2184 | fprintf(stderr,"usage: %s <switches> name.fl\n" |
---|
2185 | " -c : write .cxx and .h and exit\n" |
---|
2186 | " -cs : write .cxx and .h and strings and exit\n" |
---|
2187 | " -o <name> : .cxx output filename, or extension if <name> starts with '.'\n" |
---|
2188 | " -h <name> : .h output filename, or extension if <name> starts with '.'\n" |
---|
2189 | "%s\n", argv[0], Fl::help); |
---|
2190 | return 1; |
---|
2191 | } |
---|
2192 | const char *c = argv[i]; |
---|
2193 | |
---|
2194 | fl_register_images(); |
---|
2195 | |
---|
2196 | make_main_window(); |
---|
2197 | |
---|
2198 | #ifdef __APPLE__ |
---|
2199 | fl_open_callback(apple_open_cb); |
---|
2200 | #endif // __APPLE__ |
---|
2201 | |
---|
2202 | if (c) set_filename(c); |
---|
2203 | if (!compile_only) { |
---|
2204 | Fl::visual((Fl_Mode)(FL_DOUBLE|FL_INDEX)); |
---|
2205 | Fl_File_Icon::load_system_icons(); |
---|
2206 | main_window->callback(exit_cb); |
---|
2207 | position_window(main_window,"main_window_pos", 1, 10, 30, WINWIDTH, WINHEIGHT ); |
---|
2208 | main_window->show(argc,argv); |
---|
2209 | toggle_widgetbin_cb(0,0); |
---|
2210 | toggle_sourceview_cb(0,0); |
---|
2211 | if (!c && openlast_button->value() && absolute_history[0][0]) { |
---|
2212 | // Open previous file when no file specified... |
---|
2213 | open_history_cb(0, absolute_history[0]); |
---|
2214 | } |
---|
2215 | } |
---|
2216 | undo_suspend(); |
---|
2217 | if (c && !read_file(c,0)) { |
---|
2218 | if (compile_only) { |
---|
2219 | fprintf(stderr,"%s : %s\n", c, strerror(errno)); |
---|
2220 | exit(1); |
---|
2221 | } |
---|
2222 | fl_message("Can't read %s: %s", c, strerror(errno)); |
---|
2223 | } |
---|
2224 | undo_resume(); |
---|
2225 | if (compile_only) { |
---|
2226 | if (compile_strings) write_strings_cb(0,0); |
---|
2227 | write_cb(0,0); |
---|
2228 | exit(0); |
---|
2229 | } |
---|
2230 | set_modflag(0); |
---|
2231 | undo_clear(); |
---|
2232 | #ifndef WIN32 |
---|
2233 | signal(SIGINT,sigint); |
---|
2234 | #endif |
---|
2235 | |
---|
2236 | grid_cb(horizontal_input, 0); // Makes sure that windows get snap params... |
---|
2237 | |
---|
2238 | #ifdef WIN32 |
---|
2239 | Fl::run(); |
---|
2240 | #else |
---|
2241 | while (!quit_flag) Fl::wait(); |
---|
2242 | |
---|
2243 | if (quit_flag) exit_cb(0,0); |
---|
2244 | #endif // WIN32 |
---|
2245 | |
---|
2246 | undo_clear(); |
---|
2247 | |
---|
2248 | return (0); |
---|
2249 | } |
---|
2250 | |
---|
2251 | // |
---|
2252 | // End of "$Id$". |
---|
2253 | // |
---|