Applied #10829: docview sample: enable canvas in --single mode
[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 license
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
59 #ifdef __WXMAC__
60 #include "wx/filename.h"
61 #endif
62
63 #if !defined(__WXMSW__) && !defined(__WXPM__)
64 #include "doc.xpm"
65 #include "chart.xpm"
66 #include "notepad.xpm"
67 #endif
68
69 // ----------------------------------------------------------------------------
70 // MyApp implementation
71 // ----------------------------------------------------------------------------
72
73 IMPLEMENT_APP(MyApp)
74
75 BEGIN_EVENT_TABLE(MyApp, wxApp)
76 EVT_MENU(wxID_ABOUT, MyApp::OnAbout)
77 END_EVENT_TABLE()
78
79 MyApp::MyApp()
80 {
81 #if wxUSE_MDI_ARCHITECTURE
82 m_mode = Mode_MDI;
83 #else
84 m_mode = Mode_SDI;
85 #endif
86
87 m_canvas = NULL;
88 m_menuEdit = NULL;
89 }
90
91 // constants for the command line options names
92 namespace CmdLineOption
93 {
94
95 const char * const MDI = "mdi";
96 const char * const SDI = "sdi";
97 const char * const SINGLE = "single";
98
99 } // namespace CmdLineOption
100
101 void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
102 {
103 wxApp::OnInitCmdLine(parser);
104
105 parser.AddSwitch("", CmdLineOption::MDI,
106 "run in MDI mode: multiple documents, single window");
107 parser.AddSwitch("", CmdLineOption::SDI,
108 "run in SDI mode: multiple documents, multiple windows");
109 parser.AddSwitch("", CmdLineOption::SINGLE,
110 "run in single document mode");
111 }
112
113 bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser)
114 {
115 int numModeOptions = 0;
116
117 #if wxUSE_MDI_ARCHITECTURE
118 if ( parser.Found(CmdLineOption::MDI) )
119 {
120 m_mode = Mode_MDI;
121 numModeOptions++;
122 }
123 #endif // wxUSE_MDI_ARCHITECTURE
124
125 if ( parser.Found(CmdLineOption::SDI) )
126 {
127 m_mode = Mode_SDI;
128 numModeOptions++;
129 }
130
131 if ( parser.Found(CmdLineOption::SINGLE) )
132 {
133 m_mode = Mode_Single;
134 numModeOptions++;
135 }
136
137 if ( numModeOptions > 1 )
138 {
139 wxLogError("Only a single option choosing the mode can be given.");
140 return false;
141 }
142
143 return wxApp::OnCmdLineParsed(parser);
144 }
145
146 bool MyApp::OnInit()
147 {
148 if ( !wxApp::OnInit() )
149 return false;
150
151 SetAppName("DocView Sample");
152
153 //// Create a document manager
154 wxDocManager *docManager = new wxDocManager;
155
156 //// Create a template relating drawing documents to their views
157 new wxDocTemplate(docManager, "Drawing", "*.drw", "", "drw",
158 "Drawing Doc", "Drawing View",
159 CLASSINFO(DrawingDocument), CLASSINFO(DrawingView));
160 #if defined( __WXMAC__ ) && wxOSX_USE_CARBON
161 wxFileName::MacRegisterDefaultTypeAndCreator("drw" , 'WXMB' , 'WXMA');
162 #endif
163
164 if ( m_mode == Mode_Single )
165 {
166 // If we've only got one window, we only get to edit one document at a
167 // time. Therefore no text editing, just doodling.
168 docManager->SetMaxDocsOpen(1);
169 }
170 else // multiple documents mode: allow documents of different types
171 {
172 // Create a template relating text documents to their views
173 new wxDocTemplate(docManager, "Text", "*.txt;*.text", "", "txt;text",
174 "Text Doc", "Text View",
175 CLASSINFO(TextEditDocument), CLASSINFO(TextEditView));
176 #if defined( __WXMAC__ ) && wxOSX_USE_CARBON
177 wxFileName::MacRegisterDefaultTypeAndCreator("txt" , 'TEXT' , 'WXMA');
178 #endif
179 }
180
181 // create the main frame window
182 wxFrame *frame;
183 #if wxUSE_MDI_ARCHITECTURE
184 if ( m_mode == Mode_MDI )
185 {
186 frame = new wxDocMDIParentFrame(docManager, NULL, wxID_ANY,
187 GetAppDisplayName(),
188 wxDefaultPosition,
189 wxSize(500, 400));
190 }
191 else
192 #endif // wxUSE_MDI_ARCHITECTURE
193 {
194 frame = new wxDocParentFrame(docManager, NULL, wxID_ANY,
195 GetAppDisplayName(),
196 wxDefaultPosition,
197 wxSize(500, 400));
198 }
199
200 // and its menu bar
201 wxMenu *menuFile = new wxMenu;
202
203 menuFile->Append(wxID_NEW);
204 menuFile->Append(wxID_OPEN);
205
206 if ( m_mode == Mode_Single )
207 AppendDocumentFileCommands(menuFile, true);
208
209 menuFile->AppendSeparator();
210 menuFile->Append(wxID_EXIT);
211
212 // A nice touch: a history of files visited. Use this menu.
213 docManager->FileHistoryUseMenu(menuFile);
214
215 if ( m_mode == Mode_Single )
216 {
217 m_canvas = new MyCanvas(NULL, frame);
218 m_menuEdit = CreateDrawingEditMenu();
219 docManager->CreateNewDocument();
220 }
221
222 CreateMenuBarForFrame(frame, menuFile, m_menuEdit);
223
224 frame->SetIcon(wxICON(doc));
225 frame->Centre(wxBOTH);
226 frame->Show(true);
227
228 SetTopWindow(frame);
229 return true;
230 }
231
232 int MyApp::OnExit()
233 {
234 delete wxDocManager::GetDocumentManager();
235
236 return wxApp::OnExit();
237 }
238
239 void MyApp::AppendDocumentFileCommands(wxMenu *menu, bool supportsPrinting)
240 {
241 menu->Append(wxID_CLOSE);
242 menu->Append(wxID_SAVE);
243 menu->Append(wxID_SAVEAS);
244
245 if ( supportsPrinting )
246 {
247 menu->AppendSeparator();
248 menu->Append(wxID_PRINT);
249 menu->Append(wxID_PRINT_SETUP, "Print &Setup...");
250 menu->Append(wxID_PREVIEW);
251 }
252 }
253
254 wxMenu *MyApp::CreateDrawingEditMenu()
255 {
256 wxMenu * const menu = new wxMenu;
257 menu->Append(wxID_UNDO);
258 menu->Append(wxID_REDO);
259 menu->AppendSeparator();
260 menu->Append(wxID_CUT, "&Cut last segment");
261
262 return menu;
263 }
264
265 void MyApp::CreateMenuBarForFrame(wxFrame *frame, wxMenu *file, wxMenu *edit)
266 {
267 wxMenuBar *menubar = new wxMenuBar;
268
269 menubar->Append(file, wxGetStockLabel(wxID_FILE));
270
271 if ( edit )
272 menubar->Append(edit, wxGetStockLabel(wxID_EDIT));
273
274 wxMenu *help= new wxMenu;
275 help->Append(wxID_ABOUT);
276 menubar->Append(help, wxGetStockLabel(wxID_HELP));
277
278 frame->SetMenuBar(menubar);
279 }
280
281 wxFrame *MyApp::CreateChildFrame(wxDocument *doc, wxView *view, bool isCanvas)
282 {
283 // create a child frame of appropriate class for the current mode
284 wxFrame *subframe;
285 #if wxUSE_MDI_ARCHITECTURE
286 if ( GetMode() == Mode_MDI )
287 {
288 subframe = new wxDocMDIChildFrame
289 (
290 doc,
291 view,
292 wxStaticCast(GetTopWindow(), wxDocMDIParentFrame),
293 wxID_ANY,
294 "Child Frame",
295 wxDefaultPosition,
296 wxSize(300, 300)
297 );
298 }
299 else
300 #endif // wxUSE_MDI_ARCHITECTURE
301 {
302 subframe = new wxDocChildFrame
303 (
304 doc,
305 view,
306 wxStaticCast(GetTopWindow(), wxDocParentFrame),
307 wxID_ANY,
308 "Child Frame",
309 wxDefaultPosition,
310 wxSize(300, 300)
311 );
312
313 subframe->Centre(wxBOTH);
314 }
315
316 wxMenu *menuFile = new wxMenu;
317
318 menuFile->Append(wxID_NEW);
319 menuFile->Append(wxID_OPEN);
320 AppendDocumentFileCommands(menuFile, isCanvas);
321 menuFile->AppendSeparator();
322 menuFile->Append(wxID_EXIT);
323
324 wxMenu *menuEdit;
325 if ( isCanvas )
326 {
327 menuEdit = CreateDrawingEditMenu();
328
329 doc->GetCommandProcessor()->SetEditMenu(menuEdit);
330 doc->GetCommandProcessor()->Initialize();
331 }
332 else // text frame
333 {
334 menuEdit = new wxMenu;
335 menuEdit->Append(wxID_COPY);
336 menuEdit->Append(wxID_PASTE);
337 menuEdit->Append(wxID_SELECTALL);
338 }
339
340 CreateMenuBarForFrame(subframe, menuFile, menuEdit);
341
342 subframe->SetIcon(isCanvas ? wxICON(chrt) : wxICON(notepad));
343
344 return subframe;
345 }
346
347 void MyApp::OnAbout(wxCommandEvent& WXUNUSED(event))
348 {
349 wxString modeName;
350 switch ( m_mode )
351 {
352 #if wxUSE_MDI_ARCHITECTURE
353 case Mode_MDI:
354 modeName = "MDI";
355 break;
356 #endif // wxUSE_MDI_ARCHITECTURE
357
358 case Mode_SDI:
359 modeName = "SDI";
360 break;
361
362 case Mode_Single:
363 modeName = "single document";
364 break;
365
366 default:
367 wxFAIL_MSG( "unknown mode ");
368 }
369
370 wxLogMessage
371 (
372 "This is the wxWidgets Document/View Sample\n"
373 "running in %s mode.\n"
374 "\n"
375 "Authors: Julian Smart, Vadim Zeitlin\n"
376 "\n"
377 "Usage: docview [--{mdi,sdi,single}]",
378 modeName
379 );
380 }
381