From 1a833af2a43ef1bed45715bb725699508ba8adc3 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Tue, 10 May 2011 22:49:20 -0400 Subject: [PATCH] View - Broke out View into ViewTask and ViewText, where the former uses an external std::vector as storage, thus eliminating the additional copy, and the latter that duplicates data and color into 2D vectors for rendering non-task data. --- src/CMakeLists.txt | 75 +++++++-- src/{View.cpp => ViewTask.cpp} | 203 +----------------------- src/{View.h => ViewTask.h} | 11 +- src/ViewText.cpp | 282 +++++++++++++++++++++++++++++++++ src/ViewText.h | 92 +++++++++++ src/columns/ColString.cpp | 33 ++-- src/custom.cpp | 4 +- src/report.cpp | 12 ++ test/text.t.cpp | 8 +- test/view.t.cpp | 42 ++++- 10 files changed, 513 insertions(+), 249 deletions(-) rename src/{View.cpp => ViewTask.cpp} (61%) rename src/{View.h => ViewTask.h} (95%) create mode 100644 src/ViewText.cpp create mode 100644 src/ViewText.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6767c5ba..0c6327393 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,23 +4,64 @@ include_directories (${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/columns ${TASK_INCLUDE_DIRS}) -set (task_SRCS API.cpp API.h Att.cpp Att.h Cmd.cpp Cmd.h Color.cpp Color.h - Config.cpp Config.h Context.cpp Context.h Date.cpp Date.h - Directory.cpp Directory.h DOM.cpp DOM.h Duration.cpp Duration.h - File.cpp File.h Filter.cpp Filter.h feedback.cpp Grid.cpp Grid.h - Hooks.cpp Hooks.h JSON.cpp JSON.h Location.cpp Location.h - Nibbler.cpp Nibbler.h Path.cpp Path.h Permission.cpp Permission.h - Record.cpp Record.h Rectangle.cpp Rectangle.h Sequence.cpp - Sequence.h Subst.cpp Subst.h TDB.cpp TDB.h Table.cpp TDB2.cpp - TDB2.h Table.h Task.cpp Task.h Taskmod.cpp Taskmod.h Timer.cpp - Timer.h Transport.cpp Transport.h TransportSSH.cpp TransportSSH.h - TransportRSYNC.cpp TransportRSYNC.h TransportCurl.cpp - TransportCurl.h Tree.cpp Tree.h burndown.cpp command.cpp - custom.cpp dependency.cpp diag.cpp edit.cpp export.cpp - history.cpp i18n.h import.cpp interactive.cpp recur.cpp - report.cpp rules.cpp rx.cpp rx.h sort.cpp text.cpp text.h - utf8.cpp utf8.h util.cpp util.h Uri.cpp Uri.h Variant.cpp - Variant.h View.cpp View.h) +set (task_SRCS API.cpp API.h + Att.cpp Att.h + Cmd.cpp Cmd.h + Color.cpp Color.h + Config.cpp Config.h + Context.cpp Context.h + DOM.cpp DOM.h + Date.cpp Date.h + Directory.cpp Directory.h + Duration.cpp Duration.h + File.cpp File.h + Filter.cpp Filter.h + Grid.cpp Grid.h + Hooks.cpp Hooks.h + JSON.cpp JSON.h + Location.cpp Location.h + Nibbler.cpp Nibbler.h + Path.cpp Path.h + Permission.cpp Permission.h + Record.cpp Record.h + Rectangle.cpp Rectangle.h + Sequence.cpp Sequence.h + Subst.cpp Subst.h + TDB.cpp TDB.h + TDB2.cpp TDB2.h + Table.cpp Table.h + Task.cpp Task.h + Taskmod.cpp Taskmod.h + Timer.cpp Timer.h + Transport.cpp Transport.h + TransportCurl.cpp TransportCurl.h + TransportRSYNC.cpp TransportRSYNC.h + TransportSSH.cpp TransportSSH.h + Tree.cpp Tree.h + Uri.cpp Uri.h + Variant.cpp Variant.h + ViewTask.cpp ViewTask.h + ViewText.cpp ViewText.h + burndown.cpp + command.cpp + custom.cpp + dependency.cpp + diag.cpp + edit.cpp + export.cpp + feedback.cpp + history.cpp + i18n.h + import.cpp + interactive.cpp + recur.cpp + report.cpp + rules.cpp + rx.cpp rx.h + sort.cpp + text.cpp text.h + utf8.cpp utf8.h + util.cpp util.h) add_library (task STATIC ${task_SRCS}) add_executable (task_executable main.cpp) diff --git a/src/View.cpp b/src/ViewTask.cpp similarity index 61% rename from src/View.cpp rename to src/ViewTask.cpp index 682e7e277..0314f348b 100644 --- a/src/View.cpp +++ b/src/ViewTask.cpp @@ -25,14 +25,14 @@ // //////////////////////////////////////////////////////////////////////////////// -#include +#include #include #include #include #include //////////////////////////////////////////////////////////////////////////////// -View::View () +ViewTask::ViewTask () : _width (0) , _left_margin (0) , _header (0) @@ -94,9 +94,9 @@ View::View () // the larger fields. If the widest field is W0, and the second widest // field is W1, then a solution may be achievable by reducing W0 --> W1. // -std::string View::render (std::vector & data, std::vector & sequence) +std::string ViewTask::render (std::vector & data, std::vector & sequence) { - Timer timer ("View::render"); + Timer timer ("ViewTask::render"); // Determine minimal, ideal column widths. std::vector minimal; @@ -287,198 +287,3 @@ std::string View::render (std::vector & data, std::vector & sequence) } //////////////////////////////////////////////////////////////////////////////// -std::string View::render (std::vector >& data) -{ - Timer timer ("View::render"); -/* - // Determine minimal, ideal column widths. - std::vector minimal; - std::vector ideal; -// std::vector avg_ideal; -// int cumulative_ideal = 0; - - std::vector ::iterator i; - for (i = _columns.begin (); i != _columns.end (); ++i) - { - // Headers factor in to width calculations. - int global_min = utf8_length ((*i)->getLabel ()); - int global_ideal = global_min; - - std::vector ::iterator d; - for (d = data.begin (); d != data.end (); ++d) - { - // Determine minimum and ideal width for this column. - int min; - int ideal; - (*i)->measure (*d, min, ideal); - - if (min > global_min) global_min = min; - if (ideal > global_ideal) global_ideal = ideal; - -// cumulative_ideal += ideal; - } - - minimal.push_back (global_min); - ideal.push_back (global_ideal); - -// if (data.size ()) -// avg_ideal.push_back ((int) (cumulative_ideal / data.size ())); -// else -// avg_ideal.push_back (0); - } - - // Sum the minimal widths. - int sum_minimal = 0; - std::vector ::iterator c; - for (c = minimal.begin (); c != minimal.end (); ++c) - sum_minimal += *c; - - // Sum the ideal widths. - int sum_ideal = 0; - for (c = ideal.begin (); c != ideal.end (); ++c) - sum_ideal += *c; - - // Calculate final column widths. - int overage = _width - - _left_margin - - (2 * _extra_padding) - - ((_columns.size () - 1) * _intra_padding); - - std::vector widths; - if (sum_ideal <= overage) - widths = ideal; - else if (sum_minimal > overage) - throw std::string ("There is not enough horizontal width to display the results."); - else - { - widths = minimal; - overage -= sum_minimal; - - // Spread 'overage' among columns where width[i] < ideal[i] - while (overage) - { - for (int i = 0; i < _columns.size () && overage; ++i) - { - if (widths[i] < ideal[i]) - { - ++widths[i]; - --overage; - } - } - } - } - - // Compose column headers. - int max_lines = 0; - std::vector > headers; - for (int c = 0; c < _columns.size (); ++c) - { - headers.push_back (std::vector ()); - _columns[c]->renderHeader (headers[c], widths[c], _header); - - if (headers[c].size () > max_lines) - max_lines = headers[c].size (); - } -*/ - - // Output string. - std::string out; -/* - _lines = 0; - - // Render column headers. - std::string left_margin = std::string (_left_margin, ' '); - std::string extra = std::string (_extra_padding, ' '); - std::string intra = std::string (_intra_padding, ' '); - - std::string extra_odd = _extra_odd.colorize (extra); - std::string extra_even = _extra_even.colorize (extra); - std::string intra_odd = _intra_odd.colorize (intra); - std::string intra_even = _intra_even.colorize (intra); - - for (int i = 0; i < max_lines; ++i) - { - out += left_margin + extra; - - for (int c = 0; c < _columns.size (); ++c) - { - if (c) - out += intra; - - if (headers[i].size () < max_lines - i) - out += _header.colorize (std::string (widths[c], ' ')); - else - out += headers[c][i]; - } - - out += extra + "\n"; - - // Stop if the line limit is exceeded. - if (++_lines >= _truncate_lines && _truncate_lines != 0) - return out; - } - - // Compose, render columns, in sequence. - _rows = 0; - std::vector > cells; - std::vector ::iterator s; - for (int s = 0; s < sequence.size (); ++s) - { - max_lines = 0; - - // Apply color rules to task. - Color rule_color; - autoColorize (data[sequence[s]], rule_color); - - // Alternate rows based on |s % 2| - bool odd = (s % 2) ? true : false; - Color row_color = odd ? _odd : _even; - row_color.blend (rule_color); - - for (int c = 0; c < _columns.size (); ++c) - { - cells.push_back (std::vector ()); - _columns[c]->render (cells[c], data[sequence[s]], widths[c], row_color); - - if (cells[c].size () > max_lines) - max_lines = cells[c].size (); - } - - for (int i = 0; i < max_lines; ++i) - { - out += left_margin + (odd ? extra_odd : extra_even); - - for (int c = 0; c < _columns.size (); ++c) - { - if (c) - { - if (row_color.nontrivial ()) - out += row_color.colorize (intra); - else - out += (odd ? intra_odd : intra_even); - } - - if (i < cells[c].size ()) - out += cells[c][i]; - else - out += row_color.colorize (std::string (widths[c], ' ')); - } - - out += (odd ? extra_odd : extra_even) + "\n"; - - // Stop if the line limit is exceeded. - if (++_lines >= _truncate_lines && _truncate_lines != 0) - return out; - } - - cells.clear (); - - // Stop if the row limit is exceeded. - if (++_rows >= _truncate_rows && _truncate_rows != 0) - return out; - } -*/ - return out; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/View.h b/src/ViewTask.h similarity index 95% rename from src/View.h rename to src/ViewTask.h index 742193fe1..7a75f5d16 100644 --- a/src/View.h +++ b/src/ViewTask.h @@ -24,8 +24,8 @@ // USA // //////////////////////////////////////////////////////////////////////////////// -#ifndef INCLUDED_VIEW -#define INCLUDED_VIEW +#ifndef INCLUDED_VIEWTASK +#define INCLUDED_VIEWTASK #include #include @@ -33,11 +33,11 @@ #include #include -class View +class ViewTask { public: - View (); - ~View () {} + ViewTask (); + ~ViewTask () {} // View specifications. void add (Column* column) { _columns.push_back (column); } @@ -59,7 +59,6 @@ public: // View rendering. std::string render (std::vector &, std::vector &); - std::string render (std::vector >&); private: std::vector _columns; diff --git a/src/ViewText.cpp b/src/ViewText.cpp new file mode 100644 index 000000000..43a822c62 --- /dev/null +++ b/src/ViewText.cpp @@ -0,0 +1,282 @@ +//////////////////////////////////////////////////////////////////////////////// +// task - a command line task list manager. +// +// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +ViewText::ViewText () +: _width (0) +, _left_margin (0) +, _header (0) +, _odd (0) +, _even (0) +, _intra_padding (1) +, _intra_odd (0) +, _intra_even (0) +, _extra_padding (0) +, _extra_odd (0) +, _extra_even (0) +, _truncate_lines (0) +, _truncate_rows (0) +, _lines (0) +, _rows (0) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +void ViewText::add (const std::string& label) +{ + _columns.push_back (Column::factory ("string", label)); +} + +//////////////////////////////////////////////////////////////////////////////// +int ViewText::addRow () +{ + _data.push_back (std::vector (_columns.size (), "")); + _color.push_back (std::vector (_columns.size (), Color::nocolor)); + return _data.size () - 1; +} + +//////////////////////////////////////////////////////////////////////////////// +void ViewText::set (int row, int col, const std::string& value, Color color) +{ + _data[row][col] = value; + + if (color.nontrivial ()) + _color[row][col] = color; +} + +//////////////////////////////////////////////////////////////////////////////// +void ViewText::set (int row, int col, int value, Color color) +{ + std::string string_value = format (value); + _data[row][col] = value; + + if (color.nontrivial ()) + _color[row][col] = color; +} + +//////////////////////////////////////////////////////////////////////////////// +void ViewText::set (int row, int col, float value, int width, int precision, Color color) +{ + std::string string_value = format ((float)value, width, precision); + _data[row][col] = value; + + if (color.nontrivial ()) + _color[row][col] = color; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string ViewText::render () +{ + Timer timer ("ViewText::render"); + + // Determine minimal, ideal column widths. + std::vector minimal; + std::vector ideal; + + for (int col = 0; col < _columns.size (); ++col) + { + // Headers factor in to width calculations. + int global_min = utf8_length (_columns[col]->getLabel ()); + int global_ideal = global_min; + + for (int row = 0; row < _data.size (); ++row) + { + // Determine minimum and ideal width for this column. + int min; + int ideal; + _columns[col]->measure (_data[row][col], min, ideal); + + if (min > global_min) global_min = min; + if (ideal > global_ideal) global_ideal = ideal; + } + + minimal.push_back (global_min); + ideal.push_back (global_ideal); + } + + // Sum the minimal widths. + int sum_minimal = 0; + std::vector ::iterator c; + for (c = minimal.begin (); c != minimal.end (); ++c) + sum_minimal += *c; + + // Sum the ideal widths. + int sum_ideal = 0; + for (c = ideal.begin (); c != ideal.end (); ++c) + sum_ideal += *c; + + // Calculate final column widths. + int overage = _width + - _left_margin + - (2 * _extra_padding) + - ((_columns.size () - 1) * _intra_padding); + + std::vector widths; + if (sum_ideal <= overage) + widths = ideal; + else if (sum_minimal > overage) + throw std::string ("There is not enough horizontal width to display the results."); + else + { + widths = minimal; + overage -= sum_minimal; + + // Spread 'overage' among columns where width[i] < ideal[i] + while (overage) + { + for (int i = 0; i < _columns.size () && overage; ++i) + { + if (widths[i] < ideal[i]) + { + ++widths[i]; + --overage; + } + } + } + } + + // Compose column headers. + int max_lines = 0; + std::vector > headers; + for (int c = 0; c < _columns.size (); ++c) + { + headers.push_back (std::vector ()); + _columns[c]->renderHeader (headers[c], widths[c], _header); + + if (headers[c].size () > max_lines) + max_lines = headers[c].size (); + } + + // Output string. + std::string out; + _lines = 0; + + // Render column headers. + std::string left_margin = std::string (_left_margin, ' '); + std::string extra = std::string (_extra_padding, ' '); + std::string intra = std::string (_intra_padding, ' '); + + std::string extra_odd = _extra_odd.colorize (extra); + std::string extra_even = _extra_even.colorize (extra); + std::string intra_odd = _intra_odd.colorize (intra); + std::string intra_even = _intra_even.colorize (intra); + + for (int i = 0; i < max_lines; ++i) + { + out += left_margin + extra; + + for (int c = 0; c < _columns.size (); ++c) + { + if (c) + out += intra; + + if (headers[i].size () < max_lines - i) + out += _header.colorize (std::string (widths[c], ' ')); + else + out += headers[c][i]; + } + + out += extra + "\n"; + + // Stop if the line limit is exceeded. + if (++_lines >= _truncate_lines && _truncate_lines != 0) + return out; + } + + // Compose, render columns, in sequence. + _rows = 0; + std::vector > cells; + for (int row = 0; row < _data.size (); ++row) + { + max_lines = 0; + + // Alternate rows based on |s % 2| + bool odd = (row % 2) ? true : false; + Color row_color = odd ? _odd : _even; + + Color cell_color; + for (int col = 0; col < _columns.size (); ++col) + { + cell_color = row_color; + cell_color.blend (_color[row][col]); + + cells.push_back (std::vector ()); + _columns[col]->render (cells[col], _data[row][col], widths[col], cell_color); + + if (cells[col].size () > max_lines) + max_lines = cells[col].size (); + } + + for (int i = 0; i < max_lines; ++i) + { + out += left_margin + (odd ? extra_odd : extra_even); + + for (int col = 0; col < _columns.size (); ++col) + { + if (col) + { + if (row_color.nontrivial ()) + out += row_color.colorize (intra); + else + out += (odd ? intra_odd : intra_even); + } + + if (i < cells[col].size ()) + out += cells[col][i]; + else + { + cell_color = row_color; + cell_color.blend (_color[row][col]); + + out += cell_color.colorize (std::string (widths[col], ' ')); + } + } + + out += (odd ? extra_odd : extra_even) + "\n"; + + // Stop if the line limit is exceeded. + if (++_lines >= _truncate_lines && _truncate_lines != 0) + return out; + } + + cells.clear (); + + // Stop if the row limit is exceeded. + if (++_rows >= _truncate_rows && _truncate_rows != 0) + return out; + } + + return out; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/ViewText.h b/src/ViewText.h new file mode 100644 index 000000000..28854a15c --- /dev/null +++ b/src/ViewText.h @@ -0,0 +1,92 @@ +//////////////////////////////////////////////////////////////////////////////// +// task - a command line task list manager. +// +// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef INCLUDED_VIEWTEXT +#define INCLUDED_VIEWTEXT + +#include +#include +#include +#include +#include + +class ViewText +{ +public: + ViewText (); + ~ViewText () {} + + // View specifications. + void add (const std::string&); + void width (int width) { _width = width; } + void leftMargin (int margin) { _left_margin = margin; } + void colorHeader (Color& c) { _header = c; } + void colorOdd (Color& c) { _odd = c; } + void colorEven (Color& c) { _even = c; } + void intraPadding (int padding) { _intra_padding = padding; } + void intraColorOdd (Color& c) { _intra_odd = c; } + void intraColorEven (Color& c) { _intra_even = c; } + void extraPadding (int padding) { _extra_padding = padding; } + void extraColorOdd (Color& c) { _extra_odd = c; } + void extraColorEven (Color& c) { _extra_even = c; } + void truncateLines (int n) { _truncate_lines = n; } + void truncateRows (int n) { _truncate_rows = n; } + int lines () { return _lines; } + int rows () { return _rows; } + + // Data provision. + int addRow (); + void set (int, int, const std::string&, Color color = Color::nocolor); + void set (int, int, int, Color color = Color::nocolor); + void set (int, int, float, int, int, Color color = Color::nocolor); + + // View rendering. + std::string render (); + +private: + std::vector > _data; + std::vector > _color; + std::vector _columns; + int _width; + int _left_margin; + Color _header; + Color _odd; + Color _even; + int _intra_padding; + Color _intra_odd; + Color _intra_even; + int _extra_padding; + Color _extra_odd; + Color _extra_even; + int _truncate_lines; + int _truncate_rows; + int _lines; + int _rows; +}; + +#endif +//////////////////////////////////////////////////////////////////////////////// + diff --git a/src/columns/ColString.cpp b/src/columns/ColString.cpp index 38e9bb286..d5421a904 100644 --- a/src/columns/ColString.cpp +++ b/src/columns/ColString.cpp @@ -25,6 +25,7 @@ // //////////////////////////////////////////////////////////////////////////////// +#include // TODO Remove #include #include #include @@ -54,21 +55,18 @@ void ColumnString::setReport (const std::string& value) //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. +// void ColumnString::measure (const std::string& value, int& minimum, int& maximum) { - maximum = value.length (); + std::string stripped = Color::strip (value); + maximum = stripped.length (); - if (_style == "fixed") - { - minimum = maximum; - } - else if (_style == "default") - { - minimum = longestWord (value); - } + if (_style == "left" || + _style == "right" || + _style == "default") + minimum = longestWord (stripped); else throw std::string ("Unrecognized column format 'string.") + _style + "'"; - } //////////////////////////////////////////////////////////////////////////////// @@ -78,11 +76,7 @@ void ColumnString::render ( int width, Color& color) { - if (_style == "fixed") - { - lines.push_back (value); - } - else if (_style == "default") + if (_style == "default" || _style == "left") { std::vector raw; wrapText (raw, value, width); @@ -91,6 +85,15 @@ void ColumnString::render ( for (i = raw.begin (); i != raw.end (); ++i) lines.push_back (color.colorize (leftJustify (*i, width))); } + else if (_style == "right") + { + std::vector raw; + wrapText (raw, value, width); + + std::vector ::iterator i; + for (i = raw.begin (); i != raw.end (); ++i) + lines.push_back (color.colorize (rightJustify (*i, width))); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/custom.cpp b/src/custom.cpp index 3b77cf170..2bcd90ae7 100644 --- a/src/custom.cpp +++ b/src/custom.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include @@ -237,7 +237,7 @@ int handleCustomReport (const std::string& report, std::string& outs) sort_tasks (tasks, sequence, reportSort); // Configure the view. - View view; + ViewTask view; view.width (context.getWidth ()); view.leftMargin (context.config.getInteger ("indent.report")); view.extraPadding (context.config.getInteger ("row.padding")); diff --git a/src/report.cpp b/src/report.cpp index 309c82228..8efde1df4 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,14 @@ extern Context context; //////////////////////////////////////////////////////////////////////////////// int shortUsage (std::string& outs) { + ViewText view; + view.width (context.getWidth ()); + view.add (""); + view.add (""); + view.add (""); + + + Table table; table.addColumn (" "); @@ -284,6 +293,9 @@ int shortUsage (std::string& outs) std::stringstream out; out << table.render () << "\n" + << "-------------\n" + << view.render () + << "-------------\n" << "Documentation for taskwarrior can be found using 'man task', " << "'man taskrc', 'man task-tutorial', 'man task-color', 'man task-faq' " << "or at http://taskwarrior.org" diff --git a/test/text.t.cpp b/test/text.t.cpp index 9ebd13f7c..6191e5c68 100644 --- a/test/text.t.cpp +++ b/test/text.t.cpp @@ -35,7 +35,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (227); + UnitTest t (236); // void wrapText (std::vector & lines, const std::string& text, const int width) std::string text = "This is a test of the line wrapping code."; @@ -48,13 +48,12 @@ int main (int argc, char** argv) t.is (lines[3], "wrapping", "wrapText line 3 -> 'wrapping'"); t.is (lines[4], "code.", "wrapText line 4 -> 'code.'"); -#ifdef NOPE // void wrapText (std::vector & lines, const std::string& text, const int width) text = "This ☺ is a test of utf8 line extraction."; lines.clear (); wrapText (lines, text, 7); t.is (lines.size (), (size_t) 7, "wrapText 'This ☺ is a test of utf8 line extraction.' -> total 7 lines"); - t.is (lines[0], "This ☺", "wrapText line 0 -> 'This ☺'"); + t.is (lines[0], "This ☺", "wrapText line 0 -> 'This ☺'"); t.is (lines[1], "is a", "wrapText line 1 -> 'is a'"); t.is (lines[2], "test of", "wrapText line 2 -> 'test of'"); t.is (lines[3], "utf8", "wrapText line 3 -> 'utf8'"); @@ -64,12 +63,9 @@ int main (int argc, char** argv) // void extractLine (std::string& text, std::string& line, int length) text = "This ☺ is a test of utf8 line extraction."; -#endif std::string line; -#ifdef NOPE extractLine (text, line, 7); t.is (line, "line 1", "extractLine 7 'This ☺ is a test of utf8 line extraction.' -> 'This ☺'"); -#endif // void extractLine (std::string& text, std::string& line, int length) text = "line 1\nlengthy second line that exceeds width"; diff --git a/test/view.t.cpp b/test/view.t.cpp index f38c6b107..519fc3abf 100644 --- a/test/view.t.cpp +++ b/test/view.t.cpp @@ -28,7 +28,8 @@ #include #include #include -#include +#include +#include #include #include @@ -37,7 +38,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (1); + UnitTest t (2); try { @@ -100,7 +101,7 @@ int main (int argc, char** argv) // Create a view. std::string report = "view.t"; - View view; + ViewTask view; view.add (Column::factory ("id", report)); view.add (Column::factory ("uuid.short", report)); view.add (Column::factory ("project", report)); @@ -146,8 +147,41 @@ int main (int argc, char** argv) // Render the view. std::cout << view.render (data, sequence); - t.is (view.lines (), 5, "View::lines == 5"); + + // Now render a string-only grid. + context.config.set ("fontunderline", false); + Color single_cell ("bold white on red"); + + ViewText string_view; + string_view.width (context.getWidth ()); + string_view.leftMargin (4); + string_view.extraPadding (0); + string_view.intraPadding (1); + string_view.colorHeader (header_color); + string_view.colorOdd (odd_color); + string_view.colorEven (even_color); + string_view.intraColorOdd (odd_color); + string_view.intraColorEven (even_color); + + string_view.add ("One"); + string_view.add ("Two"); + string_view.add ("Three"); + + int row = string_view.addRow (); + string_view.set (row, 0, "top left"); + string_view.set (row, 1, "top center"); + string_view.set (row, 2, "top right"); + + row = string_view.addRow (); + string_view.set (row, 0, "bottom left", single_cell); + string_view.set (row, 1, "bottom center, containing sufficient text that " + "wrapping will occur because it exceeds all " + "reasonable values for default width."); + string_view.set (row, 2, "bottom right"); + + std::cout << string_view.render (); + t.ok (string_view.lines () > 4, "View::lines > 4"); } catch (std::string& e)