Merge remote-tracking branch 'origin/release-4-6' into HEAD
[alexxy/gromacs.git] / src / gromacs / onlinehelp / helptopic.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 helper classes and functions for implementing
34  * gmx::HelpTopicInterface.
35  *
36  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
37  * \inlibraryapi
38  * \ingroup module_onlinehelp
39  */
40 #ifndef GMX_ONLINEHELP_HELPTOPIC_H
41 #define GMX_ONLINEHELP_HELPTOPIC_H
42
43 #include "../utility/stringutil.h"
44 #include "../utility/uniqueptr.h"
45
46 #include "helptopicinterface.h"
47
48 namespace gmx
49 {
50
51 /*! \cond libapi */
52 /*! \libinternal \brief
53  * Helper for writing simple help text.
54  *
55  * \param[in] context Context for writing the help.
56  * \param[in] topic   Topic to write the help for (used for title).
57  * \param[in] text    Text to write for the topic.
58  * \throws    std::bad_alloc if out of memory.
59  * \throws    FileIOError on any I/O error.
60  *
61  * Formats basic help by writing a title (obtained from \p topic), followed by
62  * \p text with markup substituted and lines properly wrapped.
63  *
64  * \inlibraryapi
65  */
66 void writeBasicHelpTopic(const HelpWriterContext &context,
67                          const HelpTopicInterface &topic,
68                          const std::string &text);
69 //! \endcond
70
71 /*! \libinternal \brief
72  * Abstract base class for help topics that have simple text and no subtopics.
73  *
74  * This class implements subtopic-related methods from HelpTopicInterface such
75  * that there are no subtopics.  writeHelp() is also implemented such that it
76  * uses writeBasicHelpTopic() to write out the text returned by a new virtual
77  * method helpText().
78  *
79  * \see SimpleHelpTopic
80  *
81  * \inlibraryapi
82  * \ingroup module_onlinehelp
83  */
84 class AbstractSimpleHelpTopic : public HelpTopicInterface
85 {
86     public:
87         virtual const char *name() const = 0;
88         virtual const char *title() const = 0;
89
90         virtual bool hasSubTopics() const;
91         virtual const HelpTopicInterface *findSubTopic(const char *name) const;
92
93         virtual void writeHelp(const HelpWriterContext &context) const;
94
95     protected:
96         /*! \brief
97          * Returns the help text for this topic.
98          *
99          * writeHelp() calls this method to obtain the actual text to format
100          * for the topic.  Markup substitution etc. is done automatically by
101          * writeHelp().
102          */
103         virtual std::string helpText() const = 0;
104 };
105
106 /*! \libinternal \brief
107  * Abstract base class for help topics that have simple text and subtopics.
108  *
109  * This class implements an internal container for subtopics and provides
110  * public methods for adding subtopics (as HelpTopicInterface objects).
111  * Subtopic-related methods from HelpTopicInterface are implemented to access
112  * the internal container.  writeHelp() is also implemented such that it
113  * uses writeBasicHelpTopic() to write out the text returned by a new virtual
114  * method helpText(), and a list of subtopics is written after the actual text.
115  *
116  * \see CompositeHelpTopic
117  *
118  * \inlibraryapi
119  * \ingroup module_onlinehelp
120  */
121 class AbstractCompositeHelpTopic : public HelpTopicInterface
122 {
123     public:
124         AbstractCompositeHelpTopic();
125         virtual ~AbstractCompositeHelpTopic();
126
127         virtual const char *name() const = 0;
128         virtual const char *title() const = 0;
129
130         virtual bool hasSubTopics() const;
131         virtual const HelpTopicInterface *findSubTopic(const char *name) const;
132
133         virtual void writeHelp(const HelpWriterContext &context) const;
134
135         /*! \brief
136          * Adds a given topic as a subtopic of this topic.
137          *
138          * \param   topic  Topis to add.
139          * \throws  std::bad_alloc if out of memory.
140          *
141          * This topic takes ownership of the object.
142          *
143          * \see registerSubTopic()
144          */
145         void addSubTopic(HelpTopicPointer topic);
146         /*! \brief
147          * Registers a subtopic of a certain type to this topic.
148          *
149          * \tparam  Topic  Type of topic to register.
150          * \throws  std::bad_alloc if out of memory.
151          *
152          * \p Topic must be default-constructible and implement
153          * HelpTopicInterface.
154          *
155          * This method is provided as a convenient alternative to addSubTopic()
156          * for cases where each topic is implemented by a different type
157          * (which is a common case outside unit tests).
158          */
159         template <class Topic>
160         void registerSubTopic()
161         {
162             addSubTopic(HelpTopicPointer(new Topic));
163         }
164
165     protected:
166         //! \copydoc AbstractSimpleHelpTopic::helpText()
167         virtual std::string helpText() const = 0;
168
169         /*! \brief
170          * Writes the list of subtopics.
171          *
172          * \param[in] context Context for writing the help.
173          * \param[in] title  Title for the written list.
174          * \returns   true if anything was printed.
175          * \throws    std::bad_alloc if out of memory.
176          * \throws    FileIOError on any I/O error.
177          *
178          * Subtopics with empty titles are skipped from the list.
179          * If there would be no subtopics in the list, \p title is not printed
180          * either.
181          *
182          * This method is provided for cases where helpText() does not provide
183          * the needed flexibility and the derived class needs to override
184          * writeHelp().  This method can then be called to print the same
185          * subtopic list that is printed by the default writeHelp()
186          * implementation.
187          */
188         bool writeSubTopicList(const HelpWriterContext &context,
189                                const std::string &title) const;
190
191     private:
192         class Impl;
193
194         PrivateImplPointer<Impl> impl_;
195 };
196
197 /*! \cond libapi */
198 /*! \libinternal \brief
199  * Smart pointer type to manage a AbstractCompositeHelpTopic object.
200  *
201  * \inlibraryapi
202  */
203 typedef gmx_unique_ptr<AbstractCompositeHelpTopic>::type
204         CompositeHelpTopicPointer;
205 //! \endcond
206
207 /*! \libinternal \brief
208  * Template for simple implementation of AbstractSimpleHelpTopic.
209  *
210  * \tparam HelpText Struct that defines the data for the topic.
211  *
212  * \p HelpText should have public static members \c "const char name[]",
213  * \c "const char title[]" and \c "const char *const text[]".
214  *
215  * Typical use:
216  * \code
217 struct ExampleHelpText
218 {
219     static const char name[];
220     static const char title[];
221     static const char *const text[];
222 };
223
224 const char ExampleHelpText::name[] = "example";
225 const char ExampleHelpText::title[] =
226     "Example title";
227 const char *const ExampleHelpText::text[] = {
228     "Text for the topic.",
229     "More text for the topic."
230 };
231
232 typedef SimpleHelpTopic<ExampleHelpText> ExampleHelpTopic;
233  * \endcode
234  *
235  * \inlibraryapi
236  * \ingroup module_onlinehelp
237  */
238 template <class HelpText>
239 class SimpleHelpTopic : public AbstractSimpleHelpTopic
240 {
241     public:
242         virtual const char *name() const
243         {
244             return HelpText::name;
245         }
246         virtual const char *title() const
247         {
248             return HelpText::title;
249         }
250
251     protected:
252         virtual std::string helpText() const
253         {
254             return concatenateStrings(HelpText::text);
255         }
256 };
257
258 /*! \libinternal \brief
259  * Template for simple implementation of AbstractCompositeHelpTopic.
260  *
261  * \tparam HelpText Struct that defines the data for the topic.
262  *
263  * Used similarly to SimpleHelpTopic.
264  * \p HelpText should satisfy the same criteria as for SimpleHelpTopic.
265  *
266  * \see SimpleHelpTopic
267  *
268  * \inlibraryapi
269  * \ingroup module_onlinehelp
270  */
271 template <class HelpText>
272 class CompositeHelpTopic : public AbstractCompositeHelpTopic
273 {
274     public:
275         virtual const char *name() const
276         {
277             return HelpText::name;
278         }
279         virtual const char *title() const
280         {
281             return HelpText::title;
282         }
283
284     protected:
285         virtual std::string helpText() const
286         {
287             return concatenateStrings(HelpText::text);
288         }
289 };
290
291 } // namespace gmx
292
293 #endif