Save and restore file history in docview sample.
[wxWidgets.git] / samples / docview / docview.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/docview/docview.cpp
3 // Purpose: Document/view demo
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin: merge with the MDI version and general cleanup
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Julian Smart
9 // (c) 2008 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 /*
14 This sample show document/view support in wxWidgets.
15
16 It can be run in several ways:
17 * With "--mdi" command line option to use multiple MDI child frames
18 for the multiple documents (this is the default).
19 * With "--sdi" command line option to use multiple top level windows
20 for the multiple documents
21 * With "--single" command line option to support opening a single
22 document only
23
24 Notice that doing it like this somewhat complicates the code, you could
25 make things much simpler in your own programs by using either
26 wxDocParentFrame or wxDocMDIParentFrame unconditionally (and never using
27 the single mode) instead of supporting all of them as this sample does.
28 */
29
30 // ----------------------------------------------------------------------------
31 // headers
32 // ----------------------------------------------------------------------------
33
34 // For compilers that support precompilation, includes "wx/wx.h".
35 #include "wx/wxprec.h"
36
37 #ifdef __BORLANDC__
38 #pragma hdrstop
39 #endif
40
41 #ifndef WX_PRECOMP
42 #include "wx/wx.h"
43 #include "wx/stockitem.h"
44 #endif
45
46 #if !wxUSE_DOC_VIEW_ARCHITECTURE
47 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
48 #endif
49
50 #include "wx/docview.h"
51 #include "wx/docmdi.h"
52
53 #include "docview.h"
54 #include "doc.h"
55 #include "view.h"
56
57 #include "wx/cmdline.h"
58 #include "wx/config.h"
59
60 #ifdef __WXMAC__
61 #include "wx/filename.h"
62 #endif
63
64 #if !defined(__WXMSW__) && !defined(__WXPM__)
65 #include "doc.xpm"
66 #include "chart.xpm"
67 #include "notepad.xpm"
68 #endif
69
70 // ----------------------------------------------------------------------------
71 // MyApp implementation
72 // ----------------------------------------------------------------------------
73
74 IMPLEMENT_APP(MyApp)
75
76 BEGIN_EVENT_TABLE(MyApp, wxApp)
77 EVT_MENU(wxID_ABOUT, MyApp::OnAbout)
78 END_EVENT_TABLE()
79
80 MyApp::MyApp()
81 {
82 #if wxUSE_MDI_ARCHITECTURE
83 m_mode = Mode_MDI;
84 #else
85 m_mode = Mode_SDI;
86 #endif
87
88 m_canvas = NULL;
89 m_menuEdit = NULL;
90 }
91
92 // constants for the command line options names
93 namespace CmdLineOption
94 {
95
96 const char * const MDI = "mdi";
97 const char * const SDI = "sdi";
98 const char * const SINGLE = "single";
99
100 } // namespace CmdLineOption
101
102 void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
103 {
104 wxApp::OnInitCmdLine(parser);
105
106 parser.AddSwitch("", CmdLineOption::MDI,
107 "run in MDI mode: multiple documents, single window");
108 parser.AddSwitch("", CmdLineOption::SDI,
109 "run in SDI mode: multiple documents, multiple windows");
110 parser.AddSwitch("", CmdLineOption::SINGLE,
111 "run in single document mode");
112 }
113
114 bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser)
115 {
116 int numModeOptions = 0;
117
118 #if wxUSE_MDI_ARCHITECTURE
119 if ( parser.Found(CmdLineOption::MDI) )
120 {
121 m_mode = Mode_MDI;
122 numModeOptions++;
123 }
124 #endif // wxUSE_MDI_ARCHITECTURE
125
126 if ( parser.Found(CmdLineOption::SDI) )
127 {
128 m_mode = Mode_SDI;
129 numModeOptions++;
130 }
131
132 if ( parser.Found(CmdLineOption::SINGLE) )
133 {
134 m_mode = Mode_Single;
135 numModeOptions++;
136 }
137
138 if ( numModeOptions > 1 )
139 {
140 wxLogError("Only a single option choosing the mode can be given.");
141 return false;
142 }
143
144 return wxApp::OnCmdLineParsed(parser);
145 }
146
147 bool MyApp::OnInit()
148 {
149 if ( !wxApp::OnInit() )
150 return false;
151
152 ::wxInitAllImageHandlers();
153
154 // Fill in the application information fields before creating wxConfig.
155 SetVendorName("wxWidgets");
156 SetAppName("wx_docview_sample");
157 SetAppDisplayName("wxWidgets DocView Sample");
158
159 //// Create a document manager
160 wxDocManager *docManager = new wxDocManager;
161
162 //// Create a template relating drawing documents to their views
163 new wxDocTemplate(docManager, "Drawing", "*.drw", "", "drw",
164 "Drawing Doc", "Drawing View",
165 CLASSINFO(DrawingDocument), CLASSINFO(DrawingView));
166 #if defined( __WXMAC__ ) && wxOSX_USE_CARBON
167 wxFileName::MacRegisterDefaultTypeAndCreator("drw" , 'WXMB' , 'WXMA');
168 #endif
169
170 if ( m_mode == Mode_Single )
171 {
172 // If we've only got one window, we only get to edit one document at a
173 // time. Therefore no text editing, just doodling.
174 docManager->SetMaxDocsOpen(1);
175 }
176 else // multiple documents mode: allow documents of different types
177 {
178 // Create a template relating text documents to their views
179 new wxDocTemplate(docManager, "Text", "*.txt;*.text", "", "txt;text",
180 "Text Doc", "Text View",
181 CLASSINFO(TextEditDocument), CLASSINFO(TextEditView));
182 #if defined( __WXMAC__ ) && wxOSX_USE_CARBON
183 wxFileName::MacRegisterDefaultTypeAndCreator("txt" , 'TEXT' , 'WXMA');
184 #endif
185 // Create a template relating image documents to their views
186 new wxDocTemplate(docManager, "Image", "*.png;*.jpg", "", "png;jpg",
187 "Image Doc", "Image View",
188 CLASSINFO(ImageDocument), CLASSINFO(ImageView));
189 }
190
191 // create the main frame window
192 wxFrame *frame;
193 #if wxUSE_MDI_ARCHITECTURE
194 if ( m_mode == Mode_MDI )
195 {
196 frame = new wxDocMDIParentFrame(docManager, NULL, wxID_ANY,
197 GetAppDisplayName(),
198 wxDefaultPosition,
199 wxSize(500, 400));
200 }
201 else
202 #endif // wxUSE_MDI_ARCHITECTURE
203 {
204 frame = new wxDocParentFrame(docManager, NULL, wxID_ANY,
205 GetAppDisplayName(),
206 wxDefaultPosition,
207 wxSize(500, 400));
208 }
209
210 // and its menu bar
211 wxMenu *menuFile = new wxMenu;
212
213 menuFile->Append(wxID_NEW);
214 menuFile->Append(wxID_OPEN);
215
216 if ( m_mode == Mode_Single )
217 AppendDocumentFileCommands(menuFile, true);
218
219 menuFile->AppendSeparator();
220 menuFile->Append(wxID_EXIT);
221
222 // A nice touch: a history of files visited. Use this menu.
223 docManager->FileHistoryUseMenu(menuFile);
224 #if wxUSE_CONFIG
225 docManager->FileHistoryLoad(*wxConfig::Get());
226 #endif // wxUSE_CONFIG
227
228
229 if ( m_mode == Mode_Single )
230 {
231 m_canvas = new MyCanvas(NULL, frame);
232 m_menuEdit = CreateDrawingEditMenu();
233 docManager->CreateNewDocument();
234 }
235
236 CreateMenuBarForFrame(frame, menuFile, m_menuEdit);
237
238 frame->SetIcon(wxICON(doc));
239 frame->Centre();
240 frame->Show();
241
242 return true;
243 }
244
245 int MyApp::OnExit()
246 {
247 wxDocManager * const manager = wxDocManager::GetDocumentManager();
248 #if wxUSE_CONFIG
249 manager->FileHistorySave(*wxConfig::Get());
250 #endif // wxUSE_CONFIG
251 delete manager;
252
253 return wxApp::OnExit();
254 }
255
256 void MyApp::AppendDocumentFileCommands(wxMenu *menu, bool supportsPrinting)
257 {
258 menu->Append(wxID_CLOSE);
259 menu->Append(wxID_SAVE);
260 menu->Append(wxID_SAVEAS);
261 menu->Append(wxID_REVERT, _("Re&vert..."));
262
263 if ( supportsPrinting )
264 {
265 menu->AppendSeparator();
266 menu->Append(wxID_PRINT);
267 menu->Append(wxID_PRINT_SETUP, "Print &Setup...");
268 menu->Append(wxID_PREVIEW);
269 }
270 }
271
272 wxMenu *MyApp::CreateDrawingEditMenu()
273 {
274 wxMenu * const menu = new wxMenu;
275 menu->Append(wxID_UNDO);
276 menu->Append(wxID_REDO);
277 menu->AppendSeparator();
278 menu->Append(wxID_CUT, "&Cut last segment");
279
280 return menu;
281 }
282
283 void MyApp::CreateMenuBarForFrame(wxFrame *frame, wxMenu *file, wxMenu *edit)
284 {
285 wxMenuBar *menubar = new wxMenuBar;
286
287 menubar->Append(file, wxGetStockLabel(wxID_FILE));
288
289 if ( edit )
290 menubar->Append(edit, wxGetStockLabel(wxID_EDIT));
291
292 wxMenu *help= new wxMenu;
293 help->Append(wxID_ABOUT);
294 menubar->Append(help, wxGetStockLabel(wxID_HELP));
295
296 frame->SetMenuBar(menubar);
297 }
298
299 wxFrame *MyApp::CreateChildFrame(wxView *view, bool isCanvas)
300 {
301 // create a child frame of appropriate class for the current mode
302 wxFrame *subframe;
303 wxDocument *doc = view->GetDocument();
304 #if wxUSE_MDI_ARCHITECTURE
305 if ( GetMode() == Mode_MDI )
306 {
307 subframe = new wxDocMDIChildFrame
308 (
309 doc,
310 view,
311 wxStaticCast(GetTopWindow(), wxDocMDIParentFrame),
312 wxID_ANY,
313 "Child Frame",
314 wxDefaultPosition,
315 wxSize(300, 300)
316 );
317 }
318 else
319 #endif // wxUSE_MDI_ARCHITECTURE
320 {
321 subframe = new wxDocChildFrame
322 (
323 doc,
324 view,
325 wxStaticCast(GetTopWindow(), wxDocParentFrame),
326 wxID_ANY,
327 "Child Frame",
328 wxDefaultPosition,
329 wxSize(300, 300)
330 );
331
332 subframe->Centre();
333 }
334
335 wxMenu *menuFile = new wxMenu;
336
337 menuFile->Append(wxID_NEW);
338 menuFile->Append(wxID_OPEN);
339 AppendDocumentFileCommands(menuFile, isCanvas);
340 menuFile->AppendSeparator();
341 menuFile->Append(wxID_EXIT);
342
343 wxMenu *menuEdit;
344 if ( isCanvas )
345 {
346 menuEdit = CreateDrawingEditMenu();
347
348 doc->GetCommandProcessor()->SetEditMenu(menuEdit);
349 doc->GetCommandProcessor()->Initialize();
350 }
351 else // text frame
352 {
353 menuEdit = new wxMenu;
354 menuEdit->Append(wxID_COPY);
355 menuEdit->Append(wxID_PASTE);
356 menuEdit->Append(wxID_SELECTALL);
357 }
358
359 CreateMenuBarForFrame(subframe, menuFile, menuEdit);
360
361 subframe->SetIcon(isCanvas ? wxICON(chrt) : wxICON(notepad));
362
363 return subframe;
364 }
365
366 void MyApp::OnAbout(wxCommandEvent& WXUNUSED(event))
367 {
368 wxString modeName;
369 switch ( m_mode )
370 {
371 #if wxUSE_MDI_ARCHITECTURE
372 case Mode_MDI:
373 modeName = "MDI";
374 break;
375 #endif // wxUSE_MDI_ARCHITECTURE
376
377 case Mode_SDI:
378 modeName = "SDI";
379 break;
380
381 case Mode_Single:
382 modeName = "single document";
383 break;
384
385 default:
386 wxFAIL_MSG( "unknown mode ");
387 }
388
389 wxLogMessage
390 (
391 "This is the wxWidgets Document/View Sample\n"
392 "running in %s mode.\n"
393 "\n"
394 "Authors: Julian Smart, Vadim Zeitlin\n"
395 "\n"
396 "Usage: docview [--{mdi,sdi,single}]",
397 modeName
398 );
399 }
400