source: trunk/MESOSCALE_DEV/PLOT/MINIMAL/fsc/fsc_fileselect.pro @ 937

Last change on this file since 937 was 85, checked in by aslmd, 14 years ago

LMD_MM_MARS et LMD_LES_MARS: ajout des routines IDL pour tracer les sorties --> voir mesoscale/PLOT

File size: 46.5 KB
Line 
1;+
2; NAME:
3;   FSC_FILESELECT
4;
5; PURPOSE:
6;
7;   The purpose of this compound widget is to provide a means
8;   by which the user can type or select a file name. The
9;   program is written as an "object widget", meaning that
10;   the guts of the program is an object of class FSC_FILESELECT.
11;   This is meant to be an example of the obvious advantages of
12;   writing compound widget programs as objects.
13;
14; AUTHOR:
15;
16;   FANNING SOFTWARE CONSULTING
17;   David Fanning, Ph.D.
18;   1645 Sheely Drive
19;   Fort Collins, CO 80526 USA
20;   Phone: 970-221-0438
21;   E-mail: davidf@dfanning.com
22;   Coyote's Guide to IDL Programming: http://www.dfanning.com/
23;
24; CATEGORY:
25;
26;   General programming.
27;
28; CALLING SEQUENCE:
29;
30;   filenameID = FSC_FileSelect(parent)
31;
32; INPUT PARAMETERS:
33;
34;   parent -- The parent widget ID of the compound widget. Required.
35;
36; INPUT KEYWORDS:
37;
38;   Event_Pro -- The event handler procedure for this compound widget.By default: "".
39;   Event_Func -- The event handler function for this compound widget. By default: "".
40;
41;      If neither EVENT_PRO or EVENT_FUNC is defined, program events are handled internally by the compound widget.
42;
43;   DirectoryName -- The initial name of the directory. By defaut: current directory.
44;   Filename -- The initial file name in the filename text widget.
45;   Filter -- The file filter. By default: "*".
46;   Frame -- Set this keyword for a frame around the compound widget.
47;   LabelFont -- The font for the label widget. By default: "".
48;   LabelName -- The text on the label widgt. By default: "Filename: ".
49;   LabelSize -- The X screen size of the label widget. By default: 0.
50;   MustExist -- A flag that indicates selected files must exist. By default: 0.
51;   NoMaxSize -- A flag to prohibit automatic text widget sizing. By default: 0.
52;
53;     If this keyword is not set, the compound widget will automatically resize itself to
54;     the largest widget in its parent base widget. It will do this by changing the size of
55;     the text widgets holding the file and directory names.
56;
57;   Read -- Set this keyword to have file selection for reading a file. By default: 1.
58;   SelectDirectory -- The default directory for file selection. In other words, this is the
59;     default directory for DIALOG_PICKFILE, which is accessed via the BROWSE buttons.
60;   SelectFont -- The font for the "Browse" button. By default: "".
61;   SelectTitle -- The title bar text on the file selection dialog. By default: "Select a File...".
62;   TextFont -- The font for the filename text widget. By default: "".
63;   UValue -- User value for any purpose.
64;   Write -- Set this keyword to open a file for writing. By default: 0.
65;   XSize -- The X size of the text widget holding the filename. By default: StrLen(filename) * 1.5 > 40.
66;
67; OUTPUT KEYWORDS:
68;
69;   ObjectRef -- Assign this keyword to an output variable that will hold the internal object reference.
70;                With the object reference you can call object methods to easily change many properties of
71;                the compound widget.
72;
73; COMMON BLOCKS:
74;
75;   None.
76;
77; RESTRICTIONS:
78;
79;   Requires the folling files from the Coyote Library:
80;
81;      http://www.dfanning.com/programs/error_message.pro
82;
83; EVENT STRUCTURE:
84;
85;   All events are handled internally unless either the Event_Pro or Event_Func
86;   keywords are used to assign an event handler to the compound widget. All events
87;   generated by the text widgets are passed to the assigned event handler.
88;
89;   event = { CW_FILESELECT, $     ; The name of the event structure.
90;             ID: 0L, $            ; The ID of the compound widget's top-level base.
91;             TOP: 0L, $           ; The widget ID of the top-level base of the hierarchy.
92;             HANDLER: 0L, $       ; The event handler ID. Filled out by IDL.
93;             Basename: "", $      ; The base filename without directory specifiers.
94;             Filename: "", $      ; The fully qualified filename.
95;             Directory: "", $     ; The name of the current file directory.
96;           }
97;
98; EXAMPLE:
99;
100;   An example program is provided at the end of the FSC_FILESELECT code. To run it,
101;   type these commands:
102;
103;      IDL> .Compile fsc_fileselect
104;      IDL> Example
105;
106;   Or, if you want to obtain the object reference, type this:
107;
108;      IDL> Example, theObject
109;
110;   Now you can call the object's methods. For example:
111;
112;      IDL theObject->SetProperty, XSize=150
113;
114; GETTING and SETTING VALUES:
115;
116;   So as not to disrupt the accepted paradigm in using compound widgets, you
117;   can use the return value of the FSC_FILESELECT function with WIDGET_CONTROL to
118;   get and set the "value" of the widget.
119;
120;       Widget_Control, filenameID, Set_Value='C:\RSI\IDL52\DATA\cyclone.dat'
121;
122;   The program will automatically separate the file name portion of the value
123;   from the directory portion and put things in the correct text widgets.
124;
125;   Similarly, you can get the "value" of the widget:
126;
127;       Widget_Control, filenameID, Get_Value=theValue
128;       Print, theValue
129;
130;           C:\RSI\IDL52\DATA\cyclone.dat
131;
132;   The return value is the fully qualified file path to the file.
133;
134; USING OBJECT METHODS to CHANGE PROGRAM PROPERTIES:
135;
136;   If you obtain the object reference, you have a great deal more control
137;   over the properties of the compound widget. You obtain the object reference
138;   by calling the function like this:
139;
140;      filenameID = FSC_FILESELECT(parent, ObjectRef=theObject)
141;
142; OBJECT PROCEDURE METHODS:
143;
144;   GetProperty -- This method allows various properties of the widget to be
145;       returned via output keywords. The keywords that are available are:
146;
147;      DirectoryName -- The current directory.
148;      Event_Func -- The name of the event handler function for this compound widget.
149;      Event_Pro -- The name of the event handler procedure for this compound widget.
150;      Filename -- The current base filename.
151;      Filter -- The current file filter.
152;      LabelName -- The text on the label widget.
153;      LabelSize -- The X screen size of the label widget.
154;      MustExist -- A flag that indicates selected files must exist to be selected.
155;      Parent -- The parent widget of the compound widget.
156;      Read=read -- The file selection for reading flag.
157;      SelectTitle -- The title bar text on the file selection dialog.
158;      TLB -- The top-level base of the compound widget.
159;      UValue -- The user value of the compound widget.
160;      Write -- The file selection for writing flag.
161;      XSize -- The X size of the text widget holding the filename.
162;
163;   LabelSize -- This method makes sure that the directory name and file name labels
164;      are the same size. Normally, this procedure is called internally. No parameters.
165;
166;   MatchSize -- This method resizes the compound widget so that it is as long as the
167;      the longest widget in the parent base widget. This is done automatically upon
168;      realization unless the NOMAXSIZE keyword is set. The method aids in writing
169;      resizeable widget programs.
170;
171;   SetProperty -- This method allows various properties of the widget to be
172;       set via input keywords. The keywords that are available are:
173;
174;      DirectoryName -- The current directory.
175;      Event_Func -- The name of the event handler function for this compound widget.
176;      Event_Pro -- The name of the event handler procedure for this compound widget.
177;      Filename -- The current base filename.
178;      Filter -- The current file filter.
179;      LabelName -- The text on the label widget.
180;      LabelSize -- The X screen size of the label widget.
181;      MustExist -- A flag that indicates selected files must exist to be selected.
182;      Read -- The file selection for reading flag.
183;      SelectTitle -- The title bar text on the file selection dialog.
184;      UValue -- The user value of the compound widget.
185;      Write -- The file selection for writing flag.
186;      XSize -- The X size of the text widget holding the filename.
187;
188;   TextSelect - Allows you to create a selection in filename text widget. See the
189;                documentation for the SET_TEXT_SELECT keyword to Widget_Control.
190;
191;      selection -- A two-element array containing the starting position and selection length.
192;
193; OBJECT FUNCTION METHODS:
194;
195;      GetFileName -- Returns the fully qualified filename. No parameters.
196;
197;      GetTLB -- Returns the top-level base ID of the compound widget. No Parameters.
198;
199;      Inspect_DirectoryName -- Inspects the directory name for correctness. Requires one positional parameter.
200;
201;        directoryName -- The name of the directory from the directory text widget.
202;        textSelection -- The current text selection position.
203;
204;        At the moment all this does is remove any blank characters from either
205;        end of the directory name and makes sure the last character of the directory
206;        name does not end in a subdirectory specifier (except for VMS).
207;
208;     Inspect_Filename -- Inspects the file name for correctness. Requires one positional parameter.
209;
210;        filename -- The name of the file from the filename text widget.
211;        textSelection -- The current text selection position.
212;
213;        At the moment all this does is remove any blank characters from either
214;        end of the file name
215;
216; MODIFICATION HISTORY:
217;
218;   Written by: David W. Fanning, 21 NOV 1999.
219;   Fixed bug in File Name selection button. 18 MAR 2000. DWF.
220;   Fixed an error in which directory the Browse buttons should start
221;       searching. 29 SEP 2000. DWF.
222;   Previously returned events only for typing in text widgets. Now
223;       Browse button events are also returned. 29 SEP 2000. DWF.
224;   Fixed a bug in setting the file filter. 29 SEP 2000. DWF.
225;   Removed the Directory Browse button 10 AUG 2002. DWF.
226;   Added ERROR_MESSAGE to error handling. 10 AUG 2002. DWF.
227;   Changed the ability to specify a file filter as a string array, instead
228;       of just as a scalar string. This required the use of a pointer, which
229;       meant that I had to remove the FILTER field from the CW_FILESELECT
230;       event structure to avoid likely memory leakage. This is a dangerous
231;       change because it means programs that relied on this (I expect there
232;       are very, very few) will break and it goes against my philosopy of
233;       keeping my programs backward compatible. Let me know if you have
234;       problems. In testing, I discoved no problems in my own code. 31 OCT 2002. DWF.
235;   Fixed a problem with DIALOG_PICKFILE that sometimes allowed users to change
236;       directories without selecting a file. 3 Nov 2002. DWF.
237;   Fixed a problem with widget resizing with the help of Bob Portman that had plagued
238;       me from the beginning. Thanks, Bob! 5 August 2003. DWF
239;   Added TEXTSELECT method. 5 Aug 2003. DWF.
240;   Had to add FORWARD_FUNCTION statement to get error handler compiled when using
241;       DIRECTORY keyword. 24 Nov 2003. DWF.
242;   Fixed a problem with too many events going to an event handler specified with
243;       the EVENT_PRO or EVENT_FUNC keyword from the text widget. Now only Carriage
244;       Return events are passed on to the user-specified event handler. 8 July 2004. DWF.
245;   Replace all "\" characters with "/" characters in directory names. 8 Januay 2006. DWF.
246;-
247;
248;###########################################################################
249;
250; LICENSE
251;
252; This software is OSI Certified Open Source Software.
253; OSI Certified is a certification mark of the Open Source Initiative.
254;
255; Copyright © 2000-2006 Fanning Software Consulting
256;
257; This software is provided "as-is", without any express or
258; implied warranty. In no event will the authors be held liable
259; for any damages arising from the use of this software.
260;
261; Permission is granted to anyone to use this software for any
262; purpose, including commercial applications, and to alter it and
263; redistribute it freely, subject to the following restrictions:
264;
265; 1. The origin of this software must not be misrepresented; you must
266;    not claim you wrote the original software. If you use this software
267;    in a product, an acknowledgment in the product documentation
268;    would be appreciated, but is not required.
269;
270; 2. Altered source versions must be plainly marked as such, and must
271;    not be misrepresented as being the original software.
272;
273; 3. This notice may not be removed or altered from any source distribution.
274;
275; For more information on Open Source Software, visit the Open Source
276; web site: http://www.opensource.org.
277;
278;###########################################################################
279
280
281
282PRO FSC_FileSelect::Directory_Events, event
283
284; This method handles any typing in the directory name text widget.
285
286Catch, theError
287IF theError NE 0 THEN BEGIN
288   ok = Error_Message(/Traceback)
289   RETURN
290ENDIF
291
292   ; Don't deal with selection events.
293
294IF event.type EQ 3 THEN RETURN
295
296   ; Inspect the directory name and set it.
297
298Widget_Control, self.dirtextID, Get_Value=dirname
299dirname = dirname[0]
300textSelection = Widget_Info(self.dirtextID, /Text_Select)
301dirname = self->Inspect_DirectoryName(dirname, textSelection[0])
302dirname = StrJoin( StrSplit(dirname, '\\', /Regex, /Extract, /Preserve_Null), '/')
303
304self.directoryname = dirname
305END ;-----------------------------------------------------------------------------------------------------------------------------
306
307
308
309PRO FSC_FileSelect::Filename_Events, event
310
311; This method handles any typing in the file name text widget.
312
313Catch, theError
314IF theError NE 0 THEN BEGIN
315   ok = Error_Message(/Traceback)
316   RETURN
317ENDIF
318
319   ; Don't deal with selection events.
320
321IF event.type EQ 3 THEN RETURN
322
323   ; Inspect the file name and set it.
324
325Widget_Control, self.filetextID, Get_Value=filename
326filename = filename[0]
327textSelection = Widget_Info(self.filetextID, /Text_Select)
328filename = self->Inspect_Filename(filename, textSelection[0])
329filename = StrJoin( StrSplit(filename, '\\', /Regex, /Extract, /Preserve_Null), '/')
330self.filename = filename
331END ;-----------------------------------------------------------------------------------------------------------------------------
332
333
334
335FUNCTION FSC_FileSelect::GetFilename
336
337; This method returns the fully-qualified filename. Checks to be
338; sure the last character in the directory name is not a directory
339; specifier.
340
341Catch, theError
342IF theError NE 0 THEN BEGIN
343   ok = Error_Message()
344   RETURN, -1
345ENDIF
346
347   ; Get the correct directory separator.
348
349CASE StrUpCase(!Version.OS_Family) OF
350   'MACOS'   : sep = ':'    ; Macintoshes
351   'VMS'     : sep = ']'    ; VMS machines
352   ELSE      : sep = '/'    ; Unix machines
353ENDCASE
354
355IF StrUpCase(!Version.OS_Family) NE "VMS" THEN BEGIN
356   length = StrLen(self.directoryName)
357   WHILE StrMid(self.directoryName, length-1, 1) EQ sep DO BEGIN
358      self.directoryName = StrMid(self.directoryName, 0, length-1)
359      Widget_Control, self.dirTextID, Set_Value=self.directoryName
360      length = StrLen(self.directoryName)
361   ENDWHILE
362ENDIF
363
364filename = Filepath(Root_Dir=self.directoryName, self.filename)
365filename = StrJoin( StrSplit(filename, '\\', /Regex, /Extract, /Preserve_Null), '/')
366RETURN, filename
367END ;-------------------------------------------------------------------------------
368
369
370
371FUNCTION FSC_FileSelect::GetNoMaxSize
372RETURN, self.nomaxsize
373END ;-----------------------------------------------------------------------------------------------------------------------------
374
375
376
377PRO FSC_FileSelect::GetProperty, $
378   DirectoryName=dirname, $        ; The current directory.
379   Event_Func=event_func, $        ; The name of the event handler function for this compound widget.
380   Event_Pro=event_pro, $          ; The name of the event handler procedure for this compound widget.
381   Filename=filename, $            ; The current filename.
382   Filter=filter, $                ; The current file filter.
383   LabelName=labelname, $          ; The text on the label widget.
384   LabelSize=labelsize, $          ; The X screen size of the label widget.
385   MustExist=mustexist, $          ; A flag that indicates selected files must exist to be selected.
386   Parent=parent, $                ; The parent widget of the compound widget.
387   Read=read, $                    ; The file selection for reading flag.
388   SelectTitle=selecttitle, $      ; The title bar text on the file selection dialog.
389   TLB=tlb, $                      ; The top-level base of the compound widget.
390   UValue=uvalue, $                ; The user value of the compound widget.
391   Write=write, $                  ; The file selection for writing flag.
392   XSize=xsize                     ; The X size of the text widget holding the filename.
393
394Catch, theError
395IF theError NE 0 THEN BEGIN
396   ok = Error_Message()
397   RETURN
398ENDIF
399
400dirname = self.directoryname
401event_pro = self.event_pro
402event_func = self.event_func
403filename = self.filename
404filter = *self.filter
405labelname = self.labelname
406labelsize = self.labelsize
407mustexist = self.mustexist
408parent=self.parent
409read = self.read
410selecttitle = self.selecttitle
411tlb = self.tlb
412uvalue = *self.uvalue
413wirte = self.write
414xsize = self.xsize
415
416END ;-----------------------------------------------------------------------------------------------------------------------------
417
418
419
420FUNCTION FSC_FileSelect::GetTLB
421RETURN, self.tlb
422END ;-----------------------------------------------------------------------------------------------------------------------------
423
424
425
426FUNCTION FSC_FileSelect::Inspect_DirectoryName, dirname, textSelection
427
428; This method removes leading and trailing blank characters
429; in the directory name.
430
431Catch, theError
432IF theError NE 0 THEN BEGIN
433   ok = Error_Message()
434   RETURN, -1
435ENDIF
436
437thisDir = StrTrim(dirname, 2)
438IF StrLen(thisDir) NE StrLen(dirname) THEN $
439   textSelection = textSelection-( StrLen(dirname) - StrLen(thisDir) )
440Widget_Control, Set_Value=thisDir, self.dirtextID, Set_Text_Select=[textSelection, 0]
441RETURN, thisDir
442END ;-----------------------------------------------------------------------------------------------------------------------------
443
444
445
446FUNCTION FSC_FileSelect::Inspect_Filename, filename, textSelection
447
448; This method removes leading and trailing blank characters
449; in the filename.
450
451Catch, theError
452IF theError NE 0 THEN BEGIN
453   Catch, /Cancel
454   ok = Error_Message()
455   RETURN, -1
456ENDIF
457
458thisFile = StrTrim(filename, 2)
459IF StrLen(thisFile) NE StrLen(filename) THEN $
460   textSelection = textSelection-( StrLen(filename) - StrLen(thisFile) )
461Widget_Control, Set_Value=thisFile, self.filetextID, Set_Text_Select=[textSelection, 0]
462RETURN, thisFile
463END ;-----------------------------------------------------------------------------------------------------------------------------
464
465
466
467PRO FSC_FileSelect::LabelSize
468
469; This method ensures the directory and filename labels are the same size.
470
471Catch, theError
472IF theError NE 0 THEN BEGIN
473   ok = Error_Message()
474   RETURN
475ENDIF
476
477fgeo = Widget_Info(self.filelabelID, /Geometry)
478dgeo = Widget_Info(self.dirlabelID, /Geometry)
479bestSize = fgeo.scr_xsize > dgeo.scr_xsize
480Widget_Control, self.fileLabelID, Scr_XSize=bestSize
481Widget_Control, self.dirLabelID, Scr_XSize=bestSize
482END ;-------------------------------------------------------------------------------
483
484
485
486PRO FSC_FileSelect::MatchSize
487
488; This method makes the compound widget the same size as the largest
489; widget in the parent base widget. It does this by adjusting
490; the text widget sizes.
491
492Catch, theError
493IF theError NE 0 THEN BEGIN
494   ok = Error_Message()
495   RETURN
496ENDIF
497
498   ; Get the geometries of the filename widgets.
499
500tgeo = Widget_Info(self.tlb, /Geometry)
501fgeo = Widget_Info(self.filetextID, /Geometry)
502bbgeo = Widget_Info(self.filebaseID, /Geometry)
503lbgeo = Widget_Info(Widget_Info(self.dirbaseID, /Parent), /Geometry)
504rbgeo = Widget_Info(Widget_Info(self.filebrowseID, /Parent), /Geometry)
505
506   ; Add the bits and bobs together.
507
508fspacing = tgeo.space
509fpadding = 2*tgeo.xpad + 2*lbgeo.xpad
510ffixedsize = ( bbgeo.scr_xsize - 2*bbgeo.margin - (fgeo.scr_xsize) + $
511               rbgeo.scr_xsize - 2*rbgeo.margin )
512
513   ; Get the geometries of the directory name widgets.
514
515fgeo = Widget_Info(self.dirtextID, /Geometry)
516bbgeo = Widget_Info(self.dirbaseID, /Geometry)
517
518   ; Add the bits and bobs together.
519
520dspacing = tgeo.space
521dpadding = 2*tgeo.xpad + 2*lbgeo.xpad
522dfixedsize = ( bbgeo.scr_xsize - 2*bbgeo.margin - (fgeo.scr_xsize) + $
523               rbgeo.scr_xsize - 2*rbgeo.margin )
524
525   ; Go find all the children and find the biggest one of them.
526
527thisSize = 0
528childID = Widget_Info(self.parent, /Child)
529geom = Widget_Info(childID, /Geometry)
530testSize = geom.scr_xsize - 2*geom.margin
531thisSize = thisSize > testSize
532WHILE childID NE 0 DO BEGIN
533   childID = Widget_Info(childID, /Sibling)
534   IF childID GT 0 THEN BEGIN
535      geom = Widget_Info(childID, /Geometry)
536      testSize = geom.scr_xsize - 2*geom.margin
537      thisSize = thisSize > testSize
538   ENDIF
539ENDWHILE
540
541   ; Resize the widgets
542
543ftextsize = thisSize - (fspacing + fpadding + ffixedsize)
544Widget_Control, self.filetextID, Scr_XSize=ftextsize
545
546dtextsize = thisSize - (dspacing + dpadding + dfixedsize)
547Widget_Control, self.dirtextID, Scr_XSize=dtextsize
548
549END ;-------------------------------------------------------------------------------
550
551
552
553FUNCTION FSC_FileSelect_RStrPos, Expr, SubStr, Pos
554
555  ON_ERROR, 2
556  N = N_PARAMS()
557  if (n lt 2) then message, 'Incorrect number of arguments.'
558
559  ; Is expr an array or a scalar? In either case, make a result
560  ; that matches.
561  if (size(expr, /n_dimensions) eq 0) then result = 0 $
562  else result = make_array(dimension=size(expr,/dimensions), /INT)
563
564  RSubStr = STRING(REVERSE(BYTE(SubStr))) ; Reverse the substring
565
566  for i = 0, n_elements(expr) - 1 do begin
567    Len = STRLEN(Expr[i])
568    IF (N_ELEMENTS(Pos) EQ 0) THEN Start=0 ELSE Start = Len - Pos
569
570    RString = STRING(REVERSE(BYTE(Expr[i]))) ; Reverse the string
571
572    SubPos = STRPOS(RString, RSubStr, Start)
573    IF SubPos NE -1 THEN SubPos = Len - SubPos - STRLEN(SubStr)
574    result[i] = SubPos
575  endfor
576
577  RETURN, result
578END ;-------------------------------------------------------------------------
579
580
581
582PRO FSC_FileSelect::Select_File, event
583
584Catch, theError
585IF theError NE 0 THEN BEGIN
586   ok = Error_Message()
587   RETURN
588ENDIF
589
590; Use the file selection dialog to obtain a filename.
591
592currentFilename = self.filename
593self.filename = ""
594filename = Dialog_Pickfile( File=self.filename, $
595                            Filter=*self.filter, $
596                            Path=self.directoryname, $
597                            Get_Path=thePath, $
598                            Must_Exist=self.mustexist, $
599                            Read=self.read, $
600                            Title=self.selecttitle, $
601                            Write=self.write )
602
603IF filename EQ "" THEN BEGIN
604   self.filename = currentFilename
605   RETURN
606ENDIF
607
608   ; Remove the directory from the name.
609
610index = StrLen(thePath)
611theFilename = StrMid(filename, index)
612
613   ; Strip the last directory separator.
614
615length = StrLen(thePath)
616thePath = StrMid(thePath, 0, length-1)
617
618   ; Inspect the file name to make sure it is valid.
619
620textSelection = Widget_Info(self.filetextID, /Text_Select)
621filename = self->Inspect_Filename(filename, textSelection[0])
622
623   ; Update the display.
624
625self->SetProperty, Filename=theFilename, DirectoryName=thePath
626
627END ;-----------------------------------------------------------------------------------------------------------------------------
628
629
630
631PRO FSC_FileSelect::SetFilename, theName
632
633; This method separates the filename into directory and filename
634; and adds them to the interface.
635
636Catch, theError
637IF theError NE 0 THEN BEGIN
638   ok = Error_Message()
639   RETURN
640ENDIF
641
642; Change back slashes to forward slashes.
643theName = StrJoin( StrSplit(theName, '\\', /Regex, /Extract, /Preserve_Null), '/')
644
645   ; Get the correct directory separator.
646
647CASE StrUpCase(!Version.OS_Family) OF
648   'MACOS'   : sep = ':'    ; Macintoshes
649   'VMS'     : sep = ']'    ; VMS machines
650   ELSE      : sep = '/'    ; Unix machines
651ENDCASE
652
653index = FSC_FileSelect_RStrPos(theName, sep)
654IF index EQ -1 THEN BEGIN
655   self->SetProperty, Filename=theName
656   self.filename = theName
657ENDIF ELSE BEGIN
658   directoryName = StrMid(theName, 0, index)
659   filename = StrMid(theName, index+1)
660   self->SetProperty, Filename=filename, Directory=directoryName
661   self.filename = filename
662   self.directoryName = directoryName
663ENDELSE
664END ;-------------------------------------------------------------------------------
665
666
667
668PRO FSC_FileSelect::SetProperty, $
669   DirectoryName=dirname, $        ; The initial name of the directory. By defaut: current directory.
670   Event_Func=event_func, $        ; The event handler function for this compound widget.
671   Event_Pro=event_pro, $          ; The event handler procedure for this compound widget.
672   Filename=filename, $            ; The initial file name in the filename text widget.
673   Filter=filter, $                ; The file filter.
674   LabelName=labelname, $          ; The text on the label widgt.
675   LabelSize=labelsize, $          ; The X screen size of the label widget.
676   MustExist=mustexist, $          ; A flag that indicates selected files must exist.
677   Read=read, $                    ; Set this keyword to have file selection for reading a file.
678   SelectTitle=selecttitle, $      ; The title bar text on the file selection dialog.
679   UValue=uvalue, $                ; User value for any purpose.
680   Write=write, $                  ; Set this keyword to open a file for writing.
681   XSize=xsize                     ; The X size of the text widget holding the filename.
682
683Catch, theError
684IF theError NE 0 THEN BEGIN
685   ok = Error_Message()
686   RETURN
687ENDIF
688
689IF N_Elements(dirname) NE 0 THEN BEGIN
690   dirname = StrJoin( StrSplit(dirname, '\\', /Regex, /Extract, /Preserve_Null), '/')
691   self.directoryname = dirname
692   Widget_Control, self.dirtextID, Set_Value=dirname
693ENDIF
694
695IF N_Elements(event_pro) NE 0 THEN BEGIN
696   self.event_pro = event_pro
697   Widget_Control, self.tlb, Event_Pro=event_pro
698ENDIF
699
700IF N_Elements(event_func) NE 0 THEN BEGIN
701   self.event_func = event_func
702   Widget_Control, self.tlb, Event_Func=event_func
703ENDIF
704
705IF N_Elements(filename) NE 0 THEN BEGIN
706   self.filename = filename
707   strlength = StrLen(filename)
708   Widget_Control, self.filetextID, Set_Value=filename
709ENDIF
710
711IF N_Elements(labelname) NE 0 THEN BEGIN
712   self.labelname = labelname
713   Widget_Control, self.filelabelID, Set_Value=labelname
714ENDIF
715
716IF N_Elements(labelsize) NE 0 THEN BEGIN
717   Widget_Control, self.filelabelID, Scr_XSize=labelsize
718ENDIF
719
720IF N_Elements(filter) NE 0 THEN *self.filter = filter
721IF N_Elements(mustexist) NE 0 THEN self.mustexist = mustexist
722IF N_Elements(read) NE 0 THEN self.read = read
723IF N_Elements(selecttitle) NE 0 THEN self.selecttitle = selecttitle
724IF N_Elements(uvalue) NE 0 THEN *self.uvalue = uvalue
725IF N_Elements(write) NE 0 THEN self.write = write
726
727IF N_Elements(xsize) NE 0 THEN BEGIN
728   Widget_Control, self.filetextID, XSize=xsize
729   Widget_Control, self.dirtextID, XSize=xsize
730ENDIF
731
732END ;-----------------------------------------------------------------------------------------------------------------------------
733
734
735
736PRO FSC_FileSelect::TextSelect, selection
737
738Catch, theError
739IF theError NE 0 THEN BEGIN
740   ok = Error_Message()
741   RETURN
742ENDIF
743
744IF N_Elements(selection) NE 2 THEN Message, 'Text selection array is not a two-element array: [beginSelection, selectionLength]'
745Widget_Control, self.fileTextID, Set_Text_Select=selection
746
747END ;-----------------------------------------------------------------------------------------------------------------------------
748
749
750
751PRO FSC_FileSelect::CLEANUP
752Ptr_Free, self.uvalue
753Ptr_Free, self.filter
754END ;-----------------------------------------------------------------------------------------------------------------------------
755
756
757
758FUNCTION FSC_FileSelect::INIT, $
759   parent, $                       ; The parent widget ID of the compound widget.
760   DirectoryName=dirname, $        ; The initial name of the directory. By defaut: current directory.
761   Event_Pro=event_pro, $          ; The event handler procedure for this compound widget.By default: "".
762   Event_Func=event_func, $        ; The event handler function for this compound widget. By default: "".
763   Filename=filename, $            ; The initial file name in the filename text widget.
764   Filter=filter, $                ; The file filter. By default: "*".
765   Frame=frame, $                  ; Set this keyword for a frame around the compound widget.
766   LabelFont=labelfont, $          ; The font for the label widget. By default: "".
767   LabelName=labelname, $          ; The text on the label widgt. By default: "Filename: ".
768   LabelSize=labelsize, $          ; The X screen size of the label widget. By default: 0.
769   MustExist=mustexist, $          ; A flag that indicates selected files must exist. By default: 0.
770   NoMaxSize=nomaxsize, $          ; A flag to prohibit automatica text widget sizing. By default: 0.
771   Read=read, $                    ; Set this keyword to have file selection for reading a file. By default: 1.
772   Scr_XSize=scr_xsize, $          ; The X screen size of the compound widget. By default: 0
773   SelectFont=selectfont, $        ; The font for the "Browse" button. By default: "".
774   Selectdir=selectdir, $          ; The inital directory for file and directory selections.
775   SelectTitle=selecttitle, $      ; The title bar text on the file selection dialog. By default: "Select a File...".
776   TextFont=textfont, $            ; The font for the filename text widget. By default: "".
777   UValue=uvalue, $                ; User value for any purpose.
778   Write=write, $                  ; Set this keyword to open a file for writing. By default: 0.
779   XSize=xsize                     ; The X size of the text widget holding the filename. By default: StrLen(filename) * 1.5 > 40.
780
781Catch, theError
782;theError = 0
783IF theError NE 0 THEN BEGIN
784   Catch, /Cancel
785   ok = Error_Message()
786   RETURN, 0
787ENDIF
788
789   ; Populate self object.
790
791self.parent = parent
792self.directoryname = dirname
793self.event_pro = event_pro
794self.event_func = event_func
795self.filename = filename
796self.filter = Ptr_New(filter)
797self.frame = frame
798self.labelfont = labelfont
799self.labelname = labelname
800self.labelsize = labelsize
801self.mustexist = mustexist
802self.nomaxsize = nomaxsize
803self.read = read
804self.selectdir = selectdir
805self.selectfont = selectfont
806self.selecttitle = selecttitle
807self.textfont = textfont
808self.uvalue = Ptr_New(uvalue)
809self.write = write
810self.xsize = xsize
811
812
813   ; Build widgets.
814
815self.tlb = Widget_Base( self.parent, $
816                        Event_Func = self.event_func, $
817                        Event_Pro = self.event_pro, $
818                        Frame = self.frame, $
819                        Func_Get_Value='FSC_FileSelect_Get_Value', $
820                        Pro_Set_Value='FSC_FileSelect_Set_Value', $
821                        Row = 1, $
822                        Base_Align_Center=1, $
823                        UValue=*self.uvalue )
824
825   ; Put the self object in the first child of the TLB.
826
827leftbase = Widget_Base(self.tlb, Row=2, UValue=self)
828
829self.dirbaseID = Widget_Base(leftbase, Row=1)
830
831self.dirlabelID = Widget_Label( self.dirbaseID, $
832                             Font=self.labelfont, $
833                             Scr_XSize=self.labelsize, $
834                             Value='Directory: ' )
835
836
837self.dirtextID = Widget_Text( self.dirbaseID, $
838                           All_Events=1, $
839                           Editable=1, $
840                           Event_Func='FSC_FileSelect_Event_Handler', $
841                           Font=self.textfont, $
842                           UValue={method:'Directory_Events', object:self}, $
843                           Value=self.directoryname, $
844                           XSize=self.xsize, $
845                           YSize=1 )
846
847
848self.filebaseID = Widget_Base(leftbase, Row=1)
849
850self.filelabelID = Widget_Label( self.filebaseID, $
851                             Font=self.labelfont, $
852                             Kill_Notify='FSC_FileSelect_Kill_Notify', $
853                             Notify_Realize='FSC_FileSelect_Notify_Realize', $
854                             Scr_XSize=self.labelsize, $
855                             UValue=self, $
856                             Value=self.labelname )
857
858
859self.filetextID = Widget_Text( self.filebaseID, $
860                           All_Events=1, $
861                           Editable=1, $
862                           Event_Func='FSC_FileSelect_Event_Handler', $
863                           Font=self.textfont, $
864                           UValue={method:'Filename_Events', object:self}, $
865                           Value=self.filename, $
866                           XSize=self.xsize, $
867                           YSize=1 )
868
869rightbase = Widget_Base(self.tlb, Row=1, Base_Align_Center=1)
870self.filebrowseID = Widget_Button( rightbase, $
871                               Event_Func='FSC_FileSelect_Event_Handler', $
872                               UValue={method:'Select_File', object:self}, $
873                               Value='Browse')
874
875
876RETURN, 1
877END ;-----------------------------------------------------------------------------------------------------------------------------
878
879
880
881PRO FSC_FileSelect__Define
882
883   objectClass = { FSC_FileSelect, $      ; The object class FSC_FILESELECT.
884                   parent: 0L, $          ; The ID of the parent widget.
885                   tlb: 0L, $             ; The ID of the top-level base widget for the compound widget.
886                   filebaseID: 0L, $      ; The ID of the filename base widget.
887                   dirbaseID: 0L, $       ; The ID of the directory base widget.
888                   filelabelID: 0L, $     ; The ID of the filename label widget.
889                   dirlabelID: 0L, $      ; The ID of the directory label widget.
890                   filetextID: 0L, $      ; The ID of the filename text widget.
891                   dirtextID: 0L, $       ; The ID of the directory text widget.
892                   filebrowseID: 0L, $    ; The ID of the file browse button widget.
893                   dirbrowseID: 0L, $     ; Unused currently. Left here for compatibility reasons..
894                   event_pro: "", $       ; The user-defined name of the event procedure for the widget.
895                   event_func: "", $      ; The user-defined name of the event function for the widget.
896                   filename: "", $        ; The current contents of the filename text widget.
897                   directoryname: "", $   ; The current contents of the directory text widget.
898                   frame: 0L, $           ; A flag to indicate a frame around the compound widget.
899                   filter: Ptr_New(), $   ; The current file filter used in file selection.
900                   labelfont: "", $       ; The font for the label widgets.
901                   labelname: "", $       ; The VALUE of the file name label widget.
902                   labelsize: 0L, $       ; The X screen size fo the label widgets.
903                   mustexist: 0L, $       ; If this field is 1, the user can only select files that exist.
904                   nomaxsize: 0L, $       ; This widget sizes itself to the largest widget in the base, unless this is set.
905                   read: 0L, $            ; Set this keyword to select a file for reading.
906                   selectdir: "", $       ; The inital directory used for file selection.
907                   selectfont: "", $      ; The font used for the Browse buttons.
908                   selecttitle: "", $     ; The text on the Dialog_Pickfile widget.
909                   textfont: "", $        ; The font used in the text widgets.
910                   uvalue: Ptr_New(), $   ; The user's user value. Unused by the program.
911                   write: 0L, $           ; Set this keyword to select a file for writing.
912                   xsize: 0L $            ; The X size of the text widgets.
913                 }
914
915END ;-----------------------------------------------------------------------------------------------------------------------------
916
917
918
919PRO FSC_FileSelect_Set_Value, id, filename
920
921; This function sets the filename of the widget, using the
922; traditional "Widget_Control, fieldID, Set_Value=filename" syntax.
923; The directory will be stripped off the filename, if required.
924
925firstChild = Widget_Info(id, /Child)
926Widget_Control, firstChild, Get_UValue=self
927self->SetFilename,filename
928END ;-----------------------------------------------------------------------------------------------------------------------------
929
930
931
932FUNCTION FSC_FileSelect_Get_Value, id
933
934; This function returns the filename of the widget, using the
935; traditional "Widget_Control, fieldID, Get_Value=filename" syntax.
936
937firstChild = Widget_Info(id, /Child)
938Widget_Control, firstChild, Get_UValue=self
939RETURN, self->GetFilename()
940END ;-----------------------------------------------------------------------------------------------------------------------------
941
942
943
944PRO CW_FileSelect__Define
945
946; The event structure definition. This is the event structure returned by the compound widget.
947
948   eventStructure = { CW_FileSelect, $     ; The name of the event structure.
949                      ID: 0L,  $           ; The ID of the top-level base of the compound widget.
950                      TOP: 0L, $           ; The ID of the top-level base.
951                      HANDLER: 0L, $       ; The ID of the event handler widget.
952                      Filename: "", $      ; The fully qualified file name.
953                      Basename: "", $      ; The base file name without directory attached.
954                      Directory: "" }      ; The file directory.
955END ;-----------------------------------------------------------------------------------------------------------------------------
956
957
958
959FUNCTION FSC_FileSelect_Event_Handler, event
960
961; The main event handler for the compound widget. It reacts
962; to "messages" in the UValues of widgets that generate events.
963; The messages indicate which object method to call. A message
964; consists of an object method and the self object reference.
965
966Widget_Control, event.ID, Get_UValue=theMessage
967
968Call_Method, theMessage.method, theMessage.object, event
969
970   ; Events will be sent only if there is an assigned event handler.
971
972self = theMessage.object
973self->GetProperty, Filename=filename, DirectoryName=directory, $
974   Event_Pro=event_pro, Event_Func=event_func
975IF event_pro NE "" OR event_func NE "" THEN BEGIN
976
977    pseudoevent = {CW_FileSelect, self->GetTLB(), event.top, 0L, $
978      Filepath(Root_Dir=directory, filename),  filename, directory}
979
980    ; Don't return events from text widgets, unless the user has typed
981    ; a cariage return.
982    eventName = Tag_Names(event, /Structure_Name)
983    IF eventName NE "" THEN BEGIN
984
985       IF StrMid(eventName, 0, 11) EQ 'WIDGET_TEXT' THEN BEGIN
986          IF (eventName EQ 'WIDGET_TEXT_CH') THEN BEGIN
987            IF (event.ch EQ 10) THEN RETURN, pseudoevent ELSE RETURN, 0
988          ENDIF ELSE RETURN, 0
989       ENDIF
990    ENDIF
991    RETURN, pseudoevent
992ENDIF ELSE RETURN, 0
993END ;-----------------------------------------------------------------------------------------------------------------------------
994
995
996PRO FSC_FileSelect_Notify_Realize, labelID
997
998; When the compound widget is realized, make sure sizes are correct.
999
1000Widget_Control, labelID, Get_UValue=self
1001IF self->GetNoMaxSize() THEN RETURN
1002self->Matchsize
1003END ;-----------------------------------------------------------------------------------------------------------------------------
1004
1005
1006
1007PRO FSC_FileSelect_Kill_Notify, labelID
1008
1009; When the compound widget dies, destroy the self object.
1010
1011Widget_Control, labelID, Get_UValue=self
1012Obj_Destroy, self
1013END ;-----------------------------------------------------------------------------------------------------------------------------
1014
1015
1016
1017FUNCTION FSC_FileSelect, $
1018   parent, $                       ; The parent widget ID of the compound widget.
1019   Event_Pro=event_pro, $          ; The event handler procedure for this compound widget.By default: "".
1020   Event_Func=event_func, $        ; The event handler function for this compound widget. By default: "".
1021   DirectoryName=dirname, $        ; The initial name of the directory. By defaut: current directory.
1022   Filename=filename, $            ; The initial file name in the filename text widget.
1023   Filter=filter, $                ; The file filter. By default: "*".
1024   Frame=frame, $                  ; Set this keyword for a frame around the compound widget.
1025   LabelFont=labelfont, $          ; The font for the label widget. By default: "".
1026   LabelName=labelname, $          ; The text on the label widgt. By default: "Filename: ".
1027   LabelSize=labelsize, $          ; The X screen size of the label widget. By default: 0.
1028   MustExist=mustexist, $          ; A flag that indicates selected files must exist. By default: 0.
1029   NoMaxSize=nomaxsize, $          ; A flag to prohibit automatica text widget sizing. By default: 0.
1030   ObjectRef=objectref, $          ; An output keyword containing the object reference.
1031   Read=read, $                    ; Set this keyword to have file selection for reading a file. By default: 1.
1032   SelectDirectory=selectdir, $    ; The default directory for file selection.
1033   SelectFont=selectfont, $        ; The font for the "Browse" button. By default: "".
1034   SelectTitle=selecttitle, $      ; The title bar text on the file selection dialog. By default: "Select a File...".
1035   TextFont=textfont, $            ; The font for the filename text widget. By default: "".
1036   UValue=uvalue, $                ; User value for any purpose.
1037   Write=write, $                  ; Set this keyword to open a file for writing. By default: 0.
1038   XSize=xsize                     ; The X size of the text widget holding the filename. By default: StrLen(filename) * 1.5 > 40.
1039
1040Catch, theError
1041;theError = 0
1042IF theError NE 0 THEN BEGIN
1043   ok = Error_Message()
1044   RETURN, 0
1045ENDIF
1046
1047   ; Need a parent parameter.
1048
1049IF N_Elements(parent) EQ 0 THEN BEGIN
1050   ok = Dialog_Message('FSC_FILESELECT: A parent parameter is required.')
1051   RETURN, -1
1052ENDIF
1053
1054   ; Check keyword arguments.
1055
1056IF N_Elements(dirname) EQ 0 THEN CD, Current=dirname
1057dirname = StrJoin( StrSplit(dirname, '\\', /Regex, /Extract, /Preserve_Null), '/')
1058IF N_Elements(event_pro) EQ 0 THEN event_pro = ""
1059IF N_Elements(event_func) EQ 0 THEN event_func = ""
1060IF N_Elements(filename) EQ 0 THEN filename = ""
1061IF N_Elements(filter) EQ 0 THEN filter = '*'
1062IF N_Elements(Frame) EQ 0 THEN Frame = 0
1063IF N_Elements(labelfont) EQ 0 THEN labelfont = ""
1064IF N_Elements(labelname) EQ 0 THEN labelname = "Filename: "
1065IF N_Elements(labelsize) EQ 0 THEN labelsize = 0
1066IF N_Elements(mustexist) EQ 0 THEN mustexist = 0
1067IF N_Elements(nomaxsize) EQ 0 THEN nomaxsize = 0
1068IF N_Elements(read) EQ 0 THEN read = 0
1069IF N_Elements(selectdir) EQ 0 THEN selectdir = dirname
1070IF N_Elements(selectfont) EQ 0 THEN selectfont = ""
1071IF Keyword_Set(read) EQ 0 AND Keyword_Set(write) EQ 0 AND $
1072   N_Elements(selecttitle) EQ 0 THEN selecttitle = "Select a File..." ELSE selecttitle = ""
1073IF N_Elements(textfont) EQ 0 THEN textfont = ""
1074IF N_Elements(uvalue) EQ 0 THEN uvalue = ""
1075IF N_Elements(write) EQ 0 THEN write = 0
1076IF N_Elements(xsize) EQ 0 THEN xsize = Long(StrLen(dirname) * 1.20 > 40)
1077
1078   ; Create the underlying structure.
1079
1080objectref = Obj_New('FSC_FileSelect', $
1081   parent, $
1082   DirectoryName=dirname, $
1083   Event_Pro=event_pro, $
1084   Event_Func=event_func, $
1085   Filename=filename, $
1086   Filter=filter, $
1087   Frame=frame, $
1088   LabelFont=labelfont, $
1089   LabelName=labelname, $
1090   LabelSize=labelsize, $
1091   MustExist=mustexist, $
1092   NoMaxSize=nomaxsize, $
1093   Read=read, $
1094   Scr_XSize=scr_xsize, $
1095   SelectFont=selectfont, $
1096   SelectTitle=selecttitle, $
1097   Selectdir=selectdir, $
1098   TextFont=textfont, $
1099   UValue=uvalue, $
1100   Write=write, $
1101   XSize=xsize )
1102
1103   ; Return the ID of the top-level base of the compound widget.
1104
1105  RETURN, objectref->GetTLB()
1106END ;-----------------------------------------------------------------------------------------------------------------------------
1107
1108
1109
1110PRO Example_Set_Size, event
1111Widget_Control, event.top, Get_UValue=theObject
1112theObject->MatchSize
1113END ;-----------------------------------------------------------------------------------------------------------------------------
1114
1115
1116
1117PRO Example_Set_Filter, event
1118Widget_Control, event.top, Get_UValue=theObject
1119theObject->SetProperty, Filter='*.pro', Filename='cyclone.pro'
1120END ;-----------------------------------------------------------------------------------------------------------------------------
1121
1122
1123
1124PRO Example_Set_Filename, event
1125Widget_Control, event.top, Get_UValue=theObject
1126filename = Filepath(Subdir=['examples', 'data'], 'worldelv.dat')
1127theObject->SetFilename, filename
1128END ;-----------------------------------------------------------------------------------------------------------------------------
1129
1130
1131
1132PRO Example_Shrink, event
1133Widget_Control, event.top, Get_UValue=theObject
1134theObject->SetProperty, XSize=40
1135END ;-----------------------------------------------------------------------------------------------------------------------------
1136
1137
1138
1139PRO Example_Print_Filename, event
1140Widget_Control, event.top, Get_UValue=theObject
1141Print, theObject->GetFilename()
1142END ;-----------------------------------------------------------------------------------------------------------------------------
1143
1144
1145
1146PRO Example_Quit, event
1147Widget_Control, event.top, /Destroy
1148END ;-----------------------------------------------------------------------------------------------------------------------------
1149
1150
1151
1152PRO Example, theObject
1153
1154tlb = Widget_Base(Title='Exercise FSC_FILESELECT...', Column=1)
1155button = Widget_Button(tlb, Value='Make Compound Widget As Big As Me', $
1156   Event_Pro='Example_Set_Size', Scr_XSize=500)
1157button = Widget_Button(tlb, Value='Set Filename to worldelv.data in Data Directory', $
1158   Event_Pro='Example_Set_Filename')
1159button = Widget_Button(tlb, Value='Print Filename', $
1160   Event_Pro='Example_Print_Filename')
1161button = Widget_Button(tlb, Value="Shrink the Text Fields", $
1162   Event_Pro='Example_Shrink')
1163CD, Current=thisDir
1164filenameID = FSC_FileSelect(tlb, Directory=thisDir, Filename='fileselect.pro', $
1165   /NoMaxSize, ObjectRef=theObject)
1166button = Widget_Button(tlb, Value='Quit', Event_Pro='Example_Quit')
1167Widget_Control, tlb, /Realize, Set_UValue=theObject
1168XManager, 'example', tlb, /No_Block
1169END ;-----------------------------------------------------------------------------------------------------------------------------
1170
Note: See TracBrowser for help on using the repository browser.