Back to index

texmacs  1.0.7.15
file_chooser_widget.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : file_chooser.cpp
00004 * DESCRIPTION: A file_chooser widget with horizontal and vertical scrollbars.
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "Widkit/basic_widget.hpp"
00013 #include "Widkit/attribute_widget.hpp"
00014 #include "Widkit/layout.hpp"
00015 
00016 #include "bitmap_font.hpp"
00017 #include "font.hpp"
00018 #include "window.hpp"
00019 #include "file.hpp"
00020 #include "image_files.hpp"
00021 #include "analyze.hpp"
00022 #include "scheme.hpp"
00023 #include "dictionary.hpp"
00024 
00025 #ifdef OS_WIN32
00026 #include <X11/Xlib.h>
00027 #endif
00028 
00029 /******************************************************************************
00030 * File chooser commands
00031 ******************************************************************************/
00032 
00033 #define CHANGE_FILE      0
00034 #define CHANGE_DIR       1
00035 #define BUTTON_HOME      2
00036 #define BUTTON_TEXTS     3
00037 #define BUTTON_FILE_OK   4
00038 #define BUTTON_DIR_OK    5
00039 #define BUTTON_CANCEL    6
00040 #define IMAGE_HSIZE      7
00041 #define IMAGE_VSIZE      8
00042 #define IMAGE_XPOS       9
00043 #define IMAGE_YPOS      10
00044 #define CHANGE_SUFFIXES 11
00045 
00046 class file_chooser_command_rep: public command_rep {
00047   wk_widget_rep* fch;
00048   int type;
00049 public:
00050   file_chooser_command_rep (wk_widget w, int t): fch(w.rep), type(t) {}
00051   void apply ();
00052   tm_ostream& print (tm_ostream& out) {
00053     return out << "File chooser command (" << type << ")"; }
00054 };
00055 
00056 void
00057 file_chooser_command_rep::apply () {
00058   wk_widget fch_wid (fch);
00059   switch (type) {
00060   case CHANGE_FILE:
00061     {
00062       string s;
00063       fch_wid[0]["file"]["input"] << get_string ("input", s);
00064       fch_wid << set_string ("return", scm_unquote (s));
00065       break;
00066     }
00067   case CHANGE_DIR:
00068     {
00069       string dir;
00070       fch_wid[0]["directory"]["input"] << get_string ("input", dir);
00071       if (dir == "#f") fch_wid << set_string ("return", "#f");
00072       else {
00073        dir= scm_unquote (dir);
00074        fch_wid << set_string ("directory", dir);
00075       }
00076       break;
00077     }
00078   case BUTTON_HOME:
00079     fch_wid << set_string ("directory", "~");
00080     break;
00081   case BUTTON_TEXTS:
00082     fch_wid << set_string ("directory",
00083                         as_string (url ("$TEXMACS_HOME_PATH", "texts")));
00084     break;
00085   case BUTTON_FILE_OK:
00086     {
00087       string s;
00088       fch_wid[0]["file"]["input"] << get_string ("input", s);
00089       fch_wid << set_string ("return", scm_unquote (s));
00090       break;
00091     }
00092   case BUTTON_DIR_OK:
00093     {
00094       string s;
00095       fch_wid[0]["directory"]["input"] << get_string ("input", s);
00096       fch_wid << set_string ("return", scm_unquote (s));
00097       break;
00098     }
00099   case BUTTON_CANCEL:
00100     fch_wid << set_string ("return", "#f");
00101     break;
00102   case CHANGE_SUFFIXES:
00103     {
00104       string sxs;
00105       fch_wid[0]["suffixes"]["input"] << get_string ("input", sxs);
00106       fch_wid << set_string ("suffixes", scm_unquote (sxs));
00107       break;
00108     }
00109   default:
00110     {
00111       string which, s;
00112       if (type == IMAGE_HSIZE) which= "hsize";
00113       else if (type == IMAGE_VSIZE) which= "vsize";
00114       else if (type == IMAGE_XPOS) which= "xpos";
00115       else if (type == IMAGE_YPOS) which= "ypos";
00116       else break;
00117       wk_widget inp= fch_wid[0]["image"]["parameters"][which]["input"];
00118       inp << get_string ("input", s);
00119       if (s == "#f") fch_wid << set_string ("return", "#f");
00120       else inp << set_string ("input", scm_unquote (s));
00121       break;
00122     }
00123   }
00124 }
00125 
00126 command
00127 file_chooser_command (wk_widget fch, int type) {
00128   return tm_new<file_chooser_command_rep> (fch, type);
00129 }
00130 
00131 /******************************************************************************
00132 * File_list widgets
00133 ******************************************************************************/
00134 
00135 class file_list_widget_rep: public attribute_widget_rep {
00136   wk_widget_rep* fch;
00137   string             dir;
00138   array<bool>        lids;
00139   array<string>      names;
00140   array<string>      suffix;
00141   bool               dir_flag;
00142   int                hilight;
00143 
00144 public:
00145   file_list_widget_rep (wk_widget ch, array<string> suffix, bool dir_flag);
00146   operator tree ();
00147 
00148   wk_widget get_canvas ();
00149 
00150   void handle_get_size (get_size_event ev);
00151   void handle_repaint (repaint_event ev);
00152   void handle_mouse (mouse_event ev);
00153   void handle_set_string (set_string_event ev);
00154 };
00155 
00156 /******************************************************************************
00157 * Implementation of file_list widgets
00158 ******************************************************************************/
00159 
00160 file_list_widget_rep::file_list_widget_rep (
00161   wk_widget c, array<string> s, bool f):
00162     attribute_widget_rep (0), fch (c.rep),
00163     dir (""), suffix (s), dir_flag (f), hilight (-1) {}
00164 
00165 file_list_widget_rep::operator tree () {
00166   return "file_list";
00167 }
00168 
00169 wk_widget
00170 file_list_widget_rep::get_canvas () {
00171   string which (dir_flag? string ("directories"): string ("files"));
00172   wk_widget fch_wid (fch);
00173   return fch_wid[0]["list"][which];
00174 }
00175 
00176 static bool
00177 has_suffix (string name, array<string> suffix) {
00178   int i;
00179   for (i=0; i<N(suffix); i++)
00180     if (ends (locase_all (name), suffix[i])) return true;
00181   return false;
00182 }
00183 
00184 static bool
00185 list_in_directory (string dir, string name,
00186                  array<string> suffix, bool dir_flag)
00187 {
00188   if (name == "") return false;
00189   if (name == "..") return dir_flag;
00190   if (name[0]=='.') return false;
00191   if (dir_flag) return is_directory (url_system (dir, name));
00192   else return is_regular (url_system (dir, name)) && has_suffix (name, suffix);
00193 }
00194 
00195 void
00196 file_list_widget_rep::handle_get_size (get_size_event ev) {
00197   int i;
00198   metric ex;
00199   font fn= get_default_font ();
00200   ev->w= ev->h= 0;
00201   for (i=0; i<N(names); i++)
00202     if (lids[i]) {
00203       fn->var_get_extents (names[i], ex);
00204       ev->w  = max (ev->w, ((ex->x2- ex->x1+ 2)/3) + (6*PIXEL));
00205       ev->h += ((fn->y2- fn->y1+ 2)/3) + (4*PIXEL);
00206     }
00207   abs_round (ev->w, ev->h);
00208 }
00209 
00210 void
00211 file_list_widget_rep::handle_repaint (repaint_event ev) { (void) ev;
00212   renderer ren= win->get_renderer ();
00213   int i; 
00214   metric ex;
00215   ren->set_background (white);
00216   ren->clear (0, -h, w, 0);
00217   font fn= get_default_font ();
00218   ren->set_shrinking_factor (3);
00219   SI y= 0;
00220   for (i=0; i<N(names); i++)
00221     if (lids[i]) {
00222       ren->set_color (black);
00223       if (hilight == i) ren->set_color (red);
00224       fn->var_get_extents (names[i], ex);
00225       fn ->draw (ren, names[i], 9*PIXEL, y-fn->y2-6*PIXEL);
00226       y += fn->y1- fn->y2- 12*PIXEL;
00227     }
00228   ren->set_shrinking_factor (1);
00229 }
00230 
00231 void
00232 file_list_widget_rep::handle_mouse (mouse_event ev) {
00233   string type= ev->type;
00234 
00235   if ((type == "release-left") || (type == "release-right")) {
00236     int i;
00237     SI y= 0, search= ev->y*3;
00238     metric ex;
00239     font fn= get_default_font ();
00240     for (i=0; i<N(names); i++)
00241       if (lids[i]) {
00242        fn->var_get_extents (names[i], ex);
00243        if ((search >= (y+ fn->y1- fn->y2- 12*PIXEL)) && (search < y)) break;
00244        y += fn->y1- fn->y2- 12*PIXEL;
00245       }
00246     if (i==N(names)) return;
00247 
00248     string s= names[i];
00249     wk_widget fch_wid (fch);
00250     if (hilight == i) {
00251       if (dir_flag) {
00252        string name= as_string (url_system (dir, s));
00253        fch_wid << set_string ("directory", name);
00254       }
00255       else fch_wid << set_string ("return", s);
00256     }
00257     else {
00258       hilight= i;
00259       if (!dir_flag) fch_wid << set_string ("file", s);
00260       this << emit_invalidate_all ();
00261     }
00262   }
00263 
00264   if ((type == "press-up") || (type == "press-down")) {
00265     SI x, y, dy= 100*PIXEL;
00266     if (type == "press-down") dy= -dy;
00267     get_canvas () << get_coord2 ("scroll position", x, y);
00268     y += dy;
00269     get_canvas () << set_scroll_pos (x, y);
00270   }
00271 }
00272 
00273 void
00274 file_list_widget_rep::handle_set_string (set_string_event ev) {
00275   if (ev->which == "directory") {
00276     dir= ev->s;
00277     bool flag;
00278     names= read_directory (url_system (dir), flag);
00279     lids= array<bool>(N(names));
00280     for (int i=0; i<N(names); i++)
00281       lids[i]= list_in_directory (dir, names[i], suffix, dir_flag);
00282     SI w, h;
00283     this << get_size (w, h, 0);
00284     get_canvas () << set_extents (0, -h, w, 0);
00285     hilight=-1;
00286     if (attached ()) this << emit_invalidate_all ();
00287   }
00288   else attribute_widget_rep::handle_set_string (ev);
00289 }
00290 
00291 /******************************************************************************
00292 * image widgets
00293 ******************************************************************************/
00294 
00295 class image_widget_rep: public attribute_widget_rep {
00296   string file_name;
00297 public:
00298   image_widget_rep ();
00299   operator tree ();
00300   void handle_get_size (get_size_event ev);
00301   void handle_repaint (repaint_event ev);
00302   void handle_set_string (set_string_event ev);
00303 };
00304 
00305 /******************************************************************************
00306 * Implementation of image widgets
00307 ******************************************************************************/
00308 
00309 image_widget_rep::image_widget_rep ():
00310   attribute_widget_rep (0, south_west), file_name ("") {}
00311 
00312 image_widget_rep::operator tree () {
00313   return "image";
00314 }
00315 
00316 void
00317 image_widget_rep::handle_get_size (get_size_event ev) {
00318   ev->w= 221*PIXEL;
00319 }
00320 
00321 void
00322 image_widget_rep::handle_repaint (repaint_event ev) { (void) ev;
00323   renderer ren= win->get_renderer ();
00324   ren->set_background (white);
00325   ren->clear (0, 0, w, h);
00326   layout_dark_outline (ren, 0, 0, w, h);
00327   if (file_name != "") {
00328     SI iw, ih;
00329     image_size (url_system (file_name), iw, ih);
00330     
00331     SI ww= w-2*PIXEL, hh= h-2*PIXEL;
00332     if ((ww>0) && (hh>0) && (iw>0) && (ih>0)) {
00333       if (iw * hh > ih * ww)
00334        hh= (ww * ih) / iw;
00335       else ww= (hh * iw) / ih;
00336     }
00337 
00338     ren->image (url_system (file_name),
00339               ww, hh, PIXEL, PIXEL, 0.0, 0.0, 1.0, 1.0);
00340   }
00341 }
00342 
00343 void
00344 image_widget_rep::handle_set_string (set_string_event ev) {
00345   if (ev->which == "name") {
00346     file_name= ev->s;
00347     if (attached ()) this << emit_invalidate_all ();
00348   }
00349   else attribute_widget_rep::handle_set_string (ev);
00350 }
00351 
00352 /******************************************************************************
00353 * File_Chooser widgets
00354 ******************************************************************************/
00355 
00356 class file_chooser_widget_rep: public attribute_widget_rep {
00357   command       cmd;
00358   string        type;
00359   array<string> suffix;
00360 
00361 public:
00362   file_chooser_widget_rep (command cmd, string type);
00363   operator tree ();
00364 
00365   wk_widget input_widget (string what, string ref, int type);
00366   wk_widget button_widget (string what, int type);
00367 
00368   void handle_get_size (get_size_event ev);
00369   void handle_set_string (set_string_event ev);
00370   void handle_get_string (get_string_event ev);
00371   void handle_destroy (destroy_event ev);
00372 };
00373 
00374 /******************************************************************************
00375 * Drives under Windows
00376 ******************************************************************************/
00377 
00378 #ifdef OS_WIN32
00379 class drive_menu_command_rep: public command_rep {
00380   string driveLetter;
00381   file_chooser_widget_rep *fileChooser;
00382 
00383 public:
00384   drive_menu_command_rep (file_chooser_widget_rep *fileChooser2,
00385                        string driveLetter2):
00386     fileChooser (fileChooser2), driveLetter(driveLetter2) {}
00387   void apply () {
00388     fileChooser << set_string("directory", driveLetter);
00389   }
00390 };
00391 #endif
00392 
00393 /******************************************************************************
00394 * Implementation of file_chooser widgets
00395 ******************************************************************************/
00396 
00397 wk_widget
00398 file_chooser_widget_rep::input_widget (string what, string ref, int type) {
00399   SI ww1= 1280*PIXEL, hh1= 64*PIXEL, ww2= 1280*PIXEL, hh2= 64*PIXEL;
00400   wk_widget ref_w = text_wk_widget (translate (ref));
00401   wk_widget what_w= text_wk_widget (translate (what));
00402   ref_w  << get_size (ww1, hh1, 0);
00403   what_w << get_size (ww2, hh2, 0);
00404   SI offset= max (ww1 - ww2, 0);
00405 
00406   array<wk_widget> ww (4);
00407   array<string> nn (4);
00408   ww[0]= glue_wk_widget (false, false, offset);
00409   ww[1]= what_w;
00410   ww[2]= input_text_wk_widget (file_chooser_command (this, type));
00411   nn[2]= "input";
00412   ww[3]= glue_wk_widget (false, false, 3*PIXEL);
00413   if (type == CHANGE_DIR) ww[2] << set_string ("type", "directory");
00414   return horizontal_list (ww, nn);
00415 }
00416 
00417 wk_widget
00418 file_chooser_widget_rep::button_widget (string what, int type) {
00419   return command_button (text_wk_widget (translate (what)),
00420                       file_chooser_command (this, type),
00421                       WIDGET_STYLE_BUTTON);
00422 }
00423 
00424 file_chooser_widget_rep::file_chooser_widget_rep (
00425   command cmd2, string type2):
00426   attribute_widget_rep (1), cmd (cmd2), type (type2)
00427 {
00428   ref_count++;
00429 
00430   tree t= stree_to_tree (call ("format-get-suffixes*", type));
00431   int i, n= N(t);
00432   for (i=0; i<n; i++)
00433     suffix << ("." * as_string (t[i]));
00434   if (n == 0) suffix << string ("");
00435 
00436   SI sep= 3*PIXEL;
00437   int cw2n= 5;
00438   if (type == "directory") cw2n= 3;
00439   array<wk_widget> cw2 (cw2n);
00440   array<string> cn2 (cw2n);
00441   cw2[0]= glue_wk_widget (false, true, sep);
00442   cw2[1]= canvas_widget (wk_widget (tm_new<file_list_widget_rep> (this, suffix, true)));
00443   cn2[1]= "directories";
00444   cw2[2]= glue_wk_widget (false, true, sep);
00445   if (type != "directory") {
00446     cw2[3]= canvas_widget (wk_widget (tm_new<file_list_widget_rep> (this, suffix, false)));
00447     cn2[3]= "files";
00448     cw2[4]= glue_wk_widget (false, true, sep-PIXEL);
00449   }
00450 
00451 #ifdef OS_WIN32
00452   wk_widget drive_menu = vertical_menu (array<wk_widget> ());
00453   unsigned int driveMask = XGetDrivesMask();
00454   char driveString[4] = "A:\\";
00455   for (char x = 'A'; x <= 'Z'; x++)
00456     if(driveMask & (1 << (x - 'A'))) {
00457       driveString[0] = x;
00458       drive_menu << emit_insert (driveString,
00459        command_button (text_wk_widget (driveString),
00460                      tm_new<drive_menu_command_rep> (this, driveString)));
00461     }
00462   array<wk_widget> drw (2);
00463   drw[0] = pullright_button (text_wk_widget (translate ("Drive")), drive_menu);
00464   drw[1] = text_wk_widget ("");
00465   // drw[1]= glue_wk_widget (false, true, sep);
00466 #endif
00467 
00468   int BUTTON_OK= BUTTON_FILE_OK;
00469   if (type == "directory") BUTTON_OK= BUTTON_DIR_OK;
00470 
00471 #ifdef OS_WIN32
00472   array<wk_widget> cw3 (11);
00473   cw3[0]= glue_wk_widget (false, false, sep);
00474   cw3[1]= pulldown_button (text_wk_widget (translate ("Drive")),
00475                         drive_menu, true);
00476   cw3[2]= glue_wk_widget (false, false, sep);
00477   cw3[3]= button_widget ("Home", BUTTON_HOME);
00478   cw3[4]= glue_wk_widget (false, false, sep);
00479   cw3[5]= button_widget ("Texts", BUTTON_TEXTS);
00480   cw3[6]= glue_wk_widget (true, false);
00481   cw3[7]= button_widget ("Ok", BUTTON_OK);
00482   cw3[8]= glue_wk_widget (false, false, sep);
00483   cw3[9]= button_widget ("Cancel", BUTTON_CANCEL);
00484   cw3[10]= glue_wk_widget (false, false, sep);
00485 #else
00486   array<wk_widget> cw3 (9);
00487   cw3[0]= glue_wk_widget (false, false, sep);
00488   cw3[1]= button_widget ("Home", BUTTON_HOME);
00489   cw3[2]= glue_wk_widget (false, false, sep);
00490   cw3[3]= button_widget ("Texts", BUTTON_TEXTS);
00491   cw3[4]= glue_wk_widget (true, false);
00492   cw3[5]= button_widget ("Ok", BUTTON_OK);
00493   cw3[6]= glue_wk_widget (false, false, sep);
00494   cw3[7]= button_widget ("Cancel", BUTTON_CANCEL);
00495 #ifdef OS_MACOS
00496   cw3[8]= glue_wk_widget (false, false, sep + 14*PIXEL);
00497 #else
00498   cw3[8]= glue_wk_widget (false, false, sep);
00499 #endif
00500 #endif
00501 
00502   int cwn= 11;
00503   if (type == "image") cwn= 16;
00504   if (type == "directory") cwn= 7;
00505   array<wk_widget> cw (cwn);
00506   array<string> cn (cwn);
00507   cw[0]= glue_wk_widget (true, false, 0, sep);
00508   cw[1]= input_widget ("Directory:", "Directory:", CHANGE_DIR);
00509   cn[1]= "directory";
00510   cw[2]= glue_wk_widget (true, false, 0, sep);
00511 
00512   if (type == "directory") {
00513     cw[3]= horizontal_list (cw2, cn2);
00514     cn[3]= "list";
00515   }
00516 
00517   if (type != "directory") {
00518     cw[3]= input_widget ("File:", "Directory:", CHANGE_FILE);
00519     cn[3]= "file";
00520     cw[4]= glue_wk_widget (true, false, 0, sep);
00521     cw[5]= input_widget ("Suffixes:", "Directory:", CHANGE_SUFFIXES);
00522     cn[5]= "suffixes";
00523     cw[6]= glue_wk_widget (true, false, 0, sep);
00524     cw[7]= horizontal_list (cw2, cn2);
00525     cn[7]= "list";
00526   }
00527 
00528   if (type == "image") {
00529     array<wk_widget> imw (7);
00530     array<string> ims (7);
00531     imw[ 0]= input_widget ("width:", "y-position:", IMAGE_HSIZE);
00532     ims[ 0]= "hsize";
00533     imw[ 1]= glue_wk_widget (true, false, 0, sep);
00534     imw[ 2]= input_widget ("height:", "y-position:", IMAGE_VSIZE);
00535     ims[ 2]= "vsize";
00536     imw[ 3]= glue_wk_widget (true, false, 0, sep);
00537     imw[ 4]= input_widget ("x-position:", "y-position:", IMAGE_XPOS);
00538     ims[ 4]= "xpos";
00539     imw[ 5]= glue_wk_widget (true, false, 0, sep);
00540     imw[ 6]= input_widget ("y-position:", "y-position:", IMAGE_YPOS);
00541     ims[ 6]= "ypos";
00542 
00543     array<wk_widget> cw4 (5);
00544     array<string> cn4 (5);
00545     cw4[0] = glue_wk_widget (false, false, sep);
00546     cw4[1] = vertical_list (imw, ims);
00547     cn4[1] = "parameters";
00548     cw4[2] = glue_wk_widget (false, false, sep);
00549     cw4[3] = tm_new<image_widget_rep> ();
00550     cn4[3] = "image";
00551     cw4[4] = glue_wk_widget (false, false, sep);
00552 
00553     //cw[ 8] = glue_wk_widget (true, false, 0, sep);
00554     //cw[ 9] = separator_wk_widget ();
00555     cw[ 8] = glue_wk_widget (true, false, 0, sep);
00556     cw[ 9] = horizontal_list (cw4, cn4);
00557     cn[ 9] = "image";
00558     cw[10] = glue_wk_widget (true, false, 0, sep);
00559     cw[11] = separator_wk_widget ();
00560     cw[12] = glue_wk_widget (true, false, 0, sep);
00561   }
00562 
00563   cw[cwn-3]= glue_wk_widget (true, false, 0, sep);
00564   cw[cwn-2]= horizontal_list (cw3);
00565   cn[cwn-2]= "buttons";
00566   cw[cwn-1]= glue_wk_widget (true, false, 0, sep);
00567 
00568   a[0]= vertical_list (cw, cn);
00569 
00570   if (type != "directory") {
00571     string s;
00572     for (i=0; i<N(suffix); ++i) {
00573       if (i) s << " ";
00574       s << suffix[i];
00575     }
00576     a[0]["suffixes"]["input"] << set_string ("input", s);
00577   }
00578 
00579   ref_count--;
00580 }
00581 
00582 file_chooser_widget_rep::operator tree () {
00583   return tree (TUPLE, "file_chooser", (tree) a[0]);
00584 }
00585 
00586 void
00587 file_chooser_widget_rep::handle_get_size (get_size_event ev) {
00588   if (ev->mode < 1) {
00589     ev->w= 451*PIXEL;
00590     if (type == "image") ev->h= 500*PIXEL;
00591     else ev->h= 350*PIXEL;
00592   }
00593   else gui_maximal_extents (ev->w, ev->h);
00594 }
00595 
00596 void
00597 file_chooser_widget_rep::handle_set_string (set_string_event ev) {
00598   if (ev->which == "directory") {
00599     string dir= as_string (url_pwd () * url_system (ev->s));
00600     a[0]["directory"]["input"] << set_string ("input", dir);
00601     a[0]["list"]["directories"] << set_string ("directory", dir);
00602     if (type != "directory") {
00603       // a[0]["file"]["input"] << set_string ("input", "");
00604       a[0]["list"]["files"] << set_string ("directory", dir);
00605     }
00606   }
00607   else if (ev->which == "file") {
00608     if (type == "directory") return;
00609     a[0]["file"]["input"] << set_string ("input", ev->s);
00610     if (type == "image") {
00611       string dir, name= ev->s;
00612       a[0]["directory"]["input"] << get_string ("input", dir);
00613       if (name != "") name= as_string (url_system (scm_unquote (dir), name));
00614       a[0]["image"]["image"] << set_string ("name", name);
00615       array<string> ps_suffix;
00616       ps_suffix << string (".ps") << string (".eps");
00617       wk_widget par_wid= a[0]["image"]["parameters"];
00618     }
00619   }
00620   else if (ev->which == "return") {
00621     string s= ev->s;
00622     if (type == "directory") {
00623       a[0]["directory"]["input"] << set_string ("input", s);
00624       cmd ();
00625     }
00626     else {
00627       if (s != "#f" && !has_suffix (s, suffix))
00628        a[0]["file"]["input"] << set_string ("input", s * suffix[0]);
00629       else {
00630        a[0]["file"]["input"] << set_string ("input", s);
00631        cmd ();
00632       }
00633     }
00634   }
00635   else if (ev->which == "suffixes") {
00636     if (type == "directory") return;
00637     // surely the following can be done better:
00638     suffix->resize(0);
00639     int i=0, any=0;
00640     string s= scm_unquote (ev->s);
00641     a[0]["suffixes"]["input"] << set_string ("input", s);
00642     while (i<N(s)) {
00643       while (s[i]==' ') ++i;
00644       int j=i;
00645       while (j<N(s) && s[j]!=' ') ++j;
00646       if (j>i) {
00647         suffix << s(i,j);
00648         any=1;
00649       }
00650       i=j+1;
00651     }
00652     if (!any) suffix << string ("");
00653     // Force a refresh:
00654     string dir;
00655     a[0]["directory"]["input"] << get_string ("input", dir);
00656     a[0]["list"]["directories"] << set_string ("directory", scm_unquote (dir));
00657     a[0]["list"]["files"] << set_string ("directory", scm_unquote (dir));
00658   }
00659   else attribute_widget_rep::handle_set_string (ev);
00660 }
00661 
00662 void
00663 file_chooser_widget_rep::handle_get_string (get_string_event ev) {
00664   if (ev->which == "input") {
00665     string dir, name;
00666     a[0]["directory"]["input"] << get_string ("input", dir);
00667     if (type == "directory") {
00668       a[0]["directory"]["input"] << get_string ("input", name);
00669       if (name == "#f") { ev->s= "#f"; return; }
00670       url u= url_system (scm_unquote (dir));
00671       ev->s= "(url-system " * scm_quote (as_string (u)) * ")";
00672     }
00673     else {
00674       a[0]["file"]["input"] << get_string ("input", name);
00675       if (name == "#f") { ev->s= "#f"; return; }
00676       url u= url_system (scm_unquote (dir)) * url_system (scm_unquote (name));
00677       ev->s= "(url-system " * scm_quote (as_string (u)) * ")";
00678     }
00679     if (type == "image") {
00680       string hsize, vsize, xpos, ypos;
00681       wk_widget par= a[0]["image"]["parameters"];
00682       par["hsize"]["input"] << get_string ("input", hsize);
00683       par["vsize"]["input"] << get_string ("input", vsize);
00684       par["xpos"]["input"] << get_string ("input", xpos);
00685       par["ypos"]["input"] << get_string ("input", ypos);
00686       ev->s= "(list " * ev->s * " " * hsize * " " * vsize * " " *
00687                        xpos * " " * ypos * ")";
00688     }
00689   }
00690   else attribute_widget_rep::handle_get_string (ev);
00691 }
00692 
00693 void
00694 file_chooser_widget_rep::handle_destroy (destroy_event ev) {
00695   (void) ev;
00696   this << set_string ("return", "#f");
00697 }
00698 
00699 /******************************************************************************
00700 * exported routines
00701 ******************************************************************************/
00702 
00703 wk_widget
00704 file_chooser_wk_widget (command cmd, string type) {
00705   return tm_new<file_chooser_widget_rep> (cmd, type);
00706 }