| 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 | |
|---|
| 282 | PRO FSC_FileSelect::Directory_Events, event |
|---|
| 283 | |
|---|
| 284 | ; This method handles any typing in the directory name text widget. |
|---|
| 285 | |
|---|
| 286 | Catch, theError |
|---|
| 287 | IF theError NE 0 THEN BEGIN |
|---|
| 288 | ok = Error_Message(/Traceback) |
|---|
| 289 | RETURN |
|---|
| 290 | ENDIF |
|---|
| 291 | |
|---|
| 292 | ; Don't deal with selection events. |
|---|
| 293 | |
|---|
| 294 | IF event.type EQ 3 THEN RETURN |
|---|
| 295 | |
|---|
| 296 | ; Inspect the directory name and set it. |
|---|
| 297 | |
|---|
| 298 | Widget_Control, self.dirtextID, Get_Value=dirname |
|---|
| 299 | dirname = dirname[0] |
|---|
| 300 | textSelection = Widget_Info(self.dirtextID, /Text_Select) |
|---|
| 301 | dirname = self->Inspect_DirectoryName(dirname, textSelection[0]) |
|---|
| 302 | dirname = StrJoin( StrSplit(dirname, '\\', /Regex, /Extract, /Preserve_Null), '/') |
|---|
| 303 | |
|---|
| 304 | self.directoryname = dirname |
|---|
| 305 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 306 | |
|---|
| 307 | |
|---|
| 308 | |
|---|
| 309 | PRO FSC_FileSelect::Filename_Events, event |
|---|
| 310 | |
|---|
| 311 | ; This method handles any typing in the file name text widget. |
|---|
| 312 | |
|---|
| 313 | Catch, theError |
|---|
| 314 | IF theError NE 0 THEN BEGIN |
|---|
| 315 | ok = Error_Message(/Traceback) |
|---|
| 316 | RETURN |
|---|
| 317 | ENDIF |
|---|
| 318 | |
|---|
| 319 | ; Don't deal with selection events. |
|---|
| 320 | |
|---|
| 321 | IF event.type EQ 3 THEN RETURN |
|---|
| 322 | |
|---|
| 323 | ; Inspect the file name and set it. |
|---|
| 324 | |
|---|
| 325 | Widget_Control, self.filetextID, Get_Value=filename |
|---|
| 326 | filename = filename[0] |
|---|
| 327 | textSelection = Widget_Info(self.filetextID, /Text_Select) |
|---|
| 328 | filename = self->Inspect_Filename(filename, textSelection[0]) |
|---|
| 329 | filename = StrJoin( StrSplit(filename, '\\', /Regex, /Extract, /Preserve_Null), '/') |
|---|
| 330 | self.filename = filename |
|---|
| 331 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 332 | |
|---|
| 333 | |
|---|
| 334 | |
|---|
| 335 | FUNCTION 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 | |
|---|
| 341 | Catch, theError |
|---|
| 342 | IF theError NE 0 THEN BEGIN |
|---|
| 343 | ok = Error_Message() |
|---|
| 344 | RETURN, -1 |
|---|
| 345 | ENDIF |
|---|
| 346 | |
|---|
| 347 | ; Get the correct directory separator. |
|---|
| 348 | |
|---|
| 349 | CASE StrUpCase(!Version.OS_Family) OF |
|---|
| 350 | 'MACOS' : sep = ':' ; Macintoshes |
|---|
| 351 | 'VMS' : sep = ']' ; VMS machines |
|---|
| 352 | ELSE : sep = '/' ; Unix machines |
|---|
| 353 | ENDCASE |
|---|
| 354 | |
|---|
| 355 | IF 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 |
|---|
| 362 | ENDIF |
|---|
| 363 | |
|---|
| 364 | filename = Filepath(Root_Dir=self.directoryName, self.filename) |
|---|
| 365 | filename = StrJoin( StrSplit(filename, '\\', /Regex, /Extract, /Preserve_Null), '/') |
|---|
| 366 | RETURN, filename |
|---|
| 367 | END ;------------------------------------------------------------------------------- |
|---|
| 368 | |
|---|
| 369 | |
|---|
| 370 | |
|---|
| 371 | FUNCTION FSC_FileSelect::GetNoMaxSize |
|---|
| 372 | RETURN, self.nomaxsize |
|---|
| 373 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 374 | |
|---|
| 375 | |
|---|
| 376 | |
|---|
| 377 | PRO 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 | |
|---|
| 394 | Catch, theError |
|---|
| 395 | IF theError NE 0 THEN BEGIN |
|---|
| 396 | ok = Error_Message() |
|---|
| 397 | RETURN |
|---|
| 398 | ENDIF |
|---|
| 399 | |
|---|
| 400 | dirname = self.directoryname |
|---|
| 401 | event_pro = self.event_pro |
|---|
| 402 | event_func = self.event_func |
|---|
| 403 | filename = self.filename |
|---|
| 404 | filter = *self.filter |
|---|
| 405 | labelname = self.labelname |
|---|
| 406 | labelsize = self.labelsize |
|---|
| 407 | mustexist = self.mustexist |
|---|
| 408 | parent=self.parent |
|---|
| 409 | read = self.read |
|---|
| 410 | selecttitle = self.selecttitle |
|---|
| 411 | tlb = self.tlb |
|---|
| 412 | uvalue = *self.uvalue |
|---|
| 413 | wirte = self.write |
|---|
| 414 | xsize = self.xsize |
|---|
| 415 | |
|---|
| 416 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 417 | |
|---|
| 418 | |
|---|
| 419 | |
|---|
| 420 | FUNCTION FSC_FileSelect::GetTLB |
|---|
| 421 | RETURN, self.tlb |
|---|
| 422 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 423 | |
|---|
| 424 | |
|---|
| 425 | |
|---|
| 426 | FUNCTION FSC_FileSelect::Inspect_DirectoryName, dirname, textSelection |
|---|
| 427 | |
|---|
| 428 | ; This method removes leading and trailing blank characters |
|---|
| 429 | ; in the directory name. |
|---|
| 430 | |
|---|
| 431 | Catch, theError |
|---|
| 432 | IF theError NE 0 THEN BEGIN |
|---|
| 433 | ok = Error_Message() |
|---|
| 434 | RETURN, -1 |
|---|
| 435 | ENDIF |
|---|
| 436 | |
|---|
| 437 | thisDir = StrTrim(dirname, 2) |
|---|
| 438 | IF StrLen(thisDir) NE StrLen(dirname) THEN $ |
|---|
| 439 | textSelection = textSelection-( StrLen(dirname) - StrLen(thisDir) ) |
|---|
| 440 | Widget_Control, Set_Value=thisDir, self.dirtextID, Set_Text_Select=[textSelection, 0] |
|---|
| 441 | RETURN, thisDir |
|---|
| 442 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 443 | |
|---|
| 444 | |
|---|
| 445 | |
|---|
| 446 | FUNCTION FSC_FileSelect::Inspect_Filename, filename, textSelection |
|---|
| 447 | |
|---|
| 448 | ; This method removes leading and trailing blank characters |
|---|
| 449 | ; in the filename. |
|---|
| 450 | |
|---|
| 451 | Catch, theError |
|---|
| 452 | IF theError NE 0 THEN BEGIN |
|---|
| 453 | Catch, /Cancel |
|---|
| 454 | ok = Error_Message() |
|---|
| 455 | RETURN, -1 |
|---|
| 456 | ENDIF |
|---|
| 457 | |
|---|
| 458 | thisFile = StrTrim(filename, 2) |
|---|
| 459 | IF StrLen(thisFile) NE StrLen(filename) THEN $ |
|---|
| 460 | textSelection = textSelection-( StrLen(filename) - StrLen(thisFile) ) |
|---|
| 461 | Widget_Control, Set_Value=thisFile, self.filetextID, Set_Text_Select=[textSelection, 0] |
|---|
| 462 | RETURN, thisFile |
|---|
| 463 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 464 | |
|---|
| 465 | |
|---|
| 466 | |
|---|
| 467 | PRO FSC_FileSelect::LabelSize |
|---|
| 468 | |
|---|
| 469 | ; This method ensures the directory and filename labels are the same size. |
|---|
| 470 | |
|---|
| 471 | Catch, theError |
|---|
| 472 | IF theError NE 0 THEN BEGIN |
|---|
| 473 | ok = Error_Message() |
|---|
| 474 | RETURN |
|---|
| 475 | ENDIF |
|---|
| 476 | |
|---|
| 477 | fgeo = Widget_Info(self.filelabelID, /Geometry) |
|---|
| 478 | dgeo = Widget_Info(self.dirlabelID, /Geometry) |
|---|
| 479 | bestSize = fgeo.scr_xsize > dgeo.scr_xsize |
|---|
| 480 | Widget_Control, self.fileLabelID, Scr_XSize=bestSize |
|---|
| 481 | Widget_Control, self.dirLabelID, Scr_XSize=bestSize |
|---|
| 482 | END ;------------------------------------------------------------------------------- |
|---|
| 483 | |
|---|
| 484 | |
|---|
| 485 | |
|---|
| 486 | PRO 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 | |
|---|
| 492 | Catch, theError |
|---|
| 493 | IF theError NE 0 THEN BEGIN |
|---|
| 494 | ok = Error_Message() |
|---|
| 495 | RETURN |
|---|
| 496 | ENDIF |
|---|
| 497 | |
|---|
| 498 | ; Get the geometries of the filename widgets. |
|---|
| 499 | |
|---|
| 500 | tgeo = Widget_Info(self.tlb, /Geometry) |
|---|
| 501 | fgeo = Widget_Info(self.filetextID, /Geometry) |
|---|
| 502 | bbgeo = Widget_Info(self.filebaseID, /Geometry) |
|---|
| 503 | lbgeo = Widget_Info(Widget_Info(self.dirbaseID, /Parent), /Geometry) |
|---|
| 504 | rbgeo = Widget_Info(Widget_Info(self.filebrowseID, /Parent), /Geometry) |
|---|
| 505 | |
|---|
| 506 | ; Add the bits and bobs together. |
|---|
| 507 | |
|---|
| 508 | fspacing = tgeo.space |
|---|
| 509 | fpadding = 2*tgeo.xpad + 2*lbgeo.xpad |
|---|
| 510 | ffixedsize = ( 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 | |
|---|
| 515 | fgeo = Widget_Info(self.dirtextID, /Geometry) |
|---|
| 516 | bbgeo = Widget_Info(self.dirbaseID, /Geometry) |
|---|
| 517 | |
|---|
| 518 | ; Add the bits and bobs together. |
|---|
| 519 | |
|---|
| 520 | dspacing = tgeo.space |
|---|
| 521 | dpadding = 2*tgeo.xpad + 2*lbgeo.xpad |
|---|
| 522 | dfixedsize = ( 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 | |
|---|
| 527 | thisSize = 0 |
|---|
| 528 | childID = Widget_Info(self.parent, /Child) |
|---|
| 529 | geom = Widget_Info(childID, /Geometry) |
|---|
| 530 | testSize = geom.scr_xsize - 2*geom.margin |
|---|
| 531 | thisSize = thisSize > testSize |
|---|
| 532 | WHILE 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 |
|---|
| 539 | ENDWHILE |
|---|
| 540 | |
|---|
| 541 | ; Resize the widgets |
|---|
| 542 | |
|---|
| 543 | ftextsize = thisSize - (fspacing + fpadding + ffixedsize) |
|---|
| 544 | Widget_Control, self.filetextID, Scr_XSize=ftextsize |
|---|
| 545 | |
|---|
| 546 | dtextsize = thisSize - (dspacing + dpadding + dfixedsize) |
|---|
| 547 | Widget_Control, self.dirtextID, Scr_XSize=dtextsize |
|---|
| 548 | |
|---|
| 549 | END ;------------------------------------------------------------------------------- |
|---|
| 550 | |
|---|
| 551 | |
|---|
| 552 | |
|---|
| 553 | FUNCTION 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 |
|---|
| 578 | END ;------------------------------------------------------------------------- |
|---|
| 579 | |
|---|
| 580 | |
|---|
| 581 | |
|---|
| 582 | PRO FSC_FileSelect::Select_File, event |
|---|
| 583 | |
|---|
| 584 | Catch, theError |
|---|
| 585 | IF theError NE 0 THEN BEGIN |
|---|
| 586 | ok = Error_Message() |
|---|
| 587 | RETURN |
|---|
| 588 | ENDIF |
|---|
| 589 | |
|---|
| 590 | ; Use the file selection dialog to obtain a filename. |
|---|
| 591 | |
|---|
| 592 | currentFilename = self.filename |
|---|
| 593 | self.filename = "" |
|---|
| 594 | filename = 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 | |
|---|
| 603 | IF filename EQ "" THEN BEGIN |
|---|
| 604 | self.filename = currentFilename |
|---|
| 605 | RETURN |
|---|
| 606 | ENDIF |
|---|
| 607 | |
|---|
| 608 | ; Remove the directory from the name. |
|---|
| 609 | |
|---|
| 610 | index = StrLen(thePath) |
|---|
| 611 | theFilename = StrMid(filename, index) |
|---|
| 612 | |
|---|
| 613 | ; Strip the last directory separator. |
|---|
| 614 | |
|---|
| 615 | length = StrLen(thePath) |
|---|
| 616 | thePath = StrMid(thePath, 0, length-1) |
|---|
| 617 | |
|---|
| 618 | ; Inspect the file name to make sure it is valid. |
|---|
| 619 | |
|---|
| 620 | textSelection = Widget_Info(self.filetextID, /Text_Select) |
|---|
| 621 | filename = self->Inspect_Filename(filename, textSelection[0]) |
|---|
| 622 | |
|---|
| 623 | ; Update the display. |
|---|
| 624 | |
|---|
| 625 | self->SetProperty, Filename=theFilename, DirectoryName=thePath |
|---|
| 626 | |
|---|
| 627 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 628 | |
|---|
| 629 | |
|---|
| 630 | |
|---|
| 631 | PRO FSC_FileSelect::SetFilename, theName |
|---|
| 632 | |
|---|
| 633 | ; This method separates the filename into directory and filename |
|---|
| 634 | ; and adds them to the interface. |
|---|
| 635 | |
|---|
| 636 | Catch, theError |
|---|
| 637 | IF theError NE 0 THEN BEGIN |
|---|
| 638 | ok = Error_Message() |
|---|
| 639 | RETURN |
|---|
| 640 | ENDIF |
|---|
| 641 | |
|---|
| 642 | ; Change back slashes to forward slashes. |
|---|
| 643 | theName = StrJoin( StrSplit(theName, '\\', /Regex, /Extract, /Preserve_Null), '/') |
|---|
| 644 | |
|---|
| 645 | ; Get the correct directory separator. |
|---|
| 646 | |
|---|
| 647 | CASE StrUpCase(!Version.OS_Family) OF |
|---|
| 648 | 'MACOS' : sep = ':' ; Macintoshes |
|---|
| 649 | 'VMS' : sep = ']' ; VMS machines |
|---|
| 650 | ELSE : sep = '/' ; Unix machines |
|---|
| 651 | ENDCASE |
|---|
| 652 | |
|---|
| 653 | index = FSC_FileSelect_RStrPos(theName, sep) |
|---|
| 654 | IF index EQ -1 THEN BEGIN |
|---|
| 655 | self->SetProperty, Filename=theName |
|---|
| 656 | self.filename = theName |
|---|
| 657 | ENDIF 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 |
|---|
| 663 | ENDELSE |
|---|
| 664 | END ;------------------------------------------------------------------------------- |
|---|
| 665 | |
|---|
| 666 | |
|---|
| 667 | |
|---|
| 668 | PRO 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 | |
|---|
| 683 | Catch, theError |
|---|
| 684 | IF theError NE 0 THEN BEGIN |
|---|
| 685 | ok = Error_Message() |
|---|
| 686 | RETURN |
|---|
| 687 | ENDIF |
|---|
| 688 | |
|---|
| 689 | IF 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 |
|---|
| 693 | ENDIF |
|---|
| 694 | |
|---|
| 695 | IF N_Elements(event_pro) NE 0 THEN BEGIN |
|---|
| 696 | self.event_pro = event_pro |
|---|
| 697 | Widget_Control, self.tlb, Event_Pro=event_pro |
|---|
| 698 | ENDIF |
|---|
| 699 | |
|---|
| 700 | IF N_Elements(event_func) NE 0 THEN BEGIN |
|---|
| 701 | self.event_func = event_func |
|---|
| 702 | Widget_Control, self.tlb, Event_Func=event_func |
|---|
| 703 | ENDIF |
|---|
| 704 | |
|---|
| 705 | IF N_Elements(filename) NE 0 THEN BEGIN |
|---|
| 706 | self.filename = filename |
|---|
| 707 | strlength = StrLen(filename) |
|---|
| 708 | Widget_Control, self.filetextID, Set_Value=filename |
|---|
| 709 | ENDIF |
|---|
| 710 | |
|---|
| 711 | IF N_Elements(labelname) NE 0 THEN BEGIN |
|---|
| 712 | self.labelname = labelname |
|---|
| 713 | Widget_Control, self.filelabelID, Set_Value=labelname |
|---|
| 714 | ENDIF |
|---|
| 715 | |
|---|
| 716 | IF N_Elements(labelsize) NE 0 THEN BEGIN |
|---|
| 717 | Widget_Control, self.filelabelID, Scr_XSize=labelsize |
|---|
| 718 | ENDIF |
|---|
| 719 | |
|---|
| 720 | IF N_Elements(filter) NE 0 THEN *self.filter = filter |
|---|
| 721 | IF N_Elements(mustexist) NE 0 THEN self.mustexist = mustexist |
|---|
| 722 | IF N_Elements(read) NE 0 THEN self.read = read |
|---|
| 723 | IF N_Elements(selecttitle) NE 0 THEN self.selecttitle = selecttitle |
|---|
| 724 | IF N_Elements(uvalue) NE 0 THEN *self.uvalue = uvalue |
|---|
| 725 | IF N_Elements(write) NE 0 THEN self.write = write |
|---|
| 726 | |
|---|
| 727 | IF N_Elements(xsize) NE 0 THEN BEGIN |
|---|
| 728 | Widget_Control, self.filetextID, XSize=xsize |
|---|
| 729 | Widget_Control, self.dirtextID, XSize=xsize |
|---|
| 730 | ENDIF |
|---|
| 731 | |
|---|
| 732 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 733 | |
|---|
| 734 | |
|---|
| 735 | |
|---|
| 736 | PRO FSC_FileSelect::TextSelect, selection |
|---|
| 737 | |
|---|
| 738 | Catch, theError |
|---|
| 739 | IF theError NE 0 THEN BEGIN |
|---|
| 740 | ok = Error_Message() |
|---|
| 741 | RETURN |
|---|
| 742 | ENDIF |
|---|
| 743 | |
|---|
| 744 | IF N_Elements(selection) NE 2 THEN Message, 'Text selection array is not a two-element array: [beginSelection, selectionLength]' |
|---|
| 745 | Widget_Control, self.fileTextID, Set_Text_Select=selection |
|---|
| 746 | |
|---|
| 747 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 748 | |
|---|
| 749 | |
|---|
| 750 | |
|---|
| 751 | PRO FSC_FileSelect::CLEANUP |
|---|
| 752 | Ptr_Free, self.uvalue |
|---|
| 753 | Ptr_Free, self.filter |
|---|
| 754 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 755 | |
|---|
| 756 | |
|---|
| 757 | |
|---|
| 758 | FUNCTION 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 | |
|---|
| 781 | Catch, theError |
|---|
| 782 | ;theError = 0 |
|---|
| 783 | IF theError NE 0 THEN BEGIN |
|---|
| 784 | Catch, /Cancel |
|---|
| 785 | ok = Error_Message() |
|---|
| 786 | RETURN, 0 |
|---|
| 787 | ENDIF |
|---|
| 788 | |
|---|
| 789 | ; Populate self object. |
|---|
| 790 | |
|---|
| 791 | self.parent = parent |
|---|
| 792 | self.directoryname = dirname |
|---|
| 793 | self.event_pro = event_pro |
|---|
| 794 | self.event_func = event_func |
|---|
| 795 | self.filename = filename |
|---|
| 796 | self.filter = Ptr_New(filter) |
|---|
| 797 | self.frame = frame |
|---|
| 798 | self.labelfont = labelfont |
|---|
| 799 | self.labelname = labelname |
|---|
| 800 | self.labelsize = labelsize |
|---|
| 801 | self.mustexist = mustexist |
|---|
| 802 | self.nomaxsize = nomaxsize |
|---|
| 803 | self.read = read |
|---|
| 804 | self.selectdir = selectdir |
|---|
| 805 | self.selectfont = selectfont |
|---|
| 806 | self.selecttitle = selecttitle |
|---|
| 807 | self.textfont = textfont |
|---|
| 808 | self.uvalue = Ptr_New(uvalue) |
|---|
| 809 | self.write = write |
|---|
| 810 | self.xsize = xsize |
|---|
| 811 | |
|---|
| 812 | |
|---|
| 813 | ; Build widgets. |
|---|
| 814 | |
|---|
| 815 | self.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 | |
|---|
| 827 | leftbase = Widget_Base(self.tlb, Row=2, UValue=self) |
|---|
| 828 | |
|---|
| 829 | self.dirbaseID = Widget_Base(leftbase, Row=1) |
|---|
| 830 | |
|---|
| 831 | self.dirlabelID = Widget_Label( self.dirbaseID, $ |
|---|
| 832 | Font=self.labelfont, $ |
|---|
| 833 | Scr_XSize=self.labelsize, $ |
|---|
| 834 | Value='Directory: ' ) |
|---|
| 835 | |
|---|
| 836 | |
|---|
| 837 | self.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 | |
|---|
| 848 | self.filebaseID = Widget_Base(leftbase, Row=1) |
|---|
| 849 | |
|---|
| 850 | self.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 | |
|---|
| 859 | self.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 | |
|---|
| 869 | rightbase = Widget_Base(self.tlb, Row=1, Base_Align_Center=1) |
|---|
| 870 | self.filebrowseID = Widget_Button( rightbase, $ |
|---|
| 871 | Event_Func='FSC_FileSelect_Event_Handler', $ |
|---|
| 872 | UValue={method:'Select_File', object:self}, $ |
|---|
| 873 | Value='Browse') |
|---|
| 874 | |
|---|
| 875 | |
|---|
| 876 | RETURN, 1 |
|---|
| 877 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 878 | |
|---|
| 879 | |
|---|
| 880 | |
|---|
| 881 | PRO 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 | |
|---|
| 915 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 916 | |
|---|
| 917 | |
|---|
| 918 | |
|---|
| 919 | PRO 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 | |
|---|
| 925 | firstChild = Widget_Info(id, /Child) |
|---|
| 926 | Widget_Control, firstChild, Get_UValue=self |
|---|
| 927 | self->SetFilename,filename |
|---|
| 928 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 929 | |
|---|
| 930 | |
|---|
| 931 | |
|---|
| 932 | FUNCTION 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 | |
|---|
| 937 | firstChild = Widget_Info(id, /Child) |
|---|
| 938 | Widget_Control, firstChild, Get_UValue=self |
|---|
| 939 | RETURN, self->GetFilename() |
|---|
| 940 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 941 | |
|---|
| 942 | |
|---|
| 943 | |
|---|
| 944 | PRO 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. |
|---|
| 955 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 956 | |
|---|
| 957 | |
|---|
| 958 | |
|---|
| 959 | FUNCTION 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 | |
|---|
| 966 | Widget_Control, event.ID, Get_UValue=theMessage |
|---|
| 967 | |
|---|
| 968 | Call_Method, theMessage.method, theMessage.object, event |
|---|
| 969 | |
|---|
| 970 | ; Events will be sent only if there is an assigned event handler. |
|---|
| 971 | |
|---|
| 972 | self = theMessage.object |
|---|
| 973 | self->GetProperty, Filename=filename, DirectoryName=directory, $ |
|---|
| 974 | Event_Pro=event_pro, Event_Func=event_func |
|---|
| 975 | IF 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 |
|---|
| 992 | ENDIF ELSE RETURN, 0 |
|---|
| 993 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 994 | |
|---|
| 995 | |
|---|
| 996 | PRO FSC_FileSelect_Notify_Realize, labelID |
|---|
| 997 | |
|---|
| 998 | ; When the compound widget is realized, make sure sizes are correct. |
|---|
| 999 | |
|---|
| 1000 | Widget_Control, labelID, Get_UValue=self |
|---|
| 1001 | IF self->GetNoMaxSize() THEN RETURN |
|---|
| 1002 | self->Matchsize |
|---|
| 1003 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1004 | |
|---|
| 1005 | |
|---|
| 1006 | |
|---|
| 1007 | PRO FSC_FileSelect_Kill_Notify, labelID |
|---|
| 1008 | |
|---|
| 1009 | ; When the compound widget dies, destroy the self object. |
|---|
| 1010 | |
|---|
| 1011 | Widget_Control, labelID, Get_UValue=self |
|---|
| 1012 | Obj_Destroy, self |
|---|
| 1013 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1014 | |
|---|
| 1015 | |
|---|
| 1016 | |
|---|
| 1017 | FUNCTION 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 | |
|---|
| 1040 | Catch, theError |
|---|
| 1041 | ;theError = 0 |
|---|
| 1042 | IF theError NE 0 THEN BEGIN |
|---|
| 1043 | ok = Error_Message() |
|---|
| 1044 | RETURN, 0 |
|---|
| 1045 | ENDIF |
|---|
| 1046 | |
|---|
| 1047 | ; Need a parent parameter. |
|---|
| 1048 | |
|---|
| 1049 | IF N_Elements(parent) EQ 0 THEN BEGIN |
|---|
| 1050 | ok = Dialog_Message('FSC_FILESELECT: A parent parameter is required.') |
|---|
| 1051 | RETURN, -1 |
|---|
| 1052 | ENDIF |
|---|
| 1053 | |
|---|
| 1054 | ; Check keyword arguments. |
|---|
| 1055 | |
|---|
| 1056 | IF N_Elements(dirname) EQ 0 THEN CD, Current=dirname |
|---|
| 1057 | dirname = StrJoin( StrSplit(dirname, '\\', /Regex, /Extract, /Preserve_Null), '/') |
|---|
| 1058 | IF N_Elements(event_pro) EQ 0 THEN event_pro = "" |
|---|
| 1059 | IF N_Elements(event_func) EQ 0 THEN event_func = "" |
|---|
| 1060 | IF N_Elements(filename) EQ 0 THEN filename = "" |
|---|
| 1061 | IF N_Elements(filter) EQ 0 THEN filter = '*' |
|---|
| 1062 | IF N_Elements(Frame) EQ 0 THEN Frame = 0 |
|---|
| 1063 | IF N_Elements(labelfont) EQ 0 THEN labelfont = "" |
|---|
| 1064 | IF N_Elements(labelname) EQ 0 THEN labelname = "Filename: " |
|---|
| 1065 | IF N_Elements(labelsize) EQ 0 THEN labelsize = 0 |
|---|
| 1066 | IF N_Elements(mustexist) EQ 0 THEN mustexist = 0 |
|---|
| 1067 | IF N_Elements(nomaxsize) EQ 0 THEN nomaxsize = 0 |
|---|
| 1068 | IF N_Elements(read) EQ 0 THEN read = 0 |
|---|
| 1069 | IF N_Elements(selectdir) EQ 0 THEN selectdir = dirname |
|---|
| 1070 | IF N_Elements(selectfont) EQ 0 THEN selectfont = "" |
|---|
| 1071 | IF 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 = "" |
|---|
| 1073 | IF N_Elements(textfont) EQ 0 THEN textfont = "" |
|---|
| 1074 | IF N_Elements(uvalue) EQ 0 THEN uvalue = "" |
|---|
| 1075 | IF N_Elements(write) EQ 0 THEN write = 0 |
|---|
| 1076 | IF N_Elements(xsize) EQ 0 THEN xsize = Long(StrLen(dirname) * 1.20 > 40) |
|---|
| 1077 | |
|---|
| 1078 | ; Create the underlying structure. |
|---|
| 1079 | |
|---|
| 1080 | objectref = 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() |
|---|
| 1106 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1107 | |
|---|
| 1108 | |
|---|
| 1109 | |
|---|
| 1110 | PRO Example_Set_Size, event |
|---|
| 1111 | Widget_Control, event.top, Get_UValue=theObject |
|---|
| 1112 | theObject->MatchSize |
|---|
| 1113 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1114 | |
|---|
| 1115 | |
|---|
| 1116 | |
|---|
| 1117 | PRO Example_Set_Filter, event |
|---|
| 1118 | Widget_Control, event.top, Get_UValue=theObject |
|---|
| 1119 | theObject->SetProperty, Filter='*.pro', Filename='cyclone.pro' |
|---|
| 1120 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1121 | |
|---|
| 1122 | |
|---|
| 1123 | |
|---|
| 1124 | PRO Example_Set_Filename, event |
|---|
| 1125 | Widget_Control, event.top, Get_UValue=theObject |
|---|
| 1126 | filename = Filepath(Subdir=['examples', 'data'], 'worldelv.dat') |
|---|
| 1127 | theObject->SetFilename, filename |
|---|
| 1128 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1129 | |
|---|
| 1130 | |
|---|
| 1131 | |
|---|
| 1132 | PRO Example_Shrink, event |
|---|
| 1133 | Widget_Control, event.top, Get_UValue=theObject |
|---|
| 1134 | theObject->SetProperty, XSize=40 |
|---|
| 1135 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1136 | |
|---|
| 1137 | |
|---|
| 1138 | |
|---|
| 1139 | PRO Example_Print_Filename, event |
|---|
| 1140 | Widget_Control, event.top, Get_UValue=theObject |
|---|
| 1141 | Print, theObject->GetFilename() |
|---|
| 1142 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1143 | |
|---|
| 1144 | |
|---|
| 1145 | |
|---|
| 1146 | PRO Example_Quit, event |
|---|
| 1147 | Widget_Control, event.top, /Destroy |
|---|
| 1148 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1149 | |
|---|
| 1150 | |
|---|
| 1151 | |
|---|
| 1152 | PRO Example, theObject |
|---|
| 1153 | |
|---|
| 1154 | tlb = Widget_Base(Title='Exercise FSC_FILESELECT...', Column=1) |
|---|
| 1155 | button = Widget_Button(tlb, Value='Make Compound Widget As Big As Me', $ |
|---|
| 1156 | Event_Pro='Example_Set_Size', Scr_XSize=500) |
|---|
| 1157 | button = Widget_Button(tlb, Value='Set Filename to worldelv.data in Data Directory', $ |
|---|
| 1158 | Event_Pro='Example_Set_Filename') |
|---|
| 1159 | button = Widget_Button(tlb, Value='Print Filename', $ |
|---|
| 1160 | Event_Pro='Example_Print_Filename') |
|---|
| 1161 | button = Widget_Button(tlb, Value="Shrink the Text Fields", $ |
|---|
| 1162 | Event_Pro='Example_Shrink') |
|---|
| 1163 | CD, Current=thisDir |
|---|
| 1164 | filenameID = FSC_FileSelect(tlb, Directory=thisDir, Filename='fileselect.pro', $ |
|---|
| 1165 | /NoMaxSize, ObjectRef=theObject) |
|---|
| 1166 | button = Widget_Button(tlb, Value='Quit', Event_Pro='Example_Quit') |
|---|
| 1167 | Widget_Control, tlb, /Realize, Set_UValue=theObject |
|---|
| 1168 | XManager, 'example', tlb, /No_Block |
|---|
| 1169 | END ;----------------------------------------------------------------------------------------------------------------------------- |
|---|
| 1170 | |
|---|