Changeset 649


Ignore:
Timestamp:
1999-10-10T21:14:12+13:00 (25 years ago)
Author:
sjboddie
Message:
  • metadata now returns mp rather than array
  • redesigned browsing support (although it's not finished so

won't currently work ;-)

Location:
trunk/gsdl/src/recpt
Files:
8 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/src/recpt/OIDtools.cpp

    r533 r649  
    2828/*
    2929   $Log$
     30   Revision 1.17  1999/10/10 08:14:02  sjboddie
     31   - metadata now returns mp rather than array
     32   - redesigned browsing support (although it's not finished so
     33   won't currently work ;-)
     34
    3035   Revision 1.16  1999/09/07 04:56:51  sjboddie
    3136   added GPL notice
     
    135140
    136141// get_info does a protocol call and returns (in response) the metadata
    137 // associated with OID. The metadata array should be loaded with whatever
     142// associated with OID. Metadata should be loaded with whatever
    138143// metadata fields are to be requested.
    139144
    140145bool get_info (const text_t &OID, const text_t &collection,
    141            const text_tarray &metadata, bool getParents,
     146           const text_tset &metadata, bool getParents,
    142147           recptproto *collectproto, FilterResponse_t &response,
    143148           ostream &logout) {
     
    163168    return false;
    164169  }
    165 
    166   // check the result to make sure we have the right amount of metadata
    167   if (!response.docInfo.empty() &&
    168       response.docInfo[0].metadata.size() != metadata.size()) return false;
    169170 
    170171  return true;
     
    172173
    173174bool get_info (const text_tarray &OIDs, const text_t &collection,
    174            const text_tarray &metadata, bool getParents,
     175           const text_tset &metadata, bool getParents,
    175176           recptproto *collectproto, FilterResponse_t &response,
    176177           ostream &logout) {
     
    198199  }
    199200
    200   // check the result to make sure we have the right amount of metadata
    201   if (!response.docInfo.empty() &&
    202       response.docInfo[0].metadata.size() != metadata.size()) return false;
    203 
    204201  return true;
    205202}
     
    210207
    211208  FilterResponse_t response;
    212   text_tarray metadata;
    213   metadata.push_back ("haschildren");
     209  text_tset metadata;
     210  metadata.insert ("haschildren");
    214211
    215212  if (get_info (OID, collection, metadata, false, collectproto, response, logout)) {
    216     if (response.docInfo[0].metadata[0].values[0] == "1")
     213    if (response.docInfo[0].metadata["haschildren"].values[0] == "1")
    217214      return true;
    218215  }
     
    222219
    223220// get_children does a protocol call and returns (in response) the OIDs and
    224 // metadata of all the children of OID. The metadata array should be loaded
     221// metadata of all the children of OID. The metadata set should be loaded
    225222// with whatever metadata fields are to be requested.
    226223
    227224bool get_children (const text_t &OID, const text_t &collection,
    228            const text_tarray &metadata, bool getParents,
     225           const text_tset &metadata, bool getParents,
    229226           recptproto *collectproto, FilterResponse_t &response,
    230227           ostream &logout) {
     
    323320}
    324321
    325 void recurse_contents (const ResultDocInfo_t section, const bool &classify,
    326                int &totalcols, const text_t &collection,
    327                const text_tarray &metadata, recptproto *collectproto,
    328                FilterResponse_t &response, ostream &logout) {
    329  
    330   int metasize = section.metadata.size();
    331 
    332   int haschildren = section.metadata[metasize-2].values[0].getint();
    333   const text_t &doctype = section.metadata[metasize-1].values[0];
    334   int cols;
    335 
    336   if ((haschildren == 1) && ((!classify) || (doctype == "classify"))) {
    337     text_t parent = response.docInfo.back().OID;
    338     int parentcols = countchar (parent.begin(), parent.end(), '.');
     322static void recurse_contents (ResultDocInfo_t section, const bool &is_classify,
     323                  const text_t &collection, const text_tset &metadata,
     324                  recptproto *collectproto, FilterResponse_t &response,
     325                  ostream &logout) {
     326
     327  int haschildren = section.metadata["haschildren"].values[0].getint();
     328  const text_t &doctype = section.metadata["doctype"].values[0];
     329
     330  if ((haschildren == 1) && ((!is_classify) || (doctype == "classify"))) {
    339331    FilterResponse_t tmp;
    340332    bool getParents = false;
    341333    get_children (section.OID, collection, metadata, getParents, collectproto, tmp, logout);
    342     ResultDocInfo_tarray::const_iterator thisdoc = tmp.docInfo.begin();
    343     ResultDocInfo_tarray::const_iterator lastdoc = tmp.docInfo.end();
     334    ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
     335    ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
    344336    while (thisdoc != lastdoc) {
    345       if (((*thisdoc).metadata[metasize-1].values[0] != "classify") && (classify))
    346     cols = parentcols + 1;
    347       else
    348     cols = countchar ((*thisdoc).OID.begin(), (*thisdoc).OID.end(), '.');
    349       if (cols > totalcols) totalcols = cols;
    350337      response.docInfo.push_back (*thisdoc);
    351       recurse_contents (*thisdoc, classify, totalcols, collection,
    352             metadata, collectproto, response, logout);
     338      recurse_contents (*thisdoc, is_classify, collection, metadata,
     339            collectproto, response, logout);
    353340      thisdoc ++;
    354341    }
     
    358345// get_contents returns OIDs and metadata of all contents
    359346// below (and including) OID.
    360 void get_contents (const text_t &topOID, const text_t &classifytype,
    361            text_tarray &metadata, int &totalcols,
    362            const text_t &collection, recptproto *collectproto,
    363            FilterResponse_t &response, ostream &logout) {
     347void get_contents (const text_t &topOID, const bool &is_classify,
     348           text_tset &metadata, const text_t &collection,
     349           recptproto *collectproto, FilterResponse_t &response,
     350           ostream &logout) {
    364351
    365352  if (topOID.empty()) return;
    366   bool classify = false;
    367353  response.clear();
    368354
    369   metadata.push_back("haschildren");
    370   metadata.push_back("doctype");
    371 
    372   // we don't want to recurse all the way down through each document
    373   // if we're expanding top level contents
    374   if (classifytype == "classify") classify = true;
    375 
    376   // update totalcols
    377   totalcols = countchar (topOID.begin(), topOID.end(), '.');
     355  metadata.insert ("haschildren");
     356  metadata.insert ("doctype");
    378357
    379358  // get topOIDs info
    380359  if (get_info (topOID, collection, metadata, false, collectproto, response, logout))
    381       recurse_contents (response.docInfo[0], classify, totalcols, collection,
     360      recurse_contents (response.docInfo[0], is_classify, collection,
    382361            metadata, collectproto, response, logout);
    383362}
  • trunk/gsdl/src/recpt/OIDtools.h

    r533 r649  
    4545
    4646// get_info does a protocol call and returns (in response) the info
    47 // associated with OID. The metadata array should be loaded with whatever
     47// associated with OID. Metadata should be loaded with whatever
    4848// metadata fields are to be requested
    4949bool get_info (const text_t &OID, const text_t &collection,
    50            const text_tarray &metadata, bool getParents,
     50           const text_tset &metadata, bool getParents,
    5151           recptproto *collectproto, FilterResponse_t &response,
    5252           ostream &logout);
    5353bool get_info (const text_tarray &OIDs, const text_t &collection,
    54            const text_tarray &metadata, bool getParents,
     54           const text_tset &metadata, bool getParents,
    5555           recptproto *collectproto, FilterResponse_t &response,
    5656           ostream &logout);
     
    6161
    6262// get_children does a protocol call and returns (in response) the OIDs and
    63 // metadata of all the children of OID. The metadata array should be loaded
     63// metadata of all the children of OID. The metadata set should be loaded
    6464// with whatever metadata fields are to be requested.
    6565bool get_children (const text_t &OID, const text_t &collection,
    66            const text_tarray &metadata, bool getParents,
     66           const text_tset &metadata, bool getParents,
    6767           recptproto *collectproto, FilterResponse_t &response,
    6868           ostream &logout);
     
    8989// get_contents returns OIDs and metadata of all contents
    9090// below (and including) OID.
    91 void get_contents (const text_t &topOID, const text_t &classifytype,
    92            text_tarray &metadata, int &totalcols,
    93            const text_t &collection, recptproto *collectproto,
    94            FilterResponse_t &response, ostream &logout);
     91void get_contents (const text_t &topOID, const bool &is_classify,
     92           text_tset &metadata, const text_t &collection,
     93           recptproto *collectproto, FilterResponse_t &response,
     94           ostream &logout);
    9595
    9696// is_child_of returns true if OID2 is a child of OID1
  • trunk/gsdl/src/recpt/browsetools.cpp

    r635 r649  
     1
    12/**********************************************************************
    23 *
     
    2829/*
    2930   $Log$
     31   Revision 1.25  1999/10/10 08:14:04  sjboddie
     32   - metadata now returns mp rather than array
     33   - redesigned browsing support (although it's not finished so
     34   won't currently work ;-)
     35
    3036   Revision 1.24  1999/09/28 01:46:55  rjmcnab
    3137   removed some unused stuff
     
    123129 */
    124130
    125 
    126131#include "browsetools.h"
    127132#include "OIDtools.h"
     133
    128134
    129135// simply checks to see if formatstring begins with a <td> tag
     
    156162}
    157163
    158 
    159 // output_controls displays the detach, expand/contract contents,
    160 // expand/contract text and highlighting/no highlighting buttons
    161 static void output_controls (cgiargsclass &args, const text_tarray &ibuttons,
    162                  recptproto * /*collectproto*/, displayclass &disp,
    163                  outconvertclass &outconvert, ostream &textout,
    164                  ostream &/*logout*/) {
    165 
    166   if (args["u"] != "1") {
     164// expects haschidren, doctype, and classifytype metadata elements
     165static void recurse_contents (ResultDocInfo_t &section, cgiargsclass &args,
     166                  browserclass *bptr, text_tset &metadata, bool &getParents,
     167                  format_t *formatlistptr, format_tmap &formatlistmap,
     168                  formatinfo_t &formatinfo, browsermapclass *browsermap,
     169                  int colnumber, recptproto *collectproto, displayclass &disp,
     170                  outconvertclass &outconvert, ostream &textout, ostream &logout) {
     171  text_t formatstring;
     172
     173  bool is_classify = false;
     174  if (args["d"].empty()) is_classify = true;
     175
     176  // output this section
     177  bool use_table = is_table_content (formatlistptr);
     178  colnumber += bptr->output_section_group (section, args, colnumber, formatlistptr,
     179                       use_table, disp, outconvert, textout, logout);
     180
     181  text_t classification;
     182  if (!is_classify) classification = "Document";
     183  else get_top (section.OID, classification);
     184
     185  int haschildren = section.metadata["haschildren"].values[0].getint();
     186  const text_t &doctype = section.metadata["doctype"].values[0];
     187  text_t classifytype = section.metadata["classifytype"].values[0];
     188  // HLists are displayed as VLists when contents are expanded,
     189  // Books are displayed as HLists
     190  if (classifytype == "HList") classifytype = "VList";
     191  if (classifytype == "Book") classifytype = "HList";
     192
     193  // recurse through children
     194  if ((haschildren == 1) && ((!is_classify) || (doctype == "classify"))) {
     195
     196    // get browser for displaying children
     197    bptr = browsermap->getbrowser (classifytype);
     198    bptr->load_metadata_defaults (metadata);
     199
     200    // get the formatstring if there is one
     201    if (!get_formatstring (classification, classifytype,
     202               formatinfo.formatstrings, formatstring))
     203      formatstring = bptr->get_default_formatstring();
     204
     205    format_tmap::const_iterator it = formatlistmap.find (formatstring);
     206    // check if formatlistptr is cached
     207    if (it != formatlistmap.end()) formatlistptr = (*it).second;
     208    else {
     209      formatlistptr = new format_t();
     210      parse_formatstring (formatstring, formatlistptr, metadata, getParents);
     211      formatlistmap[formatstring] = formatlistptr;
     212    }
     213
     214    FilterResponse_t tmp;
     215    get_children (section.OID, args["c"], metadata, getParents, collectproto, tmp, logout);
     216    ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
     217    ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
     218
     219    while (thisdoc != lastdoc) {
     220      recurse_contents (*thisdoc, args, bptr, metadata, getParents,
     221            formatlistptr, formatlistmap, formatinfo, browsermap,
     222            colnumber, collectproto, disp, outconvert, textout, logout);
     223      thisdoc ++;
     224    }
     225  }
     226}
     227
     228
     229// expanded_contents recurses through all contents. there's a special case
     230// for an HList when contents are expanded (i.e. it's displayed as a VList)
     231//
     232// if we're inside a document we expand all contents from the top,
     233// if we're at classification level we'll just expand out those contents below
     234// the current one
     235
     236static void expanded_contents (cgiargsclass &args, browsermapclass *browsermap,
     237                   formatinfo_t &formatinfo, recptproto *collectproto,
     238                   displayclass &disp, outconvertclass &outconvert,
     239                   ostream &textout, ostream &logout) {
    167240 
    168     FilterResponse_t response;
    169     text_tarray metadata;
    170     text_tarray buttons;
    171 
    172     text_tarray::const_iterator here = ibuttons.begin();
    173     text_tarray::const_iterator end = ibuttons.end();
    174 
    175     while (here != end) {
    176    
    177       if (*here == "Detach")
    178     buttons.push_back ("_document:imagedetach_");
    179       else if (*here == "Highlight") {
    180     if (args["hl"] == "1")
    181       buttons.push_back ("_document:imagenohighlight_");
    182     else
    183       buttons.push_back ("_document:imagehighlight_");
    184       } else if (*here == "Expand Contents") {
    185     if (args["gc"] == "1")
    186       buttons.push_back ("_document:imagecontracttoc_");
    187     else
    188       buttons.push_back ("_document:imageexpandtoc_");
    189       } else if (*here == "Expand Text") {
    190     if (args.getintarg("gt"))
    191       buttons.push_back ("_document:imagecontracttext_");
    192     else
    193       buttons.push_back ("_document:imageexpandtext_");
    194       }
    195       here ++;
    196     }
    197 
    198     here = buttons.begin();
    199     end = buttons.end();
    200     int count = 0;
    201     while (here != end) {
    202       if ((count != 0) && ((count % 3) == 0)) textout << "<br>\n";
    203       textout << outconvert << disp << *here;
    204       count ++;
    205       here ++;
    206     }
    207   }
    208 }
    209 
    210 
    211 // at the moment this just writes out the html to display
    212 // the cover image (assuming it's called cover.jpg)
    213 // this whole thing should be done with a call to the collection
    214 // server which would send a link to the cover image if there
    215 // was one otherwise send title, author and stuff
    216 static void output_cover_image (cgiargsclass &args, recptproto * /*collectproto*/,
    217                 displayclass &disp, outconvertclass &outconvert,
    218                 ostream &textout, ostream &/*logout*/) {
     241  if (args["d"].empty() && args["cl"].empty()) return;
     242  text_t OID;
    219243 
    220   if (args["d"].empty()) return;
    221  
    222   textout << outconvert << disp <<
    223     "<img src=\"_httpcollection_/archives/_thisOID_/cover.jpg\"><br>\n";
    224 }
    225 
    226 
    227 
    228 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    229 Functions for generating a document type tables of contents. These aren't really tables of
    230 contents at all, just a title, some navigation buttons and arrows and maybe a page ? of ?
    231 type thing. These should only be called for document level tocs (i.e. when the "d" argument
    232 is set) as I don't think it makes sense to display top level classifications in this way.
    233 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
    234 
    235 void output_document_toc (cgiargsclass &args, const formatinfo_t &formatinfo,
    236               recptproto *collectproto, displayclass &disp,
    237               outconvertclass &outconvert, ostream &textout,
    238               ostream &logout) {
    239 
    240   text_t &arg_d = args["d"];
    241   if (arg_d.empty()) return;
    242 
    243   text_tarray metadata;
    244244  FilterResponse_t response;
    245245  bool getParents = false;
    246   ResultDocInfo_t docinfo;
    247   text_t &collection = args["c"];
    248   int gt = args.getintarg("gt");
    249 
    250   bool istop = is_top (arg_d);
    251 
    252   format_t *formatlistptr = new format_t();
    253   parse_formatstring (formatinfo.DocumentHeading, formatlistptr, metadata, getParents);
    254 
    255   text_tarray OIDs;
    256   OIDs.push_back (arg_d);
    257   if (formatinfo.DocumentArrowsTop && !gt && !istop)
    258     OIDs.push_back (arg_d + ".pr.lc");
    259 
    260   metadata.push_back ("Title");
    261   int metasize = metadata.size();
    262 
    263   if (get_info (OIDs, collection, metadata, getParents, collectproto, response, logout)) {
    264    
    265     text_t &thistitle = response.docInfo[0].metadata[metasize-1].values.back();
    266     text_t last_sib_title;
    267     if (formatinfo.DocumentArrowsTop && !gt && !istop) {
    268       if (response.docInfo.size() == 1)
    269     last_sib_title = response.docInfo[0].metadata[metasize-1].values.back();   
    270       else
    271     last_sib_title = response.docInfo[1].metadata[metasize-1].values.back();
    272     }
    273 
    274     textout
    275       << "\n<!-- Table of Contents produced by browsetools::output_document_toc -->\n\n";
    276    
    277     textout << outconvert << disp
    278         << "<p><center>\n"
    279         << "<table cellpadding=0 cellspacing=0 width=_pagewidth_>\n"
    280         << "<tr valign=top><td>\n";
    281    
    282     // top arrows and page ? of ? title
    283     if (formatinfo.DocumentArrowsTop && !gt) {
    284    
    285       // previous arrow
    286       textout << outconvert << disp << "<table><tr valign=top>\n"
    287           << "<td align=left>_document:prevarrow_</td>\n";
    288      
    289       // page ? of ? text
    290       textout << "<td align=center>\n";
    291      
    292       if (!istop && is_number (thistitle) && is_number (last_sib_title))
    293     textout << outconvert << disp << "_document:page_" << thistitle
    294         << "_document:of_" << last_sib_title;
    295 
    296       else
    297     textout << outconvert << thistitle;
    298  
    299       // next arrow
    300       textout << outconvert << disp << "</td>\n<td align=right>_document:nextarrow_</td>\n</table>\n";
    301     }
    302 
    303     // goto line
    304     if (formatinfo.DocumentGoTo)
    305       textout << outconvert << disp << "_document:gotoform_";
    306 
    307     // control buttons
    308     output_controls (args, formatinfo.DocumentButtons, collectproto,
    309              disp, outconvert, textout, logout);
    310     textout << "</td>\n";
    311 
    312     // heading
    313     textout << outconvert << "\n<td valign=top>\n"
    314         << get_formatted_string (response.docInfo[0], formatlistptr);
    315 
    316     textout << "</td></tr></table></center>\n";
    317     textout << "\n<!-- end of Table of Contents -->\n";
    318   }
    319 }
    320 
    321 
    322 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    323 Functions for generating a "Hierarchy" type table of contents. These can be used either
    324 at top classification level or at document level (the difference being that a cover
    325 image and control buttons may be displayed at document level).
    326 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
    327 
    328 // prototypes
    329 
    330 static void output_contracted_hierarchy_toc (const text_t &classifytype, text_t &formatstring,
    331                          cgiargsclass &args, recptproto *collectproto,
    332                          displayclass &disp, outconvertclass &outconvert,
    333                          ostream &textout, ostream &logout);
    334 
    335 static void output_expanded_hierarchy_toc (cgiargsclass &args, recptproto *collectproto,
    336                        displayclass &disp, outconvertclass &outconvert,
    337                        ostream &textout, ostream &logout);
    338 
    339 static void output_parents_toc (cgiargsclass &args, const FilterResponse_t &parents,
    340                 int &tabcount, displayclass &disp, recptproto *collectproto,
    341                 format_t *formatlistptr, outconvertclass &outconvert,
    342                 ostream &textout, ostream &logout);
    343 
    344 static void output_siblings_toc (const text_t &classifytype, cgiargsclass &args,
    345                  const FilterResponse_t &siblings, int &tabcount,
    346                  displayclass &disp, format_t *formatlistptr,
    347                  outconvertclass &outconvert, ostream &textout,
    348                  ostream &logout);
    349 
    350 static void output_stdlist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
    351                 ResultDocInfo_tarray::const_iterator &end, bool intable,
    352                 displayclass &disp, format_t *formatlistptr,
    353                  outconvertclass &outconvert, ostream &textout);
    354 
    355 static void output_datelist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
    356                  ResultDocInfo_tarray::const_iterator &end, bool intable,
    357                  displayclass &disp, format_t *formatlistptr,
    358                  outconvertclass &outconvert, ostream &textout);
    359 
    360 
    361 void output_standard_toc (const text_t &classifytype, const formatinfo_t &formatinfo,
    362               text_t &formatstring, cgiargsclass &args,
    363               recptproto *collectproto, displayclass &disp,
    364               outconvertclass &outconvert, ostream &textout,
    365               ostream &logout) {
    366 
    367   bool havecontrols = false;
    368 
    369   textout << "\n<!-- Table of Contents produced by browsetools::output_standard_toc -->\n\n";
    370 
    371   // get the cover image (if there is one) and the control buttons
    372   // if we're inside a book
     246  text_tset metadata;
     247  text_t classifytype, classification, formatstring;
     248  int colnumber = 0;
     249
    373250  if (!args["d"].empty()) {
    374     textout << "<p><table cellpadding=0 cellspacing=0><tr>\n";
    375     textout << "<td valign=top width=200>\n";
    376     if (formatinfo.DocumentImages)
    377       output_cover_image (args, collectproto, disp, outconvert, textout, logout);
    378     output_controls (args, formatinfo.DocumentButtons, collectproto, disp,
    379              outconvert, textout, logout);
    380     textout << "</td><td valign=top>\n";
    381     havecontrols = true;
    382   }
    383  
    384   // get table of contents
    385   textout << "<table>\n";
    386 
    387   if (args.getintarg("gc"))
    388     output_expanded_hierarchy_toc(args, collectproto, disp, outconvert, textout, logout);
    389   else
    390     output_contracted_hierarchy_toc(classifytype, formatstring, args, collectproto,
    391                     disp, outconvert, textout, logout);
    392 
    393   textout << "</table>\n";
    394 
    395   if (havecontrols) textout << "</td></tr></table>\n";
    396 
    397   textout << "\n<!-- end of Table of Contents -->\n";
    398 }
    399 
    400 
    401 void output_contracted_hierarchy_toc (const text_t &classifytype, text_t &formatstring,
    402                       cgiargsclass &args, recptproto *collectproto,
    403                       displayclass &disp, outconvertclass &outconvert,
    404                       ostream &textout, ostream &logout) {
    405 
    406   int tabcount = 0;
    407   text_tarray parents, metadata;
    408   FilterResponse_t fsiblings, fparents;
    409   bool getParents = false;
    410 
    411   text_t &arg_d = args["d"];
    412   text_t OID = arg_d;
    413   if (OID.empty()) {
    414     // if classifytype is an AZList we need to jump to
    415     // the first child
    416     if (classifytype == "AZList") OID = args["cl"] + ".fc";
    417     else OID = args["cl"];
    418   }
    419 
    420   text_t &collection = args["c"];
    421 
    422   // if format string is empty use the default
    423   if (formatstring.empty())
    424     formatstring = "<td valign=top nowrap>[link][icon][/link]</td><td>{Or}{[Title],Untitled}</td>";
     251    // document level - expand from top
     252    get_top (args["d"], OID);
     253    classification = "Document";
     254  } else {
     255    // classification level
     256    OID = args["cl"];
     257    get_top (args["cl"], classification);
     258  }
     259
     260  // get classifytype of this level
     261  text_t tOID;
     262  if (is_top(OID)) {
     263    classifytype = "thistype";
     264    tOID = OID;
     265  } else {
     266    classifytype = "childtype";
     267    tOID = get_parent (OID);
     268  }
     269  metadata.insert (classifytype);
     270
     271  if (!get_info (tOID, args["c"], metadata, getParents, collectproto, response, logout))
     272    return;
     273  classifytype = response.docInfo[0].metadata[classifytype].values[0];
     274  // if we still don't have a classifytype we'll use the default
     275  if (classifytype.empty()) {
     276    browserclass *bptr = browsermap->get_default_browser ();
     277    classifytype = bptr->get_browser_name ();
     278  }
     279
     280  // HLists are displayed as VLists when contents are expanded,
     281  // Books are displayed as HLists
     282  if (classifytype == "HList") classifytype = "VList";
     283  if (classifytype == "Book") classifytype = "HList";
     284
     285  metadata.erase (metadata.begin(), metadata.end());
     286         
     287  // metadata elements needed by recurse_contents
     288  metadata.insert ("classifytype");
     289  metadata.insert ("doctype");
     290  metadata.insert ("haschildren");
     291
     292  // load up metadata array with browser defaults
     293  browserclass *bptr = browsermap->getbrowser (classifytype);
     294  bptr->load_metadata_defaults (metadata);
     295
     296  // get the formatstring if there is one or use the browsers default
     297  if (!get_formatstring (classification, classifytype,
     298             formatinfo.formatstrings, formatstring))
     299    formatstring = bptr->get_default_formatstring();
    425300
    426301  format_t *formatlistptr = new format_t();
    427302  parse_formatstring (formatstring, formatlistptr, metadata, getParents);
    428303
    429   metadata.push_back ("Date");
    430   metadata.push_back ("hastxt");
    431   metadata.push_back ("haschildren");
    432   metadata.push_back ("doctype");
    433   metadata.push_back ("classifytype");
    434 
    435   if (has_children (OID, collection, collectproto, logout)) {
    436       get_parents_array (OID + ".fc", parents);
    437 
    438       if (!get_children (OID, collection, metadata, getParents,
    439              collectproto, fsiblings, logout))
    440     return;
     304  // protocol call
     305  if (!get_info (OID, args["c"], metadata, getParents, collectproto, response, logout))
     306    return;
     307
     308  format_tmap formatlistmap;
     309  formatlistmap[formatstring] = formatlistptr;
     310
     311  recurse_contents (response.docInfo[0], args, bptr, metadata,
     312            getParents, formatlistptr, formatlistmap, formatinfo, browsermap,
     313            colnumber, collectproto, disp, outconvert, textout, logout);
     314
     315  // clean up format list pointers
     316  format_tmap::const_iterator here = formatlistmap.begin();
     317  format_tmap::const_iterator end = formatlistmap.end();
     318  while (here != end) {
     319    delete (*here).second;
     320    here ++;
     321  }
     322}
     323
     324static void load_formatstring (const text_t &classifytype, text_tset &metadata,
     325                   bool &getParents, const text_t &classification,
     326                   browsermapclass *browsermap, formatinfo_t &formatinfo,
     327                   format_tmap &formatlistmap) {
     328  text_t formatstring;
     329
     330  // load up metadata array with browser defaults
     331  browserclass *bptr = browsermap->getbrowser (classifytype);
     332  bptr->load_metadata_defaults (metadata);
     333
     334  // get the formatstring if there is one or use the browsers default
     335  if (!get_formatstring (classification, classifytype,
     336             formatinfo.formatstrings, formatstring))
     337    formatstring = bptr->get_default_formatstring();
     338
     339  // see if it's cached
     340  format_tmap::const_iterator it = formatlistmap.find (formatstring);
     341  if (it == formatlistmap.end()) {
     342    format_t *formatlistptr = new format_t();
     343    parse_formatstring (formatstring, formatlistptr, metadata, getParents);
     344    formatlistmap[formatstring] = formatlistptr;
     345  }
     346}
     347
     348static void load_formatstrings (FilterResponse_t &response, text_tset &metadata,
     349                bool &getParents, const text_t &classification,
     350                browsermapclass *browsermap, formatinfo_t &formatinfo,
     351                format_tmap &formatlistmap) {
     352
     353  text_tset cache;
     354
     355  ResultDocInfo_tarray::iterator thisdoc = response.docInfo.begin();
     356  ResultDocInfo_tarray::iterator lastdoc = response.docInfo.end();
     357
     358  while (thisdoc != lastdoc) {
     359    if (classification != "Document" && is_top ((*thisdoc).OID)) {
     360      text_t &thistype = (*thisdoc).metadata["thistype"].values[0];
     361      if (!thistype.empty()) load_formatstring (thistype, metadata, getParents, classification,
     362                        browsermap, formatinfo, formatlistmap);
     363    }
     364    text_t &childtype = (*thisdoc).metadata["childtype"].values[0];
     365    text_tset::const_iterator it = cache.find (childtype);
     366    if (it == cache.end()) {
     367      if (!childtype.empty()) {
     368    load_formatstring (childtype, metadata, getParents, classification,
     369               browsermap, formatinfo, formatlistmap);
     370    cache.insert (childtype);
     371      }
     372    }
     373    thisdoc ++;
     374  }
     375}
     376
     377
     378static void contracted_contents (cgiargsclass &args, browsermapclass *browsermap,
     379                 formatinfo_t &formatinfo, recptproto *collectproto,
     380                 displayclass &disp, outconvertclass &outconvert,
     381                 ostream &textout, ostream &logout) {
     382  FilterResponse_t response;
     383  text_tset metadata;
     384  bool getParents = false;
     385  text_tarray parents;
     386  text_t OID = args["d"];
     387  if (OID.empty()) OID = args["d"];
     388  text_t classification = "Document";
     389  if (args["d"].empty()) get_top (args["cl"], classification);
     390
     391  bool haschildren = has_children (OID, args["c"], collectproto, logout);
     392
     393  if (haschildren) get_parents_array (OID + ".fc", parents);
     394  else get_parents_array (OID, parents);
     395
     396  // get classifytypes of each parent
     397  metadata.insert ("thistype");
     398  metadata.insert ("childtype");
     399  if (!get_info (parents, args["c"], metadata, getParents, collectproto, response, logout))
     400    return;
     401 
     402  metadata.erase (metadata.begin(), metadata.end());
     403
     404  // get formatstrings for all parents
     405  format_tmap formatlistmap; 
     406  load_formatstrings (response, metadata, getParents, classification,
     407              browsermap, formatinfo, formatlistmap);
     408
     409  ///////////////////
     410
     411}
     412
     413void output_toc (cgiargsclass &args, browsermapclass *browsermap,
     414                 formatinfo_t &formatinfo, recptproto *collectproto,
     415                 displayclass &disp, outconvertclass &outconvert,
     416                 ostream &textout, ostream &logout) {
     417
     418  if (args.getintarg("gc") == 1) {
     419
     420    // expanded table of contents
     421    expanded_contents (args, browsermap, formatinfo, collectproto,
     422               disp, outconvert, textout, logout);
    441423  } else {
    442     get_parents_array (OID, parents);
    443     if (!get_children (OID + ".pr", collection, metadata,
    444                getParents, collectproto, fsiblings, logout))
    445       return;
    446   }
    447   if (!get_info (parents, collection, metadata, false, collectproto, fparents, logout)) return;
    448  
    449   if (!fparents.docInfo.empty())
    450     output_parents_toc(args, fparents, tabcount, disp, collectproto,
    451                formatlistptr, outconvert, textout, logout);
    452  
    453   if (!fsiblings.docInfo.empty())
    454     output_siblings_toc (classifytype, args, fsiblings, tabcount, disp,
    455              formatlistptr, outconvert, textout, logout);
    456 }
    457 
    458 void output_parents_toc (cgiargsclass &args, const FilterResponse_t &parents,
    459              int &tabcount, displayclass &disp, recptproto *collectproto,
    460              format_t *formatlistptr, outconvertclass &outconvert,
    461              ostream &textout, ostream &logout) { 
    462 
    463   text_t tab, icon;
    464   text_t &arg_cl = args["cl"];
    465   text_t &arg_d = args["d"];
    466   int numcols = parents.docInfo.size() + 1;
    467 
    468   bool intable = is_table_content (formatlistptr);
    469 
    470   ResultDocInfo_tarray::const_iterator thisparent = parents.docInfo.begin();
    471   ResultDocInfo_tarray::const_iterator end = parents.docInfo.end();
    472 
    473   int len = (*thisparent).metadata.size();
    474   //  const text_t &classifytype = (*thisparent).metadata[len-1].values[0];
    475 
    476   // don't want top level of any classifications to be displayed
    477   if (arg_d.empty() && thisparent != end) {thisparent ++; numcols --;}
    478 
    479   // don't want second level of classifications using classification links
    480   //  if ((classifytype == "AZList" || classifytype == "DateList") && (thisparent != end))
    481   //    {thisparent ++; numcols --;}
    482 
    483   // the tab line
    484   if (thisparent != end) {
    485     text_t coltabs;
    486     for (int i = 0; i < numcols; i ++) coltabs += "_document:tab_";
    487     textout << outconvert << disp << "<tr>" << coltabs << "<td></td></tr>\n";
    488   }
    489 
    490   bool first = true;
    491   while (thisparent != end) {
    492 
    493     text_t link;
    494     bool azlist = false;
    495     // set azlist if we're in an AZList section (i.e. immediate parent
    496     // has classifytype of AZList
    497     if (!first && (*(thisparent-1)).metadata[len-1].values[0] == "AZList")
    498       azlist = true;
    499  
    500     const text_t &doctype = (*thisparent).metadata[len-2].values.back();
    501     //    bool thissection = false;
    502 
    503     if (!azlist) {
    504       // set up icon and pointer
    505       icon = "_document:icon";
    506       if ((doctype != "classify") && ((*thisparent).OID == arg_d))
    507     icon += "arrow";
    508       if (doctype == "classify") icon += "openbookshelf_";
    509       else if (is_top((*thisparent).OID)) icon += "openbook_";
    510       else icon += "openfolder_";
    511    
    512       // set up the link
    513       link = "<a href=\"_httpdocument_";
    514       if (is_top((*thisparent).OID) && args.getintarg("x")) link = "<a name=top>";
    515       else
    516     if (doctype == "classify") link += "&cl=" + (*thisparent).OID + ".pr\">";
    517     else
    518       if (is_top ((*thisparent).OID))
    519         if (arg_cl.empty())
    520           link = "<a name=top>";
    521         else if (arg_cl == "search")
    522           link = "<a href=\"_httpquery_\">";
    523         else
    524           link += "&cl=" + arg_cl + "\">";
    525       else link += "&cl=" + arg_cl + "&d=" + (*thisparent).OID + ".pr\">";
    526     }
    527      
    528     if (tabcount == 1) textout << "<td></td>\n";
    529     else if (tabcount > 1) textout << "<td colspan=" << tabcount << "></td>";
    530 
    531     if ((numcols-tabcount) == 1) textout << "<td>";
    532     else if ((numcols-tabcount) > 1) textout << "<td colspan="
    533                          << (numcols-tabcount) << ">";
    534 
    535     if (intable) textout << "<table><tr>";
    536 
    537     if (azlist) {
    538       FilterResponse_t response;
    539       // AZLists rely on Title metadata
    540       text_tarray metadata;
    541       metadata.push_back ("Title");
    542 
    543       // need to get siblings of this classification
    544       if (get_children ((*(thisparent-1)).OID, args["c"], metadata, false,
    545             collectproto, response, logout)) {
    546 
    547     ResultDocInfo_tarray::const_iterator thissib = response.docInfo.begin();
    548     ResultDocInfo_tarray::const_iterator endsib = response.docInfo.end();
    549 
    550     while (thissib != endsib) {
    551       link = "<a href=\"_httpdocument_&cl=" + (*thissib).OID + "\">";
    552       const text_t &title = (*thissib).metadata[0].values.back();
    553       if ((*thissib).OID == (*thisparent).OID)
    554         textout << outconvert << disp << "<b>" << title << "</b>\n";
    555       else textout << outconvert << disp << link << title << "</a>\n";
    556       thissib ++;
    557     }
    558       }
    559     } else {
    560       textout << outconvert << disp
    561           << get_formatted_string (*thisparent, formatlistptr, link, icon);
    562     }
    563    
    564     if (intable) textout << "</tr></table>";
    565     textout << "</td></tr>\n";
    566 
    567     first = false;
    568     tabcount ++;
    569     thisparent ++;
    570   }
    571 }
    572 
    573 
    574 void output_siblings_toc (const text_t &classifytype, cgiargsclass &args,
    575               const FilterResponse_t &siblings, int &tabcount,
    576               displayclass &disp, format_t *formatlistptr,
    577               outconvertclass &outconvert, ostream &textout,
    578               ostream &/*logout*/) {
    579 
    580   bool intable = is_table_content (formatlistptr);
    581 
    582   ResultDocInfo_tarray::const_iterator thissibling = siblings.docInfo.begin();
    583   ResultDocInfo_tarray::const_iterator sibend = siblings.docInfo.end();
    584 
    585   if (thissibling == sibend) return;
    586 
    587   // tabbing
    588   if (tabcount) {
    589     if (tabcount == 1) textout << "<tr><td></td>\n";
    590     else if (tabcount > 1) textout << "<tr><td colspan=" << tabcount << "></td>";
    591     textout << "<td><table>\n";
    592   }
    593 
    594   if (!intable) textout << "<tr><td>\n";
    595  
    596   if (classifytype == "DateList")
    597     output_datelist (args, thissibling, sibend, intable, disp,
    598              formatlistptr, outconvert, textout);
    599   else
    600     output_stdlist (args, thissibling, sibend, intable, disp,
    601             formatlistptr, outconvert, textout);
    602 
    603   if (!intable) textout << "</td></tr></table>\n";
    604   if (tabcount) textout << "</table></td></tr>\n";
    605 }
    606 
    607 void output_stdlist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
    608              ResultDocInfo_tarray::const_iterator &end, bool intable,
    609              displayclass &disp, format_t *formatlistptr,
    610              outconvertclass &outconvert, ostream &textout) {
    611 
    612   text_t icon;
    613   int count = 1;
    614   int gt = args.getintarg("gt");
    615   text_t &arg_cl = args["cl"];
    616   text_t &arg_d = args["d"];
    617 
    618   while (here != end) {
    619 
    620     int len = (*here).metadata.size();
    621     const text_t &doctype = (*here).metadata[len-2].values.back();
    622     const text_t &hastxt = (*here).metadata[len-4].values.back();
    623     const text_t &haschildren = (*here).metadata[len-3].values.back();
    624 
    625     // set up icon and pointer
    626     icon = "_document:icon";
    627     if (doctype == "classify") {
    628       if (((*here).OID == arg_cl) && (hastxt == "1"))
    629         icon += "arrow";
    630     } else if ((*here).OID == arg_d) icon += "arrow";
    631 
    632     if (haschildren == "0") icon += "smalltext_";
    633     else if (doctype == "classify") icon += "closedbookshelf_";
    634     else if (is_top((*here).OID)) icon += "closedbook_";
    635     else icon += "closedfolder_";
    636    
    637     // set up link
    638     text_t link = "<a href=\"_httpdocument_";
    639     if (doctype == "classify") link += "&cl=" + (*here).OID + "\">";
    640     else link += "&cl=" + arg_cl + "&d=" + (*here).OID + "\">";
    641     if (gt) {
    642       link = "<a href=\"#" + text_t(count) + "\">";
    643       count ++;
    644     }
    645 
    646     if (intable) textout << "<tr>";
    647    
    648     textout << outconvert << disp
    649         << get_formatted_string (*here, formatlistptr, link, icon) << "\n";
    650    
    651     if (intable) textout << "</tr>";
    652 
    653     here ++;
    654   }
    655 }
    656 
    657 
    658 void output_datelist (cgiargsclass &args, ResultDocInfo_tarray::const_iterator &here,
    659               ResultDocInfo_tarray::const_iterator &end, bool intable,
    660               displayclass &disp, format_t *formatlistptr,
    661               outconvertclass &outconvert, ostream &textout) {
    662 
    663   text_t lastyear = "0000";
    664   text_t lastmonth = "00";
    665 
    666   while (here != end) {
    667 
    668     int len = (*here).metadata.size();
    669     const text_t &doctype = (*here).metadata[len-2].values.back();
    670     const text_t &date = (*here).metadata[len-5].values.back();
    671 
    672     // bail on this document if it has no date
    673     if (date.empty()) continue;
    674 
    675     text_t::const_iterator datebegin = date.begin();
    676     int datesize = date.size();
    677    
    678     if (datesize < 4) continue;
    679     text_t thisyear = substr (datebegin, datebegin+4);
    680     text_t thismonth = "00";
    681     if (datesize >= 6)
    682       thismonth = substr (datebegin+4, datebegin+6);
    683 
    684     text_t link = "<a href=\"_httpdocument_&cl=";
    685     text_t icon = "_document:iconclosedbook_";
    686      
    687     if (doctype == "classify") {
    688       icon = "_document:iconclosedbookshelf_";
    689       link += (*here).OID + "\">";
    690     } else link += args["cl"] + "&d=" + (*here).OID + "\">";
    691 
    692     textout << "<tr>\n";
    693 
    694     if (thisyear != lastyear) {
    695       textout << outconvert << "<td><b>" << thisyear << "</b></td>";
    696       lastyear = thisyear;
    697     } else
    698       textout << "<td></td>";
    699 
    700     if (thismonth != lastmonth) {
    701       textout << outconvert << disp << ("<td><b>_textmonth" + thismonth + "_</b></td>");
    702       lastmonth = thismonth;
    703     } else
    704       textout << "<td></td>";
    705 
    706     if (!intable) textout << "<td>\n";
    707    
    708     textout << outconvert << disp
    709           << get_formatted_string (*here, formatlistptr, link, icon) << "\n";
    710 
    711     if (!intable) textout << "</td>";
    712      
    713     textout << "</tr>\n";
    714 
    715     here ++;
    716   }
    717 }
    718 
    719 void output_expanded_hierarchy_toc (cgiargsclass &args, recptproto *collectproto,
    720                     displayclass &disp, outconvertclass &outconvert,
    721                     ostream &textout, ostream &logout) {
    722 
    723   text_t OID, topOID, classifytype, icon;
    724   FilterResponse_t response;
    725   int tabcols=0, totalcols=0, lasttabcols=0;
    726 
    727   int gt = args.getintarg("gt");
    728   text_t doclink = "<a href=\"_httpdocument_&cl=";
    729 
    730   text_t &arg_d = args["d"];
    731   text_t &arg_cl = args["cl"];
    732 
    733   if (arg_d.empty()) {
    734     if (arg_cl.empty()) return;
    735     OID = arg_cl;
    736     topOID = OID; // don't always want to expand from top if expanding classifications
    737     classifytype = "classify";
    738   } else {
    739     OID = arg_d;
    740     get_top (arg_d, topOID);
    741     classifytype = "Document";
    742   }
    743 
    744   // Get OIDs and metadata of all topOIDs contents (and topOID itself)
    745   text_tarray metadata;
    746   metadata.push_back ("Title");
    747   metadata.push_back ("haschildren");
    748   metadata.push_back ("doctype");
    749   //  metadata.push_back ("hastxt");
    750 
    751   get_contents (topOID, classifytype, metadata, totalcols,
    752         args["c"], collectproto, response, logout);
    753   int excess = countchar (topOID.begin(), topOID.end(), '.');
    754   totalcols -= excess;
    755 
    756   // allow for pointer
    757   if (classifytype == "Document" && !gt) totalcols += 2;
    758   else totalcols += 1;
    759 
    760   ResultDocInfo_tarray::const_iterator thissection = response.docInfo.begin();
    761   ResultDocInfo_tarray::const_iterator lastsection = response.docInfo.end();
    762  
    763   int count = 1;
    764   while (thissection != lastsection) {
    765    
    766     const text_t &title = (*thissection).metadata[0].values[0];
    767     const int haschildren = (*thissection).metadata[1].values[0].getint();
    768     const text_t &doctype = (*thissection).metadata[2].values[0];
    769 
    770     text_t icontabs, tab, pointer;
    771 
    772     // set up icon
    773     icon = "_document:iconsmalltext_";
    774     if (is_top((*thissection).OID))
    775       if (classifytype == "Document") icon = "_document:iconopenbook_";
    776       else
    777     if (doctype == "classify") icon = "_document:iconopenbookshelf_";
    778     else icon = "_document:iconclosedbook_";
    779     else if (haschildren)
    780       if (classifytype == "Document") icon = "_document:iconopenfolder_";
    781       else icon = "_document:iconopenbookshelf_";
    782    
    783     // set up tabbing
    784     if ((classifytype == "classify") && (doctype != "classify"))
    785       tabcols = lasttabcols + 1;
    786     else {
    787       tabcols = countchar ((*thissection).OID.begin(), (*thissection).OID.end(), '.');
    788       lasttabcols = tabcols;
    789     }
    790     tabcols -= excess;
    791 
    792     for (int i = 0; i < tabcols; i++)
    793       icontabs += "_document:icontab_";
    794    
    795     // set up pointer
    796     if (classifytype == "Document" && !gt) {
    797       if ((*thissection).OID == OID) pointer = "_document:iconpointer_";
    798       else pointer = "_document:icontab_";
    799       tabcols ++;
    800     }
    801    
    802     int colsremaining = totalcols - tabcols;
    803 
    804     if (tabcols > 0) {
    805       tab = "<td";
    806       if (tabcols > 1) tab += " colspan=" + text_t(tabcols);
    807       tab += ">" + icontabs + pointer + "</td>";
    808     }
    809 
    810     textout << outconvert << disp << "<tr>" << tab << "<td>";
    811    
    812     if ((classifytype == "Document") && (is_top((*thissection).OID)) &&
    813     (args.getintarg("x")))
    814       textout << outconvert << disp << icon << "</td><td";
    815 
    816     else {
    817       if (!gt) {
    818     const text_t &thisOID = (*thissection).OID;
    819     text_t link;
    820     if (is_top (thisOID))
    821       if (classifytype == "classify")
    822         link = doclink + arg_cl + "&d=" + thisOID + "\">";
    823       else
    824         if (arg_cl.empty())
    825           link.clear();
    826         else if (arg_cl == "search")
    827           link = "<a href=\"_httpquery_\">";
    828         else
    829           link = doclink + arg_cl + "\">";
    830     else
    831       if (haschildren)
    832         if (classifytype == "classify")
    833           link = doclink + thisOID + ".pr\">";
    834         else
    835           link = doclink + arg_cl + "&d=" + thisOID + ".pr\">";
    836       else
    837         if (classifytype == "classify")
    838           link = doclink + thisOID + "\">";
    839         else
    840           link = doclink + arg_cl + "&d=" + thisOID + "\">";
    841    
    842     textout << outconvert << disp << link;
    843       } else {
    844     textout << "<a href=\"#" << count << "\">";
    845     count ++;
    846       }
    847    
    848       textout << outconvert << disp << icon << "</a></td><td";
    849     }
    850     if (colsremaining > 1) textout << " colspan=" << colsremaining;
    851     textout << outconvert << disp << ">" << title << "</td></tr>\n";
    852 
    853     thissection ++;
    854   }
    855 }
    856 
    857 /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    858 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
    859 
    860 // set_arrow_macros sets the _httpprevarrow_ and _httpnextarrow_ macros
    861 // it shouldn't be called if OID is the top level of a book
    862 // as the "hasprevious" and "hasnext" metadata won't be set
    863 // when the filter can't get OIDs parent info - one day I'll
    864 // fix this ;-)
    865 void set_arrow_macros (const text_t &OID, const text_t &classifytype,
    866                bool showtoppage, displayclass &disp,
    867                recptproto *collectproto, const text_t &collection,
    868                ostream &logout) {
    869 
    870   if (OID.empty()) return;
    871 
    872   text_tarray metadata;
    873   FilterResponse_t response;
    874 
    875   metadata.push_back ("haschildren");
    876   metadata.push_back ("hasnext");
    877   metadata.push_back ("hasprevious");
    878   // get "haschildren", "hasnext" and "hasprevious" metadata for OID
    879   if (get_info (OID, collection, metadata, false, collectproto, response, logout)) {
    880 
    881     text_t haschildren = response.docInfo[0].metadata[0].values[0];
    882     text_t hasnext = response.docInfo[0].metadata[1].values[0];
    883     text_t hasprevious = response.docInfo[0].metadata[2].values[0];
    884 
    885     if ((classifytype == "Hierarchy") || (classifytype == "Book")) {
    886       if (haschildren == "1")
    887     disp.setmacro ("httpnextarrow", "document",
    888                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.fc,_httpdocument_&cl=_cgiargcl_.fc)");
    889       else if (hasnext == "1")
    890     disp.setmacro ("httpnextarrow", "document",
    891                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ns,_httpdocument_&cl=_cgiargcl_.ns)");
    892       else {
    893     // see if parent has younger siblings
    894     if (get_info (OID + ".pr", collection, metadata, false, collectproto, response, logout)) {
    895       if (!response.docInfo[0].metadata.empty() &&
    896           response.docInfo[0].metadata[1].values[0] == "1")
    897         disp.setmacro ("httpnextarrow", "document",
    898                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.pr.ns,_httpdocument_&cl=_cgiargcl_.pr.ns)");
    899     }
    900       }
    901 
    902       if (hasprevious == "1") {
    903     // see if OIDs older sibling has children
    904     if (get_info (OID + ".ps", collection, metadata, false, collectproto, response, logout)) {
    905       if (response.docInfo[0].metadata[0].values[0] == "1")
    906         disp.setmacro ("httpprevarrow", "document",
    907                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ps.lc,_httpdocument_&cl=_cgiargcl_.ps.lc)");
    908       else
    909         disp.setmacro ("httpprevarrow", "document",
    910                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ps,_httpdocument_&cl=_cgiargcl_.ps)");
    911     }
    912       } else if (showtoppage && !is_top (OID))
    913     disp.setmacro ("httpprevarrow", "document",
    914                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.pr,_httpdocument_&cl=_cgiargcl_.pr)");
    915     }
    916 
    917     else {
    918       if (hasnext == "1")
    919     disp.setmacro ("httpnextarrow", "document",
    920                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ns,_httpdocument_&cl=_cgiargcl_.ns)");
    921       if (hasprevious == "1")
    922     disp.setmacro ("httpprevarrow", "document",
    923                "_If_(_cgiargd_,_httpdocument_&cl=_cgiargcl_&d=_cgiargd_.ps,_httpdocument_&cl=_cgiargcl_.ps)");
    924     }
    925   }
    926 }
     424
     425    // contracted table of contents
     426    contracted_contents (args, browsermap, formatinfo, collectproto,
     427             disp, outconvert, textout, logout);
     428
     429  }
     430}
  • trunk/gsdl/src/recpt/browsetools.h

    r533 r649  
    11/**********************************************************************
    22 *
    3  * browsetools.h -- 
     3 * browsetools.h --
    44 * Copyright (C) 1999  The New Zealand Digital Library Project
    55 *
     
    3636#include "recptproto.h"
    3737#include "formattools.h"
     38#include "browserclass.h"
    3839
     40typedef map<text_t, format_t*, lttext_t> format_tmap;
    3941
    40 void output_document_toc (cgiargsclass &args, const formatinfo_t &formatinfo,
    41               recptproto *collectproto, displayclass &disp,
    42               outconvertclass &outconvert, ostream &textout,
    43               ostream &logout);
    44 
    45 void output_standard_toc (const text_t &classifytype, const formatinfo_t &formatinfo,
    46               text_t &formatstring, cgiargsclass &args,
    47               recptproto *collectproto, displayclass &disp,
    48               outconvertclass &outconvert, ostream &textout,
    49               ostream &logout);
    50 
    51 void set_arrow_macros (const text_t &OID, const text_t &classifytype,
    52                bool showtoppage, displayclass &disp,
    53                recptproto *collectproto, const text_t &collection,
    54                ostream &logout);
     42void output_toc (cgiargsclass &args, browsermapclass *browsermap,
     43                 formatinfo_t &formatinfo, recptproto *collectproto,
     44                 displayclass &disp, outconvertclass &outconvert,
     45                 ostream &textout, ostream &logout);
    5546
    5647#endif
  • trunk/gsdl/src/recpt/documentaction.cpp

    r604 r649  
    2828/*
    2929   $Log$
     30   Revision 1.26  1999/10/10 08:14:06  sjboddie
     31   - metadata now returns mp rather than array
     32   - redesigned browsing support (although it's not finished so
     33   won't currently work ;-)
     34
    3035   Revision 1.25  1999/09/17 04:46:05  sjboddie
    3136   fixed a couple of problems with 'unknown' classifier
     
    225230}
    226231
    227 bool documentaction::init (ostream &logout) {
    228 
    229   // classify_meta should contain names of all classifiers supported
    230   // by this receptionist. classifications using metadata names not
    231   // in this list will be displayed as "unknown"
    232   classify_meta.insert ("Title");
    233   classify_meta.insert ("List");
    234   classify_meta.insert ("Creator");
    235   classify_meta.insert ("Series");
    236   classify_meta.insert ("Date");
    237   classify_meta.insert ("Subject");
    238   classify_meta.insert ("Organization");
    239   classify_meta.insert ("Howto");
    240   classify_meta.insert ("Topic");
    241   classify_meta.insert ("Browse");
    242   classify_meta.insert ("People");
    243 
    244   return action::init (logout);
    245 }
    246 
    247232bool documentaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args,
    248233                    ostream &logout) {
     
    284269
    285270void documentaction::get_cgihead_info (cgiargsclass &/*args*/, response_t &response,
    286                      text_t &response_data, ostream &/*logout*/) {
     271                       text_t &response_data, ostream &/*logout*/) {
    287272  response = content;
    288273  response_data = "text/html";
    289274}
    290275
    291 
    292276// set_widthtspace calculates how wide the spaces in the nav bar should
    293277// be and sets the appropriate macro
    294 void documentaction::set_spacemacro (displayclass &disp, const FilterResponse_t &response) {
     278void documentaction::set_spacemacro (displayclass &disp, FilterResponse_t &response) {
    295279
    296280  text_t width;
     
    298282
    299283  int numc = response.docInfo.size();
    300   ResultDocInfo_tarray::const_iterator dochere = response.docInfo.begin();
    301   ResultDocInfo_tarray::const_iterator docend = response.docInfo.end();
     284  ResultDocInfo_tarray::iterator dochere = response.docInfo.begin();
     285  ResultDocInfo_tarray::iterator docend = response.docInfo.end();
    302286   
    303287  disp.expandstring ("Global", "_pagewidth_", width);
     
    308292 
    309293  while (dochere != docend) {
    310     text_t title = (*dochere).metadata[0].values[0];
    311     text_tset::const_iterator it = classify_meta.find (title);
    312     if (it == classify_meta.end()) title = "Unknown";
     294    const text_t &title = (*dochere).metadata["Title"].values[0];
    313295
    314296    disp.expandstring ("document", "_" + title + "width_", width);
     297    if (width == ("_" + title + "width_"))
     298      disp.expandstring ("document", "_defaultwidth_", width);
    315299    iwidth += width.getint();
    316300    dochere ++;
     
    325309
    326310// set_navbarmacros sets _navigationbar_, _javaimagesnavbar_ and _httpbrowseXXX_ macros
    327 void documentaction::set_navbarmacros (displayclass &disp, const FilterResponse_t &response,
     311// reponse contains 1 metadata field (Title)
     312void documentaction::set_navbarmacros (displayclass &disp, FilterResponse_t &response,
    328313                       cgiargsclass &args) {
    329314
     
    334319  get_top (args["cl"], topparent);
    335320  int numc = response.docInfo.size();
    336   ResultDocInfo_tarray::const_iterator dochere = response.docInfo.begin();
    337   ResultDocInfo_tarray::const_iterator docend = response.docInfo.end();
     321  ResultDocInfo_tarray::iterator dochere = response.docInfo.begin();
     322  ResultDocInfo_tarray::iterator docend = response.docInfo.end();
    338323
    339324  navigationbar += "<nobr>\n";
     
    347332   
    348333  while (dochere != docend) {
    349     text_t title = (*dochere).metadata[0].values[0];
    350     const text_t &classifytype = (*dochere).metadata[1].values[0];
    351 
    352     text_tset::const_iterator it = classify_meta.find (title);
    353     if (it == classify_meta.end()) title = "Unknown";
    354      
     334    text_t title = (*dochere).metadata["Title"].values[0];
     335
     336    bool unknown = false;
     337
     338    // test the _XXXwidth_ macro to see if image macros are
     339    // defined for this type of classification - if not we'll
     340    // just display the text
     341    text_t tmpwidth;
     342    disp.expandstring ("document", "_" + title + "width_", tmpwidth);
     343    if (tmpwidth == ("_" + title + "width_")) unknown = true;
     344
    355345    // if we're inside a document all the classification buttons should be enabled
    356     if (arg_d.empty() && ((*dochere).OID == topparent))
    357       navigationbar += "_imagespacer__icontab" + title + "green_";
    358     else {
    359       navigationbar += "_imagespacer__image" + title + "_";
    360      
     346    if (arg_d.empty() && ((*dochere).OID == topparent)) {
     347      if (unknown) navigationbar += "_imagespacer_&nbsp;" + title + "&nbsp;";
     348      else navigationbar += "_imagespacer__icontab" + title + "green_";
     349    } else {
     350
    361351      // set the _httpbrowseXXX_ macro for this classification
    362       text_t link;
    363       if (classifytype == "HTML")
    364     link = "_httppagex_(html)&hp=" + (*dochere).OID + ".fc";
    365       else
    366     link = "_httpdocument_&cl=" + (*dochere).OID;
    367 
    368       if (classifytype == "AZList" || classifytype == "DateList") link += ".fc";
    369       disp.setmacro ("httpbrowse" + title, "Global", link);
    370      
    371     }
    372     javaimagesnavbar += "_java" + title + "_";
     352      if (unknown) navigationbar += "_imagespacer_&nbsp;<a href=\"_httpdocument_&cl=" +
     353             (*dochere).OID + "\">" + title + "</a>&nbsp;";
     354      else {
     355        navigationbar += "_imagespacer__image" + title + "_";
     356        disp.setmacro ("httpbrowse" + title, "Global", "_httpdocument_&cl=" + (*dochere).OID);
     357      }
     358    }
     359    if (!unknown) javaimagesnavbar += "_java" + title + "_";
    373360    dochere ++;
    374361  }
     
    376363  navigationbar += "<!-- End of Navigation Bar -->\n";
    377364  disp.setmacro ("navigationbar", "Global", navigationbar);
    378   if (args.getintarg("v") == 0) 
     365  if (args.getintarg("v") == 0)
    379366    disp.setmacro ("javaimagesnavbar", "Global", javaimagesnavbar);
    380367}
    381 
    382368
    383369// define all the macros which might be used by other actions
    384370// to produce pages.
    385 void documentaction::define_external_macros (const ColInfoResponse_t &/*collectinfo*/, displayclass &disp,
    386                          cgiargsclass &args, recptproto *collectproto,
    387                          ostream &logout) {
     371void documentaction::define_external_macros (const ColInfoResponse_t &/*collectinfo*/,
     372                         displayclass &disp, cgiargsclass &args,
     373                         recptproto *collectproto, ostream &logout) {
    388374 
    389375  // define_external_macros sets the following macros:
     
    413399  InfoFiltersResponse_t filterinfo;
    414400  FilterResponse_t response;
    415   text_tarray metadata;
     401  text_tset metadata;
    416402  text_t &collection = args["c"];
    417403
     
    424410      if (filterinfo.filterNames.find ("BrowseFilter") != filterinfo.filterNames.end()) {
    425411   
    426     metadata.push_back ("Title");
    427     metadata.push_back ("classifytype");
     412    metadata.insert ("Title");
    428413    bool getParents = false;
    429414    get_children ("", collection, metadata, getParents, collectproto, response, logout);
     
    443428}
    444429
    445 
    446430void documentaction::load_formatinfo (const text_tmap &colformat, int gt) {
    447431
     
    454438    ((*format_here).second == "true"))
    455439      formatinfo.DocumentImages = true;
    456     else if (((*format_here).first == "DocumentTopPages") &&
    457          ((*format_here).second == "false"))
    458       formatinfo.DocumentTopPages = false;
    459440    else if ((*format_here).first == "DocumentHeading")
    460441      formatinfo.DocumentHeading = (*format_here).second;
     
    473454    else if ((*format_here).first == "DocumentText")
    474455      formatinfo.DocumentText = (*format_here).second;
     456    else
     457      formatinfo.formatstrings[(*format_here).first] = (*format_here).second;
    475458
    476459    format_here ++;
     
    522505
    523506
    524 // sets the classificationlinks and navarrows macros
    525 void documentaction::get_classificationlinks (const text_t &arg_cl, const text_t &collection,
    526                           recptproto *collectproto, displayclass &disp,
    527                           ostream &logout) {
    528 
    529   FilterResponse_t response;
    530   text_t classificationlinks, navarrows, classtop;
    531   text_tarray metadata;
    532 
    533   metadata.push_back ("Title");
    534   metadata.push_back ("doctype");
    535   bool getParents = false;
    536 
    537   get_top (arg_cl, classtop);
    538   if (get_children (classtop, collection, metadata, getParents, collectproto, response, logout)) {
    539        
    540     // don't want links unless there are 2 or more sections
    541     if (response.docInfo.size() >= 2) {
    542 
    543       classificationlinks += "<!-- Classification Links -->\n";
    544       classificationlinks += "<table width=_pagewidth_ cellpadding=0 cellspacing=0 border=0>\n";
    545       classificationlinks += "<tr><td valign=top><center>\n";
    546      
    547       ResultDocInfo_tarray::const_iterator sechere = response.docInfo.begin();
    548       ResultDocInfo_tarray::const_iterator secend = response.docInfo.end();
    549      
    550       int lenlinks = 0;
    551       while (sechere != secend) {
    552     if ((*sechere).metadata[1].values[0] == "classify") {
    553       const text_t &sectionheading = (*sechere).metadata[0].values[0];
    554      
    555       if (((*sechere).OID == arg_cl) || is_child_of((*sechere).OID, arg_cl)) {
    556        
    557         // set the _httpprevarrow_, _httpnextarrow_ macros while we're here
    558         if (formatinfo.DocumentArrowsBottom) {
    559           if (sechere != response.docInfo.begin())
    560         disp.setmacro ("httpprevarrow", "document", "_httpdocument_&cl=" + (*(sechere-1)).OID);
    561           if ((sechere + 1) != secend)
    562         disp.setmacro ("httpnextarrow", "document", "_httpdocument_&cl=" + (*(sechere+1)).OID);
    563         }
    564        
    565         lenlinks += sectionheading.size();
    566         classificationlinks += "<b>" + sectionheading + "</b>";
    567         if (lenlinks > 50) {
    568           classificationlinks += "<br>\n";
    569           lenlinks = 0;
    570         } else {
    571           if (sechere+1 != secend) classificationlinks += "&nbsp;&nbsp;&nbsp;\n";
    572           lenlinks += 3;
    573         }
    574       } else {
    575         lenlinks += sectionheading.size();
    576         classificationlinks += "<a href=\"_httpdocument_&cl=" + (*sechere).OID + "\">";
    577         classificationlinks += sectionheading + "</a>";
    578         if (lenlinks > 50) {
    579           classificationlinks += "<br>\n";
    580           lenlinks = 0;
    581         } else {
    582           if (sechere+1 != secend) classificationlinks += "&nbsp;&nbsp;&nbsp;\n";
    583           lenlinks += 3;
    584         }
    585       }
    586     }
    587     sechere ++;
    588       }
    589      
    590       classificationlinks += "\n</center></td></tr></table>\n";
    591       classificationlinks += "<!-- End of Classification Links -->\n";
    592      
    593       disp.setmacro ("classificationlinks", "document", classificationlinks);
    594     }
    595   }
    596 }
    597 
    598 
    599507// define all the macros which are related to pages generated
    600508// by this action. we also load up the formatinfo structure
    601509// here (it's used in do_action as well as here)
    602 void documentaction::define_internal_macros (const ColInfoResponse_t &collectinfo, displayclass &disp,
    603                          cgiargsclass &args, recptproto *collectproto,
    604                          ostream &logout) {
     510void documentaction::define_internal_macros (const ColInfoResponse_t &collectinfo,
     511                         displayclass &disp, cgiargsclass &args,
     512                         recptproto *collectproto, ostream &logout) {
    605513 
    606514  // define_internal_macros sets the following macros:
     
    609517 
    610518  // _imagethispage_        the title image to be displayed at top right of page
    611  
    612   // _classificationlinks_  the links between classifications to be displayed
    613   //                        at top of list or datelist classifications
    614 
    615   // _httpprevarrow_        these are set if next or previous arrows
    616   // _httpnextarrow_        are to be used - (i.e. if it's an AZList or a DateList
    617   //                        classifytype at a top level or if it's a Book or a
    618   //                        Hierarchy classifytype at document level
    619519
    620520  // _navarrows_            this may be overridden to "" when format option
     
    633533  if (collectproto == NULL) return;
    634534 
    635   text_tarray metadata;
     535  text_tset metadata;
    636536  FilterResponse_t response;
    637537  text_t &arg_d = args["d"];
     
    644544    disp.setmacro("navarrows", "document", "");
    645545
    646   metadata.push_back ("Title");
    647   metadata.push_back ("classifytype");
    648   metadata.push_back ("archivedir");
     546  metadata.insert ("Title");
    649547 
    650548  if (!arg_d.empty()) {
    651549    // we're at document level
     550
     551    metadata.insert ("archivedir");
    652552   
    653553    // get metadata for this document and it's parents
     
    655555      disp.setmacro ("header", "document", "_textheader_");
    656556
    657       text_t pagetitle;
    658       if (gt)
    659     pagetitle = *(response.docInfo[0].metadata[0].values.begin());
    660       else {
    661     text_tarray::const_iterator this_title = response.docInfo[0].metadata[0].values.begin();
    662     text_tarray::const_iterator end_title = response.docInfo[0].metadata[0].values.end();
    663     while (this_title != end_title) {
    664       if ((this_title + 1) == end_title) pagetitle += *this_title;
    665       else pagetitle += *this_title + ": ";
    666       this_title ++;
     557      text_t pagetitle = response.docInfo[0].metadata["Title"].values[0];
     558      if (!gt) {
     559    MetadataInfo_t *parent = response.docInfo[0].metadata["Title"].parent;
     560    while (parent != NULL) {
     561      pagetitle += ": " + parent->values[0];
     562      parent = parent->parent;
    667563    }
    668564      }
    669565      disp.setmacro ("pagetitle", "document", pagetitle);
    670       disp.setmacro ("thisOID", "Global", response.docInfo[0].metadata[2].values[0]);
    671 
    672       text_t &classifytype = response.docInfo[0].metadata[1].values[0];
    673       if (classifytype.empty()) classifytype = "Book"; // defaults to Book
    674 
    675       // set arrow macros if required
    676       if (((classifytype == "Book") && (formatinfo.DocumentArrowsTop || formatinfo.DocumentArrowsBottom)) ||
    677       ((classifytype == "Hierarchy") && formatinfo.DocumentArrowsBottom))
    678     set_arrow_macros (arg_d, classifytype, formatinfo.DocumentTopPages,
    679               disp, collectproto, collection, logout);
     566      disp.setmacro ("thisOID", "Global", response.docInfo[0].metadata["archivedir"].values[0]);
    680567     
    681568      if (args["u"] != "1")
     
    691578      if (get_info (classtop, collection, metadata, false, collectproto, response, logout)) {
    692579     
    693     text_t title = response.docInfo[0].metadata[0].values[0];
    694     text_t &classifytype = response.docInfo[0].metadata[1].values[0];
    695 
    696     text_tset::const_iterator it = classify_meta.find (title);
    697     if (it == classify_meta.end()) title = "Unknown";
    698 
    699     disp.setmacro ("pagetitle", "document", "_text" + title + "page_");
    700     disp.setmacro ("imagethispage", "document", "_icon" + title + "page_");
    701 
    702     // now get the metadata for each child of top level
    703     // so we can generate the _classificationlinks_ and arrow macros
    704     // (if they're required by the current classification type)
    705    
    706     if ((classifytype == "AZList") || (classifytype == "DateList"))
    707       get_classificationlinks (arg_cl, collection, collectproto, disp, logout);
    708      
     580    text_t &title = response.docInfo[0].metadata["Title"].values[0];
     581    bool unknown = false;
     582
     583    // test the _XXXwidth_ macro to see if image macros are
     584    // defined for this type of classification - if not we'll
     585    // just display the text
     586    text_t tmp;
     587    disp.expandstring ("document", "_" + title + "width_", tmp);
     588    if (tmp == ("_" + title + "width_")) unknown = true;
     589
     590    if (unknown) {
     591      disp.setmacro ("pagetitle", "document", title);
     592      disp.setmacro ("imagethispage", "document", "<h2>" + title + "</h2>");
     593    } else {
     594      disp.setmacro ("pagetitle", "document", "_text" + title + "page_");
     595      disp.setmacro ("imagethispage", "document", "_icon" + title + "page_");
     596    }
    709597      }
    710598    }
     
    713601
    714602
    715 bool documentaction::do_action (cgiargsclass &args, const ColInfoResponse_t &collectinfo,
     603bool documentaction::do_action (cgiargsclass &args, const ColInfoResponse_t &/*collectinfo*/,
    716604                recptproto *collectproto, displayclass &disp,
    717605                outconvertclass &outconvert, ostream &textout,
     
    725613  } else { 
    726614
    727     text_tarray metadata;
    728     FilterResponse_t response;
    729     text_t toptitle, toptype, thistype, formatstring;
    730 
    731     text_t &collection = args["c"];
    732     text_t &arg_d = args["d"];
    733     text_t &arg_cl = args["cl"];
    734    
    735     text_t OID = arg_d;
    736     if (arg_d.empty()) OID = arg_cl;
    737    
     615    text_t OID = args["d"];
     616    if (OID.empty()) OID = args["cl"];
     617    if (OID.empty()) {
     618      textout << outconvert << disp << "Document contains no data_document:footer_\n";
     619      return true;
     620    }
     621
    738622    textout << outconvert << disp << "_document:header_\n"
    739623        << "_document:content_\n";
    740624   
    741     if (arg_d.empty() && arg_cl.empty()) {
    742       textout << outconvert << disp << "Document contains no data_document:footer_\n";
    743       return true;
    744     }
    745    
    746     // get the classifytitle and classifytype for both the top level
    747     // and the current level (using getParent=true)
    748     metadata.push_back ("Title");
    749     metadata.push_back ("classifytype");
    750     if (get_info (OID, collection, metadata, true, collectproto, response, logout)) {
    751       toptitle = response.docInfo[0].metadata[0].values[0];
    752       toptype = response.docInfo[0].metadata[1].values[0];
    753       thistype = response.docInfo[0].metadata[1].values.back();
    754     }
    755 
    756     text_t formatkey = toptype + toptitle;
    757     if (!arg_d.empty()) formatkey = toptype + "Document";
    758 
    759     text_tmap::const_iterator it = collectinfo.format.find(formatkey);
    760     if (it != collectinfo.format.end()) formatstring = (*it).second;
    761 
    762625    // output the table of contents
    763     if (!arg_d.empty()) {
    764      
    765       if (toptype == "Hierarchy")
    766     output_standard_toc (thistype, formatinfo, formatstring, args,
    767                  collectproto, disp, outconvert, textout, logout);
    768 
    769       else
    770     output_document_toc (args, formatinfo, collectproto, disp,
    771                  outconvert, textout, logout);
    772 
    773     } else {
    774       output_standard_toc (thistype, formatinfo, formatstring, args,
    775                collectproto, disp, outconvert, textout, logout);
    776     }
     626    output_toc (args, recpt->get_browsermap_ptr(), formatinfo,
     627        collectproto, disp, outconvert, textout, logout);
    777628
    778629    // output the document text
     
    785636}
    786637
    787 void documentaction::output_text (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     638void documentaction::output_text (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    788639                  const TermInfo_tarray &terminfo, const text_t &OID,
    789                   bool highlight, const text_t &hastxt, int wanttext,
    790                   text_t &collection, recptproto *collectproto, displayclass &disp,
    791                   outconvertclass &outconvert, ostream &textout,
    792                   ostream &logout) {
     640                  bool highlight, int hastxt, int wanttext,
     641                  text_t &collection, recptproto *collectproto,
     642                  displayclass &disp, outconvertclass &outconvert,
     643                  ostream &textout, ostream &logout) {
    793644 
    794645  DocumentRequest_t docrequest;
     
    796647  comerror_t err;
    797648
    798   if (hastxt == "1") {
     649  if (hastxt == 1) {
    799650
    800651    if (wanttext) {
     
    830681  FilterResponse_t inforesponse;
    831682  FilterResponse_t queryresponse;
    832   text_tarray metadata;
     683  text_tset metadata;
    833684  bool getParents = false;
    834685  bool highlight = false;
     
    849700  parse_formatstring (formatinfo.DocumentText, formatlistptr, metadata, getParents);
    850701
    851   metadata.push_back("hastxt");
    852   metadata.push_back("haschildren");
     702  metadata.insert ("hastxt");
     703  metadata.insert ("haschildren");
    853704 
    854705  if (formatinfo.DocumentText == "[Text]")
     
    864715
    865716  if (get_info (OID, collection, metadata, getParents, collectproto, inforesponse, logout)) {
    866     text_t hastxt = inforesponse.docInfo[0].metadata[metasize-2].values.back();
    867     text_t &haschildren = inforesponse.docInfo[0].metadata[metasize-1].values.back();
     717    int hastxt = inforesponse.docInfo[0].metadata["hastxt"].values[0].getint();
     718    int haschildren = inforesponse.docInfo[0].metadata["haschildren"].values[0].getint();
    868719
    869720    if (arg_gt == 0) {
     
    879730      // text is to be expanded
    880731      text_t exOID = OID;
    881       if (haschildren != "1") exOID = get_parent (OID);
     732      if (haschildren != 1) exOID = get_parent (OID);
    882733      if (exOID.empty()) exOID = OID;
    883734   
    884735      // if we're not in a document (i.e. we're in a top level classification)
    885       // we need to pass the "classify" string to get_contents so that it
     736      // we need to pass "is_classify = true" to get_contents so that it
    886737      // doesn't recurse all the way through each document in the classification
    887       text_t classifytype;
    888       if (args["d"].empty()) classifytype = "classify";
    889 
    890       int i = 0; // not used
    891       get_contents (exOID, classifytype, metadata, i, collection,
     738      bool is_classify = false;
     739      if (args["d"].empty()) is_classify = true;
     740
     741      get_contents (exOID, is_classify, metadata, collection,
    892742            collectproto, inforesponse, logout);
    893743   
    894       ResultDocInfo_tarray::const_iterator sechere = inforesponse.docInfo.begin();
    895       ResultDocInfo_tarray::const_iterator secend = inforesponse.docInfo.end();
     744      ResultDocInfo_tarray::iterator sechere = inforesponse.docInfo.begin();
     745      ResultDocInfo_tarray::iterator secend = inforesponse.docInfo.end();
    896746   
    897747      if (arg_gt == 1) {
     
    902752    int seccount = 0;
    903753    while (sechere != secend) {
    904       const text_t &shastxt = (*sechere).metadata[metasize-2].values.back();
    905       if (shastxt == "1") seccount ++;
     754      int shastxt = (*sechere).metadata["hastxt"].values[0].getint();
     755      if (shastxt == 1) seccount ++;
    906756      if (seccount > 10) break;
    907757      sechere ++;
     
    927777      textout << outconvert << disp << "\n<p><a name=" << count << "></a>\n";
    928778
    929       const text_t &shastxt = (*sechere).metadata[metasize-2].values.back();
     779      int shastxt = (*sechere).metadata["hastxt"].values[0].getint();
    930780
    931781      output_text (*sechere, formatlistptr, queryresponse.termInfo,
  • trunk/gsdl/src/recpt/documentaction.h

    r600 r649  
    3333#include "gsdlconf.h"
    3434#include "formattools.h"
     35#include "receptionist.h"
    3536
    3637class documentaction : public action {
     
    3839protected:
    3940
     41  receptionist *recpt;
     42
    4043  void load_formatinfo (const text_tmap &colformat, int gt);
    4144
    42   void set_spacemacro (displayclass &disp, const FilterResponse_t &response);
     45  void set_spacemacro (displayclass &disp, FilterResponse_t &response);
    4346
    44   void set_navbarmacros (displayclass &disp, const FilterResponse_t &response, cgiargsclass &args);
     47  void set_navbarmacros (displayclass &disp, FilterResponse_t &response,
     48             cgiargsclass &args);
    4549
    4650  void set_java_macros (cgiargsclass &args, displayclass &disp);
     
    5054                ostream &logout);
    5155
    52   virtual void output_text (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     56  virtual void output_text (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    5357                const TermInfo_tarray &terminfo, const text_t &OID,
    54                 bool highlight, const text_t &hastxt, int wanttext,
    55                 text_t &collection, recptproto *collectproto, displayclass &disp,
    56                 outconvertclass &outconvert, ostream &textout,
    57                 ostream &logout);
     58                bool highlight, int hastxt, int wanttext,
     59                text_t &collection, recptproto *collectproto,
     60                displayclass &disp, outconvertclass &outconvert,
     61                ostream &textout, ostream &logout);
    5862
    5963  virtual void output_document (const text_t &OID, cgiargsclass &args,
     
    6771
    6872  formatinfo_t formatinfo;
    69   text_tset classify_meta;
    70  
    7173
    7274public:
     
    7476  virtual ~documentaction ();
    7577
    76   bool init (ostream &logout);
     78  text_t get_action_name () {return "d";}
    7779
    78   text_t get_action_name () {return "d";}
     80  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
    7981
    8082  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args,
     
    8486                         text_t &response_data, ostream &logout);
    8587
    86   void define_external_macros (const ColInfoResponse_t &collectinfo, displayclass &disp,
    87                    cgiargsclass &args, recptproto *collectproto,
    88                    ostream &logout);
     88  void define_external_macros (const ColInfoResponse_t &collectinfo,
     89                   displayclass &disp, cgiargsclass &args,
     90                   recptproto *collectproto, ostream &logout);
    8991
    90   void define_internal_macros (const ColInfoResponse_t &collectinfo, displayclass &disp,
    91                    cgiargsclass &args, recptproto *collectproto,
    92                    ostream &logout);
     92  void define_internal_macros (const ColInfoResponse_t &collectinfo,
     93                   displayclass &disp, cgiargsclass &args,
     94                   recptproto *collectproto, ostream &logout);
    9395
    9496  bool do_action (cgiargsclass &args, const ColInfoResponse_t &collectinfo,
  • trunk/gsdl/src/recpt/formattools.cpp

    r636 r649  
    2828/*
    2929   $Log$
     30   Revision 1.12  1999/10/10 08:14:07  sjboddie
     31   - metadata now returns mp rather than array
     32   - redesigned browsing support (although it's not finished so
     33   won't currently work ;-)
     34
    3035   Revision 1.11  1999/09/28 20:38:19  rjmcnab
    3136   fixed a couple of bugs
     
    7378
    7479// a few function prototypes
    75 static text_t format_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     80static text_t format_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    7681                 const text_t &link, const text_t &icon, const text_t &text);
    7782
    7883static bool parse_action (text_t::const_iterator &here, const text_t::const_iterator &end,
    79               format_t *formatlistptr, text_tarray &metadata, bool &getParents,
    80               text_tmap &metamap, int &metacount);
     84              format_t *formatlistptr, text_tset &metadata, bool &getParents);
    8185
    8286void metadata_t::clear() {
    8387  metaname.clear();
    84   metaindex = 0;
    8588  metacommand = mNone;
    8689  parentcommand = pNone;
    87   parentindex = 0;
    8890  parentoptions.clear();
    8991};
     
    120122  DocumentButtons.push_back ("Expand Contents");
    121123  DocumentText = "[Text]";
     124  formatstrings.erase (formatstrings.begin(), formatstrings.end());
     125}
     126
     127// returns false if key isn't in formatstringmap
     128bool get_formatstring (const text_t &key, const text_tmap &formatstringmap,
     129               text_t &formatstring) {
     130
     131  formatstring.clear();
     132  text_tmap::const_iterator it = formatstringmap.find(key);
     133  if (it == formatstringmap.end()) return false;
     134  formatstring = (*it).second;
     135  return true;
     136}
     137// tries to find "key1key2" then "key1" then "key2"
     138bool get_formatstring (const text_t &key1, const text_t &key2, 
     139               const text_tmap &formatstringmap,
     140               text_t &formatstring) {
     141
     142  formatstring.clear();
     143  text_tmap::const_iterator it = formatstringmap.find(key1 + key2);
     144  if (it != formatstringmap.end()) {
     145    formatstring = (*it).second;
     146    return true;
     147  }
     148  it = formatstringmap.find(key1);
     149  if (it != formatstringmap.end()) {
     150    formatstring = (*it).second;
     151    return true;
     152  }
     153  it = formatstringmap.find(key2);
     154  if (it != formatstringmap.end()) {
     155    formatstring = (*it).second;
     156    return true;
     157  }
     158  return false;
    122159}
    123160
     
    152189static void get_parent_options (text_t &instring, metadata_t &metaoption) {
    153190
    154   metaoption.clear();
    155191  text_t meta, com, op;
    156192  bool inbraces = false;
     
    175211  else if (com == "Top")
    176212    metaoption.parentcommand = pTop;
    177   else if (is_number(com)) {
    178     metaoption.parentcommand = pIndex;
    179     metaoption.metaindex = com.getint();
    180   } else if (com == "All") {
     213  else if (com == "All") {
    181214    metaoption.parentcommand = pAll;
    182215    metaoption.parentoptions = op;
     
    184217}
    185218
    186 static bool parse_meta (text_t &meta, int &count, decision_t &decision,
    187             text_tarray &metadata, bool &getParents, text_tmap &metamap) {
     219static void parse_meta (text_t &meta, metadata_t &metaoption,
     220            text_tset &metadata, bool &getParents) {
     221
     222  if (meta.size() > 8 && (substr(meta.begin(), meta.begin()+8) == "cgisafe:")) {
     223    metaoption.metacommand = mCgiSafe;
     224    meta = substr (meta.begin()+8, meta.end());
     225  }
    188226
    189227  if (meta.size() > 7 && (substr (meta.begin(), meta.begin()+6) == "parent")) {
    190228    getParents = true;
    191     metadata_t metaoption;
    192229    get_parent_options (meta, metaoption);
    193     decision.meta = metaoption;
    194   }
    195   text_tmap::const_iterator it;
    196   if ((it = metamap.find(meta)) != metamap.end()) {
    197       decision.meta.metaindex = (*it).second.getint();
    198   } else {
    199     metamap[meta] = count;
    200     metadata.push_back (meta);
    201     decision.meta.metaindex = count;
    202     count ++;
    203   }
    204   return true;
    205 }
    206 
    207 static bool parse_meta (text_t &meta, int &count, format_t *formatlistptr,
    208             text_tarray &metadata, bool &getParents, text_tmap &metamap) {
     230  }
     231
     232  metadata.insert (meta);
     233  metaoption.metaname = meta;
     234}
     235
     236static void parse_meta (text_t &meta, format_t *formatlistptr,
     237            text_tset &metadata, bool &getParents) {
    209238 
    210239  if (meta == "link")
     
    224253  else {
    225254    formatlistptr->command = comMeta;
    226 
    227     if (meta.size() > 8 && (substr(meta.begin(), meta.begin()+8) == "cgisafe:")) {
    228       formatlistptr->meta.metacommand = mCgiSafe;
    229       meta = substr (meta.begin()+8, meta.end());
    230     }
    231 
    232     if (meta.size() > 7 && (substr (meta.begin(), meta.begin()+6) == "parent")) {
    233       getParents = true;
    234       metadata_t metaoption;
    235       get_parent_options (meta, metaoption);
    236       formatlistptr->meta = metaoption;
    237     }
    238 
    239     text_tmap::const_iterator it;
    240     if ((it = metamap.find(meta)) != metamap.end()) {
    241       formatlistptr->meta.metaindex = (*it).second.getint();
    242     } else {
    243       metamap[meta] = count;
    244       metadata.push_back (meta);
    245       formatlistptr->meta.metaindex = count;
    246       count ++;
    247     }
    248     formatlistptr->meta.metaname = meta;
    249   }
    250   return true;
     255    parse_meta (meta, formatlistptr->meta, metadata, getParents);
     256  }
    251257}
    252258
    253259static bool parse_string (const text_t &formatstring, format_t *formatlistptr,
    254               text_tarray &metadata, bool &getParents,
    255               text_tmap &metamap, int &metacount) {
     260              text_tset &metadata, bool &getParents) {
    256261
    257262  text_t text;
     
    273278    text.clear();
    274279      }
    275       if (parse_action (++here, end, formatlistptr, metadata,
    276             getParents, metamap, metacount)) {
     280      if (parse_action (++here, end, formatlistptr, metadata, getParents)) {
    277281    formatlistptr->nextptr = new format_t();
    278282    formatlistptr = formatlistptr->nextptr;
     
    295299    here ++;
    296300      }
    297       if (parse_meta (meta, metacount, formatlistptr, metadata, getParents, metamap)) {
    298     formatlistptr->nextptr = new format_t();
    299     formatlistptr = formatlistptr->nextptr;
    300       }
     301      parse_meta (meta, formatlistptr, metadata, getParents);
     302      formatlistptr->nextptr = new format_t();
     303      formatlistptr = formatlistptr->nextptr;
    301304
    302305    } else
     
    317320
    318321static bool parse_action (text_t::const_iterator &here, const text_t::const_iterator &end,
    319               format_t *formatlistptr, text_tarray &metadata, bool &getParents,
    320               text_tmap &metamap, int &metacount) {
     322              format_t *formatlistptr, text_tset &metadata, bool &getParents) {
    321323
    322324  text_t::const_iterator it = findchar (here, end, '}');
     
    371373      // it's metadata
    372374      text_t meta = substr (beginbracket+1, endbracket);
    373       parse_meta (meta, metacount, or_ptr, metadata, getParents, metamap);
     375      parse_meta (meta, or_ptr, metadata, getParents);
    374376
    375377    } else {
     
    390392      if ((*beginbracket == '[') && (*endbracket == ']')) {
    391393        text_t meta = substr (beginbracket+1, endbracket);
    392         decision_t decision;
    393         parse_meta (meta, metacount, formatlistptr->decision,
    394             metadata, getParents, metamap);
     394        parse_meta (meta, formatlistptr->decision.meta, metadata, getParents);
    395395        commacount ++;
    396396        text.clear();
     
    399399    } else if (commacount == 1) {
    400400      formatlistptr->ifptr = new format_t();
    401       parse_string (text, formatlistptr->ifptr, metadata,
    402             getParents, metamap, metacount);
     401      parse_string (text, formatlistptr->ifptr, metadata, getParents);
    403402      commacount ++;
    404403      text.clear();
     
    406405    } else if (commacount == 2) {
    407406      formatlistptr->elseptr = new format_t();
    408       parse_string (text, formatlistptr->elseptr, metadata,
    409             getParents, metamap, metacount);
     407      parse_string (text, formatlistptr->elseptr, metadata, getParents);
    410408      commacount ++;
    411409      text.clear();
     
    424422
    425423bool parse_formatstring (const text_t &formatstring, format_t *formatlistptr,
    426              text_tarray &metadata, bool &getParents) {
     424             text_tset &metadata, bool &getParents) {
    427425
    428426  formatlistptr->clear();
    429   metadata.erase (metadata.begin(), metadata.end());
    430427  getParents = false;
    431428
    432   text_tmap metamap;
    433   int metacount = 0;
    434   return (parse_string (formatstring, formatlistptr, metadata,
    435             getParents, metamap, metacount));
     429  return (parse_string (formatstring, formatlistptr, metadata, getParents));
    436430}
    437431
     
    440434// be of the form yyyymmdd, this is of course, crap ;)
    441435
    442 static text_t get_meta (const ResultDocInfo_t &docinfo, const metadata_t &meta) {
    443   int metasize = docinfo.metadata.size();
    444   int mindex = meta.metaindex;
    445   if (metasize < 1 || metasize <= mindex) return "";
    446   int valuesize = docinfo.metadata[mindex].values.size();
     436static text_t get_meta (ResultDocInfo_t &docinfo, const metadata_t &meta) {
     437 
     438  // make sure we have the requested metadata
     439  MetadataInfo_tmap::iterator it = docinfo.metadata.find (meta.metaname);
     440  if (it == docinfo.metadata.end()) return "";
     441
     442  MetadataInfo_t *parent = docinfo.metadata[meta.metaname].parent;
    447443
    448444  switch (meta.parentcommand) {
    449445  case pNone:
    450446    if (meta.metaname == "Date")
    451       return format_date (docinfo.metadata[mindex].values.back());
     447      return format_date (docinfo.metadata[meta.metaname].values[0]);
    452448    if (meta.metacommand == mCgiSafe)
    453       return cgi_safe (docinfo.metadata[mindex].values.back());
    454     else return docinfo.metadata[mindex].values.back();
     449      return cgi_safe (docinfo.metadata[meta.metaname].values[0]);
     450    else return docinfo.metadata[meta.metaname].values[0];
    455451
    456452  case pImmediate:
    457     if (valuesize > 1) {
     453    if (parent != NULL) {
    458454      if (meta.metaname == "Date")
    459     return format_date (docinfo.metadata[mindex].values[metasize-2]);
    460     if (meta.metacommand == mCgiSafe)
    461       return cgi_safe (docinfo.metadata[mindex].values[metasize-2]);
    462     else return docinfo.metadata[mindex].values[metasize-2];
     455    return format_date (parent->values[0]);
     456      if (meta.metacommand == mCgiSafe)
     457    return cgi_safe (parent->values[0]);
     458      else return parent->values[0];
    463459    }
    464460    break;
    465461
    466462  case pTop:
    467     if (valuesize > 1) {
     463    if (parent != NULL) {
     464      while (parent->parent != NULL) parent = parent->parent;
     465
    468466      if (meta.metaname == "Date")
    469     return format_date (docinfo.metadata[mindex].values[0]);
    470     if (meta.metacommand == mCgiSafe)
    471       return cgi_safe (docinfo.metadata[mindex].values[0]);
    472     else return docinfo.metadata[mindex].values[0];
     467    return format_date (parent->values[0]);
     468      if (meta.metacommand == mCgiSafe)
     469    return cgi_safe (parent->values[0]);
     470      else return parent->values[0];
    473471    }
    474472    break;
    475473
    476   case pIndex:
    477     if (valuesize > meta.parentindex) {
    478       if (meta.metaname == "Date")
    479     return format_date (docinfo.metadata[mindex].values[meta.parentindex]);
    480       if (meta.metacommand == mCgiSafe)
    481     return cgi_safe (docinfo.metadata[mindex].values[meta.parentindex]);
    482       else return docinfo.metadata[mindex].values[meta.parentindex];
    483     }
    484     break;
    485 
    486474  case pAll:
    487     bool first = true;
    488     text_t tmp;
    489     if (valuesize > 1) {
    490       text_tarray::const_iterator here = docinfo.metadata[mindex].values.begin();
    491       // don't want last value as that's the value of the current level (i.e. it's
    492       // not a parent
    493       text_tarray::const_iterator end = docinfo.metadata[mindex].values.end() - 1;
     475    MetadataInfo_t *parent = docinfo.metadata[meta.metaname].parent;
     476    if (parent != NULL) {
     477      text_tarray tmparray;
     478      while (parent != NULL) {
     479    tmparray.push_back (parent->values[0]);
     480    parent = parent->parent;
     481      }
     482      bool first = true;
     483      text_t tmp;
     484      text_tarray::reverse_iterator here = tmparray.rbegin();
     485      text_tarray::reverse_iterator end = tmparray.rend();
    494486      while (here != end) {
    495487    if (!first) tmp += meta.parentoptions;
     
    499491    here ++;
    500492      }
     493      if (meta.metacommand == mCgiSafe) return cgi_safe (tmp);
     494      else return tmp;
    501495    }
    502     if (meta.metacommand == mCgiSafe) return cgi_safe (tmp);
    503     else return tmp;
    504496  }
    505497  return "";
    506498}
    507499
    508 static text_t get_or (const ResultDocInfo_t &docinfo, format_t *orptr,
     500static text_t get_or (ResultDocInfo_t &docinfo, format_t *orptr,
    509501              const text_t &link, const text_t &icon, const text_t &text) {
    510502
     
    520512}
    521513
    522 static text_t get_if (const ResultDocInfo_t &docinfo, const decision_t &decision,
     514static text_t get_if (ResultDocInfo_t &docinfo, const decision_t &decision,
    523515              format_t *ifptr, format_t *elseptr, const text_t &link,
    524516              const text_t &icon, const text_t &text) {
     
    538530}
    539531
    540 text_t format_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     532text_t format_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    541533              const text_t &link, const text_t &icon, const text_t &text) {
    542534
     
    569561
    570562
    571 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     563text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    572564                 const text_t &link, const text_t &icon) {
    573565
     
    583575
    584576
    585 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr) {
     577text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr) {
    586578
    587579  text_t link = "<a href=\"_httpdocument_&cl=search&d=" + docinfo.OID + "\">";
     
    598590
    599591
    600 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     592text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    601593                 const text_t &text) {
    602594
     
    613605
    614606
    615 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     607text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    616608                 const text_t &link, const text_t &icon, const text_t &text) {
    617609
  • trunk/gsdl/src/recpt/formattools.h

    r533 r649  
    3434
    3535enum command_t {comIf, comOr, comMeta, comText, comLink, comEndLink, comNum, comIcon, comDoc};
    36 enum pcommand_t {pNone, pImmediate, pTop, pIndex, pAll};
     36enum pcommand_t {pNone, pImmediate, pTop, pAll};
    3737enum dcommand_t {dMeta};
    3838enum mcommand_t {mNone, mCgiSafe};
     
    4343
    4444  text_t metaname;
    45   int metaindex;
    4645  mcommand_t metacommand;
    4746  pcommand_t parentcommand;
    48   int parentindex;
    4947  text_t parentoptions;
    5048};
     
    8583  text_tarray DocumentButtons;
    8684  text_t DocumentText;
     85  text_tmap formatstrings;
    8786};
    8887
     88bool get_formatstring (const text_t &key, const text_tmap &formatstringmap,
     89               text_t &formatstring);
     90bool get_formatstring (const text_t &key1, const text_t &key2, 
     91               const text_tmap &formatstringmap,
     92               text_t &formatstring);
    8993
    9094text_t format_date (const text_t &date);
    9195
    9296bool parse_formatstring (const text_t &formatstring, format_t *formatlistptr,
    93              text_tarray &metadata, bool &getParents);
     97             text_tset &metadata, bool &getParents);
    9498
    95 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     99text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    96100                 const text_t &link, const text_t &icon);
    97101
    98 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr);
     102text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr);
    99103
    100 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     104text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    101105                 const text_t &text);
    102106
    103 text_t get_formatted_string (const ResultDocInfo_t &docinfo, format_t *formatlistptr,
     107text_t get_formatted_string (ResultDocInfo_t &docinfo, format_t *formatlistptr,
    104108                 const text_t &link, const text_t &icon, const text_t &text);
    105109
  • trunk/gsdl/src/recpt/librarymain.cpp

    r596 r649  
    2828/*
    2929   $Log$
     30   Revision 1.14  1999/10/10 08:14:09  sjboddie
     31   - metadata now returns mp rather than array
     32   - redesigned browsing support (although it's not finished so
     33   won't currently work ;-)
     34
    3035   Revision 1.13  1999/09/16 21:39:35  sjboddie
    3136   added gb converters
     
    95100#include "authenaction.h"
    96101
     102#include "browserclass.h"
     103#include "vlistbrowserclass.h"
     104#include "hlistbrowserclass.h"
     105#include "datelistbrowserclass.h"
     106#include "invbrowserclass.h"
     107
    97108#include "gsdlhome.h"
    98109
     
    187198
    188199  documentaction adocumentaction;
     200  adocumentaction.set_receptionist(&recpt);
    189201  recpt.add_action (&adocumentaction);
    190202
     
    196208  recpt.add_action (&aauthenaction);
    197209
     210  // list of browsers
     211  vlistbrowserclass avlistbrowserclass;
     212  recpt.add_browser (&avlistbrowserclass);
     213  recpt.setdefaultbrowser ("VList");
     214
     215  hlistbrowserclass ahlistbrowserclass;
     216  recpt.add_browser (&ahlistbrowserclass);
     217
     218  datelistbrowserclass adatelistbrowserclass;
     219  recpt.add_browser (&adatelistbrowserclass);
     220
     221  invbrowserclass ainvbrowserclass;
     222  recpt.add_browser (&ainvbrowserclass);
     223
    198224  cgiwrapper (recpt, "");
    199225  return 0;
  • trunk/gsdl/src/recpt/pageaction.cpp

    r604 r649  
    2828/*
    2929   $Log$
     30   Revision 1.16  1999/10/10 08:14:09  sjboddie
     31   - metadata now returns mp rather than array
     32   - redesigned browsing support (although it's not finished so
     33   won't currently work ;-)
     34
    3035   Revision 1.15  1999/09/17 04:46:05  sjboddie
    3136   fixed a couple of problems with 'unknown' classifier
     
    121126}
    122127
    123 
    124 bool pageaction::init (ostream &logout) {
    125 
    126   // classify_meta should contain names of all classifiers supported
    127   // by this receptionist. classifications using metadata names not
    128   // in this list will be displayed as "unknown"
    129   classify_meta.insert ("Title");
    130   classify_meta.insert ("List");
    131   classify_meta.insert ("Creator");
    132   classify_meta.insert ("Series");
    133   classify_meta.insert ("Date");
    134   classify_meta.insert ("Subject");
    135   classify_meta.insert ("Organization");
    136   classify_meta.insert ("Howto");
    137   classify_meta.insert ("Topic");
    138   classify_meta.insert ("Browse");
    139   classify_meta.insert ("People");
    140 
    141   return action::init (logout);
    142 }
    143 
    144 
    145128bool pageaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/,
    146129                ostream &/*logout*/) {
     
    154137  response_data = "text/html";
    155138}
    156 
    157 
    158 // define all the macros which might be used by other actions
    159 // to produce pages.
    160 void pageaction::define_external_macros (const ColInfoResponse_t &/*collectinfo*/, displayclass &/*disp*/,
    161                      cgiargsclass &/*args*/, recptproto * /*collectproto*/,
    162                      ostream &/*logout*/) {
    163 }
    164 
    165139
    166140void pageaction::define_internal_macros (const ColInfoResponse_t &collectinfo, displayclass &disp,
     
    203177    }
    204178
    205     unsigned long current_time = time(NULL);
    206     text_t homeextra;
     179    text_t homeextra = "<center><table width=_pagewidth_><tr valign=top>\n";
    207180
    208181    recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr ();
     
    213186    while (rprotolist_here != rprotolist_end) {
    214187      if ((*rprotolist_here).p != NULL) {
     188
    215189    text_tarray collist;
    216190    comerror_t err;
     
    220194      text_tarray::iterator collist_end = collist.end();
    221195
    222       homeextra += "<dl>\n";
    223 
    224       FilterResponse_t response;
    225       text_tarray metadata;
    226       metadata.push_back ("collectionname");
    227 
     196      int row1 = 6;
     197      int row2 = 4;
     198      int count = 1;
    228199      while (collist_here != collist_end) {
    229         text_t collectionname = *collist_here;
    230         if (get_info ("collection", *collist_here, metadata, false, (*rprotolist_here).p, response, logout))
    231           collectionname = response.docInfo[0].metadata[0].values[0];
    232        
     200
    233201        ColInfoResponse_t cinfo;
    234202        (*rprotolist_here).p->get_collectinfo (*collist_here, cinfo, err, logout);
    235203        if (err == noError) {
    236           text_t link = "<a href=\"_gwcgi_?a=p&p=about&c=" + *collist_here + "\">";
    237           if (!cinfo.receptionist.empty())
    238         link = "<a href=\"" + cinfo.receptionist + "?a=p&p=about&c=" + *collist_here + "\">";
    239          
    240           homeextra += "<dt>" + link + collectionname + "</a></dt>\n";
    241           homeextra += "<dd>";
    242           if (cinfo.numDocs != 0) homeextra += text_t(cinfo.numDocs) + "_documents_";
    243           if (cinfo.numWords != 0) homeextra += text_t(cinfo.numWords) + "_words_";
    244           unsigned long last_update = (current_time - cinfo.buildDate) / 86400;
    245           homeextra += "_lastupdate_ " + text_t(last_update) + " _ago_</dd>\n";
     204          if (cinfo.isPublic) {
     205
     206        FilterResponse_t response;
     207        text_tset metadata;
     208        metadata.insert ("collectionname");
     209        metadata.insert ("iconcollection");
     210        metadata.insert ("iconcollectionsmall");
     211        text_t collectionname = *collist_here;
     212        text_t alt = collectionname;
     213        if (get_info ("collection", *collist_here, metadata, false,
     214                  (*rprotolist_here).p, response, logout)) {
     215          if (!response.docInfo[0].metadata["collectionname"].values[0].empty())
     216            alt = response.docInfo[0].metadata["collectionname"].values[0];
     217         
     218          if (!response.docInfo[0].metadata["iconcollectionsmall"].values[0].empty())
     219            collectionname = "<img width=150 src=\""
     220              + response.docInfo[0].metadata["iconcollectionsmall"].values[0]
     221              + "\" alt=\"" + alt + "\">";
     222          else if (!response.docInfo[0].metadata["iconcollection"].values[0].empty())
     223            collectionname = "<img width=150 src=\""
     224              + response.docInfo[0].metadata["iconcollection"].values[0]
     225              + "\" alt=\"" + alt + "\">";
     226          else collectionname = alt;
     227        }
     228       
     229        if ((count == 1) || (count == (row1+1)) || (count == ((row1+row2)+1)))
     230          homeextra += "<td align=center>";
     231        else homeextra += "<p>";
     232        text_t link = "<a href=\"_gwcgi_?a=p&p=about&c=" + *collist_here + "\">";
     233        if (*collist_here == "chinese")
     234          link = "<a href=\"_gwcgi_?a=p&p=about&l=zh&nw=u&c=" + *collist_here + "\">";
     235
     236        if (!cinfo.receptionist.empty())
     237          link = "<a href=\"" + cinfo.receptionist + "?a=p&p=about&c="
     238            + *collist_here + "\">";
     239       
     240        homeextra += link + collectionname + "</a>\n";
     241       
     242        if ((count == row1) || (count == (row1+row2)))
     243          homeextra += "</td>";
     244       
     245        count ++;
     246          }
    246247        }
     248
    247249        collist_here ++;
    248250      }
    249       homeextra += "</dl>\n";
     251      homeextra += "</tr></table></center>\n";
    250252      disp.setmacro ("homeextra", "home", homeextra);
    251253    }
     
    265267
    266268    FilterResponse_t response;
    267     text_tarray metadata;
    268     metadata.push_back ("Title");
     269    text_tset metadata;
     270    metadata.insert ("Title");
    269271    bool getParents = false;
    270272    get_children ("", args["c"], metadata, getParents, collectproto, response, logout);
     
    272274    disp.setmacro ("numbrowseoptions", "help", response.docInfo.size()+1);
    273275
    274     ResultDocInfo_tarray::const_iterator here = response.docInfo.begin();
    275     ResultDocInfo_tarray::const_iterator end = response.docInfo.end();
     276    ResultDocInfo_tarray::iterator here = response.docInfo.begin();
     277    ResultDocInfo_tarray::iterator end = response.docInfo.end();
    276278
    277279    // we're assuming that we've always got a search button
     
    280282
    281283    while (here != end) {
    282       text_t title = (*here).metadata[0].values[0];
    283 
    284       text_tset::const_iterator it = classify_meta.find (title);
    285       if (it == classify_meta.end()) title = "Unknown";
    286 
    287       shorttext += "<li>_text" + title + "short_\n";
    288       longtext += "_text" + title + "long_";
     284      text_t title = (*here).metadata["Title"].values[0];
     285
     286      text_t stext, ltext;
     287      disp.expandstring ("document", "_text" + title + "short_", stext);
     288      if (stext == ("_text" + title + "short_")) {
     289    stext = "<li>_textdefaultshorttext_";
     290    ltext = "_textdefaultlongtext_";
     291      } else {
     292    shorttext += "<li>" + stext;
     293    longtext += "_text" + title + "long_";
     294      }
    289295      here ++;
    290296    }
  • trunk/gsdl/src/recpt/pageaction.h

    r604 r649  
    4747  virtual ~pageaction ();
    4848
    49   bool init (ostream &logout);
    50 
    5149  text_t get_action_name () {return "p";}
    5250
     
    5755  void get_cgihead_info (cgiargsclass &args, response_t &response,
    5856             text_t &response_data, ostream &logout);
    59 
    60   void define_external_macros (const ColInfoResponse_t &collectinfo, displayclass &disp,
    61                    cgiargsclass &args, recptproto *collectproto,
    62                    ostream &logout);
    6357
    6458  void define_internal_macros (const ColInfoResponse_t &collectinfo, displayclass &disp,
  • trunk/gsdl/src/recpt/queryaction.cpp

    r634 r649  
    2828/*
    2929   $Log$
     30   Revision 1.26  1999/10/10 08:14:10  sjboddie
     31   - metadata now returns mp rather than array
     32   - redesigned browsing support (although it's not finished so
     33   won't currently work ;-)
     34
    3035   Revision 1.25  1999/09/24 04:49:39  sjboddie
    3136   fixed up the query selection boxes to display properly if there's only
     
    517522
    518523    if (havequerylink)
    519       request.fields.push_back (querylinkmeta);
    520 
    521     int metasize = request.fields.size();
     524      request.fields.insert (querylinkmeta);
    522525
    523526    // do the query
     
    535538    // output the results
    536539    textout << "<table cellspacing=4>\n";
    537     ResultDocInfo_tarray::const_iterator this_doc = response.docInfo.begin();
    538     ResultDocInfo_tarray::const_iterator end_doc = response.docInfo.end();
     540    ResultDocInfo_tarray::iterator this_doc = response.docInfo.begin();
     541    ResultDocInfo_tarray::iterator end_doc = response.docInfo.end();
    539542
    540543    while (this_doc != end_doc) {
     
    544547      textout << "<tr>\n";
    545548      if (havequerylink) {
    546     const text_t &qlmeta = (*this_doc).metadata[metasize-1].values.back();
     549    const text_t &qlmeta = (*this_doc).metadata[querylinkmeta].values[0];
    547550    if (qlmeta.empty())
    548551      textout << outconvert << disp
  • trunk/gsdl/src/recpt/receptionist.cpp

    r606 r649  
    2828/*
    2929   $Log$
     30   Revision 1.33  1999/10/10 08:14:10  sjboddie
     31   - metadata now returns mp rather than array
     32   - redesigned browsing support (although it's not finished so
     33   won't currently work ;-)
     34
    3035   Revision 1.32  1999/09/21 11:28:45  sjboddie
    3136   tidied up file locking
     
    290295  // add the cgi arguments from this action
    291296  argsinfo.addarginfo (NULL, theaction->getargsinfo());
     297}
     298
     299
     300void receptionist::add_browser (browserclass *thebrowser) {
     301  // make sure we have a browser to add
     302  if (thebrowser == NULL) return;
     303
     304  // add this browser to the list of browsers
     305  browsers.addbrowser(thebrowser);
     306}
     307
     308
     309void receptionist::setdefaultbrowser (const text_t &browsername) {
     310  browsers.setdefaultbrowser (browsername);
    292311}
    293312
     
    378397    }
    379398  }
    380 
    381399 
    382400  // configure the actions
     
    403421    protohere++;
    404422  }
    405 }
     423
     424  // configure the browsers
     425  browserptrmap::iterator browserhere = browsers.begin ();
     426  browserptrmap::iterator browserend = browsers.end ();
     427
     428  while (browserhere != browserend) {
     429    assert ((*browserhere).second.b != NULL);
     430    if ((*browserhere).second.b != NULL)
     431      (*browserhere).second.b->configure(key, cfgline);
     432   
     433    browserhere++;
     434  }
     435}
     436
    406437
    407438void receptionist::configure (const text_t &key, const text_t &value) {
     
    450481  }
    451482
     483  // there must be at least one browser defined
     484  if (browsers.empty()) {
     485    logout << "Error: no browsers have been added to the receptionist\n";
     486    return false;
     487  }
     488
    452489  // create a saveconf string if there isn't one already
    453490  if (configinfo.saveconf.empty())
     
    502539    !(*protohere).p->init(logout)) return false;
    503540    protohere++;
     541  }
     542
     543  // init the browsers
     544  browserptrmap::iterator browserhere = browsers.begin ();
     545  browserptrmap::iterator browserend = browsers.end ();
     546  while (browserhere != browserend) {
     547    if (((*browserhere).second.b == NULL) ||
     548    !(*browserhere).second.b->init(logout)) return false;
     549    browserhere++;
    504550  }
    505551
     
    800846  }
    801847
     848  // get browsers to process OID
     849  text_t OID = args["d"];
     850  if (OID.empty()) OID = args["cl"];
     851  text_tset metadata;
     852  FilterResponse_t response;
     853  metadata.insert ("classifytype");
     854  if (get_info (OID + ".pr", args["c"], metadata, false, collectproto, response, logout)) {
     855    browserclass *b =
     856      browsers.getbrowser (response.docInfo[0].metadata["classifytype"].values[0]);
     857    b->processOID (args);
     858  }
     859
    802860  // translate "d", "cl", and "hp" arguments if required
    803861  translate_OIDs (args, collectproto, logout);
     
    9471005// if they use the tricky ".fc", ".lc" type syntax. also sorts out the "d" argument
    9481006// if the goto page ("gp") argument was used
    949 void receptionist::translate_OIDs (cgiargsclass &args, recptproto *collectproto, ostream &logout) {
     1007void receptionist::translate_OIDs (cgiargsclass &args, recptproto *collectproto,
     1008                   ostream &logout) {
    9501009
    9511010  FilterResponse_t response;
     
    9571016  text_t &collection = args["c"];
    9581017  text_t &arg_gp = args["gp"];
    959 
    960   bool DocumentTopPages = true;
    961   text_tmap::const_iterator it = collectinfo.format.find("DocumentTopPages");
    962   if ((it != collectinfo.format.end()) && ((*it).second == "false")) DocumentTopPages = false;
    9631018 
    9641019  // do a call to translate OIDs if required
    9651020  request.filterName = "NullFilter";
    9661021  request.filterResultOptions = FROID;
    967   if ((!arg_d.empty()) && (needs_translating (arg_d) || !DocumentTopPages)) {
     1022  if (!arg_d.empty() && needs_translating (arg_d)) {
    9681023    request.docSet.push_back (arg_d);
    969     request.fields.push_back ("classifytype");
    970     request.filterResultOptions = FRmetadata;
    971     request.getParents = true;
    9721024    collectproto->filter (collection, request, response, err, logout);
    9731025    arg_d = response.docInfo[0].OID;
    974    
    975     text_t &classifytype = response.docInfo[0].metadata[0].values[0];
    976     if (classifytype.empty() || classifytype == "Book")
    977       if (!DocumentTopPages && is_top (arg_d)) arg_d += ".fc";
    978    
    9791026    request.clear();
    9801027  }
     
    9821029  // (in case ".fc" or ".lc" have screwed up)
    9831030  if (needs_translating (arg_cl)) {
    984     request.fields.push_back("doctype");
     1031    request.fields.insert ("doctype");
    9851032    request.docSet.push_back (arg_cl);
    9861033    request.filterResultOptions = FRmetadata;
    9871034    collectproto->filter (collection, request, response, err, logout);
    9881035    // set to original value (without .xx stuff) if doctype isn't "classify"
    989     if (response.docInfo[0].metadata[0].values[0] != "classify")
     1036    if (response.docInfo[0].metadata["doctype"].values[0] != "classify")
    9901037      strip_suffix (arg_cl);
    9911038    else
     
    10041051    text_t top;
    10051052    get_top (arg_d, top);
    1006     text_tarray metadata;
    1007     metadata.push_back ("Title");
     1053    text_tset metadata;
     1054    metadata.insert ("Title");
    10081055    bool getParents = false;
    10091056    get_children (top, collection, metadata, getParents, collectproto, response, logout);
    1010     ResultDocInfo_tarray::const_iterator dochere = response.docInfo.begin();
    1011     ResultDocInfo_tarray::const_iterator docend = response.docInfo.end();
     1057    ResultDocInfo_tarray::iterator dochere = response.docInfo.begin();
     1058    ResultDocInfo_tarray::iterator docend = response.docInfo.end();
    10121059    while (dochere != docend) {
    1013       if ((*dochere).metadata[0].values[0] == arg_gp) {
     1060      if ((*dochere).metadata["Title"].values[0] == arg_gp) {
    10141061    arg_d = (*dochere).OID;
    10151062    break;
     
    10991146  if ((!collection.empty()) && (collectproto != NULL)) {
    11001147    FilterResponse_t response;
    1101     text_tarray metadata;
    1102     //    metadata.push_back (".collectionimage");
    1103    
     1148    text_tset metadata;
    11041149    get_info ("collection", collection, metadata, false,
    11051150          collectproto, response, logout);
    11061151
    11071152    if (!response.docInfo[0].metadata.empty()) {
    1108       MetadataInfo_tarray::const_iterator here = response.docInfo[0].metadata.begin();
    1109       MetadataInfo_tarray::const_iterator end = response.docInfo[0].metadata.end();
     1153      MetadataInfo_tmap::const_iterator here = response.docInfo[0].metadata.begin();
     1154      MetadataInfo_tmap::const_iterator end = response.docInfo[0].metadata.end();
    11101155      while (here != end) {
    1111     if (((*here).name != "haschildren") && ((*here).name != "hasnext") &&
    1112         ((*here).name != "hasprevious")) {
    1113       disp.setmacro ((*here).name, "Global", (*here).values[0]);
     1156    if (((*here).first != "haschildren") && ((*here).first != "hasnext") &&
     1157        ((*here).first != "hasprevious")) {
     1158      disp.setmacro ((*here).first, "Global", (*here).second.values[0]);
    11141159    }
    11151160    here ++;
  • trunk/gsdl/src/recpt/receptionist.h

    r595 r649  
    3535#include "display.h"
    3636#include "action.h"
     37#include "browserclass.h"
    3738#include "recptproto.h"
    3839#include "converter.h"
     
    7576  cgiargsinfoclass argsinfo;
    7677  actionmapclass actions;
     78  browsermapclass browsers;
    7779  recptprotolistclass protocols;
    7880  displayclass disp;
     
    8587                 outconvertclass &outconvert, ostream &logout);
    8688 
    87   virtual void translate_OIDs (cgiargsclass &args, recptproto *collectproto, ostream &logout);
     89  virtual void translate_OIDs (cgiargsclass &args, recptproto *collectproto,
     90                   ostream &logout);
    8891
    8992  bool get_cookie (text_t &cookie);
     
    106109  void add_action (action *theaction);
    107110  actionmapclass *get_actionmap_ptr () {return &actions;}
     111
     112  // add_browser makes another browser available to the receptionist
     113  // the browser remains the property of the calling code and that
     114  // code should destroy it after the recptionist has been
     115  // destroyed.
     116  void add_browser (browserclass *thebrowser);
     117  browsermapclass *get_browsermap_ptr () {return &browsers;}
     118  void setdefaultbrowser (const text_t &browsername);
    108119
    109120  // add_protocol makes another protocol available to the receptionist
Note: See TracChangeset for help on using the changeset viewer.