docview.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: docview.h
  3. // Purpose: topic overview
  4. // Author: wxWidgets team
  5. // Licence: wxWindows licence
  6. /////////////////////////////////////////////////////////////////////////////
  7. /**
  8. @page overview_docview Document/View Framework
  9. @tableofcontents
  10. The document/view framework is found in most application frameworks, because it
  11. can dramatically simplify the code required to build many kinds of application.
  12. The idea is that you can model your application primarily in terms of
  13. @e documents to store data and provide interface-independent operations upon
  14. it, and @e views to visualise and manipulate the data. Documents know how to do
  15. input and output given stream objects, and views are responsible for taking
  16. input from physical windows and performing the manipulation on the document
  17. data.
  18. If a document's data changes, all views should be updated to reflect the
  19. change. The framework can provide many user-interface elements based on this
  20. model.
  21. Once you have defined your own classes and the relationships between them, the
  22. framework takes care of popping up file selectors, opening and closing files,
  23. asking the user to save modifications, routing menu commands to appropriate
  24. (possibly default) code, even some default print/preview functionality and
  25. support for command undo/redo.
  26. The framework is highly modular, allowing overriding and replacement of
  27. functionality and objects to achieve more than the default behaviour.
  28. These are the overall steps involved in creating an application based on the
  29. document/view framework:
  30. @li Define your own document and view classes, overriding a minimal set of
  31. member functions e.g. for input/output, drawing and initialization.
  32. @li Define any subwindows (such as a scrolled window) that are needed for the
  33. view(s). You may need to route some events to views or documents, for
  34. example, "OnPaint" needs to be routed to wxView::OnDraw.
  35. @li Decide what style of interface you will use: Microsoft's MDI (multiple
  36. document child frames surrounded by an overall frame), SDI (a separate,
  37. unconstrained frame for each document), or single-window (one document open
  38. at a time, as in Windows Write).
  39. @li Use the appropriate wxDocParentFrame and wxDocChildFrame classes. Construct
  40. an instance of wxDocParentFrame in your wxApp::OnInit, and a
  41. wxDocChildFrame (if not single-window) when you initialize a view. Create
  42. menus using standard menu ids (such as wxID_OPEN, wxID_PRINT).
  43. @li Construct a single wxDocManager instance at the beginning of your
  44. wxApp::OnInit, and then as many wxDocTemplate instances as necessary to
  45. define relationships between documents and views. For a simple application,
  46. there will be just one wxDocTemplate.
  47. If you wish to implement Undo/Redo, you need to derive your own class(es) from
  48. wxCommand and use wxCommandProcessor::Submit instead of directly executing
  49. code. The framework will take care of calling Undo and Do functions as
  50. appropriate, so long as the wxID_UNDO and wxID_REDO menu items are defined in
  51. the view menu.
  52. Here are a few examples of the tailoring you can do to go beyond the default
  53. framework behaviour:
  54. @li Override wxDocument::OnCreateCommandProcessor to define a different Do/Undo
  55. strategy, or a command history editor.
  56. @li Override wxView::OnCreatePrintout to create an instance of a derived
  57. wxPrintout class, to provide multi-page document facilities.
  58. @li Override wxDocManager::SelectDocumentPath to provide a different file
  59. selector.
  60. @li Limit the maximum number of open documents and the maximum number of undo
  61. commands.
  62. Note that to activate framework functionality, you need to use some or all of
  63. the wxWidgets @ref overview_docview_predefid in your menus.
  64. @beginWxPerlOnly
  65. The document/view framework is available in wxPerl. To use it, you will need
  66. the following statements in your application code:
  67. @code{.pl}
  68. use Wx::DocView;
  69. use Wx ':docview'; # import constants (optional)
  70. @endcode
  71. @endWxPerlOnly
  72. @see @ref group_class_docview,
  73. @section overview_docview_wxdoc wxDocument Overview
  74. The wxDocument class can be used to model an application's file-based data. It
  75. is part of the document/view framework supported by wxWidgets, and cooperates
  76. with the wxView, wxDocTemplate and wxDocManager classes. Using this framework
  77. can save a lot of routine user-interface programming, since a range of menu
  78. commands -- such as open, save, save as -- are supported automatically.
  79. The programmer just needs to define a minimal set of classes and member
  80. functions for the framework to call when necessary. Data, and the means to view
  81. and edit the data, are explicitly separated out in this model, and the concept
  82. of multiple @e views onto the same data is supported.
  83. Note that the document/view model will suit many but not all styles of
  84. application. For example, it would be overkill for a simple file conversion
  85. utility, where there may be no call for @e views on @e documents or the ability
  86. to open, edit and save files. But probably the majority of applications are
  87. document-based.
  88. See the example application in @c samples/docview. To use the abstract
  89. wxDocument class, you need to derive a new class and override at least the
  90. member functions SaveObject and LoadObject. SaveObject and LoadObject will be
  91. called by the framework when the document needs to be saved or loaded.
  92. Use the macros DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS in order to
  93. allow the framework to create document objects on demand. When you create a
  94. wxDocTemplate object on application initialization, you should pass
  95. CLASSINFO(YourDocumentClass) to the wxDocTemplate constructor so that it knows
  96. how to create an instance of this class.
  97. If you do not wish to use the wxWidgets method of creating document objects
  98. dynamically, you must override wxDocTemplate::CreateDocument to return an
  99. instance of the appropriate class.
  100. @section overview_docview_wxview wxView Overview
  101. The wxView class can be used to model the viewing and editing component of an
  102. application's file-based data. It is part of the document/view framework
  103. supported by wxWidgets, and cooperates with the wxDocument, wxDocTemplate and
  104. wxDocManager classes.
  105. See the example application in @c samples/docview.
  106. To use the abstract wxView class, you need to derive a new class and override
  107. at least the member functions OnCreate, OnDraw, OnUpdate and OnClose. You will
  108. probably want to respond to menu commands from the frame containing the view.
  109. Use the macros DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS in order to
  110. allow the framework to create view objects on demand. When you create a
  111. wxDocTemplate object on application initialization, you should pass
  112. CLASSINFO(YourViewClass) to the wxDocTemplate constructor so that it knows how
  113. to create an instance of this class.
  114. If you do not wish to use the wxWidgets method of creating view objects
  115. dynamically, you must override wxDocTemplate::CreateView to return an instance
  116. of the appropriate class.
  117. @section overview_docview_wxdoctemplate wxDocTemplate Overview
  118. The wxDocTemplate class is used to model the relationship between a document
  119. class and a view class. The application creates a document template object for
  120. each document/view pair. The list of document templates managed by the
  121. wxDocManager instance is used to create documents and views. Each document
  122. template knows what file filters and default extension are appropriate for a
  123. document/view combination, and how to create a document or view.
  124. For example, you might write a small doodling application that can load and
  125. save lists of line segments. If you had two views of the data -- graphical, and
  126. a list of the segments -- then you would create one document class
  127. DoodleDocument, and two view classes (DoodleGraphicView and DoodleListView).
  128. You would also need two document templates, one for the graphical view and
  129. another for the list view. You would pass the same document class and default
  130. file extension to both document templates, but each would be passed a different
  131. view class. When the user clicks on the Open menu item, the file selector is
  132. displayed with a list of possible file filters -- one for each wxDocTemplate.
  133. Selecting the filter selects the wxDocTemplate, and when a file is selected,
  134. that template will be used for creating a document and view.
  135. For the case where an application has one document type and one view type,
  136. a single document template is constructed, and dialogs will be appropriately
  137. simplified.
  138. wxDocTemplate is part of the document/view framework supported by wxWidgets,
  139. and cooperates with the wxView, wxDocument and wxDocManager classes.
  140. See the example application in @c samples/docview.
  141. To use the wxDocTemplate class, you do not need to derive a new class. Just
  142. pass relevant information to the constructor including
  143. CLASSINFO(YourDocumentClass) and CLASSINFO(YourViewClass) to allow dynamic
  144. instance creation.
  145. If you do not wish to use the wxWidgets method of creating document
  146. objects dynamically, you must override wxDocTemplate::CreateDocument
  147. and wxDocTemplate::CreateView to return instances of the appropriate class.
  148. @note The document template has nothing to do with the C++ template construct.
  149. @section overview_docview_wxdocmanager wxDocManager Overview
  150. The wxDocManager class is part of the document/view framework supported by
  151. wxWidgets, and cooperates with the wxView, wxDocument and wxDocTemplate
  152. classes.
  153. A wxDocManager instance coordinates documents, views and document templates. It
  154. keeps a list of document and template instances, and much functionality is
  155. routed through this object, such as providing selection and file dialogs. The
  156. application can use this class 'as is' or derive a class and override some
  157. members to extend or change the functionality.
  158. Create an instance of this class near the beginning of your application
  159. initialization, before any documents, views or templates are manipulated.
  160. There may be multiple wxDocManager instances in an application. See the example
  161. application in @c samples/docview.
  162. @section overview_docview_events Event Propagation in Document/View framework
  163. While wxDocument, wxDocManager and wxView are abstract objects, with which the
  164. user can't interact directly, all of them derive from wxEvtHandler class and
  165. can handle events arising in the windows showing the document with which the
  166. user does interact. This is implemented by adding additional steps to the event
  167. handling process described in @ref overview_events_processing, so the full list
  168. of the handlers searched for an event occurring directly in wxDocChildFrame is:
  169. <ol>
  170. <li>wxDocument opened in this frame.</li>
  171. <li>wxView shown in this frame.</li>
  172. <li>wxDocManager associated with the parent wxDocParentFrame.</li>
  173. <li>wxDocChildFrame itself.</li>
  174. <li>wxDocParentFrame, as per the usual event bubbling up to parent rules.</li>
  175. <li>wxApp, again as the usual fallback for all events.</li>
  176. </ol>
  177. This is mostly useful to define handlers for some menu commands directly in
  178. wxDocument or wxView and is also used by the framework itself to define the
  179. handlers for several standard commands, such as wxID_NEW or wxID_SAVE, in
  180. wxDocManager itself. Notice that due to the order of the event handler search
  181. detailed above, the handling of these commands can @e not be overridden at
  182. wxDocParentFrame level but must be done at the level of wxDocManager itself.
  183. @section overview_docview_wxcommand wxCommand Overview
  184. wxCommand is a base class for modelling an application command, which is an
  185. action usually performed by selecting a menu item, pressing a toolbar button or
  186. any other means provided by the application to change the data or view.
  187. Instead of the application functionality being scattered around switch
  188. statements and functions in a way that may be hard to read and maintain, the
  189. functionality for a command is explicitly represented as an object which can be
  190. manipulated by a framework or application.
  191. When a user interface event occurs, the application @e submits a command to a
  192. wxCommandProcessor object to execute and store.
  193. The wxWidgets document/view framework handles Undo and Redo by use of wxCommand
  194. and wxCommandProcessor objects. You might find further uses for wxCommand, such
  195. as implementing a macro facility that stores, loads and replays commands.
  196. An application can derive a new class for every command, or, more likely, use
  197. one class parameterized with an integer or string command identifier.
  198. @section overview_docview_wxcommandproc wxCommandProcessor Overview
  199. wxCommandProcessor is a class that maintains a history of wxCommand instances,
  200. with undo/redo functionality built-in. Derive a new class from this if you want
  201. different behaviour.
  202. @section overview_docview_filehistory wxFileHistory Overview
  203. wxFileHistory encapsulates functionality to record the last few files visited,
  204. and to allow the user to quickly load these files using the list appended to
  205. the File menu. Although wxFileHistory is used by wxDocManager, it can be used
  206. independently. You may wish to derive from it to allow different behaviour,
  207. such as popping up a scrolling list of files.
  208. By calling wxFileHistory::UseMenu() you can associate a file menu with the file
  209. history. The menu will then be used for appending filenames that are added to
  210. the history.
  211. Please notice that currently if the history already contained filenames when
  212. UseMenu() is called (e.g. when initializing a second MDI child frame), the menu
  213. is not automatically initialized with the existing filenames in the history and
  214. so you need to call wxFileHistory::AddFilesToMenu() after UseMenu() explicitly
  215. in order to initialize the menu with the existing list of MRU files (otherwise
  216. an assertion failure is raised in debug builds).
  217. The filenames are appended using menu identifiers in the range @c wxID_FILE1 to
  218. @c wxID_FILE9.
  219. In order to respond to a file load command from one of these identifiers, you
  220. need to handle them using an event handler, for example:
  221. @code
  222. BEGIN_EVENT_TABLE(wxDocParentFrame, wxFrame)
  223. EVT_MENU(wxID_EXIT, wxDocParentFrame::OnExit)
  224. EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, wxDocParentFrame::OnMRUFile)
  225. END_EVENT_TABLE()
  226. void wxDocParentFrame::OnExit(wxCommandEvent& WXUNUSED(event))
  227. {
  228. Close();
  229. }
  230. void wxDocParentFrame::OnMRUFile(wxCommandEvent& event)
  231. {
  232. wxString f(m_docManager->GetHistoryFile(event.GetId() - wxID_FILE1));
  233. if (!f.empty())
  234. (void)m_docManager-CreateDocument(f, wxDOC_SILENT);
  235. }
  236. @endcode
  237. @section overview_docview_predefid Predefined Command Identifiers
  238. To allow communication between the application's menus and the document/view
  239. framework, several command identifiers are predefined for you to use in menus.
  240. @verbatim
  241. wxID_OPEN (5000)
  242. wxID_CLOSE (5001)
  243. wxID_NEW (5002)
  244. wxID_SAVE (5003)
  245. wxID_SAVEAS (5004)
  246. wxID_REVERT (5005)
  247. wxID_EXIT (5006)
  248. wxID_UNDO (5007)
  249. wxID_REDO (5008)
  250. wxID_HELP (5009)
  251. wxID_PRINT (5010)
  252. wxID_PRINT_SETUP (5011)
  253. wxID_PREVIEW (5012)
  254. @endverbatim
  255. */