home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / xarchie / part21 < prev    next >
Encoding:
Text File  |  1993-06-14  |  50.5 KB  |  1,551 lines

  1. Newsgroups: comp.sources.x
  2. From: ferguson@cs.rochester.edu (George Ferguson)
  3. Subject: v20i049:  xarchie - An X browser interface to Archie, v2.0.6, Part21/24
  4. Message-ID: <1993Jun15.223532.1873@sparky.imd.sterling.com>
  5. X-Md4-Signature: 41ea0e40f9111a080ee810b8d504c0f3
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Tue, 15 Jun 1993 22:35:32 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: ferguson@cs.rochester.edu (George Ferguson)
  12. Posting-number: Volume 20, Issue 49
  13. Archive-name: xarchie/part21
  14. Environment: X11
  15. Supersedes: xarchie: Volume 14, Issue 82-90
  16.  
  17. Submitted-by: ferguson@cs.rochester.edu
  18. Archive-name: xarchie-2.0.6/part21
  19.  
  20. #!/bin/sh
  21. # this is Part.21 (part 21 of xarchie-2.0.6)
  22. # do not concatenate these parts, unpack them in order with /bin/sh
  23. # file xarchie-2.0.6/FWF/FileChooser/FChooser.c continued
  24. #
  25. if test ! -r _shar_seq_.tmp; then
  26.     echo 'Please unpack part 1 first!'
  27.     exit 1
  28. fi
  29. (read Scheck
  30.  if test "$Scheck" != 21; then
  31.     echo Please unpack part "$Scheck" next!
  32.     exit 1
  33.  else
  34.     exit 0
  35.  fi
  36. ) < _shar_seq_.tmp || exit 1
  37. if test ! -f _shar_wnt_.tmp; then
  38.     echo 'x - still skipping xarchie-2.0.6/FWF/FileChooser/FChooser.c'
  39. else
  40. echo 'x - continuing file xarchie-2.0.6/FWF/FileChooser/FChooser.c'
  41. sed 's/^X//' << 'SHAR_EOF' >> 'xarchie-2.0.6/FWF/FileChooser/FChooser.c' &&
  42. XXfwfFileChooserWidget fcw;
  43. {
  44. X    int i;
  45. X
  46. X    XtFree(FCCurrentDirectory(fcw));
  47. X    XtFree(FCCurrentFile(fcw));
  48. X    XtFree(FCPattern(fcw));
  49. X    if (FCFileNames(fcw) != NULL) {
  50. X    for (i=0; i < FCNumFileNames(fcw); i++)
  51. X        XtFree(FCFileNames(fcw)[i]);
  52. X    XtFree((char *)FCFileNames(fcw));
  53. X    }
  54. X    if (FCDirNames(fcw) != NULL) {
  55. X    for (i=0; i < FCNumDirNames(fcw); i++)
  56. X        XtFree(FCDirNames(fcw)[i]);
  57. X    XtFree((char *)FCDirNames(fcw));
  58. X    }
  59. } /* End Destroy */
  60. X
  61. /*---------------------------------------------------------------------------*
  62. X
  63. X    Resize()
  64. X
  65. X    This function is called to resize a FileChooser widget.
  66. X
  67. X *---------------------------------------------------------------------------*/
  68. X
  69. static void
  70. Resize(w) 
  71. Widget w;
  72. {
  73. X    XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)w;
  74. X
  75. X    ChildrenUpdate(fcw);
  76. } /* End Resize */
  77. X
  78. /*---------------------------------------------------------------------------*
  79. X
  80. X    SetValues()
  81. X
  82. X    This function is the external interface for setting resources.
  83. X
  84. X *---------------------------------------------------------------------------*/
  85. X
  86. /* ARGSUSED */
  87. static Boolean
  88. SetValues(current,request,new)
  89. Widget current,request,new;
  90. {
  91. X    XfwfFileChooserWidget fcw_current = (XfwfFileChooserWidget)current;
  92. X    XfwfFileChooserWidget fcw_new = (XfwfFileChooserWidget)new;
  93. X
  94. X    if (FCCurrentDirectory(fcw_current) != FCCurrentDirectory(fcw_new)){
  95. X    strcpy(FCCurrentDirectory(fcw_current),FCCurrentDirectory(fcw_new));
  96. X    FCCurrentDirectory(fcw_new) = FCCurrentDirectory(fcw_current);
  97. X    Chdir(fcw_new);
  98. X    }
  99. X    if (FCCurrentFile(fcw_current) != FCCurrentFile(fcw_new)) {
  100. X    char *new_name;
  101. X
  102. X    new_name = FCCurrentFile(fcw_new);
  103. X    FCCurrentFile(fcw_new) = FCCurrentFile(fcw_current);
  104. X    SelectFileByName(fcw_new,new_name);
  105. X    }
  106. X    if (FCPattern(fcw_current) != FCPattern(fcw_new)) {
  107. X    XtFree(FCPattern(fcw_current));
  108. X    FCPattern(fcw_new) = XtNewString(FCPattern(fcw_current));
  109. X    Chdir(fcw_new);
  110. X    }
  111. X    if (FCSortMode(fcw_current) != FCSortMode(fcw_new)) {
  112. X    Chdir(fcw_new);
  113. X    }
  114. X    return(False);
  115. } /* End SetValues() */
  116. X
  117. /*---------------------------------------------------------------------------*
  118. X
  119. X    GeometryManager(w,request,reply)
  120. X
  121. X    This routine acts as the geometry_manager method for the
  122. X    FileChooser widget.  It is called when a child wants to
  123. X    resize/reposition itself.
  124. X
  125. X    Currently, we allow all requests.
  126. X
  127. X *---------------------------------------------------------------------------*/
  128. X
  129. /* ARGSUSED */
  130. static XtGeometryResult
  131. GeometryManager(w,request,reply)
  132. Widget w;
  133. XXtWidgetGeometry *request;
  134. XXtWidgetGeometry *reply;
  135. {
  136. X    return(XtGeometryYes);
  137. } /* End GeometryManager */
  138. X
  139. /*---------------------------------------------------------------------------*
  140. X
  141. X                     L O C A L    R O U T I N E S
  142. X
  143. X *---------------------------------------------------------------------------*/
  144. X
  145. /*---------------------------------------------------------------------------*
  146. X
  147. X    ChildrenCreate(fcw)
  148. X
  149. X    This routine creates the initial child widgets for the
  150. X    file selector widget and places them in the widget fcw.
  151. X    No placement or resizing is done.  That is done by
  152. X    ChildrenUpdate().
  153. X
  154. X *---------------------------------------------------------------------------*/
  155. X
  156. static void
  157. ChildrenCreate(fcw)
  158. XXfwfFileChooserWidget fcw;
  159. {
  160. X    Arg args[2];
  161. X    static char *str = NULL;
  162. X
  163. X    XtSetArg(args[0],XtNmenuName,FC_DIR_MENU_NAME);
  164. X    FCDirMenuButton(fcw) =
  165. X    XtCreateManagedWidget(FC_DIR_MENU_BUTTON_NAME,menuButtonWidgetClass,
  166. X                  (Widget)fcw,args,1);
  167. X    XtSetArg(args[0],XtNallowVert,True);
  168. X    XtSetArg(args[1],XtNforceBars,True);
  169. X    FCFileViewport(fcw) =
  170. X    XtCreateManagedWidget(FC_FILE_VIEWPORT_NAME,viewportWidgetClass,
  171. X                  (Widget)fcw,args,2);
  172. X    XtSetArg(args[0],XtNlist,&str);
  173. X    XtSetArg(args[1],XtNverticalList,True);
  174. X    FCFileList(fcw) = XtCreateManagedWidget(FC_FILE_LIST_NAME,listWidgetClass,
  175. X                        FCFileViewport(fcw),args,2);
  176. X    XtAddCallback(FCFileList(fcw),XtNcallback,
  177. X          (XtCallbackProc)FileCallback,(XtPointer)fcw);
  178. } /* End ChildrenCreate */
  179. X
  180. /*---------------------------------------------------------------------------*
  181. X
  182. X    ChildrenRealize(fcw)
  183. X
  184. X    This routine realizes the child widgets.  The widgets must
  185. X    already have been created and initialized.  Their coordinates
  186. X    should already have been set.
  187. X
  188. X *---------------------------------------------------------------------------*/
  189. X
  190. static void
  191. ChildrenRealize(fcw)
  192. XXfwfFileChooserWidget fcw;
  193. {
  194. X    XtRealizeWidget(FCDirMenuButton(fcw));
  195. X    XtRealizeWidget(FCFileViewport(fcw));
  196. X    XtRealizeWidget(FCFileList(fcw));
  197. } /* End ChildrenRealize */
  198. X
  199. /*---------------------------------------------------------------------------*
  200. X
  201. X    ChildrenUpdate(fcw)
  202. X
  203. X    This routine takes a FileChooser widget fcw and updates
  204. X    the child widgets by recalculating their coordinates based
  205. X    on the current size of the FileChooser, and setting the
  206. X    appropriate resources.
  207. X
  208. X    We go to some trouble to get something useful displayed in the
  209. X    FCDirMenuButton(fcw) if the current directory name is too long
  210. X    to fit in the button. It would be nice if the "justify" resource
  211. X    of the MenuButton widget did this, but...
  212. X
  213. X *---------------------------------------------------------------------------*/
  214. X
  215. static void
  216. ChildrenUpdate(fcw)
  217. XXfwfFileChooserWidget fcw;
  218. {
  219. X    Dimension w,h;
  220. X    int gap;
  221. X    Dimension menuButtonW,menuButtonH,fileListW,fileListH;
  222. X    Position menuButtonX,menuButtonY,fileListX,fileListY;
  223. X    XtWidgetGeometry parent_idea,child_idea;
  224. X    Arg args[3];
  225. X    XFontStruct *fs;
  226. X    char *label;
  227. X    Dimension intw;
  228. X
  229. X    if (!XtIsRealized((Widget)fcw)) {
  230. X    return;
  231. X    }
  232. X    w = CoreWidth(fcw);
  233. X    h = CoreHeight(fcw);
  234. X    gap = 3;
  235. X    /* Get The Child Widgets Current Widths And Heights */
  236. X    /* (although we don't actually use the existing values... */
  237. X    menuButtonW = CoreWidth(FCDirMenuButton(fcw));
  238. X    menuButtonH = CoreHeight(FCDirMenuButton(fcw));
  239. X    fileListW = CoreWidth(FCFileList(fcw));
  240. X    fileListH = CoreHeight(FCFileList(fcw));
  241. X    /* Adjust Widths */
  242. X    menuButtonW = w;
  243. X    fileListW = w;
  244. X    /* Adjust menu button label if too small */
  245. X    /* It would be nice if the "justify" resource of MenuButton did this... */
  246. X    XtSetArg(args[0],XtNinternalWidth,&intw);
  247. X    XtSetArg(args[1],XtNfont,&fs);
  248. X    XtGetValues(FCDirMenuButton(fcw),args,2);
  249. X    label = FCCurrentDirectory(fcw);
  250. X    if (XTextWidth(fs,label,strlen(label)) > (int)(menuButtonW-intw)) {
  251. X    char newLabel[MAXPATHLEN];
  252. X    while (*label && XTextWidth(fs,label,strlen(label)) >
  253. X                                               (int)(menuButtonW-intw)) {
  254. X        label += 1;
  255. X    }
  256. X    if (*label)
  257. X        label += 1;
  258. X    strcpy(newLabel,"<");
  259. X    strcat(newLabel,label);
  260. X    XtSetArg(args[0],XtNlabel,newLabel);
  261. X    XtSetValues(FCDirMenuButton(fcw),args,1);
  262. X    }
  263. X    /* Adjust Heights */
  264. X    fileListH = h - menuButtonH - gap;
  265. X    /* Listen To Child Height Request For List */
  266. X    parent_idea.request_mode = CWWidth | CWHeight;
  267. X    parent_idea.width = fileListW;
  268. X    parent_idea.height = fileListH;
  269. X    XtQueryGeometry(FCFileList(fcw),&parent_idea,&child_idea);
  270. X    if ((child_idea.request_mode & CWHeight) &&
  271. X    (child_idea.height < parent_idea.height)) {
  272. X    fileListH = child_idea.height;
  273. X    }
  274. X    /* Vertical Positions */
  275. X    menuButtonY = 0;
  276. X    fileListY = menuButtonH + gap;
  277. X    /* Horizontal Positions */
  278. X    menuButtonX = 0;
  279. X    fileListX = 0;
  280. X    /* Move them */
  281. X    XtMoveWidget(FCDirMenuButton(fcw),menuButtonX,menuButtonY);
  282. X    XtMoveWidget(FCFileViewport(fcw),fileListX,fileListY);
  283. X    /* Resize them */
  284. X    XtResizeWidget(FCDirMenuButton(fcw),menuButtonW,menuButtonH,
  285. X           CoreBorderWidth(FCDirMenuButton(fcw)));
  286. X    XtResizeWidget(FCFileViewport(fcw),fileListW,fileListH,
  287. X           CoreBorderWidth(FCFileViewport(fcw)));
  288. } /* End ChildrenUpdate */
  289. X
  290. /*---------------------------------------------------------------------------*
  291. X
  292. X                 I N T E R N A L    C A L L B A C K S
  293. X
  294. X *---------------------------------------------------------------------------*/
  295. X
  296. /*---------------------------------------------------------------------------*
  297. X
  298. X    DirectoryCallback(w,client_data,call_data)
  299. X
  300. X    This is called when the user selects an ancestor directory from
  301. X    the menu. The argument "w" is the selected object (hence the two
  302. X    calls to XtParent()) and "client_data" is it's index in the menu.
  303. X
  304. X *---------------------------------------------------------------------------*/
  305. X
  306. /*ARGSUSED*/
  307. static void
  308. DirectoryCallback(w,client_data,call_data)
  309. Widget w;
  310. XXtPointer client_data;    /* index */
  311. XXtPointer call_data;    /* not used */
  312. {
  313. X    int index = (int)client_data;
  314. X    XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)XtParent(XtParent(w));
  315. X    int i;
  316. X
  317. X    strcpy(FCCurrentDirectory(fcw),"/");
  318. X    for (i = 1; i <= index; i++) {
  319. X    strcat(FCCurrentDirectory(fcw),FCDirNames(fcw)[i]);
  320. X    strcat(FCCurrentDirectory(fcw),"/");
  321. X    }
  322. X    Chdir(fcw);
  323. } /* End DirectoryCallback */
  324. X
  325. /*---------------------------------------------------------------------------*
  326. X
  327. X    FileCallback(w,client_data,call_data)
  328. X
  329. X    This is called when the user selects a file in the fileList.
  330. X    The argument "client_data" is the FileChooser widget, "call_data"
  331. X    is a pointer to the standard List widget callback information.
  332. X
  333. X *---------------------------------------------------------------------------*/
  334. X
  335. /*ARGSUSED*/
  336. static void
  337. FileCallback(w,client_data,call_data)
  338. Widget w;
  339. XXtPointer client_data;    /* fcw */
  340. XXtPointer call_data;    /* return struct */
  341. {
  342. X    XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)client_data;
  343. X    XawListReturnStruct *ret = (XawListReturnStruct *)call_data;
  344. X
  345. X    if (ret->list_index == -1) {
  346. X    UnselectAll(fcw);        /* Click On Blank Space */
  347. X    Notify(fcw);
  348. X    } else {
  349. X    SelectFileByIndex(fcw,ret->list_index);
  350. X    }
  351. } /* End FileCallback */
  352. X
  353. /*---------------------------------------------------------------------------*
  354. X
  355. X             I N T E R N A L    S U P P O R T    R O U T I N E S
  356. X
  357. X *---------------------------------------------------------------------------*/
  358. X
  359. static void
  360. SelectFileByIndex(fcw,index)
  361. XXfwfFileChooserWidget fcw;
  362. int index;
  363. {
  364. X    DirEntry *dir_entry;
  365. X
  366. X    DirectoryMgrGotoItem(FCDirMgr(fcw),index);
  367. X    if ((dir_entry=DirectoryMgrCurrentEntry(FCDirMgr(fcw))) == NULL) {
  368. X    fprintf(stderr,"SelectFileByIndex: Entry %d invalid\n",index);
  369. X    XtAppErrorMsg(XtWidgetToApplicationContext((Widget)fcw),
  370. X              "selectFailed","SelectFileByIndex","XfwfError",
  371. X              "FileChooser: SelectFileByIndex failed.",
  372. X              (String*)NULL,(Cardinal*)NULL);
  373. X    }
  374. X    if (DirEntryIsDir(dir_entry) || DirEntryIsDirectoryLink(dir_entry)) {
  375. X    strcat(FCCurrentDirectory(fcw),DirEntryFileName(dir_entry));
  376. X    Chdir(fcw);
  377. X    } else if (!DirEntryIsBrokenLink(dir_entry)) {    /* File */
  378. X    strcpy(FCCurrentFile(fcw),DirEntryFileName(dir_entry));
  379. X    XawListHighlight(FCFileList(fcw),index);
  380. X    Notify(fcw);
  381. X    } else {                        /* Broken Link */
  382. X    XBell(XtDisplay(fcw),0);
  383. X    UnselectAll(fcw);
  384. X    }
  385. } /* End SelectFileByIndex */
  386. X
  387. static Boolean
  388. SelectFileByName(fcw,name)
  389. XXfwfFileChooserWidget fcw;
  390. char *name;
  391. {
  392. X    if (DirectoryMgrGotoNamedItem(FCDirMgr(fcw),name) == FALSE) {
  393. X    return(False);
  394. X    }
  395. X    SelectFileByIndex(fcw,DirectoryMgrCurrentIndex(FCDirMgr(fcw)));
  396. X    return(True);
  397. } /* End SelectFileByName */
  398. X
  399. static void
  400. UnselectAll(fcw)
  401. XXfwfFileChooserWidget fcw;
  402. {
  403. X    Boolean selected = FCCurrentFile(fcw)[0] != '\0';
  404. X
  405. X    FCCurrentFile(fcw)[0] = '\0';
  406. X    XawListUnhighlight(FCFileList(fcw));
  407. X    if (selected)
  408. X    Notify(fcw);
  409. } /* End UnselectAll */
  410. X
  411. static void
  412. Notify(fcw)
  413. XXfwfFileChooserWidget fcw;
  414. {
  415. X    XfwfFileChooserReturnStruct ret;
  416. X
  417. X    if (FCCurrentFile(fcw)[0] != '\0') {
  418. X    ret.directory = FCCurrentDirectory(fcw);
  419. X    ret.file = FCCurrentFile(fcw);
  420. X    } else {
  421. X    ret.directory = NULL;
  422. X    ret.file = NULL;
  423. X    }
  424. X    XtCallCallbacks((Widget)fcw,XtNcallback,(XtPointer)&ret);
  425. } /* End Notify */
  426. X
  427. /*---------------------------------------------------------------------------*
  428. X
  429. X    GotoDeepestLegalDirectory(fcw)
  430. X
  431. X    This function takes a FileChooser widget <fcw> and modifies the
  432. X    directory string in FCCurrentDirectory(fcw) to be the deepest
  433. X    legal directory above the string.  Partial or incorrect directory
  434. X    names are stripped starting at the end.
  435. X
  436. X    It then calls UpdateLists() to reset the information dislayed in
  437. X    the FileChooser.
  438. X
  439. X *---------------------------------------------------------------------------*/
  440. X
  441. static void
  442. GotoDeepestLegalDirectory(fcw)
  443. XXfwfFileChooserWidget fcw;
  444. {
  445. X    char *dir,*end;
  446. X    char temp[MAXPATHLEN + 2];
  447. X
  448. X    dir = FCCurrentDirectory(fcw);
  449. X    for (end=dir; *end != '\0'; ++end)
  450. X    /*EMPTY*/;
  451. X    while (1) {
  452. X    if (DirectoryPathExpand(dir,temp) == NULL) {
  453. X        while (*end != '/' && end != dir) {
  454. X        end -= 1;
  455. X        }
  456. X        *end = '\0';
  457. X    } else {
  458. X        strcpy(FCCurrentDirectory(fcw),temp);
  459. X        break;
  460. X    }
  461. X    }
  462. X    UnselectAll(fcw);
  463. X    UpdateLists(fcw);
  464. } /* End GotoDeepestLegalDirectory */
  465. X
  466. /*---------------------------------------------------------------------------*
  467. X
  468. X    UpdateLists(fcw)
  469. X
  470. X    This routine resets the information displayed in a FileChooser
  471. X    widget by doing the following:
  472. X    1. It changes the cursor to the value of the "busyCursor" resource.
  473. X    2. The old directory manager (FCDirMgr(fcw)) is closed and a
  474. X       new one opened based on the value of FCCurrentDirectory(fcw).
  475. X    3. Any old string arrays are freed, and any existing directory
  476. X       menu is destroyed.
  477. X    4. A new array of strings (FCFileNames(fcw)) is allocated and filled
  478. X       with the names of the files in the directory, then this array
  479. X       is used to set what is displayed in the FCFileList(fcw) widget.
  480. X    5. A new array of strings (FCDirNames(fcw)) is allocated and filled
  481. X       with the names of the ancestor directories. These are also used
  482. X       to create a new FCDirMenu(fcw), and the label FCDirMenuButton(fcw)
  483. X       is set to the name of the directory.
  484. X    6. Finally, the cursor is restored.
  485. X
  486. X *---------------------------------------------------------------------------*/
  487. X
  488. static void
  489. UpdateLists(fcw)
  490. XXfwfFileChooserWidget fcw;
  491. {
  492. X    Arg args[1];
  493. X    int i,count;
  494. X    char *dir,*start;
  495. X    DirEntry *dir_entry;
  496. X    char temp[MAXPATHLEN + 2];
  497. X    Widget menuItem;
  498. X
  499. X    if (XtIsRealized((Widget)fcw)) {
  500. X    /* This is puke-ola. */
  501. X    XDefineCursor(XtDisplay(fcw),XtWindow(fcw),FCBusyCursor(fcw));
  502. X    XDefineCursor(XtDisplay(fcw),XtWindow(FCFileList(fcw)),
  503. X              FCBusyCursor(fcw));
  504. X    XDefineCursor(XtDisplay(fcw),XtWindow(FCDirMenuButton(fcw)),
  505. X              FCBusyCursor(fcw));
  506. X    XFlush(XtDisplay(fcw));
  507. X    }
  508. X    if (FCDirMgr(fcw))
  509. X    DirectoryMgrClose(FCDirMgr(fcw));
  510. X    FCDirMgr(fcw) = DirectoryMgrSimpleOpen(FCCurrentDirectory(fcw),
  511. X                       FCSortMode(fcw),FCPattern(fcw));
  512. X
  513. X    /* Throw away old info */
  514. X    if (FCFileNames(fcw) != NULL) {
  515. X    for (i = 0; i < FCNumFileNames(fcw); i++)
  516. X        XtFree(FCFileNames(fcw)[i]);
  517. X    XtFree((char *)FCFileNames(fcw));
  518. X    }
  519. X    if (FCDirNames(fcw) != NULL) {
  520. X    for (i = 0; i < FCNumDirNames(fcw); i++)
  521. X        XtFree(FCDirNames(fcw)[i]);
  522. X    XtFree((char *)FCDirNames(fcw));
  523. X    }
  524. X    if (FCDirMenu(fcw) != NULL)
  525. X    XtDestroyWidget(FCDirMenu(fcw));
  526. X
  527. X    /* Count how many files and dirs we have now */
  528. X    FCNumFileNames(fcw) = DirectoryMgrFilteredCount(FCDirMgr(fcw));
  529. X    FCNumDirNames(fcw) = 1;
  530. X    for (dir=FCCurrentDirectory(fcw)+1; *dir != '\0'; dir++) {
  531. X    if (*dir == '/') 
  532. X        FCNumDirNames(fcw) += 1;
  533. X    }
  534. X
  535. X    /* Make the array of filenames and set the fileList widget */
  536. X    FCFileNames(fcw) = (char **)XtCalloc(FCNumFileNames(fcw)+1,sizeof(char *));
  537. X    for (i=0; i < FCNumFileNames(fcw); i++) {
  538. X    dir_entry = DirectoryMgrNextEntry(FCDirMgr(fcw));
  539. X    if (dir_entry == NULL)
  540. X        XtError("Inconsistent Directory");
  541. X    strcpy(temp,DirEntryFileName(dir_entry));
  542. X    if (DirEntryIsDir(dir_entry))
  543. X        strcat(temp,"/");
  544. X    else if (DirEntryIsBrokenLink(dir_entry))
  545. X        strcat(temp," X");
  546. X    else if (DirEntryIsDirectoryLink(dir_entry))
  547. X        strcat(temp,"/");
  548. X    else if (DirEntryIsSymLink(dir_entry))
  549. X        strcat(temp," @");
  550. X    FCFileNames(fcw)[i] = XtNewString(temp);
  551. X    }
  552. X    FCFileNames(fcw)[i] = NULL;
  553. X    XawListChange(FCFileList(fcw),FCFileNames(fcw),FCNumFileNames(fcw),0,True);
  554. X
  555. X    /* Make the array of dirnames and build a new dirMenu widget */
  556. X    FCDirNames(fcw) = (char **)XtCalloc(FCNumDirNames(fcw)+1,sizeof(char *));
  557. X    FCDirNames(fcw)[0] = XtNewString("/");
  558. X    FCDirMenu(fcw) = XtCreatePopupShell(FC_DIR_MENU_NAME,simpleMenuWidgetClass,
  559. X                    (Widget)fcw,NULL,0);
  560. X    menuItem = XtCreateManagedWidget("/",smeBSBObjectClass,FCDirMenu(fcw),
  561. X                     NULL,0);
  562. X    XtAddCallback(menuItem,XtNcallback,DirectoryCallback,(XtPointer)0);
  563. X    start = FCCurrentDirectory(fcw);
  564. X    for (i = 1; i < FCNumDirNames(fcw); i++) {
  565. X    while (*start != '\0' && *start == '/')
  566. X        start += 1;
  567. X    count = 0;
  568. X    while (*start != '\0' && *start != '/')
  569. X        temp[count++] = *start++;
  570. X    temp[count] = '\0';
  571. X    FCDirNames(fcw)[i] = XtNewString(temp);
  572. X    XtSetArg(args[0],XtNlabel,temp);
  573. X    menuItem = XtCreateManagedWidget("dirMenuItem",smeBSBObjectClass,
  574. X                     FCDirMenu(fcw),args,1);
  575. X        XtAddCallback(menuItem,XtNcallback,DirectoryCallback,(XtPointer)i);
  576. X    }
  577. X    XtSetArg(args[0],XtNlabel,FCCurrentDirectory(fcw));
  578. X    XtSetValues(FCDirMenuButton(fcw),args,1);
  579. X    if (XtIsRealized((Widget)fcw)) {
  580. X    XUndefineCursor(XtDisplay(fcw),XtWindow(fcw));
  581. X    XUndefineCursor(XtDisplay(fcw),XtWindow(FCFileList(fcw)));
  582. X    XUndefineCursor(XtDisplay(fcw),XtWindow(FCDirMenuButton(fcw)));
  583. X    }
  584. } /* End UpdateLists */
  585. X
  586. static void Chdir(fcw)
  587. XXfwfFileChooserWidget fcw;
  588. {
  589. X    GotoDeepestLegalDirectory(fcw);
  590. X    ChildrenUpdate(fcw);
  591. } /* End Chdir */
  592. X
  593. /*---------------------------------------------------------------------------*
  594. X
  595. X                    E X T E R N A L    R O U T I N E S
  596. X
  597. X *---------------------------------------------------------------------------*/
  598. X
  599. void
  600. XXfwfFileChooserChangeDirectory(fcw,dir)
  601. XXfwfFileChooserWidget fcw;
  602. char *dir;
  603. {
  604. X    strcpy(FCCurrentDirectory(fcw),dir);
  605. X    Chdir(fcw);
  606. } /* End XfwfFileChooserChangeDirectory */
  607. X
  608. void
  609. XXfwfFileChooserRefresh(fcw)
  610. XXfwfFileChooserWidget fcw;
  611. {
  612. X    XfwfFileChooserChangeDirectory(fcw,".");
  613. } /* End XfwfFileChooserRefresh */
  614. X
  615. char *
  616. XXfwfFileChooserCurrentDirectory(fcw)
  617. XXfwfFileChooserWidget fcw;
  618. {
  619. X    return(FCCurrentDirectory(fcw));
  620. } /* End XfwfFileChooserCurrentDirectory */
  621. X
  622. char *
  623. XXfwfFileChooserCurrentFile(fcw)
  624. XXfwfFileChooserWidget fcw;
  625. {
  626. X    return(FCCurrentFile(fcw));
  627. } /* End XfwfFileChooserCurrentFile */
  628. X
  629. SHAR_EOF
  630. echo 'File xarchie-2.0.6/FWF/FileChooser/FChooser.c is complete' &&
  631. chmod 0644 xarchie-2.0.6/FWF/FileChooser/FChooser.c ||
  632. echo 'restore of xarchie-2.0.6/FWF/FileChooser/FChooser.c failed'
  633. Wc_c="`wc -c < 'xarchie-2.0.6/FWF/FileChooser/FChooser.c'`"
  634. test 28282 -eq "$Wc_c" ||
  635.     echo 'xarchie-2.0.6/FWF/FileChooser/FChooser.c: original size 28282, current size' "$Wc_c"
  636. rm -f _shar_wnt_.tmp
  637. fi
  638. # ============= xarchie-2.0.6/FWF/FileChooser/FChooser.h ==============
  639. if test -f 'xarchie-2.0.6/FWF/FileChooser/FChooser.h' -a X"$1" != X"-c"; then
  640.     echo 'x - skipping xarchie-2.0.6/FWF/FileChooser/FChooser.h (File already exists)'
  641.     rm -f _shar_wnt_.tmp
  642. else
  643. > _shar_wnt_.tmp
  644. echo 'x - extracting xarchie-2.0.6/FWF/FileChooser/FChooser.h (Text)'
  645. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/FWF/FileChooser/FChooser.h' &&
  646. /*
  647. X * FChooser.h : Public header file for the FileChooser widget
  648. X *
  649. X * George Ferguson, ferguson@cs.rochester.edu, 21 Jan 1993.
  650. X *
  651. X * This code is derived from the FileSelector widget by Brian Totty,
  652. X * hence the following copyright applies:
  653. X *
  654. X * Copyright 1990,1991,1992 Brian Totty
  655. X * 
  656. X * Permission to use, copy, modify, distribute, and sell this software
  657. X * and its documentation for any purpose is hereby granted without fee,
  658. X * provided that the above copyright notice appears in all copies and that
  659. X * both that copyright notice and this permission notice appear in
  660. X * supporting documentation, and that the name of Brian Totty or
  661. X * University of Illinois not be used in advertising or publicity
  662. X * pertaining to distribution of the software without specific, written
  663. X * prior permission.  Brian Totty and University of Illinois make no
  664. X * representations about the suitability of this software for any
  665. X * purpose.  It is provided "as is" without express or implied warranty.
  666. X *
  667. X * Brian Totty and University of Illinois disclaim all warranties with
  668. X * regard to this software, including all implied warranties of
  669. X * merchantability and fitness, in no event shall Brian Totty or
  670. X * University of Illinois be liable for any special, indirect or
  671. X * consequential damages or any damages whatsoever resulting from loss of
  672. X * use, data or profits, whether in an action of contract, negligence or
  673. X * other tortious action, arising out of or in connection with the use or
  674. X * performance of this software.
  675. X *
  676. X * Author:
  677. X *     Brian Totty
  678. X *     Department of Computer Science
  679. X *     University Of Illinois at Urbana-Champaign
  680. X *    1304 West Springfield Avenue
  681. X *     Urbana, IL 61801
  682. X * 
  683. X *     totty@cs.uiuc.edu
  684. X *     
  685. X */ 
  686. X
  687. #ifndef _FCHOOSER_H
  688. #define _FCHOOSER_H
  689. X
  690. #include <DirMgr.h>
  691. X
  692. extern WidgetClass xfwfFileChooserWidgetClass;
  693. X
  694. typedef struct _XfwfFileChooserClassRec    *XfwfFileChooserWidgetClass;
  695. typedef struct _XfwfFileChooserRec    *XfwfFileChooserWidget;
  696. X
  697. #define    XtNcurrentDirectory        "currentDirectory"
  698. #define    XtNcurrentFile            "currentFile"
  699. #define    XtNsortMode            "sortMode"
  700. #define    XtNpattern            "pattern"
  701. X
  702. #define    XtCPathname            "Pathname"
  703. #define    XtCFilename            "Filename"
  704. X
  705. typedef struct _XfwfFileChooserReturnStruct
  706. {
  707. X    char *directory;
  708. X    char *file;
  709. } XfwfFileChooserReturnStruct;
  710. X
  711. /*---------------------------------------------------------------------------*
  712. X
  713. X                  E X T E R N A L    F U N C T I O N S
  714. X
  715. X *---------------------------------------------------------------------------*/
  716. X
  717. #if (!NeedFunctionPrototypes)
  718. X
  719. void    XfwfFileChooserChangeDirectory();
  720. void    XfwfFileChooserRefresh();
  721. char    *XfwfFileChooserCurrentDirectory();
  722. char    *XfwfFileChooserCurrentFile();
  723. X
  724. #else
  725. X
  726. void    XfwfFileChooserChangeDirectory(XfwfFileChooserWidget fcw, char *dir);
  727. void    XfwfFileChooserRefresh(XfwfFileChooserWidget fcw);
  728. char    *XfwfFileChooserCurrentDirectory(XfwfFileChooserWidget fcw);
  729. char    *XfwfFileChooserCurrentFile(XfwfFileChooserWidget fcw);
  730. X
  731. #endif /* !NeedFunctionPrototypes */
  732. #endif /* !_FCHOOSER_H */
  733. SHAR_EOF
  734. chmod 0644 xarchie-2.0.6/FWF/FileChooser/FChooser.h ||
  735. echo 'restore of xarchie-2.0.6/FWF/FileChooser/FChooser.h failed'
  736. Wc_c="`wc -c < 'xarchie-2.0.6/FWF/FileChooser/FChooser.h'`"
  737. test 3001 -eq "$Wc_c" ||
  738.     echo 'xarchie-2.0.6/FWF/FileChooser/FChooser.h: original size 3001, current size' "$Wc_c"
  739. rm -f _shar_wnt_.tmp
  740. fi
  741. # ============= xarchie-2.0.6/FWF/FileChooser/FChooser.man ==============
  742. if test -f 'xarchie-2.0.6/FWF/FileChooser/FChooser.man' -a X"$1" != X"-c"; then
  743.     echo 'x - skipping xarchie-2.0.6/FWF/FileChooser/FChooser.man (File already exists)'
  744.     rm -f _shar_wnt_.tmp
  745. else
  746. > _shar_wnt_.tmp
  747. echo 'x - extracting xarchie-2.0.6/FWF/FileChooser/FChooser.man (Text)'
  748. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/FWF/FileChooser/FChooser.man' &&
  749. '\" t
  750. .TH "FileChooser" "3" "28 Jan 1993" "Version 1.0" "Free Widget Foundation"
  751. .SH Name
  752. FileChooser \- Another widget for choosing a file
  753. .SH Synopsis
  754. .nf
  755. #include <Xfwf/FChooser.h>
  756. X
  757. widget = XtCreateManagedWidget(name, xfwfFileChooserWidgetClass, ...);
  758. .fi
  759. .SH Class Hierarchy
  760. The following describes the classes from which XfwfFileChooser
  761. inherits resources:
  762. .ce
  763. Core-->Composite-->XfwfFileChooser
  764. .SH Widget Hierarchy
  765. .PP
  766. The XfwfFileChooser widget is a composite widget with the following
  767. internal structure:
  768. .RS 5
  769. .nf
  770. MenuButton dirMenuButton
  771. SimpleMenu dirMenu
  772. Viewport fileViewport
  773. X    List fileList
  774. .fi
  775. .RE
  776. You can use these names to specify resources for FileChooser
  777. children, or use XtNameToWidget() to locate them programmatically.
  778. .SH Description
  779. XXfwfFileChooser provides a list of files in the current directory, and
  780. a dynamically-updated menu of ancestor directories. A file can be
  781. selected from the list, or a directory can be selected from either the
  782. list (a sub-directory) or the menu (an ancestor directory). When a
  783. directory is selected (from the menu or the list), the list is
  784. re-filled with the contents of the new directory.  Callback procedures
  785. are called whenever the selected file or directory changes.
  786. .PP
  787. This widget is meant to function within, say, a Form, which would
  788. provide buttons and perhaps a Text item for entering new filenames.
  789. In this sense, it is different from the XfwfFileSelector widget that
  790. provides builtin additional functionality but at the cost of more
  791. screen real estate and some inflexibility in terms of input policy.
  792. The sample program distributed with the widget presents an example of
  793. such usage.
  794. .PP
  795. The source code in the Dir directory of the FWF distribution contains
  796. system-independent file listing functions that are required by 
  797. FileChooser.
  798. .SH Resources
  799. In addition to the resources defined by superclasses, this widget
  800. defines the following:
  801. .TS
  802. tab(/) ;
  803. lB lB lB lB.
  804. Name/Class/Type/Default
  805. .T&
  806. lB l l l.
  807. XXtNwidth/Width/Dimension/250
  808. XXtNheight/Height/Dimension/500
  809. XXtNbackground/Background/Pixel/XtDefaultBackground
  810. XXtNcallback/Callback/Callback/NULL
  811. XXtNcurrentDirectory/Pathname/String/current directory
  812. XXtNcurrentFile/Filename/String/NULL
  813. XXtNsortMode/Int/Int/2
  814. XXtNpattern/Filename/String/NULL
  815. .TE
  816. .PP
  817. The XtNcurrentDirectory and XtNcurrentFile resources can be used to
  818. specify the initial contents and selection of the XfwfFileChooser
  819. widget. Changing them after creation results in the contents being
  820. recomputed appropriately and the callbacks being invoked (see below).
  821. .PP
  822. The filter pattern is specified in the string XtNpattern.  The method
  823. used to sort the file list is specified in XtNsortMode.  The sort mode
  824. is encoded as an integer.  The integers are defined in the DirMgr.h
  825. file which is part of the libDir directory management package included
  826. in the FWF release.  Sample XtNsortMode values are depicted below:
  827. .RS 5
  828. .TS
  829. tab(/) ;
  830. lB lB lB.
  831. XXtNsortMode Name/Value/Sort By
  832. .T&
  833. lB l l.
  834. SORT_NONE/0/No sorting
  835. SORT_NAME/1/File name
  836. SORT_NAME_DIRS_FIRST/2/File name, directories first
  837. SORT_SIZE_ASCENDING/3/Ascending file size
  838. SORT_SIZE_DESCENDING/4/Descending file size
  839. SORT_ACCESS_ASCENDING/5/Ascending access time
  840. SORT_ACCESS_DESCENDING/6/Descending access time
  841. .TE
  842. .RE
  843. .ne 4
  844. .SH Callbacks
  845. .PP
  846. The XfwfFileChooser widget provides a single callback list,
  847. XXtNcallback. This callback is called whenever the contents of the
  848. XXfwfFileChooser change, either because the user selected a file or
  849. directory (or selected the background, which unselects any selected
  850. file) or because the XtNcurrentDirectry or XtNcurrentFile resources
  851. were changed programmatically. The call_data parameter of the call
  852. contains an instance of the following structure:
  853. .sp
  854. .RS 5
  855. .nf
  856. typedef struct _XfwfFileChooserReturnStruct
  857. {
  858. X        String directory;
  859. X        String file;
  860. } XfwfFileChooserReturnStruct;
  861. .fi
  862. .RE
  863. .sp
  864. The "file" member is NULL if no file is selected in the fileList.
  865. .RE
  866. .SH Public Functions
  867. .nf
  868. .ta 3i
  869. void XfwfFileChooserChangeDirectory(fcw,dir)
  870. XXfwfFileChooserWidget fcw;
  871. char *dir;
  872. .fi
  873. .sp
  874. .RS 5
  875. This routine changes the current directory of the XfwfFileChooser
  876. widget \fIfcw\fP to be \fIdir\fP, and invokes the callbacks.
  877. .RE
  878. .sp
  879. .nf
  880. void XfwfFileChooserRefresh(fcw)
  881. XXfwfFileChooserWidget fcw;
  882. .fi
  883. .sp
  884. .RS 5
  885. This routine causes the XfwfFileChooser widget \fIfcw\fP to re-read
  886. the current directory, refreshing the widget.  Changes to the file
  887. system will not automatically propogate to the widget.  This routine
  888. forces the refresh.
  889. .RE
  890. .sp
  891. .nf
  892. void XfwfFileChooserCurrentDirectory(fcw)
  893. XXfwfFileChooserWidget fcw;
  894. .fi
  895. .sp
  896. .RS 5
  897. Returns the value of the XtNcurrentDirectory resource for the
  898. XXfwfFileChooser widget \fIfcw\fP.
  899. .RE
  900. .sp
  901. .nf
  902. void XfwfFileChooserCurrentFile(fcw)
  903. XXfwfFileChooserWidget fcw;
  904. .fi
  905. .sp
  906. .RS 5
  907. Returns the value of the XtNcurrentFile resource for the
  908. XXfwfFileChooser widget \fIfcw\fP.
  909. .RE
  910. .ne 4
  911. .SH Restrictions
  912. .PP
  913. The filter function is currently limited to shell-style pattern matching,
  914. even though the underlying directory management functions support arbitrary
  915. filter functions.
  916. .PP
  917. Layout parameters of the XfwfFileChooser widget's children cannot be
  918. changed, but other resources can using the names described above under
  919. "Widget Hierarchy".
  920. .PP
  921. The slider bars of the viewports do not "snap back" when a smaller
  922. directory is loaded, and the sliders are down at the bottom.
  923. .PP
  924. The stupid List widget doesn't notify when the background is selected,
  925. although it unhighlights the item. Blech. This means your callbacks
  926. won't always be called when you think they should.
  927. .SH Author
  928. .PP
  929. George Ferguson, ferguson@cs.rochester.edu.
  930. .PP
  931. Based on FileSelector by:
  932. .RS 5
  933. .nf
  934. Brian Totty, \fItotty@cs.uiuc.edu\fR
  935. Department of Computer Science,
  936. University of Illinois at Urbana-Champaign
  937. 1304 W. Springfield Avenue
  938. Urbana, IL 61801
  939. .fi
  940. .RE
  941. SHAR_EOF
  942. chmod 0644 xarchie-2.0.6/FWF/FileChooser/FChooser.man ||
  943. echo 'restore of xarchie-2.0.6/FWF/FileChooser/FChooser.man failed'
  944. Wc_c="`wc -c < 'xarchie-2.0.6/FWF/FileChooser/FChooser.man'`"
  945. test 5827 -eq "$Wc_c" ||
  946.     echo 'xarchie-2.0.6/FWF/FileChooser/FChooser.man: original size 5827, current size' "$Wc_c"
  947. rm -f _shar_wnt_.tmp
  948. fi
  949. # ============= xarchie-2.0.6/FWF/FileChooser/FChooserP.h ==============
  950. if test -f 'xarchie-2.0.6/FWF/FileChooser/FChooserP.h' -a X"$1" != X"-c"; then
  951.     echo 'x - skipping xarchie-2.0.6/FWF/FileChooser/FChooserP.h (File already exists)'
  952.     rm -f _shar_wnt_.tmp
  953. else
  954. > _shar_wnt_.tmp
  955. echo 'x - extracting xarchie-2.0.6/FWF/FileChooser/FChooserP.h (Text)'
  956. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/FWF/FileChooser/FChooserP.h' &&
  957. /*
  958. X * FChooserP.h : Private header file for the FileChooser widget
  959. X *
  960. X * George Ferguson, ferguson@cs.rochester.edu, 21 Jan 1993.
  961. X *
  962. X * This code is derived from the FileSelector widget by Brian Totty,
  963. X * hence the following copyright applies:
  964. X *
  965. X * Copyright 1990,1991,1992 Brian Totty
  966. X * 
  967. X * Permission to use, copy, modify, distribute, and sell this software
  968. X * and its documentation for any purpose is hereby granted without fee,
  969. X * provided that the above copyright notice appears in all copies and that
  970. X * both that copyright notice and this permission notice appear in
  971. X * supporting documentation, and that the name of Brian Totty or
  972. X * University of Illinois not be used in advertising or publicity
  973. X * pertaining to distribution of the software without specific, written
  974. X * prior permission.  Brian Totty and University of Illinois make no
  975. X * representations about the suitability of this software for any
  976. X * purpose.  It is provided "as is" without express or implied warranty.
  977. X *
  978. X * Brian Totty and University of Illinois disclaim all warranties with
  979. X * regard to this software, including all implied warranties of
  980. X * merchantability and fitness, in no event shall Brian Totty or
  981. X * University of Illinois be liable for any special, indirect or
  982. X * consequential damages or any damages whatsoever resulting from loss of
  983. X * use, data or profits, whether in an action of contract, negligence or
  984. X * other tortious action, arising out of or in connection with the use or
  985. X * performance of this software.
  986. X *
  987. X * Author:
  988. X *     Brian Totty
  989. X *     Department of Computer Science
  990. X *     University Of Illinois at Urbana-Champaign
  991. X *    1304 West Springfield Avenue
  992. X *     Urbana, IL 61801
  993. X * 
  994. X *     totty@cs.uiuc.edu
  995. X *     
  996. X */ 
  997. X
  998. #ifndef    _FCHOOSERP_H
  999. #define    _FCHOOSERP_H
  1000. X
  1001. #include <DirMgr.h>
  1002. X
  1003. #include <X11/CoreP.h>
  1004. #include <X11/Core.h>
  1005. X
  1006. /*---------------------------------------------------------------------------*
  1007. X
  1008. X                C O N S T A N T S
  1009. X
  1010. X *---------------------------------------------------------------------------*/
  1011. X
  1012. #define FC_DIR_MENU_NAME    "dirMenu"
  1013. #define FC_DIR_MENU_BUTTON_NAME    "dirMenuButton"
  1014. #define FC_FILE_VIEWPORT_NAME    "fileViewport"
  1015. #define FC_FILE_LIST_NAME    "fileList"
  1016. X
  1017. /*---------------------------------------------------------------------------*
  1018. X
  1019. X      S T R U C T U R E   &   W I D G E T    A C C E S S    M A C R O S
  1020. X
  1021. X *---------------------------------------------------------------------------*/
  1022. X
  1023. #define    FCCorePart(w)        (&((w)->core))
  1024. #define    FCCompositePart(w)    (&((w)->composite))
  1025. #define    FCFCPart(w)        (&((w)->fileChooser))
  1026. X
  1027. #define    FCDirMgr(w)        (FCFCPart(w)->dir_mgr)
  1028. #define    FCDirMenu(w)        (FCFCPart(w)->dir_menu)
  1029. #define    FCDirMenuButton(w)    (FCFCPart(w)->dir_menu_button)
  1030. #define    FCFileViewport(w)    (FCFCPart(w)->file_viewport)
  1031. #define    FCFileList(w)        (FCFCPart(w)->file_list)
  1032. #define    FCCurrentDirectory(w)    (FCFCPart(w)->current_dir)
  1033. #define    FCCurrentFile(w)    (FCFCPart(w)->current_file)
  1034. #define    FCDirNames(w)        (FCFCPart(w)->dir_names)
  1035. #define    FCNumDirNames(w)    (FCFCPart(w)->num_dir_names)
  1036. #define    FCFileNames(w)        (FCFCPart(w)->file_names)
  1037. #define    FCNumFileNames(w)    (FCFCPart(w)->num_file_names)
  1038. #define    FCBusyCursor(w)        (FCFCPart(w)->busy_cursor)
  1039. #define    FCSortMode(w)        (FCFCPart(w)->sort_mode)
  1040. #define    FCPattern(w)        (FCFCPart(w)->pattern)
  1041. X
  1042. #define CoreWidth(w)            ((w)->core.width)
  1043. #define CoreHeight(w)           ((w)->core.height)
  1044. #define CoreBorderWidth(w)      ((w)->core.border_width)
  1045. X
  1046. /*---------------------------------------------------------------------------*
  1047. X
  1048. X           W I D G E T    S T R U C T U R E    D E F I N I T I O N
  1049. X
  1050. X *---------------------------------------------------------------------------*/
  1051. X
  1052. typedef struct
  1053. {
  1054. X    DIRECTORY_MGR    *dir_mgr;
  1055. X    Widget        dir_menu;
  1056. X    Widget        dir_menu_button;
  1057. X    Widget        file_viewport;
  1058. X    Widget        file_list;
  1059. X    char        *current_dir;
  1060. X    char        *current_file;
  1061. X    char        **dir_names;
  1062. X    int        num_dir_names;
  1063. X    char        **file_names;
  1064. X    int        num_file_names;
  1065. X    XtCallbackList    callbacks;
  1066. X    Cursor        busy_cursor;
  1067. X    int        sort_mode;
  1068. X    char        *pattern;
  1069. } XfwfFileChooserPart;
  1070. X
  1071. typedef struct _XfwfFileChooserClassPart
  1072. {
  1073. X    int    empty;
  1074. } XfwfFileChooserClassPart;
  1075. X
  1076. typedef struct _XfwfFileChooserClassRec
  1077. {
  1078. X    CoreClassPart            core_class;
  1079. X    CompositeClassPart        composite_class;
  1080. X    XfwfFileChooserClassPart    fileChooser_class;
  1081. } XfwfFileChooserClassRec;
  1082. X
  1083. X    /* This Is What A Widget Instance Points To */
  1084. X
  1085. typedef struct _XfwfFileChooserRec
  1086. {
  1087. X    CorePart        core;
  1088. X    CompositePart        composite;
  1089. X    XfwfFileChooserPart    fileChooser;
  1090. } XfwfFileChooserRec;
  1091. X
  1092. extern XfwfFileChooserClassRec xfwfFileChooserClassRec;
  1093. X
  1094. #endif /* !_FCHOOSERP_H */
  1095. SHAR_EOF
  1096. chmod 0644 xarchie-2.0.6/FWF/FileChooser/FChooserP.h ||
  1097. echo 'restore of xarchie-2.0.6/FWF/FileChooser/FChooserP.h failed'
  1098. Wc_c="`wc -c < 'xarchie-2.0.6/FWF/FileChooser/FChooserP.h'`"
  1099. test 4545 -eq "$Wc_c" ||
  1100.     echo 'xarchie-2.0.6/FWF/FileChooser/FChooserP.h: original size 4545, current size' "$Wc_c"
  1101. rm -f _shar_wnt_.tmp
  1102. fi
  1103. # ============= xarchie-2.0.6/FWF/FileChooser/FChooserT.c ==============
  1104. if test -f 'xarchie-2.0.6/FWF/FileChooser/FChooserT.c' -a X"$1" != X"-c"; then
  1105.     echo 'x - skipping xarchie-2.0.6/FWF/FileChooser/FChooserT.c (File already exists)'
  1106.     rm -f _shar_wnt_.tmp
  1107. else
  1108. > _shar_wnt_.tmp
  1109. echo 'x - extracting xarchie-2.0.6/FWF/FileChooser/FChooserT.c (Text)'
  1110. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/FWF/FileChooser/FChooserT.c' &&
  1111. /*
  1112. X * FChooserT.c : Test program for the FileChooser widget
  1113. X *
  1114. X * George Ferguson, ferguson@cs.rochester.edu, 21 Jan 1993.
  1115. X *
  1116. X * This program illustrates use of a FileChooser together with "Ok"
  1117. X * and "Cancel" buttons, and with a Text widget for new filenames.
  1118. X * Messages are printed to stdout whenever something is selected in
  1119. X * in the FileChooser, or prior to exiting after selecting one of the
  1120. X * buttons. Typing <Return> in the Text window is equivalent to
  1121. X * clicking on "Ok". Note that it is the responsability of the program
  1122. X * to keep the FileChooser and Text widget in sync -- the FileChooser
  1123. X * knows nothing about buttons or Text widgets, deliberately.
  1124. X * I added a menu for changing the sort mode, and another Text item
  1125. X * for changing the filter pattern. I guess that makes this a bit overly
  1126. X * complicated, but I wanted to show everything.
  1127. X */
  1128. #include <stdio.h>
  1129. #include <X11/Intrinsic.h>
  1130. #include <X11/StringDefs.h>
  1131. #include <X11/Shell.h>
  1132. #include <X11/Xaw/Form.h>
  1133. #include <X11/Xaw/Label.h>
  1134. #include <X11/Xaw/Command.h>
  1135. #include <X11/Xaw/MenuButton.h>
  1136. #include <X11/Xaw/SimpleMenu.h>
  1137. #include <X11/Xaw/SmeBSB.h>
  1138. #include <X11/Xaw/AsciiText.h>
  1139. #include <Xfwf/FChooser.h>
  1140. X
  1141. static void selectionChangedCallback();
  1142. static void okCallback(),cancelCallback();
  1143. static void sortModeCallback();
  1144. static void okAction();
  1145. static void filterAction();
  1146. X
  1147. static XtAppContext appContext;
  1148. static Widget toplevel;
  1149. static Widget chooser;
  1150. static Widget filterText,fileText;
  1151. X
  1152. static XtActionsRec actionTable[] = {
  1153. X    { "ok",    okAction },
  1154. X    { "filter",    filterAction },
  1155. };
  1156. X
  1157. static char *sortMenuItemNames[] = {
  1158. X    "None", "Name", "Name, dirs first",
  1159. X    "Size, ascending", "Size, descending",
  1160. X    "Access, ascending", "Access, descending",
  1161. };
  1162. X
  1163. main(argc,argv)
  1164. int argc;
  1165. char **argv;
  1166. {
  1167. X    Widget form,button,menu,menuItem,label;
  1168. X    Arg args[4];
  1169. X    int i;
  1170. X
  1171. X    toplevel = XtAppInitialize(&appContext,"FileChooserTest",
  1172. X                   NULL, 0,&argc,argv,NULL,NULL,0);
  1173. X    XtAppAddActions(appContext,actionTable,XtNumber(actionTable));
  1174. X
  1175. X    form = XtCreateManagedWidget("form",formWidgetClass,toplevel,NULL,0);
  1176. X
  1177. X    XtSetArg(args[0],XtNwidth,300);
  1178. X    chooser = XtCreateManagedWidget("chooser",xfwfFileChooserWidgetClass,
  1179. X                    form,args,1);
  1180. X    XtAddCallback(chooser,XtNcallback,selectionChangedCallback,NULL);
  1181. X
  1182. X    XtSetArg(args[0],XtNlabel,"Ok");
  1183. X    XtSetArg(args[1],XtNfromHoriz,chooser);
  1184. X    XtSetArg(args[2],XtNvertDistance,40);
  1185. X    XtSetArg(args[3],XtNborderWidth,3);
  1186. X    button = XtCreateManagedWidget("ok",commandWidgetClass,form,args,4);
  1187. X    XtAddCallback(button,XtNcallback,okCallback,NULL);
  1188. X
  1189. X    XtSetArg(args[0],XtNlabel,"Cancel");
  1190. X    XtSetArg(args[1],XtNfromHoriz,chooser);
  1191. X    XtSetArg(args[2],XtNfromVert,button);
  1192. X    button = XtCreateManagedWidget("cancel",commandWidgetClass,form,args,3);
  1193. X    XtAddCallback(button,XtNcallback,cancelCallback,NULL);
  1194. X
  1195. X    menu = XtCreatePopupShell("sortMenu",simpleMenuWidgetClass,form,NULL,0);
  1196. X    for (i = 0; i < XtNumber(sortMenuItemNames); i++) {
  1197. X    XtSetArg(args[0],XtNlabel,sortMenuItemNames[i]);
  1198. X    menuItem = XtCreateManagedWidget("sortMenuItem",smeBSBObjectClass,
  1199. X                     menu,args,1);
  1200. X        XtAddCallback(menuItem,XtNcallback,sortModeCallback,(XtPointer)i);
  1201. X    }
  1202. X
  1203. X    XtSetArg(args[0],XtNlabel,"Sort Mode");
  1204. X    XtSetArg(args[1],XtNfromHoriz,chooser);
  1205. X    XtSetArg(args[2],XtNfromVert,button);
  1206. X    XtSetArg(args[3],XtNmenuName,"sortMenu");
  1207. X    button = XtCreateManagedWidget("sort",menuButtonWidgetClass,form,args,4);
  1208. X
  1209. X    XtSetArg(args[0],XtNlabel,"Filter:");
  1210. X    XtSetArg(args[1],XtNborderWidth,0);
  1211. X    XtSetArg(args[2],XtNfromVert,chooser);
  1212. X    label = XtCreateManagedWidget("filterLabel",labelWidgetClass,form,args,3);
  1213. X
  1214. X    XtSetArg(args[0],XtNfromVert,chooser);
  1215. X    XtSetArg(args[1],XtNfromHoriz,label);
  1216. X    XtSetArg(args[2],XtNwidth,300);
  1217. X    XtSetArg(args[3],XtNeditType,XawtextEdit);
  1218. X    filterText = XtCreateManagedWidget("filterText",asciiTextWidgetClass,
  1219. X                       form,args,4); 
  1220. X    XtOverrideTranslations(filterText,
  1221. X         XtParseTranslationTable("<Key>Return: filter()"));
  1222. X
  1223. X    XtSetArg(args[0],XtNlabel,"File:");
  1224. X    XtSetArg(args[1],XtNborderWidth,0);
  1225. X    XtSetArg(args[2],XtNfromVert,label);
  1226. X    label = XtCreateManagedWidget("fileLabel",labelWidgetClass,form,args,3);
  1227. X
  1228. X    XtSetArg(args[0],XtNfromVert,filterText);
  1229. X    XtSetArg(args[1],XtNfromHoriz,label);
  1230. X    XtSetArg(args[2],XtNwidth,300);
  1231. X    XtSetArg(args[3],XtNeditType,XawtextEdit);
  1232. X    fileText = XtCreateManagedWidget("fileText",asciiTextWidgetClass,
  1233. X                     form,args,3);
  1234. X    XtOverrideTranslations(fileText,
  1235. X         XtParseTranslationTable("<Key>Return: ok()"));
  1236. X
  1237. X    XtRealizeWidget(toplevel);
  1238. X    XtAppMainLoop(appContext);
  1239. X    /*NOTREACHED*/
  1240. }
  1241. X
  1242. /*
  1243. X * CALLBACKS:
  1244. X */
  1245. X
  1246. /*ARGSUSED*/
  1247. static void
  1248. selectionChangedCallback(w,client_data,call_data)
  1249. Widget w;
  1250. XXtPointer client_data;    /* not used */
  1251. XXtPointer call_data;    /* return struct */
  1252. {
  1253. X    XfwfFileChooserReturnStruct *ret =
  1254. X    (XfwfFileChooserReturnStruct *)call_data;
  1255. X    Arg args[1];
  1256. X
  1257. X    if (ret->directory == NULL || ret->file == NULL) {
  1258. X    printf("No selection\n");
  1259. X    XtSetArg(args[0],XtNstring,"");
  1260. X    } else {
  1261. X    printf("Directory: \"%s\"\n",ret->directory);
  1262. X    printf("File: \"%s\"\n",ret->file);
  1263. X    XtSetArg(args[0],XtNstring,ret->file);
  1264. X    }
  1265. X    XtSetValues(fileText,args,1);
  1266. }
  1267. X
  1268. /*ARGSUSED*/
  1269. static void
  1270. okCallback(w,client_data,call_data)
  1271. Widget w;
  1272. XXtPointer client_data;    /* not used */
  1273. XXtPointer call_data;    /* not used */
  1274. {
  1275. X    Arg args[1];
  1276. X    char *dir,*file;
  1277. X
  1278. X    printf("Ok!\n");
  1279. X    /* Get directory from chooser (or use XfwfFileChooserCurrentDirectory()) */
  1280. X    XtSetArg(args[0],XtNcurrentDirectory,&dir);
  1281. X    XtGetValues(chooser,args,1);
  1282. X    /* But get file from text item (might differ from XtNcurrentFile) */
  1283. X    XtSetArg(args[0],XtNstring,&file);
  1284. X    XtGetValues(fileText,args,1);
  1285. X    /* Sanity check */
  1286. X    if (dir == NULL || !*dir || file == NULL || !*file) {
  1287. X    printf("You need to select something before saying Ok!\n");
  1288. X    return;
  1289. X    }
  1290. X    /* Everything ok */
  1291. X    printf("Directory: \"%s\"\n",dir);
  1292. X    printf("File: \"%s\"\n",file);
  1293. X    /* Say goodbye */
  1294. X    XtDestroyApplicationContext(appContext);
  1295. X    exit(0);
  1296. }
  1297. X
  1298. /*ARGSUSED*/
  1299. static void
  1300. cancelCallback(w,client_data,call_data)
  1301. Widget w;
  1302. XXtPointer client_data;    /* not used */
  1303. XXtPointer call_data;    /* not used */
  1304. {
  1305. X    printf("Cancel!\n");
  1306. X    XtDestroyApplicationContext(appContext);
  1307. X    exit(0);
  1308. }
  1309. X
  1310. /*ARGSUSED*/
  1311. static void
  1312. sortModeCallback(w,client_data,call_data)
  1313. Widget w;
  1314. XXtPointer client_data;    /* not used */
  1315. XXtPointer call_data;    /* item index == sort mode */
  1316. {
  1317. X    int sortMode = (int)client_data;
  1318. X    Arg args[1];
  1319. X
  1320. X    printf("Setting sort mode to %s\n",sortMenuItemNames[sortMode]);
  1321. X    XtSetArg(args[0],XtNsortMode,sortMode);
  1322. X    XtSetValues(chooser,args,1);
  1323. }
  1324. X
  1325. /*
  1326. X * ACTIONS:
  1327. X */
  1328. X
  1329. /*ARGSUSED*/
  1330. static void
  1331. okAction(w,event,params,num_params)
  1332. Widget w;
  1333. XXEvent *event;
  1334. String *params;
  1335. Cardinal *num_params;
  1336. {
  1337. X    okCallback(NULL,NULL,NULL);
  1338. }
  1339. X
  1340. /*ARGSUSED*/
  1341. static void
  1342. filterAction(w,event,params,num_params)
  1343. Widget w;
  1344. XXEvent *event;
  1345. String *params;
  1346. Cardinal *num_params;
  1347. {
  1348. X    Arg args[1];
  1349. X    char *s;
  1350. X
  1351. X    XtSetArg(args[0],XtNstring,&s);
  1352. X    XtGetValues(filterText,args,1);
  1353. X    printf("Setting filter pattern to \"%s\"\n",s);
  1354. X    XtSetArg(args[0],XtNpattern,s);
  1355. X    XtSetValues(chooser,args,1);
  1356. }
  1357. SHAR_EOF
  1358. chmod 0644 xarchie-2.0.6/FWF/FileChooser/FChooserT.c ||
  1359. echo 'restore of xarchie-2.0.6/FWF/FileChooser/FChooserT.c failed'
  1360. Wc_c="`wc -c < 'xarchie-2.0.6/FWF/FileChooser/FChooserT.c'`"
  1361. test 7260 -eq "$Wc_c" ||
  1362.     echo 'xarchie-2.0.6/FWF/FileChooser/FChooserT.c: original size 7260, current size' "$Wc_c"
  1363. rm -f _shar_wnt_.tmp
  1364. fi
  1365. # ============= xarchie-2.0.6/FWF/FileChooser/FChooserT.man ==============
  1366. if test -f 'xarchie-2.0.6/FWF/FileChooser/FChooserT.man' -a X"$1" != X"-c"; then
  1367.     echo 'x - skipping xarchie-2.0.6/FWF/FileChooser/FChooserT.man (File already exists)'
  1368.     rm -f _shar_wnt_.tmp
  1369. else
  1370. > _shar_wnt_.tmp
  1371. echo 'x - extracting xarchie-2.0.6/FWF/FileChooser/FChooserT.man (Text)'
  1372. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/FWF/FileChooser/FChooserT.man' &&
  1373. .TH "FChooserT" "1" "28 Jan 1993" "Version 1.0" "Free Widget Foundation"
  1374. .SH NAME
  1375. FChooserT \- Test Program For The FileChooser Widget
  1376. .SH DESCRIPTION
  1377. .PP
  1378. .I FChooserT
  1379. is a simple program that creates and tests a FileChooser widget in a
  1380. Form with some other buttons to indicate typical usage.  The source
  1381. may be useful is seeing how the FileChooser widget can be used.
  1382. .PP
  1383. The test program allows you to traverse the directory hierarchy by
  1384. selecting files or directories from the FileChooser by clicking on
  1385. them with the mouse. A message is printed each time the selection
  1386. changes. The current directory is shown in the FileChooser on the
  1387. MenuButton above the list of files. Clicking on it pops up a menu from
  1388. which an ancestor directory can be selected if you want to go up the
  1389. tree. This functionality is all part of the FileChooser itself.
  1390. .PP
  1391. The test program provides some other things to allow you to experiemnt
  1392. with the functionality and to provide usage examples. The Text item
  1393. below the FileChooser labelled "File" is updated whenever you select a
  1394. file, and it can be edited, for example to enter new filenames. The
  1395. "Ok" button exits the program, printing the current directory (from
  1396. the FileChooser) and current file (from the Text item, in case you
  1397. edited it). Hitting Return in the Text item is like clicking on "Ok".
  1398. The "Cancel" button exits without printing anything. The "Sort Mode"
  1399. button allows you change the sorting of files in the FileChooser by
  1400. selecting a different sort mode from the menu. You can change the
  1401. FileChooser's filter pattern (a shell-like "globbing" pattern) by
  1402. typing in the Text item labelled "Filter" and hitting Return.
  1403. .SH AUTHOR
  1404. .PP
  1405. George Ferguson, ferguson@cs.rochester.edu.
  1406. SHAR_EOF
  1407. chmod 0644 xarchie-2.0.6/FWF/FileChooser/FChooserT.man ||
  1408. echo 'restore of xarchie-2.0.6/FWF/FileChooser/FChooserT.man failed'
  1409. Wc_c="`wc -c < 'xarchie-2.0.6/FWF/FileChooser/FChooserT.man'`"
  1410. test 1720 -eq "$Wc_c" ||
  1411.     echo 'xarchie-2.0.6/FWF/FileChooser/FChooserT.man: original size 1720, current size' "$Wc_c"
  1412. rm -f _shar_wnt_.tmp
  1413. fi
  1414. # ============= xarchie-2.0.6/FWF/FileChooser/Imakefile ==============
  1415. if test -f 'xarchie-2.0.6/FWF/FileChooser/Imakefile' -a X"$1" != X"-c"; then
  1416.     echo 'x - skipping xarchie-2.0.6/FWF/FileChooser/Imakefile (File already exists)'
  1417.     rm -f _shar_wnt_.tmp
  1418. else
  1419. > _shar_wnt_.tmp
  1420. echo 'x - extracting xarchie-2.0.6/FWF/FileChooser/Imakefile (Text)'
  1421. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/FWF/FileChooser/Imakefile' &&
  1422. #
  1423. # Imakefile for FileChooser
  1424. #
  1425. # Note that this Imakefile is just sufficient to build the FileChooser
  1426. # for use with xarchie. The original FWF distribution contains a more
  1427. # elaborate Imakefile for a variety of purposes. See the file ../README.
  1428. #
  1429. # George Ferguson, ferguson@cs.rochester.edu, 28 Jan 1993.
  1430. #
  1431. X
  1432. SRCS = FChooser.c
  1433. OBJS = FChooser.o
  1434. X
  1435. INCLUDES = -I. -I../Dir
  1436. X
  1437. NormalLibraryTarget(FChooser,$(OBJS))
  1438. X
  1439. DependTarget()
  1440. SHAR_EOF
  1441. chmod 0644 xarchie-2.0.6/FWF/FileChooser/Imakefile ||
  1442. echo 'restore of xarchie-2.0.6/FWF/FileChooser/Imakefile failed'
  1443. Wc_c="`wc -c < 'xarchie-2.0.6/FWF/FileChooser/Imakefile'`"
  1444. test 426 -eq "$Wc_c" ||
  1445.     echo 'xarchie-2.0.6/FWF/FileChooser/Imakefile: original size 426, current size' "$Wc_c"
  1446. rm -f _shar_wnt_.tmp
  1447. fi
  1448. # ============= xarchie-2.0.6/FWF/FileChooser/Makefile ==============
  1449. if test -f 'xarchie-2.0.6/FWF/FileChooser/Makefile' -a X"$1" != X"-c"; then
  1450.     echo 'x - skipping xarchie-2.0.6/FWF/FileChooser/Makefile (File already exists)'
  1451.     rm -f _shar_wnt_.tmp
  1452. else
  1453. > _shar_wnt_.tmp
  1454. echo 'x - extracting xarchie-2.0.6/FWF/FileChooser/Makefile (Text)'
  1455. sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/FWF/FileChooser/Makefile' &&
  1456. # Makefile generated by imake - do not edit!
  1457. # $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
  1458. #
  1459. # The cpp used on this machine replaces all newlines and multiple tabs and
  1460. # spaces in a macro expansion with a single space.  Imake tries to compensate
  1461. # for this, but is not always successful.
  1462. #
  1463. X
  1464. # -------------------------------------------------------------------------
  1465. # Makefile generated from "Imake.tmpl" and </tmp/IIf.a12634>
  1466. # $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
  1467. #
  1468. # Platform-specific parameters may be set in the appropriate <vendor>.cf
  1469. # configuration files.  Site-specific parameters should be set in the file
  1470. # site.def.  Full rebuilds are recommended if any parameters are changed.
  1471. #
  1472. # If your C preprocessor does not define any unique symbols, you will need
  1473. # to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
  1474. # "make World" the first time).
  1475. #
  1476. X
  1477. # -------------------------------------------------------------------------
  1478. # site-specific configuration parameters that need to come before
  1479. # the platform-specific parameters - edit site.def to change
  1480. X
  1481. # site:  $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
  1482. X
  1483. # -------------------------------------------------------------------------
  1484. # platform-specific configuration parameters - edit sun.cf to change
  1485. X
  1486. # platform:  $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
  1487. X
  1488. # operating system:  SunOS 4.1.1
  1489. X
  1490. # $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
  1491. X
  1492. # -------------------------------------------------------------------------
  1493. # site-specific configuration parameters that go after
  1494. # the platform-specific parameters - edit site.def to change
  1495. X
  1496. # site:  $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
  1497. X
  1498. X            SHELL = /bin/sh
  1499. X
  1500. X              TOP = ../../.
  1501. X      CURRENT_DIR = ./FWF/FileChooser
  1502. X
  1503. X               AR = ar clq
  1504. X  BOOTSTRAPCFLAGS =
  1505. X               CC = cc
  1506. X               AS = as
  1507. X
  1508. X         COMPRESS = compress
  1509. X              CPP = /lib/cpp $(STD_CPP_DEFINES)
  1510. X    PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
  1511. X          INSTALL = install
  1512. X               LD = ld
  1513. X             LINT = lint
  1514. X      LINTLIBFLAG = -C
  1515. X         LINTOPTS = -axz
  1516. X               LN = ln -s
  1517. X             MAKE = make
  1518. X               MV = mv
  1519. X               CP = cp
  1520. X
  1521. X           RANLIB = ranlib
  1522. X  RANLIBINSTFLAGS =
  1523. X
  1524. X               RM = rm -f
  1525. X            TROFF = psroff
  1526. X         MSMACROS = -ms
  1527. X              TBL = tbl
  1528. X              EQN = eqn
  1529. X     STD_INCLUDES =
  1530. X  STD_CPP_DEFINES =
  1531. X      STD_DEFINES =
  1532. X EXTRA_LOAD_FLAGS =
  1533. X  EXTRA_LIBRARIES =
  1534. X             TAGS = ctags
  1535. X
  1536. X    SHAREDCODEDEF = -DSHAREDCODE
  1537. SHAR_EOF
  1538. true || echo 'restore of xarchie-2.0.6/FWF/FileChooser/Makefile failed'
  1539. fi
  1540. echo 'End of xarchie-2.0.6 part 21'
  1541. echo 'File xarchie-2.0.6/FWF/FileChooser/Makefile is continued in part 22'
  1542. echo 22 > _shar_seq_.tmp
  1543. exit 0
  1544.  
  1545. exit 0 # Just in case...
  1546. -- 
  1547.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  1548. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  1549.  "It's intuitively obvious to the |
  1550.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1551.