2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: SearchScopeAgentMotif.C /main/27 1998/04/17 11:35:37 mgreess $ */
24 /* Copyright (c) 1994,1995,1996 FUJITSU LIMITED */
25 /* All Rights Reserved */
28 * Copyright (c) 1991 HaL Computer Systems, Inc. All rights reserved.
29 * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
30 * States. Use of a copyright notice is precautionary only and does not
31 * imply publication or disclosure.
33 * This software contains confidential information and trade secrets of HaL
34 * Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
35 * without the prior express written permission of HaL Computer Systems, Inc.
37 * RESTRICTED RIGHTS LEGEND
38 * Use, duplication, or disclosure by the Government is subject to
39 * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
40 * Technical Data and Computer Software clause at DFARS 252.227-7013.
41 * HaL Computer Systems, Inc.
42 * 1315 Dell Avenue, Campbell, CA 95008
47 #include "Support/UtilityFunctions.hh"
53 #define C_SearchScopeMgr
56 #define C_WindowSystem
60 #define C_OutlineString
72 #define C_OutlineListView
73 #define C_SearchScopeList
74 #define C_SearchScopeAgent
81 #include "Other/XmStringLocalized.hh"
82 #include "Managers/CatMgr.hh"
84 #include "Exceptions.hh"
87 #include "Registration.hh"
89 #include <WWL/WXmForm.h>
90 #include <WWL/WXmLabel.h>
91 #include <WWL/WXmPushButton.h>
92 #include <WWL/WXmRowColumn.h>
93 #include <WWL/WXmCascadeButton.h>
94 #include <WWL/WXmSeparator.h>
95 #include <WWL/WXmMenu.h>
97 #include <WWL/WXmDialogShell.h>
98 #include <WWL/WXmTextField.h>
99 #include <WWL/WXmMessageBox.h>
103 #include <libintl.h> // 1/19/94 yuji
108 #include <iostream.h>
111 #define CLASS SearchScopeAgent
112 STATIC_SENDER_CC (UpdateMenu);
116 #if defined(i386) || defined(_IBMR2)
120 extern int strcasecmp(const char *s1, const char *s2);
127 strcasecmp(register const char *s1,
128 register const char *s2)
133 c1 = isupper(*s1) ? tolower(*s1) : *s1;
134 c2 = isupper(*s2) ? tolower(*s2) : *s2;
140 return (int) (*s1 - *s2);
145 #define CLASS SearchScopeAgent
146 #include "create_macros.hh"
148 // /////////////////////////////////////////////////////////////////////////
149 // class ScopeOutlineListView
151 // This is a subclass of OutlineListView
152 // The difference between this class and the parent class is that this class
153 // will deselect all parents and children of a selected item. This
154 // functionality is to show that a selected item includes its children
155 // -11:22 07/ 8/93 - jbm
156 // /////////////////////////////////////////////////////////////////////////
159 class ScopeOutlineListView : public OutlineListView
162 ScopeOutlineListView(const WComposite &parent,
164 bool automanage = FALSE,
165 bool enable_activate = FALSE)
166 : OutlineListView(parent, name, automanage, enable_activate)
168 virtual void select(WCallback *wcb);
169 virtual void clear();
172 OutlineElement *find_parent(int, OutlineElement *);
174 void unset_parent(OutlineElement *p);
175 int lid_to_index(const UAS_String &lid);
176 void select_infolib (UAS_String &lid, BitHandle handle);
177 UAS_String name_to_lid(UAS_String& name);
178 UAS_String lid_to_name(UAS_String& lid);
182 OutlineElement *find_parent(OutlineElement *possible_parent,
183 OutlineElement *child);
188 ScopeOutlineListView::clear()
190 // empty list like usual
191 OutlineListView::clear();
194 ((OutlineElement *)(*list())[0])->set_selected(data_handle());
195 // NOTE: slow, set directly ???
196 u_int starting_pos = 1;
197 update_highlighting(list(), starting_pos);
201 ScopeOutlineListView::unset_parent(OutlineElement *parent)
203 parent->unset_selected(data_handle());
207 ScopeOutlineListView::select(WCallback *wcb)
209 bool update = FALSE ;
211 // do selection work in base class
212 OutlineListView::select(wcb);
214 // now do some special handling
216 if (f_selected_item_count == 0)
221 // first get item that was selected
222 XmStringTable items = Items();
223 XmListCallbackStruct *lcs = (XmListCallbackStruct *)wcb->CallData();
227 extract_pointer(items[lcs->item_position-1], &oe);
229 oe = item_at(lcs->item_position-1);
232 // we want to deselect all children
233 if (oe->has_children() && oe->children_cached())
235 oe->children()->deselect_all(data_handle());
239 // now de-select parent (if have one)
240 OutlineElement *parent;
241 if (strcmp("infobases", XtName(wcb->GetWidget())) == 0)
242 parent = find_parent(1, oe);
244 parent = find_parent(0, oe);
248 parent->unset_selected(data_handle());
254 u_int starting_pos = 1;
255 update_highlighting(list(), starting_pos);
261 ScopeOutlineListView::find_parent(int infolib, OutlineElement *element)
267 UAS_Pointer<UAS_Common> ilib = ((TOC_Element*)element)->toc();
269 // need to find out which infolib we're dealing with
270 int infolib_index = lid_to_index(ilib->lid());
271 top = (OutlineElement*)(*list())[infolib_index] ;
274 top = (OutlineElement*)(*list())[0] ;
276 return find_parent(top, element);
281 ScopeOutlineListView::find_parent(OutlineElement *parent,
282 OutlineElement *element)
284 OutlineElement *current, *value ;
286 if (parent->has_children() && parent->children_cached())
288 OutlineList *olist = parent->children() ;
289 for (int i = 0 ; i < olist->length(); i++)
291 current = (OutlineElement*)(*olist)[i] ;
292 if (current == element)
293 return parent ; // NOTE: procedure EXIT
295 value = find_parent(current, element);
298 // NOTE: this action should not really be here
299 ((*this).unset_parent)(parent);
300 return value ; // NOTE: procedure EXIT
308 ScopeOutlineListView::select_infolib (UAS_String &lid, BitHandle handle)
310 int index = lid_to_index(lid);
311 OutlineElement *oe = ((OutlineElement*)(*list())[index]);
312 //((OutlineElement*)(*f_infolib_list->list())[index])->set_selected (handle);
315 oe->set_selected (handle);
317 // deselect all children
318 oe->children()->deselect_all(handle);
320 // udpate highlighting
321 u_int starting_pos = 1;
322 update_highlighting(list(), starting_pos);
326 // Give a infolib id, return its index into the f_infolib_list
329 ScopeOutlineListView::lid_to_index(const UAS_String &lid)
331 OutlineList *ol = list();
333 for (int i = 0; i < ol->length(); i++)
335 oe = ((OutlineElement *) (*ol)[i]);
336 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
337 if( infolib->lid() == lid)
341 return -1; // lid not found
345 ScopeOutlineListView::lid_to_name(UAS_String &lid)
347 OutlineList *ol = list();
349 for (int i = 0; i < ol->length(); i++)
351 oe = ((OutlineElement *) (*ol)[i]);
352 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
353 if( infolib->lid() == lid)
354 return infolib->name();
356 // There has to be an infolib for a given lid--if
357 // not, something has gone wrong.
358 throw (CASTEXCEPT Exception());
362 ScopeOutlineListView::name_to_lid(UAS_String &name)
364 OutlineList *ol = list();
366 for (int i = 0; i < ol->length(); i++)
368 oe = ((OutlineElement *) (*ol)[i]);
369 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
370 if( infolib->name() == name)
371 return infolib->lid();
373 // There has to be an infolib for a given lid--if
374 // not, something has gone wrong.
375 throw (CASTEXCEPT Exception());
378 // **********************************************************************
379 // **********************************************************************
381 SearchScopeAgent::SearchScopeAgent()
385 f_option_menu (NULL),
386 f_current_scope (NULL)
388 f_auto_expand = True;
390 f_scope_list.restore();
394 // /////////////////////////////////////////////////////////////////
396 // /////////////////////////////////////////////////////////////////
398 SearchScopeAgent::~SearchScopeAgent()
401 // dont need to delete these because not called anyway - jbm
403 // NOTE: Destroy should destroy & delete!
405 delete f_infolib_list;
406 delete f_component_list;
407 // LEAK: need to delete the scope objects
414 // /////////////////////////////////////////////////////////////////
416 // /////////////////////////////////////////////////////////////////
419 SearchScopeAgent::display()
428 f_first_time = False;
437 if (search_scope_mgr().show_warning())
439 // dialog is not real useful in a multi-infolib environment
442 message_mgr().warning_dialog (
443 (char*)UAS_String(CATGETS(Set_Messages, 31,
444 "Ignoring invalid scopes in your profile.")));
446 search_scope_mgr().show_warning(False);
451 // /////////////////////////////////////////////////////////////////
452 // fill_option_menu - fills the option menu with named scopes
453 // /////////////////////////////////////////////////////////////////
455 SearchScopeAgent::fill_option_menu()
457 int position = 1; // skip past unnamed scope button
458 List_Iterator<UAS_SearchScope *> i (f_scope_list);
459 WComposite menu (f_scope_option.SubMenuId());
461 ON_DEBUG (printf ("There are %d user scopes:\n", f_scope_list.length()));
462 for (; i != NULL; i++)
464 if (i.item()->read_only())
466 //DECLM (WXmPushButton, scope_btn, f_scope_option.SubMenuId(),
468 DECLM (WXmPushButton, scope_btn, menu, i.item()->name());
469 ON_ACTIVATE (scope_btn,select_scope);
470 scope_btn.UserData (i.item());
471 scope_btn.PositionIndex (position++);
473 f_first_time = False;
476 // /////////////////////////////////////////////////////////////////
478 // /////////////////////////////////////////////////////////////////
481 SearchScopeAgent::create_ui()
483 XmStringLocalized mtfstring;
486 f_shell = WTopLevelShell (window_system().toplevel(),WPopup,"scope_editor");
487 window_system().register_shell(&f_shell);
489 string = CATGETS(Set_SearchScopeAgent, 1, "Dtinfo: Search Scope Editor");
490 XtVaSetValues((Widget)f_shell, XmNtitle, string, NULL);
492 DECL (WXmForm, form, f_shell, "form");
493 DECL (WXmPulldownMenu, scope_menu, form, "scope_menu");
496 XtSetArg(args[n], XmNsubMenuId, (Widget) scope_menu); n++;
497 f_scope_option = WXmOptionMenu (form, "scope_option", WAutoManage, args, n);
498 ASSN (WXmPushButton, f_unnamed, scope_menu, "unnamed");
500 mtfstring = CATGETS(Set_AgentLabel, 212, "Scope Name");
501 XtVaSetValues(f_scope_option, XmNlabelString, (XmString)mtfstring, NULL);
502 mtfstring = CATGETS(Set_AgentLabel, 213, "Unnamed");
503 XtVaSetValues(f_unnamed, XmNlabelString, (XmString)mtfstring, NULL);
505 ASSNM (WXmPushButton, f_new, form, "new");
506 ASSNM (WXmPushButton, f_save, form, "save");
507 ASSNM (WXmPushButton, f_rename, form, "rename");
508 ASSNM (WXmPushButton, f_delete, form, "delete");
509 ASSNM (WXmPushButton, f_reset, form, "reset");
510 DECLM (WXmPushButton, close, form, "close");
511 DECLM (WXmPushButton, help, form, "help");
513 DECLM (WXmSeparator, separator, form, "separator");
515 DECLM (WXmLabel, bookshelf, form, "books");
516 DECLM (WXmLabel, components, form, "components");
518 mtfstring = CATGETS(Set_AgentLabel, 214, "Books");
519 XtVaSetValues(bookshelf, XmNlabelString, (XmString)mtfstring, NULL);
520 mtfstring = CATGETS(Set_AgentLabel, 215, "Components");
521 XtVaSetValues(components, XmNlabelString, (XmString)mtfstring, NULL);
522 mtfstring = CATGETS(Set_AgentLabel, 216, "New");
523 XtVaSetValues(f_new, XmNlabelString, (XmString)mtfstring, NULL);
524 mtfstring = CATGETS(Set_AgentLabel, 217, "Save");
525 XtVaSetValues(f_save, XmNlabelString, (XmString)mtfstring, NULL);
526 mtfstring = CATGETS(Set_AgentLabel, 218, "Rename");
527 XtVaSetValues(f_rename, XmNlabelString, (XmString)mtfstring, NULL);
528 mtfstring = CATGETS(Set_AgentLabel, 183, "Delete");
529 XtVaSetValues(f_delete, XmNlabelString, (XmString)mtfstring, NULL);
530 mtfstring = CATGETS(Set_AgentLabel, 202, "Reset");
531 XtVaSetValues(f_reset, XmNlabelString, (XmString)mtfstring, NULL);
532 mtfstring = CATGETS(Set_AgentLabel, 12, "Close");
533 XtVaSetValues(close, XmNlabelString, (XmString)mtfstring, NULL);
534 mtfstring = CATGETS(Set_AgentLabel, 48, "Help");
535 XtVaSetValues(help, XmNlabelString, (XmString)mtfstring, NULL);
537 // WARNING: the widget name, infobases, is used else where--do not alter.
538 f_infolib_list = new ScopeOutlineListView (form, "infobases", WAutoManage);
539 f_infolib_list->max_level (2);
541 f_component_list = new ScopeOutlineListView (form, "components",WAutoManage);
543 ON_ACTIVATE (f_new,new_scope);
544 ON_ACTIVATE (f_save,save_scope);
545 ON_ACTIVATE (f_rename,rename_scope);
546 ON_ACTIVATE (f_delete,delete_scope);
547 ON_ACTIVATE (f_reset,reset);
548 ON_ACTIVATE (close,close);
549 help_agent().add_activate_help (help, "scope_editor_help");
551 form.ShadowThickness (0);
554 // set up callback when item selected from list
555 Observe (f_infolib_list, OutlineListView::ENTRY_SELECTED,
556 &SearchScopeAgent::scope_modified);
558 Observe(f_component_list, OutlineListView::ENTRY_SELECTED,
559 &SearchScopeAgent::scope_modified);
561 // NOTE: May want to create dialogs on the fly.
562 // Types: prompt: save & rename, yes/no: delete & close
564 /* -------- Fill in lists -------- */
567 OutlineList *ol = new OutlineList (1);
568 // NOTE: hack ahead, direct reference to mmdb for wedged searching:
569 ol->append (new TOC_Element (new TOC_mmdb_lib (the_mmdb())));
572 UAS_Pointer<UAS_Common> d = UAS_Common::create ("mmdb:/t/");
573 UAS_Pointer<UAS_Collection> cd = (UAS_Collection *) ((UAS_Common *) d);
574 ol->append (new TOC_Element (cd->root()));
576 UAS_List<UAS_String> rootList = UAS_Common::rootLocators ();
577 OutlineList *ol = new OutlineList(rootList.length());
578 for (int i = 0; i < rootList.length(); i ++) {
579 UAS_Pointer<UAS_Common> d = UAS_Common::create(*(UAS_String *)rootList[i]);
580 UAS_Pointer<UAS_Collection> cd = (UAS_Collection *) ((UAS_Common *) d);
581 ol->append (new TOC_Element (cd->root()));
587 BitHandle handle = ol->get_data_handle();
588 ((OutlineElement *) (*ol)[0])->set_expanded (handle);
589 f_infolib_list->set_list (ol, handle);
590 f_infolib_list->clear();
592 // Generate a components list
593 OutlineList *component_list = generate_component_list();
594 BitHandle component_handle = component_list->get_data_handle();
595 ((OutlineElement*)(*component_list)[0])->set_expanded (component_handle);
596 f_component_list->set_list (component_list, component_handle);
597 f_component_list->clear();
599 ON_DEBUG (printf ("IB handle = %ld, CP handle = %ld\n",
600 handle, component_handle));
604 // /////////////////////////////////////////////////////////////////
605 // new_scppe - create a new scope
606 // /////////////////////////////////////////////////////////////////
609 SearchScopeAgent::new_scope()
611 if (f_reset.Sensitive())
613 bool dosave = message_mgr().question_dialog (
614 (char*)UAS_String(CATGETS(Set_Messages, 17,
615 "Do you want to save changes to the current scope?")));
620 if (! XtIsManaged((Widget)f_unnamed)) {
622 // re-computation needed, weird - 11/2/94 kamiya
623 f_scope_option.Unmanage();
624 f_scope_option.Manage();
626 f_scope_option.MenuHistory (f_unnamed);
628 f_infolib_list->clear();
629 f_component_list->clear();
631 ON_DEBUG (printf("new_scope: handle = %ld\n",f_infolib_list->data_handle()));
633 f_new.SetSensitive (False);
634 f_save.SetSensitive (True);
635 f_rename.SetSensitive (False);
636 f_delete.SetSensitive (False);
637 f_reset.SetSensitive (False);
639 f_current_scope = NULL;
643 // /////////////////////////////////////////////////////////////////
644 // scope_name_prompt - prompt for a scope name and validate it
645 // /////////////////////////////////////////////////////////////////
648 SearchScopeAgent::scope_name_prompt()
650 char *default_name = new char [31];
651 int default_name_len = 20 ;
652 const char *scope_name = "";
655 // Input validation loop.
658 int len = strlen(scope_name);
659 if (len > default_name_len)
661 delete [] default_name ;
662 default_name = new char[len + 1] ;
663 default_name_len = len ;
665 strcpy (default_name, scope_name);
666 message_mgr().set_max_length(default_name_len);
667 scope_name = message_mgr().get_string(
668 (char*)UAS_String(CATGETS(Set_SearchScopeAgent, 2,
669 "Enter the scope name to save as:")),
670 (char*)UAS_String(CATGETS(Set_SearchScopeAgent, 3,
671 "Dtinfo: Save Scope")),
674 // look for canceled operation
675 if (scope_name == NULL)
677 delete [] default_name ;
678 message_mgr().set_max_length(40);
682 scope_name = truncate ((char *) scope_name);
683 // look for bogus characters
684 if (strpbrk (scope_name, ":,;") != NULL)
686 message_mgr().error_dialog (
687 (char*)UAS_String(CATGETS(Set_Messages, 18,
688 "You cannot use a colon, comma or semicolon in a search scope name.")));
690 // look for empty scope name
691 else if (*scope_name == '\0')
693 message_mgr().error_dialog (
694 (char*)UAS_String(CATGETS(Set_Messages, 19,
695 "Please choose a non-empty scope name.")));
697 // look for name too long
698 else if (strlen (scope_name) > 20)
700 // this dialog should never popup, since we don't allow
701 // the user to enter more than the max. But, since the
702 // max char length has changed to 20, the message should
703 // be changed to reflect that--or just removed.
704 message_mgr().error_dialog (
705 (char*)UAS_String(CATGETS(Set_Messages, 20,
706 "A search scope name may not exceed 30 characters.")));
708 // look for duplicate scope name
711 // Check for name in use.
712 List_Iterator<UAS_SearchScope *> s (f_scope_list);
713 if (strcasecmp (scope_name, "unnamed") != 0)
714 for (; s != NULL; s++)
715 if (strcmp (scope_name, s.item()->name()) == 0)
719 message_mgr().error_dialog (
720 (char*)UAS_String(CATGETS(Set_Messages, 21,
721 "The name you entered is already in use.")));
729 delete [] default_name;
730 message_mgr().set_max_length(40);
735 // /////////////////////////////////////////////////////////////////
736 // save_scope - save the current scope, prompting if necessary
737 // /////////////////////////////////////////////////////////////////
740 SearchScopeAgent::save_scope()
742 // get a name and create a new scope
744 if (f_current_scope == NULL) // ie: unnamed
746 name = scope_name_prompt();
750 save_unnamed_scope (name);
751 if (XtIsManaged(f_unnamed)) {
752 f_unnamed.Unmanage();
753 // re-computation needed, weird - 11/2/94 kamiya
754 f_scope_option.Unmanage();
755 f_scope_option.Manage();
758 f_new.SetSensitive (True);
759 f_rename.SetSensitive (True);
760 f_delete.SetSensitive (True);
762 // just save it otherwise
765 BitHandle data_handle = f_scope_list.lookup_handle(f_current_scope);
766 BitHandle visible_handle = f_infolib_list->data_handle();
768 // save the bits from the applied handle
769 ON_DEBUG (printf("Copy handle %ld to %ld\n", visible_handle, data_handle));
770 f_infolib_list->list()->copy_selected (visible_handle, data_handle);
772 f_infolib_list->list()->copy_expanded (visible_handle, data_handle);
773 f_component_list->list()->copy_selected (visible_handle, data_handle);
775 // Update the component mask value in the scope.
776 f_current_scope->search_zones().zones(component_mask (data_handle));
778 UAS_PtrList<UAS_BookcaseEntry>bcases = bookcase_list(data_handle);
779 f_current_scope->bookcases(bcases);
781 // Save the scope to disk.
784 f_save.SetSensitive (False);
785 f_reset.SetSensitive (False);
789 // /////////////////////////////////////////////////////////////////
790 // create_scope - create a new scope given various info
791 // /////////////////////////////////////////////////////////////////
794 SearchScopeAgent::create_scope (const char *name,
795 UAS_PtrList<UAS_BookcaseEntry> &base_list,
796 unsigned int component_mask, bool ro)
798 // this flag should be defined elsewhere-this could
799 // become a command-line option
805 // Get a new bit handle for the new scope.
806 BitHandle handle = f_infolib_list->list()->get_data_handle();
808 // Create the new scope object.
809 UAS_SearchScope *scope = new UAS_SearchScope (name, base_list, component_mask, ro);
810 // append handle and scope to scope list
811 if(scope->read_only())
813 List_Iterator<UAS_SearchScope *> s (f_scope_list);
815 // put all read only scopes at beginning, but
816 // after the "Current Section" and "All Libraries" scopes
817 // which should always be the first 2 on the list.
818 f_scope_list.insert_after (s, scope);
819 f_scope_list.add_handle(handle, 1);
823 f_scope_list.append (scope);
824 f_scope_list.add_handle(handle, -1);
828 // Select the infobase level if the scope contains no infolibs.
829 if (base_list.numItems() == 0)
830 ((OutlineElement*)(*f_infolib_list->list())[0])->set_selected (handle);
832 UAS_BookcaseEntry *bce;
833 for (int i = 0; i < base_list.numItems(); i++)
837 // Select the correct entries in the list.
838 int index = lid_to_index(bce->lid());
839 UAS_String bce_lid(bce->lid());
840 UAS_String bce_bid(bce->bid());
841 int bcindex = bid_to_index(bce_lid, bce_bid);
843 ((OutlineElement*)(*f_infolib_list->list())[index])->children();
845 ON_DEBUG (printf ("Using base %d of %d\n",
846 bce->base_num(), iblist->length()));
848 UAS_ObjList<int> book_list = bce->book_list();
849 if (book_list.numItems() == 0)
851 ((OutlineElement*)(*iblist)[bcindex])->set_selected (handle);
852 // ((OutlineElement*)(*iblist)[bce->base_num()])->set_selected (handle);
854 // since the bookcase is selected, need to expand parent
857 ((OutlineElement*)(*f_infolib_list->list())[index])->set_expanded (handle);
863 ((OutlineElement*)(*iblist)[bcindex])->children();
864 // ((OutlineElement*)(*iblist)[bce->base_num()])->children();
868 // need to expand bookcase and infolib
869 if(book_list.numItems() > 0)
871 ((OutlineElement*)(*f_infolib_list->list())[index])->set_expanded (handle);
872 ((OutlineElement*)(*iblist)[bcindex])->set_expanded (handle);
875 for (int j = 0; j < book_list.numItems(); j++)
876 ((OutlineElement*)(*books)[book_list[j]-1])->set_selected (handle);
878 //book_list.clear(); // old code reset this list... but why? -rtp
885 SearchScopeAgent::select_infolib (UAS_String &lid, BitHandle handle)
887 ((ScopeOutlineListView *)f_infolib_list)->select_infolib(lid, handle);
890 // /////////////////////////////////////////////////////////////////
891 // select_initial - select the first scope and display it
892 // /////////////////////////////////////////////////////////////////
895 SearchScopeAgent::select_initial (Widget exception)
897 // Select the Unnamed scope if it is the only (non-exception) one left.
898 WComposite menu (f_scope_option.SubMenuId());
900 int num_kids = menu.NumChildren();
901 if ((exception != NULL && num_kids == 2) || num_kids == 1)
903 f_reset.SetSensitive (False);
906 // Select the first (non-exception) scope in the list otherwise.
909 WXmPushButton btn (menu.Children()[1]);
910 if (btn == exception)
911 btn = WXmPushButton (menu.Children()[2]);
913 set_current_scope(btn);
915 f_scope_option.MenuHistory (btn);
916 f_current_scope = (UAS_SearchScope *) btn.UserData();
917 f_infolib_list->list()->copy_selected(f_scope_list.lookup_handle(f_current_scope),
918 f_infolib_list->data_handle());
921 f_infolib_list->list()->copy_expanded(f_scope_list.lookup_handle(f_current_scope),
922 f_infolib_list->data_handle());
923 f_infolib_list->update_list(f_infolib_list->list(),
924 f_infolib_list->data_handle());
926 set_components (f_current_scope->search_zones().zones());
928 f_infolib_list->data_handle (f_infolib_list->data_handle());
929 f_component_list->data_handle (f_component_list->data_handle());
931 f_new.SetSensitive (True);
932 f_save.SetSensitive (False);
933 f_delete.SetSensitive (True);
934 f_rename.SetSensitive (True);
935 f_reset.SetSensitive (False);
941 // /////////////////////////////////////////////////////////////////
942 // rename - rename the current scope
943 // /////////////////////////////////////////////////////////////////
946 SearchScopeAgent::rename_scope()
948 WXmPushButton scope_btn (f_scope_option.MenuHistory());
949 // Rename must be insensitive for Unnamed scope. Use save instead.
950 Xassert (scope_btn != f_unnamed);
951 Xassert (f_current_scope != NULL);
952 Xassert (f_current_scope == (UAS_SearchScope *) scope_btn.UserData());
954 const char *name = scope_name_prompt();
958 scope_btn.LabelString (name);
960 f_save.SetSensitive (False);
961 f_reset.SetSensitive (False);
963 int position = 1, old_position = -1;
964 List_Iterator<UAS_SearchScope *> s (f_scope_list);
965 for (; s != NULL; s++)
967 if (s.item()->read_only())
969 if (s.item() == f_current_scope)
971 old_position = position;
974 ON_DEBUG (printf ("ScopeAgent: strcmp against <%s>\n",
976 if (strcmp (name, s.item()->name()) < 0)
981 // Move the item to the correct alphabetical placement in the list.
982 ON_DEBUG (printf ("ScopeAgent: old position = %d, new position = %d\n",
983 old_position, position));
984 if (position != old_position)
986 // look up handle for scope and save it
987 BitHandle data_handle = f_scope_list.lookup_handle(f_current_scope);
988 // remove handle and scope from scope list
989 f_scope_list.remove_handle(f_current_scope);
990 f_scope_list.remove (f_current_scope);
991 ON_DEBUG (printf ("ScopeAgent: Inserting before <%s>\n",
992 s != NULL ? s.item()->name() : "LAST"));
993 // add handle and scope back in appropriate location
994 f_scope_list.add_handle(data_handle, position-1);
995 f_scope_list.insert_before (s, f_current_scope);
997 scope_btn.PositionIndex (position);
1000 // Make sure old scope name preference isn't saved by NULLing out
1001 // it's value. This should really happen in a ScopeListMgr object. DJB
1003 sprintf (scratch, "Scope.%s", f_current_scope->name());
1004 StringPref (scratch).value ("");
1005 f_current_scope->set_name (name);
1006 f_scope_list.save();
1010 // /////////////////////////////////////////////////////////////////////////
1011 // reset - resets window to values at last save
1012 // /////////////////////////////////////////////////////////////////////////
1015 SearchScopeAgent::reset()
1017 WXmPushButton scope_btn (f_scope_option.MenuHistory());
1018 // Handle Unnamed scope as a special case.
1019 if (scope_btn == f_unnamed)
1021 f_infolib_list->clear();
1022 f_component_list->clear();
1026 UAS_SearchScope *scope = (UAS_SearchScope *) scope_btn.UserData();
1027 f_infolib_list->list()->copy_selected(f_scope_list.lookup_handle(scope),
1028 f_infolib_list->data_handle());
1029 // f_infolib_list->list()->copy_expanded(f_scope_list.lookup_handle(scope),
1030 // f_infolib_list->data_handle());
1031 set_components (scope->search_zones().zones());
1033 // update visually by resetting flag (to itself)
1034 f_infolib_list->data_handle(f_infolib_list->data_handle());
1035 f_component_list->data_handle(f_component_list->data_handle());
1038 if (scope_btn != f_unnamed)
1039 f_save.SetSensitive (False);
1040 f_reset.SetSensitive (False);
1044 // /////////////////////////////////////////////////////////////////////////
1045 // scope_modified - called when selection made in sublist
1046 // /////////////////////////////////////////////////////////////////////////
1049 SearchScopeAgent::scope_modified()
1051 f_save.SetSensitive (True);
1052 f_reset.SetSensitive (True);
1056 // /////////////////////////////////////////////////////////////////
1058 // /////////////////////////////////////////////////////////////////
1061 SearchScopeAgent::close()
1063 if (f_reset.Sensitive())
1065 bool dosave = message_mgr().question_dialog (
1066 (char*)UAS_String(CATGETS(Set_Messages, 17,
1067 "Do you want to save changes to the current scope?")));
1072 if (f_current_scope == NULL)
1073 f_unnamed.Unmanage();
1079 // /////////////////////////////////////////////////////////////////////////
1080 // save_unnamed_scope
1081 // /////////////////////////////////////////////////////////////////////////
1084 SearchScopeAgent::save_unnamed_scope (const char *name)
1088 // Allocate a bit handle for the new scope
1089 BitHandle data_handle = f_infolib_list->list()->get_data_handle();
1090 BitHandle visible_handle = f_infolib_list->data_handle();
1092 // save the bits from the applied handle
1093 ON_DEBUG (printf("Copying handle %ld to %ld\n", visible_handle, data_handle));
1094 f_infolib_list->list()->copy_selected (visible_handle, data_handle);
1096 f_infolib_list->list()->copy_expanded (visible_handle, data_handle);
1097 f_component_list->list()->copy_selected (visible_handle, data_handle);
1099 unsigned int mask = component_mask (data_handle);
1102 UAS_PtrList<UAS_BookcaseEntry>bcases = bookcase_list(data_handle);
1103 f_current_scope = new UAS_SearchScope (name, bcases, mask);
1107 // Scan the current menu to find the correct insertion position.
1108 List_Iterator<UAS_SearchScope *> s (f_scope_list);
1109 for (; s != NULL; s++, position++)
1111 if (s.item()->read_only())
1114 // Find the first item that the new entry belongs before.
1115 ON_DEBUG (printf ("Editor strcmp to <%s>\n", s.item()->name()));
1116 if (strcmp (name, s.item()->name()) < 0)
1120 f_scope_list.add_handle(data_handle, position);
1121 f_scope_list.insert_before (s, f_current_scope);
1122 ON_DEBUG (printf ("Final editor position = %d\n", position));
1124 // Create the new button.
1125 DECLM (WXmPushButton, scope_btn, f_scope_option.SubMenuId(), name);
1126 ON_ACTIVATE (scope_btn,select_scope);
1127 scope_btn.PositionIndex (position);
1128 scope_btn.UserData (f_current_scope);
1129 f_scope_option.MenuHistory (scope_btn);
1131 // Flush the changes to disk.
1132 ON_DEBUG (puts (">> About to save scope"));
1133 f_scope_list.save();
1138 SearchScopeAgent::component_mask (BitHandle handle)
1140 unsigned int return_mask = 0;
1142 OutlineList *scope_list = f_component_list->list();
1143 // BitHandle handle = f_component_list->data_handle();
1145 if (((OutlineElement*)(*scope_list)[0])->is_selected(handle)){
1146 return_mask = f_all;
1147 ON_DEBUG(cerr << "ALL COMPONENTS selected" << endl);
1149 List *top = ((OutlineElement*)(*scope_list)[0])->children();
1150 if (((OutlineElement*)(*top)[0])->is_selected(handle)){
1151 return_mask |= f_titles;
1152 ON_DEBUG(cerr << "TITLES selected" << endl);
1154 if (((OutlineElement*)(*top)[1])->is_selected(handle)){
1155 return_mask |= f_bodies;
1156 ON_DEBUG(cerr << "BODY selected" << endl);
1158 if (((OutlineElement*)(*top)[2])->is_selected(handle)){
1159 return_mask |= f_examples;
1160 ON_DEBUG(cerr << "EXAMPLES selected" << endl);
1162 if (((OutlineElement*)(*top)[3])->is_selected(handle)){
1163 return_mask |= f_indexes;
1164 ON_DEBUG(cerr << "INDEX selected" << endl);
1166 if (((OutlineElement*)(*top)[4])->is_selected(handle)){
1167 return_mask |= f_tables;
1168 ON_DEBUG(cerr << "TABLES selected" << endl);
1170 #ifndef DtinfoClient
1171 if (((OutlineElement*)(*top)[5])->is_selected(handle)){
1172 return_mask |= f_graphics;
1173 ON_DEBUG(cerr << "GRAPHICS selected" << endl);
1177 return return_mask ;
1182 SearchScopeAgent::set_components (u_int mask)
1184 #define SELECT(list, item, handle) \
1185 ((OutlineElement*)(*list)[item])->set_selected(handle)
1186 #define DESELECT(list, item, handle) \
1187 ((OutlineElement*)(*list)[item])->unset_selected(handle)
1189 OutlineList *scope_list = f_component_list->list();
1190 BitHandle handle = f_component_list->data_handle();
1191 List *top = ((OutlineElement*)(*scope_list)[0])->children();
1193 if ((mask & f_all) == f_all)
1195 SELECT(scope_list, 0, handle);
1196 DESELECT(top,0,handle);
1197 DESELECT(top,1,handle);
1198 DESELECT(top,2,handle);
1199 DESELECT(top,3,handle);
1200 DESELECT(top,4,handle);
1201 #ifndef DtinfoClient
1202 DESELECT(top,5,handle);
1207 DESELECT(scope_list, 0, handle);
1209 if (mask & f_titles)
1210 SELECT(top,0,handle);
1212 DESELECT(top,0,handle);
1214 if (mask & f_bodies)
1215 SELECT(top,1,handle);
1217 DESELECT(top,1,handle);
1219 if (mask & f_examples)
1220 SELECT(top,2,handle);
1222 DESELECT(top,2,handle);
1224 if (mask & f_indexes)
1225 SELECT(top,3,handle);
1227 DESELECT(top,3,handle);
1229 if (mask & f_tables)
1230 SELECT(top,4,handle);
1232 DESELECT(top,4,handle);
1234 #ifndef DtinfoClient
1235 if (mask & f_graphics)
1236 SELECT(top,5,handle);
1238 DESELECT(top,5,handle);
1246 // /////////////////////////////////////////////////////////////////
1247 // generate_component_list
1248 // /////////////////////////////////////////////////////////////////
1250 #define ADD(LIST,STRING,CHILD,EXPANDED) \
1251 oe = new OutlineString (STRING); \
1252 if (CHILD) oe->set_children (CHILD); \
1253 if (EXPANDED) oe->set_expanded (0x1); \
1257 SearchScopeAgent::generate_component_list()
1259 OutlineList *components = new OutlineList (10);
1260 OutlineList *parts = new OutlineList (10);
1263 ADD (components, CATGETS(Set_Messages, 22, "Everything"), parts, True);
1264 ADD (parts, CATGETS(Set_Messages, 23, "Titles"), NULL, False);
1265 ADD (parts, CATGETS(Set_Messages, 24, "Body"), NULL, False);
1266 ADD (parts, CATGETS(Set_Messages, 25, "Examples"), NULL, False);
1267 ADD (parts, CATGETS(Set_Messages, 26, "Index"), NULL, False);
1268 ADD (parts, CATGETS(Set_Messages, 27, "Tables"), NULL, False);
1269 #ifndef DtinfoClient
1270 ADD (parts, CATGETS(Set_Messages, 28, "Graphics"), NULL, False);
1273 return (components);
1277 // check to see if the first infolib is selected in the scope (handle).
1279 SearchScopeAgent::infolib_selected (BitHandle handle)
1281 OutlineElement *infolib = (OutlineElement *) (*f_infolib_list->list())[0];
1282 return (infolib->is_selected (handle));
1286 // check to see if infolib is selected in the scope (handle).
1288 SearchScopeAgent::infolib_selected (UAS_String &lid, BitHandle handle)
1290 int index = lid_to_index(lid);
1291 OutlineElement *infolib = (OutlineElement *) (*f_infolib_list->list())[index];
1293 return (infolib->is_selected (handle));
1296 // /////////////////////////////////////////////////////////////////
1297 // bookcase_list - return a list of bookcases for a given handle
1298 // /////////////////////////////////////////////////////////////////
1300 UAS_PtrList<UAS_BookcaseEntry>
1301 SearchScopeAgent::bookcase_list (BitHandle handle)
1303 ON_DEBUG (printf ("*** BUILDING SCOPE LIST, handle = %ld ***\n", handle));
1304 // Get the list of all infobases.
1306 // get the list of bookcase names
1307 UAS_List<UAS_Common> bcase_list = bookcaseList();
1308 OutlineList *ol = f_infolib_list->list();
1310 // NOTE: hardcoding - assuming 0 is only library
1313 UAS_PtrList<UAS_BookcaseEntry> bcases;
1314 UAS_BookcaseEntry *bce;
1316 UAS_Pointer<UAS_Common> common;
1317 int infolib, bookcase;
1319 // Iterate over the infolibs looking for selected entries.
1320 assert (handle != 0);
1321 for (infolib = 0; infolib < ol->length(); infolib++)
1324 // See if the infolib is selected.
1326 oe = ((OutlineElement*)(*ol)[infolib]);
1327 List *bclist = ((OutlineElement*)(*ol)[infolib])->children();
1328 if (oe->is_selected (handle))
1330 // get all bookcases and append them to the selected list
1331 for (bookcase = 0; bookcase < bclist->length(); bookcase++)
1333 oe = ((OutlineElement *)(*bclist)[bookcase]);
1334 common = ((TOC_Element*)oe)->toc();
1335 if (common->type() == UAS_BOOKCASE)
1337 // note: copied into a scope obj; deleted in scope obj's dtor
1338 bce = new UAS_BookcaseEntry(common);
1340 ON_DEBUG (printf("Adding base: %s\n",bce->name()));
1346 // The infolib is not selected--check to see if any of its
1347 // children (bookcases) are selected.
1349 // Get children of the infolib.
1350 // If the bookcase is selected, create a BookcaseEntry and
1351 // append it to the list.
1352 for (bookcase = 0; bookcase < bclist->length(); bookcase++)
1354 oe = ((OutlineElement *)(*bclist)[bookcase]);
1355 if (oe->is_selected (handle))
1357 common = ((TOC_Element*)oe)->toc();
1358 if (common->type() == UAS_BOOKCASE)
1360 // note: copied into a scope obj; deleted in scope obj's dtor
1361 bce = new UAS_BookcaseEntry(common);
1363 ON_DEBUG (printf("Adding base: %s\n",bce->name()));
1368 // The bookcase is not selected, so check to see if any kids are.
1370 // Check for any children book selections. If found, add an
1371 // entry for the enclosing bookcase and add the books to it.
1372 UAS_ObjList<int> booklist;
1373 if (oe->children_cached())
1376 // build a list of books for a give bookcase
1378 List *books = oe->children();
1379 // (1-based book, since that's how they're indexed in Fulcrum.)
1380 for (int book_num = 1; book_num <= books->length(); book_num++)
1382 ON_DEBUG (printf ("Checking Book #%d: ", book_num));
1383 if (((OutlineElement*)(*books)[book_num-1])->is_selected (handle))
1385 ON_DEBUG (puts ("selected"));
1386 booklist.append (book_num);
1390 ON_DEBUG (puts ("NOT selected"));
1393 if (booklist.numItems() == 0)
1394 continue; // nothing was selected--go to next infolib
1396 common = ((TOC_Element*)oe)->toc();
1397 // note: copied into a scope obj; deleted in scope obj's dtor
1398 bce = new UAS_BookcaseEntry(common);
1400 ON_DEBUG (printf("Adding base: %s\n",bce->name()));
1402 // Now add the booklist to that parent, which owns it now.
1403 bce->set_book_list (booklist);
1413 // ////////////////////////////////////////////////////////////////
1414 // return a list of bookcases from all infolibs currently installed
1415 // ////////////////////////////////////////////////////////////////
1416 UAS_PtrList<UAS_BookcaseEntry>
1417 SearchScopeAgent::bookcase_list()
1419 UAS_PtrList<UAS_BookcaseEntry> bcases;
1420 UAS_BookcaseEntry *bce;
1421 OutlineList *ol = f_infolib_list->list();
1424 for (int i = 0; i < ol->length(); i++)
1426 oe = ((OutlineElement *) (*ol)[i]);
1427 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
1428 UAS_List<UAS_Common> kids = infolib->children();
1429 for (int j = 0; j < kids.length(); j++)
1431 if (kids[j]->type() == UAS_BOOKCASE)
1433 // the uas scope object dups this list and will delete it
1434 bce = new UAS_BookcaseEntry(kids[j]);
1435 bce->set_base_num(j);
1436 bce->set_infolib_num(i);
1445 // Return the list of bookcases for a given infolib.
1447 UAS_PtrList<UAS_BookcaseEntry>
1448 SearchScopeAgent::bookcase_list(UAS_String &lid)
1450 int index = lid_to_index(lid);
1451 OutlineList *ol = f_infolib_list->list();
1452 OutlineElement *oe = ((OutlineElement *) (*ol)[index]);
1453 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
1455 UAS_PtrList<UAS_BookcaseEntry> bcases;
1456 UAS_BookcaseEntry *bce;
1457 UAS_List<UAS_Common> kids = infolib->children();
1459 for (int j = 0; j < kids.length(); j++)
1461 if (kids[j]->type() == UAS_BOOKCASE)
1463 // the uas scope object dups this list and will delete it
1464 bce = new UAS_BookcaseEntry(kids[j]);
1465 bce->set_base_num(j);
1472 // /////////////////////////////////////////////////////////////////////////
1473 // truncate - destructively removes leading and trailing blanks
1474 // /////////////////////////////////////////////////////////////////////////
1477 SearchScopeAgent::truncate (char *string)
1479 // remove leading blanks
1480 char *newstr = string;
1481 while (*newstr == ' ')
1484 // remove trailing blanks
1485 u_int len = strlen (newstr);
1486 char *eptr = newstr + len - 1 ;
1487 while (*eptr == ' ')
1493 // change newlines to spaces
1494 for (char *s = newstr; *s != '\0'; s++)
1502 // /////////////////////////////////////////////////////////////////////////
1504 // /////////////////////////////////////////////////////////////////////////
1507 SearchScopeAgent::select_scope (WCallback *wcb)
1509 WXmPushButton scope_btn (wcb->GetWidget());
1510 ON_DEBUG (fprintf (stderr,"ScopeEdit: selecting scope\n"));
1512 if (f_reset.Sensitive())
1514 bool dosave = message_mgr().question_dialog (
1515 (char*)UAS_String(CATGETS(Set_Messages, 17,
1516 "Do you want to save changes to the current scope?")));
1519 // Reset the menu history in case a new scope was created.
1520 f_scope_option.MenuHistory (scope_btn);
1522 set_current_scope(scope_btn);
1526 SearchScopeAgent::set_current_scope (WXmPushButton& btn)
1528 // update current selection in option menu
1529 f_scope_option.MenuHistory (btn);
1530 f_unnamed.Unmanage();
1532 // re-computation needed. - 12/20/94 haya(addition 11/2/94 kamiya)
1533 f_scope_option.Unmanage();
1534 f_scope_option.Manage();
1536 f_current_scope = (UAS_SearchScope *) btn.UserData();
1538 // Copy the specified scope's selections in the list.
1539 f_infolib_list->list()->copy_selected(f_scope_list.lookup_handle(f_current_scope),
1540 f_infolib_list->data_handle());
1543 f_infolib_list->list()->copy_expanded(f_scope_list.lookup_handle(f_current_scope),
1544 f_infolib_list->data_handle());
1545 f_infolib_list->update_list(f_infolib_list->list(), f_infolib_list->data_handle());
1547 set_components (f_current_scope->search_zones().zones());
1550 f_infolib_list->data_handle (f_infolib_list->data_handle());
1551 f_component_list->data_handle (f_component_list->data_handle());
1553 f_new.SetSensitive (True);
1554 f_save.SetSensitive (False);
1555 f_rename.SetSensitive (True);
1556 f_delete.SetSensitive (True);
1557 f_reset.SetSensitive (False);
1562 SearchScopeAgent::delete_scope()
1564 Xassert (f_current_scope != NULL);
1566 bool doit = message_mgr().question_dialog (
1567 (char*)UAS_String(CATGETS(Set_Messages, 29,
1568 "Are you sure you want to delete the scope?")));
1572 UAS_SearchScope *scope = f_current_scope;
1574 // remove the associated button
1575 Widget dead_meat = f_scope_option.MenuHistory();
1576 XtUnmanageChild (dead_meat);
1577 XtDestroyWidget (dead_meat);
1578 select_initial (dead_meat);
1580 // remove the scope from the scope list
1581 f_scope_list.remove_handle(scope);
1582 f_scope_list.remove (scope);
1584 // Make sure old scope name preference isn't saved by NULLing out
1585 // it's value. This should really happen in a ScopeListMgr object. DJB
1587 sprintf (scratch, "Scope.%s", scope->name());
1588 StringPref (scratch).value ("");
1592 f_scope_list.save();
1595 // Add new infolib to list
1597 SearchScopeAgent::add_infolib(UAS_Pointer<UAS_Common> &lib)
1599 // get infolib list and append new infolib to the list
1601 OutlineList *ol = f_infolib_list->list();
1605 UAS_String temp_lid;
1607 // See if infolib is already in list--if it's there,
1608 // don't add it again.
1609 for (int i = 0; i < ol->length(); i++)
1611 oe = ((OutlineElement *) (*ol)[i]);
1612 if (((TOC_Element *)oe)->toc() == lib)
1616 // need to make our own copy of this infolib
1617 UAS_Pointer<UAS_Common> newLib = UAS_Common::create(lib->locator());
1618 UAS_Pointer<UAS_Collection> cd = (UAS_Collection *) ((UAS_Common *) newLib);
1619 newLib = cd->root();
1620 ol->append (new TOC_Element (cd->root()));
1623 BitHandle handle = f_infolib_list->data_handle();
1624 ((OutlineElement *) (*ol)[0])->set_expanded (handle);
1625 f_infolib_list->set_list (ol, handle);
1626 f_infolib_list->clear();
1628 // find infolib insertion point in list; need the index number
1629 for (i = 0; i < ol->length(); i++)
1631 oe = ((OutlineElement *) (*ol)[i]);
1632 if (((TOC_Element *)oe)->toc()->lid() == newLib->lid())
1636 infolib_num = i; // next insertion point in list
1638 // Create search scope for new infolib
1639 UAS_String newLib_lid(newLib->lid());
1640 UAS_SearchScope *scope = create_infolib_scope(newLib_lid);
1643 // update the "All Libraries" search scope
1647 scope = get_search_scope((char*)UAS_String(
1648 CATGETS(Set_SearchScopeAgent, 4, "All Libraries")));
1650 // get a list of all bookcases
1651 UAS_PtrList<UAS_BookcaseEntry>bcases = bookcase_list();
1653 // update list of bookcases in the scope
1654 scope->bookcases(bcases);
1658 f_first_time = False;
1663 rebuild_scope_list();
1666 // Remove infolib from infobase list
1668 SearchScopeAgent::remove_infolib(UAS_Pointer<UAS_Common> &lib)
1670 // get infolib list and remove infolib from the list
1671 OutlineList *ol = f_infolib_list->list();
1675 // Get index of infolib in infobase list
1676 infolib_num = lid_to_index(lib->lid());
1678 if (infolib_num < 0)
1679 return; // infolib not in list
1681 // Remove infolib from list
1682 ol->remove (infolib_num);
1685 BitHandle handle = f_infolib_list->data_handle();
1687 f_infolib_list->clear();
1688 for (int i = 0; i < ol->length(); i ++)
1689 ((OutlineElement *) (*ol)[i])->set_expanded (handle);
1691 f_infolib_list->set_list (ol, handle);
1692 for (i = 0; i < ol->length(); i ++)
1693 ((OutlineElement *) (*ol)[i])->set_expanded (handle);
1695 f_infolib_list->set_list (ol, handle);
1700 // find the scope for deleted library.
1701 // TEMPORARY: The scope name is the id of the first
1703 UAS_List<UAS_Common> kids = lib->children();
1704 for (i = 0; i < kids.length(); i++)
1706 if (kids[i]->type() == UAS_BOOKCASE)
1710 sprintf(scratch, "Infolib %s", (char *)kids[i]->id());
1713 // remove search scope associated with infolib
1714 UAS_SearchScope *scope = get_search_scope(lib);
1716 // remove the scope from the scope list
1717 f_scope_list.remove_handle(scope);
1718 f_scope_list.remove (scope);
1721 // Make sure old scope name preference isn't saved by NULLing out
1722 // it's value. This should really happen in a ScopeListMgr
1725 sprintf (scratch, "Scope.%s", scope->name());
1726 StringPref (scratch).value ("");
1732 // update the "All Libraries" search scope
1736 scope = get_search_scope((char*)UAS_String(
1737 CATGETS(Set_SearchScopeAgent, 4, "All Libraries")));
1739 // get a list of all bookcases
1740 UAS_PtrList<UAS_BookcaseEntry>bcases = bookcase_list();
1742 // update list of bookcases in the scope
1743 scope->bookcases(bcases);
1745 rebuild_scope_list();
1748 /* work procedure */
1749 // Set current scope after callback has finished
1751 current_scope(XtPointer client_data)
1753 SearchScopeAgent* agent = (SearchScopeAgent*)client_data;
1754 agent->update_current_scope();
1759 SearchScopeAgent::update_current_scope()
1765 UAS_SearchScope* scope;
1766 UAS_SearchScope* current_scope=NULL;
1769 XtSetArg(args[n], XmNnumChildren, &num_kids); n++;
1770 XtSetArg(args[n], XmNchildren, &kids); n++;
1771 XtGetValues(f_scope_option.SubMenuId(), args, n);
1773 if(f_current_scope != NULL)
1775 for (int i = 1; i < num_kids; i++)
1777 WXmPushButton btn (kids[i]);
1778 scope = (UAS_SearchScope*)btn.UserData();
1779 if(scope->name() == f_current_scope->name())
1781 set_current_scope(btn);
1789 WXmPushButton btn (kids[1]);
1790 set_current_scope(btn);
1794 // There are no user scopes in list. Manage the unnamed button
1795 // and set current scope to NULL
1796 f_reset.SetSensitive (False);
1800 // Rebuild the scope list after an infolib is added or removed.
1801 // Then update the option menu to reflect changes that may
1802 // have occured in the scope list.
1805 SearchScopeAgent::rebuild_scope_list()
1807 UAS_SearchScope *scope;
1808 // Save the name of the current scope.
1810 if (f_current_scope != NULL)
1812 name = UAS_String(f_current_scope->name());
1815 // Delete all named scopes so list can be rebuilt.
1816 List_Iterator<UAS_SearchScope *> si (f_scope_list);
1818 for (; si != NULL; si++)
1822 // delete all named scopes
1823 if (!scope->read_only())
1825 // remove the scope from the scope list
1826 f_scope_list.remove_handle(scope);
1827 f_scope_list.remove (scope);
1830 si.reset(); // this really is necessary.
1831 // see comment in List_base::remove()
1835 // Rebuild the named scope list.
1836 f_scope_list.create_named_scopes();
1838 // update query editor menu
1839 if (f_option_menu != NULL)
1840 f_option_menu->update_option_menu();
1842 update_option_menu(name);
1844 static UpdateMenu update_menu;
1845 update_menu.update = True;
1846 send_message(update_menu);
1849 // Update the option menu to reflect any changes
1850 // that may have occured in the list of named scopes due
1851 // to addition or removal of infolibs.
1852 // Update current scope.
1854 SearchScopeAgent::update_option_menu(UAS_String &scope_name)
1863 XtSetArg(args[n], XmNnumChildren, &num_kids); n++;
1864 XtSetArg(args[n], XmNchildren, &kids); n++;
1865 XtGetValues(f_scope_option.SubMenuId(), args, n);
1867 // destroy all toggle buttons in menu except
1868 // the unnamed button.
1869 for (int i = 1; i < num_kids; i++)
1871 XtUnmanageChild (kids[i]);
1872 XtDestroyWidget (kids[i]);
1877 XtAppAddWorkProc(window_system().app_context(), (XtWorkProc)current_scope, this);
1879 // need to set current scope to a valid scope.
1880 // see if the former "current scope" is still around.
1881 // if not, set current scope to first scope in list.
1882 // if there are no scopes in the list, set current scope
1883 // to NULL and manage the UnNamed scope button.
1885 // iterate through search scope list to see if current
1886 // scope is still there
1887 List_Iterator<UAS_SearchScope *> si (f_scope_list);
1889 UAS_SearchScope *scope;
1890 UAS_SearchScope *user_scope = NULL;
1892 f_current_scope = NULL;
1893 for (; si != NULL; si++)
1897 if (!scope->read_only())
1899 if (user_scope == NULL)
1900 user_scope = scope; // keep track of first user scope
1901 if(scope_name == scope->name())
1903 set_current_scope(scope);
1909 // see if former current scope has been deleted
1910 // due to infolib removal.
1911 if (user_scope == NULL)
1913 // There are no user scopes in list. Manage the unnamed button
1914 // and set current scope to NULL
1915 f_reset.SetSensitive (False);
1920 // set current scope to first user scope-need to get
1921 // associated menu button.
1924 XtSetArg(args[n], XmNnumChildren, &num_kids); n++;
1925 XtSetArg(args[n], XmNchildren, &kids); n++;
1926 XtGetValues(f_scope_option.SubMenuId(), args, n);
1928 set_current_scope(kids[1]);
1933 UAS_List<UAS_Common>
1934 SearchScopeAgent::list()
1936 if (f_shell == NULL)
1941 UAS_List<UAS_Common> rval;
1942 OutlineList *ol = f_infolib_list->list();
1945 for (int i = 0; i < ol->length(); i++)
1947 oe = ((OutlineElement *) (*ol)[i]);
1948 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
1949 rval.insert_item((UAS_Common *)(infolib));
1954 // return a list of bookcase objects for a given infolib
1956 UAS_List<UAS_Common>
1957 SearchScopeAgent::list(UAS_String &lid)
1959 // convert lid into index
1960 int index = lid_to_index(lid);
1961 OutlineList *ol = f_infolib_list->list();
1962 OutlineElement *oe = ((OutlineElement *) (*ol)[index]);
1964 // extract the infolib
1965 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
1967 UAS_List<UAS_Common> rval;
1969 // get infolibs children--only save bookcases
1970 UAS_List<UAS_Common> kids = infolib->children();
1971 for (int i = 0; i < kids.length(); i++)
1972 if (kids[i]->type() == UAS_BOOKCASE)
1973 rval.insert_item(kids[i]);
1977 // Create a scope for an infolib based on the infolib id
1980 SearchScopeAgent::create_infolib_scope(UAS_String &lid)
1982 int index = lid_to_index(lid);
1983 OutlineList *ol = f_infolib_list->list();
1984 OutlineElement *oe = ((OutlineElement *) (*ol)[index]);
1985 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
1987 UAS_PtrList<UAS_BookcaseEntry> bcases;
1988 UAS_BookcaseEntry *bce;
1992 int first_base_num = -1;
1998 cerr << "locator: " << (char *)infolib->locator() << endl;
1999 cerr << " id: " << (char *)infolib->id() << endl;
2000 cerr << " lid: " << (char *)infolib->lid() << endl;
2001 cerr << " name: " << (char *)infolib->name() << endl;
2002 cerr << " locale: " << (char *)infolib->locale() << endl;
2005 // get list of all bookcases for infolib and create bookcase
2006 // entry for each one.
2008 UAS_List<UAS_Common> kids = list(lid);
2009 for (int i = 0; i < kids.length(); i++)
2011 bce = new UAS_BookcaseEntry(kids[i]);
2017 sprintf(scratch, "Infolib %s", (char *)kids[first_base_num]->id());
2020 // create search scope for infolib using the infolib name as
2021 // search scope name.
2024 s = create_scope((char*)infolib->name(), bcases, f_all, TRUE);
2025 s->set_infolib(infolib);
2029 // Find the index into the f_infolib_list given a lid
2032 SearchScopeAgent::lid_to_index(const UAS_String &lid)
2034 return ((ScopeOutlineListView *)f_infolib_list)->lid_to_index(lid);
2038 SearchScopeAgent::lid_to_name(UAS_String &lid)
2040 return ((ScopeOutlineListView *)f_infolib_list)->lid_to_name(lid);
2044 SearchScopeAgent::name_to_lid(UAS_String &name)
2046 return ((ScopeOutlineListView *)f_infolib_list)->name_to_lid(name);
2049 // Given a bookcase id, return its index into the f_infolib_list
2052 SearchScopeAgent::bid_to_index(UAS_String &lid, UAS_String &bid)
2054 int index = ((ScopeOutlineListView *)f_infolib_list)->lid_to_index(lid);
2055 OutlineList *ol = f_infolib_list->list();
2056 OutlineElement *oe = ((OutlineElement *) (*ol)[index]);
2057 UAS_Pointer<UAS_Common> infolib = ((TOC_Element *)oe)->toc();
2058 UAS_List<UAS_Common> kids = infolib->children();
2059 for (int i = 0; i < kids.length(); i++)
2061 if (kids[i]->bid() == bid)
2064 // There has to be an bookcase for a given bid--if
2065 // not, something has gone wrong.
2066 throw (CASTEXCEPT Exception());
2069 // given a search scope name, return the search scope
2071 SearchScopeAgent::get_search_scope(const char* name)
2073 xList<UAS_SearchScope *> &scopes = f_scope_list;
2074 List_Iterator<UAS_SearchScope *> iter (scopes);
2075 UAS_SearchScope *scope;
2079 scope = iter.item();
2080 if (strcmp(name, scope->name()) == 0)
2083 throw (CASTEXCEPT Exception());
2086 // Given an infolib, return the search scope.
2089 SearchScopeAgent::get_search_scope(UAS_Pointer<UAS_Common> &infolib)
2091 xList<UAS_SearchScope *> &scopes = f_scope_list;
2092 List_Iterator<UAS_SearchScope *> iter (scopes);
2093 UAS_SearchScope *scope;
2095 int maxScope=0; // max scope index
2097 iter++; // skip "Current Section" scope
2098 iter++; // skip "All Libraries" scope
2100 // find scope for associated infolib
2103 scope = iter.item();
2104 if(scope->get_infolib() == infolib)
2107 throw (CASTEXCEPT Exception());
2110 // Search scope agent needs access to query editor
2112 SearchScopeAgent::option_menu(QueryEditor *menu)
2114 f_option_menu = menu;