Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / Managers / SearchMgr.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*      Copyright (c) 1994,1995,1996 FUJITSU LIMITED            */
24 /*      All Rights Reserved                                     */
25
26 /*
27  * $TOG: SearchMgr.C /main/17 1998/04/17 11:37:13 mgreess $
28  *
29  * Copyright (c) 1992 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.
33  * 
34  * This software contains confidential information and trade secrets of HaL
35  * Computer Systems, Inc.  Use, disclosure, or reproduction is prohibited
36  * without the prior express written permission of HaL Computer Systems, Inc.
37  * 
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
44  * 
45  */
46
47 #include <stream.h>
48
49 #include "Registration.hh"
50
51 #include "UAS.hh"
52
53 #define C_ResultID
54 #define L_OliasSearch
55
56 #define C_WindowSystem
57 #define L_Other
58
59 #define C_QueryEditor
60 #define L_Query
61
62 #define C_xList
63 #define L_Support
64
65 #define C_SearchHistoryListView
66 #define L_Agents
67
68 #define C_MessageMgr
69 #define C_SearchResultsMgr
70 #define C_SearchMgr
71 #define C_SearchScopeMgr
72 #define C_PrefMgr
73 #define L_Managers
74
75 #include <Prelude.h>
76
77 #include "Managers/CatMgr.hh"
78
79 #include <stream.h>
80
81 LONG_LIVED_CC(SearchMgr,search_mgr)
82
83 // Reconfigure search engine
84 class SeReconfigure : public UAS_Receiver<UAS_CollectionRetrievedMsg >,
85                       public UAS_Receiver<UAS_LibraryDestroyedMsg>
86 {
87 public:
88   SeReconfigure();
89
90 private:
91   void receive (UAS_CollectionRetrievedMsg &message, void *client_data);
92   void receive (UAS_LibraryDestroyedMsg &message, void *client_data);
93 };
94
95 SeReconfigure::SeReconfigure()
96 {
97   UAS_Collection::request((UAS_Receiver<UAS_CollectionRetrievedMsg> *)
98                         this);
99   UAS_Common::request ((UAS_Receiver<UAS_LibraryDestroyedMsg> *)this);
100 }
101
102 // infolib was added to system, need to reinit search engine
103 void
104 SeReconfigure::receive (UAS_CollectionRetrievedMsg &message, void *client_data)
105 {
106   ON_DEBUG (printf ("Received UAS_CollectionRetrievedMsg message!\n"));
107   UAS_Pointer<UAS_Common> root(message.fCol->root());
108   search_mgr().add_root(root);
109 }
110
111 // infolib was removed from system, need to reinit search engine
112 void
113 SeReconfigure::receive (UAS_LibraryDestroyedMsg &message, void *client_data)
114 {
115   ON_DEBUG (printf ("Received UAS_LibraryDestroyedMsg message!\n"));
116   search_mgr().remove_root(message.fLib);
117 }
118
119 static SeReconfigure se_reconfigure;
120
121
122
123 // /////////////////////////////////////////////////////////////////
124 // class constructor
125 // /////////////////////////////////////////////////////////////////
126
127 SearchMgr::SearchMgr()
128 : f_search_engine(NULL),
129   f_query_editor (NULL),
130   f_search_history_list (pref_mgr().get_int (PrefMgr::SearchHistSize)),
131   f_search_history_list_view (NULL),
132   f_search_section ("")
133 {
134   init();
135 }
136
137 // /////////////////////////////////////////////////////////////////
138 // init
139 // /////////////////////////////////////////////////////////////////
140
141 void
142 SearchMgr::init()
143 {
144     UAS_List<UAS_String> rootLocs = UAS_Common::rootLocators ();
145
146     int i;
147     for (i = 0; i < rootLocs.length(); i ++) {
148         UAS_Pointer<UAS_Common> theDoc =
149                                 UAS_Common::create(*(UAS_String*)rootLocs[i]);
150         UAS_Pointer<UAS_Collection> theCol = (UAS_Collection *)
151                 ((UAS_Common *) theDoc);
152         theDoc = theCol->root();
153         f_roots.insert_item (theDoc);
154     }
155
156   setInitialized();
157   setStatus (eSuccess);
158 }
159
160 SearchMgr::~SearchMgr()
161 {
162     while (f_search_history_list.length () > 0)
163         f_search_history_list.remove_first();
164 }
165
166 UAS_SearchEngine &
167 SearchMgr::search_engine () {
168     if (f_search_engine == 0) {
169         if (f_roots.length() > 0)
170             f_search_engine = f_roots[0]->search_engine();
171         else
172             throw (CASTEXCEPT Exception());
173     }
174     return *(UAS_SearchEngine*)f_search_engine;
175 }
176
177
178 // /////////////////////////////////////////////////////////////////
179 // history_entry_activate - user says display something from hist
180 // /////////////////////////////////////////////////////////////////
181
182 void
183 SearchMgr::history_entry_activate (FolioObject *, u_int,
184                                    void *notify_data, void *)
185 {
186   Wait_Cursor bob;
187   u_int which_item = (int) notify_data;
188
189   ResultID *rid = (ResultID *) f_search_history_list[which_item];
190
191   // Fix for DTS 8327. 
192   if (rid->ndocs() > 0)
193     search_results_mgr().display (rid);
194   else
195     display_message (NO_HITS);
196 }
197
198
199 // /////////////////////////////////////////////////////////////////
200 // search_history_list_view
201 // /////////////////////////////////////////////////////////////////
202
203 ListView &
204 SearchMgr::search_history_list_view()
205 {
206   if (f_search_history_list_view == NULL)
207     {
208       f_search_history_list_view =
209         new SearchHistoryListView (&f_search_history_list, "search_history");
210       f_search_history_list_view->AddDependent
211         ((notify_handler_t) &SearchMgr::history_entry_activate,
212          ListView::ENTRY_ACTIVATE);
213     }
214
215   return (*f_search_history_list_view);
216 }
217
218 // /////////////////////////////////////////////////////////////////
219 // display_editor
220 // /////////////////////////////////////////////////////////////////
221
222 void
223 SearchMgr::display_editor()
224 {
225   if (f_query_editor == NULL)
226     f_query_editor = new QueryEditor(search_engine());
227
228   f_query_editor->display();
229 }
230
231 // /////////////////////////////////////////////////////////////////
232 // search - invoke search engine on raw query and display results
233 // /////////////////////////////////////////////////////////////////
234
235 void
236 SearchMgr::parse_and_search (char *query, UAS_SearchScope *scope) {
237 //
238 //  SWM -- code lifted from old SearchQuery object. If no scope
239 //  is passed, pass "current section" if f_search_section is set,
240 //  otherwise, pass "information library"
241 //
242     if (scope == NULL) {
243        xList<UAS_SearchScope *> &scope_list = search_scope_mgr().scope_list();
244        List_Iterator<UAS_SearchScope *> s (scope_list);
245        if (!f_search_section.length())
246             s ++;
247        scope = s.item();
248     }
249
250   // Hand off to search engine.
251   UAS_Pointer<UAS_SearchResults> tmp_results;
252   ResultID *search_results = 0;
253   if (f_search_section.length()) {
254     scope->search_zones().section ((char*)f_search_section);
255   }
256   try
257   {
258       tmp_results = search_engine().search (query, *scope);
259   }
260   catch (UAS_Exception&, e)
261   {
262       message_mgr().error_dialog ((char*)e->message());
263       return;
264   }
265   catch_any ()
266   {
267
268   }
269   end_try;
270
271   if (tmp_results == 0) {
272     display_message(BAD_QUERY);
273   } else {
274
275     if (tmp_results->num_docs() > 0) {
276         search_results = new ResultID (tmp_results);
277         f_search_history_list.append (*search_results);
278
279         if (!f_search_section.length()) {
280           search_results_mgr().display (search_results);
281         }
282
283         if (f_search_section.length() ||
284             pref_mgr().get_boolean (PrefMgr::DisplayFirstHit))
285           {
286             UAS_Pointer<UAS_List<UAS_SearchResultsEntry> > tmpPtr =
287               tmp_results->create_results(0, 1);
288
289             UAS_List<UAS_SearchResultsEntry> * tmpTmpPtr =
290                  (UAS_List<UAS_SearchResultsEntry>*)tmpPtr;
291
292             UAS_List<UAS_SearchResultsEntry> tmp3Ptr =
293                  *tmpTmpPtr;
294
295             UAS_Pointer<UAS_SearchResultsEntry> tmp4Ptr =  tmp3Ptr[0];
296
297             f_current_hits = tmp4Ptr->create_matches(); 
298             UAS_String target = tmp4Ptr->id();  
299             UAS_Pointer<UAS_Common> doc_ptr = UAS_Common::create (target);
300             doc_ptr->retrieve();
301           }
302     } else if (tmp_results->num_docs() == 0) {
303         display_message(NO_HITS);
304     }
305   } 
306 }
307
308 void
309 SearchMgr::display_message (SearchMessageType msg, int)
310 {
311   char *msg_str;
312
313   switch( msg ){
314   case NO_HITS:
315     message_mgr().info_dialog (
316         (char*)UAS_String(CATGETS(Set_Messages, 40, "File a Bug")));
317     break;
318   case BAD_QUERY:
319     message_mgr().warning_dialog (
320         (char*)UAS_String(CATGETS(Set_Messages, 41, "File a Bug")));
321     break;
322   }
323 }
324
325 UAS_Pointer<UAS_List<UAS_TextRun> >
326 SearchMgr::current_hits()
327 {
328   UAS_Pointer<UAS_List<UAS_TextRun> > rval = NULL;
329   if (f_search_section) {
330     rval = f_current_hits;
331     f_current_hits = NULL; // f_current_hits is volatile
332   }
333   return rval;
334 }
335
336 void
337 SearchMgr::add_root(UAS_Pointer<UAS_Common>& root)
338 {
339     int i;
340     for (i = 0; i < f_roots.length(); i++) {
341         if (f_roots[i] == root)
342             break;
343     }
344     if (i < f_roots.length())
345         return;
346
347     f_roots.insert_item(root);
348
349     f_search_engine = NULL;
350 }
351
352 void
353 SearchMgr::remove_root(UAS_Pointer<UAS_Common>& root)
354 {
355     int i;
356     for (i = 0; i < f_roots.length(); i++) {
357         if (f_roots[i] == root)
358             break;
359     }
360     if (i == f_roots.length())
361         return;
362     
363     f_roots.remove_item(i);
364
365     f_search_engine = NULL;
366 }
367