Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / onlinehelp / helpformat.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \libinternal \file
32  * \brief
33  * Declares common string formatting routines for online help.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \inlibraryapi
37  * \ingroup module_onlinehelp
38  */
39 #ifndef GMX_ONLINEHELP_HELPFORMAT_H
40 #define GMX_ONLINEHELP_HELPFORMAT_H
41
42 #include <string>
43
44 #include "../utility/common.h"
45
46 namespace gmx
47 {
48
49 class File;
50
51 /*! \libinternal \brief
52  * Formats rows of a table for text output.
53  *
54  * This utility class formats tabular data, mainly for console output.
55  * Each row in the table can take multiple lines, and automatic text wrapping
56  * is supported.  If text overflows the allocated width, the remaining columns
57  * on that line become shifted.  To avoid this, it is possible to start the
58  * output for different columns from different lines (it is the caller's
59  * responsibility to check that overflows are avoided or are acceptable).
60  *
61  * Column definitions are first set with addColumn().
62  * To format a row, first call clear().  Then call addColumnLine() to add text
63  * to each column (can be called multiple times on a single column to add
64  * multiple lines), and possibly setColumnFirstLineOffset() to adjust the line
65  * from which the column output should start.  Finally, call formatRow() to
66  * obtain the formatted row.
67  *
68  * A header (column titles and a horizontal line) is printed before the first
69  * line.
70  *
71  * Typical usage:
72  * \code
73 gmx::TextTableFormatter formatter;
74 formatter.addColumn("Name", 10, false);
75 formatter.addColumn("Type", 10, false);
76 formatter.addColumn("Description", 50, true);
77
78 formatter.clear();
79 formatter.addColumnLine(0, "name");
80 formatter.addColumnLine(1, "type");
81 formatter.addColumnLine(2, "Description for name");
82 printf("%s", formatter.formatRow().c_str());
83
84 formatter.clear();
85 formatter.addColumnLine(0, "averylongname");
86 formatter.addColumnLine(1, "type");
87 formatter.setColumnFirstLineOffset(1, 1);
88 formatter.addColumnLine(2, "Description for name");
89 printf("%s", formatter.formatRow().c_str());
90
91 // format other rows by repeating the above code
92  * \endcode
93  *
94  * Methods in this class may throw std::bad_alloc if out of memory.
95  * Other exceptions are not thrown.
96  *
97  * \inlibraryapi
98  * \ingroup module_onlinehelp
99  */
100 class TextTableFormatter
101 {
102     public:
103         //! Constructs an empty formatter.
104         TextTableFormatter();
105         ~TextTableFormatter();
106
107         /*! \brief
108          * Adds a column to the table.
109          *
110          * \param[in]  title  Title string for the column (used for header).
111          * \param[in]  width  Width of the column (must be > 0).
112          * \param[in]  bWrap  Whether text that exceeds \p width is
113          *      automatically wrapped.
114          *
115          * The length of \p title must not exceed \p width.
116          */
117         void addColumn(const char *title, int width, bool bWrap);
118         /*! \brief
119          * Sets amount on indentation before the first column.
120          *
121          * \param[in]  indent  Number of spaces to use for indenting.
122          *
123          * Does not throw.
124          */
125         void setFirstColumnIndent(int indent);
126
127         /*! \brief
128          * Whether formatRow() has been successfully called.
129          *
130          * This method can be used to determine after-the-fact whether anything
131          * was written in the table.
132          *
133          * Does not throw.
134          */
135         bool didOutput() const;
136
137         /*! \brief
138          * Removes all text from all columns and resets the line offsets.
139          *
140          * Removes all text added using addColumnLine() and resets line offsets
141          * set with setColumnFirstLineOffset() to zero.
142          * Should be called before starting to add data for a row.
143          *
144          * Does not throw.
145          */
146         void clear();
147         /*! \brief
148          * Adds text to be printed in a column.
149          *
150          * \param[in]  index     Zero-based column index.
151          * \param[in]  text      Text to add.
152          *
153          * Can be called multiple times.  Additional calls append \p text as
154          * additional lines.  Any calls with \p text empty have no effect.
155          * To add an empty line, use "\n" as \p text.
156          *
157          * If \p text contains newlines, the text is automatically splitted to
158          * multiple lines.  The same happens if automatic wrapping is on for
159          * the column and the text contains lines that are longer than what
160          * fits the column.
161          */
162         void addColumnLine(int index, const std::string &text);
163         /*! \brief
164          * Sets the first line to which text is printed for a column.
165          *
166          * \param[in]  index     Zero-based column index.
167          * \param[in]  firstLine Zero-based line index from which to start the
168          *      output.
169          *
170          * Can be called if there is no text for column \p index.
171          * Does not affect the output in this case.
172          *
173          * Does not throw.
174          */
175         void setColumnFirstLineOffset(int index, int firstLine);
176         /*! \brief
177          * Formats the lines for the current row.
178          *
179          * \returns  Current row formatted as a single string
180          *      (contains newlines).
181          *
182          * Formats the data as set after the previous clear()/formatRow() using
183          * addColumnLine() and setColumnFirstLineOffset().
184          *
185          * If this is the first line to be formatted, a header is also added to
186          * the beginning of the returned string if any column has a title.
187          *
188          * The return value always terminates with a newline.
189          *
190          * Calls clear() on successful return.
191          */
192         std::string formatRow();
193
194         /*! \brief
195          * Returns the last line on which column \p index has text.
196          *
197          * \param[in] index  Zero-based column index.
198          * \returns   Last line index (zero-based) on which \p index has text.
199          *
200          * The return value is the sum of the number of lines added with
201          * addColumnLine() (taking into account possible wrapping) and the line
202          * offset set with setColumnFirstLineOffset().
203          *
204          * Does not throw.
205          */
206         int lastColumnLine(int index) const;
207
208     private:
209         class Impl;
210
211         PrivateImplPointer<Impl> impl_;
212 };
213
214 } // namespace gmx
215
216 #endif