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

Last change on this file since 533 was 533, checked in by sjboddie, 25 years ago

added GPL notice

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 29.5 KB
Line 
1/**********************************************************************
2 *
3 * browsetools.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * $Id: browsetools.cpp 533 1999-09-07 04:57:01Z sjboddie $
25 *
26 *********************************************************************/
27
28/*
29 $Log$
30 Revision 1.21 1999/09/07 04:56:52 sjboddie
31 added GPL notice
32
33 Revision 1.20 1999/08/25 04:46:58 sjboddie
34 fixed bug
35
36 Revision 1.19 1999/08/13 04:18:04 sjboddie
37 fixed some typos
38
39 Revision 1.18 1999/08/10 22:42:21 sjboddie
40 added more format options to document tocs - there are now just two
41 types of toc - standard (Hierarchical) and document (as in books)
42
43 Revision 1.17 1999/08/09 02:12:07 sjboddie
44 made it so dates may be only 4 digits (i.e. year only)
45
46 Revision 1.16 1999/07/30 02:16:10 sjboddie
47 -added ability to display nested classifications (expanded versions
48 of nested classifications has yet to be done).
49 -changed set_arrow_macros slightly to fit in with new showtoppage
50 format option
51
52 Revision 1.15 1999/07/21 05:01:56 sjboddie
53 wrote handler for DateList classification
54
55 Revision 1.14 1999/07/20 02:58:15 sjboddie
56 got List and AZList classifications using format strings - tidied
57 up a bit
58
59 Revision 1.13 1999/07/07 05:44:25 sjboddie
60 Made some changes to allow for new way classifiers work (i.e. you can
61 now have classifiers containing other classifiers). At present there's
62 only a special case for dealing with the hdl 'magazine' section. A bit
63 of a redesign is needed to get it completely flexible
64
65 Revision 1.12 1999/07/01 03:47:49 rjmcnab
66 Fixed a small warning.
67
68 Revision 1.11 1999/06/27 21:49:01 sjboddie
69 fixed a couple of version conflicts - tidied up some small things
70
71 Revision 1.10 1999/06/26 01:07:21 rjmcnab
72 Fixed a small "bug" -- well I probably just covered another one...
73
74 Revision 1.9 1999/06/24 05:12:15 sjboddie
75 lots of small changes
76
77 Revision 1.8 1999/06/17 03:06:53 sjboddie
78 got detach button working properly - the close book icon is now disabled
79 when page is detached as the javascript close() function I was using is
80 too unreliable over different browsers
81 note that in my last comment I meant the "cl" arg (not the "c" arg).
82
83 Revision 1.7 1999/06/16 23:53:14 sjboddie
84 tidied a few things up. documentaction::define_external_macros now
85 resets the "c" arg if it's set to something stupid by the .xx suffixes
86
87 Revision 1.6 1999/06/16 04:03:47 sjboddie
88 Now sets "cl" arg to "search" when going to a document from a search
89 results page. This allows the close book icon (in hierarchy toc) to
90 take you back to the results page if that's where you came from.
91 If you got to the document page somehow other than from a
92 classification or a search (i.e. if "cl" isn't set) then the close
93 book icon is disabled
94
95 Revision 1.5 1999/06/16 03:11:25 sjboddie
96 get_info() now takes a getParents argument
97
98 Revision 1.4 1999/05/10 03:40:26 sjboddie
99 lots of changes - slowly getting document action sorted out
100
101 Revision 1.3 1999/04/30 01:59:39 sjboddie
102 lots of stuff - getting documentaction working (documentaction replaces
103 old browseaction)
104
105 Revision 1.2 1999/03/29 02:14:29 sjboddie
106
107 More changes to browseaction
108
109 Revision 1.1 1999/03/25 03:10:15 sjboddie
110
111 new library for browse stuff
112
113 */
114
115
116#include "browsetools.h"
117#include "OIDtools.h"
118
119// simply checks to see if formatstring begins with a <td> tag
120static bool is_table_content (const text_t &formatstring) {
121 text_t::const_iterator here = formatstring.begin();
122 text_t::const_iterator end = formatstring.end();
123
124 while (here != end) {
125 if (*here != ' ') {
126 if (*here == '<') {
127 if ((*(here+1) == 't' || *(here+1) == 'T') &&
128 (*(here+2) == 'd' || *(here+2) == 'D') &&
129 (*(here+3) == '>' || *(here+3) == ' '))
130 return true;
131 } else return false;
132 }
133 here ++;
134 }
135 return false;
136}
137
138static bool is_table_content (const format_t *formatlistptr) {
139
140 if (formatlistptr == NULL) return false;
141
142 if (formatlistptr->command == comText)
143 return is_table_content (formatlistptr->text);
144
145 return false;
146}
147
148
149// output_controls displays the detach, expand/contract contents,
150// expand/contract text and highlighting/no highlighting buttons
151static void output_controls (cgiargsclass &args, const text_tarray &ibuttons,
152 recptproto */*collectproto*/, displayclass &disp,
153 outconvertclass &outconvert, ostream &textout,
154 ostream &/*logout*/) {
155
156 if (args["u"] != "1") {
157
158 FilterResponse_t response;
159 text_tarray metadata;
160 text_tarray buttons;
161
162 text_tarray::const_iterator here = ibuttons.begin();
163 text_tarray::const_iterator end = ibuttons.end();
164
165 while (here != end) {
166
167 if (*here == "Detach")
168 buttons.push_back ("_document:imagedetach_");
169 else if (*here == "Highlight") {
170 if (args["hl"] == "1")
171 buttons.push_back ("_document:imagenohighlight_");
172 else
173 buttons.push_back ("_document:imagehighlight_");
174 } else if (*here == "Expand Contents") {
175 if (args["gc"] == "1")
176 buttons.push_back ("_document:imagecontracttoc_");
177 else
178 buttons.push_back ("_document:imageexpandtoc_");
179 } else if (*here == "Expand Text") {
180 if (args.getintarg("gt"))
181 buttons.push_back ("_document:imagecontracttext_");
182 else
183 buttons.push_back ("_document:imageexpandtext_");
184 }
185 here ++;
186 }
187
188 here = buttons.begin();
189 end = buttons.end();
190 int count = 0;
191 while (here != end) {
192 if ((count != 0) && ((count % 3) == 0)) textout << "<br>\n";
193 textout << outconvert << disp << *here;
194 count ++;
195 here ++;
196 }
197 }
198}
199
200
201// at the moment this just writes out the html to display
202// the cover image (assuming it's called cover.jpg)
203// this whole thing should be done with a call to the collection
204// server which would send a link to the cover image if there
205// was one otherwise send title, author and stuff
206static void output_cover_image (cgiargsclass &args, recptproto */*collectproto*/,
207 displayclass &disp, outconvertclass &outconvert,
208 ostream &textout, ostream &/*logout*/) {
209
210 if (args["d"].empty()) return;
211
212 textout << outconvert << disp <<
213 "<img src=\"_httpcollection_/archives/_thisOID_/cover.jpg\"><br>\n";
214}
215
216
217
218/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
219Functions for generating a document type tables of contents. These aren't really tables of
220contents at all, just a title, some navigation buttons and arrows and maybe a page ? of ?
221type thing. These should only be called for document level tocs (i.e. when the "d" argument
222is set) as I don't think it makes sense to display top level classifications in this way.
223-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
224
225void output_document_toc (cgiargsclass &args, const formatinfo_t &formatinfo,
226 recptproto *collectproto, displayclass &disp,
227 outconvertclass &outconvert, ostream &textout,
228 ostream &logout) {
229
230 text_t &arg_d = args["d"];
231 if (arg_d.empty()) return;
232
233 text_tarray metadata;
234 FilterResponse_t response;
235 bool getParents = false;
236 ResultDocInfo_t docinfo;
237 text_t &collection = args["c"];
238 int gt = args.getintarg("gt");
239
240 bool istop = is_top (arg_d);
241
242 format_t *formatlistptr = new format_t();
243 parse_formatstring (formatinfo.DocumentHeading, formatlistptr, metadata, getParents);
244
245 text_tarray OIDs;
246 OIDs.push_back (arg_d);
247 if (formatinfo.DocumentArrowsTop && !gt && !istop)
248 OIDs.push_back (arg_d + ".pr.lc");
249
250 metadata.push_back ("Title");
251 int metasize = metadata.size();
252
253 if (get_info (OIDs, collection, metadata, getParents, collectproto, response, logout)) {
254
255 text_t &thistitle = response.docInfo[0].metadata[metasize-1].values.back();
256 text_t last_sib_title;
257 if (formatinfo.DocumentArrowsTop && !gt && !istop) {
258 if (response.docInfo.size() == 1)
259 last_sib_title = response.docInfo[0].metadata[metasize-1].values.back();
260 else
261 last_sib_title = response.docInfo[1].metadata[metasize-1].values.back();
262 }
263
264 textout
265 << "\n<!-- Table of Contents produced by browsetools::output_document_toc -->\n\n";
266
267 textout << outconvert << disp
268 << "<p><center>\n"
269 << "<table cellpadding=0 cellspacing=0 width=_pagewidth_>\n"
270 << "<tr valign=top><td>\n";
271
272 // top arrows and page ? of ? title
273 if (formatinfo.DocumentArrowsTop && !gt) {
274
275 // previous arrow
276 textout << outconvert << disp << "<table><tr valign=top>\n"
277 << "<td align=left>_document:prevarrow_</td>\n";
278
279 // page ? of ? text
280 textout << "<td align=center>\n";
281
282 if (!istop && is_number (thistitle) && is_number (last_sib_title))
283 textout << outconvert << disp << "_document:page_" << thistitle
284 << "_document:of_" << last_sib_title;
285
286 else
287 textout << outconvert << thistitle;
288
289 // next arrow
290 textout << outconvert << disp << "</td>\n<td align=right>_document:nextarrow_</td>\n</table>\n";
291 }
292
293 // goto line
294 if (formatinfo.DocumentGoTo)
295 textout << outconvert << disp << "_document:gotoform_";
296
297 // control buttons
298 output_controls (args, formatinfo.DocumentButtons, collectproto,
299 disp, outconvert, textout, logout);
300 textout << "</td>\n";
301
302 // heading
303 textout << outconvert << "\n<td valign=top>\n"
304 << get_formatted_string (response.docInfo[0], formatlistptr);
305
306 textout << "</td></tr></table></center>\n";
307 textout << "\n<!-- end of Table of Contents -->\n";
308 }
309}
310
311
312/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
313Functions for generating a "Hierarchy" type table of contents. These can be used either
314at top classification level or at document level (the difference being that a cover
315image and control buttons may be displayed at document level).
316-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
317
318// prototypes
319
320static void output_contracted_hierarchy_toc (const text_t &classifytype, text_t &formatstring,
321 cgiargsclass &args, recptproto *collectproto,
322 displayclass &disp, outconvertclass &outconvert,
323 ostream &textout, ostream &logout);
324
325static void output_expanded_hierarchy_toc (cgiargsclass &args, recptproto *collectproto,
326 displayclass &disp, outconvertclass &outconvert,
327 ostream &textout, ostream &logout);
328
329static void output_parents_toc (cgiargsclass &args, const FilterResponse_t &parents,
330 int &tabcount, displayclass &disp,
331 format_t *formatlistptr, outconvertclass &outconvert,
332 ostream &textout, ostream &logout);
333
334static void output_siblings_toc (const text_t &classifytype, cgiargsclass &args,
335 const FilterResponse_t &siblings, int &tabcount,
336 displayclass &disp, format_t *formatlistptr,
337 outconvertclass &outconvert, ostream &textout,
338 ostream &logout);
339
340static void output_stdlist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
341 ResultDocInfo_tarray::const_iterator &end, bool intable,
342 displayclass &disp, format_t *formatlistptr,
343 outconvertclass &outconvert, ostream &textout);
344
345static void output_datelist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
346 ResultDocInfo_tarray::const_iterator &end, bool intable,
347 displayclass &disp, format_t *formatlistptr,
348 outconvertclass &outconvert, ostream &textout);
349
350
351void output_standard_toc (const text_t &classifytype, const formatinfo_t &formatinfo,
352 text_t &formatstring, cgiargsclass &args,
353 recptproto *collectproto, displayclass &disp,
354 outconvertclass &outconvert, ostream &textout,
355 ostream &logout) {
356
357 bool havecontrols = false;
358
359 textout << "\n<!-- Table of Contents produced by browsetools::output_standard_toc -->\n\n";
360
361 // get the cover image (if there is one) and the control buttons
362 // if we're inside a book
363 if (!args["d"].empty()) {
364 textout << "<p><table cellpadding=0 cellspacing=0><tr>\n";
365 textout << "<td valign=top width=200>\n";
366 if (formatinfo.DocumentImages)
367 output_cover_image (args, collectproto, disp, outconvert, textout, logout);
368 output_controls (args, formatinfo.DocumentButtons, collectproto, disp,
369 outconvert, textout, logout);
370 textout << "</td><td valign=top>\n";
371 havecontrols = true;
372 }
373
374 // get table of contents
375 textout << "<table>\n";
376
377 if (args.getintarg("gc"))
378 output_expanded_hierarchy_toc(args, collectproto, disp, outconvert, textout, logout);
379 else
380 output_contracted_hierarchy_toc(classifytype, formatstring, args, collectproto,
381 disp, outconvert, textout, logout);
382
383 textout << "</table>\n";
384
385 if (havecontrols) textout << "</td></tr></table>\n";
386
387 textout << "\n<!-- end of Table of Contents -->\n";
388}
389
390
391void output_contracted_hierarchy_toc (const text_t &classifytype, text_t &formatstring,
392 cgiargsclass &args, recptproto *collectproto,
393 displayclass &disp, outconvertclass &outconvert,
394 ostream &textout, ostream &logout) {
395
396 int tabcount = 0;
397 text_tarray parents, metadata;
398 FilterResponse_t fsiblings, fparents;
399 bool getParents = false;
400
401 text_t &arg_d = args["d"];
402 text_t OID = arg_d;
403 if (OID.empty()) OID = args["cl"];
404 text_t &collection = args["c"];
405
406 // if format string is empty use the default
407 if (formatstring.empty())
408 formatstring = "<td valign=top nowrap>[link][icon][/link]</td><td>{Or}{[Title],Untitled}</td>";
409
410 format_t *formatlistptr = new format_t();
411 parse_formatstring (formatstring, formatlistptr, metadata, getParents);
412
413 metadata.push_back ("Date");
414 metadata.push_back ("hastxt");
415 metadata.push_back ("haschildren");
416 metadata.push_back ("doctype");
417 metadata.push_back ("classifytype");
418
419 if (has_children (OID, collection, collectproto, logout)) {
420 get_parents_array (OID + ".fc", parents);
421
422 if (!get_children (OID, collection, metadata, getParents,
423 collectproto, fsiblings, logout))
424 return;
425 } else {
426 get_parents_array (OID, parents);
427 if (!get_children (OID + ".pr", collection, metadata,
428 getParents, collectproto, fsiblings, logout))
429 return;
430 }
431 if (!get_info (parents, collection, metadata, false, collectproto, fparents, logout)) return;
432
433 if (!fparents.docInfo.empty())
434 output_parents_toc(args, fparents, tabcount, disp,
435 formatlistptr, outconvert, textout, logout);
436
437 if (!fsiblings.docInfo.empty())
438 output_siblings_toc (classifytype, args, fsiblings, tabcount, disp,
439 formatlistptr, outconvert, textout, logout);
440}
441
442void output_parents_toc (cgiargsclass &args, const FilterResponse_t &parents,
443 int &tabcount, displayclass &disp,
444 format_t *formatlistptr, outconvertclass &outconvert,
445 ostream &textout, ostream &/*logout*/) {
446
447 text_t tab, icon;
448 text_t &arg_cl = args["cl"];
449 text_t &arg_d = args["d"];
450 int numcols = parents.docInfo.size() + 1;
451
452 bool intable = is_table_content (formatlistptr);
453
454 ResultDocInfo_tarray::const_iterator thisparent = parents.docInfo.begin();
455 ResultDocInfo_tarray::const_iterator end = parents.docInfo.end();
456
457 int len = (*thisparent).metadata.size();
458 const text_t &classifytype = (*thisparent).metadata[len-1].values[0];
459
460 // don't want top level of any classifications to be displayed
461 if (arg_d.empty() && thisparent != end) {thisparent ++; numcols --;}
462
463 // don't want second level of classifications using classification links
464 if ((classifytype == "AZList" || classifytype == "DateList") && (thisparent != end))
465 {thisparent ++; numcols --;}
466
467 // the tab line
468 if (thisparent != end) {
469 text_t coltabs;
470 for (int i = 0; i < numcols; i ++) coltabs += "_document:tab_";
471 textout << outconvert << disp << "<tr>" << coltabs << "<td></td></tr>\n";
472 }
473
474 while (thisparent != end) {
475
476 const text_t &doctype = (*thisparent).metadata[len-2].values.back();
477
478 // set up icon and pointer
479 icon = "_document:icon";
480 if ((doctype != "classify") && ((*thisparent).OID == arg_d))
481 icon += "arrow";
482 if (doctype == "classify") icon += "openbookshelf_";
483 else if (is_top((*thisparent).OID)) icon += "openbook_";
484 else icon += "openfolder_";
485
486 if (tabcount == 1) textout << "<td></td>\n";
487 else if (tabcount > 1) textout << "<td colspan=" << tabcount << "></td>";
488
489 // set up the link
490 text_t link = "<a href=\"_httpdocument_";
491 if (is_top((*thisparent).OID) && args.getintarg("x")) link = "<a name=top>";
492 else
493 if (doctype == "classify") link += "&cl=" + (*thisparent).OID + ".pr\">";
494 else
495 if (is_top ((*thisparent).OID))
496 if (arg_cl.empty())
497 link = "<a name=top>";
498 else if (arg_cl == "search")
499 link = "<a href=\"_httpquery_\">";
500 else
501 link += "&cl=" + arg_cl + "\">";
502 else link += "&cl=" + arg_cl + "&d=" + (*thisparent).OID + ".pr\">";
503
504 if ((numcols-tabcount) == 1) textout << "<td>";
505 else if ((numcols-tabcount) > 1) textout << "<td colspan="
506 << (numcols-tabcount) << ">";
507
508 if (intable) textout << "<table><tr>";
509
510 textout << outconvert << disp
511 << get_formatted_string (*thisparent, formatlistptr, link, icon);
512
513 if (intable) textout << "</tr></table>";
514 textout << "</td></tr>\n";
515
516 tabcount ++;
517 thisparent ++;
518 }
519}
520
521
522void output_siblings_toc (const text_t &classifytype, cgiargsclass &args,
523 const FilterResponse_t &siblings, int &tabcount,
524 displayclass &disp, format_t *formatlistptr,
525 outconvertclass &outconvert, ostream &textout,
526 ostream &/*logout*/) {
527
528 bool intable = is_table_content (formatlistptr);
529
530 ResultDocInfo_tarray::const_iterator thissibling = siblings.docInfo.begin();
531 ResultDocInfo_tarray::const_iterator sibend = siblings.docInfo.end();
532
533 if (thissibling == sibend) return;
534
535 // tabbing
536 if (tabcount) {
537 if (tabcount == 1) textout << "<tr><td></td>\n";
538 else if (tabcount > 1) textout << "<tr><td colspan=" << tabcount << "></td>";
539 textout << "<td><table>\n";
540 }
541
542 if (!intable) textout << "<tr><td>\n";
543
544 if (classifytype == "DateList")
545 output_datelist (args, thissibling, sibend, intable, disp,
546 formatlistptr, outconvert, textout);
547 else
548 output_stdlist (args, thissibling, sibend, intable, disp,
549 formatlistptr, outconvert, textout);
550
551 if (!intable) textout << "</td></tr></table>\n";
552 if (tabcount) textout << "</table></td></tr>\n";
553}
554
555void output_stdlist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
556 ResultDocInfo_tarray::const_iterator &end, bool intable,
557 displayclass &disp, format_t *formatlistptr,
558 outconvertclass &outconvert, ostream &textout) {
559
560 text_t icon;
561 int count = 1;
562 int gt = args.getintarg("gt");
563 text_t &arg_cl = args["cl"];
564 text_t &arg_d = args["d"];
565
566 while (here != end) {
567
568 int len = (*here).metadata.size();
569 const text_t &doctype = (*here).metadata[len-2].values.back();
570 const text_t &hastxt = (*here).metadata[len-4].values.back();
571 const text_t &haschildren = (*here).metadata[len-3].values.back();
572
573 // set up icon and pointer
574 icon = "_document:icon";
575 if (doctype == "classify") {
576 if (((*here).OID == arg_cl) && (hastxt == "1"))
577 icon += "arrow";
578 } else if ((*here).OID == arg_d) icon += "arrow";
579
580 if (haschildren == "0") icon += "smalltext_";
581 else if (doctype == "classify") icon += "closedbookshelf_";
582 else if (is_top((*here).OID)) icon += "closedbook_";
583 else icon += "closedfolder_";
584
585 // set up link
586 text_t link = "<a href=\"_httpdocument_";
587 if (doctype == "classify") link += "&cl=" + (*here).OID + "\">";
588 else link += "&cl=" + arg_cl + "&d=" + (*here).OID + "\">";
589 if (gt) {
590 link = "<a href=\"#" + text_t(count) + "\">";
591 count ++;
592 }
593
594 if (intable) textout << "<tr>";
595
596 textout << outconvert << disp
597 << get_formatted_string (*here, formatlistptr, link, icon) << "\n";
598
599 if (intable) textout << "</tr>";
600
601 here ++;
602 }
603}
604
605
606void output_datelist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
607 ResultDocInfo_tarray::const_iterator &end, bool intable,
608 displayclass &disp, format_t *formatlistptr,
609 outconvertclass &outconvert, ostream &textout) {
610
611 text_t lastyear = "0000";
612 text_t lastmonth = "00";
613
614 while (here != end) {
615
616 int len = (*here).metadata.size();
617 const text_t &doctype = (*here).metadata[len-2].values.back();
618 const text_t &date = (*here).metadata[len-5].values.back();
619
620 // bail on this document if it has no date
621 if (date.empty()) continue;
622
623 text_t::const_iterator datebegin = date.begin();
624 int datesize = date.size();
625
626 if (datesize < 4) continue;
627 text_t thisyear = substr (datebegin, datebegin+4);
628 text_t thismonth = "00";
629 if (datesize >= 6)
630 thismonth = substr (datebegin+4, datebegin+6);
631
632 text_t link = "<a href=\"_httpdocument_&cl=";
633 text_t icon = "_document:iconclosedbook_";
634
635 if (doctype == "classify") {
636 icon = "_document:iconclosedbookshelf_";
637 link += (*here).OID + "\">";
638 } else link += args["cl"] + "&d=" + (*here).OID + "\">";
639
640 textout << "<tr>\n";
641
642 if (thisyear != lastyear) {
643 textout << outconvert << "<td><b>" << thisyear << "</b></td>";
644 lastyear = thisyear;
645 } else
646 textout << "<td></td>";
647
648 if (thismonth != lastmonth) {
649 textout << outconvert << disp << ("<td><b>_textmonth" + thismonth + "_</b></td>");
650 lastmonth = thismonth;
651 } else
652 textout << "<td></td>";
653
654 if (!intable) textout << "<td>\n";
655
656 textout << outconvert << disp
657 << get_formatted_string (*here, formatlistptr, link, icon) << "\n";
658
659 if (!intable) textout << "</td>";
660
661 textout << "</tr>\n";
662
663 here ++;
664 }
665}
666
667void output_expanded_hierarchy_toc (cgiargsclass &args, recptproto *collectproto,
668 displayclass &disp, outconvertclass &outconvert,
669 ostream &textout, ostream &logout) {
670
671 text_t OID, topOID, classifytype, icon;
672 FilterResponse_t response;
673 int tabcols=0, totalcols=0, lasttabcols=0;
674
675 int gt = args.getintarg("gt");
676 text_t doclink = "<a href=\"_httpdocument_&cl=";
677
678 text_t &arg_d = args["d"];
679 text_t &arg_cl = args["cl"];
680
681 if (arg_d.empty()) {
682 if (arg_cl.empty()) return;
683 OID = arg_cl;
684 topOID = OID; // don't always want to expand from top if expanding classifications
685 classifytype = "classify";
686 } else {
687 OID = arg_d;
688 get_top (arg_d, topOID);
689 classifytype = "Document";
690 }
691
692 // Get OIDs and metadata of all topOIDs contents (and topOID itself)
693 text_tarray metadata;
694 metadata.push_back ("Title");
695 metadata.push_back ("haschildren");
696 metadata.push_back ("doctype");
697 // metadata.push_back ("hastxt");
698
699 get_contents (topOID, classifytype, metadata, totalcols,
700 args["c"], collectproto, response, logout);
701 int excess = countchar (topOID.begin(), topOID.end(), '.');
702 totalcols -= excess;
703
704 // allow for pointer
705 if (classifytype == "Document" && !gt) totalcols += 2;
706 else totalcols += 1;
707
708 ResultDocInfo_tarray::const_iterator thissection = response.docInfo.begin();
709 ResultDocInfo_tarray::const_iterator lastsection = response.docInfo.end();
710
711 int count = 1;
712 while (thissection != lastsection) {
713
714 const text_t &title = (*thissection).metadata[0].values[0];
715 const int haschildren = (*thissection).metadata[1].values[0].getint();
716 const text_t &doctype = (*thissection).metadata[2].values[0];
717
718 text_t icontabs, tab, pointer;
719
720 // set up icon
721 icon = "_document:iconsmalltext_";
722 if (is_top((*thissection).OID))
723 if (classifytype == "Document") icon = "_document:iconopenbook_";
724 else
725 if (doctype == "classify") icon = "_document:iconopenbookshelf_";
726 else icon = "_document:iconclosedbook_";
727 else if (haschildren)
728 if (classifytype == "Document") icon = "_document:iconopenfolder_";
729 else icon = "_document:iconopenbookshelf_";
730
731 // set up tabbing
732 if ((classifytype == "classify") && (doctype != "classify"))
733 tabcols = lasttabcols + 1;
734 else {
735 tabcols = countchar ((*thissection).OID.begin(), (*thissection).OID.end(), '.');
736 lasttabcols = tabcols;
737 }
738 tabcols -= excess;
739
740 for (int i = 0; i < tabcols; i++)
741 icontabs += "_document:icontab_";
742
743 // set up pointer
744 if (classifytype == "Document" && !gt) {
745 if ((*thissection).OID == OID) pointer = "_document:iconpointer_";
746 else pointer = "_document:icontab_";
747 tabcols ++;
748 }
749
750 int colsremaining = totalcols - tabcols;
751
752 if (tabcols > 0) {
753 tab = "<td";
754 if (tabcols > 1) tab += " colspan=" + text_t(tabcols);
755 tab += ">" + icontabs + pointer + "</td>";
756 }
757
758 textout << outconvert << disp << "<tr>" << tab << "<td>";
759
760 if ((classifytype == "Document") && (is_top((*thissection).OID)) &&
761 (args.getintarg("x")))
762 textout << outconvert << disp << icon << "</td><td";
763
764 else {
765 if (!gt) {
766 const text_t &thisOID = (*thissection).OID;
767 text_t link;
768 if (is_top (thisOID))
769 if (classifytype == "classify")
770 link = doclink + arg_cl + "&d=" + thisOID + "\">";
771 else
772 if (arg_cl.empty())
773 link.clear();
774 else if (arg_cl == "search")
775 link = "<a href=\"_httpquery_\">";
776 else
777 link = doclink + arg_cl + "\">";
778 else
779 if (haschildren)
780 if (classifytype == "classify")
781 link = doclink + thisOID + ".pr\">";
782 else
783 link = doclink + arg_cl + "&d=" + thisOID + ".pr\">";
784 else
785 if (classifytype == "classify")
786 link = doclink + thisOID + "\">";
787 else
788 link = doclink + arg_cl + "&d=" + thisOID + "\">";
789
790 textout << outconvert << disp << link;
791 } else {
792 textout << "<a href=\"#" << count << "\">";
793 count ++;
794 }
795
796 textout << outconvert << disp << icon << "</a></td><td";
797 }
798 if (colsremaining > 1) textout << " colspan=" << colsremaining;
799 textout << outconvert << disp << ">" << title << "</td></tr>\n";
800
801 thissection ++;
802 }
803}
804
805/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
806-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
807
808// set_arrow_macros sets the _httpprevarrow_ and _httpnextarrow_ macros
809// it shouldn't be called if OID is the top level of a book
810// as the "hasprevious" and "hasnext" metadata won't be set
811// when the filter can't get OIDs parent info - one day I'll
812// fix this ;-)
813void set_arrow_macros (const text_t &OID, const text_t &classifytype,
814 bool showtoppage, displayclass &disp,
815 recptproto *collectproto, const text_t &collection,
816 ostream &logout) {
817
818 if (OID.empty()) return;
819
820 text_tarray metadata;
821 FilterResponse_t response;
822
823 metadata.push_back ("haschildren");
824 metadata.push_back ("hasnext");
825 metadata.push_back ("hasprevious");
826 // get "haschildren", "hasnext" and "hasprevious" metadata for OID
827 if (get_info (OID, collection, metadata, false, collectproto, response, logout)) {
828
829 text_t haschildren = response.docInfo[0].metadata[0].values[0];
830 text_t hasnext = response.docInfo[0].metadata[1].values[0];
831 text_t hasprevious = response.docInfo[0].metadata[2].values[0];
832
833 if ((classifytype == "Hierarchy") || (classifytype == "Book")) {
834 if (haschildren == "1")
835 disp.setmacro ("httpnextarrow", "document",
836 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.fc,_httpdocument_&cl=_cgiargcl_.fc)");
837 else if (hasnext == "1")
838 disp.setmacro ("httpnextarrow", "document",
839 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ns,_httpdocument_&cl=_cgiargcl_.ns)");
840 else {
841 // see if parent has younger siblings
842 if (get_info (OID + ".pr", collection, metadata, false, collectproto, response, logout)) {
843 if (!response.docInfo[0].metadata.empty() &&
844 response.docInfo[0].metadata[1].values[0] == "1")
845 disp.setmacro ("httpnextarrow", "document",
846 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.pr.ns,_httpdocument_&cl=_cgiargcl_.pr.ns)");
847 }
848 }
849
850 if (hasprevious == "1") {
851 // see if OIDs older sibling has children
852 if (get_info (OID + ".ps", collection, metadata, false, collectproto, response, logout)) {
853 if (response.docInfo[0].metadata[0].values[0] == "1")
854 disp.setmacro ("httpprevarrow", "document",
855 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ps.lc,_httpdocument_&cl=_cgiargcl_.ps.lc)");
856 else
857 disp.setmacro ("httpprevarrow", "document",
858 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ps,_httpdocument_&cl=_cgiargcl_.ps)");
859 }
860 } else if (showtoppage && !is_top (OID))
861 disp.setmacro ("httpprevarrow", "document",
862 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.pr,_httpdocument_&cl=_cgiargcl_.pr)");
863 }
864
865 else {
866 if (hasnext == "1")
867 disp.setmacro ("httpnextarrow", "document",
868 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ns,_httpdocument_&cl=_cgiargcl_.ns)");
869 if (hasprevious == "1")
870 disp.setmacro ("httpprevarrow", "document",
871 "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ps,_httpdocument_&cl=_cgiargcl_.ps)");
872 }
873 }
874}
Note: See TracBrowser for help on using the repository browser.