1 | /**********************************************************************
|
---|
2 | *
|
---|
3 | * browse.cpp --
|
---|
4 | * Copyright (C) 1999 The New Zealand Digital Library Project
|
---|
5 | *
|
---|
6 | * PUT COPYRIGHT NOTICE HERE
|
---|
7 | *
|
---|
8 | * $Id: browse.cpp 172 1999-02-25 21:59:02Z rjmcnab $
|
---|
9 | *
|
---|
10 | *********************************************************************/
|
---|
11 |
|
---|
12 | /*
|
---|
13 | $Log$
|
---|
14 | Revision 1.9 1999/02/25 21:58:55 rjmcnab
|
---|
15 |
|
---|
16 | Merged sources.
|
---|
17 |
|
---|
18 | Revision 1.8 1999/01/21 21:20:10 sjboddie
|
---|
19 | removed unused collection parameter from several functions
|
---|
20 |
|
---|
21 | Revision 1.7 1999/01/12 01:51:03 rjmcnab
|
---|
22 |
|
---|
23 | Standard header.
|
---|
24 |
|
---|
25 | */
|
---|
26 |
|
---|
27 |
|
---|
28 | #include "browse.h"
|
---|
29 |
|
---|
30 |
|
---|
31 |
|
---|
32 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
33 | // get_browse_bar returns (in return_text) the html for the browse bar at the top of
|
---|
34 | // each page with the button for the current classification hierarchy deactivated
|
---|
35 |
|
---|
36 | void browseclass::get_browse_bar(const text_t &targetdoc, text_t &return_text) {
|
---|
37 | if (targetdoc[0] == 'B') return_text = "_imagestandardbar_";
|
---|
38 | else {
|
---|
39 | return_text = "_browse:imagebrowse";
|
---|
40 | return_text.push_back(targetdoc[0]);
|
---|
41 | return_text += "bar_";
|
---|
42 | }
|
---|
43 | }
|
---|
44 |
|
---|
45 |
|
---|
46 |
|
---|
47 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
48 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
49 | // toc functions
|
---|
50 |
|
---|
51 |
|
---|
52 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
53 | // get_list_toc returns all the titles of the sections in secarray as a list of links
|
---|
54 | // (i.e. as used by howto classifications in hdl collection)
|
---|
55 | void browseclass::get_list_toc (vector<text_t> &secarray, gdbmclass &gdbm, text_t &return_text) {
|
---|
56 | gdbm_info info;
|
---|
57 | text_t section, child;
|
---|
58 |
|
---|
59 | text_t doclink = "<a href=\"_httptext_&d=";
|
---|
60 | return_text += "<p>\n";
|
---|
61 |
|
---|
62 | vector<text_t>::const_iterator thissection = secarray.begin();
|
---|
63 | vector<text_t>::const_iterator end = secarray.end();
|
---|
64 |
|
---|
65 | while (thissection != end) {
|
---|
66 |
|
---|
67 | section.clear();
|
---|
68 | child.clear();
|
---|
69 | // get info on this section from gdbm
|
---|
70 | if (is_book(*thissection)) get_book(*thissection, section);
|
---|
71 | else section = *thissection;
|
---|
72 |
|
---|
73 | gdbm.getinfo(section, info);
|
---|
74 | get_first_section(info.contents, child);
|
---|
75 |
|
---|
76 | // return_text += "<br>" + doclink + *thissection + "." + child + "\">" + info.title + "</a>\n";
|
---|
77 | return_text += "<br>" + doclink + *thissection + "." + child +
|
---|
78 | ".1\">" + info.title + "</a>\n";
|
---|
79 | thissection ++;
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 |
|
---|
84 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
85 | // get_page_toc returns links to previous and next pages and text box for going to
|
---|
86 | // a selected page (as used by gberg collection). It is intended for use with collections
|
---|
87 | // whose documents are simply numbered as pages (should be single level TOCs).
|
---|
88 | // There may be introductory text sections before numbered pages.
|
---|
89 | void browseclass::get_page_toc (cgiargsclass &args, const text_t &booksection,
|
---|
90 | const text_t &classification, const text_t &class_string,
|
---|
91 | gdbmclass &gdbm, text_t &return_text) {
|
---|
92 | gdbm_info info, topinfo;
|
---|
93 | text_t previous, next;
|
---|
94 | vector<text_t> contents;
|
---|
95 |
|
---|
96 | // don't want arrows and page number if text expanded
|
---|
97 | if (args["g"][1] != '1') {
|
---|
98 |
|
---|
99 | // get links to previous and next sections.
|
---|
100 | get_prev_next_links(booksection, previous, next);
|
---|
101 |
|
---|
102 | return_text += "<p>\n<table cellpadding=\"0\" cellspacing=\"0\">\n";
|
---|
103 | return_text += "<tr valign=\"absmiddle\">\n";
|
---|
104 |
|
---|
105 | // get previous arrow
|
---|
106 | if (gdbm.exists(previous)) {
|
---|
107 | return_text += "<td><a href=\"_httptext_&d=" + classification + "." + previous;
|
---|
108 | return_text += "\">_iconless_</a></td>\n";
|
---|
109 | }
|
---|
110 |
|
---|
111 | // get page ? of ? text
|
---|
112 | return_text += "<td align=\"center\">\n";
|
---|
113 | gdbm.getinfo(booksection, info);
|
---|
114 | if (is_number(info.title)) {
|
---|
115 | splitstring(class_string, contents);
|
---|
116 | gdbm.getinfo(contents.back(), topinfo);
|
---|
117 | if (is_number(topinfo.title))
|
---|
118 | return_text += " page " + info.title + " of " + topinfo.title + " ";
|
---|
119 | else
|
---|
120 | return_text += " " + info.title + " ";
|
---|
121 | } else {
|
---|
122 | return_text += " " + info.title + " ";
|
---|
123 | }
|
---|
124 | return_text += "</td>\n";
|
---|
125 |
|
---|
126 | // get next arrow
|
---|
127 | if (gdbm.exists(next)) {
|
---|
128 | return_text += "<td><a href=\"_httptext_&d=" + classification + "." + next;
|
---|
129 | return_text += "\">_iconmore_</a></td>\n";
|
---|
130 | }
|
---|
131 | return_text += "</tr></table>\n";
|
---|
132 | }
|
---|
133 | // goto line
|
---|
134 | return_text += "_gotoform_";
|
---|
135 | }
|
---|
136 |
|
---|
137 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
138 | // get_standard_toc is the standard (unexpanded) toc used by hdl, unu, unesco etc.
|
---|
139 |
|
---|
140 | void browseclass::get_standard_toc(cgiargsclass &args, text_t &booksection,
|
---|
141 | const text_t &classification, gdbmclass &gdbm,
|
---|
142 | text_t &return_text) {
|
---|
143 |
|
---|
144 | // text_t doclink, tab, pagetype, section, icon, pointer, fulldoc;
|
---|
145 | int colnum, tabcount = 0;
|
---|
146 | text_t fulldoc;
|
---|
147 | // gdbm_info info;
|
---|
148 | // vector<text_t> contents, parents, siblings;
|
---|
149 | vector<text_t> parents, siblings;
|
---|
150 |
|
---|
151 | if (!booksection.empty()) fulldoc = classification + "." + booksection;
|
---|
152 | else fulldoc = classification;
|
---|
153 |
|
---|
154 | get_parents (fulldoc, parents);
|
---|
155 | get_siblings (classification, booksection, gdbm, siblings);
|
---|
156 |
|
---|
157 | // remove everything above top level of book from parents
|
---|
158 | // list if inside of book
|
---|
159 | if (!booksection.empty() && !is_top_level(booksection)) {
|
---|
160 | vector<text_t> temp;
|
---|
161 | for (unsigned int i = 0; i < parents.size(); i++) {
|
---|
162 | if (is_book(parents[i])) temp.push_back(parents[i]);
|
---|
163 | }
|
---|
164 | parents = temp;
|
---|
165 | }
|
---|
166 |
|
---|
167 | // remove top level of title and author hierarchies
|
---|
168 | if (((classification[0] == 'T') || (classification[0] == 'A')) &&
|
---|
169 | (booksection.empty() || is_top_level(booksection))) {
|
---|
170 | if (!parents.empty())
|
---|
171 | parents.erase(parents.begin(), parents.begin()+1);
|
---|
172 | }
|
---|
173 | colnum = parents.size() + 1;
|
---|
174 |
|
---|
175 | // sort out toc of sections parents
|
---|
176 | if (parents.size() > 0)
|
---|
177 | get_parents_toc(args, parents, gdbm, tabcount, colnum, return_text);
|
---|
178 |
|
---|
179 | // sort out toc of sections siblings
|
---|
180 | if (siblings.size() > 0)
|
---|
181 | get_siblings_toc (args, siblings, gdbm, booksection, classification,
|
---|
182 | tabcount, colnum, return_text);
|
---|
183 |
|
---|
184 | return_text += "</table>\n";
|
---|
185 | return_text += "</td></tr></table>\n";
|
---|
186 | }
|
---|
187 |
|
---|
188 |
|
---|
189 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
190 | // get_expanded_toc is the expanded toc used by hdl, unu, unesco etc.
|
---|
191 |
|
---|
192 | void browseclass::get_expanded_toc(cgiargsclass &args, text_t &booksection,
|
---|
193 | const text_t &classification, gdbmclass &gdbm,
|
---|
194 | text_t &return_text) {
|
---|
195 |
|
---|
196 | text_t doclink, icon, pointer, tab, pagetype;
|
---|
197 | int totalcols, tabcols, tabsleft;
|
---|
198 | vector<text_t> contents;
|
---|
199 | gdbm_info info;
|
---|
200 |
|
---|
201 | // get array of all contents to be included (all contents of entire book)
|
---|
202 | text_t book_top;
|
---|
203 | get_book_top (booksection, book_top);
|
---|
204 | get_contents (book_top, gdbm, contents, totalcols);
|
---|
205 |
|
---|
206 | vector<text_t>::const_iterator section = contents.begin();
|
---|
207 | vector<text_t>::const_iterator end = contents.end();
|
---|
208 |
|
---|
209 | int count = 1;
|
---|
210 | while (section != end) {
|
---|
211 | tab.clear();
|
---|
212 | gdbm.getinfo(*section, info);
|
---|
213 | text_t icontabs;
|
---|
214 |
|
---|
215 | // set up icon
|
---|
216 | icon = "_iconsmalltext_";
|
---|
217 | if (is_top_level(*section)) icon = "_iconopenbook_";
|
---|
218 | else if (!info.contents.empty()) icon = "_iconopenfolder_";
|
---|
219 |
|
---|
220 | // set up pointer
|
---|
221 | if (*section == booksection) pointer = "_iconpointer_";
|
---|
222 | else pointer = "_icontab_";
|
---|
223 |
|
---|
224 | // set up tabbing
|
---|
225 | tabcols = count_dots(*section);
|
---|
226 | for (int i = 0; i < (tabcols - 1); i++) {
|
---|
227 | icontabs += "_icontab_";
|
---|
228 | }
|
---|
229 | //char *tabcolsstr;
|
---|
230 | //itoa(tabcols, tabcolsstr, 10);
|
---|
231 | tab = "<td valign=top colspan=" + text_t(tabcols);
|
---|
232 | tab += ">" + icontabs + pointer + "</td>";
|
---|
233 | tabsleft = totalcols - tabcols;
|
---|
234 |
|
---|
235 | // set up url
|
---|
236 | if (is_book(*section) && !is_top_level(*section))
|
---|
237 | doclink = "<a href=\"_httptext_";
|
---|
238 | else doclink = "<a href=\"_httpbrowse_";
|
---|
239 | if (args["x"] == "1") doclink += "&x=1";
|
---|
240 |
|
---|
241 | return_text += "<tr>" + tab + "<td valign=top>";
|
---|
242 | if (is_top_level(*section) && args["x"] == "1") {
|
---|
243 | return_text += "<a href=\"\" onClick = \"close_detach()";
|
---|
244 | } else {
|
---|
245 | if (args["g"][1] == '0' || is_top_level(*section) ||
|
---|
246 | !are_same_chapter(booksection, *section) ||
|
---|
247 | !info.contents.empty()) {
|
---|
248 | return_text += doclink + "d=" + classification;
|
---|
249 | return_text += "." + *section + "&a=" + pagetype;
|
---|
250 | } else {
|
---|
251 | return_text += "<a href=\"#";
|
---|
252 | return_text += count;
|
---|
253 | count ++;
|
---|
254 | }
|
---|
255 | }
|
---|
256 | return_text += "\">" + icon + "</a></td>";
|
---|
257 | return_text += "<td colspan=" + text_t(tabsleft);
|
---|
258 | return_text += "><_font_>" + info.title + "</font>";
|
---|
259 | return_text += "</td></tr>\n";
|
---|
260 |
|
---|
261 | section ++;
|
---|
262 | }
|
---|
263 | return_text += "</table>\n";
|
---|
264 | return_text += "</td></tr></table>\n";
|
---|
265 | }
|
---|
266 |
|
---|
267 |
|
---|
268 | void browseclass::get_parents_toc (cgiargsclass &args, const vector<text_t> &parents,
|
---|
269 | gdbmclass &gdbm, int &tabcount, int &colnum,
|
---|
270 | text_t &return_text) {
|
---|
271 |
|
---|
272 | text_t section, tab, icon, doclink;
|
---|
273 | gdbm_info info;
|
---|
274 |
|
---|
275 | vector<text_t>::const_iterator thisparent = parents.begin();
|
---|
276 | vector<text_t>::const_iterator end = parents.end();
|
---|
277 |
|
---|
278 | while (thisparent != end) {
|
---|
279 | text_t icontabs;
|
---|
280 | section.clear();
|
---|
281 | tab.clear();
|
---|
282 |
|
---|
283 | // get info on this parent from gdbm
|
---|
284 | if (is_book(*thisparent)) get_book(*thisparent, section);
|
---|
285 | else section = *thisparent;
|
---|
286 | gdbm.getinfo(section, info);
|
---|
287 |
|
---|
288 | // set up icon for this parent
|
---|
289 | icon = "_iconopenfolder_";
|
---|
290 | if (!is_book(*thisparent)) icon = "_iconopenbookshelf_";
|
---|
291 | else if (is_top_level(*thisparent)) icon = "_iconopenbook_";
|
---|
292 |
|
---|
293 | for (int j = 0; j < tabcount; j++) {
|
---|
294 | icontabs += "_icontab_";
|
---|
295 | }
|
---|
296 |
|
---|
297 | if (!icontabs.empty()) {
|
---|
298 | tab = "<td valign=top";
|
---|
299 | if (tabcount > 1) tab += " colspan=" + text_t(tabcount);
|
---|
300 | tab += ">" + icontabs + "</td>";
|
---|
301 | }
|
---|
302 | tabcount ++;
|
---|
303 |
|
---|
304 | // set up url
|
---|
305 | if (is_book(*thisparent) && !is_top_level(*thisparent))
|
---|
306 | doclink = "<a href=\"_httptext_";
|
---|
307 | else doclink = "<a href=\"_httpbrowse_";
|
---|
308 | if (args["x"] == "1") doclink += "&x=1";
|
---|
309 |
|
---|
310 | if (is_top_level(*thisparent) && args["x"] == "1") {
|
---|
311 | return_text += "<tr>" + tab + "<td valign=top><a href=\"\" ";
|
---|
312 | return_text += "onClick = \"close_detach()\">" + icon + "</a></td>";
|
---|
313 | } else {
|
---|
314 | return_text += "<tr>" + tab + "<td valign=top>" + doclink + "&d=" + *thisparent;
|
---|
315 | return_text += "\">" + icon + "</a></td>";
|
---|
316 | }
|
---|
317 | return_text += "<td";
|
---|
318 | if (colnum > 1) return_text += " colspan=" + text_t(colnum);
|
---|
319 | return_text += "><_font_>" + info.title;
|
---|
320 | if (!info.author.empty()) return_text += " by " + info.author;
|
---|
321 | return_text += "</font>";
|
---|
322 | return_text += "</td></tr>\n";
|
---|
323 | colnum --;
|
---|
324 | thisparent ++;
|
---|
325 | }
|
---|
326 | }
|
---|
327 |
|
---|
328 | ///////////////////////////////////////////////////////////////////////////////////////////
|
---|
329 | ///////////////////////// get siblings table of contents //////////////////////////////////
|
---|
330 | ///////////////////////////////////////////////////////////////////////////////////////////
|
---|
331 |
|
---|
332 | void browseclass::get_siblings_toc (cgiargsclass &args, const vector<text_t> &siblings,
|
---|
333 | gdbmclass &gdbm, const text_t &booksection,
|
---|
334 | const text_t &classification, int &tabcount,
|
---|
335 | int &colnum, text_t &return_text) {
|
---|
336 |
|
---|
337 | text_t tab, section, icon, pointer, child, doclink;
|
---|
338 | int count = 1;
|
---|
339 | gdbm_info info;
|
---|
340 |
|
---|
341 | vector<text_t>::const_iterator thissibling = siblings.begin();
|
---|
342 | vector<text_t>::const_iterator sibend = siblings.end();
|
---|
343 |
|
---|
344 | while (thissibling != sibend) {
|
---|
345 | section.clear();
|
---|
346 |
|
---|
347 | // get info on this sibling from gdbm
|
---|
348 | if (is_book(*thissibling)) get_book(*thissibling, section);
|
---|
349 | else section = *thissibling;
|
---|
350 | gdbm.getinfo(section, info);
|
---|
351 |
|
---|
352 | // set up icon for this sibling
|
---|
353 | icon = "_iconclosedfolder_";
|
---|
354 | if (!is_book(*thissibling)) icon = "_iconclosedbookshelf_";
|
---|
355 | else if (is_top_level(*thissibling)) icon = "_iconclosedbook_";
|
---|
356 |
|
---|
357 | // fit pointer into tabbing if current section
|
---|
358 | pointer = "_icontab_";
|
---|
359 | if (is_book(section)) {
|
---|
360 | if (section == booksection) pointer = "_iconpointer_";
|
---|
361 | } else if (section == classification) pointer = "_iconpointer_";
|
---|
362 |
|
---|
363 | text_t thesetabs;
|
---|
364 | for (int j = 0; j < (tabcount - 1); j++) {
|
---|
365 | thesetabs += "_icontab_";
|
---|
366 | }
|
---|
367 |
|
---|
368 | tab = "<td valign=top";
|
---|
369 | if (tabcount > 1) tab += " colspan=" + text_t(tabcount);
|
---|
370 | tab += ">" + thesetabs + pointer + "</td>";
|
---|
371 |
|
---|
372 | if (info.contents.empty()) {
|
---|
373 | // sibling is text document
|
---|
374 | icon = "_iconsmalltext_";
|
---|
375 |
|
---|
376 | // set up url
|
---|
377 | if (is_book(*thissibling) && !is_top_level(*thissibling))
|
---|
378 | doclink = "<a href=\"_httptext_";
|
---|
379 | else doclink = "<a href=\"_httpbrowse_";
|
---|
380 | if (args["x"] == "1") doclink += "&x=1";
|
---|
381 |
|
---|
382 | return_text += "<tr>" + tab + "<td valign=top>";
|
---|
383 | if (args["g"][1] == '0') {
|
---|
384 | return_text += doclink + "&d=" + *thissibling;
|
---|
385 | } else {
|
---|
386 | return_text += "<a href=\"#";
|
---|
387 | return_text += count;
|
---|
388 | count ++;
|
---|
389 | }
|
---|
390 | return_text += "\">" + icon + "</a></td><td";
|
---|
391 | if (colnum > 1) return_text += " colspan=" + text_t(colnum);
|
---|
392 | return_text += "><_font_>" + info.title;
|
---|
393 | if (!info.author.empty()) return_text += " by " + info.author;
|
---|
394 | return_text += "</font></td></tr>\n";
|
---|
395 | } else {
|
---|
396 | // sibling is closed book or folder so clicking
|
---|
397 | // it should open contents
|
---|
398 | get_first_section(info.contents, child);
|
---|
399 |
|
---|
400 | // get classification of child if it's a book
|
---|
401 | if (is_book(child)) {
|
---|
402 | text_t classif = classification;
|
---|
403 | // remove last part (i.e. '.n') from classification if current section is
|
---|
404 | // a classification and sibling is a book
|
---|
405 | if (booksection.empty() && is_book(*thissibling)) {
|
---|
406 | get_parent_section(classif);
|
---|
407 | }
|
---|
408 | // if sibling is a classification it is the classification of its child
|
---|
409 | if (!is_book(*thissibling)) classif = *thissibling;
|
---|
410 |
|
---|
411 | child = classif + "." + child;
|
---|
412 | }
|
---|
413 |
|
---|
414 | // set up url
|
---|
415 | if (is_book(child) && !is_top_level(child))
|
---|
416 | doclink = "<a href=\"_httptext_";
|
---|
417 | else doclink = "<a href=\"_httpbrowse_";
|
---|
418 | if (args["x"] == "1") doclink += "&x=1";
|
---|
419 |
|
---|
420 | return_text += "<tr>" + tab + "<td valign=top>" + doclink + "&d=" + child;
|
---|
421 | return_text += "\">" + icon + "</a></td><td";
|
---|
422 | if (colnum > 1) return_text += " colspan=" + text_t(colnum);
|
---|
423 | return_text += "><_font_>" + info.title;
|
---|
424 | if (!info.author.empty()) return_text += " by " + info.author;
|
---|
425 | return_text += "</font></td></tr>\n";
|
---|
426 | }
|
---|
427 | thissibling ++;
|
---|
428 | }
|
---|
429 | }
|
---|
430 |
|
---|
431 |
|
---|
432 |
|
---|
433 | // get_alphabet_links adds the html for the letter selection links to return_text
|
---|
434 | void browseclass::get_alphabet_links (const text_t &classification,
|
---|
435 | const text_t &/*booksection*/, gdbmclass &gdbm,
|
---|
436 | text_t &return_text) {
|
---|
437 |
|
---|
438 | gdbm_info info;
|
---|
439 |
|
---|
440 | text_t link = "<a href=\"_httpbrowse_&d=";
|
---|
441 | vector<text_t> classcontents;
|
---|
442 | text_t classt, firstcontent;
|
---|
443 | classt.push_back(classification[0]);
|
---|
444 |
|
---|
445 | return_text += "\n<p>\n";
|
---|
446 | return_text += "<table width=\"100%\" cellpadding=0 cellspacing=0 border=0>\n";
|
---|
447 | return_text += "<tr><td valign=top><center>\n";
|
---|
448 | return_text += "<_font_>\n";
|
---|
449 |
|
---|
450 | // get list of contents for this classification
|
---|
451 | gdbm.getinfo(classt, info);
|
---|
452 | if (!info.contents.empty()) {
|
---|
453 | splitstring(info.contents, classcontents);
|
---|
454 | vector<text_t>::const_iterator here = classcontents.begin();
|
---|
455 | vector<text_t>::const_iterator end = classcontents.end();
|
---|
456 |
|
---|
457 | while (here != end) {
|
---|
458 | gdbm.getinfo(*here, info);
|
---|
459 |
|
---|
460 | if (*here == classification) {
|
---|
461 | return_text += "<b>" + info.title + "</b> ";
|
---|
462 | } else {
|
---|
463 | if (!info.contents.empty()) {
|
---|
464 | get_first_section(info.contents, firstcontent);
|
---|
465 | return_text += link + *here + "." + firstcontent + "\">";
|
---|
466 | return_text += info.title + "</a> ";
|
---|
467 | }
|
---|
468 | }
|
---|
469 | here ++;
|
---|
470 | }
|
---|
471 | }
|
---|
472 | return_text += "</font>\n";
|
---|
473 | return_text += "</center></td>\n</tr><tr>\n";
|
---|
474 | }
|
---|
475 |
|
---|
476 | // get_arrows returns (in arrows) the html for the arrows to select
|
---|
477 | // next/previous section at same level. If there is no next/previous
|
---|
478 | // section at current level then there'll be no arrow.
|
---|
479 | void browseclass::get_arrows(text_t &docref, gdbmclass &gdbm,
|
---|
480 | text_t &arrows) {
|
---|
481 | text_t previous, next, firstcontent;
|
---|
482 | gdbm_info info;
|
---|
483 |
|
---|
484 | arrows = "\n<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
---|
485 | arrows += "<tr><td align=left>\n";
|
---|
486 | arrows += "<_font_>\n";
|
---|
487 |
|
---|
488 | // get links to previous and next sections.
|
---|
489 | get_prev_next_links(docref, previous, next);
|
---|
490 |
|
---|
491 | // get html for previous link if it exists
|
---|
492 | gdbm.getinfo(previous, info);
|
---|
493 | if (!info.contents.empty()) {
|
---|
494 | get_first_section(info.contents, firstcontent);
|
---|
495 | arrows += "<a href=\"_httpbrowse_&d=";
|
---|
496 | arrows += previous + "." + firstcontent + "\">";
|
---|
497 | arrows += "_iconalphless_</a>\n";
|
---|
498 | }
|
---|
499 |
|
---|
500 | arrows += "</font>\n";
|
---|
501 | arrows += "</td><td align=right>\n";
|
---|
502 | arrows += "<_font_>\n";
|
---|
503 |
|
---|
504 | // get html for next link if it exists
|
---|
505 | gdbm.getinfo(next, info);
|
---|
506 | if (!info.contents.empty()) {
|
---|
507 | get_first_section(info.contents, firstcontent);
|
---|
508 | arrows += "<a href=\"_httpbrowse_&d=";
|
---|
509 | arrows += next + "." + firstcontent + "\">";
|
---|
510 | arrows += "_iconalphmore_</a>\n";
|
---|
511 | }
|
---|
512 |
|
---|
513 | arrows += "</font>\n";
|
---|
514 | arrows += "</td></tr></table>\n";
|
---|
515 | }
|
---|
516 |
|
---|
517 | // get_prev_next_links returns (in previous and next) the sections previous to
|
---|
518 | // and next after docref (on the same level). These sections may not be
|
---|
519 | // defined in the infodb so calling function should check.
|
---|
520 |
|
---|
521 | void browseclass::get_prev_next_links (text_t docref, text_t &previous, text_t &next) {
|
---|
522 | int prevnum, nextnum, thisnum;
|
---|
523 | text_t section;
|
---|
524 |
|
---|
525 | get_parent_section(docref, section);
|
---|
526 |
|
---|
527 | thisnum = section.getint();
|
---|
528 | prevnum = thisnum - 1;
|
---|
529 | nextnum = thisnum + 1;
|
---|
530 |
|
---|
531 | previous = docref + "." + text_t(prevnum);
|
---|
532 | next = docref + "." + text_t(nextnum);
|
---|
533 | }
|
---|
534 |
|
---|
535 | // get contents returns a contents array of all contents below (and including)
|
---|
536 | // the classification in expandlevel.
|
---|
537 | // it also returns (in totalcols) the total number of columns needed for
|
---|
538 | // a table of contents using contents
|
---|
539 | void browseclass::get_contents (text_t expandlevel1, gdbmclass &gdbm,
|
---|
540 | vector<text_t> &contents, int &totalcols) {
|
---|
541 |
|
---|
542 | text_t expandlevel = expandlevel1;
|
---|
543 |
|
---|
544 | contents.erase(contents.begin(), contents.end());
|
---|
545 | totalcols = 0;
|
---|
546 |
|
---|
547 | vector<text_t> sections;
|
---|
548 | text_t section, book_top;
|
---|
549 | int cols;
|
---|
550 | gdbm_info info;
|
---|
551 |
|
---|
552 | if (!is_top_level(expandlevel)) get_parent_section(expandlevel);
|
---|
553 |
|
---|
554 | sections.push_back(expandlevel);
|
---|
555 |
|
---|
556 | while (!sections.empty()) {
|
---|
557 | section = sections.back();
|
---|
558 | sections.pop_back();
|
---|
559 | get_book (section, section);
|
---|
560 |
|
---|
561 | contents.push_back(section);
|
---|
562 |
|
---|
563 | // update number of columns needed for table
|
---|
564 | cols = count_dots(section) + 1;
|
---|
565 | if (cols > totalcols) totalcols = cols;
|
---|
566 |
|
---|
567 | gdbm.getinfo(section, info);
|
---|
568 | if (!info.contents.empty()) {
|
---|
569 | vector<text_t> temp;
|
---|
570 | splitstring(info.contents, temp);
|
---|
571 | while (!temp.empty()) {
|
---|
572 | sections.push_back(temp.back());
|
---|
573 | temp.pop_back();
|
---|
574 | }
|
---|
575 | }
|
---|
576 | }
|
---|
577 | // get top level of book and add to contents if not already there
|
---|
578 | get_book_top(expandlevel, book_top);
|
---|
579 |
|
---|
580 | if (contents.front() != book_top) {
|
---|
581 | contents.insert(contents.begin(), book_top);
|
---|
582 | }
|
---|
583 | }
|
---|
584 |
|
---|
585 |
|
---|
586 | //////////////////////////////////////////////////////////////////////////////////////////////
|
---|
587 | // get_links returns (in return_text) the html for the buttons to link to the next and
|
---|
588 | // previous sections
|
---|
589 |
|
---|
590 | void browseclass::get_links(cgiargsclass &args, gdbmclass &gdbm, text_t &return_text) {
|
---|
591 |
|
---|
592 | text_t doclink, classification, booksection;
|
---|
593 | text_t nextsibling, previoussibling, lastsibling;
|
---|
594 | vector<text_t> siblings;
|
---|
595 | gdbm_info info;
|
---|
596 |
|
---|
597 | separate_parts(args["d"], gdbm, classification, booksection);
|
---|
598 |
|
---|
599 | // don't want links at top levels
|
---|
600 | if (booksection.empty() || is_top_level(booksection)) return;
|
---|
601 |
|
---|
602 | text_t current_classification = classification + "." + booksection;
|
---|
603 |
|
---|
604 | return_text += "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>\n";
|
---|
605 | return_text += "<tr><td align=left>\n";
|
---|
606 |
|
---|
607 | get_siblings (classification, booksection, gdbm, siblings);
|
---|
608 |
|
---|
609 | // get older and younger siblings if they exist
|
---|
610 | int found = 0;
|
---|
611 | vector<text_t>::const_iterator thissibling = siblings.begin();
|
---|
612 | vector<text_t>::const_iterator end = siblings.end();
|
---|
613 | while (thissibling != end) {
|
---|
614 | if (found) {
|
---|
615 | nextsibling = *thissibling;
|
---|
616 | break;
|
---|
617 | }
|
---|
618 |
|
---|
619 | if (*thissibling == current_classification) {
|
---|
620 | previoussibling = lastsibling;
|
---|
621 | found = 1;
|
---|
622 | }
|
---|
623 | lastsibling = *thissibling;
|
---|
624 | thissibling ++;
|
---|
625 | }
|
---|
626 |
|
---|
627 | // don't want 'next' arrow pointing to next sibling if current section
|
---|
628 | // has children
|
---|
629 | gdbm.getinfo(booksection, info);
|
---|
630 | if (!info.contents.empty()) nextsibling = current_classification;
|
---|
631 |
|
---|
632 | // set up the 'previous' arrow
|
---|
633 |
|
---|
634 | if (is_section_top(booksection)) {
|
---|
635 | // if this section is the top of any section in line with
|
---|
636 | // top of book there'll be no 'previous' arrow
|
---|
637 | // (i.e. B.n.1, B.n.1.1, B.n.1.1.1 etc.)
|
---|
638 | } else {
|
---|
639 | // get parents older sibling if no older sibling of own
|
---|
640 | text_t sec = booksection;
|
---|
641 | while (previoussibling.empty()) {
|
---|
642 | vector<text_t> parentsiblings;
|
---|
643 | gdbm.getinfo(sec, info); // info on this section
|
---|
644 | text_t last, parent = info.parent;
|
---|
645 | gdbm.getinfo(parent, info); // info on parent
|
---|
646 | gdbm.getinfo(info.parent, info); // info on grandparent
|
---|
647 | splitstring(info.contents, parentsiblings); // now have parents siblings
|
---|
648 |
|
---|
649 | vector<text_t>::const_iterator thisuncle = parentsiblings.begin();
|
---|
650 | vector<text_t>::const_iterator end = parentsiblings.end();
|
---|
651 |
|
---|
652 | while (thisuncle != end) {
|
---|
653 | if (*thisuncle == parent) {
|
---|
654 | previoussibling = last;
|
---|
655 | break;
|
---|
656 | }
|
---|
657 | last = *thisuncle;
|
---|
658 | thisuncle ++;
|
---|
659 | }
|
---|
660 | sec = parent;
|
---|
661 | }
|
---|
662 |
|
---|
663 | // if previous section has contents then we need to link to the last
|
---|
664 | // of those contents
|
---|
665 | text_t prev; // use this in case previoussibling contains classification
|
---|
666 | get_book(previoussibling, prev);
|
---|
667 | gdbm.getinfo(prev, info);
|
---|
668 | while (!info.contents.empty()) {
|
---|
669 | vector<text_t> contents;
|
---|
670 | splitstring(info.contents, contents);
|
---|
671 | previoussibling = contents.back();
|
---|
672 | gdbm.getinfo(previoussibling, info);
|
---|
673 | }
|
---|
674 |
|
---|
675 | if (previoussibling[0] == 'B') previoussibling = classification + "." + previoussibling;
|
---|
676 | }
|
---|
677 |
|
---|
678 |
|
---|
679 | // set up the 'next' arrow
|
---|
680 | text_t sec = booksection;
|
---|
681 | // if no younger siblings get parents younger siblings
|
---|
682 | while (nextsibling.empty()) {
|
---|
683 | gdbm.getinfo(sec, info);
|
---|
684 | text_t parent = info.parent;
|
---|
685 | gdbm.getinfo(parent, info); // parent info
|
---|
686 | if (!info.parent.empty()) {
|
---|
687 | vector<text_t> parentsiblings;
|
---|
688 | gdbm.getinfo(info.parent, info); // grandparent info
|
---|
689 | splitstring(info.contents, parentsiblings); // got parents siblings
|
---|
690 |
|
---|
691 | vector<text_t>::iterator thissibling = parentsiblings.begin();
|
---|
692 | vector<text_t>::iterator end = parentsiblings.end();
|
---|
693 | int found = 0;
|
---|
694 | while(thissibling != end) {
|
---|
695 | if (found) {
|
---|
696 | nextsibling = *thissibling;
|
---|
697 | break;
|
---|
698 | }
|
---|
699 | if (*thissibling == parent) found = 1;
|
---|
700 | thissibling ++;
|
---|
701 | }
|
---|
702 | sec = parent;
|
---|
703 | } else {
|
---|
704 | // no more contents
|
---|
705 | break;
|
---|
706 | }
|
---|
707 | }
|
---|
708 |
|
---|
709 | if (!nextsibling.empty()) {
|
---|
710 | // if nextsibling still isn't set there are no more sections in the
|
---|
711 | // book and so no 'next' arrow
|
---|
712 |
|
---|
713 | // if next section has contents we want to link to the first
|
---|
714 | // of those contents
|
---|
715 | text_t next;
|
---|
716 | get_book(nextsibling, next);
|
---|
717 | gdbm.getinfo(next, info);
|
---|
718 | while (!info.contents.empty()) {
|
---|
719 | get_first_section(info.contents, nextsibling);
|
---|
720 | gdbm.getinfo(nextsibling, info);
|
---|
721 | }
|
---|
722 | if (nextsibling[0] == 'B') nextsibling = classification + "." + nextsibling;
|
---|
723 | }
|
---|
724 |
|
---|
725 | // html for 'previous' arrow
|
---|
726 | if (!previoussibling.empty()) {
|
---|
727 | if (is_book(previoussibling) && !is_top_level(previoussibling))
|
---|
728 | doclink = "<a href=\"_httptext_";
|
---|
729 | else doclink = "<a href=\"_httpbrowse_";
|
---|
730 | if (args["x"] == "1") doclink += "&x=1";
|
---|
731 |
|
---|
732 | return_text += doclink + "&d=" + previoussibling + "\">_iconless_</a>\n";
|
---|
733 | }
|
---|
734 |
|
---|
735 | return_text += "</td><td align=right>\n";
|
---|
736 |
|
---|
737 | // html for 'next' arrow
|
---|
738 | if (!nextsibling.empty()) {
|
---|
739 | if (is_book(nextsibling) && !is_top_level(nextsibling))
|
---|
740 | doclink = "<a href=\"_httptext_";
|
---|
741 | else doclink = "<a href=\"_httpbrowse_";
|
---|
742 | if (args["x"] == "1") doclink += "&x=1";
|
---|
743 |
|
---|
744 | return_text += doclink + "&d=" + nextsibling + "\">_iconmore_</a>\n";
|
---|
745 | }
|
---|
746 |
|
---|
747 | return_text += "</td></tr></table>\n";
|
---|
748 | }
|
---|
749 |
|
---|
750 | // get_contents_arr returns an array containing the classifications of all the sections
|
---|
751 | // in the book mentioned in targetdoc
|
---|
752 |
|
---|
753 | void browseclass::get_contents_arr(const text_t &targetdoc, gdbmclass &gdbm,
|
---|
754 | vector<text_t> &contents_arr) {
|
---|
755 | text_t booksection;
|
---|
756 | int totalcols = 0;
|
---|
757 | get_book(targetdoc, booksection);
|
---|
758 | get_contents (booksection, gdbm, contents_arr, totalcols);
|
---|
759 | }
|
---|
760 |
|
---|
761 |
|
---|
762 | // sorts an array of sections alphabetically (i.e. by title, author depending
|
---|
763 | // on what classification is) or by date
|
---|
764 | void browseclass::sort_array (vector<text_t> &array, gdbmclass &gdbm, const text_t classification) {
|
---|
765 |
|
---|
766 | if ((classification[0] != 'T') && (classification[0] != 'A') &&
|
---|
767 | (classification[0] != 'D')) return;
|
---|
768 |
|
---|
769 | gdbm_info info;
|
---|
770 | char **tmparray = NULL;
|
---|
771 | int len = 0, i;
|
---|
772 | text_t tmpstr;
|
---|
773 |
|
---|
774 | vector<text_t>::const_iterator here = array.begin();
|
---|
775 | vector<text_t>::const_iterator end = array.end();
|
---|
776 |
|
---|
777 | while (here != end) {
|
---|
778 | text_t key;
|
---|
779 | if (is_book(*here)) get_book(*here, key);
|
---|
780 | else key = *here;
|
---|
781 |
|
---|
782 | gdbm.getinfo(key, info);
|
---|
783 | if (classification[0] == 'T') {
|
---|
784 |
|
---|
785 | alphabetize_string_english(info.title);
|
---|
786 | info.title += ":#:" + *here;
|
---|
787 | tmparray = string_add(tmparray, &len, info.title.getcstr());
|
---|
788 |
|
---|
789 | } else if (classification[0] == 'A') {
|
---|
790 | alphabetize_string_name(info.author);
|
---|
791 | info.author += ":#:" + *here;
|
---|
792 | tmparray = string_add(tmparray, &len, info.author.getcstr());
|
---|
793 |
|
---|
794 | } else {
|
---|
795 | info.date += ":#:" + *here;
|
---|
796 | tmparray = string_add(tmparray, &len, info.date.getcstr());
|
---|
797 | }
|
---|
798 | here ++;
|
---|
799 | }
|
---|
800 | string_sort (tmparray, len);
|
---|
801 |
|
---|
802 | array.erase(array.begin(), array.end());
|
---|
803 | for (i = 0; i < len; i ++) {
|
---|
804 | tmpstr = get_section_str(tmparray[i]);
|
---|
805 | array.push_back(tmpstr);
|
---|
806 | }
|
---|
807 | string_free(tmparray, len);
|
---|
808 | }
|
---|
809 |
|
---|