dtinfo subtree dtinfo
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / Agents / LibraryAgentMotif.C
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 librararies 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 /* $TOG: LibraryAgentMotif.C /main/50 1998/07/27 14:20:02 mgreess $ */
24 /*
25  * (c) Copyright 1996 Digital Equipment Corporation.
26  * (c) Copyright 1996 Hewlett-Packard Company.
27  * (c) Copyright 1996 International Business Machines Corp.
28  * (c) Copyright 1996 Sun Microsystems, Inc.
29  * (c) Copyright 1996 Novell, Inc. 
30  * (c) Copyright 1994, 1996 FUJITSU LIMITED.
31  * (c) Copyright 1996 Hitachi.
32  */
33 /*
34  * Copyright (c) 1991 HaL Computer Systems, Inc.  All rights reserved.
35  * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
36  * States.  Use of a copyright notice is precautionary only and does not
37  * imply publication or disclosure.
38  * 
39  * This software contains confidential information and trade secrets of HaL
40  * Computer Systems, Inc.  Use, disclosure, or reproduction is prohibited
41  * without the prior express written permission of HaL Computer Systems, Inc.
42  * 
43  *                         RESTRICTED RIGHTS LEGEND
44  * Use, duplication, or disclosure by the Government is subject to
45  * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
46  * Technical Data and Computer Software clause at DFARS 252.227-7013.
47  *                        HaL Computer Systems, Inc.
48  *                  1315 Dell Avenue, Campbell, CA  95008
49  * 
50  */
51
52 #include <sys/stat.h>
53
54 #include <sstream>
55 #include <iostream>
56 using namespace std;
57
58 #define C_xList
59 #define L_Support
60
61 #define C_OutlineString
62 #define C_OutlineElement
63 #define C_OutlineList
64 #define C_TOC_Element
65 #define L_Basic
66
67 #define C_PrintPanelAgent
68 #define C_HelpAgent
69 #define C_LibraryAgent
70 #define C_NodeWindowAgent
71 #define C_NodeViewInfo
72 #define C_OutlineListView
73 #define C_AddLibraryAgent
74 #define C_ScopeMenu
75 #define C_BookmarkEdit
76 #define L_Agents
77
78 #define C_ListView
79 #define C_NodeMgr
80 #define C_MapMgr
81 #define C_LibraryMgr
82 #define C_GlobalHistoryMgr
83 #define C_PrintMgr
84 #define C_SearchMgr
85 #define C_SearchScopeMgr
86 #define C_MessageMgr
87 #define C_PrefMgr
88 #define C_EnvMgr
89 #define C_GraphicsMgr
90 #define L_Managers
91
92
93 #define USES_OLIAS_FONT
94
95 #include "UAS.hh"
96 #include "Managers/CatMgr.hh"
97 #include "Other/XmStringLocalized.hh"
98
99 #include "Prelude.h"
100
101 #include "Registration.hh"
102
103 #include <WWL/WTopLevelShell.h>
104 #include <Xm/MainW.h>
105 #include <Xm/RowColumn.h>
106 #include <Xm/PushBG.h>
107 #include <Xm/PushB.h>
108 #include <Xm/ToggleBG.h>
109 #include <Xm/CascadeBG.h>
110 #include <Xm/SeparatoG.h>
111 #include <Xm/TextF.h>
112 extern "C" {
113 #include <Xm/TransferP.h>
114 }
115 #include <Dt/Dnd.h>
116 #include <Tt/tt_c.h>
117 #include <WWL/WXmPushButtonGadget.h>
118 #include <WWL/WXmFrame.h>
119 #include <WWL/WXmCascadeButtonGadget.h>
120 #include <WWL/WXmCascadeButton.h>
121
122 static BitHandle g_handle;
123 static bool g_ignore_wm_delete;
124
125
126 struct TrackingEntry
127 {
128   TrackingEntry (UAS_Pointer<UAS_Common> &toc, TrackingEntry *child)
129     : f_toc (toc), f_child (child) { }
130
131   UAS_Pointer<UAS_Common>    f_toc;
132   TrackingEntry  *f_child;
133 };
134
135
136 // /////////////////////////////////////////////////////////////////
137 // class destructor
138 // /////////////////////////////////////////////////////////////////
139
140 LibraryAgent::~LibraryAgent()
141 {
142   if (f_shell != NULL)
143   {
144     //f_shell->Destroy();
145     XtDestroyWidget(f_shell);
146   }
147   delete f_doc_tree_view;
148   delete f_wm_delete_callback;
149   delete f_scope_menu;
150   free_tracking_hierarchy();
151 }
152   
153
154 // /////////////////////////////////////////////////////////////////
155 // display
156 // /////////////////////////////////////////////////////////////////
157
158 void
159 LibraryAgent::display (OutlineList *f_outline_list)
160 {
161   if (f_shell == NULL)
162   {
163     create_ui();
164   }
165
166   // NOTE: More of the evil hack... 00:20 01/14/93 DJB
167   // g_handle is the handle of the list that this one was detached from.
168   // We want the new list to have the same state as the new one, so we
169   // copy the expanded state bits to the position that will be allocated
170   // when the list is created. 
171   if (g_handle != 0)
172     {
173       ON_DEBUG (puts (">> Copying expanded entries for DETACH!"));
174       BitHandle handle = library_mgr().library()->get_data_handle();
175       f_outline_list->copy_expanded (g_handle, handle);
176       f_doc_tree_view->set_list (f_outline_list, handle);
177     }
178   else
179     {
180       f_doc_tree_view->set_list (f_outline_list);
181     }
182
183   //f_wm_delete_callback =
184     //new WCallback (*f_shell, window_system().WM_DELETE_WINDOW(),
185                    //this, (WWL_FUN) &LibraryAgent::close_window);
186
187   popup();
188
189   // moved to EnvMgr()--also, don't need to support AutoHelp since
190   // only the script sent this message to dtinfo< ie this is not
191   // a user option.
192   // Display some initial help for newbie users if AutoHelp is on. 
193 #ifdef EAM
194   static bool initial_help = True;
195   if (initial_help && pref_mgr().get_boolean (PrefMgr::AutomaticHelp))
196     {
197       initial_help = False;
198       help_agent().display_help ("doc_list_help");
199     }
200 #endif
201 }
202
203 void
204 LibraryAgent::popup()
205 {
206   f_popped_down = FALSE;
207   track_to (node_mgr().last_displayed());
208   //f_shell->Popup();
209   //f_shell->DeIconify();
210   XtPopup(f_shell, XtGrabNone);
211   // insure booklist gets raised when asynchronous requests require
212   // it in a new workspace...
213   //XRaiseWindow (XtDisplay ((Widget)f_shell), XtWindow ((Widget)f_shell));
214   XMapRaised (XtDisplay (f_shell), XtWindow (f_shell));
215 }
216
217 // /////////////////////////////////////////////////////////////////
218 // file Callbacks
219 // /////////////////////////////////////////////////////////////////
220
221 static void
222 exitCB(Widget, XtPointer client_data, XtPointer)
223 {
224   Widget f_shell = (Widget) client_data;
225
226   if (BookmarkEdit::modified_count() > 0)
227     {
228       if (! message_mgr().question_dialog(
229                 (char*)UAS_String(CATGETS(Set_Messages, 5,
230                         "There are unsaved bookmarks open.\n"
231                         "Quit without saving them?")),
232                 f_shell))
233           return;
234     }
235   
236   //XtPopup(f_shell, XtGrabNone);
237   //if (XtIsRealized(f_shell)) XMapRaised(XtDisplay(f_shell), XtWindow(f_shell));
238
239   message_mgr().quit_dialog(
240       (char*)UAS_String(CATGETS(Set_Messages, 6, "Quit Dtinfo?")), f_shell);
241 }
242
243 // /////////////////////////////////////////////////////////////////
244 // edit Callbacks
245 // /////////////////////////////////////////////////////////////////
246
247 static void
248 copyCB(Widget, XtPointer client_data, XtPointer)
249 {
250   LibraryAgent *agent = (LibraryAgent *)client_data;
251   agent->copy_to_clipbd();
252 }
253
254 // /////////////////////////////////////////////////////////////////
255 // options Callbacks
256 // /////////////////////////////////////////////////////////////////
257
258 static void
259 prefsCB(Widget, XtPointer, XtPointer)
260
261 {
262   pref_mgr().display();
263 }
264
265 static void
266 tool_bar_toggleCB(Widget, XtPointer client_data, XtPointer call_data)
267 {
268   Widget tool_bar = (Widget) client_data;
269   XmToggleButtonCallbackStruct *cdata =
270       (XmToggleButtonCallbackStruct *) call_data;
271
272   if (cdata->set)
273       XtManageChild(tool_bar);
274   else
275       XtUnmanageChild(tool_bar);
276 }
277
278 static void
279 search_area_toggleCB(Widget, XtPointer client_data, XtPointer call_data)
280 {
281   Widget search_area = (Widget) client_data;
282   XmToggleButtonCallbackStruct *cdata =
283       (XmToggleButtonCallbackStruct *) call_data;
284
285   if (cdata->set)
286       XtManageChild(search_area);
287   else
288       XtUnmanageChild(search_area);
289 }
290
291 // /////////////////////////////////////////////////////////////////
292 // windows Callbacks
293 // /////////////////////////////////////////////////////////////////
294
295 static void
296 mark_listCB(Widget, XtPointer, XtPointer)
297 {
298   mark_mgr().display_mark_list();
299 }
300
301 static void
302 section_historyCB(Widget, XtPointer, XtPointer)
303 {
304   global_history_mgr().display();
305 }
306
307 static void
308 search_historyCB(Widget, XtPointer, XtPointer)
309 {
310   search_mgr().search_history_list_view().display();
311 }
312
313 static void
314 query_editorCB(Widget, XtPointer, XtPointer)
315 {
316   search_mgr().display_editor();
317 }
318
319 static void
320 scope_editorCB(Widget, XtPointer, XtPointer)
321 {
322   search_scope_mgr().display();
323 }
324
325 // /////////////////////////////////////////////////////////////////
326 // create_ui
327 // /////////////////////////////////////////////////////////////////
328
329 #define ON_ACTIVATE(WOBJ,FUNC) \
330   (WOBJ).SetActivateCallback (this, (WWL_FUN) &LibraryAgent::FUNC)
331
332 void
333 LibraryAgent::create_ui()
334 {
335   Widget widget;
336   Arg args[5];
337   int n;
338
339   String            string;
340   UAS_Pointer<UAS_String> help_text;
341
342 #if 0
343   f_shell = (WTopLevelShell*)(Widget)
344       WTopLevelShell (toplevel(), WPopup, "doc_tree");
345 #endif
346
347   f_shell = window_system().toplevel();
348   window_system().register_shell ((WTopLevelShell*)f_shell);
349
350   // set title of doc_tree
351   string = CATGETS(Set_LibraryAgent, 3, "Dtinfo: Book List");
352   XtVaSetValues(f_shell, XmNtitle, string, NULL);
353
354   // just use "delete_response" instead
355   // add a destroy callback to nuke the agent when widget is destroyed.
356
357   XtAddCallback(f_shell, XmNdestroyCallback, ui_destroyedCB, this);
358
359
360   Widget mainw = XtCreateWidget("mainw", xmMainWindowWidgetClass,
361                                 f_shell, 0, 0);
362
363
364   n = 0;
365   XtSetArg(args[n], XmNscrolledWindowChildType, XmMENU_BAR); n++;
366   Widget menu_bar = XmCreateMenuBar(mainw, (char*)"menu_bar", args, n);
367
368   n = 0;
369   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
370   XtSetArg(args[n], XmNscrolledWindowChildType, XmCOMMAND_WINDOW); n++;
371   Widget tool_bar = XtCreateWidget("tool_bar", xmRowColumnWidgetClass,
372                                    mainw, args, n);
373
374   n = 0;
375   XtSetArg(args[n], XmNscrolledWindowChildType, XmMESSAGE_WINDOW); n++;
376   Widget search_area = XtCreateWidget("search_area", xmFormWidgetClass,
377                                       mainw, args, n);
378
379   // Menus
380   Widget fileM = XmCreatePulldownMenu(menu_bar, (char*)"file_menu", 0, 0);
381
382   n = 0;
383   XtSetArg(args[n], XmNsubMenuId, fileM); n++;
384   widget = XtCreateManagedWidget("file", xmCascadeButtonGadgetClass, menu_bar, args, n);
385   XtVaSetValues(widget,
386         XmNlabelString,
387         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 1, "File")),
388         XmNmnemonic,
389         *CATGETS(Set_AgentLabel, 2, ""),
390         NULL);
391   help_agent().add_help_cb(widget);
392
393   f_view = XtCreateManagedWidget("view",
394                                  xmPushButtonGadgetClass, fileM, 0, 0);
395   XtAddCallback(f_view, XmNactivateCallback, display_nodeCB, this);
396
397   // add labelString to f_view
398
399   XtVaSetValues(f_view,
400         XmNlabelString,
401         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 4, "View")),
402         XmNmnemonic,
403         *CATGETS(Set_AgentLabel, 5, ""),
404         NULL);
405
406 #ifdef AllowDetach
407   f_detach = XtCreateManagedWidget("detach",
408                                    xmPushButtonGadgetClass, fileM, 0, 0);
409   XtAddCallback(f_detach, XmNactivateCallback, detach_subtreeCB, this);
410
411   // add labelString to f_detach
412   XtVaSetValues(f_detach,
413         XmNlabelString,
414         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 6, "Detach")),
415         XmNmnemonic,
416         *CATGETS(Set_AgentLabel, 7, ""),
417         NULL);
418 #endif
419
420   XtCreateManagedWidget("sep1", xmSeparatorGadgetClass, fileM, 0, 0);
421
422   n = 0;
423   XtSetArg(args[n], XmNsensitive, FALSE); n++;
424   f_print_as = XtCreateManagedWidget("print_as",
425                                      xmPushButtonGadgetClass, fileM, args, n);
426   XtAddCallback(f_print_as, XmNactivateCallback, print_asCB, this);
427   // add labelString to f_print_as
428   XtVaSetValues(f_print_as,
429         XmNlabelString,
430         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 10, "Print...")),
431         XmNmnemonic,
432         *CATGETS(Set_AgentLabel, 9, "P"),
433         NULL);
434
435   XtCreateManagedWidget("sep2", xmSeparatorGadgetClass, fileM, 0, 0);
436
437   n = 0;
438   XtSetArg(args[n], XmNsensitive, f_close_sensitive); n++;
439   f_close = XtCreateManagedWidget("close",
440                                   xmPushButtonGadgetClass, fileM, args, n);
441   XtAddCallback(f_close, XmNactivateCallback, close_windowCB, this);
442   // add labelString to f_close
443   XtVaSetValues(f_close,
444         XmNlabelString,
445         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 12, "Close")),
446         XmNmnemonic,
447         *CATGETS(Set_AgentLabel, 13, ""),
448         NULL);
449
450   widget = XtCreateManagedWidget("exit", xmPushButtonGadgetClass, fileM, 0, 0);
451   XtAddCallback(widget, XmNactivateCallback, exitCB, f_shell);
452   // add labelString to "exit"
453   XtVaSetValues(widget,
454         XmNlabelString,
455         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 14, "Exit")),
456         XmNmnemonic,
457         *CATGETS(Set_AgentLabel, 15, ""),
458         NULL);
459
460   // edit menu
461   Widget editM = XmCreatePulldownMenu(menu_bar, (char*)"edit_menu", 0, 0);
462
463   n = 0;
464   XtSetArg(args[n], XmNsubMenuId, editM); n++;
465   widget = XtCreateManagedWidget("edit", xmCascadeButtonGadgetClass,
466                                 menu_bar, args, n);
467   // add labelString to "edit"
468   XtVaSetValues(widget,
469         XmNlabelString,
470         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 16, "Edit")),
471         XmNmnemonic,
472         *CATGETS(Set_AgentLabel, 17, ""),
473         NULL);
474   help_agent().add_help_cb(widget);
475
476   f_copy = XtCreateManagedWidget("copy", xmPushButtonGadgetClass, editM, 0, 0);
477   //XtSetSensitive(f_copy, True);
478   XtAddCallback(f_copy, XmNactivateCallback, copyCB, this);
479   // add labelString to "copy"
480   XtVaSetValues(f_copy,
481         XmNlabelString,
482         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 18, "Copy")),
483         XmNmnemonic,
484         *CATGETS(Set_AgentLabel, 19, ""),
485         NULL);
486
487   widget = XtCreateManagedWidget("add", xmPushButtonWidgetClass, editM, 0, 0);
488   XtAddCallback(widget, XmNactivateCallback, add_libraryCB, this);
489   // add labelString to "add"
490   XtVaSetValues(widget,
491         XmNlabelString,
492         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 20, "Add...")),
493         XmNmnemonic,
494         *CATGETS(Set_AgentLabel, 21, ""),
495         NULL);
496
497   f_remove = XtCreateManagedWidget("remove",
498                                    xmPushButtonGadgetClass, editM, 0, 0);
499   XtAddCallback(f_remove, XmNactivateCallback, remove_libraryCB, this);
500   // add labelString to "remove"
501   XtVaSetValues(f_remove,
502         XmNlabelString,
503         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 22, "Remove")),
504         XmNmnemonic,
505         *CATGETS(Set_AgentLabel, 23, ""),
506         NULL);
507
508   // options menu
509   Widget optionsM = XmCreatePulldownMenu(menu_bar, (char*)"options_menu", 0, 0);
510
511   n = 0;
512   XtSetArg(args[n], XmNsubMenuId, optionsM); n++;
513   widget = XtCreateManagedWidget("options", xmCascadeButtonGadgetClass,
514                         menu_bar, args, n);
515   // add labelString to "options"
516   XtVaSetValues(widget,
517         XmNlabelString,
518         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 24, "Options")),
519         XmNmnemonic,
520         *CATGETS(Set_AgentLabel, 25, ""),
521         NULL);
522   help_agent().add_help_cb(widget);
523
524   widget = XtCreateManagedWidget("preferences", xmPushButtonGadgetClass,
525                               optionsM, 0, 0);
526   XtAddCallback(widget, XmNactivateCallback, prefsCB, 0);
527   // add labelString to "preferences"
528   XtVaSetValues(widget,
529         XmNlabelString,
530         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 26, "Preferences...")),
531         XmNmnemonic,
532         *CATGETS(Set_AgentLabel, 27, ""),
533         NULL);
534
535   XtCreateManagedWidget("sep1", xmSeparatorGadgetClass, optionsM, 0, 0);
536
537   f_auto_track = XtCreateManagedWidget("auto_track",
538                                        xmToggleButtonGadgetClass,
539                                        optionsM, 0, 0);
540   XtAddCallback(f_auto_track, XmNvalueChangedCallback,
541                 auto_track_toggleCB, this);
542   // add labelString to "auto_track"
543   XtVaSetValues(f_auto_track,
544         XmNlabelString,
545         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 28, "Auto Track")),
546         XmNmnemonic,
547         *CATGETS(Set_AgentLabel, 29, ""),
548         NULL);
549
550   Widget tool_barT = XtCreateManagedWidget("show_tool_bar",
551                                            xmToggleButtonGadgetClass,
552                                            optionsM, 0, 0);
553   XtAddCallback(tool_barT, XmNvalueChangedCallback,
554                 tool_bar_toggleCB, tool_bar);
555   // add labelString to "show_tool_bar"
556   XtVaSetValues(tool_barT,
557         XmNlabelString,
558         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 30, "Show ToolBar")),
559         XmNmnemonic,
560         *CATGETS(Set_AgentLabel, 31, ""),
561         NULL);
562
563   Widget search_areaT = XtCreateManagedWidget("show_search_area",
564                                               xmToggleButtonGadgetClass,
565                                               optionsM, 0, 0);
566   XtAddCallback(search_areaT, XmNvalueChangedCallback,
567                 search_area_toggleCB, search_area);
568   // add labelString to "show_search_area"
569   XtVaSetValues(search_areaT,
570         XmNlabelString,
571         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 32, "Show Search Area")),
572         XmNmnemonic,
573         *CATGETS(Set_AgentLabel, 33, ""),
574         NULL);
575
576   // windows menu
577   Widget windowsM = XmCreatePulldownMenu(menu_bar, (char*)"windows_menu", 0, 0);
578
579   n = 0;
580   XtSetArg(args[n], XmNsubMenuId, windowsM); n++;
581   widget = XtCreateManagedWidget("windows", xmCascadeButtonGadgetClass,
582                                 menu_bar, args, n);
583   // add labelString to "windows"
584   XtVaSetValues(widget,
585         XmNlabelString,
586         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 34, "Windows")),
587         XmNmnemonic,
588         *CATGETS(Set_AgentLabel, 35, ""),
589         NULL);
590   help_agent().add_help_cb(widget);
591
592   widget = XtCreateManagedWidget("marks_list", xmPushButtonGadgetClass,
593                               windowsM, 0, 0);
594   XtAddCallback(widget, XmNactivateCallback, mark_listCB, 0);
595   XtVaSetValues(widget,
596         XmNlabelString,
597         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 40, "Marks List")),
598         XmNmnemonic,
599         *CATGETS(Set_AgentLabel, 41, ""),
600         NULL);
601
602   widget = XtCreateManagedWidget("section_history", xmPushButtonGadgetClass,
603                               windowsM, 0, 0);
604   XtAddCallback(widget, XmNactivateCallback, section_historyCB, 0);
605   XtVaSetValues(widget,
606         XmNlabelString,
607         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 38, "Section History")),
608         XmNmnemonic,
609         *CATGETS(Set_AgentLabel, 39, ""),
610         NULL);
611
612   widget = XtCreateManagedWidget("search_history", xmPushButtonGadgetClass,
613                               windowsM, 0, 0);
614   XtAddCallback(widget, XmNactivateCallback, search_historyCB, 0);
615   XtVaSetValues(widget,
616         XmNlabelString,
617         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 42, "Search History")),
618         XmNmnemonic,
619         *CATGETS(Set_AgentLabel, 43, ""),
620         NULL);
621
622   widget = XtCreateManagedWidget("query", xmPushButtonGadgetClass,
623                               windowsM, 0, 0);
624   XtAddCallback(widget, XmNactivateCallback, query_editorCB, 0);
625   XtVaSetValues(widget,
626         XmNlabelString,
627         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 44, "Query Editor")),
628         XmNmnemonic,
629         *CATGETS(Set_AgentLabel, 45, ""),
630         NULL);
631
632   widget = XtCreateManagedWidget("scope", xmPushButtonGadgetClass,
633                               windowsM, 0, 0);
634   XtAddCallback(widget, XmNactivateCallback, scope_editorCB, 0);
635   XtVaSetValues(widget,
636         XmNlabelString,
637         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 46, "Scope Editor")),
638         XmNmnemonic,
639         *CATGETS(Set_AgentLabel, 47, ""),
640         NULL);
641
642   Widget helpM = XmCreatePulldownMenu(menu_bar, (char*)"help_menu", 0, 0);
643
644   // create help menu
645   n = 0;
646   XtSetArg(args[n], XmNsubMenuId, helpM); n++;
647   widget = XtCreateManagedWidget("help", xmCascadeButtonGadgetClass,
648                               menu_bar, args, n);
649   XtVaSetValues(widget,
650         XmNlabelString,
651         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 48, "Help")),
652         XmNmnemonic,
653         *CATGETS(Set_AgentLabel, 49, ""),
654         NULL);
655   help_agent().add_help_cb(widget);
656   n = 0;
657   XtSetArg(args[n], XmNmenuHelpWidget, widget); n++;
658   XtSetValues(menu_bar, args, n);
659
660 #if EAM
661
662   widget = XtCreateManagedWidget("help", xmPushButtonGadgetClass,
663                               helpM, 0, 0);
664   XtVaSetValues(widget,
665         XmNlabelString,
666         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 50, "On Item...")),
667         XmNmnemonic,
668         *CATGETS(Set_AgentLabel, 51, ""),
669         NULL);
670
671 #endif
672
673   Widget on_overview, on_tasks, on_reference;
674   Widget on_item, on_help, on_about, sep;
675
676   on_overview = XtCreateManagedWidget("on_overview", xmPushButtonGadgetClass,
677                               helpM, 0, 0);
678   XtVaSetValues(on_overview,
679         XmNlabelString,
680         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 257, "Overview")),
681         XmNmnemonic,
682         *CATGETS(Set_AgentLabel, 258, ""),
683         NULL);
684
685   sep = XtCreateManagedWidget("sep", xmSeparatorGadgetClass,
686                               helpM, 0, 0);
687   on_tasks = XtCreateManagedWidget("on_tasks", xmPushButtonGadgetClass,
688                               helpM, 0, 0);
689   XtVaSetValues(on_tasks,
690         XmNlabelString,
691         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 249, "Tasks")),
692         XmNmnemonic,
693         *CATGETS(Set_AgentLabel, 250, ""),
694         NULL);
695
696   on_reference = XtCreateManagedWidget("on_reference", xmPushButtonGadgetClass,
697                               helpM, 0, 0);
698   XtVaSetValues(on_reference,
699         XmNlabelString,
700         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 251, "Reference")),
701         XmNmnemonic,
702         *CATGETS(Set_AgentLabel, 252, ""),
703         NULL);
704   on_item = XtCreateManagedWidget("on_item", xmPushButtonGadgetClass,
705                               helpM, 0, 0);
706   XtVaSetValues(on_item,
707         XmNlabelString,
708         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 50, "On Item...")),
709         XmNmnemonic,
710         *CATGETS(Set_AgentLabel, 51, ""),
711         NULL);
712   sep = XtCreateManagedWidget("sep", xmSeparatorGadgetClass,
713                               helpM, 0, 0);
714   on_help = XtCreateManagedWidget("on_help", xmPushButtonGadgetClass,
715                               helpM, 0, 0);
716   XtVaSetValues(on_help,
717         XmNlabelString,
718         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 253, "Using Help")),
719         XmNmnemonic,
720         *CATGETS(Set_AgentLabel, 254, ""),
721         NULL);
722   sep = XtCreateManagedWidget("sep", xmSeparatorGadgetClass,
723                               helpM, 0, 0);
724   on_about = XtCreateManagedWidget("on_about", xmPushButtonGadgetClass,
725                               helpM, 0, 0);
726   XtVaSetValues(on_about,
727         XmNlabelString,
728         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 255, "About Information Manager")),
729         XmNmnemonic,
730         *CATGETS(Set_AgentLabel, 256, ""),
731         NULL);
732
733   // WXmPushButtonGadget tmp_pbg(tmp);
734   // help_agent().add_activate_help (tmp_pbg, "doc_list_help");
735   WXmPushButtonGadget on_overview_pbg(on_overview);
736   help_agent().add_activate_help (on_overview, (char*)"on_overview");
737   WXmPushButtonGadget on_tasks_pbg(on_tasks);
738   help_agent().add_activate_help (on_tasks, (char*)"on_tasks");
739   WXmPushButtonGadget on_reference_pbg(on_reference);
740   help_agent().add_activate_help (on_reference, (char*)"on_reference");
741   WXmPushButtonGadget on_item_pbg(on_item);
742   help_agent().add_context_help (on_item);
743   WXmPushButtonGadget on_help_pbg(on_help);
744   help_agent().add_activate_help (on_help,  (char*)"on_help");
745   WXmPushButtonGadget on_about_pbg(on_about);
746   help_agent().add_activate_help (on_about, (char*)"on_about");
747
748   // Tools
749   f_view2 = XtCreateManagedWidget("view", xmPushButtonWidgetClass,
750                                   tool_bar, 0, 0);
751   XtAddCallback(f_view2, XmNactivateCallback, display_nodeCB, this);
752   help_text = new UAS_String(
753                 CATGETS(Set_AgentQHelp, 52, "Display selected section"));
754   add_quick_help(f_view2, (char*)*help_text);
755   f_help_text.insert_item(help_text);
756   help_agent().add_help_cb(f_view2);
757
758
759
760 #ifdef AllowDetach
761   // decision made to remove detach capabilities from CDE 2.1, rCs 6-14-96
762   f_detach2 = XtCreateManagedWidget("detach", xmPushButtonWidgetClass,
763                                     tool_bar, 0, 0);
764   XtAddCallback(f_detach2, XmNactivateCallback, detach_subtreeCB, this);
765   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 53, "Display selected section in a separate Book List"));
766   add_quick_help(f_detach2, (char*)*help_text);
767   f_help_text.insert_item(help_text);
768 #endif
769
770   f_print2 = XtCreateManagedWidget("print", xmPushButtonWidgetClass,
771                                    tool_bar, 0, 0);
772   XtAddCallback(f_print2, XmNactivateCallback, printCB, this);
773   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 54,
774                                      "Print selected section"));
775   add_quick_help(f_print2, (char*)*help_text);
776   f_help_text.insert_item(help_text);
777   help_agent().add_help_cb(f_print2);
778
779   widget = XtCreateManagedWidget("add", xmPushButtonWidgetClass, tool_bar, 0, 0);
780   XtAddCallback(widget, XmNactivateCallback, add_libraryCB, this);
781   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 55,
782                                 "Open an additional information library"));
783   add_quick_help(widget, (char*)*help_text);
784   f_help_text.insert_item(help_text);
785   help_agent().add_help_cb(widget);
786
787   f_remove2 = XtCreateManagedWidget("remove", xmPushButtonWidgetClass,
788                                     tool_bar, 0, 0);
789   XtAddCallback(f_remove2, XmNactivateCallback, remove_libraryCB, this);
790   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 56,
791                                 "Close selected information library"));
792   add_quick_help(f_remove2, (char*)*help_text);
793   f_help_text.insert_item(help_text);
794   help_agent().add_help_cb(f_remove2);
795
796   widget = XtCreateManagedWidget("query", xmPushButtonWidgetClass,
797                               tool_bar, 0, 0);
798   XtAddCallback(widget, XmNactivateCallback, query_editorCB, 0);
799   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 57,
800                                 "Perform a search using the Query Editor"));
801   add_quick_help(widget, (char*)*help_text);
802   f_help_text.insert_item(help_text);
803   help_agent().add_help_cb(widget);
804
805
806   widget = XtCreateManagedWidget("marks_list", xmPushButtonWidgetClass,
807                               tool_bar, 0, 0);
808   XtAddCallback(widget, XmNactivateCallback, mark_listCB, 0);
809   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 58,
810                                 "Display the bookmarks and notes list"));
811   add_quick_help(widget, (char*)*help_text);
812   f_help_text.insert_item(help_text);
813   help_agent().add_help_cb(widget);
814
815   n = 0;
816   XtSetArg(args[n], XmNscrolledWindowChildType, XmWORK_AREA); n++;
817   Widget form = XtCreateWidget("form", xmFormWidgetClass, mainw, args, n);
818
819   // this needs to be here for reference through the resources (attachments)
820   Widget message = XtCreateManagedWidget("message", xmFrameWidgetClass,
821                                          form, 0, 0);
822
823   // Booklist
824   // we need a WXmFrame to pass to the following list
825   WXmFrame frame = WXmFrame(form, "frame", WAutoManage, 0, 0);
826
827   f_doc_tree_view = new OutlineListView(frame, "doc_list", WAutoManage, True);
828   help_agent().add_help_cb((Widget)*f_doc_tree_view);
829
830
831 #ifdef DtinfoClient
832   Atom atoms[4];
833   atoms[0] = XInternAtom(XtDisplay(*f_doc_tree_view), "_DT_NETFILE", False);
834   atoms[1] = XInternAtom(XtDisplay(*f_doc_tree_view), "FILE_NAME",   False);
835   atoms[2] = XA_TEXT(XtDisplay(*f_doc_tree_view));
836   atoms[3] = None;
837   n = 0;
838   XtSetArg(args[n], XmNimportTargets, atoms); n++;
839   XtSetArg(args[n], XmNnumImportTargets, 3); n++;
840   // becoming a sink of drag and drop
841   XmeDropSink((Widget)*f_doc_tree_view, args, n);
842   // add destination callback
843   XtAddCallback((Widget)*f_doc_tree_view, XmNdestinationCallback, destCB, this);
844 #endif
845
846   //  XtAddCallback(f_print, XmNactivateCallback, PrintButtonCB, window_system().GetAppPrintData());
847
848   f_doc_tree_view->set_agent (this);
849
850   Observe (f_doc_tree_view, OutlineListView::ENTRY_SELECTED,
851            &LibraryAgent::entry_selected);
852   UAS_Common::request ((UAS_Receiver<UAS_DocumentRetrievedMsg> *) this);
853
854   // Status line - force its colors to the same as its parent's ones
855   Pixel fg, bg;
856   n = 0;
857   XtSetArg(args[n], XmNforeground, &fg); n++;
858   XtSetArg(args[n], XmNbackground, &bg); n++;
859   XtGetValues(message, args, n);
860   n = 0;
861   XtSetArg(args[n], XmNforeground, fg); n++;
862   XtSetArg(args[n], XmNbackground, bg); n++;
863   f_status_text = XtCreateManagedWidget("text", xmTextFieldWidgetClass,
864                                         message, args, n);
865   string = CATGETS(Set_LibraryAgent, 63, "Welcome to Dtinfo!");
866   XtVaSetValues(f_status_text, XmNvalue, string, NULL);
867
868   // Search area
869   widget = XmCreatePulldownMenu(search_area, (char*)"scope_menu", 0, 0);
870
871   n = 0;
872   XtSetArg(args[n], XmNsubMenuId, widget); n++;
873   XtManageChild(widget = XmCreateOptionMenu(search_area, (char*)"scope", args, n));
874   XtVaSetValues(widget,
875         XmNlabelString,
876         (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 59, "Search:")),
877         NULL);
878   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 60,
879                                      "Specify search scope"));
880   add_quick_help(widget, (char*)*help_text);
881   f_help_text.insert_item(help_text);
882   help_agent().add_help_cb(widget);
883
884   // hookup the ScopeMenu object here
885   f_scope_menu = new ScopeMenu (widget);
886
887   n = 0;
888   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
889   XtSetArg(args[n], XmNleftWidget, widget); n++;
890
891   // print callback pass a pointer to the AppPrintData class as client data
892   
893   //  f_print_button->SetActivateCallback(this, 
894   //                                 (WWL_FUN) &LibraryAgent::print_panel_activate,
895   //                                 );
896
897   WXmTextField *search_text = (WXmTextField*)(Widget)
898       WXmTextField (search_area, "text", WAutoManage, args, n);
899   XtAddEventHandler (*search_text, EnterWindowMask, False,
900                      (XtEventHandler) search_help, (XtPointer) this);
901   XtAddEventHandler (*search_text, LeaveWindowMask, False,
902                      (XtEventHandler) search_help, (XtPointer) this);
903   XtAddEventHandler (*search_text, FocusChangeMask, False,
904                      (XtEventHandler) search_help, (XtPointer) this);
905   ON_ACTIVATE (*search_text,            text_callback);
906   help_agent().add_help_cb((Widget)search_text);
907
908
909   widget = XtCreateManagedWidget("scope_editor", xmPushButtonWidgetClass,
910                               search_area, 0, 0);
911   XtAddCallback(widget, XmNactivateCallback, scope_editorCB, 0);
912   XtVaSetValues(widget,
913     XmNlabelString,
914     (XmString)XmStringLocalized(CATGETS(Set_AgentLabel, 61, "Scope Editor")),
915     NULL);
916   help_text = new UAS_String(CATGETS(Set_AgentQHelp, 62,
917                              "Specify search scope using the Scope Editor"));
918   add_quick_help(widget, (char*)*help_text);
919   f_help_text.insert_item(help_text);
920   help_agent().add_help_cb(widget);
921
922
923   // set right attachment here since it cannot be set at creation time
924   XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
925   XtSetArg(args[n], XmNrightWidget, widget); n++;
926   XtSetValues(*search_text, args, n);
927
928   XtManageChild(form);
929   XtManageChild(menu_bar);
930   if (XmToggleButtonGadgetGetState(tool_barT))
931       XtManageChild(tool_bar);
932   if (XmToggleButtonGadgetGetState(search_areaT))
933       XtManageChild(search_area);
934   XtManageChild(frame);
935   XtManageChild(mainw);
936
937   f_wm_delete_callback =
938     new WCallback (f_shell, window_system().WM_DELETE_WINDOW(),
939                    this, (WWL_FUN) &LibraryAgent::close_window);
940 }
941
942 //////////////////////////////////////////////////////////////////
943 // close_window
944 // /////////////////////////////////////////////////////////////////
945
946 void
947 LibraryAgent::close_windowCB(Widget, XtPointer client_data, XtPointer)
948 {
949   LibraryAgent *agent = (LibraryAgent *)client_data;
950   agent->close_window();
951 }
952
953 void
954 LibraryAgent::close_window()
955 {
956   if (g_ignore_wm_delete)
957     return;
958   if (!XtIsSensitive(f_close)) {
959       exitCB(0, f_shell, 0);
960       return;
961   }
962   if (f_keep_forever)
963     {
964       f_popped_down = TRUE;
965       f_doc_tree_view->untrack();
966       //f_shell->Popdown();
967       XtPopdown(f_shell);
968       library_mgr().agent_unmapped(this);
969     }
970   else
971     {
972       delete this;
973     }
974 }
975
976 // /////////////////////////////////////////////////////////////////
977 // add_quick_help
978 // /////////////////////////////////////////////////////////////////
979
980 void
981 LibraryAgent::add_quick_help (Widget w, const char* help_text)
982 {
983   if (help_text == NULL || *help_text == '\0') {
984     XtVaSetValues(w, XmNuserData, NULL, NULL);
985     return;
986   }
987
988   XtVaSetValues(w, XmNuserData, (void*)this, NULL);
989
990   // Now add the event handlers to display the quick help.
991   XtAddEventHandler (w, EnterWindowMask, False, quick_helpEH, (XtPointer)help_text);
992   XtAddEventHandler (w, LeaveWindowMask, False, quick_helpEH, (XtPointer)help_text);
993   XtAddEventHandler (w, FocusChangeMask, False, quick_helpEH, (XtPointer)help_text);
994 }
995
996 // /////////////////////////////////////////////////////////////////
997 // quick_help
998 // /////////////////////////////////////////////////////////////////
999
1000 void
1001 LibraryAgent::quick_helpEH (Widget w, XtPointer client_data,
1002                           XEvent *event, Boolean *)
1003 {
1004   // display the help text. 
1005   Arg args[2];
1006   int n;
1007   LibraryAgent *agent;
1008
1009   n = 0;
1010   XtSetArg(args[n], XmNuserData, &agent); n++;
1011   XtGetValues(w, args, n);
1012
1013   // display quick help if moving into widget or clear quick help
1014   // if moving out of widget.
1015   if (event->type == EnterNotify || event->type == FocusIn)
1016     XmTextFieldSetString(agent->f_status_text, (char*)client_data);
1017   else if (event->type == LeaveNotify || event->type != FocusOut)
1018     XmTextFieldSetString(agent->f_status_text, (char*)"");
1019 }
1020
1021
1022 // /////////////////////////////////////////////////////////////////
1023 // search text callbacks
1024 // /////////////////////////////////////////////////////////////////
1025
1026 void
1027 LibraryAgent::text_callback(WCallback *wcb)
1028 {
1029     XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct*)wcb->CallData();
1030     char *text = XmTextGetString(wcb->GetWidget());
1031
1032     if (*text != '\0')
1033     {
1034       Wait_Cursor bob;
1035       search_mgr().parse_and_search (text, f_scope_menu->current_scope());
1036       search_mgr().search_section ("");
1037     }
1038     XtFree (text);
1039 }
1040
1041 void
1042 LibraryAgent::search_help (Widget, XtPointer client_data,
1043                               XEvent *event, Boolean *)
1044 {
1045   // Make sure the event is what we expect.
1046   if (event->type != EnterNotify && event->type != FocusIn &&
1047       event->type != LeaveNotify && event->type != FocusOut)
1048     return;
1049
1050   LibraryAgent* agent = (LibraryAgent*)client_data;
1051   if (agent == NULL)
1052     return;
1053
1054
1055   if (event->type == LeaveNotify || event->type == FocusOut)
1056   {
1057     XmTextFieldSetString(agent->f_status_text, (char*)"");
1058     return;
1059   }
1060
1061   
1062   static String help_text     = NULL;
1063   static String default_scope = NULL;
1064
1065   if (help_text == NULL) {
1066     UAS_Pointer<UAS_String> str;
1067     str = new UAS_String(CATGETS(Set_AgentQHelp, 64, "Search %s"));
1068     help_text = (char*)*str;
1069     agent->f_help_text.insert_item(str);
1070
1071     str = new UAS_String(CATGETS(Set_LibraryAgent, 65, "Current Section"));
1072     default_scope = (char*)*str;
1073     agent->f_help_text.insert_item(str);
1074   }
1075   
1076   // Format the search help string. 
1077   UAS_SearchScope *scope = agent->f_scope_menu->current_scope();
1078   char buffer[128];
1079   if (scope != NULL)
1080     sprintf (buffer, help_text, (char *) scope->name());
1081   else
1082     sprintf (buffer, help_text, default_scope);
1083
1084   // Finally, display it in the quick help field.
1085   XmTextFieldSetString(agent->f_status_text, buffer);
1086 }
1087
1088
1089 // /////////////////////////////////////////////////////////////////
1090 // ui_destroyed - user nuked Motif window, so kill myself
1091 // /////////////////////////////////////////////////////////////////
1092
1093 void
1094 LibraryAgent::ui_destroyed()
1095 {
1096   // Set f_shell to NULL, since Xt is destroying it for us. 
1097   f_shell = NULL;
1098   delete this;
1099 }
1100
1101 void
1102 LibraryAgent::ui_destroyedCB(Widget, XtPointer client_data, XtPointer)
1103 {
1104   LibraryAgent *agent = (LibraryAgent*)client_data;
1105   delete agent;
1106 }
1107
1108 #ifdef AllowDetach
1109 // /////////////////////////////////////////////////////////////////
1110 // detach_subtree
1111 // /////////////////////////////////////////////////////////////////
1112
1113 void
1114 LibraryAgent::detach_subtreeCB(Widget, XtPointer client_data, XtPointer)
1115 {
1116   LibraryAgent *agent = (LibraryAgent *)client_data;
1117   agent->detach_subtree();
1118 }
1119
1120 void
1121 LibraryAgent::detach_subtree()
1122 {
1123   // NOTE: EVIL hack here.  Save the bithandle for the view that will
1124   // be created by the display call.  00:14 01/14/93 DJB
1125   ON_DEBUG (puts ("Doing the DETACH thing"));
1126   g_handle = f_doc_tree_view->data_handle();
1127   library_mgr().display (f_doc_tree_view->selection());
1128   g_handle = 0;
1129 }
1130 #endif
1131
1132 ///////////////////////////////////////////////////////////////////////////////
1133 //  add_library
1134 ///////////////////////////////////////////////////////////////////////////////
1135
1136 void
1137 LibraryAgent::add_libraryCB(Widget w, XtPointer client_data, XtPointer)
1138 {
1139   LibraryAgent *agent = (LibraryAgent *)client_data;
1140   // put up the add library application modal dialog...
1141   //AddLibraryAgent addLib (*agent->f_shell);
1142   AddLibraryAgent addLib (w);
1143   char *newLib = addLib.getInfolibName();
1144
1145   if (newLib)
1146   {
1147     agent->add_library(newLib);
1148     XtFree (newLib);
1149   }
1150 }
1151
1152
1153 // status flags for return from add_library()
1154 // (these should never be changed in value -- see TtIpcMgr)
1155 #define ID_SUCCESS      1
1156 #define BAD_ARG_FORMAT  2
1157 #define LOAD_ERROR      3
1158 #define NOT_FOUND       5
1159
1160 int
1161 LibraryAgent::add_library(char* newLib, Widget parent)
1162 {
1163     int   sts = ID_SUCCESS ;
1164
1165     if(  (newLib == NULL) ||
1166         ((newLib != NULL) && ( *newLib == '\0' )) )
1167     {
1168         message_mgr().error_dialog(
1169                 (char*)UAS_String(CATGETS( Set_AddLibraryAgent, 6,
1170                       "No Infolib specified." )), parent);
1171         return (sts = BAD_ARG_FORMAT);
1172     }
1173
1174     UAS_Pointer<UAS_Common> d = NULL ;
1175     mtry {
1176         // (precise locator format parsing to be done in the UAS layer)
1177
1178         if( strchr( newLib, ':' ) && strchr( newLib, '/' ) ) {
1179             // assume to have a fully-qualified locator
1180
1181             d = UAS_Common::create( newLib ) ;
1182         }
1183         else if( *newLib == '/' ) {
1184             // assume given absolute path to an infolib.
1185             // construct the fully-qualified form and pass it on.
1186             char *buffer =
1187                     new char[strlen("mmdb:INFOLIB=") + strlen(newLib) + 1];
1188             sprintf (buffer, "mmdb:INFOLIB=%s", newLib);
1189             d = UAS_Common::create (buffer);
1190             delete [] buffer;
1191         }
1192         else if( !strchr( newLib, '/' ) ) {
1193
1194             char* pathname;
1195             // check environment variables for valid paths
1196             pathname = env().infolibNameToPath(newLib);
1197             if (pathname != NULL)
1198             {
1199                 // construct the fully-qualified form and pass it on.
1200                 char *buffer =
1201                      new char[strlen("mmdb:INFOLIB=") + strlen(pathname) + 1];
1202                 sprintf (buffer, "mmdb:INFOLIB=%s", pathname);
1203                 XtFree(pathname);
1204                 d = UAS_Common::create (buffer);
1205                 delete [] buffer;
1206             }
1207             else
1208             {
1209                 message_mgr().error_dialog (
1210                   (char*)UAS_String(CATGETS(Set_AddLibraryAgent, 5,
1211                        "Infolib specification format error.")),
1212                   parent);
1213                 sts = BAD_ARG_FORMAT ;
1214             }
1215
1216         }
1217         else {
1218             message_mgr().error_dialog (
1219                 (char*)UAS_String(CATGETS(Set_AddLibraryAgent, 2,
1220                      "Please enter an absolute path to the infolib.")),
1221                 parent);
1222         }
1223
1224         if (d != (const int)NULL) {
1225             d->retrieve ();
1226         } else {
1227 #ifdef DEBUG
1228             // if returned to reach here, error msg probably given by
1229             // MMDB interface:   "Invalid MMDB infolib path: <>"
1230             message_mgr().error_dialog (
1231               (char*)UAS_String(CATGETS(Set_AddLibraryAgent, 3,
1232                      "Infolib open failed. Check the path specified.")),
1233               parent);
1234 #endif
1235             sts = NOT_FOUND ;
1236         }
1237     } mcatch_any () {
1238         // one case that will reach here, but get no MMDB interface error
1239         // is if a (close to) fully qualified locator format is entered,
1240         // but with keyword error.
1241
1242         // report error only if likely from retrieval; others handled already
1243         if( d != (const int)NULL )
1244         {
1245           message_mgr().error_dialog(
1246                 (char*)UAS_String(CATGETS(Set_AddLibraryAgent, 4,
1247                        "Infolib creation failed.")),
1248                 parent) ;
1249         }
1250         sts = LOAD_ERROR ;
1251     } end_try;
1252     return sts;
1253 }
1254
1255 ///////////////////////////////////////////////////////////////////////////////
1256 //  remove_library
1257 ///////////////////////////////////////////////////////////////////////////////
1258
1259 void
1260 LibraryAgent::remove_libraryCB(Widget, XtPointer client_data, XtPointer)
1261 {
1262   LibraryAgent *agent = (LibraryAgent *)client_data;
1263   library_mgr().undisplay (agent->f_doc_tree_view->selection());
1264 }
1265
1266
1267 // /////////////////////////////////////////////////////////////////
1268 // entry_selected - something selected in list, sensitize detach
1269 // /////////////////////////////////////////////////////////////////
1270
1271 void
1272 LibraryAgent::entry_selected (void *, u_int notify_type)
1273 {
1274   bool sensitize_print = False;
1275   int selected_item_count = f_doc_tree_view->selected_item_count();
1276
1277   Xassert (notify_type == OutlineListView::ENTRY_SELECTED);
1278   Xassert (selected_item_count >= 0);
1279
1280   // Need to disable print if any selected items are infobase
1281   // or info library level.
1282
1283   if (selected_item_count == 0)
1284     {
1285       f_oe = NULL;
1286
1287 #ifdef AllowDetach
1288       XtSetSensitive(f_detach, False);
1289       XtSetSensitive(f_detach2, False);
1290 #endif
1291
1292       XtSetSensitive(f_view, False);
1293       XtSetSensitive(f_view2, False);
1294       XtSetSensitive(f_remove, False);
1295       XtSetSensitive(f_remove2, False);
1296       XtSetSensitive(f_print2, False);
1297       XtSetSensitive(f_print_as, False);
1298       XtSetSensitive(f_copy, False);
1299     }
1300   else if (selected_item_count == 1)
1301     {
1302       // Get the single selected item.
1303       // NOTE: This is sort of round-about.
1304       // Got a better idea?  20:42 17-Mar-93 DJB 
1305       List *select_list = f_doc_tree_view->selected_item_list();
1306       f_oe = (OutlineElement *) (*select_list)[0];
1307       delete select_list;
1308
1309 #ifdef AllowDetach
1310       if (f_oe->has_children())
1311       {
1312           XtSetSensitive(f_detach, True);
1313           XtSetSensitive(f_detach2, True);
1314       }
1315       else
1316       {
1317           XtSetSensitive(f_detach, False);
1318           XtSetSensitive(f_detach2, False);
1319       }
1320 #endif
1321
1322       if (((TOC_Element *) f_oe)->toc()->data_length() != 0)
1323         {
1324           XtSetSensitive(f_view, True);
1325           XtSetSensitive(f_view2, True);
1326         }
1327       else
1328         {
1329           XtSetSensitive(f_view, False);
1330           XtSetSensitive(f_view2, False);
1331         }
1332       //
1333       //  Only enable remove if the selected item is one
1334       //  of the list's roots (corresponding to a top level
1335       //  information library, etc)
1336       //
1337       OutlineList &rootList = *(f_doc_tree_view->list());
1338       int removeSensitive = 0;
1339       if (rootList.length() > 1) { // don't let 'em remove the last one...
1340           if (((TOC_Element *) f_oe)->toc()->type() == UAS_LIBRARY) {
1341               for (int i = 0; i < rootList.length(); i ++) {
1342                 if (((TOC_Element *) f_oe)->toc() ==
1343                                     ((TOC_Element *) rootList[i])->toc()) {
1344                     removeSensitive = 1;
1345                     break;
1346                 }
1347               }
1348           }
1349       }
1350       XtSetSensitive(f_remove, removeSensitive);
1351       XtSetSensitive(f_remove2, removeSensitive);
1352       sensitize_print = True;
1353       XtSetSensitive(f_copy, True);
1354     }
1355   else // (selected_item_count > 1)
1356     {
1357       f_oe = NULL;
1358
1359 #ifdef AllowDetach
1360       XtSetSensitive(f_detach, False);
1361       XtSetSensitive(f_detach2, False);
1362 #endif
1363
1364       XtSetSensitive(f_view, False);
1365       XtSetSensitive(f_view2, False);
1366       XtSetSensitive(f_remove, False);
1367       XtSetSensitive(f_remove2, False);
1368       XtSetSensitive(f_copy, True);
1369       sensitize_print = True;
1370     }
1371
1372   // Only allow print to be sensitive if selected list does NOT contain
1373   // InfoLibrary or InfoBase elements.
1374
1375   if (sensitize_print)
1376     {
1377       // Get the list of selections. 
1378       List *select_list = f_doc_tree_view->selected_item_list();
1379       Xassert (selected_item_count == select_list->length());
1380
1381       for (int i = 0; i < select_list->length(); i++)
1382         {
1383           if (((TOC_Element *) (*select_list)[i])->toc()->data_length() == 0)
1384             {
1385               sensitize_print = False;
1386               // No need to continue if non-printable found. 
1387               break;
1388             }
1389         }
1390       delete select_list;
1391     }
1392
1393     XtSetSensitive(f_print2, sensitize_print);
1394     XtSetSensitive(f_print_as, sensitize_print);
1395 }
1396
1397 // /////////////////////////////////////////////////////////////////
1398 // Display button pressed
1399 // ////////////////////////////////////////////////////////////////
1400 void
1401 LibraryAgent::display_nodeCB(Widget, XtPointer client_data, XtPointer)
1402 {
1403   LibraryAgent *agent = (LibraryAgent *)client_data;
1404   agent->display_node();
1405 }
1406
1407 void
1408 LibraryAgent::display_node ()
1409 {
1410   Xassert (f_oe != NULL);
1411   if (f_oe)
1412     f_oe->display();
1413 }
1414
1415
1416 // /////////////////////////////////////////////////////////////////
1417 // print
1418 // /////////////////////////////////////////////////////////////////
1419
1420
1421 /*
1422  * ------------------------------------------------------------------------
1423  * Name: LibraryAgent::print_asCB
1424  *
1425  * Description:
1426  *
1427  *     This is called for "Print..." and will always bring up the
1428  *     print setup dialog.
1429  *     
1430  */
1431
1432 void
1433 LibraryAgent::print_asCB(Widget w, XtPointer client_data, XtPointer)
1434 {
1435     LibraryAgent *agent = (LibraryAgent *)client_data;
1436
1437     //  Get a handle to the AppPrintData allocated in the WindowSystem class
1438     
1439     AppPrintData* p = window_system().GetAppPrintData();
1440
1441     // Get the list of selected items. 
1442     List *select_list = agent->f_doc_tree_view->selected_item_list();
1443     xList<UAS_Pointer<UAS_Common> > * print_list = new  xList<UAS_Pointer<UAS_Common> >;
1444     
1445     for (int i = 0; i < select_list->length(); i++) {
1446         print_list->append (((TOC_Element *) (*select_list)[i])->toc());
1447     }
1448
1449     p->f_print_list = print_list;
1450     p->f_outline_element = agent->f_oe;
1451  
1452     CreatePrintSetup(w, p);
1453     
1454     XtManageChild(p->f_print_dialog); /* popup dialog each time */
1455     
1456     delete select_list;
1457
1458 }
1459
1460 /*
1461  * ------------------------------------------------------------------------
1462  * Name: LibraryAgent::printCB
1463  *
1464  * Description:
1465  *
1466  *     Called when the user hits "Print" quick button.  Prints without
1467  *     displaying the Print setup dialog.
1468  *     
1469  */
1470 void
1471 LibraryAgent::printCB(Widget w, XtPointer client_data, XtPointer)
1472 {
1473     LibraryAgent *agent = (LibraryAgent *)client_data;
1474
1475     //  Get a handle to the AppPrintData allocated in the WindowSystem class
1476     
1477     AppPrintData* p = window_system().GetAppPrintData();
1478
1479     // Get the list of selected items. 
1480     List *select_list = agent->f_doc_tree_view->selected_item_list();
1481     xList<UAS_Pointer<UAS_Common> > * print_list = new  xList<UAS_Pointer<UAS_Common> >;
1482     
1483     for (int i = 0; i < select_list->length(); i++) {
1484         print_list->append (((TOC_Element *) (*select_list)[i])->toc());
1485     }
1486
1487     p->f_print_list = print_list;
1488     p->f_outline_element = agent->f_oe;
1489  
1490     CreatePrintSetup(w, p);
1491
1492     // check if the DtPrintSetupBox ("Print...") has been called yet 
1493
1494     if(p->f_print_data->print_display == (Display*)NULL)
1495     {
1496         
1497         // first time thru print setup, so get default data 
1498         
1499         if (DtPrintFillSetupData(p->f_print_dialog, p->f_print_data)
1500             != DtPRINT_SUCCESS) {
1501
1502             // NOTE: DtPrintFillSetupData() already posts an error
1503             // dialog on failure - no need to post our own.
1504     
1505             delete select_list;
1506             return ;
1507         }
1508     }
1509  
1510     DoPrint(w, p) ;
1511     
1512     delete select_list;
1513     
1514 }
1515
1516 OutlineList *LibraryAgent::outline_list()
1517 {
1518   return (f_doc_tree_view->list());
1519 }
1520
1521
1522 // /////////////////////////////////////////////////////////////////
1523 // receive - handle node display by auto-tracking to it
1524 // /////////////////////////////////////////////////////////////////
1525
1526 void
1527 LibraryAgent::receive (UAS_DocumentRetrievedMsg &message, void *)
1528 {
1529   extern bool g_style_sheet_update ;
1530   if (!g_style_sheet_update)
1531     track_to (message.fDoc);
1532 }
1533
1534 void
1535 LibraryAgent::track_to (UAS_Pointer<UAS_Common> &node_ptr)
1536 {
1537   ON_DEBUG (printf ("LibraryAgent::track_to: popped_down = %d, track set = %d, node_ptr = %p\n", f_popped_down, XmToggleButtonGadgetGetState(f_auto_track),(UAS_Common *) node_ptr));
1538   if (f_popped_down || !XmToggleButtonGadgetGetState(f_auto_track) || node_ptr == (const int)NULL)
1539     return;
1540   Wait_Cursor bob;
1541   ON_DEBUG (puts ("TRYING to locate document in doc tree!"));
1542
1543   // First track document back up to it's root, so that
1544   // we can find it in our list.  If our root isn't in
1545   // the path to the root for the displayed document it
1546   // can't possible be displayed in our current subtree.
1547   OutlineList &rootList = *(f_doc_tree_view->list());
1548   bool in_subtree = FALSE;
1549   UAS_Pointer<UAS_Common> doc_root = node_ptr;
1550   int inum;
1551
1552   // Trace up to the root.
1553   free_tracking_hierarchy();
1554   while (doc_root != (const int)NULL && !in_subtree)
1555     {
1556       f_tracking_hierarchy = new TrackingEntry(doc_root, f_tracking_hierarchy);
1557       for (int i = 0; i < rootList.length(); i ++) {
1558         if (doc_root == ((TOC_Element *) rootList[i])->toc()) {
1559             in_subtree = TRUE;
1560             inum = i;
1561             break;
1562         }
1563       }
1564       doc_root = doc_root->parent();
1565     }
1566
1567   if (in_subtree)
1568     {
1569       ON_DEBUG (printf ("Found node <%s> in my doc list subtree <%s>\n",
1570                     (char*)node_ptr->title(),
1571                     (char*)((TOC_Element *) rootList[inum])->toc()->title()));
1572       // Track to the element, scrolling if necessary. 
1573       track (TRUE);
1574     }
1575   else
1576     {
1577       f_doc_tree_view->untrack();
1578       free_tracking_hierarchy();
1579     }
1580 }
1581
1582
1583 // /////////////////////////////////////////////////////////////////
1584 // track - (re)compute tracking position
1585 // /////////////////////////////////////////////////////////////////
1586
1587 void
1588 LibraryAgent::track (bool scroll)
1589 {
1590   if (f_popped_down || f_tracking_hierarchy == NULL || !XmToggleButtonGadgetGetState(f_auto_track))
1591     return;
1592
1593   // Now walk back down the tree and highlight the lowest visible
1594   // entry above the document we are tracking.
1595   OutlineList &rootList = *(f_doc_tree_view->list());
1596   BitHandle handle = f_doc_tree_view->data_handle();
1597   // We must keep track of the number of items linerally skipped so
1598   // that we can ultimately highlight the right entry in the list. 
1599   unsigned int list_location = 0;
1600   // Make sure the roots match up, just to be safe.
1601   TrackingEntry *t;
1602   OutlineElement *oe;
1603   for (int cnt = 0; cnt < rootList.length(); cnt ++) {
1604       list_location ++;
1605       t = f_tracking_hierarchy->f_child;
1606       oe = (OutlineElement *) rootList[cnt];
1607
1608       if (! oe->has_children())
1609         continue;
1610
1611       // unexpanded infolib needs special handling here since
1612       // the while loop below does not work for this case
1613       if (! oe->is_expanded (handle)) {
1614         if (f_tracking_hierarchy &&
1615             f_tracking_hierarchy->f_toc != ((TOC_Element *)oe)->toc())
1616           continue;
1617       }
1618
1619       // Scan the child list of the outline element
1620       // for the next matching TrackingEntry.
1621       int found = 1;
1622       while (t != NULL && oe->is_expanded (handle))
1623         {
1624           // If the entry is expanded, it MUST have children. 
1625           Xassert (oe->has_children());
1626           OutlineList &kids = *(oe->children());
1627           int i;
1628           for (i = 0; i < kids.length(); i++)
1629             {
1630               // Keep track of how many expanded items we skip over.
1631               list_location++;
1632               if (((TOC_Element *) kids[i])->toc() == t->f_toc)
1633                 break;
1634               // Not found, so we must add all expanded children to count.
1635               oe = (OutlineElement *) kids[i];
1636               if (oe->is_expanded (handle) && oe->has_children())
1637                 list_location += oe->children()->count_expanded (handle);
1638             }
1639           if (i < kids.length()) {
1640               // Move down to the next level. 
1641               oe = (OutlineElement *) kids[i];
1642               t = t->f_child;
1643           } else {
1644               found = 0;
1645               break;
1646           }
1647         }
1648       if (found)
1649         break;
1650     }
1651
1652   // At this point the oe ponts to the closest expanded entry
1653   // to the document that has just been displayed and location
1654   // is it's index in the overall list.
1655
1656   ON_DEBUG (printf ("target element = <%s>, list_location = %d\n",
1657                     oe->display_as(), list_location));
1658   int old_selection  = f_doc_tree_view->tracking_position();
1659
1660   // Select the icon depending on wheter or not we're on the exact
1661   // entry that we were seeking. 
1662   if (t == NULL)
1663     f_doc_tree_view->track_to (oe, list_location, OLIAS_SOLID_TRACKER);
1664   else
1665     f_doc_tree_view->track_to (oe, list_location, OLIAS_HOLLOW_TRACKER);
1666
1667   // Scroll the entry into view if necessary.
1668   // If the entry is not visible and is one position before
1669   // or after the currently selected entry, scroll the list
1670   // by one position in the correct position.
1671
1672   if (scroll)
1673     {
1674       int visible_items = f_doc_tree_view->VisibleItemCount();
1675       int top_position = f_doc_tree_view->TopItemPosition();
1676       int bottom_position = top_position + visible_items - 1;
1677       ON_DEBUG (printf ("top = %d, bottom = %d, old = %d\n",
1678                         top_position, bottom_position, old_selection));
1679
1680       if (list_location < top_position ||
1681           list_location > bottom_position)
1682         {
1683           ON_DEBUG (puts ("* About to scroll list"));
1684           if (old_selection == top_position &&
1685               list_location == top_position - 1)
1686             {
1687               // Scroll up one item. 
1688               f_doc_tree_view->TopItemPosition (top_position - 1);
1689             }
1690           else if (old_selection == bottom_position &&
1691                    list_location == bottom_position + 1)
1692             {
1693               // Scroll down one item. 
1694               f_doc_tree_view->TopItemPosition (top_position + 1);
1695             }
1696           else
1697             {
1698               // Center the entry in the list.
1699               int new_top = list_location - (visible_items - 1) / 2;
1700               int new_bottom = new_top + visible_items - 1;
1701               if (new_bottom > f_doc_tree_view->ItemCount())
1702                 new_top = f_doc_tree_view->ItemCount() - visible_items + 1;
1703               else if (new_top < 1)
1704                 new_top = 1;
1705               ON_DEBUG (printf ("Centering, new_top = %d\n", new_top));
1706               f_doc_tree_view->TopItemPosition (new_top);
1707             }
1708         }
1709     }
1710 }
1711
1712
1713 // /////////////////////////////////////////////////////////////////
1714 // free_tracking_hierarchy
1715 // /////////////////////////////////////////////////////////////////
1716
1717 void
1718 LibraryAgent::free_tracking_hierarchy()
1719 {
1720   TrackingEntry *tmp;
1721   while (f_tracking_hierarchy != NULL)
1722     {
1723       tmp = f_tracking_hierarchy;
1724       f_tracking_hierarchy = tmp->f_child;
1725       delete tmp;
1726     }
1727 }
1728
1729
1730 // /////////////////////////////////////////////////////////////////
1731 // auto_track_toggle - turn auto track on and off
1732 // /////////////////////////////////////////////////////////////////
1733
1734 void
1735 LibraryAgent::auto_track_toggleCB(Widget, XtPointer client_data, XtPointer)
1736 {
1737   LibraryAgent *agent = (LibraryAgent *)client_data;
1738   if (XmToggleButtonGadgetGetState(agent->f_auto_track))
1739       agent->track_to(node_mgr().last_displayed());
1740   else
1741     {
1742       agent->f_doc_tree_view->untrack();
1743       agent->free_tracking_hierarchy();
1744     }
1745 }
1746
1747 void
1748 LibraryAgent::library_removed (UAS_Pointer<UAS_Common> lib)
1749 {
1750     OutlineList &rootList = *(f_doc_tree_view->list());
1751     int i;
1752     for (i = rootList.length() - 1; i >= 0; i --) {
1753         TOC_Element *te = (TOC_Element *) rootList[i];
1754         if (te->toc()->get_library() == lib) {
1755             if (f_tracking_hierarchy && f_tracking_hierarchy->f_toc == lib) {
1756                 f_doc_tree_view->untrack();
1757                 free_tracking_hierarchy ();
1758             }
1759             rootList.remove(i);
1760             // Not sure if I delete this guy...
1761             delete te;
1762         }
1763     }
1764     f_doc_tree_view->clear ();
1765
1766     // don't need to generate a new handle, just use the old one
1767     //BitHandle handle = rootList.get_data_handle();
1768     BitHandle handle = f_doc_tree_view->data_handle();
1769
1770     int level = ((OutlineElement *) rootList[0])->level();
1771     for (i = 0; i < rootList.length(); i ++)
1772     {
1773       ((OutlineElement *) rootList[i])->set_expanded (handle);
1774
1775       // check bookcases to make sure they are not expanded.
1776       // if they are expanded, make them contract.
1777       OutlineElement *oe = (OutlineElement*)rootList[i];
1778
1779       List *bclist = oe->children();
1780          
1781       for(int b = 0; b < bclist->length(); b++)
1782       {
1783         OutlineElement *coe = (OutlineElement *)(*bclist)[b];
1784         if (coe->is_expanded(handle))
1785           coe->set_contracted(handle);
1786       }
1787     }
1788
1789     // for some reason set_list doesn't think that the outline
1790     // list needs to be updated--so force the update to happen
1791     f_doc_tree_view->update_list(&rootList, handle);
1792     f_doc_tree_view->set_list (&rootList, handle);
1793     entry_selected (NULL, OutlineListView::ENTRY_SELECTED);
1794 }
1795
1796 void
1797 LibraryAgent::destCB(Widget w, XtPointer client_data, XtPointer call_data)
1798 {
1799     XmDestinationCallbackStruct* cs = (XmDestinationCallbackStruct*)call_data;
1800     
1801 #if 0
1802     Atom targets = XInternAtom(XtDisplay(w), "_MOTIF_EXPORT_TARGETS", False);
1803 #endif
1804
1805     XmTransferValue(cs->transfer_id, XA_TARGETS(XtDisplay(w)),
1806                     (XtCallbackProc)transferCB, client_data,
1807                     XtLastTimestampProcessed(XtDisplay(w)));
1808 }
1809
1810 static Atom
1811 pickup_target(Widget w, Atom* targets, unsigned long length)
1812 {
1813     if (targets == NULL || length == 0)
1814         return None;
1815
1816     Atom best = None;
1817
1818     Atom *iter;
1819     for (iter = targets; iter < targets + length; iter++) {
1820         if (*iter == XInternAtom(XtDisplay(w), "_DT_NETFILE", False)) {
1821             best = *iter;
1822 #ifdef DD_DEBUG
1823             cerr << "(DEBUG) pickup _DT_NETFILE" << endl;
1824 #endif
1825             break;
1826         }
1827     }
1828     if (best != None)
1829         return best;
1830
1831     for (iter = targets; iter < targets + length; iter++) {
1832         if (*iter == XInternAtom(XtDisplay(w), "FILE_NAME", False)) {
1833             best = *iter;
1834 #ifdef DD_DEBUG
1835             cerr << "(DEBUG) pickup FILE_NAME" << endl;
1836 #endif
1837             break;
1838         }
1839     }
1840     if (best != None)
1841         return best;
1842
1843 #if 0
1844     for (iter = targets; iter < targets + length; iter++) {
1845         if (*iter == XA_COMPOUND_TEXT(XtDisplay(w))) {
1846             best = *iter;
1847 #ifdef DD_DEBUG
1848             cerr << "(DEBUG) pickup XA_COMPOUND_TEXT" << endl;
1849 #endif
1850             break;
1851         }
1852     }
1853     if (best != None)
1854         return best;
1855 #endif
1856
1857     for (iter = targets; iter < targets + length; iter++) {
1858         if (*iter == XA_TEXT(XtDisplay(w))) {
1859             best = *iter;
1860 #ifdef DD_DEBUG
1861             cerr << "(DEBUG) pickup XA_TEXT" << endl;
1862 #endif
1863             break;
1864         }
1865     }    
1866     if (best != None)
1867         return best;
1868
1869     for (iter = targets; iter < targets + length; iter++) {
1870         if (*iter == XA_STRING) {
1871             best = *iter;
1872 #ifdef DD_DEBUG
1873             cerr << "(DEBUG) pickup XA_STRING" << endl;
1874 #endif
1875             break;
1876         }
1877     }    
1878
1879 #ifdef DD_DEBUG
1880     if (best == None)
1881         cerr << "(DEBUG) no proper Atoms found" << endl;
1882 #endif
1883
1884     return best;
1885 }
1886
1887 static int
1888 IsInfolib(const char* path)
1889 {
1890     if (path == NULL || *path == '\0')
1891         return False;
1892
1893     struct stat stat_buf;
1894     if (stat(path, &stat_buf) < 0)
1895         return False;
1896     
1897     if ((stat_buf.st_mode & S_IFMT & S_IFDIR) == 0)
1898         return False;
1899         
1900     if (access((char*)path, R_OK) < 0)
1901         return False;
1902
1903     UAS_String map = path;
1904     map = map + "/" + "bookcase.map";
1905
1906     if (access((char*)map, R_OK) < 0)
1907         return False;
1908
1909     return True;
1910 }
1911
1912 void
1913 LibraryAgent::transferCB(Widget w, XtPointer client_data, XtPointer call_data)
1914 {
1915     XmSelectionCallbackStruct* cs = (XmSelectionCallbackStruct*)call_data;
1916
1917 #ifdef DD_DEBUG
1918     cerr << "transferCB called." << endl;
1919 #endif
1920
1921     if (cs->target == XA_TARGETS(XtDisplay(w))) {
1922
1923         if (cs->type != XA_ATOM || cs->length == 0) { // check integrity
1924 #ifdef DD_DEBUG
1925             cerr << "this guy doesn't understand XA_TARGETS." << endl;
1926 #endif
1927             XmTransferDone(cs->transfer_id, XmTRANSFER_DONE_FAIL);
1928             return;
1929         }
1930
1931         Atom best_target = None;
1932         best_target = pickup_target(w, (Atom *)cs->value, cs->length);
1933
1934         if (best_target == None) {
1935 #ifdef DD_DEBUG
1936             cerr << "could not resolve the best target." << endl;
1937 #endif
1938             XmTransferDone(cs->transfer_id, XmTRANSFER_DONE_FAIL);
1939             return;
1940         }
1941
1942         XmTransferValue(cs->transfer_id, best_target,
1943                         (XtCallbackProc)transferCB, client_data,
1944                         XtLastTimestampProcessed(XtDisplay(w)));
1945         return;
1946     }
1947     else if (cs->target == XInternAtom(XtDisplay(w), "_DT_NETFILE", False) ||
1948              cs->target == XInternAtom(XtDisplay(w), "FILE_NAME", False) ||
1949              cs->target == XA_TEXT(XtDisplay(w))) {
1950
1951         char* netfile = (char*)cs->value;
1952         if (netfile == NULL || *netfile == '\0') {
1953             XmTransferDone(cs->transfer_id, XmTRANSFER_DONE_FAIL);
1954             return;
1955         }
1956
1957         char* file;
1958         if (cs->target == XInternAtom(XtDisplay(w), "_DT_NETFILE", False))
1959             file = tt_netfile_file(netfile);
1960         else
1961             file = strdup(netfile);
1962
1963         if (file == NULL || *file == '\0') {
1964                 XtFree(netfile);
1965                 XmTransferDone(cs->transfer_id, XmTRANSFER_DONE_FAIL);
1966                 return;
1967         }
1968
1969         XtFree(netfile);
1970
1971 #ifdef DD_DEBUG
1972         fprintf(stderr, "(DEBUG) local filename=\"%s\"\n", file);
1973 #endif
1974         if (! IsInfolib(file)) { // inaccesible from the host
1975             tt_free(file);
1976             XmTransferDone(cs->transfer_id, XmTRANSFER_DONE_FAIL);
1977             return;
1978         }
1979
1980         UAS_String url = "mmdb:INFOLIB=";
1981         url = url + file;
1982
1983         UAS_Pointer<UAS_Common> pIL;
1984         mtry {
1985             pIL = UAS_Common::create ((char*)url);
1986             if (! (pIL == (UAS_Pointer<UAS_Common>)NULL)) {
1987                 pIL->retrieve();
1988             }
1989         }
1990         mcatch_any() {
1991             pIL = NULL;
1992         }
1993         end_try;
1994
1995         if (pIL ==  (UAS_Pointer<UAS_Common>)NULL) {
1996             tt_free(file);
1997             XmTransferDone(cs->transfer_id, XmTRANSFER_DONE_FAIL);
1998             return;
1999         }
2000
2001         tt_free(file);
2002
2003         XmTransferDone(cs->transfer_id, XmTRANSFER_DONE_SUCCEED);
2004         return;
2005     }
2006 }
2007
2008 void
2009 LibraryAgent::copy_to_clipbd()
2010 {
2011   List *select_list = f_doc_tree_view->selected_item_list();
2012   int status;
2013   UAS_String buf;
2014   XmString clip_label;
2015   static int private_id = 0;
2016   //Window window = XtWindowOfObject((Widget)f_shell);
2017   Window window = XtWindowOfObject(f_shell);
2018   long item_id = 0;
2019   clip_label = XmStringCreateLocalized((char*)"Data");
2020   Wait_Cursor bob;
2021   UAS_String nl("\n");
2022   
2023   for (int i = 0; i < select_list->length(); i++)
2024   {
2025     UAS_Pointer<UAS_Common> toc;
2026     toc = ((TOC_Element *) (*select_list)[i])->toc();
2027
2028     buf = buf + toc->title() + nl;
2029   }
2030
2031   private_id++;
2032
2033   // start a copy--retry until unlocked
2034   do
2035   {
2036     status = XmClipboardStartCopy(
2037                 window_system().display(),
2038                 window,
2039                 clip_label,
2040                 CurrentTime,
2041                 NULL, NULL, &item_id);
2042   } while(status == ClipboardLocked);
2043                 
2044   do
2045   {
2046     status = XmClipboardCopy(
2047                 window_system().display(),
2048                 window,
2049                 item_id,
2050                 (char*)"STRING",
2051                 (char*)buf, (long)strlen((char*)buf) + 1,
2052                 private_id, NULL);
2053   } while(status == ClipboardLocked);
2054               
2055   do
2056   {
2057     status = XmClipboardEndCopy(
2058                 window_system().display(),
2059                 window,
2060                 item_id);
2061   } while(status == ClipboardLocked);
2062
2063
2064   XmStringFree(clip_label);
2065   delete select_list;
2066 }
2067