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 /* Copyright (c) 1994,1995,1996 FUJITSU LIMITED */
24 /* All Rights Reserved */
27 * $TOG: SearchResultsAgentMotif.C /main/17 1998/04/17 11:35:18 mgreess $
29 * Copyright (c) 1991 HaL Computer Systems, Inc. All rights reserved.
30 * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
31 * States. Use of a copyright notice is precautionary only and does not
32 * imply publication or disclosure.
34 * This software contains confidential information and trade secrets of HaL
35 * Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
36 * wihtout the prior express written permission of HaL Computer Systems, Inc.
38 * RESTRICTED RIGHTS LEGEND
39 * Use, duplication, or disclosure by the Government is subject to
40 * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
41 * Technical Data and Computer Software clause at DFARS 252.227-7013.
42 * HaL Computer Systems, Inc.
43 * 1315 Dell Avenue, Campbell, CA 95008
59 #define C_SearchResultsMgr
65 #define C_SearchResultsAgent
66 #define C_NodeListAgent
70 #define USES_OLIAS_FONT
72 #include "Other/XmStringLocalized.hh"
73 #include "Managers/CatMgr.hh"
74 #include "Managers/WString.hh"
80 #include "Registration.hh"
82 #include <WWL/WXmList.h>
83 #include <WWL/WXmForm.h>
84 #include <WWL/WXmLabel.h>
85 #include <WWL/WXmText.h>
86 #include <WWL/WXmToggleButton.h>
87 #include <WWL/WXmPushButton.h>
88 #include <WWL/WXmPanedWindow.h>
96 static Boolean g_allow_query_text_change;
98 #define INITIAL_FILL_SIZE 1000
99 #define INCREMENTAL_FILL_SIZE 100
102 // /////////////////////////////////////////////////////////////////
104 // /////////////////////////////////////////////////////////////////
107 SearchResultsAgent::init()
109 NodeListAgent::init();
113 // /////////////////////////////////////////////////////////////////
114 // form_result_string
115 // /////////////////////////////////////////////////////////////////
117 // Hard Coded pixel offset (from left margin) where Node Title Starts in
118 // result list - 14:36 07/26/93 - jbm
119 #define SECTION_OFFSET 150
122 SearchResultsAgent::form_result_string (UAS_Pointer<UAS_SearchResultsEntry> re)
124 static char relevancy[3];
125 if (relevancy[1] == '\0')
127 if (window_system().nofonts())
130 relevancy[1] = OLIAS_SPACE08;
133 // Scale all weights from to the range 0 to 8. While 8 / scale
134 // may look like a constant, it cannot be factored because integer
135 // arithmetic rounding might adversely affect the results. DJB
136 relevancy[0] = OLIAS_RELEVANCY_ICON;
138 relevancy[0] += (char) ((re->relevance() * 8 ) / f_scale);
141 WXmString rel (relevancy, (char*)OLIAS_FONT);
148 book = (char *) re->book();
149 name = (char *) re->section();
153 // backward compatibility
155 UAS_Pointer<UAS_Common> doc_ptr = UAS_Common::create (re->id());
156 UAS_String bn = doc_ptr->book_name (UAS_SHORT_TITLE);
157 UAS_String tt = doc_ptr->title();
162 int section_offset = f_list->Width() / 3;
164 int allowance = section_offset - book.Width(f_list->FontList());
167 // NOTE: space is hardcoded and will cause problems if font changes
168 // -10:24 07/12/93 - jbm
169 XmString xmstr = window_system().make_space(allowance, *f_list);
175 char* dots = (char*)"...";
177 WXmString temp_xmstring = book + WXmString(dots);
178 char *temp_str = (char*)temp_xmstring;
180 WString temp_WString(temp_str);
181 wchar_t* buf = (wchar_t*) temp_WString;
182 wchar_t* ptr = buf + wcslen(buf) - (strlen(dots)+1);
189 memcpy(ptr--, (wchar_t*)wdots, (strlen(dots)+1) * sizeof(wchar_t));
191 stake = str = WString(buf).get_mbstr();
193 allowance = section_offset - stake.Width(f_list->FontList());
197 while (allowance <= 0 && ptr >= buf);
200 while (*ptr <= (wchar_t)' ' && ptr >= buf)
203 memcpy(ptr--, (wchar_t*)wdots, (strlen(dots)+1) * sizeof(wchar_t));
205 stake = str = WString(buf).get_mbstr();
206 allowance = section_offset - stake.Width(f_list->FontList());
212 XmString xmstr = window_system().make_space(allowance, *f_list);
219 // Entire string must be disowned to prevent destructor of temporary
220 // object from freeing its XmString.
222 XmString string = (rel + book + space + name).disown();
228 // /////////////////////////////////////////////////////////////////
230 // /////////////////////////////////////////////////////////////////
235 return x < y ? x : y ;
239 SearchResultsAgent::resizeCB(Widget, XtPointer client_data, XEvent*, Boolean*)
241 SearchResultsAgent* agent = (SearchResultsAgent*)client_data;
247 SearchResultsAgent::compose_header()
250 (WXmLabel*)XtNameToWidget((Widget)*f_list_form, "header");
252 WXmString bookString = CATGETS(Set_AgentLabel, 184, "Book");
253 WXmString sectString = CATGETS(Set_AgentLabel, 185, "Section");
255 WXmString bookPostfix(
256 window_system().make_space(
257 f_list->Width() / 3 - bookString.Width(header->FontList()),
262 WXmString header_string = bookString + bookPostfix + sectString;
264 header->LabelString((XmString)header_string);
268 SearchResultsAgent::resize()
270 UAS_List<UAS_SearchResultsEntry>& rlist =
271 *(f_results->results()->create_results(0, f_count));
279 SearchResultsAgent::display (ResultID *results)
286 UAS_SearchEngine &se = search_mgr().search_engine();
288 // get window up quick
290 f_docs_to_display = imin(results->ndocs(), pref_mgr().get_int(PrefMgr::MaxSearchHits));
293 if (INITIAL_FILL_SIZE < f_docs_to_display)
294 f_count = INITIAL_FILL_SIZE;
296 f_count = f_docs_to_display ;
298 // INITIAL_FILL_SIZE(1000) is greater than the maximum of preference
299 // so, f_docs_to_display never exceeds INITIAL_FILL_SIZE
300 f_count = f_docs_to_display;
303 UAS_Pointer<UAS_List<UAS_SearchResultsEntry> > tmpList =
304 results->results()->create_results(0, f_count);
305 UAS_List<UAS_SearchResultsEntry>& rlist =
306 *(UAS_List<UAS_SearchResultsEntry> *)tmpList;
308 // All entries scaled by the weight of the first because it is
309 // be the max weight for the list.
310 assert( rlist[0] != 0);
311 f_scale = rlist[0]->relevance ();
313 // NOTE: Using bogus internal string below:
315 message_mgr().warning_dialog (
316 (char*)UAS_String(CATGETS(Set_Messages, 69,
317 "Search results weighting are not available.")));
319 /* -------- Display the number of hits. -------- */
322 sprintf (buffer, "%d of %d sections",
323 f_docs_to_display, results->ndocs());
324 f_hits_label->LabelString (buffer);
325 sprintf (buffer, "%s",
326 (char *)*(UAS_String*)(results->results()->scope_name()));
327 f_scope_label->LabelString (buffer);
329 /* -------- Display the text of the query. -------- */
330 g_allow_query_text_change = True;
332 f_query_text->Value ((char*)*(UAS_String*)(results->results()->query()));
334 g_allow_query_text_change = False;
337 NodeListAgent::display();
342 if (pref_mgr().get_boolean (PrefMgr::DisplayFirstHit))
344 f_list->SelectPos (1, True);
348 f_list->DeselectAllItems();
349 f_display.SetSensitive (False);
352 XtAddEventHandler((Widget)*f_list_form, StructureNotifyMask, False,
353 resizeCB, (XtPointer)this);
357 // /////////////////////////////////////////////////////////////////
359 // /////////////////////////////////////////////////////////////////
362 SearchResultsAgent::fill_list_wp (XtPointer /*client_data*/)
365 return ((SearchResultsAgent *) client_data)->fill_list();
372 // /////////////////////////////////////////////////////////////////
374 // /////////////////////////////////////////////////////////////////
377 SearchResultsAgent::fill_list(UAS_List<UAS_SearchResultsEntry>& rlist)
379 static XmString string_table[INITIAL_FILL_SIZE];
380 XmString *t = string_table;
382 int string_count = 0 ;
384 for (i = 0; i < rlist.length(); i ++) {
386 *t++ = form_result_string (rlist[i]);
390 f_list->Set (WArgList (XmNitems, (XtArgVal) string_table,
391 XmNitemCount, f_count,
394 for (i = 0 ; i < string_count; i++) {
395 XmStringFree(string_table[i]);
396 string_table[i] = NULL;
400 static XmString string_table [INCREMENTAL_FILL_SIZE];
401 XmString *t = string_table;
403 int number, num_remaining = f_docs_to_display - f_count;
405 if (INCREMENTAL_FILL_SIZE < num_remaining)
406 number = INCREMENTAL_FILL_SIZE;
408 number = num_remaining;
410 UAS_Pointer<UAS_List<UAS_SearchResultsEntry> > tmpList =
411 f_results->results()->create_results(f_count, number);
412 UAS_List<UAS_SearchResultsEntry> & rlist =
413 *(UAS_List<UAS_SearchResultsEntry>*)tmpList;
416 for (i = 0; i < rlist.length(); i ++) {
417 *t++ = form_result_string (rlist[i]);
419 // 0 means add at last position in the list.
420 XmListAddItems (*f_list, (XmString *) string_table, number, 0);
424 for (i = 0 ; i < number; i++)
425 XmStringFree ((XmString) string_table[i]);
427 // Return True if the list is complete, False otherwise.
428 if (f_count == f_docs_to_display)
430 f_work_proc_id = NULL;
443 // /////////////////////////////////////////////////////////////////
445 // /////////////////////////////////////////////////////////////////
448 SearchResultsAgent::create_window()
450 create_base_window ((char*)"results");
452 XmStringLocalized mtfstring;
455 string = CATGETS(Set_SearchResultsAgent, 1, "Dtinfo: Search Results");
456 XtVaSetValues((Widget)*f_shell, XmNtitle, string, NULL);
458 help_agent().add_activate_help(f_help, (char*)"results_help");
460 #define AM WAutoManage
461 // NOTE: need form to contain things in the same row 'cause of resizing
465 new WXmToggleButton (*f_form, "retain", AM,
466 WArgList (XmNlabelPixmap,
467 (XtArgVal)window_system().unlocked_pixmap(*f_form),
469 window_system().semilocked_pixmap(*f_form),
472 f_retain_toggle = new WXmToggleButton (*f_form, "retain", AM);
474 WXmLabel retrieved (*f_form, "retrieved", AM);
475 f_hits_label = (WXmLabel*)(Widget) WXmLabel (*f_form, "num_hits", AM);
476 WXmLabel scope (*f_form, "scope", AM);
477 f_scope_label = (WXmLabel*)(Widget) WXmLabel (*f_form, "scope_name", AM);
478 WXmLabel query_label (*f_form, "query_label", AM);
480 mtfstring = CATGETS(Set_AgentLabel, 219, "Retrieved:");
481 XtVaSetValues(retrieved, XmNlabelString, (XmString)mtfstring, NULL);
482 mtfstring = CATGETS(Set_AgentLabel, 194, "File a Bug");
483 XtVaSetValues((Widget)f_hits_label, XmNlabelString, (XmString)mtfstring, NULL);
484 mtfstring = CATGETS(Set_AgentLabel, 220, "Scope:");
485 XtVaSetValues(scope, XmNlabelString, (XmString)mtfstring, NULL);
486 mtfstring = CATGETS(Set_AgentLabel, 194, "File a Bug");
487 XtVaSetValues((Widget)f_scope_label, XmNlabelString, (XmString)mtfstring, NULL);
488 mtfstring = CATGETS(Set_AgentLabel, 221, "Query:");
489 XtVaSetValues(query_label, XmNlabelString, (XmString)mtfstring, NULL);
491 Widget textw = XmCreateScrolledText (*f_pane, (char*)"query_text", NULL, 0);
492 f_query_text = new WXmText (textw);
493 f_query_text->Manage();
494 // WXmPushButton editq (*f_panel, "edit_query", AM);
496 f_retain_toggle->SetValueChangedCallback
497 (this, (WWL_FUN) &SearchResultsAgent::retain_changed);
498 set_retain_default();
501 CXmForm pane (*f_pane);
504 pane.TopWidget (query_label, args);
505 pane.TopAttachment (XmATTACH_WIDGET, args);
506 pane.Set (args.Args(), args.NumArgs());
509 static char relevancy[3];
510 if (relevancy[0] == '\0')
512 relevancy[0] = OLIAS_RELEVANCY_ICON;
513 if (window_system().nofonts())
516 relevancy[1] = OLIAS_SPACE08;
519 // set up column labels (Book, Section)
520 WXmLabel header (*f_list_form, "header", AM);
522 { // header needs dtinfo space font
523 XmFontList header_font = XmFontListCopy(header.FontList());
525 if (window_system().dtinfo_space_font())
526 header_font = XmFontListAppendEntry(header_font,
527 window_system().dtinfo_space_font());
529 header.FontList(header_font);
532 int offset = WXmString(relevancy,(char*)OLIAS_FONT).Width(f_list->FontList());
533 header.LeftOffset(offset);
535 WXmPrimitive prim(XtParent(*f_list));
536 prim.TopWidget(header);
537 prim.TopAttachment(XmATTACH_WIDGET);
542 f_list->SetSingleSelectionCallback (this,
543 (WWL_FUN) &SearchResultsAgent::select_item);
544 f_list->SetBrowseSelectionCallback (this,
545 (WWL_FUN) &SearchResultsAgent::select_item);
546 f_list->SetDefaultActionCallback (this,
547 (WWL_FUN) &SearchResultsAgent::view_activate);
548 f_display.SetActivateCallback (this,
549 (WWL_FUN) &SearchResultsAgent::view_activate);
550 f_query_text->SetModifyVerifyCallback (this,
551 (WWL_FUN) &SearchResultsAgent::modify_verify);
553 XmProcessTraversal (f_display, XmTRAVERSE_CURRENT);
557 // /////////////////////////////////////////////////////////////////
559 // /////////////////////////////////////////////////////////////////
561 // NOTE: perhaps this should be in the base class?? 6/12/92 djb
564 SearchResultsAgent::select_item (WCallback *wcb)
566 XmListCallbackStruct *lcs = (XmListCallbackStruct *) wcb->CallData();
568 f_selected_item = lcs->item_position - 1;
570 ON_DEBUG (printf ("Selected item #%d\n", f_selected_item);)
572 f_display.SetSensitive (True);
576 // /////////////////////////////////////////////////////////////////
578 // /////////////////////////////////////////////////////////////////
581 SearchResultsAgent::view_activate (WCallback *)
583 if (f_list->SelectedItemCount() != 1)
590 UAS_List<UAS_SearchResultsEntry> & rlist = f_results->results()->results();
592 search_mgr().current_hits (rlist[f_selected_item]->create_matches());
593 target = rlist[f_selected_item]->id();
595 UAS_Pointer<UAS_Common> doc_ptr = UAS_Common::create (target);
597 UAS_String temp_str = doc_ptr->lid();
598 if (library_mgr().lib_exist(temp_str)) {
602 message_mgr().warning_dialog (
603 (char*)UAS_String(CATGETS(Set_Messages, 51,
604 "The document or section requested is not available.")));
608 // /////////////////////////////////////////////////////////////////
610 // /////////////////////////////////////////////////////////////////
613 SearchResultsAgent::retain_changed (WCallback *wcb)
615 XmToggleButtonCallbackStruct &tbcs =
616 *((XmToggleButtonCallbackStruct *) wcb->CallData());
621 f_retain_toggle->WObject::Set (WArgList (XmNselectPixmap,
622 window_system().locked_pixmap(wcb->GetWidget()),
624 window_system().semilocked_pixmap(wcb->GetWidget()),
627 f_retain_toggle->WObject::Set (WArgList (XmNselectPixmap,
628 window_system().semilocked_pixmap(wcb->GetWidget()),
630 window_system().unlocked_pixmap(wcb->GetWidget()),
634 // /////////////////////////////////////////////////////////////////
636 // /////////////////////////////////////////////////////////////////
639 SearchResultsAgent::close_window (WCallback *wcb)
641 if (f_popped_up == FALSE)
645 NodeListAgent::close_window (wcb);
646 search_results_mgr().deactivate (f_my_ale);
648 set_retain_default();
651 // /////////////////////////////////////////////////////////////////
652 // set_retain_default - set retain to default settings
653 // /////////////////////////////////////////////////////////////////
656 SearchResultsAgent::set_retain_default()
658 // NOTE: hardcoded for now, user preference later
661 f_retain_toggle->Set (False);
662 f_retain_toggle->WObject::Set (WArgList (XmNselectPixmap,
663 window_system().semilocked_pixmap(f_retain_toggle->Parent()),
665 window_system().unlocked_pixmap(f_retain_toggle->Parent()),
670 // /////////////////////////////////////////////////////////////////
672 // /////////////////////////////////////////////////////////////////
675 SearchResultsAgent::modify_verify (WCallback *wcb)
677 if (g_allow_query_text_change)
680 XmTextVerifyPtr tvp = (XmTextVerifyPtr) wcb->CallData();
682 // Editing never allowed.
685 message_mgr().warning_dialog (
686 (char*)UAS_String(CATGETS(Set_Messages, 47,
687 "This is a display-only field.")));