1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: xitFileSel 4 -- 5 -- Project: Xtools 6 -- System: <> 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- Display a file selection dialog and let the user select a file. 12 -- 13 -- Filename: xitFileSel.c 14 -- 15 -- Authors: Roger Larsson, Ulrika Bornetun 16 -- Creation date: 1992-05-18 17 -- 18 -- 19 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 20 -- All rights reserved 21 -- 22 -- Permission to use, copy, modify, and distribute this software and its 23 -- documentation for any purpose and without fee is hereby granted, 24 -- provided that the above copyright notice appear in all copies. Ulrika 25 -- Bornetun and Roger Larsson make no representations about the usability 26 -- of this software for any purpose. It is provided "as is" without express 27 -- or implied warranty. 28 ----------------------------------------------------------------------------*/ 29 30 /* SCCS module identifier. */ 31 static char SCCSID[] = "@(#) Module: xitFileSel.c, Version: 1.1, Date: 95/02/18 15:10:31"; 32 33 34 /*---------------------------------------------------------------------------- 35 -- Include files 36 ----------------------------------------------------------------------------*/ 37 38 #include <stdio.h> 39 #include <string.h> 40 #include <unistd.h> 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 44 #include <X11/Intrinsic.h> 45 46 #include <Xm/Xm.h> 47 #include <Xm/FileSB.h> 48 49 #include "System.h" 50 51 #include "xitError.h" 52 #include "xitTools.h" 53 54 55 /*---------------------------------------------------------------------------- 56 -- Macro definitions 57 ----------------------------------------------------------------------------*/ 58 59 60 /*---------------------------------------------------------------------------- 61 -- Type declarations 62 ----------------------------------------------------------------------------*/ 63 64 /* Internal data to use. */ 65 typedef struct { 66 67 /* Flags. */ 68 UINT32 flags; 69 70 /* Messages to use. */ 71 char *no_file_sel_msg; 72 char *cannot_read_file_msg; 73 74 /* The file selection window. */ 75 Widget mainW; 76 77 /* User data and use callback. */ 78 XIT_FILE_SEL_CB actionCB; 79 void *user_data; 80 81 } SELECT_INFO, *SELECT_INFO_REF; 82 83 84 /*---------------------------------------------------------------------------- 85 -- Global definitions 86 ----------------------------------------------------------------------------*/ 87 88 /* Name of module. */ 89 static char *module_name = "xitFileSel"; 90 91 92 /*---------------------------------------------------------------------------- 93 -- Function prototypes 94 ----------------------------------------------------------------------------*/ 95 96 static void 97 cancelCB( Widget widget, 98 SELECT_INFO_REF sel_ref, 99 XtPointer call_data ); 100 101 static void 102 destroyCB( Widget widget, 103 SELECT_INFO_REF sel_ref, 104 XtPointer call_data ); 105 106 static void 107 okCB( Widget widget, 108 SELECT_INFO_REF sel_ref, 109 XmFileSelectionBoxCallbackStruct *call_data ); 110 111 112 113 /*---------------------------------------------------------------------------- 114 -- Functions 115 ----------------------------------------------------------------------------*/ 116 117 Widget xitCreateFileSelect(Widget parent,char * name,UINT32 flags,char * source_dir,XIT_FILE_SEL_LABELS * labels,XIT_FILE_SEL_CB actionCB,void * user_data)118 xitCreateFileSelect( Widget parent, 119 char *name, 120 UINT32 flags, 121 char *source_dir, 122 XIT_FILE_SEL_LABELS *labels, 123 XIT_FILE_SEL_CB actionCB, 124 void *user_data ) 125 { 126 127 /* Variables. */ 128 Arg args[ 10 ]; 129 Cardinal n; 130 Widget fileSelW; 131 Widget tempW; 132 XmString xstr; 133 SELECT_INFO_REF sel_ref; 134 135 136 /* Code. */ 137 138 /* Only directories? */ 139 if( flagIsSet( flags, XIT_FILE_SELECT_ONLY_DIRS ) ) 140 flagSet( flags, XIT_FILE_SELECT_DIRS_OK ); 141 142 143 n = 0; 144 145 /* This window is always deleted. */ 146 XtSetArg( args[ n ], XmNdeleteResponse, XmDESTROY ); n++; 147 148 /* Create and initialize our private data. */ 149 sel_ref = SysNew( SELECT_INFO ); 150 if( sel_ref == NULL ) 151 return( NULL ); 152 153 sel_ref -> flags = flags; 154 sel_ref -> no_file_sel_msg = labels -> no_file_sel_msg; 155 sel_ref -> cannot_read_file_msg = labels -> cannot_read_file_msg; 156 157 sel_ref -> actionCB = actionCB; 158 sel_ref -> user_data = user_data; 159 160 161 /* Create the file selection dialog. */ 162 fileSelW = XmCreateFileSelectionDialog( parent, name, args, n ); 163 164 sel_ref -> mainW = fileSelW; 165 166 XtAddCallback( fileSelW, XmNokCallback, 167 (XtCallbackProc) okCB, (XtPointer) sel_ref ); 168 XtAddCallback( fileSelW, XmNcancelCallback, 169 (XtCallbackProc) cancelCB, (XtPointer) sel_ref ); 170 XtAddCallback( fileSelW, XmNdestroyCallback, 171 (XtCallbackProc) destroyCB, (XtPointer) sel_ref ); 172 173 174 /* The labels. */ 175 if( strlen( labels -> filter_label ) > 0 ) { 176 xstr = XmStringCreate( labels -> filter_label, CS ); 177 178 XtSetArg( args[ 0 ], XmNfilterLabelString, xstr ); 179 XtSetValues( fileSelW, args, 1 ); 180 181 XmStringFree( xstr ); 182 } 183 184 if( strlen( labels -> dir_list_label ) > 0 ) { 185 xstr = XmStringCreate( labels -> dir_list_label, CS ); 186 187 XtSetArg( args[ 0 ], XmNdirListLabelString, xstr ); 188 XtSetValues( fileSelW, args, 1 ); 189 190 XmStringFree( xstr ); 191 } 192 193 if( strlen( labels -> file_list_label ) > 0 ) { 194 xstr = XmStringCreate( labels -> file_list_label, CS ); 195 196 XtSetArg( args[ 0 ], XmNfileListLabelString, xstr ); 197 XtSetValues( fileSelW, args, 1 ); 198 199 XmStringFree( xstr ); 200 } 201 202 if( strlen( labels -> selection_label ) > 0 ) { 203 xstr = XmStringCreate( labels -> selection_label, CS ); 204 205 XtSetArg( args[ 0 ], XmNselectionLabelString, xstr ); 206 XtSetValues( fileSelW, args, 1 ); 207 208 XmStringFree( xstr ); 209 } 210 211 /* The action buttons. */ 212 if( strlen( labels -> ok_button ) > 0 ) { 213 xstr = XmStringCreate( labels -> ok_button, CS ); 214 215 XtSetArg( args[ 0 ], XmNokLabelString, xstr ); 216 XtSetValues( fileSelW, args, 1 ); 217 218 XmStringFree( xstr ); 219 } 220 221 if( strlen( labels -> filter_button ) > 0 ) { 222 xstr = XmStringCreate( labels -> filter_button, CS ); 223 224 XtSetArg( args[ 0 ], XmNapplyLabelString, xstr ); 225 XtSetValues( fileSelW, args, 1 ); 226 227 XmStringFree( xstr ); 228 } 229 230 if( strlen( labels -> cancel_button ) > 0 ) { 231 xstr = XmStringCreate( labels -> cancel_button, CS ); 232 233 XtSetArg( args[ 0 ], XmNcancelLabelString, xstr ); 234 XtSetValues( fileSelW, args, 1 ); 235 236 XmStringFree( xstr ); 237 } 238 239 240 /* We don't use the Help button. */ 241 tempW = XmFileSelectionBoxGetChild( fileSelW, XmDIALOG_HELP_BUTTON ); 242 XtUnmanageChild( tempW ); 243 244 245 /* No title. */ 246 n = 0; 247 XtSetArg( args[ n ], XmNtitle, " " ); n++; 248 XtSetValues( XtParent( fileSelW ), args, n ); 249 250 251 return( fileSelW ); 252 253 } /* xitCreateFileSelect */ 254 255 256 /*----------------------------------------------------------------------*/ 257 258 void xitFileSelectDisplay(Widget widget)259 xitFileSelectDisplay( Widget widget ) 260 { 261 262 /* Code. */ 263 264 if( widget == NULL ) 265 return; 266 267 268 /* Make sure the file selection window is visable. */ 269 XtManageChild( widget ); 270 271 XtPopup( XtParent( widget ), XtGrabNone ); 272 273 XRaiseWindow( XtDisplay( widget ), XtWindow( widget ) ); 274 XtMapWidget( widget ); 275 276 277 return; 278 279 } /* xitFileSelectDisplay */ 280 281 282 /*----------------------------------------------------------------------*/ 283 284 static void cancelCB(Widget widget,SELECT_INFO_REF sel_ref,XtPointer call_data)285 cancelCB( Widget widget, 286 SELECT_INFO_REF sel_ref, 287 XtPointer call_data ) 288 { 289 290 /* Code. */ 291 292 /* User callback? */ 293 if( sel_ref -> actionCB != NULL ) 294 (* sel_ref -> actionCB)( XIT_FILE_SELECT_CANCEL, NULL, 295 sel_ref -> user_data ); 296 297 /* Remove the window. */ 298 XtUnmanageChild( sel_ref -> mainW ); 299 300 301 return; 302 303 } /* cancelCB */ 304 305 306 /*----------------------------------------------------------------------*/ 307 308 static void destroyCB(Widget widget,SELECT_INFO_REF sel_ref,XtPointer call_data)309 destroyCB( Widget widget, 310 SELECT_INFO_REF sel_ref, 311 XtPointer call_data ) 312 { 313 314 /* Code. */ 315 316 /* Free the internal data. */ 317 if( sel_ref != NULL ) 318 SysFree( sel_ref ); 319 320 321 return; 322 323 } /* destroyCB */ 324 325 326 /*----------------------------------------------------------------------*/ 327 328 static void okCB(Widget widget,SELECT_INFO_REF sel_ref,XmFileSelectionBoxCallbackStruct * call_data)329 okCB( Widget widget, 330 SELECT_INFO_REF sel_ref, 331 XmFileSelectionBoxCallbackStruct *call_data ) 332 { 333 334 /* Variables. */ 335 int status; 336 char *file_name; 337 struct stat file_info; 338 339 340 /* Code. */ 341 342 /* The selected file name. */ 343 file_name = xitStringGetString( call_data -> value, CS ); 344 345 346 /* Only directory? */ 347 if( flagIsSet( sel_ref -> flags, XIT_FILE_SELECT_ONLY_DIRS ) ) { 348 SysFree( file_name ); 349 350 file_name = xitStringGetString( call_data -> dir, CS ); 351 } 352 353 354 /* No file selected? */ 355 if( file_name == NULL || *file_name == '\0' ) { 356 xitErMessage( sel_ref -> mainW, XIT_ER_ERROR, 357 module_name, "okCB", 358 sel_ref -> no_file_sel_msg ); 359 360 SysFree( file_name ); 361 return; 362 } 363 364 /* Is the file a normal file and can it be read? */ 365 status = stat( file_name, &file_info ); 366 367 if( status != 0 ) { 368 xitErMessage( sel_ref -> mainW, XIT_ER_ERROR, 369 module_name, "okCB", 370 sel_ref -> cannot_read_file_msg ); 371 372 SysFree( file_name ); 373 return; 374 } 375 376 if( S_ISDIR( file_info.st_mode ) && 377 flagIsClear( sel_ref -> flags, XIT_FILE_SELECT_DIRS_OK ) ) { 378 xitErMessage( sel_ref -> mainW, XIT_ER_ERROR, 379 module_name, "okCB", 380 sel_ref -> cannot_read_file_msg ); 381 382 SysFree( file_name ); 383 return; 384 } 385 386 387 status = access( file_name, (F_OK | R_OK) ); 388 389 if( status != 0 ) { 390 xitErMessage( sel_ref -> mainW, XIT_ER_ERROR, 391 module_name, "okCB", 392 sel_ref -> cannot_read_file_msg ); 393 394 SysFree( file_name ); 395 return; 396 } 397 398 399 /* User callback? */ 400 if( sel_ref -> actionCB != NULL ) 401 (* sel_ref -> actionCB)( XIT_FILE_SELECT_OK, file_name, 402 sel_ref -> user_data ); 403 404 405 /* Remove the window. */ 406 XtUnmanageChild( sel_ref -> mainW ); 407 408 SysFree( file_name ); 409 410 411 return; 412 413 } /* okCB */ 414