1 /* Copyright (c) 1994,1995,1996 FUJITSU LIMITED */
2 /* All Rights Reserved */
5 * $TOG: SearchResultsAgentMotif.C /main/17 1998/04/17 11:35:18 mgreess $
7 * Copyright (c) 1991 HaL Computer Systems, Inc. All rights reserved.
8 * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
9 * States. Use of a copyright notice is precautionary only and does not
10 * imply publication or disclosure.
12 * This software contains confidential information and trade secrets of HaL
13 * Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
14 * wihtout the prior express written permission of HaL Computer Systems, Inc.
16 * RESTRICTED RIGHTS LEGEND
17 * Use, duplication, or disclosure by the Government is subject to
18 * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
19 * Technical Data and Computer Software clause at DFARS 252.227-7013.
20 * HaL Computer Systems, Inc.
21 * 1315 Dell Avenue, Campbell, CA 95008
37 #define C_SearchResultsMgr
43 #define C_SearchResultsAgent
44 #define C_NodeListAgent
48 #define USES_OLIAS_FONT
50 #include "Other/XmStringLocalized.hh"
51 #include "Managers/CatMgr.hh"
52 #include "Managers/WString.hh"
57 #include "Registration.hh"
59 #include <WWL/WXmList.h>
60 #include <WWL/WXmForm.h>
61 #include <WWL/WXmLabel.h>
62 #include <WWL/WXmText.h>
63 #include <WWL/WXmToggleButton.h>
64 #include <WWL/WXmPushButton.h>
65 #include <WWL/WXmPanedWindow.h>
73 static Boolean g_allow_query_text_change;
75 #define INITIAL_FILL_SIZE 1000
76 #define INCREMENTAL_FILL_SIZE 100
79 // /////////////////////////////////////////////////////////////////
81 // /////////////////////////////////////////////////////////////////
84 SearchResultsAgent::init()
86 NodeListAgent::init();
90 // /////////////////////////////////////////////////////////////////
92 // /////////////////////////////////////////////////////////////////
94 // Hard Coded pixel offset (from left margin) where Node Title Starts in
95 // result list - 14:36 07/26/93 - jbm
96 #define SECTION_OFFSET 150
99 SearchResultsAgent::form_result_string (UAS_Pointer<UAS_SearchResultsEntry> re)
101 static char relevancy[3];
102 if (relevancy[1] == '\0')
104 if (window_system().nofonts())
107 relevancy[1] = OLIAS_SPACE08;
110 // Scale all weights from to the range 0 to 8. While 8 / scale
111 // may look like a constant, it cannot be factored because integer
112 // arithmetic rounding might adversely affect the results. DJB
113 relevancy[0] = OLIAS_RELEVANCY_ICON;
115 relevancy[0] += (char) ((re->relevance() * 8 ) / f_scale);
118 WXmString rel (relevancy, OLIAS_FONT);
125 book = (char *) re->book();
126 name = (char *) re->section();
130 // backward compatibility
132 UAS_Pointer<UAS_Common> doc_ptr = UAS_Common::create (re->id());
133 UAS_String bn = doc_ptr->book_name (UAS_SHORT_TITLE);
134 UAS_String tt = doc_ptr->title();
139 int section_offset = f_list->Width() / 3;
141 int allowance = section_offset - book.Width(f_list->FontList());
144 // NOTE: space is hardcoded and will cause problems if font changes
145 // -10:24 07/12/93 - jbm
146 XmString xmstr = window_system().make_space(allowance, *f_list);
154 WXmString temp_xmstring = book + WXmString(dots);
155 char *temp_str = (char*)temp_xmstring;
157 WString temp_WString(temp_str);
158 wchar_t* buf = (wchar_t*) temp_WString;
159 wchar_t* ptr = buf + wcslen(buf) - (strlen(dots)+1);
166 memcpy(ptr--, (wchar_t*)wdots, (strlen(dots)+1) * sizeof(wchar_t));
168 stake = str = WString(buf).get_mbstr();
170 allowance = section_offset - stake.Width(f_list->FontList());
174 while (allowance <= 0 && ptr >= buf);
177 while (*ptr <= (wchar_t)' ' && ptr >= buf)
180 memcpy(ptr--, (wchar_t*)wdots, (strlen(dots)+1) * sizeof(wchar_t));
182 stake = str = WString(buf).get_mbstr();
183 allowance = section_offset - stake.Width(f_list->FontList());
189 XmString xmstr = window_system().make_space(allowance, *f_list);
196 // Entire string must be disowned to prevent destructor of temporary
197 // object from freeing its XmString.
199 XmString string = (rel + book + space + name).disown();
205 // /////////////////////////////////////////////////////////////////
207 // /////////////////////////////////////////////////////////////////
212 return x < y ? x : y ;
216 SearchResultsAgent::resizeCB(Widget, XtPointer client_data, XEvent*, Boolean*)
218 SearchResultsAgent* agent = (SearchResultsAgent*)client_data;
224 SearchResultsAgent::compose_header()
227 (WXmLabel*)XtNameToWidget((Widget)*f_list_form, "header");
229 WXmString bookString = CATGETS(Set_AgentLabel, 184, "Book");
230 WXmString sectString = CATGETS(Set_AgentLabel, 185, "Section");
232 WXmString bookPostfix(
233 window_system().make_space(
234 f_list->Width() / 3 - bookString.Width(header->FontList()),
239 WXmString header_string = bookString + bookPostfix + sectString;
241 header->LabelString((XmString)header_string);
245 SearchResultsAgent::resize()
247 UAS_List<UAS_SearchResultsEntry>& rlist =
248 *(f_results->results()->create_results(0, f_count));
256 SearchResultsAgent::display (ResultID *results)
263 UAS_SearchEngine &se = search_mgr().search_engine();
265 // get window up quick
267 f_docs_to_display = imin(results->ndocs(), pref_mgr().get_int(PrefMgr::MaxSearchHits));
270 if (INITIAL_FILL_SIZE < f_docs_to_display)
271 f_count = INITIAL_FILL_SIZE;
273 f_count = f_docs_to_display ;
275 // INITIAL_FILL_SIZE(1000) is greater than the maximum of preference
276 // so, f_docs_to_display never exceeds INITIAL_FILL_SIZE
277 f_count = f_docs_to_display;
280 UAS_Pointer<UAS_List<UAS_SearchResultsEntry> > tmpList =
281 results->results()->create_results(0, f_count);
282 UAS_List<UAS_SearchResultsEntry>& rlist =
283 *(UAS_List<UAS_SearchResultsEntry> *)tmpList;
285 // All entries scaled by the weight of the first because it is
286 // be the max weight for the list.
287 assert( rlist[0] != 0);
288 f_scale = rlist[0]->relevance ();
290 // NOTE: Using bogus internal string below:
292 message_mgr().warning_dialog (
293 (char*)UAS_String(CATGETS(Set_Messages, 69,
294 "Search results weighting are not available.")));
296 /* -------- Display the number of hits. -------- */
299 sprintf (buffer, "%d of %d sections",
300 f_docs_to_display, results->ndocs());
301 f_hits_label->LabelString (buffer);
302 sprintf (buffer, "%s",
303 (char *)*(UAS_String*)(results->results()->scope_name()));
304 f_scope_label->LabelString (buffer);
306 /* -------- Display the text of the query. -------- */
307 g_allow_query_text_change = True;
309 f_query_text->Value ((char*)*(UAS_String*)(results->results()->query()));
311 g_allow_query_text_change = False;
314 NodeListAgent::display();
319 if (pref_mgr().get_boolean (PrefMgr::DisplayFirstHit))
321 f_list->SelectPos (1, True);
325 f_list->DeselectAllItems();
326 f_display.SetSensitive (False);
329 XtAddEventHandler((Widget)*f_list_form, StructureNotifyMask, False,
330 resizeCB, (XtPointer)this);
334 // /////////////////////////////////////////////////////////////////
336 // /////////////////////////////////////////////////////////////////
339 SearchResultsAgent::fill_list_wp (XtPointer /*client_data*/)
342 return ((SearchResultsAgent *) client_data)->fill_list();
349 // /////////////////////////////////////////////////////////////////
351 // /////////////////////////////////////////////////////////////////
354 SearchResultsAgent::fill_list(UAS_List<UAS_SearchResultsEntry>& rlist)
356 static XmString string_table[INITIAL_FILL_SIZE];
357 XmString *t = string_table;
359 int string_count = 0 ;
360 for (int i = 0; i < rlist.length(); i ++) {
362 *t++ = form_result_string (rlist[i]);
366 f_list->Set (WArgList (XmNitems, (XtArgVal) string_table,
367 XmNitemCount, f_count,
370 for (i = 0 ; i < string_count; i++) {
371 XmStringFree(string_table[i]);
372 string_table[i] = NULL;
376 static XmString string_table [INCREMENTAL_FILL_SIZE];
377 XmString *t = string_table;
379 int number, num_remaining = f_docs_to_display - f_count;
381 if (INCREMENTAL_FILL_SIZE < num_remaining)
382 number = INCREMENTAL_FILL_SIZE;
384 number = num_remaining;
386 UAS_Pointer<UAS_List<UAS_SearchResultsEntry> > tmpList =
387 f_results->results()->create_results(f_count, number);
388 UAS_List<UAS_SearchResultsEntry> & rlist =
389 *(UAS_List<UAS_SearchResultsEntry>*)tmpList;
392 for (i = 0; i < rlist.length(); i ++) {
393 *t++ = form_result_string (rlist[i]);
395 // 0 means add at last position in the list.
396 XmListAddItems (*f_list, (XmString *) string_table, number, 0);
400 for (i = 0 ; i < number; i++)
401 XmStringFree ((XmString) string_table[i]);
403 // Return True if the list is complete, False otherwise.
404 if (f_count == f_docs_to_display)
406 f_work_proc_id = NULL;
419 // /////////////////////////////////////////////////////////////////
421 // /////////////////////////////////////////////////////////////////
424 SearchResultsAgent::create_window()
426 create_base_window ("results");
428 XmStringLocalized mtfstring;
431 string = CATGETS(Set_SearchResultsAgent, 1, "Dtinfo: Search Results");
432 XtVaSetValues((Widget)*f_shell, XmNtitle, string, NULL);
434 help_agent().add_activate_help(f_help, "results_help");
436 #define AM WAutoManage
437 // NOTE: need form to contain things in the same row 'cause of resizing
441 new WXmToggleButton (*f_form, "retain", AM,
442 WArgList (XmNlabelPixmap,
443 (XtArgVal)window_system().unlocked_pixmap(*f_form),
445 window_system().semilocked_pixmap(*f_form),
448 f_retain_toggle = new WXmToggleButton (*f_form, "retain", AM);
450 WXmLabel retrieved (*f_form, "retrieved", AM);
451 f_hits_label = (WXmLabel*)(Widget) WXmLabel (*f_form, "num_hits", AM);
452 WXmLabel scope (*f_form, "scope", AM);
453 f_scope_label = (WXmLabel*)(Widget) WXmLabel (*f_form, "scope_name", AM);
454 WXmLabel query_label (*f_form, "query_label", AM);
456 mtfstring = CATGETS(Set_AgentLabel, 219, "Retrieved:");
457 XtVaSetValues(retrieved, XmNlabelString, (XmString)mtfstring, NULL);
458 mtfstring = CATGETS(Set_AgentLabel, 194, "File a Bug");
459 XtVaSetValues((Widget)f_hits_label, XmNlabelString, (XmString)mtfstring, NULL);
460 mtfstring = CATGETS(Set_AgentLabel, 220, "Scope:");
461 XtVaSetValues(scope, XmNlabelString, (XmString)mtfstring, NULL);
462 mtfstring = CATGETS(Set_AgentLabel, 194, "File a Bug");
463 XtVaSetValues((Widget)f_scope_label, XmNlabelString, (XmString)mtfstring, NULL);
464 mtfstring = CATGETS(Set_AgentLabel, 221, "Query:");
465 XtVaSetValues(query_label, XmNlabelString, (XmString)mtfstring, NULL);
467 Widget textw = XmCreateScrolledText (*f_pane, "query_text", NULL, 0);
468 f_query_text = new WXmText (textw);
469 f_query_text->Manage();
470 // WXmPushButton editq (*f_panel, "edit_query", AM);
472 f_retain_toggle->SetValueChangedCallback
473 (this, (WWL_FUN) &SearchResultsAgent::retain_changed);
474 set_retain_default();
477 CXmForm pane (*f_pane);
480 pane.TopWidget (query_label, args);
481 pane.TopAttachment (XmATTACH_WIDGET, args);
482 pane.Set (args.Args(), args.NumArgs());
485 static char relevancy[3];
486 if (relevancy[0] == '\0')
488 relevancy[0] = OLIAS_RELEVANCY_ICON;
489 if (window_system().nofonts())
492 relevancy[1] = OLIAS_SPACE08;
495 // set up column labels (Book, Section)
496 WXmLabel header (*f_list_form, "header", AM);
498 { // header needs dtinfo space font
499 XmFontList header_font = XmFontListCopy(header.FontList());
501 if (window_system().dtinfo_space_font())
502 header_font = XmFontListAppendEntry(header_font,
503 window_system().dtinfo_space_font());
505 header.FontList(header_font);
508 int offset = WXmString(relevancy, OLIAS_FONT).Width(f_list->FontList());
509 header.LeftOffset(offset);
511 WXmPrimitive prim(XtParent(*f_list));
512 prim.TopWidget(header);
513 prim.TopAttachment(XmATTACH_WIDGET);
518 f_list->SetSingleSelectionCallback (this,
519 (WWL_FUN) &SearchResultsAgent::select_item);
520 f_list->SetBrowseSelectionCallback (this,
521 (WWL_FUN) &SearchResultsAgent::select_item);
522 f_list->SetDefaultActionCallback (this,
523 (WWL_FUN) &SearchResultsAgent::view_activate);
524 f_display.SetActivateCallback (this,
525 (WWL_FUN) &SearchResultsAgent::view_activate);
526 f_query_text->SetModifyVerifyCallback (this,
527 (WWL_FUN) &SearchResultsAgent::modify_verify);
529 XmProcessTraversal (f_display, XmTRAVERSE_CURRENT);
533 // /////////////////////////////////////////////////////////////////
535 // /////////////////////////////////////////////////////////////////
537 // NOTE: perhaps this should be in the base class?? 6/12/92 djb
540 SearchResultsAgent::select_item (WCallback *wcb)
542 XmListCallbackStruct *lcs = (XmListCallbackStruct *) wcb->CallData();
544 f_selected_item = lcs->item_position - 1;
546 ON_DEBUG (printf ("Selected item #%d\n", f_selected_item);)
548 f_display.SetSensitive (True);
552 // /////////////////////////////////////////////////////////////////
554 // /////////////////////////////////////////////////////////////////
557 SearchResultsAgent::view_activate (WCallback *)
559 if (f_list->SelectedItemCount() != 1)
566 UAS_List<UAS_SearchResultsEntry> & rlist = f_results->results()->results();
568 search_mgr().current_hits (rlist[f_selected_item]->create_matches());
569 target = rlist[f_selected_item]->id();
571 UAS_Pointer<UAS_Common> doc_ptr = UAS_Common::create (target);
573 UAS_String temp_str = doc_ptr->lid();
574 if (library_mgr().lib_exist(temp_str)) {
578 message_mgr().warning_dialog (
579 (char*)UAS_String(CATGETS(Set_Messages, 51,
580 "The document or section requested is not available.")));
584 // /////////////////////////////////////////////////////////////////
586 // /////////////////////////////////////////////////////////////////
589 SearchResultsAgent::retain_changed (WCallback *wcb)
591 XmToggleButtonCallbackStruct &tbcs =
592 *((XmToggleButtonCallbackStruct *) wcb->CallData());
597 f_retain_toggle->WObject::Set (WArgList (XmNselectPixmap,
598 window_system().locked_pixmap(wcb->GetWidget()),
600 window_system().semilocked_pixmap(wcb->GetWidget()),
603 f_retain_toggle->WObject::Set (WArgList (XmNselectPixmap,
604 window_system().semilocked_pixmap(wcb->GetWidget()),
606 window_system().unlocked_pixmap(wcb->GetWidget()),
610 // /////////////////////////////////////////////////////////////////
612 // /////////////////////////////////////////////////////////////////
615 SearchResultsAgent::close_window (WCallback *wcb)
617 if (f_popped_up == FALSE)
621 NodeListAgent::close_window (wcb);
622 search_results_mgr().deactivate (f_my_ale);
624 set_retain_default();
627 // /////////////////////////////////////////////////////////////////
628 // set_retain_default - set retain to default settings
629 // /////////////////////////////////////////////////////////////////
632 SearchResultsAgent::set_retain_default()
634 // NOTE: hardcoded for now, user preference later
637 f_retain_toggle->Set (False);
638 f_retain_toggle->WObject::Set (WArgList (XmNselectPixmap,
639 window_system().semilocked_pixmap(f_retain_toggle->Parent()),
641 window_system().unlocked_pixmap(f_retain_toggle->Parent()),
646 // /////////////////////////////////////////////////////////////////
648 // /////////////////////////////////////////////////////////////////
651 SearchResultsAgent::modify_verify (WCallback *wcb)
653 if (g_allow_query_text_change)
656 XmTextVerifyPtr tvp = (XmTextVerifyPtr) wcb->CallData();
658 // Editing never allowed.
661 message_mgr().warning_dialog (
662 (char*)UAS_String(CATGETS(Set_Messages, 47,
663 "This is a display-only field.")));