source: trunk/gsdl/src/recpt/browsetools.cpp@ 2664

Last change on this file since 2664 was 2664, checked in by sjboddie, 23 years ago

Re-introduced the old "u" cgi argument for suppressing certain parts of
the Greenstone interface (like searching) for use when generating static
collections.

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