14 namespace duds {
namespace ui {
17 const std::string &separator,
18 const std::string &ellips,
21 ) : sep(separator), maxLen(mlen), maxPageLen(mtitle) {
37 std::string::size_type len = h.size() +
ellip.size() +
postCur.size();
48 std::string::size_type len = f.size() +
ellip.size() +
preCur.size();
76 if (max <=
ellip.size()) {
106 const std::string &title,
110 if (title.size() > max) {
113 std::string::size_type space =
114 title.find_last_of(
' ', max -
ellip.size());
116 if ((space != std::string::npos) && (space >=
minPageLen)) {
118 total += space +
ellip.size();
124 while ((max >
ellip.size()) && (title[max -
ellip.size() - 1] ==
' ')) {
130 return max -
ellip.size();
133 total += title.size();
138 total -= tt.
len +
sep.size();
140 total -=
ellip.size();
149 return (totalLen - currLen) / (numtitles - 1) +
150 (((totalLen - currLen) % (numtitles - 1) > 0) ? 1 : 0);
156 return std::string();
160 std::vector<TrucatedTitle> titles;
162 Path::PageStack::const_reverse_iterator eiter = path.
rend();
164 Path::PageStack::const_reverse_iterator citer = path.
rcurrent();
166 Path::PageStack::const_reverse_iterator iter = citer;
177 int pcount = eiter - iter;
185 int tlen = -(int)
sep.size();
188 titles.reserve(pcount);
192 for (; (iter != eiter) && ((tlen < 0) || ((tlen >> 1) <
maxLen)); ++iter) {
193 int &len = (iter == citer) ? clen : tlen;
222 titles.resize(haveFwd + 1);
226 titles.erase(titles.begin());
228 assert(titles.size() == 1);
230 tlen = clen = titles.front().len +
preCur.size() +
postCur.size();
231 assert((
unsigned int)tlen <=
maxLen);
234 else if ((
unsigned int)tlen >
maxLen) {
241 ((
unsigned int)tlen >
maxLen) &&
244 (avgLen >=
minPageLen) && (titles.size() > (2 + haveFwd))
251 if (haveFwd && (titles.size() == 3) && ((
unsigned int)tlen >
maxLen)) {
255 titles.erase(titles.begin());
260 while ((
unsigned int)tlen >
maxLen) {
264 int poveracc = overacc;
267 std::vector<TrucatedTitle>::reverse_iterator titer = titles.rbegin();
268 std::vector<TrucatedTitle>::reverse_iterator etiter = titles.rend();
269 std::vector<TrucatedTitle>::reverse_iterator ctiter =
270 titles.rend() - (1 + haveFwd);
271 for (; titer != etiter; ++titer) {
273 if (titer == ctiter)
continue;
275 std::string::size_type len = titer->len;
276 if (len != titer->title->size()) {
283 int plen = titer->len;
284 titer->len =
titleLength(*titer->title, tlen, pmax);
287 if ((plen == titer->len) ||
293 (titles.size() > 2) &&
295 ((*titer->title)[titer->len] !=
' ')
301 (titer == titles.rbegin()) ||
302 (titer == (etiter - 1))
308 titles.erase(titles.begin());
314 else if (titer == titles.rbegin()) {
324 if (plen != titer->len) {
328 tlen += plen +
sep.size();
329 if (titer->len < titer->title->size()) {
330 tlen +=
ellip.size();
335 overacc += len - pmax;
339 assert(((
int)len - pmax) > 0);
345 if ((overacc == poveracc) && ((
unsigned int)tlen >
maxLen)) {
351 ) * (
int)titles.size() - (int)
maxLen,
356 assert((
unsigned int)tlen <=
maxLen);
360 std::vector<TrucatedTitle>::reverse_iterator titer = titles.rbegin();
361 std::vector<TrucatedTitle>::reverse_iterator etiter = titles.rend();
362 std::vector<TrucatedTitle>::reverse_iterator ctiter =
363 titles.rend() - (1 + haveFwd);
364 for (; titer != etiter; ++titer) {
366 if (titer == ctiter) {
371 res.insert(res.size(), *titer->title, 0, titer->len);
373 if (titer->title->size() != titer->len) {
378 if (titer == ctiter) {
383 if (titer != (etiter - 1)) {
388 assert(res.size() == tlen);
std::string::size_type titleLength(const std::string &title, int &total, unsigned int max) const
Finds the usable length of the given title and adjusts the total length of the path string...
const std::string * title
The title string.
unsigned int maxTitleLength() const
Returns the maximum length allocated to a page title in the output path string.
PageStack::const_reverse_iterator rend() const
Reverse iterator to the start of the page stack.
std::string preCur
Marker string that preceds the current page title.
unsigned int maxPages
The maximum number of titles to show.
boost::error_info< struct Info_StringLength, std::string::size_type > StringLength
Error attribute used by PathStringGenerator to denote a string length that is important in the contex...
PageStack::const_reverse_iterator rcurrent() const
Reverse iterator to the current page.
unsigned int maxLen
The maximum length of the output string.
const std::string & ellipsis() const
Returns the string appended to the end of page titles that are shortened to fit.
bool abruptSplit
Break long titles without considering spaces within the title.
static int averageLength(int numtitles, int totalLen, int currLen)
Computes the average length of the titles, excluding the current page title, and rounds up...
unsigned int maxLength() const
Returns the maximum length of the generated path strings.
const std::string & currentHeader() const
Returns the string prepended to the current page title.
bool wholeCurrent
True to show the entire title of the current page if it will fit within maxLen, and use more than max...
std::string ellip
Last character(s) to use when part of a title is not shown.
std::string::size_type len
The length of the title.
boost::error_info< struct Info_PathMaxTitleLength, unsigned int > PathMaxTitleLength
Error attribute used by PathStringGenerator to hold the maximum length of page titles in its output...
bool empty() const
Returns true if the page stack is empty.
std::string postCur
Marker string that follows the current page title.
unsigned int minPageLen
The minimum length of any title; if fewer characters are availble, fewer titles will be shown...
std::string sep
Separator between page titles.
bool showFwd
True to show one page forward past the current page if such a page exits.
PageStack::const_reverse_iterator rbegin() const
Reverse iterator to the end of the page stack.
std::string generate(const Path &path) const
Generates the path string for the given Path object.
const std::string & currentFooter() const
Returns the string appended to the end of the current page title.
boost::error_info< struct Info_PathMaxLength, unsigned int > PathMaxLength
Error attribute used by PathStringGenerator to hold the maximum length of its string output...
Error that signifies a PathStringGenerator object was given a parameter value that conflicts with ano...
unsigned int minTitleLength() const
Returns the minimum length for a shortened page title in the output path string.
void decTitleLen(const TrucatedTitle &tt, int &total) const
Removes the given title from the total path length, along with the length of the separator and ellips...
unsigned int maxPageLen
The maximum length of any single title, with the possibile exception of the current page...
boost::error_info< struct Info_PathMinTitleLength, unsigned int > PathMinTitleLength
Error attribute used by PathStringGenerator to hold the minimum length of page titles in its output...
PathStringGenerator()=default
Makes a PathStringGenerator with default values.
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
An internal data structure used to track the titles to include in the path string and the length of e...
Stores a list of pages the user has visited in the order of the visits.