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

Last change on this file since 12008 was 11889, checked in by mdewsnip, 18 years ago

Fixed a couple of calls to output_section_group where "" was passed in as the collection name, meaning any get_info()s would fail (and consequently messing up some format statements).

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 31.7 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 11889 2006-05-30 03:31:22Z mdewsnip $
26 *
27 *********************************************************************/
28
29#include "browsetools.h"
30#include "OIDtools.h"
31#include "gsdlunicode.h"
32
33#if defined(GSDL_USE_IOS_H)
34# if defined(__WIN32__)
35# include <strstrea.h> // vc4
36# else
37# include <strstream.h>
38# endif
39#else
40# include <sstream>
41#endif
42
43
44// output_controls displays the detach, expand/contract contents,
45// expand/contract text and highlighting/no highlighting buttons
46
47void output_controls (cgiargsclass &args, const text_tarray &ibuttons,
48 recptproto * /*collectproto*/, displayclass &disp,
49 outconvertclass &outconvert, ostream &textout,
50 ostream &/*logout*/) {
51
52 if (args["u"] != "1") {
53
54 FilterResponse_t response;
55 text_tarray metadata;
56 text_tarray buttons;
57
58 text_tarray::const_iterator here = ibuttons.begin();
59 text_tarray::const_iterator end = ibuttons.end();
60
61 while (here != end) {
62
63 if (*here == "Detach")
64 buttons.push_back ("_document:imagedetach_");
65 else if (*here == "Highlight") {
66 if (args["hl"] == "1")
67 buttons.push_back ("_document:imagenohighlight_");
68 else
69 buttons.push_back ("_document:imagehighlight_");
70 } else if (*here == "Expand Contents") {
71 if (args["gc"] == "1")
72 buttons.push_back ("_document:imagecontracttoc_");
73 else
74 buttons.push_back ("_document:imageexpandtoc_");
75 } else if (*here == "Expand Text") {
76 if (args.getintarg("gt"))
77 buttons.push_back ("_document:imagecontracttext_");
78 else
79 buttons.push_back ("_document:imageexpandtext_");
80 }
81 ++here;
82 }
83
84 here = buttons.begin();
85 end = buttons.end();
86 while (here != end) {
87 textout << outconvert << disp << *here;
88 ++here;
89 }
90 }
91}
92
93text_t get_cover_image () {
94 return "_httpcollimg_/{Or}{[parent(Top):archivedir],[archivedir]}/cover.jpg";
95}
96
97// at the moment this just writes out the html to display
98// the cover image (assuming it's called cover.jpg)
99// this whole thing should be done with a call to the collection
100// server which would send a link to the cover image if there
101// was one otherwise send title, author and stuff
102void output_cover_image (cgiargsclass &args, recptproto * /*collectproto*/,
103 displayclass &disp, outconvertclass &outconvert,
104 ostream &textout, ostream &/*logout*/) {
105
106 if (args["d"].empty()) return;
107
108 textout << outconvert << disp << "<img alt=\"\" onError=\"src='_httpimg_/blank.gif'\" src=\"_httpcollimg_/_thisOID_/cover.jpg\">\n";
109}
110
111void output_titles (cgiargsclass &args, recptproto *collectproto,
112 browsermapclass *browsermap, formatinfo_t &formatinfo,
113 displayclass &disp, outconvertclass &outconvert,
114 ostream &textout, ostream &logout) {
115
116 if (args["d"].empty()) return;
117
118 text_tset metadata;
119 bool getParents;
120 FilterResponse_t response;
121
122 format_t *formatlistptr = new format_t();
123 parse_formatstring (formatinfo.DocumentHeading, formatlistptr, metadata, getParents);
124
125 if (!get_info (args["d"], args["c"], args["l"], metadata, getParents, collectproto, response, logout))
126 return;
127
128 text_tmap options;
129 if (formatinfo.AllowExtendedOptions) {
130 load_extended_options(options, args, browsermap, formatinfo,
131 collectproto, disp, outconvert, logout);
132 }
133 textout << outconvert << disp
134 << get_formatted_string (args["c"],collectproto, response.docInfo[0], disp,
135 formatlistptr, options, logout);
136}
137
138//this function outputs the related documents in the format specified
139//in the collection configuration file if the collection preferences
140//indicate they wish related documents to be displayed.
141void output_related_docs (cgiargsclass &args, recptproto *collectproto,
142 formatinfo_t &formatinfo, displayclass &disp,
143 outconvertclass &outconvert, ostream &textout,
144 ostream &logout) {
145
146 if (args["d"].empty()) return; //if no OID
147 if (args["rd"] != "1") return; //if preferences say no related documents
148
149 text_tset metadata;
150 bool getParents;
151 FilterResponse_t response;
152
153 //create new format pointer and parse the related doc format
154 //string specified in the collection config file
155 format_t *formatlistptr = new format_t();
156 parse_formatstring (formatinfo.RelatedDocuments, formatlistptr, metadata, getParents);
157
158 if (!get_info (args["d"], args["c"], args["l"], metadata, getParents, collectproto, response, logout))
159 return;
160
161 //get the format string from formattools.cpp
162 text_tmap options; // no options
163 text_t relateddocs = get_formatted_string (args["c"],collectproto, response.docInfo[0],
164 disp, formatlistptr, options, logout);
165 //output the related documents
166 textout << outconvert << disp << relateddocs;
167}
168
169
170
171static void recurse_contents (ResultDocInfo_t &section, cgiargsclass &args, bool fulltoc,
172 browserclass *bptr, text_tset &metadata, bool &getParents,
173 format_t *formatlistptr, format_tmap &formatlistmap,
174 formatinfo_t &formatinfo, browsermapclass *browsermap,
175 int tabcount, recptproto *collectproto, displayclass &disp,
176 outconvertclass &outconvert, ostream &textout, ostream &logout) {
177 text_t formatstring;
178
179 bool is_classify = false;
180 if (args["d"].empty() || fulltoc) is_classify = true;
181
182 // output this section
183 bool use_table = is_table_content (formatlistptr);
184 tabcount += bptr->output_section_group (section, args, args["c"], tabcount, formatlistptr, use_table,
185 metadata, getParents, collectproto, disp, outconvert,
186 textout, logout);
187
188 text_t classification;
189 if (!is_classify) classification = "Document";
190 else get_top (args["cl"], classification);
191
192 int haschildren = section.metadata["haschildren"].values[0].getint();
193 const text_t &doctype = section.metadata["doctype"].values[0];
194 text_t classifytype = section.metadata["childtype"].values[0];
195 // HLists and DateLists are displayed as VLists when contents
196 // are expanded, Paged documents are displayed as HLists
197 if (classifytype == "HList" || classifytype == "DateList") classifytype = "VList";
198 if (classifytype == "Paged") classifytype = "HList";
199
200 // recurse through children
201 if ((haschildren == 1) && (!is_classify || fulltoc || doctype == "classify")) {
202
203 // get browser for displaying children
204 bptr = browsermap->getbrowser (classifytype);
205 bptr->load_metadata_defaults (metadata);
206
207 // get the formatstring if there is one
208 if (!get_formatstring (classification, classifytype,
209 formatinfo.formatstrings, formatstring))
210 formatstring = bptr->get_default_formatstring();
211
212 format_tmap::const_iterator it = formatlistmap.find (formatstring);
213 // check if formatlistptr is cached
214 if (it != formatlistmap.end()) formatlistptr = (*it).second;
215 else {
216 formatlistptr = new format_t();
217 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
218 formatlistmap[formatstring] = formatlistptr;
219 }
220
221 FilterResponse_t tmp;
222 get_children (section.OID, args["c"], args["l"], metadata, getParents, collectproto, tmp, logout);
223 ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
224 ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
225
226 while (thisdoc != lastdoc) {
227 recurse_contents (*thisdoc, args, fulltoc, bptr, metadata, getParents,
228 formatlistptr, formatlistmap, formatinfo, browsermap,
229 tabcount, collectproto, disp, outconvert, textout, logout);
230 ++thisdoc;
231 }
232 }
233}
234
235
236// expanded_contents recurses through all contents. there's a special case
237// for an HList when contents are expanded (i.e. it's displayed as a VList)
238//
239// if we're inside a document we expand all contents from the top,
240// if we're at classification level we'll just expand out those contents below
241// the current one
242
243void expanded_contents (cgiargsclass &args, int tabcount, bool fulltoc,
244 browsermapclass *browsermap, formatinfo_t &formatinfo,
245 recptproto *collectproto, displayclass &disp,
246 outconvertclass &outconvert, ostream &textout,
247 ostream &logout) {
248
249 if (args["d"].empty() && args["cl"].empty()) return;
250 text_t OID;
251
252 FilterResponse_t response;
253 bool getParents = false;
254 text_tset metadata;
255 text_t classifytype, classification, formatstring;
256
257 if (!args["d"].empty()) {
258 // document level
259 if (fulltoc) {
260 get_top (args["cl"], OID);
261 classification = OID;
262 }
263 else {
264 // always expand document level from top
265 get_top (args["d"], OID);
266 classification = "Document";
267 }
268 } else {
269 // classification level
270 OID = args["cl"];
271 get_top (args["cl"], classification);
272 }
273
274 // get classifytype of this level
275 text_t tOID;
276 if (is_top(OID)) {
277 classifytype = "thistype";
278 tOID = OID;
279 } else {
280 classifytype = "childtype";
281 tOID = get_parent (OID);
282 }
283 metadata.insert (classifytype);
284
285 if (!get_info (tOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
286 return;
287 classifytype = response.docInfo[0].metadata[classifytype].values[0];
288 // if we still don't have a classifytype we'll use the default
289 if (classifytype.empty()) {
290 browserclass *bptr = browsermap->get_default_browser ();
291 classifytype = bptr->get_browser_name ();
292 }
293
294 // HLists are displayed as VLists when contents are expanded,
295 // Paged documents are displayed as HLists
296 if (classifytype == "HList") {
297 classifytype = "VList";
298 text_t pOID = get_parent (OID);
299 if (!pOID.empty()) {
300 OID = pOID;
301 // this is assuming that top levels are always 'Invisible' !!!
302 if (is_top (OID)) classifytype = "Invisible";
303 }
304 }
305 if (classifytype == "Paged") classifytype = "HList";
306
307 metadata.erase (metadata.begin(), metadata.end());
308
309 // metadata elements needed by recurse_contents
310 metadata.insert ("childtype");
311 metadata.insert ("doctype");
312 metadata.insert ("haschildren");
313
314 // load up metadata array with browser defaults
315 browserclass *bptr = browsermap->getbrowser (classifytype);
316 bptr->load_metadata_defaults (metadata);
317
318 // get the formatstring if there is one or use the browsers default
319 if (!get_formatstring (classification, classifytype,
320 formatinfo.formatstrings, formatstring))
321 formatstring = bptr->get_default_formatstring();
322
323 format_t *formatlistptr = new format_t();
324 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
325
326 // protocol call
327 if (!get_info (OID, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
328 return;
329
330 format_tmap formatlistmap;
331 formatlistmap[formatstring] = formatlistptr;
332
333 recurse_contents (response.docInfo[0], args, fulltoc, bptr, metadata,
334 getParents, formatlistptr, formatlistmap, formatinfo, browsermap,
335 tabcount, collectproto, disp, outconvert, textout, logout);
336
337 // clean up format list pointers
338 format_tmap::const_iterator here = formatlistmap.begin();
339 format_tmap::const_iterator end = formatlistmap.end();
340 while (here != end) {
341 delete (*here).second;
342 ++here;
343 }
344}
345
346
347static void load_formatstring (const text_t &classifytype, text_tset &metadata,
348 bool &getParents, const text_t &classification,
349 browsermapclass *browsermap, formatinfo_t &formatinfo,
350 format_tmap &formatlistmap) {
351 text_t formatstring;
352
353 // load up metadata array with browser defaults
354 browserclass *bptr = browsermap->getbrowser (classifytype);
355 bptr->load_metadata_defaults (metadata);
356
357 // get the formatstring if there is one or use the browsers default
358 if (!get_formatstring (classification, classifytype,
359 formatinfo.formatstrings, formatstring))
360 formatstring = bptr->get_default_formatstring();
361
362 // see if it's cached
363 format_tmap::const_iterator it = formatlistmap.find (formatstring);
364 if (it == formatlistmap.end()) {
365 format_t *formatlistptr = new format_t();
366 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
367 formatlistmap[formatstring] = formatlistptr;
368 }
369}
370
371static void load_formatstrings (FilterResponse_t &response, text_tset &metadata,
372 bool &getParents, const text_t &classification,
373 browsermapclass *browsermap, formatinfo_t &formatinfo,
374 format_tmap &formatlistmap) {
375
376 text_tset cache;
377
378 ResultDocInfo_tarray::iterator thisdoc = response.docInfo.begin();
379 ResultDocInfo_tarray::iterator lastdoc = response.docInfo.end();
380
381 while (thisdoc != lastdoc) {
382
383 if (is_top ((*thisdoc).OID)) {
384 load_formatstring ((*thisdoc).metadata["thistype"].values[0], metadata,
385 getParents, classification, browsermap, formatinfo,
386 formatlistmap);
387 }
388
389 // sometimes childtype is not set - why??
390 if ((*thisdoc).metadata.find("childtype") != (*thisdoc).metadata.end()) {
391 text_t &childtype = (*thisdoc).metadata["childtype"].values[0];
392
393 text_tset::const_iterator it = cache.find (childtype);
394 if (it == cache.end()) {
395 load_formatstring (childtype, metadata, getParents, classification,
396 browsermap, formatinfo, formatlistmap);
397 cache.insert (childtype);
398 }
399 }
400 ++thisdoc;
401 }
402}
403
404static void output_parents (FilterResponse_t &response, cgiargsclass &args,
405 browsermapclass *browsermap, formatinfo_t &formatinfo,
406 format_tmap &formatlistmap, const text_t &classification,
407 int &tabcount, text_tset &metadata, bool &getParents,
408 recptproto *collectproto, displayclass &disp,
409 outconvertclass &outconvert, ostream &textout,
410 ostream &logout) {
411
412 format_t *formatlistptr = NULL;
413 text_t classifytype, formatstring;
414 bool use_table, first = true;
415 ResultDocInfo_tarray::iterator thisparent = response.docInfo.begin();
416 ResultDocInfo_tarray::iterator lastparent = response.docInfo.end();
417 while (thisparent != lastparent) {
418
419 // get classifytype of this level
420 if (is_top ((*thisparent).OID)) classifytype = (*thisparent).metadata["thistype"].values[0];
421 else if (!first && (*(thisparent-1)).metadata.find("childtype") != (*(thisparent-1)).metadata.end()) classifytype = (*(thisparent-1)).metadata["childtype"].values[0];
422
423 // if we still don't have a classifytype we'll use the default
424 if (classifytype.empty()) {
425 browserclass *bptr = browsermap->get_default_browser ();
426 classifytype = bptr->get_browser_name ();
427 }
428
429 browserclass *bptr = browsermap->getbrowser (classifytype);
430
431 // get the formatstring if there is one or use the browsers default
432 if (!get_formatstring (classification, classifytype,
433 formatinfo.formatstrings, formatstring))
434 formatstring = bptr->get_default_formatstring();
435
436 // see if it's cached
437 format_tmap::const_iterator it = formatlistmap.find (formatstring);
438 if (it != formatlistmap.end()) formatlistptr = (*it).second;
439 else {
440 logout << "browsetools error\n";
441 return;
442 }
443
444 use_table = is_table_content (formatlistptr);
445 tabcount += bptr->output_section_group (*thisparent, args, args["c"], tabcount, formatlistptr,
446 use_table, metadata, getParents, collectproto,
447 disp, outconvert, textout, logout);
448 first = false;
449 ++thisparent;
450 }
451}
452
453void contracted_contents (cgiargsclass &args, int tabcount, bool fulltoc,
454 browsermapclass *browsermap, formatinfo_t &formatinfo,
455 recptproto *collectproto, displayclass &disp,
456 outconvertclass &outconvert, ostream &textout,
457 ostream &logout) {
458
459 FilterResponse_t response;
460 text_tset metadata;
461 bool getParents = false;
462 text_t formatstring;
463 text_tarray parents;
464 text_t OID = args["d"];
465 text_t classification = "Document";
466
467 // if we're not outputting the TOC for a valid OID, then we should be giving
468 // the TOC of a classification
469 if (OID.empty()) {
470 OID = args["cl"];
471 get_top (OID, classification);
472 }
473 // if we're to give the full TOC of a document, get the parent for the whole
474 // document now
475 else if (fulltoc)
476 get_top (args["cl"], classification);
477
478 bool haschildren = has_children (OID, args["c"], args["l"], collectproto, logout);
479
480 if ((!args["d"].empty()) && fulltoc)
481 get_parents_array (args["cl"] + ".fc", parents);
482 if (haschildren) get_parents_array (OID + ".fc", parents);
483 else get_parents_array (OID, parents);
484
485 if (!parents.empty()) {
486 // get classifytypes of each parent
487 metadata.insert ("thistype");
488 metadata.insert ("childtype");
489 metadata.insert("mdtype");
490
491 if (!get_info (parents, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
492 return;
493
494 // get formatstrings for all parents
495 format_tmap formatlistmap;
496 load_formatstrings (response, metadata, getParents, classification,
497 browsermap, formatinfo, formatlistmap);
498
499 if (!get_info (parents, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
500 return;
501
502 // display each parent
503 output_parents (response, args, browsermap, formatinfo, formatlistmap,
504 classification, tabcount, metadata, getParents,
505 collectproto, disp, outconvert, textout, logout);
506
507 metadata.erase (metadata.begin(), metadata.end());
508
509 // clean up cached format list pointers
510 format_tmap::const_iterator here = formatlistmap.begin();
511 format_tmap::const_iterator end = formatlistmap.end();
512 while (here != end) {
513 delete (*here).second;
514 ++here;
515 }
516 }
517
518 // get childrens classifytype
519 text_t classifytype;
520 int numparents = response.docInfo.size();
521 if (!parents.empty() && (response.docInfo[numparents-1].metadata.find("childtype") != response.docInfo[numparents-1].metadata.end()))
522 classifytype = response.docInfo[numparents-1].metadata["childtype"].values[0];
523 else {
524 // use the default
525 browserclass *bptr = browsermap->get_default_browser ();
526 classifytype = bptr->get_browser_name ();
527 }
528
529 // load up metadata array with browser defaults
530 browserclass *bptr = browsermap->getbrowser (classifytype);
531 bptr->load_metadata_defaults (metadata);
532
533 if (classifytype == "DateList") {
534 // get the mdtype
535 text_t datelist = "Date";
536 if (!parents.empty() && (response.docInfo[0].metadata.find("mdtype") != response.docInfo[0].metadata.end())) {
537 datelist = response.docInfo[0].metadata["mdtype"].values[0];
538 }
539 args.setarg("dm", datelist);
540 text_tarray dates;
541 splitchar(datelist.begin(), datelist.end(), ',', dates);
542 text_tarray::iterator begin = dates.begin();
543 text_tarray::iterator end = dates.end();
544 while (begin!= end) {
545 metadata.insert(*begin);
546 begin++;
547 }
548
549 }
550
551 // get the formatstring if there is one or use the browsers default
552 if (!get_formatstring (classification, classifytype,
553 formatinfo.formatstrings, formatstring))
554 formatstring = bptr->get_default_formatstring();
555
556 format_t *formatlistptr = new format_t();
557 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
558
559 if (haschildren)
560 get_children (OID, args["c"], args["l"], metadata, getParents,
561 collectproto, response, logout);
562 else if (!is_top(OID)) {
563 get_children (OID + ".pr", args["c"], args["l"], metadata, getParents,
564 collectproto, response, logout);
565 haschildren = true;
566 }
567
568 // display children
569 if (haschildren) {
570 bool use_table = is_table_content (formatlistptr);
571 bptr->output_section_group (response, args, args["c"], tabcount, formatlistptr, use_table,
572 metadata, getParents, collectproto, disp, outconvert,
573 textout, logout);
574 }
575 delete formatlistptr;
576}
577
578/**
579 * This function outputs contents of a classifier to the reader
580 * including parent levels
581 */
582void expand_show_contents (cgiargsclass &args, int tabcount, bool fulltoc,
583 browsermapclass *browsermap, formatinfo_t &formatinfo,
584 recptproto *collectproto, displayclass &disp,
585 outconvertclass &outconvert, ostream &textout,
586 ostream &logout)
587{
588
589 int coloffset = 0;
590 text_tarray parents;
591 FilterResponse_t response;
592 text_t OID = args["d"];
593 if (OID.empty()) OID = args["cl"];
594
595 bool haschildren = has_children (OID, args["c"], args["l"], collectproto, logout);
596
597 // get parents list
598 if (!is_top(OID)) get_parents_array (OID, parents);
599 if (args["d"].empty() || haschildren || parents.empty())
600 parents.push_back(OID);
601
602 // if inside a book top title is needed
603 if (!args["d"].empty()) {
604
605 coloffset = 1;
606 text_t classification, classifytype, formatstring, topOID = parents[0];
607 text_tset metadata;
608 format_t *formatlistptr = new format_t();
609 bool use_table, getParents = false;
610
611 get_top (args["cl"], classification);
612
613 // getting information about top OID
614 metadata.insert ("thistype");
615
616 get_info ( topOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
617 if (!response.docInfo[0].metadata["thistype"].values.empty())
618 classifytype = response.docInfo[0].metadata["thistype"].values[0];
619
620 browserclass *bptr = browsermap->getbrowser (classifytype);
621
622 if (classifytype.empty()) {
623 bptr = browsermap->get_default_browser();
624 }
625
626 // get the formatstring if there is one or use the browsers default
627 if (!get_formatstring (classification, classifytype,
628 formatinfo.formatstrings, formatstring))
629 formatstring = bptr->get_default_formatstring();
630
631 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
632
633 metadata.insert ("doctype");
634 metadata.insert ("haschildren");
635
636 get_info (topOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
637
638 // ouput top OID section
639 use_table = is_table_content (formatlistptr);
640 bptr->output_section_group (response.docInfo[0], args, args["c"], tabcount, formatlistptr, use_table,
641 metadata, getParents, collectproto, disp, outconvert, textout, logout);
642
643 }
644
645 recurse_contents_levels (parents, args, coloffset, tabcount, fulltoc, browsermap,
646 formatinfo, collectproto, disp, outconvert, textout, logout);
647
648 // This messes things up when gc = 2 and doesn't seem to matter otherwise. By Richard Managh
649 // textout << outconvert << "</table></td></tr></table>\n";
650}
651
652void recurse_contents_levels (text_tarray &parents,
653 cgiargsclass &args, int coloffset, int tabcount, bool fulltoc,
654 browsermapclass *browsermap, formatinfo_t &formatinfo,
655 recptproto *collectproto, displayclass &disp,
656 outconvertclass &outconvert, ostream &textout,
657 ostream &logout)
658{
659 FilterResponse_t response;
660 text_tset metadata;
661 text_t OID, formatstring, classification, classifytype;;
662 bool use_table, getParents = false;
663 int haschildren = 0;
664 format_t *formatlistptr = new format_t();
665
666 // display children for last level
667 if (tabcount == (parents.size() - 1)) {
668
669 logout << "@@@lastlevel@@@\n";
670 // setting metadata fields
671 metadata.insert ("thistype");
672 metadata.insert ("childtype");
673 metadata.insert ("haschildren");
674
675 OID = parents[tabcount];
676 get_info (OID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
677 get_top (OID, classification);
678
679 if (!response.docInfo.empty())
680 haschildren = response.docInfo[0].metadata["haschildren"].values[0].getint();
681
682 // get childrens classifytype
683 if (!response.docInfo.empty())
684 classifytype = response.docInfo[0].metadata["childtype"].values[0];
685 else {
686 // use the default
687 browserclass *bptr = browsermap->get_default_browser ();
688 classifytype = bptr->get_browser_name ();
689 }
690
691 // load up metadata array with browser defaults
692 browserclass *bptr = browsermap->getbrowser (classifytype);
693 bptr->load_metadata_defaults (metadata);
694
695 // get the formatstring if there is one or use the browsers default
696 if (!get_formatstring (classification, classifytype,
697 formatinfo.formatstrings, formatstring))
698 formatstring = bptr->get_default_formatstring();
699
700 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
701
702 if (haschildren)
703 get_children (OID, args["c"], args["l"], metadata, getParents,
704 collectproto, response, logout);
705 else if (!is_top(OID)) {
706 get_children (OID + ".pr", args["c"], args["l"], metadata, getParents,
707 collectproto, response, logout);
708 haschildren = true;
709 }
710
711 // display children
712 if (haschildren) {
713 use_table = is_table_content (formatlistptr);
714 bptr->output_section_group (response, args, args["c"], coloffset + tabcount, formatlistptr, use_table,
715 metadata, getParents, collectproto, disp, outconvert,
716 textout, logout);
717 }
718
719 } else {
720
721 text_t pOID;
722 OID = parents[tabcount];
723 get_top (OID, classification);
724
725 // load metadata fields
726 metadata.insert ("thistype");
727 metadata.insert ("childtype");
728 metadata.insert ("haschildren");
729 metadata.insert ("doctype");
730
731 if (tabcount) pOID = parents[tabcount-1];
732 else pOID = OID;
733 get_info (pOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
734
735 // get classifytype of this level
736 if (is_top (pOID)) classifytype = response.docInfo[0].metadata["childtype"].values[0];
737 else classifytype = response.docInfo[0].metadata["thistype"].values[0];
738
739 // if we still don't have a classifytype we'll use the default
740 if (classifytype.empty()) {
741 browserclass *bptr = browsermap->get_default_browser ();
742 classifytype = bptr->get_browser_name ();
743 }
744
745 browserclass *bptr = browsermap->getbrowser (classifytype);
746
747 // get the formatstring if there is one or use the browsers default
748 if (!get_formatstring (classification, classifytype,
749 formatinfo.formatstrings, formatstring))
750 formatstring = bptr->get_default_formatstring();
751
752
753 // parse format string
754 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
755
756 use_table = is_table_content (formatlistptr);
757
758 get_children (OID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
759
760 ResultDocInfo_tarray::iterator thissibling = response.docInfo.begin();
761 ResultDocInfo_tarray::iterator lastsibling = response.docInfo.end();
762
763 while (thissibling != lastsibling) {
764
765 logout << "@@@level:@@@" << tabcount << "\n";
766
767 bptr->output_section_group (*thissibling, args, args["c"], coloffset + tabcount, formatlistptr,
768 use_table, metadata, getParents, collectproto,
769 disp, outconvert, textout, logout);
770
771 if ((*thissibling).OID == parents[tabcount+1]) {
772 recurse_contents_levels (parents, args, coloffset, tabcount+1, fulltoc, browsermap,
773 formatinfo, collectproto, disp, outconvert,textout, logout);
774 }
775
776 ++thissibling;
777 }
778 }
779 delete formatlistptr;
780}
781
782/**
783 * This function outputs the contents of a classifier list to the reader -
784 * the document will in fact be empty, so this does the "real" output
785 */
786void output_toc (cgiargsclass &args, browsermapclass *browsermap,
787 formatinfo_t &formatinfo, recptproto *collectproto,
788 displayclass &disp, outconvertclass &outconvert,
789 ostream &textout, ostream &logout) {
790
791 if (!args["d"].empty() && formatinfo.AllowExtendedOptions) {
792 // If AllowExtendedOptions is set and we're viewing a document,
793 // DocumentButtons, DocumentContent, and DocumentImages are effectively
794 // disabled. We just output the DocumentHeading format string and
795 // return
796 output_titles (args, collectproto, browsermap, formatinfo, disp, outconvert, textout, logout);
797 return;
798 }
799
800 int tabcount = 0;
801 bool fulltoc = false;
802 text_t cl_top, full_toc;
803 if (args["cl"] != "search") {
804 // see if there's a FullTOC string
805 get_top (args["cl"], cl_top);
806 if (get_formatstring (cl_top, "FullTOC", formatinfo.formatstrings, full_toc))
807 if (full_toc == "true") fulltoc = true;
808 }
809
810 // get the cover image (if there is one) and the control buttons
811 // if we're inside a book
812 if ((!fulltoc) && (!args["d"].empty())) {
813 if (formatinfo.DocumentImages) {
814 textout << outconvert << "<div class=\"heading_image\">\n";
815 output_cover_image(args, collectproto, disp, outconvert, textout, logout);
816 textout << outconvert << "</div>\n";
817 } else if (formatinfo.DocumentTitles) {
818 textout << outconvert << "<div class=\"heading_title\">\n";
819 output_titles(args, collectproto, browsermap, formatinfo, disp, outconvert, textout, logout);
820 textout << outconvert << "</div>\n";
821 }
822 textout << outconvert << "<div class=\"buttons\" id=\"toc_buttons\">\n";
823 if (args["u"] != "1") {
824 output_controls (args, formatinfo.DocumentButtons, collectproto, disp,
825 outconvert, textout, logout);
826 }
827 textout << outconvert << "</div>\n\n";
828 }
829
830 if (formatinfo.DocumentContents || args["d"].empty()) {
831 if (args["d"].empty()) {
832 textout << outconvert << "<div id=\""<<cl_top<<"\" class=\"toc\">\n";
833 } else {
834 textout << outconvert << "<div class=\"toc\">\n";
835
836 }
837 if (args.getintarg("gc") == 1) {
838
839 // expanded table of contents
840 expanded_contents (args, tabcount, fulltoc, browsermap, formatinfo,
841 collectproto, disp, outconvert, textout, logout);
842 } else if (args.getintarg("gc") == 2) {
843
844 // expand visible levels of table of contents
845 expand_show_contents(args, tabcount, fulltoc, browsermap, formatinfo,
846 collectproto, disp, outconvert, textout, logout);
847 } else {
848
849 // contracted table of contents
850 contracted_contents (args, tabcount, fulltoc, browsermap, formatinfo,
851 collectproto, disp, outconvert, textout, logout);
852 }
853 textout << outconvert << "</div>\n";
854 }
855
856 //if there is a format specified in the config file then
857 //try to display the related documents (may not be displayed
858 //if preference file does not indicate a wish to display
859 //related documents.
860 if (!formatinfo.RelatedDocuments.empty())
861 output_related_docs(args, collectproto, formatinfo, disp, outconvert, textout, logout);
862
863}
864
865void load_extended_options(text_tmap &options, cgiargsclass &args, browsermapclass *browsers,
866 formatinfo_t &formatinfo, recptproto *collectproto,
867 displayclass &disp, outconvertclass &outconvert, ostream &logout) {
868
869 options["DocImage"] = get_cover_image();
870
871#if defined(GSDL_USE_IOS_H)
872 ostrstream *tmpstr = new ostrstream();
873#else
874 ostringstream *tmpstr = new ostringstream(ostringstream::binary);
875#endif
876
877 if (args["gc"] == "1") {
878 expanded_contents (args, 0, false, browsers, formatinfo,
879 collectproto, disp, outconvert, *tmpstr,
880 logout);
881 } else {
882 contracted_contents (args, 0, false, browsers, formatinfo,
883 collectproto, disp, outconvert, *tmpstr, logout);
884 }
885#if defined(GSDL_USE_IOS_H)
886 char *t = tmpstr->str();
887 text_t tmp;
888 tmp.setcarr(t, tmpstr->pcount());
889 delete [] t;
890#else
891 text_t tmp = (char *)(tmpstr->str().c_str());
892#endif
893 int len = tmp.size();
894 char *ctmp = tmp.getcstr();
895 utf8inconvertclass utf82text_t;
896 utf82text_t.setinput(ctmp, len);
897 convertclass::status_t status;
898 utf82text_t.convert(tmp, status);
899 options["DocTOC"] = tmp;
900 delete []ctmp;
901 delete tmpstr;
902
903 options["DocumentButtonDetach"] = "_document:imagedetach_";
904 if (args["hl"] == "1") {
905 options["DocumentButtonHighlight"] = "_document:imagenohighlight_";
906 } else {
907 options["DocumentButtonHighlight"] = "_document:imagehighlight_";
908 }
909 if (args["gc"] == "1") {
910 options["DocumentButtonExpandContents"] = "_document:imagecontracttoc_";
911 } else {
912 options["DocumentButtonExpandContents"] = "_document:imageexpandtoc_";
913 }
914 if (args["gt"] == "1") {
915 options["DocumentButtonExpandText"] = "_document:imagecontracttext_";
916 } else {
917 options["DocumentButtonExpandText"] = "_document:imageexpandtext_";
918 }
919}
Note: See TracBrowser for help on using the repository browser.