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

Last change on this file since 1804 was 1610, checked in by paynter, 24 years ago

Changed the formatstring parser in formattools so that an {If} macro (which
has the form {If}{decision,then,else}) can branch on any text, not just on
metadata. This means you can use extra cgi arguments and macros like
_cgiargmode_ to display documents in different modes and switch between
them. To accomplish all this, the formattools class needed to be able to
evaluate macros (through displayclass), so the other files have been
changed to pass in a displayclass object.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 19.1 KB
RevLine 
[649]1
[208]2/**********************************************************************
3 *
4 * browsetools.cpp --
5 * Copyright (C) 1999 The New Zealand Digital Library Project
6 *
[533]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.
[208]10 *
[533]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 *
[208]25 *********************************************************************/
26
27#include "browsetools.h"
[213]28#include "OIDtools.h"
[208]29
[649]30
[1079]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
[1443]116 textout << outconvert << disp
117 << get_formatted_string (args["c"],collectproto,
[1610]118 response.docInfo[0], disp, formatlistptr,
[1443]119 logout);
[1079]120}
121
122
[737]123static void recurse_contents (ResultDocInfo_t &section, cgiargsclass &args, bool fulltoc,
[649]124 browserclass *bptr, text_tset &metadata, bool &getParents,
125 format_t *formatlistptr, format_tmap &formatlistmap,
[1079]126 formatinfo_t &formatinfo, browsermapclass *browsermap,
[737]127 int tabcount, recptproto *collectproto, displayclass &disp,
[649]128 outconvertclass &outconvert, ostream &textout, ostream &logout) {
129 text_t formatstring;
[419]130
[649]131 bool is_classify = false;
[737]132 if (args["d"].empty() || fulltoc) is_classify = true;
[404]133
[649]134 // output this section
135 bool use_table = is_table_content (formatlistptr);
[748]136 tabcount += bptr->output_section_group (section, args, "", tabcount, formatlistptr, use_table,
[737]137 metadata, getParents, collectproto, disp, outconvert,
138 textout, logout);
[404]139
[649]140 text_t classification;
141 if (!is_classify) classification = "Document";
[737]142 else get_top (args["cl"], classification);
[404]143
[649]144 int haschildren = section.metadata["haschildren"].values[0].getint();
145 const text_t &doctype = section.metadata["doctype"].values[0];
[730]146 text_t classifytype = section.metadata["childtype"].values[0];
[737]147 // HLists and DateLists are displayed as VLists when contents
148 // are expanded, Paged documents are displayed as HLists
149 if (classifytype == "HList" || classifytype == "DateList") classifytype = "VList";
[667]150 if (classifytype == "Paged") classifytype = "HList";
[404]151
[649]152 // recurse through children
[737]153 if ((haschildren == 1) && (!is_classify || fulltoc || doctype == "classify")) {
[404]154
[649]155 // get browser for displaying children
156 bptr = browsermap->getbrowser (classifytype);
157 bptr->load_metadata_defaults (metadata);
[404]158
[649]159 // get the formatstring if there is one
[1079]160 if (!get_formatstring (classification, classifytype,
161 formatinfo.formatstrings, formatstring))
[649]162 formatstring = bptr->get_default_formatstring();
[404]163
[649]164 format_tmap::const_iterator it = formatlistmap.find (formatstring);
165 // check if formatlistptr is cached
166 if (it != formatlistmap.end()) formatlistptr = (*it).second;
167 else {
168 formatlistptr = new format_t();
169 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
170 formatlistmap[formatstring] = formatlistptr;
[469]171 }
[213]172
[649]173 FilterResponse_t tmp;
174 get_children (section.OID, args["c"], metadata, getParents, collectproto, tmp, logout);
175 ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
176 ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
[444]177
[649]178 while (thisdoc != lastdoc) {
[737]179 recurse_contents (*thisdoc, args, fulltoc, bptr, metadata, getParents,
[1079]180 formatlistptr, formatlistmap, formatinfo, browsermap,
[737]181 tabcount, collectproto, disp, outconvert, textout, logout);
[649]182 thisdoc ++;
[213]183 }
184 }
185}
186
[257]187
[649]188// expanded_contents recurses through all contents. there's a special case
189// for an HList when contents are expanded (i.e. it's displayed as a VList)
190//
191// if we're inside a document we expand all contents from the top,
192// if we're at classification level we'll just expand out those contents below
193// the current one
[344]194
[1079]195void expanded_contents (cgiargsclass &args, int tabcount, bool fulltoc,
196 browsermapclass *browsermap, formatinfo_t &formatinfo,
197 recptproto *collectproto, displayclass &disp,
198 outconvertclass &outconvert, ostream &textout,
199 ostream &logout) {
[248]200
[649]201 if (args["d"].empty() && args["cl"].empty()) return;
202 text_t OID;
203
204 FilterResponse_t response;
[404]205 bool getParents = false;
[649]206 text_tset metadata;
207 text_t classifytype, classification, formatstring;
[213]208
[649]209 if (!args["d"].empty()) {
[737]210 // document level
211 if (fulltoc) {
212 get_top (args["cl"], OID);
213 classification = OID;
214 }
215 else {
216 // always expand document level from top
217 get_top (args["d"], OID);
218 classification = "Document";
219 }
[649]220 } else {
221 // classification level
222 OID = args["cl"];
223 get_top (args["cl"], classification);
[624]224 }
225
[649]226 // get classifytype of this level
227 text_t tOID;
228 if (is_top(OID)) {
229 classifytype = "thistype";
230 tOID = OID;
[419]231 } else {
[649]232 classifytype = "childtype";
233 tOID = get_parent (OID);
[419]234 }
[649]235 metadata.insert (classifytype);
[344]236
[649]237 if (!get_info (tOID, args["c"], metadata, getParents, collectproto, response, logout))
238 return;
239 classifytype = response.docInfo[0].metadata[classifytype].values[0];
240 // if we still don't have a classifytype we'll use the default
241 if (classifytype.empty()) {
242 browserclass *bptr = browsermap->get_default_browser ();
243 classifytype = bptr->get_browser_name ();
[257]244 }
245
[649]246 // HLists are displayed as VLists when contents are expanded,
[730]247 // Paged documents are displayed as HLists
[778]248 if (classifytype == "HList") {
249 classifytype = "VList";
250 text_t pOID = get_parent (OID);
251 if (!pOID.empty()) {
252 OID = pOID;
253 // this is assuming that top levels are always 'Invisible' !!!
254 if (is_top (OID)) classifytype = "Invisible";
255 }
256 }
[730]257 if (classifytype == "Paged") classifytype = "HList";
[213]258
[649]259 metadata.erase (metadata.begin(), metadata.end());
260
261 // metadata elements needed by recurse_contents
[730]262 metadata.insert ("childtype");
[649]263 metadata.insert ("doctype");
264 metadata.insert ("haschildren");
[419]265
[649]266 // load up metadata array with browser defaults
267 browserclass *bptr = browsermap->getbrowser (classifytype);
268 bptr->load_metadata_defaults (metadata);
[624]269
[649]270 // get the formatstring if there is one or use the browsers default
[1079]271 if (!get_formatstring (classification, classifytype,
272 formatinfo.formatstrings, formatstring))
[649]273 formatstring = bptr->get_default_formatstring();
[419]274
[649]275 format_t *formatlistptr = new format_t();
276 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
[624]277
[649]278 // protocol call
279 if (!get_info (OID, args["c"], metadata, getParents, collectproto, response, logout))
280 return;
[624]281
[649]282 format_tmap formatlistmap;
283 formatlistmap[formatstring] = formatlistptr;
[624]284
[737]285 recurse_contents (response.docInfo[0], args, fulltoc, bptr, metadata,
[1079]286 getParents, formatlistptr, formatlistmap, formatinfo, browsermap,
[737]287 tabcount, collectproto, disp, outconvert, textout, logout);
[624]288
[649]289 // clean up format list pointers
290 format_tmap::const_iterator here = formatlistmap.begin();
291 format_tmap::const_iterator end = formatlistmap.end();
292 while (here != end) {
293 delete (*here).second;
294 here ++;
[419]295 }
296}
297
[667]298
[649]299static void load_formatstring (const text_t &classifytype, text_tset &metadata,
300 bool &getParents, const text_t &classification,
[1079]301 browsermapclass *browsermap, formatinfo_t &formatinfo,
[649]302 format_tmap &formatlistmap) {
303 text_t formatstring;
[419]304
[649]305 // load up metadata array with browser defaults
306 browserclass *bptr = browsermap->getbrowser (classifytype);
307 bptr->load_metadata_defaults (metadata);
[419]308
[649]309 // get the formatstring if there is one or use the browsers default
[1079]310 if (!get_formatstring (classification, classifytype,
311 formatinfo.formatstrings, formatstring))
[649]312 formatstring = bptr->get_default_formatstring();
[419]313
[649]314 // see if it's cached
315 format_tmap::const_iterator it = formatlistmap.find (formatstring);
316 if (it == formatlistmap.end()) {
317 format_t *formatlistptr = new format_t();
318 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
319 formatlistmap[formatstring] = formatlistptr;
[419]320 }
[208]321}
[213]322
[649]323static void load_formatstrings (FilterResponse_t &response, text_tset &metadata,
324 bool &getParents, const text_t &classification,
[1079]325 browsermapclass *browsermap, formatinfo_t &formatinfo,
[649]326 format_tmap &formatlistmap) {
[213]327
[649]328 text_tset cache;
[419]329
[649]330 ResultDocInfo_tarray::iterator thisdoc = response.docInfo.begin();
331 ResultDocInfo_tarray::iterator lastdoc = response.docInfo.end();
[419]332
[649]333 while (thisdoc != lastdoc) {
[667]334
335 if (is_top ((*thisdoc).OID))
336 load_formatstring ((*thisdoc).metadata["thistype"].values[0], metadata,
[1079]337 getParents, classification, browsermap, formatinfo,
[667]338 formatlistmap);
339
[649]340 text_t &childtype = (*thisdoc).metadata["childtype"].values[0];
341 text_tset::const_iterator it = cache.find (childtype);
342 if (it == cache.end()) {
[667]343 load_formatstring (childtype, metadata, getParents, classification,
[1079]344 browsermap, formatinfo, formatlistmap);
[667]345 cache.insert (childtype);
[649]346 }
347 thisdoc ++;
[419]348 }
349}
350
[667]351static void output_parents (FilterResponse_t &response, cgiargsclass &args,
[1079]352 browsermapclass *browsermap, formatinfo_t &formatinfo,
[667]353 format_tmap &formatlistmap, const text_t &classification,
[737]354 int &tabcount, text_tset &metadata, bool &getParents,
[667]355 recptproto *collectproto, displayclass &disp,
[688]356 outconvertclass &outconvert, ostream &textout,
[667]357 ostream &logout) {
[419]358
[667]359 format_t *formatlistptr = NULL;
360 text_t classifytype, formatstring;
361 bool use_table, first = true;
362 ResultDocInfo_tarray::iterator thisparent = response.docInfo.begin();
363 ResultDocInfo_tarray::iterator lastparent = response.docInfo.end();
364 while (thisparent != lastparent) {
365
366 // get classifytype of this level
367 if (is_top ((*thisparent).OID)) classifytype = (*thisparent).metadata["thistype"].values[0];
368 else if (!first) classifytype = (*(thisparent-1)).metadata["childtype"].values[0];
369
370 // if we still don't have a classifytype we'll use the default
371 if (classifytype.empty()) {
372 browserclass *bptr = browsermap->get_default_browser ();
373 classifytype = bptr->get_browser_name ();
374 }
375
376 browserclass *bptr = browsermap->getbrowser (classifytype);
377
378 // get the formatstring if there is one or use the browsers default
[1079]379 if (!get_formatstring (classification, classifytype,
380 formatinfo.formatstrings, formatstring))
[667]381 formatstring = bptr->get_default_formatstring();
382
383 // see if it's cached
384 format_tmap::const_iterator it = formatlistmap.find (formatstring);
385 if (it != formatlistmap.end()) formatlistptr = (*it).second;
386 else {
387 logout << "browsetools error\n";
388 return;
389 }
390
391 use_table = is_table_content (formatlistptr);
[748]392 tabcount += bptr->output_section_group (*thisparent, args, "", tabcount, formatlistptr,
[737]393 use_table, metadata, getParents, collectproto,
394 disp, outconvert, textout, logout);
[667]395 first = false;
396 thisparent ++;
397 }
398}
399
[1079]400void contracted_contents (cgiargsclass &args, int tabcount, bool fulltoc,
401 browsermapclass *browsermap, formatinfo_t &formatinfo,
402 recptproto *collectproto, displayclass &disp,
403 outconvertclass &outconvert, ostream &textout,
404 ostream &logout) {
[914]405
[257]406 FilterResponse_t response;
[649]407 text_tset metadata;
408 bool getParents = false;
[667]409 text_t formatstring;
[649]410 text_tarray parents;
411 text_t OID = args["d"];
412 text_t classification = "Document";
[667]413 if (OID.empty()) {
414 OID = args["cl"];
415 get_top (OID, classification);
[737]416 } else if (fulltoc)
417 get_top (args["cl"], classification);
[257]418
[649]419 bool haschildren = has_children (OID, args["c"], collectproto, logout);
[257]420
[737]421 if ((!args["d"].empty()) && fulltoc)
422 get_parents_array (args["cl"] + ".fc", parents);
[649]423 if (haschildren) get_parents_array (OID + ".fc", parents);
424 else get_parents_array (OID, parents);
[279]425
[667]426 if (!parents.empty()) {
427 // get classifytypes of each parent
428 metadata.insert ("thistype");
429 metadata.insert ("childtype");
430
431 if (!get_info (parents, args["c"], metadata, getParents, collectproto, response, logout))
432 return;
433
434 // get formatstrings for all parents
435 format_tmap formatlistmap;
436 load_formatstrings (response, metadata, getParents, classification,
[1079]437 browsermap, formatinfo, formatlistmap);
[213]438
[667]439 if (!get_info (parents, args["c"], metadata, getParents, collectproto, response, logout))
440 return;
441
442 // display each parent
[1079]443 output_parents (response, args, browsermap, formatinfo, formatlistmap,
[737]444 classification, tabcount, metadata, getParents,
[667]445 collectproto, disp, outconvert, textout, logout);
446
447 metadata.erase (metadata.begin(), metadata.end());
448
449 // clean up cached format list pointers
450 format_tmap::const_iterator here = formatlistmap.begin();
451 format_tmap::const_iterator end = formatlistmap.end();
452 while (here != end) {
453 delete (*here).second;
454 here ++;
455 }
456 }
[257]457
[667]458 // get childrens classifytype
459 text_t classifytype;
460 int numparents = response.docInfo.size();
461 if (!parents.empty())
462 classifytype = response.docInfo[numparents-1].metadata["childtype"].values[0];
463 else {
464 // use the default
465 browserclass *bptr = browsermap->get_default_browser ();
466 classifytype = bptr->get_browser_name ();
467 }
468
469 // load up metadata array with browser defaults
470 browserclass *bptr = browsermap->getbrowser (classifytype);
471 bptr->load_metadata_defaults (metadata);
[213]472
[667]473 // get the formatstring if there is one or use the browsers default
[1079]474 if (!get_formatstring (classification, classifytype,
475 formatinfo.formatstrings, formatstring))
[667]476 formatstring = bptr->get_default_formatstring();
477
478 format_t *formatlistptr = new format_t();
479 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
480
481 if (haschildren)
482 get_children (OID, args["c"], metadata, getParents,
483 collectproto, response, logout);
[941]484 else if (!is_top(OID)) {
[667]485 get_children (OID + ".pr", args["c"], metadata, getParents,
486 collectproto, response, logout);
[941]487 haschildren = true;
488 }
[667]489
490 // display children
[941]491 if (haschildren) {
492 bool use_table = is_table_content (formatlistptr);
[1443]493 // collection used to be "" // **** // check with Stef!!!!
494 bptr->output_section_group (response, args, args["c"], tabcount, formatlistptr, use_table,
[941]495 metadata, getParents, collectproto, disp, outconvert,
496 textout, logout);
497 }
[667]498
499 delete formatlistptr;
[213]500}
501
[649]502void output_toc (cgiargsclass &args, browsermapclass *browsermap,
[1079]503 formatinfo_t &formatinfo, recptproto *collectproto,
[649]504 displayclass &disp, outconvertclass &outconvert,
505 ostream &textout, ostream &logout) {
[344]506
[737]507 int tabcount = 0;
[1079]508 bool havecontrols = false;
[737]509 bool fulltoc = false;
510
511 if (args["cl"] != "search") {
512 // see if there's a FullTOC string
513 text_t cl_top, full_toc;
514 get_top (args["cl"], cl_top);
[1079]515 if (get_formatstring (cl_top, "FullTOC", formatinfo.formatstrings, full_toc))
[737]516 if (full_toc == "true") fulltoc = true;
517 }
[1079]518
519 // get the cover image (if there is one) and the control buttons
520 // if we're inside a book
521 if ((!fulltoc) && (!args["d"].empty())) {
[1606]522 textout << "<center>\n";
523 textout << outconvert << disp << "<p><table width=_pagewidth_ cellpadding=0 cellspacing=0><tr>\n";
524 textout << "<td valign=top align=left";
[1079]525 if (formatinfo.DocumentContents) textout << " width=200>\n";
526 else textout << " width=100%>\n";
527 if (formatinfo.DocumentImages)
528 output_cover_image (args, collectproto, disp, outconvert, textout, logout);
529 else if (formatinfo.DocumentTitles)
530 output_titles (args, collectproto, formatinfo, disp, outconvert, textout, logout);
531 output_controls (args, formatinfo.DocumentButtons, collectproto, disp,
532 outconvert, textout, logout);
533 textout << "</td><td valign=top>\n";
534 havecontrols = true;
535 }
[248]536
[1079]537 if (formatinfo.DocumentContents || args["d"].empty()) {
538 if (args.getintarg("gc") == 1) {
[667]539
[1079]540 // expanded table of contents
541 expanded_contents (args, tabcount, fulltoc, browsermap, formatinfo,
542 collectproto, disp, outconvert, textout, logout);
543 } else {
[1059]544
[1079]545 // contracted table of contents
546 contracted_contents (args, tabcount, fulltoc, browsermap, formatinfo,
547 collectproto, disp, outconvert, textout, logout);
548 }
[667]549 }
[1079]550
[1606]551 if (havecontrols) textout << "</td></tr></table></center>\n";
[248]552}
Note: See TracBrowser for help on using the repository browser.