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