/**********************************************************************
*
* 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);
}
}
|