IconicPath.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: IconicPath.c /main/9 1996/10/15 10:08:03 mustafa $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. *
  27. * FILE: IconicPath.c
  28. *
  29. * COMPONENT_NAME: Desktop File Manager (dtfile)
  30. *
  31. * Description: Contains routines to handle the Iconic Path.
  32. *
  33. * FUNCTIONS: ButtonCallback
  34. * ChangeManaged
  35. * ClassInitialize
  36. * ClassPartInitialize
  37. * DESIRED_HEIGHT
  38. * DESIRED_WIDTH
  39. * Destroy
  40. * DtUpdateIconicPath
  41. * GeometryManager
  42. * ICON_HT
  43. * IconicPathRedraw
  44. * Initialize
  45. * MHT
  46. * MIN_WD
  47. * MWD
  48. * QueryGeometry
  49. * Redisplay
  50. * Resize
  51. * SPC
  52. * SetValues
  53. * Update
  54. * WidgetNavigable
  55. * _DtCreateIconicPath
  56. * externaldef
  57. *
  58. * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
  59. * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
  60. * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
  61. * (c) Copyright 1993, 1994, 1995 Novell, Inc.
  62. *
  63. ****************************************************************************
  64. ************************************<+>*************************************/
  65. /* Copied from Xm/XmI.h */
  66. #define GMode(g) ((g)->request_mode)
  67. #define IsWidth(g) (GMode (g) & CWWidth)
  68. #define IsHeight(g) (GMode (g) & CWHeight)
  69. #define IsBorder(g) (GMode (g) & CWBorderWidth)
  70. #define IsQueryOnly(g) (GMode (g) & XtCWQueryOnly)
  71. #include <Xm/TransltnsP.h>
  72. #include <Xm/LabelG.h>
  73. #include <Xm/PushBG.h>
  74. #include <Xm/DragDrop.h>
  75. #include <Dt/Icon.h>
  76. #include <Dt/IconP.h>
  77. #include <Dt/DtNlUtils.h>
  78. #include <Dt/Connect.h>
  79. #include <Dt/FileM.h>
  80. #include <Dt/Dts.h>
  81. #include "Encaps.h"
  82. #include "SharedProcs.h"
  83. #include <Xm/XmPrivate.h> /* _XmShellIsExclusive */
  84. #include "Desktop.h"
  85. #include "FileMgr.h"
  86. #include "Main.h"
  87. #include "ChangeDir.h"
  88. #include "Prefs.h"
  89. #include "IconicPathP.h"
  90. #define defaultTranslations _XmManager_defaultTranslations
  91. #define traversalTranslations _XmManager_managerTraversalTranslations
  92. /******** Static Function Declarations ********/
  93. static void ClassInitialize( void ) ;
  94. static void ClassPartInitialize(
  95. WidgetClass w_class) ;
  96. static void Initialize(
  97. Widget rw,
  98. Widget nw,
  99. ArgList args,
  100. Cardinal *num_args) ;
  101. static void Destroy(
  102. Widget w) ;
  103. static void Redisplay(
  104. Widget wid,
  105. XEvent *event,
  106. Region region) ;
  107. static void Resize(
  108. Widget wid) ;
  109. static XtGeometryResult GeometryManager(
  110. Widget w,
  111. XtWidgetGeometry *request,
  112. XtWidgetGeometry *reply) ;
  113. static void ChangeManaged(
  114. Widget wid) ;
  115. static Boolean SetValues(
  116. Widget cw,
  117. Widget rw,
  118. Widget nw,
  119. ArgList args,
  120. Cardinal *num_args) ;
  121. static XtGeometryResult QueryGeometry(
  122. Widget wid,
  123. XtWidgetGeometry *intended,
  124. XtWidgetGeometry *desired) ;
  125. static XmNavigability WidgetNavigable(
  126. Widget wid) ;
  127. /******** End Static Function Declarations ********/
  128. /*--------------------------------------------------------------------
  129. * Convenience macros
  130. *------------------------------------------------------------------*/
  131. #define MWD(ip) ((ip)->iconic_path.margin_width)
  132. #define MHT(ip) ((ip)->iconic_path.margin_height)
  133. #define SPC(ip) ((ip)->iconic_path.spacing)
  134. #define MIN_WD(ip) ((ip)->iconic_path.large_icons? \
  135. (ip)->iconic_path.large_min_width: \
  136. (ip)->iconic_path.small_min_width)
  137. #define ICON_HT(ip) ((ip)->iconic_path.large_icons? 32: 16)
  138. #define DESIRED_WIDTH(ip) \
  139. (MWD(ip) + (ip)->iconic_path.dotdot_button->core.width + MWD(ip) \
  140. + ((ip)->iconic_path.dropzone? \
  141. ((ip)->iconic_path.dropzone_icon->core.width + MWD(ip)): 0) \
  142. + ((ip)->iconic_path.status_msg? \
  143. ((ip)->iconic_path.status_label->core.width + MWD(ip)): 0))
  144. #define DESIRED_HEIGHT(ip) \
  145. (MHT(ip) + ICON_HT(ip) + SPC(ip) + \
  146. (ip)->iconic_path.dotdot_button->core.height + MHT(ip))
  147. /*--------------------------------------------------------------------
  148. * Resource definitions for IconicPath
  149. *------------------------------------------------------------------*/
  150. static XmSyntheticResource syn_resources[] =
  151. {
  152. { XmNmarginWidth,
  153. sizeof (Dimension),
  154. XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_width),
  155. XmeFromHorizontalPixels,
  156. XmeToHorizontalPixels
  157. },
  158. { XmNmarginHeight,
  159. sizeof (Dimension),
  160. XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_height),
  161. XmeFromVerticalPixels,
  162. XmeToVerticalPixels
  163. },
  164. };
  165. static XtResource resources[] =
  166. {
  167. { XmNmarginWidth,
  168. XmCMarginWidth, XmRHorizontalDimension, sizeof (Dimension),
  169. XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_width),
  170. XmRImmediate, (XtPointer) 5
  171. },
  172. { XmNmarginHeight,
  173. XmCMarginHeight, XmRVerticalDimension, sizeof (Dimension),
  174. XtOffsetOf( struct _DtIconicPathRec, iconic_path.margin_height),
  175. XmRImmediate, (XtPointer) 2
  176. },
  177. { XmNspacing,
  178. XmCSpacing, XmRVerticalDimension, sizeof (Dimension),
  179. XtOffsetOf( struct _DtIconicPathRec, iconic_path.spacing),
  180. XmRImmediate, (XtPointer) 4
  181. },
  182. { DtNsmallMinWidth,
  183. XmCMinWidth, XmRHorizontalDimension, sizeof (Dimension),
  184. XtOffsetOf( struct _DtIconicPathRec,
  185. iconic_path.small_min_width),
  186. XmRImmediate, (XtPointer) 25
  187. },
  188. { DtNlargeMinWidth,
  189. XmCMinWidth, XmRHorizontalDimension, sizeof (Dimension),
  190. XtOffsetOf( struct _DtIconicPathRec,
  191. iconic_path.large_min_width),
  192. XmRImmediate, (XtPointer) 45
  193. },
  194. { DtNforceSmallIcons,
  195. DtCForceSmallIcons, XmRBoolean, sizeof (Boolean),
  196. XtOffsetOf( struct _DtIconicPathRec,
  197. iconic_path.force_small_icons),
  198. XmRImmediate, (XtPointer) False
  199. },
  200. { DtNforceLargeIcons,
  201. DtCForceLargeIcons, XmRBoolean, sizeof (Boolean),
  202. XtOffsetOf( struct _DtIconicPathRec,
  203. iconic_path.force_large_icons),
  204. XmRImmediate, (XtPointer) False
  205. },
  206. { "buttons",
  207. "Buttons", XmRBoolean, sizeof (Boolean),
  208. XtOffsetOf( struct _DtIconicPathRec, iconic_path.buttons),
  209. XmRImmediate, (XtPointer) False
  210. },
  211. { "dropZone",
  212. "DropZone", XmRBoolean, sizeof (Boolean),
  213. XtOffsetOf( struct _DtIconicPathRec, iconic_path.dropzone),
  214. XmRImmediate, (XtPointer) False
  215. },
  216. { "statusMsg",
  217. "StatusMsg", XmRBoolean, sizeof (Boolean),
  218. XtOffsetOf( struct _DtIconicPathRec, iconic_path.status_msg),
  219. XmRImmediate, (XtPointer) True
  220. },
  221. { DtNfileMgrRec,
  222. DtCfileMgrRec, XmRString, sizeof (char *),
  223. XtOffsetOf( struct _DtIconicPathRec, iconic_path.file_mgr_rec),
  224. XmRImmediate, (XtPointer) NULL
  225. },
  226. { DtNcurrentDirectory,
  227. DtCCurrentDirectory, XmRString, sizeof (char *),
  228. XtOffsetOf( struct _DtIconicPathRec,
  229. iconic_path.current_directory),
  230. XmRImmediate, (XtPointer) NULL
  231. },
  232. { DtNlargeIcons,
  233. DtCLargeIcons, XmRBoolean, sizeof (Boolean),
  234. XtOffsetOf( struct _DtIconicPathRec, iconic_path.large_icons),
  235. XmRImmediate, (XtPointer) True
  236. },
  237. { DtNiconsChanged,
  238. DtCIconsChanged, XmRBoolean, sizeof (Boolean),
  239. XtOffsetOf( struct _DtIconicPathRec, iconic_path.icons_changed),
  240. XmRImmediate, (XtPointer) True
  241. },
  242. };
  243. /*--------------------------------------------------------------------
  244. *
  245. * Full class record constant
  246. *
  247. *------------------------------------------------------------------*/
  248. static XmBaseClassExtRec baseClassExtRec = {
  249. NULL,
  250. NULLQUARK,
  251. XmBaseClassExtVersion,
  252. sizeof(XmBaseClassExtRec),
  253. NULL, /* InitializePrehook */
  254. NULL, /* SetValuesPrehook */
  255. NULL, /* InitializePosthook */
  256. NULL, /* SetValuesPosthook */
  257. NULL, /* secondaryObjectClass */
  258. NULL, /* secondaryCreate */
  259. NULL, /* getSecRes data */
  260. { 0 }, /* fastSubclass flags */
  261. NULL, /* getValuesPrehook */
  262. NULL, /* getValuesPosthook */
  263. NULL, /* classPartInitPrehook */
  264. NULL, /* classPartInitPosthook*/
  265. NULL, /* ext_resources */
  266. NULL, /* compiled_ext_resources*/
  267. 0, /* num_ext_resources */
  268. FALSE, /* use_sub_resources */
  269. WidgetNavigable, /* widgetNavigable */
  270. NULL /* focusChange */
  271. };
  272. externaldef( dticonicpathclassrec) DtIconicPathClassRec dtIconicPathClassRec =
  273. {
  274. { /* core_class fields */
  275. (WidgetClass) &xmManagerClassRec, /* superclass */
  276. "DtIconicPath", /* class_name */
  277. sizeof(DtIconicPathRec), /* widget_size */
  278. ClassInitialize, /* class_initialize */
  279. ClassPartInitialize, /* class_part_init */
  280. FALSE, /* class_inited */
  281. Initialize, /* initialize */
  282. NULL, /* initialize_hook */
  283. XtInheritRealize, /* realize */
  284. NULL, /* actions */
  285. 0, /* num_actions */
  286. resources, /* resources */
  287. XtNumber(resources), /* num_resources */
  288. NULLQUARK, /* xrm_class */
  289. TRUE, /* compress_motion */
  290. FALSE, /* compress_exposure */
  291. TRUE, /* compress_enterlv */
  292. FALSE, /* visible_interest */
  293. Destroy, /* destroy */
  294. Resize, /* resize */
  295. Redisplay, /* expose */
  296. SetValues, /* set_values */
  297. NULL, /* set_values_hook */
  298. XtInheritSetValuesAlmost, /* set_values_almost */
  299. NULL, /* get_values_hook */
  300. NULL, /* accept_focus */
  301. XtVersion, /* version */
  302. NULL, /* callback_private */
  303. defaultTranslations, /* tm_table */
  304. QueryGeometry, /* query_geometry */
  305. NULL, /* display_accelerator*/
  306. (XtPointer)&baseClassExtRec, /* extension */
  307. },
  308. { /* composite_class fields */
  309. GeometryManager, /* geometry_manager */
  310. ChangeManaged, /* change_managed */
  311. XtInheritInsertChild, /* insert_child */
  312. XtInheritDeleteChild, /* delete_child */
  313. NULL, /* extension */
  314. },
  315. { /* constraint_class fields */
  316. NULL, /* resource list */
  317. 0, /* num resources */
  318. 0, /* constraint size */
  319. NULL, /* init proc */
  320. NULL, /* destroy proc */
  321. NULL, /* set values proc */
  322. NULL, /* extension */
  323. },
  324. { /* manager_class fields */
  325. traversalTranslations, /* translations */
  326. syn_resources, /* syn_resources */
  327. XtNumber (syn_resources), /* num_get_resources */
  328. NULL, /* syn_cont_resources */
  329. 0, /* num_get_cont_resources */
  330. XmInheritParentProcess, /* parent_process */
  331. NULL, /* extension */
  332. },
  333. { /* drawingArea class - none */
  334. 0 /* mumble */
  335. }
  336. };
  337. externaldef( dticonicpathwidgetclass) WidgetClass dtIconicPathWidgetClass
  338. = (WidgetClass) &dtIconicPathClassRec ;
  339. /*--------------------------------------------------------------------
  340. * Activate Callback for iconic path buttons and double click on icons
  341. *------------------------------------------------------------------*/
  342. static void
  343. ButtonCallback(
  344. Widget w,
  345. XtPointer client_data,
  346. XtPointer call_data )
  347. {
  348. DtIconicPathWidget ip = (DtIconicPathWidget)client_data;
  349. FileMgrRec *file_mgr_rec = (FileMgrRec *) ip->iconic_path.file_mgr_rec;
  350. DialogData *dialog_data;
  351. FileMgrData *file_mgr_data;
  352. char host_name[MAX_PATH];
  353. int i;
  354. if (XtClass(w) == dtIconGadgetClass)
  355. {
  356. if (((XmAnyCallbackStruct *)call_data)->reason != XmCR_DEFAULT_ACTION)
  357. return;
  358. }
  359. if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
  360. return;
  361. file_mgr_data = (FileMgrData *) dialog_data->data;
  362. strcpy(host_name, file_mgr_data->host);
  363. if (w == ip->iconic_path.dotdot_button)
  364. i = ip->iconic_path.left_component - 1;
  365. else
  366. {
  367. for (i = 0; i < ip->iconic_path.num_components; i++)
  368. if (w == ip->iconic_path.components[i].button ||
  369. w == ip->iconic_path.components[i].icon)
  370. {
  371. break;
  372. }
  373. }
  374. if (i == ip->iconic_path.num_components - 1)
  375. FileMgrReread (file_mgr_rec);
  376. else if (i < ip->iconic_path.num_components)
  377. ShowNewDirectory (file_mgr_data, host_name,
  378. ip->iconic_path.components[i].path);
  379. }
  380. /*--------------------------------------------------------------------
  381. * Iconic path update function
  382. *------------------------------------------------------------------*/
  383. static int
  384. Update(
  385. DtIconicPathWidget ip,
  386. FileMgrRec *file_mgr_rec,
  387. FileMgrData *file_mgr_data)
  388. {
  389. static Pixmap change_view_pixmap = XmUNSPECIFIED_PIXMAP;
  390. char *fileLabel;
  391. Widget *manage;
  392. int nmanage;
  393. Dimension iwidth, iheight;
  394. int twidth;
  395. Pixel foreground, background;
  396. Arg args[35];
  397. char *ptr, *path, *name;
  398. XmString xm_string;
  399. int restricted_len;
  400. int path_len;
  401. Boolean forbidden;
  402. int i, j, n;
  403. int x, y;
  404. int n_changes = 0;
  405. PixmapData *pixmapData;
  406. char msg_buf[21+MAX_PATH];
  407. /* macro that updates the change count */
  408. # define INC_N_CHANGES() \
  409. if (n_changes++ == 0) \
  410. { /* first change: unmanage all children and clear the window */ \
  411. XtUnmanageChildren(ip->composite.children, ip->composite.num_children); \
  412. if (XtIsRealized((Widget)ip)) \
  413. XClearWindow(XtDisplay(ip), XtWindow(ip)); \
  414. } else
  415. /* macro that moves a child and updates the change count */
  416. # define MOVE_OBJECT(w,_x,_y) \
  417. if ((w)->core.x != (_x) || (w)->core.y != (_y)) \
  418. { \
  419. INC_N_CHANGES(); \
  420. XmeConfigureObject(w, _x, _y, (w)->core.width, (w)->core.height, (w)->core.border_width); \
  421. } else
  422. DPRINTF2((
  423. "IconicPath.Update: cur_dir '%s', dir_shown '%s', icons_changed %d\n",
  424. ip->iconic_path.current_directory,
  425. ip->iconic_path.directory_shown? ip->iconic_path.directory_shown: "(nil)",
  426. ip->iconic_path.icons_changed));
  427. /* enforce the forceSmallIconsor forceLargeIcons resources */
  428. if (ip->iconic_path.force_small_icons)
  429. ip->iconic_path.large_icons = False;
  430. else if (ip->iconic_path.force_large_icons)
  431. ip->iconic_path.large_icons = True;
  432. /* create "..." button, if necessary */
  433. if (ip->iconic_path.dotdot_button == NULL)
  434. {
  435. xm_string = XmStringCreateLocalized("...");
  436. n = 0;
  437. XtSetArg (args[n], XmNlabelString, xm_string); n++;
  438. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  439. XtSetArg (args[n], XmNmarginHeight, 0); n++;
  440. XtSetArg (args[n], XmNhighlightThickness, 0); n++;
  441. if (ip->iconic_path.buttons)
  442. {
  443. XtSetArg (args[n], XmNshadowThickness, 1); n++;
  444. XtSetArg (args[n], XmNtraversalOn, False); n++;
  445. ip->iconic_path.dotdot_button =
  446. XmCreatePushButtonGadget((Widget)ip, "iconic_path_button", args, n);
  447. XtAddCallback(ip->iconic_path.dotdot_button,
  448. XmNactivateCallback, ButtonCallback, ip);
  449. }
  450. else
  451. {
  452. ip->iconic_path.dotdot_button =
  453. XmCreateLabelGadget((Widget)ip, "iconic_path_label", args, n);
  454. }
  455. XmStringFree(xm_string);
  456. if (ip->iconic_path.dotdot_button->core.width < (Dimension)((Dimension)MIN_WD(ip)/(Dimension)2))
  457. {
  458. XmeConfigureObject(ip->iconic_path.dotdot_button,
  459. ip->iconic_path.dotdot_button->core.x,
  460. ip->iconic_path.dotdot_button->core.y,
  461. (Dimension)MIN_WD(ip)/(Dimension)2,
  462. ip->iconic_path.dotdot_button->core.height, 0);
  463. }
  464. }
  465. else if (ip->iconic_path.large_shown != ip->iconic_path.large_icons)
  466. {
  467. xm_string = XmStringCreateLocalized("...");
  468. XtSetArg (args[0], XmNlabelString, xm_string);
  469. XtSetValues(ip->iconic_path.dotdot_button, args, 1);
  470. XmStringFree(xm_string);
  471. if (ip->iconic_path.dotdot_button->core.width < (Dimension)((Dimension)MIN_WD(ip)/(Dimension)2))
  472. {
  473. XmeConfigureObject(ip->iconic_path.dotdot_button,
  474. ip->iconic_path.dotdot_button->core.x,
  475. ip->iconic_path.dotdot_button->core.y,
  476. (Dimension)MIN_WD(ip)/(Dimension)2,
  477. ip->iconic_path.dotdot_button->core.height, 0);
  478. }
  479. }
  480. /* create StatuMsg, if necessary */
  481. if (ip->iconic_path.status_msg && ip->iconic_path.status_label == NULL)
  482. {
  483. /* create StatuMsg */
  484. n = 0;
  485. XtSetArg (args[n], XmNmarginHeight, 0); n++;
  486. XtSetArg (args[n], XmNhighlightThickness, 0); n++;
  487. ip->iconic_path.status_label =
  488. XmCreateLabelGadget((Widget)ip, "status_label", args, n);
  489. }
  490. foreground = ip->manager.foreground;
  491. background = ip->core.background_pixel;
  492. /* create DropZone, if necessary */
  493. if (ip->iconic_path.dropzone && ip->iconic_path.dropzone_icon == NULL)
  494. {
  495. /* create DropZone */
  496. if (change_view_pixmap == XmUNSPECIFIED_PIXMAP)
  497. {
  498. foreground = ip->manager.foreground;
  499. background = ip->core.background_pixel;
  500. change_view_pixmap = _DtGetPixmap(XtScreen(ip), CHANGE_VIEW_ICON_M,
  501. foreground, background);
  502. }
  503. n = 0;
  504. XtSetArg (args[n], XmNstring, NULL); n++;
  505. XtSetArg (args[n], XmNshadowThickness, 2); n++;
  506. XtSetArg (args[n], XmNfillOnArm, False); n++;
  507. XtSetArg (args[n], XmNhighlightThickness, 0); n++;
  508. XtSetArg (args[n], XmNpixmap, change_view_pixmap); n++;
  509. XtSetArg (args[n], XmNtraversalOn, False); n++;
  510. XtSetArg (args[n], XmNdropSiteOperations,
  511. XmDROP_MOVE | XmDROP_COPY | XmDROP_LINK); n++;
  512. ip->iconic_path.dropzone_icon =
  513. _DtCreateIcon ((Widget)ip, "change_view", args, n);
  514. XtAddCallback (ip->iconic_path.dropzone_icon, XmNdropCallback,
  515. DropOnChangeView, (XtPointer) file_mgr_rec);
  516. XtAddCallback (ip->iconic_path.dropzone_icon, XmNcallback,
  517. CurrentDirDropCallback, file_mgr_rec);
  518. }
  519. /* if the current directory changed, update component list */
  520. if (file_mgr_data != NULL && ip->iconic_path.current_directory != NULL &&
  521. ip->iconic_path.current_directory[0] == '/' &&
  522. (ip->iconic_path.directory_shown == NULL ||
  523. strcmp(ip->iconic_path.directory_shown,
  524. ip->iconic_path.current_directory) != 0 ||
  525. ip->iconic_path.large_shown != ip->iconic_path.large_icons ||
  526. ip->iconic_path.icons_changed))
  527. {
  528. /* store the new directory */
  529. XtFree(ip->iconic_path.directory_shown);
  530. ip->iconic_path.directory_shown =
  531. XtNewString(ip->iconic_path.current_directory);
  532. /* for restricted directory: compute length of unshown path */
  533. if (file_mgr_data->restricted_directory)
  534. {
  535. ptr = strrchr(file_mgr_data->restricted_directory, '/');
  536. if( ptr == file_mgr_data->restricted_directory )
  537. restricted_len = 1;
  538. else
  539. restricted_len = ptr? ptr - file_mgr_data->restricted_directory: 0;
  540. }
  541. else
  542. restricted_len = 0;
  543. /* get all path components */
  544. i = 0;
  545. ptr = ip->iconic_path.directory_shown;
  546. for (;;)
  547. {
  548. /* extract the next path component */
  549. if (ptr != NULL)
  550. *ptr = '\0';
  551. if (ip->iconic_path.directory_shown[0] == '\0')
  552. path = name = "/";
  553. else
  554. {
  555. path = ip->iconic_path.directory_shown;
  556. name = strrchr(path, '/') + 1;
  557. }
  558. /* don't show path components above a restricted directory */
  559. path_len = strlen(path);
  560. if (restricted_len && path_len <= restricted_len)
  561. goto next_component;
  562. /* in restricted mode: check if this component is above $HOME */
  563. forbidden = restrictMode
  564. && strncmp(path, users_home_dir, path_len) == 0
  565. && (path_len == 1 ||
  566. users_home_dir[path_len] == '/' &&
  567. users_home_dir[path_len + 1] != '\0');
  568. /* check if we need to add or update the path component */
  569. if (i >= ip->iconic_path.num_components)
  570. {
  571. /* create new component */
  572. INC_N_CHANGES();
  573. ip->iconic_path.components = (struct _IconicPathComponent *)
  574. XtRealloc((char *)ip->iconic_path.components,
  575. (i + 1)*sizeof(struct _IconicPathComponent));
  576. ip->iconic_path.components[i].path = XtNewString(path);
  577. pixmapData = GetPixmapData(file_mgr_rec,
  578. file_mgr_data,
  579. path,
  580. ip->iconic_path.large_icons);
  581. n = 0;
  582. XtSetArg (args[n], XmNstring, NULL); n++;
  583. if (pixmapData)
  584. {
  585. XtSetArg (args[n], XmNimageName, pixmapData->iconFileName);
  586. ip->iconic_path.components[i].icon_name =
  587. XtNewString(pixmapData->iconFileName);
  588. }
  589. else
  590. {
  591. XtSetArg (args[n], XmNimageName, NULL);
  592. ip->iconic_path.components[i].icon_name = NULL;
  593. }
  594. n++;
  595. if ( background == white_pixel )
  596. {
  597. XtSetArg (args[n], XmNbackground, white_pixel); n++;
  598. XtSetArg (args[n], XmNpixmapBackground, white_pixel); n++;
  599. XtSetArg (args[n], XmNpixmapForeground, black_pixel); n++;
  600. }
  601. else if ( background == black_pixel )
  602. {
  603. XtSetArg (args[n], XmNbackground, black_pixel); n++;
  604. XtSetArg (args[n], XmNpixmapBackground, white_pixel); n++;
  605. XtSetArg (args[n], XmNpixmapForeground, black_pixel); n++;
  606. }
  607. else
  608. {
  609. XtSetArg (args[n], XmNbackground, background); n++;
  610. }
  611. XtSetArg (args[n], XmNhighlightThickness, 0); n++;
  612. XtSetArg (args[n], XmNmarginHeight, 0); n++;
  613. XtSetArg (args[n], XmNmarginWidth, 0); n++;
  614. XtSetArg (args[n], XmNtraversalOn, False); n++;
  615. ip->iconic_path.components[i].icon =
  616. _DtCreateIcon ((Widget)ip, "iconic_path_icon", args, n);
  617. _DtCheckAndFreePixmapData(
  618. GetDirectoryLogicalType(file_mgr_data, path),
  619. file_mgr_rec->shell,
  620. (DtIconGadget) ip->iconic_path.components[i].icon,
  621. pixmapData);
  622. XtAddCallback (ip->iconic_path.components[i].icon, XmNcallback,
  623. ButtonCallback, ip);
  624. if (fileLabel = DtDtsDataTypeToAttributeValue(
  625. GetDirectoryLogicalType(file_mgr_data, path),
  626. DtDTS_DA_LABEL,
  627. NULL))
  628. {
  629. xm_string = XmStringCreateLocalized(fileLabel);
  630. DtDtsFreeAttributeValue(fileLabel);
  631. }
  632. else
  633. {
  634. xm_string = XmStringCreateLocalized(name);
  635. }
  636. n = 0;
  637. XtSetArg (args[n], XmNlabelString, xm_string); n++;
  638. XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  639. XtSetArg (args[n], XmNmarginHeight, 0); n++;
  640. XtSetArg (args[n], XmNhighlightThickness, 0); n++;
  641. if (ip->iconic_path.buttons)
  642. {
  643. XtSetArg (args[n], XmNshadowThickness, 1); n++;
  644. XtSetArg (args[n], XmNtraversalOn, False); n++;
  645. XtSetArg (args[n], XmNsensitive, !forbidden); n++;
  646. ip->iconic_path.components[i].button =
  647. XmCreatePushButtonGadget ((Widget)ip, "iconic_path_button",
  648. args, n);
  649. XtAddCallback(ip->iconic_path.components[i].button,
  650. XmNactivateCallback, ButtonCallback, ip);
  651. }
  652. else
  653. {
  654. ip->iconic_path.components[i].button =
  655. XmCreateLabelGadget((Widget)ip, "iconic_path_label", args, n);
  656. }
  657. XmStringFree(xm_string);
  658. }
  659. else
  660. {
  661. /* check if the existing component needs to be updated */
  662. /* check if the path has changed */
  663. if (strcmp(ip->iconic_path.components[i].path, path) != 0 ||
  664. ip->iconic_path.large_shown != ip->iconic_path.large_icons)
  665. {
  666. INC_N_CHANGES();
  667. XtFree(ip->iconic_path.components[i].path);
  668. ip->iconic_path.components[i].path = XtNewString(path);
  669. }
  670. if (fileLabel = DtDtsDataTypeToAttributeValue(
  671. GetDirectoryLogicalType(file_mgr_data, path),
  672. DtDTS_DA_LABEL,
  673. NULL))
  674. {
  675. xm_string = XmStringCreateLocalized(fileLabel);
  676. DtDtsFreeAttributeValue(fileLabel);
  677. }
  678. else
  679. {
  680. xm_string = XmStringCreateLocalized(name);
  681. }
  682. XtSetArg (args[0], XmNlabelString, xm_string);
  683. XtSetArg (args[1], XmNsensitive, !forbidden);
  684. XtSetValues(ip->iconic_path.components[i].button, args, 2);
  685. XmStringFree(xm_string);
  686. /* check if the icon has changed */
  687. pixmapData = GetPixmapData(file_mgr_rec,
  688. file_mgr_data,
  689. path,
  690. ip->iconic_path.large_icons);
  691. if (pixmapData)
  692. {
  693. if ((pixmapData->iconFileName == NULL) !=
  694. (ip->iconic_path.components[i].icon_name == NULL) ||
  695. pixmapData->iconFileName != NULL &&
  696. strcmp(pixmapData->iconFileName,
  697. ip->iconic_path.components[i].icon_name) != 0)
  698. {
  699. INC_N_CHANGES();
  700. XtFree(ip->iconic_path.components[i].icon_name);
  701. ip->iconic_path.components[i].icon_name =
  702. XtNewString(pixmapData->iconFileName);
  703. XtSetArg (args[0], XmNimageName, pixmapData->iconFileName);
  704. XtSetValues(ip->iconic_path.components[i].icon, args, 1);
  705. _DtCheckAndFreePixmapData(
  706. GetDirectoryLogicalType(file_mgr_data, path),
  707. file_mgr_rec->shell,
  708. (DtIconGadget) ip->iconic_path.components[i].icon,
  709. pixmapData);
  710. }
  711. }
  712. else
  713. {
  714. XtFree(ip->iconic_path.components[i].icon_name);
  715. ip->iconic_path.components[i].icon_name = NULL;
  716. XtSetArg (args[0], XmNimageName, NULL);
  717. XtSetValues(ip->iconic_path.components[i].icon, args, 1);
  718. }
  719. }
  720. /* update component count */
  721. i++;
  722. next_component:
  723. /* go to the next path component */
  724. if (ptr == NULL)
  725. break;
  726. /* restore '/' */
  727. *ptr = '/';
  728. /* find next component */
  729. if (strcmp(ptr, "/") == 0)
  730. break;
  731. ptr = DtStrchr(ptr + 1, '/');
  732. }
  733. /* free any leftover components */
  734. for (j = i; j < ip->iconic_path.num_components; j++)
  735. {
  736. INC_N_CHANGES();
  737. XtFree(ip->iconic_path.components[j].path);
  738. ip->iconic_path.components[j].path = NULL;
  739. XtFree(ip->iconic_path.components[j].icon_name);
  740. ip->iconic_path.components[j].icon_name = NULL;
  741. XtDestroyWidget(ip->iconic_path.components[j].icon);
  742. XtDestroyWidget(ip->iconic_path.components[j].button);
  743. }
  744. ip->iconic_path.num_components = i;
  745. ip->iconic_path.large_shown = ip->iconic_path.large_icons;
  746. }
  747. /* update component widths */
  748. for (i = 0; i < ip->iconic_path.num_components; i++)
  749. {
  750. /* determine width for this component */
  751. twidth = MIN_WD(ip);
  752. if (ip->iconic_path.components[i].icon->core.width > (Dimension)twidth)
  753. twidth = ip->iconic_path.components[i].icon->core.width;
  754. if (ip->iconic_path.components[i].button->core.width > (Dimension)twidth)
  755. twidth = ip->iconic_path.components[i].button->core.width;
  756. if (ip->iconic_path.components[i].button->core.width < (Dimension)twidth)
  757. {
  758. /* increment the change count */
  759. INC_N_CHANGES();
  760. /* resize */
  761. XmeConfigureObject(ip->iconic_path.components[i].button,
  762. ip->iconic_path.components[i].button->core.x,
  763. ip->iconic_path.components[i].button->core.y,
  764. twidth,
  765. ip->iconic_path.components[i].button->core.height,
  766. 0);
  767. }
  768. ip->iconic_path.components[i].width = twidth;
  769. }
  770. /* update the status message */
  771. if (file_mgr_data && ip->iconic_path.status_msg)
  772. GetStatusMsg(file_mgr_data, msg_buf);
  773. else
  774. strcpy(msg_buf, "");
  775. if (ip->iconic_path.msg_text == NULL ||
  776. strcmp(msg_buf, ip->iconic_path.msg_text) != 0)
  777. {
  778. /* remember the new status message text */
  779. XtFree(ip->iconic_path.msg_text);
  780. ip->iconic_path.msg_text = XtNewString(msg_buf);
  781. if (ip->iconic_path.status_label)
  782. {
  783. /* clear the area under the old status message text */
  784. if (XtIsRealized((Widget)ip) &&
  785. ip->iconic_path.status_label->core.x > 0)
  786. XClearArea(XtDisplay(ip), XtWindow(ip),
  787. ip->iconic_path.status_label->core.x,
  788. ip->iconic_path.status_label->core.y,
  789. ip->iconic_path.status_label->core.width,
  790. ip->iconic_path.status_label->core.height, False);
  791. /* set a new status message text */
  792. xm_string = XmStringCreateLocalized(msg_buf);
  793. XtSetArg (args[0], XmNlabelString, xm_string);
  794. XtSetValues(ip->iconic_path.status_label, args, 1);
  795. XmStringFree(xm_string);
  796. }
  797. }
  798. /* set widget size, if necessary */
  799. if (ip->core.width == 0)
  800. ip->core.width = DESIRED_WIDTH(ip);
  801. if (ip->core.height == 0)
  802. ip->core.height = DESIRED_HEIGHT(ip);
  803. /* for the layout: check how much of the path will fit */
  804. twidth = MWD(ip) + ip->iconic_path.dotdot_button->core.width + MWD(ip);
  805. if (ip->iconic_path.status_msg && ip->iconic_path.dropzone)
  806. {
  807. if (ip->iconic_path.status_label->core.width
  808. >= ip->iconic_path.dropzone_icon->core.width)
  809. twidth += ip->iconic_path.status_label->core.width + MWD(ip);
  810. else
  811. twidth += ip->iconic_path.dropzone_icon->core.width + MWD(ip);
  812. }
  813. else if (ip->iconic_path.status_msg)
  814. twidth += ip->iconic_path.status_label->core.width + MWD(ip);
  815. else if (ip->iconic_path.dropzone)
  816. twidth += ip->iconic_path.dropzone_icon->core.width + MWD(ip);
  817. for (i = ip->iconic_path.num_components; i > 0; i--)
  818. {
  819. twidth += SPC(ip) + ip->iconic_path.components[i - 1].width;
  820. if ((Dimension)twidth > ip->core.width)
  821. break;
  822. }
  823. if (i == 1 && (Dimension)(twidth - ip->iconic_path.dotdot_button->core.width - SPC(ip))
  824. <= ip->core.width)
  825. {
  826. i--;
  827. }
  828. if (i != ip->iconic_path.left_component)
  829. {
  830. INC_N_CHANGES();
  831. ip->iconic_path.left_component = i;
  832. }
  833. /* allocate list of to-be-managed children */
  834. manage = (Widget *)
  835. XtMalloc((2*(ip->iconic_path.num_components - i) + 2)*sizeof(Widget));
  836. nmanage = 0;
  837. /* position & manage the path components */
  838. x = MWD(ip);
  839. y = ip->core.height - MHT(ip) - ip->iconic_path.dotdot_button->core.height
  840. - SPC(ip);
  841. if (i > 0)
  842. {
  843. MOVE_OBJECT(ip->iconic_path.dotdot_button, x, y + SPC(ip));
  844. manage[nmanage++] = ip->iconic_path.dotdot_button;
  845. x += ip->iconic_path.dotdot_button->core.width + SPC(ip);
  846. }
  847. for (j = i; j < ip->iconic_path.num_components; j++)
  848. {
  849. MOVE_OBJECT(ip->iconic_path.components[j].icon,
  850. x + SPC(ip),
  851. y - ip->iconic_path.components[j].icon->core.height);
  852. MOVE_OBJECT(ip->iconic_path.components[j].button, x, y + SPC(ip));
  853. x += ip->iconic_path.components[j].width + SPC(ip);
  854. manage[nmanage++] = ip->iconic_path.components[j].icon;
  855. manage[nmanage++] = ip->iconic_path.components[j].button;
  856. }
  857. /* position & manage the status message label */
  858. if (ip->iconic_path.status_msg)
  859. {
  860. x = ip->core.width - MWD(ip) -
  861. (int)ip->iconic_path.status_label->core.width;
  862. if (x < 0)
  863. x = 0;
  864. y = ip->core.height - MHT(ip) -
  865. (int)ip->iconic_path.status_label->core.height;
  866. if (y < 0)
  867. y = 0;
  868. if (ip->iconic_path.status_label->core.x != x ||
  869. ip->iconic_path.status_label->core.y != y)
  870. {
  871. XmeConfigureObject(ip->iconic_path.status_label, x, y,
  872. ip->iconic_path.status_label->core.width,
  873. ip->iconic_path.status_label->core.height,
  874. ip->iconic_path.status_label->core.border_width);
  875. }
  876. manage[nmanage++] = ip->iconic_path.status_label;
  877. y -= SPC(ip);
  878. }
  879. else
  880. y = ip->core.height;
  881. /* position & manage the drop zone icon */
  882. if (ip->iconic_path.dropzone)
  883. {
  884. x = ip->core.width - MWD(ip) -
  885. (int)ip->iconic_path.dropzone_icon->core.width;
  886. if (x < 0)
  887. x = 0;
  888. y = (y - (int)ip->iconic_path.dropzone_icon->core.height + 1)/2;
  889. if (y < 0)
  890. y = 0;
  891. MOVE_OBJECT(ip->iconic_path.dropzone_icon, x, y);
  892. manage[nmanage++] = ip->iconic_path.dropzone_icon;
  893. }
  894. /* if all icons are there, manage the children */
  895. for (i = 0; i < ip->iconic_path.num_components; i++)
  896. if (ip->iconic_path.components[i].icon_name == NULL)
  897. break;
  898. if (file_mgr_data != NULL && i == ip->iconic_path.num_components)
  899. {
  900. DPRINTF2(("IconicPath.Update: manage %d children\n", nmanage));
  901. XtManageChildren(manage, nmanage);
  902. }
  903. XtFree((char *)manage);
  904. /* reset icons_changed flag */
  905. ip->iconic_path.icons_changed = False;
  906. return n_changes;
  907. }
  908. /*--------------------------------------------------------------------
  909. * Iconic path redraw function
  910. *------------------------------------------------------------------*/
  911. static void
  912. IconicPathRedraw(
  913. DtIconicPathWidget ip)
  914. {
  915. FileMgrRec *file_mgr_rec = (FileMgrRec *)ip->iconic_path.file_mgr_rec;
  916. DialogData * dialog_data;
  917. FileMgrData *file_mgr_data;
  918. int i;
  919. int x, y, l;
  920. if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
  921. return;
  922. file_mgr_data = (FileMgrData *) dialog_data->data;
  923. if (ip->iconic_path.gc == None)
  924. {
  925. XGCValues gc_values;
  926. gc_values.foreground = ip->manager.foreground;
  927. gc_values.line_width = 2;
  928. ip->iconic_path.gc = XCreateGC(XtDisplay(ip), XtWindow(ip),
  929. GCForeground | GCLineWidth, &gc_values);
  930. }
  931. x = MWD(ip);
  932. y = ip->core.height - MHT(ip) - ip->iconic_path.dotdot_button->core.height
  933. - SPC(ip) - ICON_HT(ip)/2;
  934. if (ip->iconic_path.left_component > 0)
  935. {
  936. XSetLineAttributes(XtDisplay(ip), ip->iconic_path.gc,
  937. 2, LineOnOffDash, CapNotLast, JoinMiter);
  938. XSetDashes(XtDisplay(ip), ip->iconic_path.gc, 0, "\04", 1);
  939. l = ip->iconic_path.dotdot_button->core.width + SPC(ip) - 3;
  940. l = (l/4) * 4;
  941. XDrawLine(XtDisplay(ip), XtWindow(ip), ip->iconic_path.gc,
  942. x + 2 + l, y, x + 2, y);
  943. x += ip->iconic_path.dotdot_button->core.width + SPC(ip);
  944. XSetLineAttributes(XtDisplay(ip), ip->iconic_path.gc,
  945. 2, LineSolid, CapNotLast, JoinMiter);
  946. }
  947. for (i = ip->iconic_path.left_component;
  948. i < ip->iconic_path.num_components - 1;
  949. i++)
  950. {
  951. if (ip->iconic_path.components[i].icon_name != NULL &&
  952. ip->iconic_path.components[i+1].icon_name != NULL)
  953. {
  954. XDrawLine(XtDisplay(ip), XtWindow(ip), ip->iconic_path.gc,
  955. x + SPC(ip) +
  956. ip->iconic_path.components[i].icon->core.width + 1,
  957. y,
  958. x + SPC(ip) +
  959. ip->iconic_path.components[i].width + SPC(ip) - 1,
  960. y);
  961. }
  962. x += ip->iconic_path.components[i].width + SPC(ip);
  963. }
  964. }
  965. /*--------------------------------------------------------------------
  966. * Class initialize
  967. *------------------------------------------------------------------*/
  968. static void
  969. ClassInitialize( void )
  970. {
  971. baseClassExtRec.record_type = XmQmotif ;
  972. }
  973. static void
  974. ClassPartInitialize(
  975. WidgetClass w_class )
  976. {
  977. _XmFastSubclassInit( w_class, XmDRAWING_AREA_BIT) ;
  978. return ;
  979. }
  980. /*--------------------------------------------------------------------
  981. * Instance initialize
  982. *------------------------------------------------------------------*/
  983. static void
  984. Initialize(
  985. Widget rw,
  986. Widget nw,
  987. ArgList args,
  988. Cardinal *num_args )
  989. {
  990. DtIconicPathWidget new_w = (DtIconicPathWidget) nw ;
  991. FileMgrRec *file_mgr_rec = (FileMgrRec *)new_w->iconic_path.file_mgr_rec;
  992. new_w->iconic_path.msg_text = NULL;
  993. new_w->iconic_path.current_directory = NULL;
  994. new_w->iconic_path.directory_shown = NULL;
  995. new_w->iconic_path.large_shown = False;
  996. new_w->iconic_path.status_label = NULL;
  997. new_w->iconic_path.dotdot_button = NULL;
  998. new_w->iconic_path.dropzone_icon = NULL;
  999. new_w->iconic_path.num_components = 0;
  1000. new_w->iconic_path.components = NULL;
  1001. new_w->iconic_path.left_component = 0;
  1002. new_w->iconic_path.gc = None;
  1003. Update(new_w, file_mgr_rec, NULL);
  1004. return;
  1005. }
  1006. /*--------------------------------------------------------------------
  1007. * Instance destroy
  1008. *------------------------------------------------------------------*/
  1009. static void
  1010. Destroy(
  1011. Widget w )
  1012. {
  1013. DtIconicPathWidget ip = (DtIconicPathWidget) w;
  1014. int i;
  1015. /*
  1016. XtFree(ip->iconic_path.current_directory);
  1017. */
  1018. ip->iconic_path.current_directory = NULL;
  1019. XtFree(ip->iconic_path.msg_text);
  1020. ip->iconic_path.msg_text = NULL;
  1021. XtFree(ip->iconic_path.directory_shown);
  1022. ip->iconic_path.directory_shown = NULL;
  1023. for (i = 0; i < ip->iconic_path.num_components; i++)
  1024. {
  1025. XtFree(ip->iconic_path.components[i].path);
  1026. ip->iconic_path.components[i].path = NULL;
  1027. }
  1028. XtFree((char *)ip->iconic_path.components);
  1029. ip->iconic_path.components = NULL;
  1030. return;
  1031. }
  1032. /*--------------------------------------------------------------------
  1033. * General redisplay function called on exposure events
  1034. *------------------------------------------------------------------*/
  1035. static void
  1036. Redisplay(
  1037. Widget wid,
  1038. XEvent *event,
  1039. Region region )
  1040. {
  1041. DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
  1042. IconicPathRedraw (ip);
  1043. XmeRedisplayGadgets( (Widget) ip, event, region);
  1044. return ;
  1045. }
  1046. /*--------------------------------------------------------------------
  1047. * Resize
  1048. *------------------------------------------------------------------*/
  1049. static void
  1050. Resize(
  1051. Widget wid )
  1052. {
  1053. DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
  1054. FileMgrRec *file_mgr_rec = (FileMgrRec *)ip->iconic_path.file_mgr_rec;
  1055. DialogData *dialog_data;
  1056. FileMgrData *file_mgr_data;
  1057. if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
  1058. return;
  1059. file_mgr_data = (FileMgrData *) dialog_data->data;
  1060. Update(ip, file_mgr_rec, file_mgr_data);
  1061. return ;
  1062. }
  1063. /*--------------------------------------------------------------------
  1064. * GeometryManager
  1065. *------------------------------------------------------------------*/
  1066. static XtGeometryResult
  1067. GeometryManager(
  1068. Widget w,
  1069. XtWidgetGeometry *request,
  1070. XtWidgetGeometry *reply )
  1071. {
  1072. DtIconicPathWidget ip;
  1073. ip = (DtIconicPathWidget) w->core.parent;
  1074. if (IsQueryOnly(request)) return XtGeometryYes;
  1075. if (IsWidth(request)) w->core.width = request->width;
  1076. if (IsHeight(request)) w->core.height = request->height;
  1077. if (IsBorder(request)) w->core.border_width = request->border_width;
  1078. /* @@@ adjust layout ? */
  1079. return XtGeometryYes;
  1080. }
  1081. /*--------------------------------------------------------------------
  1082. * Re-layout children
  1083. *------------------------------------------------------------------*/
  1084. static void
  1085. ChangeManaged(
  1086. Widget wid )
  1087. {
  1088. DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
  1089. XtWidgetProc manager ;
  1090. XmeNavigChangeManaged((Widget) ip) ;
  1091. return;
  1092. }
  1093. /*--------------------------------------------------------------------
  1094. * SetValues
  1095. *------------------------------------------------------------------*/
  1096. static Boolean
  1097. SetValues(
  1098. Widget cw,
  1099. Widget rw,
  1100. Widget nw,
  1101. ArgList args,
  1102. Cardinal *num_args )
  1103. {
  1104. DtIconicPathWidget current = (DtIconicPathWidget) cw ;
  1105. DtIconicPathWidget ip = (DtIconicPathWidget) nw ;
  1106. FileMgrRec *file_mgr_rec = (FileMgrRec *)ip->iconic_path.file_mgr_rec;
  1107. DialogData *dialog_data;
  1108. FileMgrData *file_mgr_data;
  1109. Boolean redisplay;
  1110. dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
  1111. file_mgr_data = dialog_data? (FileMgrData *) dialog_data->data: NULL;
  1112. redisplay = (Update(ip, file_mgr_rec, file_mgr_data) > 0);
  1113. if (XtHeight(ip) != DESIRED_HEIGHT(ip)
  1114. || (Dimension)XtWidth(ip) < (Dimension)DESIRED_WIDTH(ip))
  1115. {
  1116. XtWidgetGeometry request;
  1117. XtWidgetGeometry reply;
  1118. request.request_mode = 0;
  1119. if (XtHeight(ip) != DESIRED_HEIGHT(ip))
  1120. {
  1121. request.request_mode |= CWHeight;
  1122. request.height = DESIRED_HEIGHT(ip);
  1123. }
  1124. if ((Dimension)XtWidth(ip) < (Dimension)DESIRED_WIDTH(ip))
  1125. {
  1126. request.request_mode |= CWWidth;
  1127. request.width = DESIRED_WIDTH(ip);
  1128. }
  1129. if (XtMakeGeometryRequest(nw, &request, &reply) != XtGeometryNo)
  1130. Update(ip, file_mgr_rec, file_mgr_data);
  1131. redisplay = True;
  1132. }
  1133. return redisplay;
  1134. }
  1135. /*--------------------------------------------------------------------
  1136. * QueryGeometry
  1137. *------------------------------------------------------------------*/
  1138. static XtGeometryResult
  1139. QueryGeometry(
  1140. Widget wid,
  1141. XtWidgetGeometry *intended,
  1142. XtWidgetGeometry *desired )
  1143. {
  1144. DtIconicPathWidget ip = (DtIconicPathWidget) wid ;
  1145. desired->width = DESIRED_WIDTH(ip);
  1146. desired->height = DESIRED_HEIGHT(ip);
  1147. /* deal with user initial size setting */
  1148. if (!XtIsRealized(wid))
  1149. {
  1150. if (XtWidth(wid) != 0) desired->width = XtWidth(wid) ;
  1151. if (XtHeight(wid) != 0) desired->height = XtHeight(wid) ;
  1152. }
  1153. return XmeReplyToQueryGeometry(wid, intended, desired) ;
  1154. }
  1155. static XmNavigability
  1156. WidgetNavigable(
  1157. Widget wid)
  1158. {
  1159. if( wid->core.sensitive
  1160. && wid->core.ancestor_sensitive
  1161. && ((XmManagerWidget) wid)->manager.traversal_on )
  1162. {
  1163. XmNavigationType nav_type
  1164. = ((XmManagerWidget) wid)->manager.navigation_type ;
  1165. if( (nav_type == XmSTICKY_TAB_GROUP)
  1166. || (nav_type == XmEXCLUSIVE_TAB_GROUP)
  1167. || ( (nav_type == XmTAB_GROUP)
  1168. && !_XmShellIsExclusive( wid)) )
  1169. {
  1170. return XmDESCENDANTS_TAB_NAVIGABLE ;
  1171. }
  1172. }
  1173. return XmNOT_NAVIGABLE ;
  1174. }
  1175. /*--------------------------------------------------------------------
  1176. * _DtCreateIconicPath: creates and returns a IconicPath widget.
  1177. *------------------------------------------------------------------*/
  1178. Widget
  1179. _DtCreateIconicPath(
  1180. Widget p,
  1181. String name,
  1182. ArgList args,
  1183. Cardinal n )
  1184. {
  1185. return( XtCreateWidget( name, dtIconicPathWidgetClass, p, args, n)) ;
  1186. }
  1187. /*--------------------------------------------------------------------
  1188. * UpdateIconicPath: update IconicPath widget.
  1189. *------------------------------------------------------------------*/
  1190. void
  1191. DtUpdateIconicPath(
  1192. FileMgrRec *file_mgr_rec,
  1193. FileMgrData *file_mgr_data,
  1194. Boolean icons_changed)
  1195. {
  1196. Arg args[8];
  1197. XtSetArg (args[0], DtNfileMgrRec, file_mgr_rec);
  1198. XtSetArg (args[1], DtNcurrentDirectory, file_mgr_data->current_directory);
  1199. XtSetArg (args[2], DtNlargeIcons, file_mgr_data->view == BY_NAME_AND_ICON);
  1200. XtSetArg (args[3], DtNiconsChanged, icons_changed);
  1201. XtSetArg (args[4], "statusMsg", !file_mgr_data->show_status_line);
  1202. XtSetValues(file_mgr_rec->iconic_path_da, args, 5);
  1203. }