source: branches/z3950-branch/gsdl/src/recpt/browsetools.cpp@ 1342

Last change on this file since 1342 was 1342, checked in by johnmcp, 24 years ago

Relatively stable z39.50 implementation now, merged with the mgpp source.
(Still needs a decent interface and query language though...)

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 18.9 KB
Line 
1
2/**********************************************************************
3 *
4 * browsetools.cpp --
5 * Copyright (C) 1999 The New Zealand Digital Library Project
6 *
7 * A component of the Greenstone digital library software
8 * from the New Zealand Digital Library Project at the
9 * University of Waikato, New Zealand.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *********************************************************************/
26
27#include "browsetools.h"
28#include "OIDtools.h"
29
30
31// output_controls displays the detach, expand/contract contents,
32// expand/contract text and highlighting/no highlighting buttons
33
34void output_controls (cgiargsclass &args, const text_tarray &ibuttons,
35 recptproto * /*collectproto*/, displayclass &disp,
36 outconvertclass &outconvert, ostream &textout,
37 ostream &/*logout*/) {
38
39 if (args["u"] != "1") {
40
41 FilterResponse_t response;
42 text_tarray metadata;
43 text_tarray buttons;
44
45 text_tarray::const_iterator here = ibuttons.begin();
46 text_tarray::const_iterator end = ibuttons.end();
47
48 while (here != end) {
49
50 if (*here == "Detach")
51 buttons.push_back ("_document:imagedetach_");
52 else if (*here == "Highlight") {
53 if (args["hl"] == "1")
54 buttons.push_back ("_document:imagenohighlight_");
55 else
56 buttons.push_back ("_document:imagehighlight_");
57 } else if (*here == "Expand Contents") {
58 if (args["gc"] == "1")
59 buttons.push_back ("_document:imagecontracttoc_");
60 else
61 buttons.push_back ("_document:imageexpandtoc_");
62 } else if (*here == "Expand Text") {
63 if (args.getintarg("gt"))
64 buttons.push_back ("_document:imagecontracttext_");
65 else
66 buttons.push_back ("_document:imageexpandtext_");
67 }
68 here ++;
69 }
70
71 here = buttons.begin();
72 end = buttons.end();
73 int count = 0;
74 while (here != end) {
75 if ((count != 0) && ((count % 2) == 0)) textout << "<br>\n";
76 textout << outconvert << disp << *here;
77 count ++;
78 here ++;
79 }
80 }
81}
82
83
84// at the moment this just writes out the html to display
85// the cover image (assuming it's called cover.jpg)
86// this whole thing should be done with a call to the collection
87// server which would send a link to the cover image if there
88// was one otherwise send title, author and stuff
89void output_cover_image (cgiargsclass &args, recptproto * /*collectproto*/,
90 displayclass &disp, outconvertclass &outconvert,
91 ostream &textout, ostream &/*logout*/) {
92
93 if (args["d"].empty()) return;
94
95 textout << outconvert << disp <<
96 "<img src=\"_httpcollimg_/_thisOID_/cover.jpg\"><br>\n";
97}
98
99void output_titles (cgiargsclass &args, recptproto *collectproto,
100 formatinfo_t &formatinfo, displayclass &disp,
101 outconvertclass &outconvert, ostream &textout,
102 ostream &logout) {
103
104 if (args["d"].empty()) return;
105
106 text_tset metadata;
107 bool getParents;
108 FilterResponse_t response;
109
110 format_t *formatlistptr = new format_t();
111 parse_formatstring (formatinfo.DocumentHeading, formatlistptr, metadata, getParents);
112
113 if (!get_info (args["d"], args["c"], metadata, getParents, collectproto, response, logout))
114 return;
115
116 textout << outconvert << disp << get_formatted_string (response.docInfo[0], formatlistptr);
117}
118
119
120static void recurse_contents (ResultDocInfo_t &section, cgiargsclass &args, bool fulltoc,
121 browserclass *bptr, text_tset &metadata, bool &getParents,
122 format_t *formatlistptr, format_tmap &formatlistmap,
123 formatinfo_t &formatinfo, browsermapclass *browsermap,
124 int tabcount, recptproto *collectproto, displayclass &disp,
125 outconvertclass &outconvert, ostream &textout, ostream &logout) {
126 text_t formatstring;
127
128 bool is_classify = false;
129 if (args["d"].empty() || fulltoc) is_classify = true;
130
131 // output this section
132 bool use_table = is_table_content (formatlistptr);
133 tabcount += bptr->output_section_group (section, args, "", tabcount, formatlistptr, use_table,
134 metadata, getParents, collectproto, disp, outconvert,
135 textout, logout);
136
137 text_t classification;
138 if (!is_classify) classification = "Document";
139 else get_top (args["cl"], classification);
140
141 int haschildren = section.metadata["haschildren"].values[0].getint();
142 const text_t &doctype = section.metadata["doctype"].values[0];
143 text_t classifytype = section.metadata["childtype"].values[0];
144 // HLists and DateLists are displayed as VLists when contents
145 // are expanded, Paged documents are displayed as HLists
146 if (classifytype == "HList" || classifytype == "DateList") classifytype = "VList";
147 if (classifytype == "Paged") classifytype = "HList";
148
149 // recurse through children
150 if ((haschildren == 1) && (!is_classify || fulltoc || doctype == "classify")) {
151
152 // get browser for displaying children
153 bptr = browsermap->getbrowser (classifytype);
154 bptr->load_metadata_defaults (metadata);
155
156 // get the formatstring if there is one
157 if (!get_formatstring (classification, classifytype,
158 formatinfo.formatstrings, formatstring))
159 formatstring = bptr->get_default_formatstring();
160
161 format_tmap::const_iterator it = formatlistmap.find (formatstring);
162 // check if formatlistptr is cached
163 if (it != formatlistmap.end()) formatlistptr = (*it).second;
164 else {
165 formatlistptr = new format_t();
166 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
167 formatlistmap[formatstring] = formatlistptr;
168 }
169
170 FilterResponse_t tmp;
171 get_children (section.OID, args["c"], metadata, getParents, collectproto, tmp, logout);
172 ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
173 ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
174
175 while (thisdoc != lastdoc) {
176 recurse_contents (*thisdoc, args, fulltoc, bptr, metadata, getParents,
177 formatlistptr, formatlistmap, formatinfo, browsermap,
178 tabcount, collectproto, disp, outconvert, textout, logout);
179 thisdoc ++;
180 }
181 }
182}
183
184
185// expanded_contents recurses through all contents. there's a special case
186// for an HList when contents are expanded (i.e. it's displayed as a VList)
187//
188// if we're inside a document we expand all contents from the top,
189// if we're at classification level we'll just expand out those contents below
190// the current one
191
192void expanded_contents (cgiargsclass &args, int tabcount, bool fulltoc,
193 browsermapclass *browsermap, formatinfo_t &formatinfo,
194 recptproto *collectproto, displayclass &disp,
195 outconvertclass &outconvert, ostream &textout,
196 ostream &logout) {
197
198 if (args["d"].empty() && args["cl"].empty()) return;
199 text_t OID;
200
201 FilterResponse_t response;
202 bool getParents = false;
203 text_tset metadata;
204 text_t classifytype, classification, formatstring;
205
206 if (!args["d"].empty()) {
207 // document level
208 if (fulltoc) {
209 get_top (args["cl"], OID);
210 classification = OID;
211 }
212 else {
213 // always expand document level from top
214 get_top (args["d"], OID);
215 classification = "Document";
216 }
217 } else {
218 // classification level
219 OID = args["cl"];
220 get_top (args["cl"], classification);
221 }
222
223 // get classifytype of this level
224 text_t tOID;
225 if (is_top(OID)) {
226 classifytype = "thistype";
227 tOID = OID;
228 } else {
229 classifytype = "childtype";
230 tOID = get_parent (OID);
231 }
232 metadata.insert (classifytype);
233
234 if (!get_info (tOID, args["c"], metadata, getParents, collectproto, response, logout))
235 return;
236 classifytype = response.docInfo[0].metadata[classifytype].values[0];
237 // if we still don't have a classifytype we'll use the default
238 if (classifytype.empty()) {
239 browserclass *bptr = browsermap->get_default_browser ();
240 classifytype = bptr->get_browser_name ();
241 }
242
243 // HLists are displayed as VLists when contents are expanded,
244 // Paged documents are displayed as HLists
245 if (classifytype == "HList") {
246 classifytype = "VList";
247 text_t pOID = get_parent (OID);
248 if (!pOID.empty()) {
249 OID = pOID;
250 // this is assuming that top levels are always 'Invisible' !!!
251 if (is_top (OID)) classifytype = "Invisible";
252 }
253 }
254 if (classifytype == "Paged") classifytype = "HList";
255
256 metadata.erase (metadata.begin(), metadata.end());
257
258 // metadata elements needed by recurse_contents
259 metadata.insert ("childtype");
260 metadata.insert ("doctype");
261 metadata.insert ("haschildren");
262
263 // load up metadata array with browser defaults
264 browserclass *bptr = browsermap->getbrowser (classifytype);
265 bptr->load_metadata_defaults (metadata);
266
267 // get the formatstring if there is one or use the browsers default
268 if (!get_formatstring (classification, classifytype,
269 formatinfo.formatstrings, formatstring))
270 formatstring = bptr->get_default_formatstring();
271
272 format_t *formatlistptr = new format_t();
273 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
274
275 // protocol call
276 if (!get_info (OID, args["c"], metadata, getParents, collectproto, response, logout))
277 return;
278
279 format_tmap formatlistmap;
280 formatlistmap[formatstring] = formatlistptr;
281
282 recurse_contents (response.docInfo[0], args, fulltoc, bptr, metadata,
283 getParents, formatlistptr, formatlistmap, formatinfo, browsermap,
284 tabcount, collectproto, disp, outconvert, textout, logout);
285
286 // clean up format list pointers
287 format_tmap::const_iterator here = formatlistmap.begin();
288 format_tmap::const_iterator end = formatlistmap.end();
289 while (here != end) {
290 delete (*here).second;
291 here ++;
292 }
293}
294
295
296static void load_formatstring (const text_t &classifytype, text_tset &metadata,
297 bool &getParents, const text_t &classification,
298 browsermapclass *browsermap, formatinfo_t &formatinfo,
299 format_tmap &formatlistmap) {
300 text_t formatstring;
301
302 // load up metadata array with browser defaults
303 browserclass *bptr = browsermap->getbrowser (classifytype);
304 bptr->load_metadata_defaults (metadata);
305
306 // get the formatstring if there is one or use the browsers default
307 if (!get_formatstring (classification, classifytype,
308 formatinfo.formatstrings, formatstring))
309 formatstring = bptr->get_default_formatstring();
310
311 // see if it's cached
312 format_tmap::const_iterator it = formatlistmap.find (formatstring);
313 if (it == formatlistmap.end()) {
314 format_t *formatlistptr = new format_t();
315 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
316 formatlistmap[formatstring] = formatlistptr;
317 }
318}
319
320static void load_formatstrings (FilterResponse_t &response, text_tset &metadata,
321 bool &getParents, const text_t &classification,
322 browsermapclass *browsermap, formatinfo_t &formatinfo,
323 format_tmap &formatlistmap) {
324
325 text_tset cache;
326
327 ResultDocInfo_tarray::iterator thisdoc = response.docInfo.begin();
328 ResultDocInfo_tarray::iterator lastdoc = response.docInfo.end();
329
330 while (thisdoc != lastdoc) {
331
332 if (is_top ((*thisdoc).OID))
333 load_formatstring ((*thisdoc).metadata["thistype"].values[0], metadata,
334 getParents, classification, browsermap, formatinfo,
335 formatlistmap);
336
337 text_t &childtype = (*thisdoc).metadata["childtype"].values[0];
338 text_tset::const_iterator it = cache.find (childtype);
339 if (it == cache.end()) {
340 load_formatstring (childtype, metadata, getParents, classification,
341 browsermap, formatinfo, formatlistmap);
342 cache.insert (childtype);
343 }
344 thisdoc ++;
345 }
346}
347
348static void output_parents (FilterResponse_t &response, cgiargsclass &args,
349 browsermapclass *browsermap, formatinfo_t &formatinfo,
350 format_tmap &formatlistmap, const text_t &classification,
351 int &tabcount, text_tset &metadata, bool &getParents,
352 recptproto *collectproto, displayclass &disp,
353 outconvertclass &outconvert, ostream &textout,
354 ostream &logout) {
355
356 format_t *formatlistptr = NULL;
357 text_t classifytype, formatstring;
358 bool use_table, first = true;
359 ResultDocInfo_tarray::iterator thisparent = response.docInfo.begin();
360 ResultDocInfo_tarray::iterator lastparent = response.docInfo.end();
361 while (thisparent != lastparent) {
362
363 // get classifytype of this level
364 if (is_top ((*thisparent).OID)) classifytype = (*thisparent).metadata["thistype"].values[0];
365 else if (!first) classifytype = (*(thisparent-1)).metadata["childtype"].values[0];
366
367 // if we still don't have a classifytype we'll use the default
368 if (classifytype.empty()) {
369 browserclass *bptr = browsermap->get_default_browser ();
370 classifytype = bptr->get_browser_name ();
371 }
372
373 browserclass *bptr = browsermap->getbrowser (classifytype);
374
375 // get the formatstring if there is one or use the browsers default
376 if (!get_formatstring (classification, classifytype,
377 formatinfo.formatstrings, formatstring))
378 formatstring = bptr->get_default_formatstring();
379
380 // see if it's cached
381 format_tmap::const_iterator it = formatlistmap.find (formatstring);
382 if (it != formatlistmap.end()) formatlistptr = (*it).second;
383 else {
384 logout << "browsetools error\n";
385 return;
386 }
387
388 use_table = is_table_content (formatlistptr);
389 tabcount += bptr->output_section_group (*thisparent, args, "", tabcount, formatlistptr,
390 use_table, metadata, getParents, collectproto,
391 disp, outconvert, textout, logout);
392 first = false;
393 thisparent ++;
394 }
395}
396
397void contracted_contents (cgiargsclass &args, int tabcount, bool fulltoc,
398 browsermapclass *browsermap, formatinfo_t &formatinfo,
399 recptproto *collectproto, displayclass &disp,
400 outconvertclass &outconvert, ostream &textout,
401 ostream &logout) {
402
403 FilterResponse_t response;
404 text_tset metadata;
405 bool getParents = false;
406 text_t formatstring;
407 text_tarray parents;
408 text_t OID = args["d"];
409 text_t classification = "Document";
410 if (OID.empty()) {
411 OID = args["cl"];
412 get_top (OID, classification);
413 } else if (fulltoc)
414 get_top (args["cl"], classification);
415
416 bool haschildren = has_children (OID, args["c"], collectproto, logout);
417
418 if ((!args["d"].empty()) && fulltoc)
419 get_parents_array (args["cl"] + ".fc", parents);
420 if (haschildren) get_parents_array (OID + ".fc", parents);
421 else get_parents_array (OID, parents);
422
423 if (!parents.empty()) {
424 // get classifytypes of each parent
425 metadata.insert ("thistype");
426 metadata.insert ("childtype");
427
428 if (!get_info (parents, args["c"], metadata, getParents, collectproto, response, logout))
429 return;
430
431 // get formatstrings for all parents
432 format_tmap formatlistmap;
433 load_formatstrings (response, metadata, getParents, classification,
434 browsermap, formatinfo, formatlistmap);
435
436 if (!get_info (parents, args["c"], metadata, getParents, collectproto, response, logout))
437 return;
438
439 // display each parent
440 output_parents (response, args, browsermap, formatinfo, formatlistmap,
441 classification, tabcount, metadata, getParents,
442 collectproto, disp, outconvert, textout, logout);
443
444 metadata.erase (metadata.begin(), metadata.end());
445
446 // clean up cached format list pointers
447 format_tmap::const_iterator here = formatlistmap.begin();
448 format_tmap::const_iterator end = formatlistmap.end();
449 while (here != end) {
450 delete (*here).second;
451 here ++;
452 }
453 }
454
455 // get childrens classifytype
456 text_t classifytype;
457 int numparents = response.docInfo.size();
458 if (!parents.empty())
459 classifytype = response.docInfo[numparents-1].metadata["childtype"].values[0];
460 else {
461 // use the default
462 browserclass *bptr = browsermap->get_default_browser ();
463 classifytype = bptr->get_browser_name ();
464 }
465
466 // load up metadata array with browser defaults
467 browserclass *bptr = browsermap->getbrowser (classifytype);
468 bptr->load_metadata_defaults (metadata);
469
470 // get the formatstring if there is one or use the browsers default
471 if (!get_formatstring (classification, classifytype,
472 formatinfo.formatstrings, formatstring))
473 formatstring = bptr->get_default_formatstring();
474
475 format_t *formatlistptr = new format_t();
476 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
477
478 if (haschildren)
479 get_children (OID, args["c"], metadata, getParents,
480 collectproto, response, logout);
481 else if (!is_top(OID)) {
482 get_children (OID + ".pr", args["c"], metadata, getParents,
483 collectproto, response, logout);
484 haschildren = true;
485 }
486
487 // display children
488 if (haschildren) {
489 bool use_table = is_table_content (formatlistptr);
490 bptr->output_section_group (response, args, "", tabcount, formatlistptr, use_table,
491 metadata, getParents, collectproto, disp, outconvert,
492 textout, logout);
493 }
494
495 delete formatlistptr;
496}
497
498void output_toc (cgiargsclass &args, browsermapclass *browsermap,
499 formatinfo_t &formatinfo, recptproto *collectproto,
500 displayclass &disp, outconvertclass &outconvert,
501 ostream &textout, ostream &logout) {
502
503 int tabcount = 0;
504 bool havecontrols = false;
505 bool fulltoc = false;
506
507 if (args["cl"] != "search") {
508 // see if there's a FullTOC string
509 text_t cl_top, full_toc;
510 get_top (args["cl"], cl_top);
511 if (get_formatstring (cl_top, "FullTOC", formatinfo.formatstrings, full_toc))
512 if (full_toc == "true") fulltoc = true;
513 }
514
515 // get the cover image (if there is one) and the control buttons
516 // if we're inside a book
517 if ((!fulltoc) && (!args["d"].empty())) {
518 textout << "<p><table cellpadding=0 cellspacing=0><tr>\n";
519 textout << "<td valign=top";
520 if (formatinfo.DocumentContents) textout << " width=200>\n";
521 else textout << " width=100%>\n";
522 if (formatinfo.DocumentImages)
523 output_cover_image (args, collectproto, disp, outconvert, textout, logout);
524 else if (formatinfo.DocumentTitles)
525 output_titles (args, collectproto, formatinfo, disp, outconvert, textout, logout);
526 output_controls (args, formatinfo.DocumentButtons, collectproto, disp,
527 outconvert, textout, logout);
528 textout << "</td><td valign=top>\n";
529 havecontrols = true;
530 }
531
532 if (formatinfo.DocumentContents || args["d"].empty()) {
533 if (args.getintarg("gc") == 1) {
534
535 // expanded table of contents
536 expanded_contents (args, tabcount, fulltoc, browsermap, formatinfo,
537 collectproto, disp, outconvert, textout, logout);
538 } else {
539
540 // contracted table of contents
541 contracted_contents (args, tabcount, fulltoc, browsermap, formatinfo,
542 collectproto, disp, outconvert, textout, logout);
543 }
544 }
545
546 if (havecontrols) textout << "</td></tr></table>\n";
547}
Note: See TracBrowser for help on using the repository browser.