1 //
2 // "$Id: file_chooser.cxx 8164 2011-01-01 20:17:58Z matt $"
3 //
4 // File chooser test program.
5 //
6 // Copyright 1999-2010 by Michael Sweet.
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 // Contents:
28 //
29 //   main()           - Create a file chooser and wait for a selection to
30 //                      be made.
31 //   close_callback() - Close the main window...
32 //   fc_callback()    - Handle choices in the file chooser...
33 //   pdf_check()      - Check for and load the first page of a PDF file.
34 //   ps_check()       - Check for and load the first page of a PostScript
35 //                      file.
36 //   show_callback()  - Show the file chooser...
37 //
38 //   extra_callback() - circle extra groups (none,group1,check_button);
39 //
40 
41 //
42 // Include necessary headers...
43 //
44 
45 #include <stdio.h>
46 #include <FL/Fl_File_Chooser.H>
47 #include <FL/Fl_File_Icon.H>
48 #include <FL/Fl_Shared_Image.H>
49 #include <FL/Fl_PNM_Image.H>
50 #include <FL/Fl_Light_Button.H>
51 #include <FL/Fl_Double_Window.H>
52 #include <string.h>
53 
54 
55 //
56 // Globals...
57 //
58 
59 Fl_Input		*filter;
60 Fl_File_Browser		*files;
61 Fl_File_Chooser		*fc;
62 Fl_Shared_Image		*image = 0;
63 
64 // for choosing extra groups
65 Fl_Choice *ch_extra;
66 // first extra group
67 Fl_Group *encodings = (Fl_Group*)0;
68 Fl_Choice *ch_enc;
69 // second extra widget
70 Fl_Check_Button *version = (Fl_Check_Button*)0;
71 
72 //
73 // Functions...
74 //
75 
76 void		close_callback(void);
77 void		create_callback(void);
78 void		dir_callback(void);
79 void		fc_callback(Fl_File_Chooser *, void *);
80 void		multi_callback(void);
81 Fl_Image	*pdf_check(const char *, uchar *, int);
82 Fl_Image	*ps_check(const char *, uchar *, int);
83 void		show_callback(void);
84 
85 void		extra_callback(Fl_Choice*,void*);
86 
87 //
88 // 'main()' - Create a file chooser and wait for a selection to be made.
89 //
90 
91 int			// O - Exit status
main(int argc,char * argv[])92 main(int  argc,		// I - Number of command-line arguments
93      char *argv[])	// I - Command-line arguments
94 {
95   Fl_Double_Window	*window;// Main window
96   Fl_Button		*button;// Buttons
97   Fl_File_Icon		*icon;	// New file icon
98 
99 
100   // Make the file chooser...
101   Fl::scheme(NULL);
102   Fl_File_Icon::load_system_icons();
103 
104   fc = new Fl_File_Chooser(".", "*", Fl_File_Chooser::SINGLE, "Fl_File_Chooser Test");
105   fc->callback(fc_callback);
106 
107   // Register the PS and PDF image types...
108   Fl_Shared_Image::add_handler(pdf_check);
109   Fl_Shared_Image::add_handler(ps_check);
110 
111   // Make the main window...
112   window = new Fl_Double_Window(400, 215, "File Chooser Test");
113 
114   filter = new Fl_Input(50, 10, 315, 25, "Filter:");
115   int argn = 1;
116 #ifdef __APPLE__
117   // OS X may add the process number as the first argument - ignore
118   if (argc>argn && strncmp(argv[1], "-psn_", 5)==0)
119     argn++;
120 #endif
121   if (argc > argn)
122     filter->value(argv[argn]);
123   else
124     filter->value("PDF Files (*.pdf)\t"
125                   "PostScript Files (*.ps)\t"
126 		  "Image Files (*.{bmp,gif,jpg,png})\t"
127 		  "C/C++ Source Files (*.{c,C,cc,cpp,cxx})");
128 
129   button = new Fl_Button(365, 10, 25, 25);
130   button->labelcolor(FL_YELLOW);
131   button->callback((Fl_Callback *)show_callback);
132 
133   icon   = Fl_File_Icon::find(".", Fl_File_Icon::DIRECTORY);
134   icon->label(button);
135 
136   button = new Fl_Light_Button(50, 45, 80, 25, "MULTI");
137   button->callback((Fl_Callback *)multi_callback);
138 
139   button = new Fl_Light_Button(140, 45, 90, 25, "CREATE");
140   button->callback((Fl_Callback *)create_callback);
141 
142   button = new Fl_Light_Button(240, 45, 115, 25, "DIRECTORY");
143   button->callback((Fl_Callback *)dir_callback);
144 
145   //
146   ch_extra = new Fl_Choice(150, 75, 150, 25, "Extra Group:");
147   ch_extra->add("none|encodings group|check button");
148   ch_extra->value(0);
149   ch_extra->callback((Fl_Callback *)extra_callback);
150   //
151   files = new Fl_File_Browser(50, 105, 340, 75, "Files:");
152   files->align(FL_ALIGN_LEFT);
153 
154   button = new Fl_Button(340, 185, 50, 25, "Close");
155   button->callback((Fl_Callback *)close_callback);
156 
157   window->resizable(files);
158   window->end();
159   window->show(1, argv);
160 
161   Fl::run();
162 
163   return (0);
164 }
165 
166 
167 void
extra_callback(Fl_Choice * w,void *)168 extra_callback(Fl_Choice*w,void*)
169 {
170   int val=w->value();
171   if (0 == val) fc->add_extra(NULL);
172   else if (1 == val) {
173     if(!encodings){
174       encodings=new Fl_Group(0,0,254,30);
175       ch_enc=new Fl_Choice(152,2,100,25,"Choose Encoding:");
176       ch_enc->add("ASCII|Koi8-r|win1251|Utf-8");
177       encodings->end();
178     }
179     fc->add_extra(encodings);
180   } else {
181     if (!version) {
182       version = new Fl_Check_Button(5,0,200,25,"Save binary 1.0 version");
183     }
184     fc->add_extra(version);
185   }
186 }
187 
188 
189 //
190 // 'close_callback()' - Close the main window...
191 //
192 
193 void
close_callback(void)194 close_callback(void)
195 {
196   exit(0);
197 }
198 
199 
200 //
201 // 'create_callback()' - Handle clicks on the create button.
202 //
203 
204 void
create_callback(void)205 create_callback(void)
206 {
207   fc->type(fc->type() ^ Fl_File_Chooser::CREATE);
208 }
209 
210 
211 //
212 // 'dir_callback()' - Handle clicks on the directory button.
213 //
214 
215 void
dir_callback(void)216 dir_callback(void)
217 {
218   fc->type(fc->type() ^ Fl_File_Chooser::DIRECTORY);
219 }
220 
221 
222 //
223 // 'fc_callback()' - Handle choices in the file chooser...
224 //
225 
226 void
fc_callback(Fl_File_Chooser * fc,void * data)227 fc_callback(Fl_File_Chooser *fc,	// I - File chooser
228             void            *data)	// I - Data
229 {
230   const char		*filename;	// Current filename
231 
232 
233   printf("fc_callback(fc = %p, data = %p)\n", fc, data);
234 
235   filename = fc->value();
236 
237   printf("    filename = \"%s\"\n", filename ? filename : "(null)");
238 }
239 
240 
241 //
242 // 'multi_callback()' - Handle clicks on the multi button.
243 //
244 
245 void
multi_callback(void)246 multi_callback(void)
247 {
248   fc->type(fc->type() ^ Fl_File_Chooser::MULTI);
249 }
250 
251 
252 //
253 // 'pdf_check()' - Check for and load the first page of a PDF file.
254 //
255 
256 Fl_Image *			// O - Page image or NULL
pdf_check(const char * name,uchar * header,int)257 pdf_check(const char *name,	// I - Name of file
258           uchar      *header,	// I - Header data
259 	  int)			// I - Length of header data (unused)
260 {
261   const char	*home;		// Home directory
262   char		preview[FL_PATH_MAX],	// Preview filename
263 		command[FL_PATH_MAX];	// Command
264 
265 
266   if (memcmp(header, "%PDF", 4) != 0)
267     return 0;
268 
269   home = getenv("HOME");
270   sprintf(preview, "%s/.preview.ppm", home ? home : "");
271 
272   sprintf(command,
273           "gs -r100 -dFIXED -sDEVICE=ppmraw -dQUIET -dNOPAUSE -dBATCH "
274 	  "-sstdout=\"%%stderr\" -sOUTPUTFILE=\'%s\' "
275 	  "-dFirstPage=1 -dLastPage=1 \'%s\' 2>/dev/null", preview, name);
276 
277   if (system(command)) return 0;
278 
279   return new Fl_PNM_Image(preview);
280 }
281 
282 
283 //
284 // 'ps_check()' - Check for and load the first page of a PostScript file.
285 //
286 
287 Fl_Image *			// O - Page image or NULL
ps_check(const char * name,uchar * header,int)288 ps_check(const char *name,	// I - Name of file
289          uchar      *header,	// I - Header data
290 	 int)			// I - Length of header data (unused)
291 {
292   const char	*home;		// Home directory
293   char		preview[FL_PATH_MAX],	// Preview filename
294 		outname[FL_PATH_MAX],	// Preview PS file
295 		command[FL_PATH_MAX];	// Command
296   FILE		*in,		// Input file
297 		*out;		// Output file
298   int		page;		// Current page
299   char		line[256];	// Line from file
300 
301 
302   if (memcmp(header, "%!", 2) != 0)
303     return 0;
304 
305   home = getenv("HOME");
306   sprintf(preview, "%s/.preview.ppm", home ? home : "");
307 
308   if (memcmp(header, "%!PS", 4) == 0) {
309     // PS file has DSC comments; extract the first page...
310     sprintf(outname, "%s/.preview.ps", home ? home : "");
311 
312     if (strcmp(name, outname) != 0) {
313       in   = fl_fopen(name, "rb");
314       out  = fl_fopen(outname, "wb");
315       page = 0;
316 
317       while (fgets(line, sizeof(line), in) != NULL) {
318 	if (strncmp(line, "%%Page:", 7) == 0) {
319           page ++;
320 	  if (page > 1) break;
321 	}
322 
323 	fputs(line, out);
324       }
325 
326       fclose(in);
327       fclose(out);
328     }
329   } else {
330     // PS file doesn't have DSC comments; do the whole file...
331     strncpy(outname, name, sizeof(outname) - 1);
332     outname[sizeof(outname) - 1] = '\0';
333   }
334 
335   sprintf(command,
336           "gs -r100 -dFIXED -sDEVICE=ppmraw -dQUIET -dNOPAUSE -dBATCH "
337 	  "-sstdout=\"%%stderr\" -sOUTPUTFILE=\'%s\' \'%s\' 2>/dev/null",
338 	  preview, outname);
339 
340   if (system(command)) return 0;
341 
342   return new Fl_PNM_Image(preview);
343 }
344 
345 
346 //
347 // 'show_callback()' - Show the file chooser...
348 //
349 
350 void
show_callback(void)351 show_callback(void)
352 {
353   int	i;			// Looping var
354   int	count;			// Number of files selected
355   char	relative[FL_PATH_MAX];	// Relative filename
356 
357 
358   if (filter->value()[0])
359     fc->filter(filter->value());
360 
361   fc->show();
362 
363   while (fc->visible()) {
364     Fl::wait();
365   }
366 
367   count = fc->count();
368   if (count > 0)
369   {
370     files->clear();
371 
372     for (i = 1; i <= count; i ++)
373     {
374       if (!fc->value(i))
375         break;
376 
377       fl_filename_relative(relative, sizeof(relative), fc->value(i));
378 
379       files->add(relative,
380                  Fl_File_Icon::find(fc->value(i), Fl_File_Icon::PLAIN));
381     }
382 
383     files->redraw();
384   }
385 }
386 
387 
388 //
389 // End of "$Id: file_chooser.cxx 8164 2011-01-01 20:17:58Z matt $".
390 //
391