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 /* $XConsortium: ScopeMenu.C /main/6 1996/10/14 17:59:18 cde-hal $ */
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 1996 FUJITSU LIMITED.
31 * (c) Copyright 1996 Hitachi.
34 * Copyright (c) 1994 HAL Computer Systems International, Ltd.
35 * All rights reserved. Unpublished -- rights reserved under
36 * the Copyright Laws of the United States. USE OF A COPYRIGHT
37 * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
40 * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
41 * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. USE,
42 * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
43 * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
46 * RESTRICTED RIGHTS LEGEND
47 * Use, duplication, or disclosure by the Government is subject
48 * to the restrictions as set forth in subparagraph (c)(l)(ii)
49 * of the Rights in Technical Data and Computer Software clause
50 * at DFARS 252.227-7013.
52 * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
64 #define C_SearchScopeAgent
70 #define C_SearchScopeMgr
74 #define C_WindowSystem
79 #define CLASS ScopeMenu
80 #include "create_macros.hh"
82 #include <WWL/WXmPushButtonGadget.h>
83 #include <WWL/WXmSeparator.h>
84 #include <WWL/WXmMenu.h>
85 #include <WWL/WXmCascadeButton.h>
87 ScopeMenu::ScopeMenu (Widget option_menu, bool require_current_section)
88 : f_current_scope (NULL),
89 f_use_current_section(require_current_section),
90 f_option_menu(option_menu)
96 XtSetArg(args[n], XmNsubMenuId, &f_pull_menu); n++;
97 XtGetValues(option_menu, args, n);
101 UAS_SearchScope::request ((UAS_Receiver<ScopeCreated> *) this);
102 UAS_SearchScope::request ((UAS_Receiver<ScopeDeleted> *) this);
103 UAS_SearchScope::request ((UAS_Receiver<ScopeRenamed> *) this);
105 SearchScopeAgent::request ((UAS_Receiver<UpdateMenu> *) this);
108 ScopeMenu::~ScopeMenu()
114 ScopeMenu::fill_menu()
119 // Create toggle buttons for each scope.
120 xList<UAS_SearchScope *> &scope_list = search_scope_mgr().scope_list();
121 List_Iterator<UAS_SearchScope *> s (scope_list);
122 bool old_read_only = TRUE;
124 // Set the current scope to the first entry
125 // (Current Section or Information Library)
126 f_current_scope = s.item();
128 ON_DEBUG(cerr << "Scope Popup" << endl);
134 // in case we are not using Current Section
135 if (f_current_scope == NULL)
136 f_current_scope = s.item();
138 ON_DEBUG(cerr << "\t" << f_current_scope->name() << endl);
139 // ON_DEBUG(f_current_scope->dump_items());
141 // Add a separator when they change from read only to changable.
142 if (old_read_only != s.item()->read_only())
144 DECLM (WXmSeparator, sep1, f_pull_menu, "separator");
145 sep1.PositionIndex (position++);
146 old_read_only = FALSE;
148 DECLM (WXmPushButtonGadget, scope, f_pull_menu, s.item()->name());
149 if (first && !f_use_current_section)
153 // Reset current scope so that it is set to Library on next pass.
154 f_current_scope = NULL;
156 scope.UserData (s.item());
157 scope.PositionIndex (position++);
159 WCallback *cb = SET_CALLBACK(scope,Activate,set_scope);
160 SET_CALLBACK_D (scope,Destroy,destroy_scope,cb);
161 if (f_current_scope == s.item())
165 XtSetArg(args[n], XmNmenuHistory, (Widget)scope); n++;
166 XtSetValues(f_option_menu, args, n);
170 //UAS_SearchScope::request ((UAS_Receiver<ScopeCreated> *) this);
171 //UAS_SearchScope::request ((UAS_Receiver<ScopeDeleted> *) this);
172 //UAS_SearchScope::request ((UAS_Receiver<ScopeRenamed> *) this);
177 ScopeMenu::set_scope (WCallback *wcb)
179 CALL_DATA (XmToggleButtonCallbackStruct,tbcs);
182 (UAS_SearchScope *) WXmPushButtonGadget(wcb->GetWidget()).UserData();
187 ScopeMenu::destroy_scope (WCallback *wcb)
189 WCallback *cb = (WCallback *) wcb->ClientData();
194 // /////////////////////////////////////////////////////////////////
195 // receive - handle scope created / deleted messages
196 // /////////////////////////////////////////////////////////////////
199 ScopeMenu::receive (ScopeCreated &msg, void *client_data)
202 const char *scope_name = msg.f_search_scope->name();
203 xList<UAS_SearchScope *> &scope_list = search_scope_mgr().scope_list();
204 List_Iterator<UAS_SearchScope *> s (scope_list);
205 bool need_sep = TRUE;
213 XtSetArg(args[n], XmNnumChildren, &num_kids); n++;
214 XtSetArg(args[n], XmNchildren, &kids); n++;
215 XtGetValues(f_pull_menu, args, n);
217 UAS_SearchScope *scope;
219 if (msg.f_search_scope->read_only())
221 // insert read-only scopes at the start; reserve position 0
222 // for "Current Section" scope and position 1 for
223 // the "All Libraries" scope
229 // Scan the current menu to find the correct insertion position.
230 for (; s != 0; s++, position++)
233 if (need_sep != scope->read_only())
235 position++; // skip separator
238 if (scope->read_only())
240 // Find the first item that the new entry belongs after.
241 ON_DEBUG (printf ("Scope strcmp to <%s>\n", scope->name()));
242 if (strcmp (scope_name, scope->name()) < 0)
247 ON_DEBUG (printf ("Final position = %d\n", position));
249 // Add a separator if this is the first user-defined entry.
250 if (need_sep == TRUE)
252 DECLM (WXmSeparator, separator, f_pull_menu, "separator");
253 separator.PositionIndex (position);
257 // Create the new toggle button.
258 DECLM (WXmPushButtonGadget, scope_btn, f_pull_menu, scope_name);
259 scope_btn.PositionIndex (position);
260 scope_btn.UserData (msg.f_search_scope);
261 WCallback *cb = SET_CALLBACK(scope_btn,Activate,set_scope);
262 SET_CALLBACK_D(scope_btn,Destroy,destroy_scope,cb);
266 ScopeMenu::receive (ScopeDeleted &msg, void *client_data)
268 // find the associated button and nuke it
269 ON_DEBUG (puts ("ScopeMenu: handling delete message"));
270 // First find renamed button in our list.
275 int separator_pos = -1;
279 XtSetArg(args[n], XmNmenuHistory, &selected); n++;
280 XtGetValues(f_option_menu, args, n);
283 XtSetArg(args[n], XmNnumChildren, &num_kids); n++;
284 XtSetArg(args[n], XmNchildren, &kids); n++;
285 XtGetValues(f_pull_menu, args, n);
288 for (i = 0; i < num_kids; i++)
290 if (XmIsSeparator (kids[i]))
292 separator_pos = i + 1;
295 if (XmIsPushButtonGadget (kids[i]) &&
296 msg.f_search_scope ==
297 ((UAS_SearchScope *) WXmPushButtonGadget (kids[i]).UserData()))
301 // It had better be in the list!
303 Xassert (theKid != num_kids);
304 ON_DEBUG (printf ("widget #%d is the button\n", theKid));
306 // if it is selected, select first w/ callback called
307 if (kids[theKid] == selected)
310 if (XtIsManaged (kids[0]))
311 XtSetArg(args[n], XmNmenuHistory, kids[0]);
313 XtSetArg(args[n], XmNmenuHistory, kids[1]);
315 XtSetValues(f_option_menu, args, n);
318 XtUnmanageChild (kids[theKid]);
319 XtDestroyWidget (kids[theKid]);
321 // Get rid of the separator if no user scopes remain.
322 ON_DEBUG (printf ("ScopeMenu: sep pos = %d, num_kids = %d (%d)\n",
323 separator_pos, num_kids, num_kids -1 -2));
324 // - 1 for deleted widget
325 if (separator_pos == (num_kids - 1))
327 ON_DEBUG (puts (" destroying separator"));
328 XtDestroyWidget (kids[separator_pos-1]);
334 ScopeMenu::receive (ScopeRenamed &msg, void *client_data)
336 ON_DEBUG (puts ("ScopeMenu: handling rename message"));
337 // First find renamed button in our list.
342 int separator_pos = -1;
345 XtSetArg(args[n], XmNnumChildren, &num_kids); n++;
346 XtSetArg(args[n], XmNchildren, &kids); n++;
347 XtGetValues(f_pull_menu, args, n);
350 for (i = 0; i < num_kids; i++)
352 if (XmIsPushButtonGadget (kids[i]) &&
353 msg.f_search_scope ==
354 ((UAS_SearchScope *) WXmPushButtonGadget (kids[i]).UserData()))
358 // It had better be in the list!
359 Xassert (i != num_kids);
360 ON_DEBUG (printf ("ScopeMenu: widget #%d is the button\n", i));
362 // Now find the new insertion position in the list.
363 int position = 0, old_position = i;
364 xList<UAS_SearchScope *> &scope_list = search_scope_mgr().scope_list();
365 List_Iterator<UAS_SearchScope *> s (scope_list);
367 // find the new position in the list
370 if (s.item() == msg.f_search_scope)
373 if (s.item()->read_only())
375 ON_DEBUG (printf ("ScopeMenu: strcmp <%s>\n", s.item()->name()));
376 if (strcmp (msg.f_search_scope->name(), s.item()->name()) < 0)
383 ON_DEBUG (printf ("ScopeMenu: Rename position = %d, old = %d\n",
384 position, old_position));
385 WXmPushButtonGadget scope_btn (kids[i]);
386 scope_btn.LabelString (msg.f_search_scope->name());
387 if (position != old_position)
388 scope_btn.PositionIndex (position);
392 ScopeMenu::receive (UpdateMenu &msg, void *client_data)
394 xList<UAS_SearchScope *> &scope_list = search_scope_mgr().scope_list();
395 List_Iterator<UAS_SearchScope *> s (scope_list);
403 XtSetArg(args[n], XmNnumChildren, &num_kids); n++;
404 XtSetArg(args[n], XmNchildren, &kids); n++;
405 XtGetValues(f_pull_menu, args, n);
407 // destroy all toggle buttons in menu
408 for (int i = 0; i < num_kids; i++)
410 XtUnmanageChild (kids[i]);
411 XtDestroyWidget (kids[i]);
414 // select current scope
415 if(f_use_current_section)
416 f_current_scope = s.item();
420 f_current_scope = s.item();
423 XtUnmanageChild(XtParent(f_option_menu));
424 XtManageChild(XtParent(f_option_menu));
425 XtUnmanageChild(f_option_menu);
426 XtManageChild(f_option_menu);