/********************************************************************** * * browsetools.cpp -- * Copyright (C) 1999 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: browsetools.cpp 649 1999-10-10 08:14:12Z sjboddie $ * *********************************************************************/ /* $Log$ Revision 1.25 1999/10/10 08:14:04 sjboddie - metadata now returns mp rather than array - redesigned browsing support (although it's not finished so won't currently work ;-) Revision 1.24 1999/09/28 01:46:55 rjmcnab removed some unused stuff Revision 1.23 1999/09/23 10:09:17 sjboddie made some changes so AZLists within other classifications are handled properly Revision 1.22 1999/09/07 23:06:58 rjmcnab removed some compiler warnings. Revision 1.21 1999/09/07 04:56:52 sjboddie added GPL notice Revision 1.20 1999/08/25 04:46:58 sjboddie fixed bug Revision 1.19 1999/08/13 04:18:04 sjboddie fixed some typos Revision 1.18 1999/08/10 22:42:21 sjboddie added more format options to document tocs - there are now just two types of toc - standard (Hierarchical) and document (as in books) Revision 1.17 1999/08/09 02:12:07 sjboddie made it so dates may be only 4 digits (i.e. year only) Revision 1.16 1999/07/30 02:16:10 sjboddie -added ability to display nested classifications (expanded versions of nested classifications has yet to be done). -changed set_arrow_macros slightly to fit in with new showtoppage format option Revision 1.15 1999/07/21 05:01:56 sjboddie wrote handler for DateList classification Revision 1.14 1999/07/20 02:58:15 sjboddie got List and AZList classifications using format strings - tidied up a bit Revision 1.13 1999/07/07 05:44:25 sjboddie Made some changes to allow for new way classifiers work (i.e. you can now have classifiers containing other classifiers). At present there's only a special case for dealing with the hdl 'magazine' section. A bit of a redesign is needed to get it completely flexible Revision 1.12 1999/07/01 03:47:49 rjmcnab Fixed a small warning. Revision 1.11 1999/06/27 21:49:01 sjboddie fixed a couple of version conflicts - tidied up some small things Revision 1.10 1999/06/26 01:07:21 rjmcnab Fixed a small "bug" -- well I probably just covered another one... Revision 1.9 1999/06/24 05:12:15 sjboddie lots of small changes Revision 1.8 1999/06/17 03:06:53 sjboddie got detach button working properly - the close book icon is now disabled when page is detached as the javascript close() function I was using is too unreliable over different browsers note that in my last comment I meant the "cl" arg (not the "c" arg). Revision 1.7 1999/06/16 23:53:14 sjboddie tidied a few things up. documentaction::define_external_macros now resets the "c" arg if it's set to something stupid by the .xx suffixes Revision 1.6 1999/06/16 04:03:47 sjboddie Now sets "cl" arg to "search" when going to a document from a search results page. This allows the close book icon (in hierarchy toc) to take you back to the results page if that's where you came from. If you got to the document page somehow other than from a classification or a search (i.e. if "cl" isn't set) then the close book icon is disabled Revision 1.5 1999/06/16 03:11:25 sjboddie get_info() now takes a getParents argument Revision 1.4 1999/05/10 03:40:26 sjboddie lots of changes - slowly getting document action sorted out Revision 1.3 1999/04/30 01:59:39 sjboddie lots of stuff - getting documentaction working (documentaction replaces old browseaction) Revision 1.2 1999/03/29 02:14:29 sjboddie More changes to browseaction Revision 1.1 1999/03/25 03:10:15 sjboddie new library for browse stuff */ #include "browsetools.h" #include "OIDtools.h" // simply checks to see if formatstring begins with a tag static bool is_table_content (const text_t &formatstring) { text_t::const_iterator here = formatstring.begin(); text_t::const_iterator end = formatstring.end(); while (here != end) { if (*here != ' ') { if (*here == '<') { if ((*(here+1) == 't' || *(here+1) == 'T') && (*(here+2) == 'd' || *(here+2) == 'D') && (*(here+3) == '>' || *(here+3) == ' ')) return true; } else return false; } here ++; } return false; } static bool is_table_content (const format_t *formatlistptr) { if (formatlistptr == NULL) return false; if (formatlistptr->command == comText) return is_table_content (formatlistptr->text); return false; } // expects haschidren, doctype, and classifytype metadata elements static void recurse_contents (ResultDocInfo_t §ion, cgiargsclass &args, browserclass *bptr, text_tset &metadata, bool &getParents, format_t *formatlistptr, format_tmap &formatlistmap, formatinfo_t &formatinfo, browsermapclass *browsermap, int colnumber, recptproto *collectproto, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &logout) { text_t formatstring; bool is_classify = false; if (args["d"].empty()) is_classify = true; // output this section bool use_table = is_table_content (formatlistptr); colnumber += bptr->output_section_group (section, args, colnumber, formatlistptr, use_table, disp, outconvert, textout, logout); text_t classification; if (!is_classify) classification = "Document"; else get_top (section.OID, classification); int haschildren = section.metadata["haschildren"].values[0].getint(); const text_t &doctype = section.metadata["doctype"].values[0]; text_t classifytype = section.metadata["classifytype"].values[0]; // HLists are displayed as VLists when contents are expanded, // Books are displayed as HLists if (classifytype == "HList") classifytype = "VList"; if (classifytype == "Book") classifytype = "HList"; // recurse through children if ((haschildren == 1) && ((!is_classify) || (doctype == "classify"))) { // get browser for displaying children bptr = browsermap->getbrowser (classifytype); bptr->load_metadata_defaults (metadata); // get the formatstring if there is one if (!get_formatstring (classification, classifytype, formatinfo.formatstrings, formatstring)) formatstring = bptr->get_default_formatstring(); format_tmap::const_iterator it = formatlistmap.find (formatstring); // check if formatlistptr is cached if (it != formatlistmap.end()) formatlistptr = (*it).second; else { formatlistptr = new format_t(); parse_formatstring (formatstring, formatlistptr, metadata, getParents); formatlistmap[formatstring] = formatlistptr; } FilterResponse_t tmp; get_children (section.OID, args["c"], metadata, getParents, collectproto, tmp, logout); ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin(); ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end(); while (thisdoc != lastdoc) { recurse_contents (*thisdoc, args, bptr, metadata, getParents, formatlistptr, formatlistmap, formatinfo, browsermap, colnumber, collectproto, disp, outconvert, textout, logout); thisdoc ++; } } } // expanded_contents recurses through all contents. there's a special case // for an HList when contents are expanded (i.e. it's displayed as a VList) // // if we're inside a document we expand all contents from the top, // if we're at classification level we'll just expand out those contents below // the current one static void expanded_contents (cgiargsclass &args, browsermapclass *browsermap, formatinfo_t &formatinfo, recptproto *collectproto, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &logout) { if (args["d"].empty() && args["cl"].empty()) return; text_t OID; FilterResponse_t response; bool getParents = false; text_tset metadata; text_t classifytype, classification, formatstring; int colnumber = 0; if (!args["d"].empty()) { // document level - expand from top get_top (args["d"], OID); classification = "Document"; } else { // classification level OID = args["cl"]; get_top (args["cl"], classification); } // get classifytype of this level text_t tOID; if (is_top(OID)) { classifytype = "thistype"; tOID = OID; } else { classifytype = "childtype"; tOID = get_parent (OID); } metadata.insert (classifytype); if (!get_info (tOID, args["c"], metadata, getParents, collectproto, response, logout)) return; classifytype = response.docInfo[0].metadata[classifytype].values[0]; // if we still don't have a classifytype we'll use the default if (classifytype.empty()) { browserclass *bptr = browsermap->get_default_browser (); classifytype = bptr->get_browser_name (); } // HLists are displayed as VLists when contents are expanded, // Books are displayed as HLists if (classifytype == "HList") classifytype = "VList"; if (classifytype == "Book") classifytype = "HList"; metadata.erase (metadata.begin(), metadata.end()); // metadata elements needed by recurse_contents metadata.insert ("classifytype"); metadata.insert ("doctype"); metadata.insert ("haschildren"); // load up metadata array with browser defaults browserclass *bptr = browsermap->getbrowser (classifytype); bptr->load_metadata_defaults (metadata); // get the formatstring if there is one or use the browsers default if (!get_formatstring (classification, classifytype, formatinfo.formatstrings, formatstring)) formatstring = bptr->get_default_formatstring(); format_t *formatlistptr = new format_t(); parse_formatstring (formatstring, formatlistptr, metadata, getParents); // protocol call if (!get_info (OID, args["c"], metadata, getParents, collectproto, response, logout)) return; format_tmap formatlistmap; formatlistmap[formatstring] = formatlistptr; recurse_contents (response.docInfo[0], args, bptr, metadata, getParents, formatlistptr, formatlistmap, formatinfo, browsermap, colnumber, collectproto, disp, outconvert, textout, logout); // clean up format list pointers format_tmap::const_iterator here = formatlistmap.begin(); format_tmap::const_iterator end = formatlistmap.end(); while (here != end) { delete (*here).second; here ++; } } static void load_formatstring (const text_t &classifytype, text_tset &metadata, bool &getParents, const text_t &classification, browsermapclass *browsermap, formatinfo_t &formatinfo, format_tmap &formatlistmap) { text_t formatstring; // load up metadata array with browser defaults browserclass *bptr = browsermap->getbrowser (classifytype); bptr->load_metadata_defaults (metadata); // get the formatstring if there is one or use the browsers default if (!get_formatstring (classification, classifytype, formatinfo.formatstrings, formatstring)) formatstring = bptr->get_default_formatstring(); // see if it's cached format_tmap::const_iterator it = formatlistmap.find (formatstring); if (it == formatlistmap.end()) { format_t *formatlistptr = new format_t(); parse_formatstring (formatstring, formatlistptr, metadata, getParents); formatlistmap[formatstring] = formatlistptr; } } static void load_formatstrings (FilterResponse_t &response, text_tset &metadata, bool &getParents, const text_t &classification, browsermapclass *browsermap, formatinfo_t &formatinfo, format_tmap &formatlistmap) { text_tset cache; ResultDocInfo_tarray::iterator thisdoc = response.docInfo.begin(); ResultDocInfo_tarray::iterator lastdoc = response.docInfo.end(); while (thisdoc != lastdoc) { if (classification != "Document" && is_top ((*thisdoc).OID)) { text_t &thistype = (*thisdoc).metadata["thistype"].values[0]; if (!thistype.empty()) load_formatstring (thistype, metadata, getParents, classification, browsermap, formatinfo, formatlistmap); } text_t &childtype = (*thisdoc).metadata["childtype"].values[0]; text_tset::const_iterator it = cache.find (childtype); if (it == cache.end()) { if (!childtype.empty()) { load_formatstring (childtype, metadata, getParents, classification, browsermap, formatinfo, formatlistmap); cache.insert (childtype); } } thisdoc ++; } } static void contracted_contents (cgiargsclass &args, browsermapclass *browsermap, formatinfo_t &formatinfo, recptproto *collectproto, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &logout) { FilterResponse_t response; text_tset metadata; bool getParents = false; text_tarray parents; text_t OID = args["d"]; if (OID.empty()) OID = args["d"]; text_t classification = "Document"; if (args["d"].empty()) get_top (args["cl"], classification); bool haschildren = has_children (OID, args["c"], collectproto, logout); if (haschildren) get_parents_array (OID + ".fc", parents); else get_parents_array (OID, parents); // get classifytypes of each parent metadata.insert ("thistype"); metadata.insert ("childtype"); if (!get_info (parents, args["c"], metadata, getParents, collectproto, response, logout)) return; metadata.erase (metadata.begin(), metadata.end()); // get formatstrings for all parents format_tmap formatlistmap; load_formatstrings (response, metadata, getParents, classification, browsermap, formatinfo, formatlistmap); /////////////////// } void output_toc (cgiargsclass &args, browsermapclass *browsermap, formatinfo_t &formatinfo, recptproto *collectproto, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &logout) { if (args.getintarg("gc") == 1) { // expanded table of contents expanded_contents (args, browsermap, formatinfo, collectproto, disp, outconvert, textout, logout); } else { // contracted table of contents contracted_contents (args, browsermap, formatinfo, collectproto, disp, outconvert, textout, logout); } }