1 /*
2 * Copyright 2005-2007 Gerald Schmidt.
3 *
4 * This file is part of Xml Copy Editor.
5 *
6 * Xml Copy Editor is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * Xml Copy Editor is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Xml Copy Editor; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <iostream>
22 #include <fstream>
23 #include <string>
24 #include <wx/aboutdlg.h>
25 #include "xmlcopyeditor.h"
26 #include "xmlcopyeditorcopy.h"
27 #include "readfile.h"
28 #include "xmldoc.h"
29 #include "xmlctrl.h"
30 #include "wraplibxml.h"
31 #include "xmlschemalocator.h"
32 #include "xsllocator.h"
33 #include "xmlutf8reader.h"
34 #include "xmlpromptgenerator.h"
35 #include "xmlencodingspy.h"
36 #include "styledialog.h"
37 #include "mypropertysheet.h"
38 #include "wraptempfilename.h"
39 #include "globalreplacedialog.h"
40 #include "replace.h"
41 #include "associatedialog.h"
42 #include "xmlassociatexsd.h"
43 #include "xmlassociatexsl.h"
44 #include "xmlassociatedtd.h"
45 #include "wrapdaisy.h"
46 #include "aboutdialog.h"
47 #include "pathresolver.h"
48 #include "locationpanel.h"
49 #include "insertpanel.h"
50 #include "xmlwordcount.h"
51 #include "mynotebook.h"
52 #include "commandpanel.h"
53 #include "binaryfile.h"
54 #include "exportdialog.h"
55 #include <wx/aui/auibook.h>
56 #include <wx/richtext/richtextsymboldlg.h>
57 #include <wx/textctrl.h>
58 #include <wx/artprov.h>
59 #include <wx/stockitem.h>
60 #include <iconv.h>
61 #include <wx/stdpaths.h>
62 #include <wx/tokenzr.h>
63 #include <wx/dir.h>
64 #include "xmlschemagenerator.h"
65 #include "threadreaper.h"
66 #include <wx/wupdlock.h>
67 #include "dtd2schema.h"
68 #include "myipc.h"
69 #include <wx/debug.h>
70
71 #ifdef NEWFINDREPLACE
72 #include "findreplacepanel.h"
73 #endif
74
75 #include "wrapxerces.h"
76 #ifndef __WXMSW__
77 #include "xpm/appicon.xpm"
78 #endif
79
80 typedef size_t universal_iconv (iconv_t cd,
81 char* * inbuf, size_t * inbytesleft,
82 char* * outbuf, size_t * outbytesleft);
83 /* On other platform, it could be:
84 size_t iconv (iconv_t cd,
85 const char* * inbuf, size_t * inbytesleft,
86 char* * outbuf, size_t * outbytesleft);
87 and a char ** can't be assigned to const char **
88 http://c-faq.com/ansi/constmismatch.html
89 Let's deal with this mess.
90 */
91
BEGIN_EVENT_TABLE(MyFrame,wxFrame)92 BEGIN_EVENT_TABLE ( MyFrame, wxFrame )
93 EVT_ACTIVATE_APP ( MyFrame::OnActivateApp )
94 EVT_CLOSE ( MyFrame::OnFrameClose )
95 EVT_KEY_DOWN ( MyFrame::OnKeyPressed )
96 EVT_MENU ( wxID_ABOUT, MyFrame::OnAbout )
97 EVT_MENU ( wxID_CLOSE, MyFrame::OnClose )
98 EVT_MENU ( wxID_CLOSE_ALL, MyFrame::OnCloseAll )
99 EVT_MENU ( wxID_CUT, MyFrame::OnCut )
100 EVT_MENU ( wxID_COPY, MyFrame::OnCopy )
101 EVT_MENU ( wxID_HELP, MyFrame::OnHelp )
102 EVT_MENU ( wxID_PASTE, MyFrame::OnPaste )
103 EVT_MENU ( ID_PASTE_NEW_DOCUMENT, MyFrame::OnPasteNewDocument )
104 EVT_MENU ( wxID_EXIT, MyFrame::OnQuit )
105 EVT_MENU ( wxID_NEW, MyFrame::OnNew )
106 EVT_MENU ( wxID_OPEN, MyFrame::OnOpen )
107 EVT_MENU ( wxID_SAVE, MyFrame::OnSave )
108 EVT_MENU ( wxID_SAVEAS, MyFrame::OnSaveAs )
109 EVT_MENU ( ID_RELOAD, MyFrame::OnReload )
110 EVT_MENU ( wxID_UNDO, MyFrame::OnUndo )
111 EVT_MENU ( wxID_REDO, MyFrame::OnRedo )
112 EVT_MENU ( wxID_REVERT, MyFrame::OnRevert )
113 EVT_MENU ( ID_INSERT_CHILD, MyFrame::OnInsertChild )
114 EVT_MENU ( ID_INSERT_SIBLING, MyFrame::OnInsertSibling )
115 EVT_MENU ( ID_INSERT_ENTITY, MyFrame::OnInsertEntity )
116 EVT_MENU ( ID_INSERT_TWIN, MyFrame::OnInsertTwin )
117 EVT_MENU ( ID_INSERT_SYMBOL, MyFrame::OnInsertSymbol )
118 EVT_MENU ( ID_TOGGLE_FOLD, MyFrame::OnToggleFold )
119 EVT_MENU ( ID_FOLD_ALL, MyFrame::OnFoldAll )
120 EVT_MENU ( ID_UNFOLD_ALL, MyFrame::OnUnfoldAll )
121 EVT_MENU ( ID_OPEN_LARGE_FILE, MyFrame::OnOpen )
122 EVT_MENU ( ID_PRINT_PREVIEW, MyFrame::OnPrintPreview )
123 EVT_MENU ( ID_PRINT_SETUP, MyFrame::OnPrintSetup )
124 EVT_MENU ( ID_PRINT, MyFrame::OnPrint )
125 EVT_MENU ( ID_WORD_COUNT, MyFrame::OnWordCount )
126 EVT_MENU ( ID_IMPORT_MSWORD, MyFrame::OnImportMSWord )
127 EVT_MENU ( ID_EXPORT_MSWORD, MyFrame::OnExportMSWord )
128 EVT_MENU ( ID_EXPORT, MyFrame::OnExport )
129 EVT_MENU ( ID_CLOSE_MESSAGE_PANE, MyFrame::OnCloseMessagePane )
130 EVT_MENU ( ID_CLOSE_FIND_REPLACE_PANE, MyFrame::OnCloseFindReplacePane )
131 EVT_MENU ( ID_CLOSE_COMMAND_PANE, MyFrame::OnCloseCommandPane )
132 EVT_MENU ( ID_COMMAND, MyFrame::OnCommand )
133 EVT_MENU ( ID_FIND, MyFrame::OnFind )
134 EVT_MENU ( ID_FIND_AGAIN, MyFrame::OnFindAgain )
135 EVT_MENU ( ID_GOTO, MyFrame::OnGoto )
136 EVT_MENU ( ID_TOGGLE_COMMENT, MyFrame::OnToggleComment )
137 EVT_MENU ( ID_FEEDBACK, MyFrame::OnFeedback )
138 EVT_MENU ( ID_PREVIOUS_DOCUMENT, MyFrame::OnPreviousDocument )
139 EVT_MENU ( ID_NEXT_DOCUMENT, MyFrame::OnNextDocument )
140 EVT_MENU ( ID_BROWSER, MyFrame::OnBrowser )
141 EVT_MENU ( ID_REPLACE, MyFrame::OnFindReplace )
142 EVT_MENU ( ID_GLOBAL_REPLACE, MyFrame::OnGlobalReplace )
143 EVT_MENU ( ID_CHECK_WELLFORMED, MyFrame::OnCheckWellformedness )
144 EVT_MENU ( ID_VALIDATE_RELAX_NG, MyFrame::OnValidateRelaxNG )
145 EVT_MENU ( ID_VALIDATE_W3C_SCHEMA, MyFrame::OnValidateSchema )
146 EVT_MENU ( ID_CREATE_SCHEMA, MyFrame::OnCreateSchema )
147 EVT_MENU ( ID_DTD_TO_SCHEMA, MyFrame::OnDtd2Schema )
148 EVT_MENU ( ID_XPATH, MyFrame::OnXPath )
149 EVT_MENU_RANGE ( ID_XSLT, ID_XSLT_WORDML_DOCBOOK, MyFrame::OnXslt )
150 EVT_MENU ( ID_PRETTYPRINT, MyFrame::OnPrettyPrint )
151 EVT_MENU ( ID_ENCODING, MyFrame::OnEncoding )
152 EVT_MENU ( ID_STYLE, MyFrame::OnSpelling )
153 EVT_MENU ( ID_SPELL, MyFrame::OnSpelling )
154 EVT_MENU ( ID_FONT_SMALLER, MyFrame::OnFontSmaller )
155 EVT_MENU ( ID_FONT_NORMAL, MyFrame::OnFontMedium )
156 EVT_MENU ( ID_FONT_LARGER, MyFrame::OnFontLarger )
157 EVT_MENU ( ID_OPTIONS, MyFrame::OnOptions )
158 EVT_MENU ( ID_HOME, MyFrame::OnHome )
159 EVT_MENU ( ID_DOWNLOAD_SOURCE, MyFrame::OnDownloadSource )
160 EVT_MENU ( ID_TOOLBAR_VISIBLE, MyFrame::OnToolbarVisible )
161 EVT_MENU ( ID_LOCATION_PANE_VISIBLE, MyFrame::OnLocationPaneVisible )
162 EVT_MENU ( ID_PROTECT_TAGS, MyFrame::OnProtectTags )
163 EVT_MENU ( ID_WRAP_WORDS, MyFrame::OnWrapWords )
164 EVT_MENU ( ID_COPY_XPATH, MyFrame::OnCopyXPath )
165 EVT_MENU_RANGE ( ID_SHOW_TAGS, ID_HIDE_TAGS, MyFrame::OnVisibilityState )
166 EVT_MENU_RANGE ( ID_ASSOCIATE_DTD_PUBLIC, ID_ASSOCIATE_XSL, MyFrame::OnAssociate )
167 EVT_MENU_RANGE ( wxID_FILE1, wxID_FILE9, MyFrame::OnHistoryFile )
168 EVT_MENU_RANGE (
169 ID_VALIDATE_PRESET1, ID_VALIDATE_PRESET9, MyFrame::OnValidatePreset )
170 EVT_MENU_RANGE (
171 ID_COLOR_SCHEME_DEFAULT,
172 ID_COLOR_SCHEME_NONE,
173 MyFrame::OnColorScheme )
174
175 EVT_MENU_RANGE (
176 ID_SPLIT_TAB_TOP,
177 ID_SPLIT_TAB_LEFT,
178 MyFrame::OnSplitTab )
179
180 EVT_UPDATE_UI_RANGE ( ID_REPLACE, ID_GLOBAL_REPLACE, MyFrame::OnUpdateReplaceRange )
181 EVT_FIND ( wxID_ANY, MyFrame::OnDialogFind )
182 EVT_FIND_NEXT ( wxID_ANY, MyFrame::OnDialogFind )
183 EVT_FIND_REPLACE ( wxID_ANY, MyFrame::OnDialogReplace )
184 EVT_FIND_REPLACE_ALL ( wxID_ANY, MyFrame::OnDialogReplaceAll )
185 EVT_ICONIZE ( MyFrame::OnIconize )
186 EVT_UPDATE_UI ( ID_LOCATION_PANE_VISIBLE, MyFrame::OnUpdateLocationPaneVisible )
187 EVT_UPDATE_UI ( wxID_CLOSE, MyFrame::OnUpdateDocRange )
188 EVT_UPDATE_UI ( wxID_SAVEAS, MyFrame::OnUpdateDocRange )
189 EVT_UPDATE_UI ( wxID_CLOSE_ALL, MyFrame::OnUpdateCloseAll )
190 EVT_UPDATE_UI_RANGE ( ID_SPLIT_TAB_TOP, ID_SPLIT_TAB_LEFT, MyFrame::OnUpdateCloseAll )
191 EVT_UPDATE_UI ( wxID_REVERT, MyFrame::OnUpdateUndo )
192 EVT_UPDATE_UI ( wxID_SAVE, MyFrame::OnUpdateDocRange ) // always allow save if doc present
193 EVT_UPDATE_UI ( wxID_UNDO, MyFrame::OnUpdateUndo )
194 EVT_UPDATE_UI ( wxID_REDO, MyFrame::OnUpdateRedo )
195 EVT_UPDATE_UI ( wxID_PASTE, MyFrame::OnUpdatePaste )
196 EVT_UPDATE_UI ( wxID_CUT, MyFrame::OnUpdateCutCopy )
197 EVT_UPDATE_UI ( wxID_COPY, MyFrame::OnUpdateCutCopy )
198 EVT_UPDATE_UI ( ID_FIND_AGAIN, MyFrame::OnUpdateFindAgain )
199 EVT_UPDATE_UI ( ID_TOGGLE_COMMENT, MyFrame::OnUpdateToggleComment )
200 EVT_UPDATE_UI_RANGE ( ID_FIND, ID_EXPORT_MSWORD, MyFrame::OnUpdateDocRange )
201 EVT_UPDATE_UI ( ID_PREVIOUS_DOCUMENT, MyFrame::OnUpdatePreviousDocument )
202 EVT_UPDATE_UI ( ID_NEXT_DOCUMENT, MyFrame::OnUpdateNextDocument )
203 EVT_UPDATE_UI ( ID_CLOSE_MESSAGE_PANE, MyFrame::OnUpdateCloseMessagePane )
204 EVT_UPDATE_UI ( ID_CLOSE_FIND_REPLACE_PANE, MyFrame::OnUpdateCloseFindReplacePane )
205 EVT_UPDATE_UI ( ID_CLOSE_COMMAND_PANE, MyFrame::OnUpdateCloseCommandPane )
206 EVT_UPDATE_UI ( ID_RELOAD, MyFrame::OnUpdateReload )
207 EVT_UPDATE_UI ( ID_COPY_XPATH, MyFrame::OnUpdateCopyXPath )
208 EVT_IDLE ( MyFrame::OnIdle )
209 EVT_AUINOTEBOOK_PAGE_CLOSE ( wxID_ANY, MyFrame::OnPageClosing )
210 #ifdef __WXMSW__
211 EVT_DROP_FILES ( MyFrame::OnDropFiles )
212 #endif
213 EVT_NOTIFY ( myEVT_NOTIFY_PROMPT_GENERATED, wxID_ANY, MyFrame::OnPromptGenerated )
214 END_EVENT_TABLE()
215
216 IMPLEMENT_APP ( MyApp)
217
218 MyApp::MyApp()
219 : checker ( NULL )
220 , server ( NULL )
221 , singleInstanceCheck ( false )
222 , lang ( 0 )
223 #if defined(__WXMSW__) && !wxCHECK_VERSION(2,9,0)
224 , config ( new wxFileConfig ( _T ( ".xmlcopyeditor" ) ) )//( _T ( "SourceForge Project\\XML Copy Editor" ) ) )
225 #else
226 , config ( new wxFileConfig ( _T ( "xmlcopyeditor" ) ) )
227 #endif
228 {
229 #if wxCHECK_VERSION(2,9,0) && !defined ( __WXDEBUG__ )
230 wxDisableAsserts();
231 #endif
232
233 #if defined ( __WXGTK__ ) && !defined ( __WXDEBUG__ )
234 int fdnull = open ( "/dev/null", O_WRONLY, 0 );
235 dup2 ( fdnull, STDERR_FILENO );
236 #endif
237 }
238
~MyApp()239 MyApp::~MyApp()
240 {
241 delete checker;
242 delete server;
243 }
244
OnInit()245 bool MyApp::OnInit()
246 {
247 #ifdef __WXDEBUG__
248 wxLog::SetActiveTarget ( new wxLogStderr() );
249 wxLog::SetLogLevel ( wxLOG_Max );
250 #endif
251
252 int systemLocale = myLocale.GetSystemLanguage();
253 switch ( systemLocale )
254 {
255 case wxLANGUAGE_GERMAN:
256 case wxLANGUAGE_GERMAN_AUSTRIAN:
257 case wxLANGUAGE_GERMAN_BELGIUM:
258 case wxLANGUAGE_GERMAN_LIECHTENSTEIN:
259 case wxLANGUAGE_GERMAN_LUXEMBOURG:
260 case wxLANGUAGE_GERMAN_SWISS:
261 systemLocale = wxLANGUAGE_GERMAN;
262 break;
263 case wxLANGUAGE_CHINESE_SIMPLIFIED:
264 systemLocale = wxLANGUAGE_CHINESE_SIMPLIFIED;
265 break;
266 case wxLANGUAGE_CHINESE_TRADITIONAL:
267 systemLocale = wxLANGUAGE_CHINESE_TRADITIONAL;
268 break;
269 case wxLANGUAGE_CATALAN:
270 systemLocale = wxLANGUAGE_CATALAN;
271 break;
272 case wxLANGUAGE_SPANISH:
273 case wxLANGUAGE_SPANISH_ARGENTINA:
274 case wxLANGUAGE_SPANISH_BOLIVIA:
275 case wxLANGUAGE_SPANISH_CHILE:
276 case wxLANGUAGE_SPANISH_COLOMBIA:
277 case wxLANGUAGE_SPANISH_COSTA_RICA:
278 case wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
279 case wxLANGUAGE_SPANISH_ECUADOR:
280 case wxLANGUAGE_SPANISH_EL_SALVADOR:
281 case wxLANGUAGE_SPANISH_GUATEMALA:
282 case wxLANGUAGE_SPANISH_HONDURAS:
283 case wxLANGUAGE_SPANISH_MEXICAN:
284 case wxLANGUAGE_SPANISH_MODERN:
285 case wxLANGUAGE_SPANISH_NICARAGUA:
286 case wxLANGUAGE_SPANISH_PANAMA:
287 case wxLANGUAGE_SPANISH_PARAGUAY:
288 case wxLANGUAGE_SPANISH_PERU:
289 case wxLANGUAGE_SPANISH_PUERTO_RICO:
290 case wxLANGUAGE_SPANISH_URUGUAY:
291 case wxLANGUAGE_SPANISH_US:
292 case wxLANGUAGE_SPANISH_VENEZUELA:
293 systemLocale = wxLANGUAGE_SPANISH;
294 break;
295 case wxLANGUAGE_SLOVAK:
296 systemLocale = wxLANGUAGE_SLOVAK;
297 break;
298 case wxLANGUAGE_SWEDISH:
299 systemLocale = wxLANGUAGE_SWEDISH;
300 break;
301 case wxLANGUAGE_FRENCH:
302 systemLocale = wxLANGUAGE_FRENCH;
303 break;
304 case wxLANGUAGE_UKRAINIAN:
305 systemLocale = wxLANGUAGE_UKRAINIAN;
306 break;
307 case wxLANGUAGE_ITALIAN:
308 systemLocale = wxLANGUAGE_ITALIAN;
309 break;
310 case wxLANGUAGE_RUSSIAN:
311 systemLocale = wxLANGUAGE_RUSSIAN;
312 break;
313 case wxLANGUAGE_DUTCH:
314 systemLocale = wxLANGUAGE_DUTCH;
315 break;
316 default:
317 systemLocale = wxLANGUAGE_DEFAULT;
318 break;
319 }
320
321 wxString dataDir = wxStandardPaths::Get().GetDataDir();
322 #ifdef __WXMSW__
323 singleInstanceCheck = true;
324 #else
325 singleInstanceCheck = false;
326 #endif
327 if ( config.get() )
328 {
329 singleInstanceCheck = config->Read ( _T ( "singleInstanceCheck" ),
330 singleInstanceCheck );
331 lang = config->Read ( _T ( "lang" ), systemLocale );
332 dataDir = config->Read ( _T ( "applicationDir" ), dataDir );
333 }
334 else
335 {
336 lang = systemLocale;
337 }
338
339 if ( singleInstanceCheck )
340 {
341 wxString name;
342 name.Printf ( _T ( "xmlcopyeditor-%s" ), wxGetUserId().c_str() );
343 checker = new wxSingleInstanceChecker ( name );
344 if ( checker->IsAnotherRunning() )
345 {
346 MyClient client;
347 if ( client.talkToServer ( argc, argv ) )
348 return false;
349 }
350 }
351
352 server = new MyServer;
353 server->Create ( IPC_SERVICE );
354
355 myLocale.Init ( lang, wxLOCALE_LOAD_DEFAULT );
356
357 wxArrayString prefixes;
358 #ifdef __WXGTK__
359 prefixes.Add ( _T ( "/usr/share/locale" ) );
360 prefixes.Add ( _T ( "/usr/share/locale-langpack" ) );
361 prefixes.Add ( _T ( "/usr/local/share/locale" ) );
362 #endif
363 wxString poDir = dataDir + wxFileName::GetPathSeparator() + _T ( "po" )
364 + wxFileName::GetPathSeparator();
365 prefixes.Add ( poDir );
366 for ( size_t i = 0; i < prefixes.Count(); )
367 {
368 if ( wxDirExists ( prefixes[i] ) )
369 wxLocale::AddCatalogLookupPathPrefix ( prefixes[i++] );
370 else
371 prefixes.RemoveAt ( i );
372 }
373
374 wxString catalog = _T ( "xmlcopyeditor" );
375 getAvailableTranslations ( &prefixes, &catalog );
376
377 if ( !myLocale.AddCatalog ( catalog ) )
378 {}
379
380 #ifndef __WXMSW__
381 {
382 wxLogNull noLog;
383 myLocale.AddCatalog ( _T ( "coreutils" ) );
384 }
385 #endif
386
387 MyFrame *frame;
388 try
389 {
390 wxImage::AddHandler ( new wxPNGHandler );
391 wxSystemOptions::SetOption ( _T ( "msw.remap" ), 0 );
392
393 frame = new MyFrame (
394 _ ( "XML Copy Editor" ),
395 config.get(),
396 myLocale,
397 singleInstanceCheck,
398 lang );
399 frame->Show ( true );
400
401 bool rememberOpenTabs = config->Read ( _T ( "rememberOpenTabs" ), true );
402 if ( rememberOpenTabs )
403 frame->openRememberedTabs();
404 else if ( !frame->getHandleCommandLineFlag() )
405 frame->newDocument ( wxEmptyString );
406
407 if ( frame->getHandleCommandLineFlag() )
408 frame->handleCommandLine();
409 }
410 catch ( const XMLException &e )
411 {
412 wxString error;
413 error << _ ( "Failed to initialize Xerces-C:\n" )
414 << WrapXerces::toString ( e.getMessage() );
415 wxMessageBox ( error, _ ( "Error" ), wxOK | wxICON_ERROR );
416 return false;
417 }
418 catch ( exception &e )
419 {
420 const char *what;
421 what = e.what();
422 wxString wideWhat, errorString;
423 wideWhat = wxString ( what, wxConvLocal, strlen ( what ) );
424
425 if ( wideWhat.empty() )
426 wideWhat = _ ( "(unknown error)" );
427
428 errorString = _ ( "XML Copy Editor has encountered the following error and needs to close: " );
429 errorString += wideWhat;
430 errorString += _T ( "." );
431 #ifdef __WXMSW__
432 ::MessageBox (
433 NULL,
434 errorString,
435 _ ( "Error" ),
436 MB_ICONERROR | MB_TASKMODAL );
437 #else
438 wxMessageBox ( errorString, _ ( "Error" ), wxICON_ERROR );
439 #endif
440 exit ( EXIT_FAILURE );
441 }
442 catch ( ... )
443 {
444 exit ( EXIT_FAILURE );
445 }
446 return true;
447 }
448
OnUnhandledException()449 void MyApp::OnUnhandledException()
450 {
451 #ifdef __WXMSW__
452 ::MessageBox (
453 NULL,
454 _ ( "XML Copy Editor has encountered an error and needs to close." ),
455 _ ( "Error" ),
456 MB_ICONERROR | MB_TASKMODAL );
457 #else
458 wxMessageBox (
459 _ ( "XML Copy Editor has encountered an error and needs to close." ),
460 _ ( "Error" ),
461 wxICON_ERROR );
462 #endif
463 exit ( EXIT_FAILURE );
464 }
465
OnExceptionInMainLoop()466 bool MyApp::OnExceptionInMainLoop()
467 {
468 try
469 {
470 throw;
471 }
472 #ifdef __WXMSW__
473 catch ( bad_alloc& )
474 {
475 ::MessageBox (
476 NULL,
477 _ ( "The operating system has turned down a request for additional memory" ),
478 _ ( "Out of memory" ),
479 MB_ICONERROR );
480 return true;
481 }
482 #endif
483 catch ( exception &e )
484 {
485 const char *what;
486 what = e.what();
487 wxString wideWhat, errorString;
488 wideWhat = wxString ( what, wxConvLocal, strlen ( what ) );
489
490 if ( wideWhat.empty() )
491 _ ( "(unknown error)" );
492
493 errorString = _ ( "The following error has occurred: " );
494 errorString += wideWhat;
495 errorString += _ ( ".\n\nSelect \"Abort\" to exit, \"Retry\" to close this window and \"Ignore\" to continue." );
496 #ifdef __WXMSW__
497 int ret = ::MessageBox (
498 NULL,
499 errorString,
500 _ ( "Error" ),
501 MB_ABORTRETRYIGNORE |
502 MB_ICONERROR |
503 MB_TASKMODAL );
504 switch ( ret )
505 {
506 case IDABORT:
507 exit ( EXIT_FAILURE );
508 break;
509 case IDRETRY:
510 return false;
511 case IDIGNORE:
512 return true;
513 default:
514 throw;
515 }
516 #else
517 // wxGTK does not reach this point; see HandleEvent below
518 wxMessageBox (
519 errorString,
520 _ ( "Error" ),
521 wxICON_ERROR );
522 return false;
523 #endif
524 }
525 catch ( ... )
526 {
527 wxString otherError ( _ ( "XML Copy Editor has encountered an error and needs to close." ) );
528 #ifdef __WXMSW__
529 ::MessageBox (
530 NULL,
531 otherError,
532 _ ( "Error" ),
533 MB_ICONERROR );
534 return false;
535 #else
536 wxMessageBox (
537 otherError,
538 _ ( "Error" ),
539 wxICON_ERROR );
540 return false;
541 #endif
542 }
543 return false;
544 }
545
546 #ifndef __WXMSW__
HandleEvent(wxEvtHandler * handler,wxEventFunction func,wxEvent & event) const547 void MyApp::HandleEvent ( wxEvtHandler *handler, wxEventFunction func, wxEvent& event ) const
548 {
549 try
550 {
551 wxApp::HandleEvent ( handler, func, event );
552 }
553 catch ( std::bad_alloc& )
554 {
555 wxMessageBox (
556 _ ( "The operating system has turned down a request for additional memory" ),
557 _ ( "Out of memory" ),
558 wxICON_ERROR );
559 return;
560 }
561 catch ( std::exception& e )
562 {
563 std::string s ( e.what() );
564 wxString ws = wxString ( s.c_str(), wxConvUTF8, s.size() );
565 wxMessageBox (
566 ws,
567 _ ( "Error" ),
568 wxICON_ERROR );
569 return;
570 }
571 catch ( ... )
572 {
573 throw;
574 }
575 }
576 #endif
577
getAvailableTranslations(const wxArrayString * catalogLookupPathPrefixes,const wxString * catalog)578 const std::set<const wxLanguageInfo *> &MyApp::getAvailableTranslations (
579 const wxArrayString *catalogLookupPathPrefixes /*= NULL*/,
580 const wxString *catalog /*= NULL*/ )
581 {
582 static class Translations // Most of the code was copied from wxTranslations
583 {
584 public:
585 Translations ( const wxArrayString *catalogLookupPathPrefixes,
586 const wxString *catalog )
587 {
588 if ( catalogLookupPathPrefixes == NULL )
589 throw std::invalid_argument ( "catalogLookupPathPrefixes" );
590 if ( catalog == NULL )
591 throw std::invalid_argument ( "catelog" );
592
593 const wxLanguageInfo *info;
594 #if wxCHECK_VERSION(2,9,0)
595 wxTranslations *t = wxTranslations::Get();
596 if ( t != NULL )
597 {
598 wxArrayString all = t->GetAvailableTranslations ( *catalog );
599 wxArrayString::const_iterator trans = all.begin();
600 for ( ; trans != all.end(); trans++ )
601 {
602 info = wxLocale::FindLanguageInfo ( *trans );
603 if ( info != NULL )
604 translations.insert ( info );
605 }
606 }
607 #else
608 wxArrayString::const_iterator i = catalogLookupPathPrefixes->begin();
609 for ( i = catalogLookupPathPrefixes->begin();
610 i != catalogLookupPathPrefixes->end(); ++i )
611 {
612 if ( i->empty() )
613 continue;
614
615 wxDir dir;
616 if ( !dir.Open(*i) )
617 continue;
618
619 wxString lang;
620 for ( bool ok = dir.GetFirst ( &lang, wxEmptyString, wxDIR_DIRS ); ok;
621 ok = dir.GetNext (&lang) ) {
622 const wxString langdir = *i + wxFILE_SEP_PATH + lang;
623 if ( HasMsgCatalogInDir ( langdir, *catalog ) ) {
624 #ifdef __WXOSX__
625 wxString rest;
626 if ( lang.EndsWith(".lproj", &rest) )
627 lang = rest;
628 #endif // __WXOSX__
629 info = wxLocale::FindLanguageInfo ( lang );
630 if ( info != NULL )
631 translations.insert ( info );
632 }
633 }
634 }
635 #endif
636 }
637 bool HasMsgCatalogInDir ( const wxString &dir, const wxString &catelog )
638 {
639 return wxFileName ( dir, catelog, _T ( "mo" ) ).FileExists()
640 || wxFileName ( dir + wxFILE_SEP_PATH + _T ( "LC_MESSAGES" ), catelog, _T ( "mo" ) ).FileExists();
641 }
642 const std::set<const wxLanguageInfo *> &operator()() { return translations; }
643 protected:
644 std::set<const wxLanguageInfo *> translations;
645 } translations ( catalogLookupPathPrefixes, catalog );
646
647 return translations();
648 }
649
MyFrame(const wxString & title,wxFileConfig * configParameter,wxLocale & locale,bool singleInstanceCheckParameter,int langParameter)650 MyFrame::MyFrame (
651 const wxString& title,
652 wxFileConfig *configParameter,
653 wxLocale& locale,
654 bool singleInstanceCheckParameter,
655 int langParameter ) :
656 wxFrame ( NULL, wxID_ANY, title ),
657 config ( configParameter ),
658 myLocale ( locale ),
659 singleInstanceCheck ( singleInstanceCheckParameter ),
660 lang ( langParameter ),
661 htmlPrinting ( new wxHtmlEasyPrinting (
662 wxEmptyString,
663 this ) ),
664 findDialog ( 0 ),
665 helpController ( new wxHtmlHelpController (
666 #ifdef __WXOSX__
667 wxHF_CONTENTS | wxHF_INDEX | wxHF_SEARCH | wxHF_BOOKMARKS | wxHF_PRINT
668 #endif
669 ) ),
670 menuBar ( 0 ),
671 toolBar ( 0 ),
672 xmlMenu ( 0 ),
673 mainBook ( 0 ),
674 restoreFocusToNotebook ( false )
675 {
676 manager.SetManagedWindow ( this );
677
678 lastPos = 0;
679 htmlReport = NULL;
680 lastDoc = NULL;
681
682 wxString defaultFont = wxSystemSettings::GetFont ( wxSYS_ANSI_VAR_FONT ).GetFaceName();
683
684 bool findMatchCase;
685
686 // fetch configuration
687 if ( config ) // config found
688 {
689 history.Load ( *config );
690 properties.insertCloseTag =
691 config->Read ( _T ( "insertCloseTag" ), true );
692 properties.completion =
693 config->Read ( _T ( "completion" ), true );
694 properties.number =
695 config->Read ( _T ( "number" ), true );
696 properties.fold =
697 config->Read ( _T ( "fold" ), true );
698 properties.foldCompact =
699 config->Read ( _T ( "foldCompact" ), true );
700 properties.currentLine =
701 config->Read ( _T ( "currentLine" ), true );
702 properties.highlightSyntax =
703 config->Read ( _T ( "highlightSyntax" ), true );
704 properties.whitespaceVisible =
705 config->Read ( _T ( "whitespaceVisible" ), true );
706 properties.indentLines =
707 config->Read ( _T ( "indentLines" ), true );
708 properties.toggleLineBackground =
709 config->Read ( _T ( "toggleLineBackground" ), true );
710 properties.protectHiddenElements =
711 config->Read ( _T ( "protectHiddenElements" ), true );
712 properties.deleteWholeTag =
713 config->Read ( _T ( "deleteWholeTag" ), true );
714 properties.validateAsYouType =
715 config->Read ( _T ( "validateAsYouType" ), true );
716 properties.font =
717 config->Read ( _T ( "font" ), defaultFont );
718 findRegex =
719 config->Read ( _T ( "findRegex" ), true );
720 xpathExpression =
721 config->Read ( _T ( "xpathExpression" ), wxEmptyString );
722 lastXslStylesheet =
723 config->Read ( _T ( "lastXslStylesheet" ), wxEmptyString );
724 lastRelaxNGSchema =
725 config->Read ( _T ( "lastRelaxNGSchema" ), wxEmptyString );
726
727 exportQuiet =
728 config->Read ( _T ( "exportQuiet" ), (long)true );
729 exportMp3Album =
730 config->Read ( _T ( "exportMp3Album" ), (long)true );
731 exportSuppressOptional =
732 config->Read ( _T ( "exportSuppressOptional" ), (long)true );
733 exportHtml =
734 config->Read ( _T ( "exportHtml" ), (long)true );
735 exportEpub =
736 config->Read ( _T ( "exportEpub" ), (long)true );
737 exportRtf =
738 config->Read ( _T ( "exportRtf" ), (long)true );
739 exportDoc =
740 config->Read ( _T ( "exportDoc" ), (long)true );
741 exportFullDaisy =
742 config->Read ( _T ( "exportFullDaisy" ), (long)true );
743
744 applicationDir =
745 config->Read ( _T ( "applicationDir" ), wxStandardPaths::Get().GetDataDir() );
746
747 // if default value != true, type as long int
748 long valZoom, longFalse;
749 longFalse = false;
750 valZoom = 0;
751 frameWidth = frameHeight = framePosX = framePosY = 0;
752
753 properties.wrap =
754 config->Read ( _T ( "wrap" ), longFalse );
755
756 properties.zoom =
757 config->Read ( _T ( "zoom" ), valZoom );
758
759 properties.colorScheme = config->Read ( _T ( "colorScheme" ), COLOR_SCHEME_DEFAULT );
760
761 globalReplaceAllDocuments =
762 config->Read ( _T ( "globalReplaceAllDocuments" ), longFalse );
763 showFullPathOnFrame =
764 config->Read ( _T ( "showFullPathOnFrame" ), longFalse );
765 findMatchCase =
766 config->Read ( _T ( "findMatchCase" ), longFalse );
767
768 commandSync = config->Read ( _T ( "commandSync" ), longFalse );
769 commandOutput = config->Read ( _T ( "commandOutput" ), ID_COMMAND_OUTPUT_IGNORE );
770 commandString = config->Read ( _T ( "commandString" ), wxEmptyString );
771
772 exportStylesheet = config->Read ( _T ( "exportStylesheet" ), wxEmptyString );
773 exportFolder = config->Read ( _T ( "exportFolder" ), wxEmptyString );
774
775 ruleSetPreset =
776 config->Read ( _T ( "ruleSetPreset" ), _ ( "Default style" ) );
777 dictionaryPreset =
778 config->Read ( _T ( "dictionaryPreset" ), _ ( "en_US" ) );
779
780 filterPreset =
781 config->Read ( _T ( "filterPreset" ), _ ( "(No filter)" ) );
782 findData.SetFindString ( config->Read ( _T ( "findReplaceFind" ), _T ( "" ) ) );
783 findData.SetReplaceString ( config->Read ( _T ( "findReplaceReplace" ), _T ( "" ) ) );
784
785 toolbarVisible =
786 config->Read ( _T ( "toolbarVisible" ), true );
787 protectTags = config->Read ( _T ( "protectTags" ), longFalse );
788 visibilityState = config->Read ( _T ( "visibilityState" ), ID_SHOW_TAGS );
789
790 framePosX = config->Read ( _T ( "framePosX" ), framePosX );
791 framePosY = config->Read ( _T ( "framePosY" ), framePosY );
792 frameWidth = config->Read ( _T ( "frameWidth" ), frameWidth );
793 frameHeight = config->Read ( _T ( "frameHeight" ), frameHeight );
794 rememberOpenTabs = config->Read ( _T ( "rememberOpenTabs" ), true );
795 libxmlNetAccess = config->Read ( _T ( "libxmlNetAccess" ), longFalse );
796 openTabsOnClose = config->Read ( _T ( "openTabsOnClose" ), _T ( "" ) );
797 notebookStyle = config->Read ( _T ( "notebookStyle" ), ID_NOTEBOOK_STYLE_VC8_COLOR );
798 saveBom = config->Read ( _T ( "saveBom" ), true );
799 unlimitedUndo = config->Read ( _T ( "unlimitedUndo" ), true );
800 layout = config->Read ( _T ( "layout" ), wxEmptyString );
801 restoreLayout = config->Read ( _T ( "restoreLayout" ), true );
802 showLocationPane = config->Read ( _T ( "showLocationPane" ), true );
803 showInsertChildPane = config->Read ( _T ( "showInsertChildPane" ), true );
804 showInsertSiblingPane = config->Read ( _T ( "showInsertSiblingPane" ), true );
805 showInsertEntityPane = config->Read ( _T ( "showInsertEntityPane" ), true );
806 expandInternalEntities = config->Read ( _T ( "expandInternalEntities" ), true );
807
808 lastSymbol = config->Read( _T( "lastSymbol" ), _T ( "*" ) );
809
810 #if defined(XERCES_HAVE_SSE2_INTRINSIC) && defined(__WXDEBUG__)
811 xercescSSE2Warning = config->Read ( _T ( "xercescSSE2Warning" ), true );
812 #endif
813 }
814 else // config not found
815 {
816 properties.insertCloseTag =
817 properties.completion =
818 properties.currentLine =
819 properties.indentLines =
820 properties.protectHiddenElements =
821 properties.toggleLineBackground =
822 properties.deleteWholeTag =
823 properties.highlightSyntax = true;
824 properties.font = defaultFont;
825 properties.wrap = properties.whitespaceVisible = false;
826 properties.zoom = 0;
827 properties.colorScheme = COLOR_SCHEME_DEFAULT;
828 applicationDir = wxStandardPaths::Get().GetDataDir();
829 ruleSetPreset = _ ( "Default style" );
830 dictionaryPreset = _ ( "en_US" );
831 filterPreset = _ ( "No filter" );
832 xpathExpression = lastXslStylesheet = lastRelaxNGSchema = wxEmptyString;
833 findRegex = true;
834 findMatchCase = globalReplaceAllDocuments =
835 showFullPathOnFrame = false;
836 toolbarVisible = true;
837 protectTags = false;
838 visibilityState = SHOW_TAGS;
839 framePosX = framePosY = frameWidth = frameHeight = 0;
840 rememberOpenTabs = true;
841 libxmlNetAccess = false;
842 openTabsOnClose = wxEmptyString;
843 notebookStyle = ID_NOTEBOOK_STYLE_VC8_COLOR;
844 saveBom = unlimitedUndo = true;
845 layout = wxEmptyString;
846 restoreLayout = true;
847 showLocationPane = true;
848 showInsertChildPane = true;
849 showInsertSiblingPane = true;
850 showInsertEntityPane = true;
851 expandInternalEntities = true;
852 properties.validateAsYouType = true;
853
854 commandSync = false;
855 commandOutput = ID_COMMAND_OUTPUT_IGNORE;
856 commandString = wxEmptyString;
857
858 exportStylesheet = exportFolder = wxEmptyString;
859 exportQuiet = exportMp3Album = exportSuppressOptional = exportHtml =
860 exportEpub = exportRtf = exportDoc = exportFullDaisy = true;
861
862 lastSymbol = _T( "*" );
863
864 #if defined(XERCES_HAVE_SSE2_INTRINSIC) && defined(__WXDEBUG__)
865 xercescSSE2Warning = true;
866 #endif
867 }
868
869 largeFileProperties.completion = false;
870 largeFileProperties.fold = false;
871 largeFileProperties.foldCompact = false;
872 largeFileProperties.whitespaceVisible = false;
873 largeFileProperties.wrap = false;
874 largeFileProperties.indentLines = false;
875 largeFileProperties.protectHiddenElements = false;
876 largeFileProperties.toggleLineBackground = false;
877 largeFileProperties.insertCloseTag = false;
878 largeFileProperties.deleteWholeTag = false;
879 largeFileProperties.highlightSyntax = false;
880 largeFileProperties.validateAsYouType = false;
881 largeFileProperties.number = properties.number;
882 largeFileProperties.currentLine = properties.currentLine;
883 largeFileProperties.font = properties.font;
884 largeFileProperties.zoom = 0;
885 largeFileProperties.colorScheme = COLOR_SCHEME_NONE;
886
887 updatePaths();
888 loadBitmaps();
889
890 // Initialize libxml
891 WrapLibxml::Init ( catalogPath );
892
893 // Initialize Xerces-C++
894 WrapXerces::Init ( libxmlNetAccess );
895
896 #if defined(XERCES_HAVE_SSE2_INTRINSIC) && defined(__WXDEBUG__)
897 if ( xercescSSE2Warning && wxTheApp->argc == 1 )
898 {
899 xercescSSE2Warning = wxMessageBox (
900 _ ("SSE2 is enabled in Xerces-C++ library. SSE2 should be "\
901 "checked at run time rather than compile time. The program " \
902 "may crash (segmentation fault) on a machine that " \
903 "doesn't support SSE2.\n\n"\
904 "If it happens, please try compiling Xerces-C++ with SSE2 "\
905 "disabled.\n\n"\
906 "OK:\tShow this warning next time\n"\
907 "Cancel:\tDisable the warning\n"),
908 _ ("SSE2 is checked at compile time"),
909 wxOK | wxCANCEL | wxICON_WARNING
910 ) == wxOK;
911 }
912 #endif // XERCES_HAVE_SSE2_INTRINSIC
913
914 size_t findFlags = 0;
915 findFlags |= wxFR_DOWN;
916
917 if ( findMatchCase )
918 findFlags |= wxFR_MATCHCASE;
919
920 findData.SetFlags ( findFlags );
921
922 // initialise document count for tab labels
923 documentCount = 1;
924
925 SetIcon ( wxICON ( appicon ) );
926
927 CreateStatusBar();
928 wxStatusBar *status = GetStatusBar();
929 int widths[] = { -24, -6, -6, -6, -8 };
930 status->SetFieldsCount ( 5 );
931 status->SetStatusWidths ( 5, widths );
932
933 if ( !frameWidth ||
934 !frameHeight ||
935 frameWidth < 0 ||
936 frameHeight < 0 ||
937 framePosX < 0 ||
938 framePosY < 0 )
939 {
940 #ifdef __WXMSW__
941 Maximize();
942 #else
943 SetSize ( 50, 50, 640, 480 );
944 #endif
945 }
946 else
947 {
948 SetSize ( framePosX, framePosY, frameWidth, frameHeight );
949 }
950
951 stylePosition = aboutPosition = wxDefaultPosition;
952 styleSize = wxSize ( 720, 540 );
953
954 long style = wxAUI_NB_TOP |
955 wxAUI_NB_TAB_SPLIT |
956 wxAUI_NB_TAB_MOVE |
957 wxAUI_NB_SCROLL_BUTTONS |
958 wxAUI_NB_WINDOWLIST_BUTTON |
959 wxAUI_NB_CLOSE_ON_ALL_TABS |
960 wxNO_BORDER;
961
962 mainBook = new MyNotebook (
963 this,
964 ID_NOTEBOOK,
965 wxDefaultPosition,
966 wxDefaultSize,
967 style );
968
969 manager.AddPane ( mainBook, wxAuiPaneInfo().CenterPane()
970 .PaneBorder ( false ).Name ( _T ( "documentPane" ) ) );
971 manager.GetPane ( mainBook ).dock_proportion = 10;
972
973 // add insert child panes
974 locationPanel = new LocationPanel ( this, ID_LOCATION_PANEL );
975 insertChildPanel = new InsertPanel ( this, ID_INSERT_CHILD_PANEL,
976 INSERT_PANEL_TYPE_CHILD );
977 insertSiblingPanel = new InsertPanel ( this, ID_INSERT_SIBLING_PANEL,
978 INSERT_PANEL_TYPE_SIBLING );
979 insertEntityPanel = new InsertPanel ( this, ID_INSERT_ENTITY_PANEL,
980 INSERT_PANEL_TYPE_ENTITY );
981
982 #ifdef __WXMSW__
983 manager.AddPane ( ( wxWindow * ) locationPanel, wxRIGHT, _ ( "Current Element" ) );
984 manager.AddPane ( ( wxWindow * ) insertChildPanel, wxRIGHT, _ ( "Insert Element" ) );
985 manager.AddPane ( ( wxWindow * ) insertSiblingPanel, wxRIGHT, _ ( "Insert Sibling" ) );
986 manager.AddPane ( ( wxWindow * ) insertEntityPanel, wxRIGHT, _ ( "Insert Entity" ) );
987 #else
988 manager.AddPane ( ( wxWindow * ) insertEntityPanel, wxRIGHT, _ ( "Insert Entity" ) );
989 manager.AddPane ( ( wxWindow * ) insertSiblingPanel, wxRIGHT, _ ( "Insert Sibling" ) );
990 manager.AddPane ( ( wxWindow * ) insertChildPanel, wxRIGHT, _ ( "Insert Element" ) );
991 manager.AddPane ( ( wxWindow * ) locationPanel, wxRIGHT, _ ( "Current Element" ) );
992 #endif
993
994 manager.GetPane ( locationPanel ).Name ( _T ( "locationPane" ) ).Show (
995 ( restoreLayout ) ? showLocationPane : true ).DestroyOnClose ( false ).PinButton ( true );
996 manager.GetPane ( locationPanel ).dock_proportion = 1;
997
998 manager.GetPane ( insertChildPanel ).Name ( _T ( "insertChildPane" ) ).Show (
999 ( restoreLayout ) ? showInsertChildPane : true ).DestroyOnClose ( false ).PinButton ( true );
1000 manager.GetPane ( insertChildPanel ).dock_proportion = 1;
1001
1002 manager.GetPane ( insertSiblingPanel ).Name ( _T ( "insertSiblingPane" ) ).Show (
1003 ( restoreLayout ) ? showInsertSiblingPane : true ).DestroyOnClose ( false ).PinButton ( true );
1004 manager.GetPane ( insertSiblingPanel ).dock_proportion = 1;
1005
1006 manager.GetPane ( insertEntityPanel ).Name ( _T ( "insertEntityPane" ) ).Show (
1007 ( restoreLayout ) ? showInsertEntityPane : true ).DestroyOnClose ( false ).PinButton ( true );
1008 manager.GetPane ( insertEntityPanel ).dock_proportion = 1;
1009
1010 // add (hidden) message pane
1011 htmlReport = new MyHtmlPane (
1012 this,
1013 ID_VALIDATION_PANE,
1014 wxDefaultPosition,
1015 wxSize ( -1, 48 ) );
1016 #ifndef __WXMSW__
1017 const int sizeArray[] =
1018 {
1019 8, 9, 10, 11, 12, 13, 14
1020 };
1021 htmlReport->SetFonts ( wxEmptyString, wxEmptyString, sizeArray );
1022 #endif
1023 htmlReport->SetBorders ( 0 );
1024 manager.AddPane ( htmlReport, wxAuiPaneInfo().Movable().Bottom()
1025 .Hide().Name ( _T ( "messagePane" ) )
1026 .DestroyOnClose ( false ).Layer ( 1 ) );
1027 manager.GetPane ( htmlReport ).dock_proportion = 1;
1028
1029 #ifdef NEWFINDREPLACE
1030 findReplacePanel = new FindReplacePanel (
1031 this,
1032 ID_FIND_REPLACE_PANEL,
1033 &findData,
1034 true,
1035 findRegex );
1036
1037 manager.AddPane (
1038 ( wxWindow * ) findReplacePanel,
1039 wxAuiPaneInfo().Bottom().Hide().Caption ( wxEmptyString ).
1040 DestroyOnClose ( false ).Layer ( 2 ) );
1041 #endif
1042
1043 commandPanel = new CommandPanel (
1044 this,
1045 wxID_ANY,
1046 commandString, // tbd
1047 commandSync, // tbd
1048 commandOutput // tbd
1049 );
1050 manager.AddPane (
1051 ( wxWindow * ) commandPanel,
1052 wxAuiPaneInfo().Bottom().Hide().Caption ( _T ( "Command" ) ).DestroyOnClose ( false ).Layer ( 3 ) );
1053
1054 validatePaths();
1055
1056 // handle command line and, on Windows, MS Word integration
1057 handleCommandLineFlag = ( wxTheApp->argc > 1 ) ? true : false;
1058
1059 #ifdef __WXMSW__
1060 DragAcceptFiles ( true ); // currently Windows only
1061 #endif
1062
1063 manager.Update();
1064
1065 showTopBars (
1066 #ifndef __WXOSX__
1067 toolbarVisible
1068 #else
1069 false
1070 #endif
1071 );
1072
1073 wxAcceleratorEntry entry ( wxACCEL_CTRL, WXK_F4, wxID_CLOSE );
1074 wxAcceleratorTable accel ( 1, &entry );
1075 SetAcceleratorTable ( accel );
1076
1077 /*
1078 defaultLayout = manager.SavePerspective();
1079
1080 // restore layout if req'd
1081 if (restoreLayout && !layout.empty())
1082 {
1083 if (!manager.LoadPerspective(layout, true))
1084 manager.LoadPerspective(defaultLayout, true);
1085 }
1086 */
1087 }
1088
~MyFrame()1089 MyFrame::~MyFrame()
1090 {
1091 ThreadReaper::get().clear();
1092
1093 std::vector<wxString>::iterator it;
1094 for ( it = tempFileVector.begin(); it != tempFileVector.end(); ++it )
1095 wxRemoveFile ( *it );
1096
1097 layout = manager.SavePerspective();
1098 if ( !config )
1099 return;
1100 history.Save ( *config );
1101 config->Write ( _T ( "insertCloseTag" ), properties.insertCloseTag );
1102 config->Write ( _T ( "completion" ), properties.completion );
1103 config->Write ( _T ( "number" ), properties.number );
1104 config->Write ( _T ( "fold" ), properties.fold );
1105 config->Write ( _T ( "foldCompact" ), properties.foldCompact );
1106 config->Write ( _T ( "currentLine" ), properties.currentLine );
1107 config->Write ( _T ( "whitespaceVisible" ), properties.whitespaceVisible );
1108 config->Write ( _T ( "wrap" ), properties.wrap );
1109 config->Write ( _T ( "indentLines" ), properties.indentLines );
1110 config->Write ( _T ( "zoom" ), properties.zoom );
1111 config->Write ( _T ( "colorScheme" ), properties.colorScheme );
1112 config->Write ( _T ( "protectHiddenElements" ), properties.protectHiddenElements );
1113 config->Write ( _T ( "toggleLineBackground" ), properties.toggleLineBackground );
1114 config->Write ( _T ( "deleteWholeTag" ), properties.deleteWholeTag );
1115 config->Write ( _T ( "validateAsYouType" ), properties.validateAsYouType );
1116 config->Write ( _T ( "font" ), properties.font );
1117 config->Write ( _T ( "highlightSyntax" ), properties.highlightSyntax );
1118 config->Write ( _T ( "applicationDir" ), applicationDir );
1119 config->Write ( _T ( "ruleSetPreset" ), ruleSetPreset );
1120 config->Write ( _T ( "dictionaryPreset" ), dictionaryPreset );
1121 config->Write ( _T ( "filterPreset" ), filterPreset );
1122 config->Write ( _T ( "xpathExpression" ), xpathExpression );
1123 config->Write ( _T ( "findReplaceFind" ), findData.GetFindString() );
1124 config->Write ( _T ( "findReplaceReplace" ), findData.GetReplaceString() );
1125 config->Write ( _T ( "globalReplaceAllDocuments" ), globalReplaceAllDocuments );
1126 config->Write ( _T ( "showFullPathOnFrame" ), showFullPathOnFrame );
1127 config->Write ( _T ( "toolbarVisible" ), toolbarVisible );
1128 config->Write ( _T ( "protectTags" ), protectTags );
1129 config->Write ( _T ( "visibilityState" ), visibilityState );
1130 config->Write ( _T ( "showLocationPane" ), manager.GetPane ( locationPanel ).IsShown() );
1131 config->Write ( _T ( "showInsertChildPane" ), manager.GetPane ( insertChildPanel ).IsShown() );
1132 config->Write ( _T ( "showInsertSiblingPane" ), manager.GetPane ( insertSiblingPanel ).IsShown() );
1133 config->Write ( _T ( "showInsertEntityPane" ), manager.GetPane ( insertEntityPanel ).IsShown() );
1134 config->Write ( _T ( "expandInternalEntities" ), expandInternalEntities );
1135 config->Write ( _T ( "findRegex" ), findReplacePanel->getRegex() );
1136 config->Write ( _T ( "findMatchCase" ), ( findData.GetFlags() ) & wxFR_MATCHCASE );
1137 config->Write ( _T ( "commandSync" ), commandPanel->getSync() );
1138 config->Write ( _T ( "commandOutput" ), commandPanel->getOutput() );
1139 config->Write ( _T ( "commandString" ), commandPanel->getCommand() );
1140 config->Write ( _T ( "restoreLayout" ), restoreLayout );
1141 config->Write ( _T ( "lastXslStylesheet" ), lastXslStylesheet );
1142 config->Write ( _T ( "lastRelaxNGSchema" ), lastRelaxNGSchema );
1143 config->Write ( _T ( "exportStylesheet" ), exportStylesheet );
1144 config->Write ( _T ( "exportFolder" ), exportFolder );
1145 config->Write ( _T ( "exportQuiet" ), exportQuiet );
1146 config->Write ( _T ( "exportMp3Album" ), exportMp3Album );
1147 config->Write ( _T ( "exportSuppressOptional" ), exportSuppressOptional );
1148 config->Write ( _T ( "exportHtml" ), exportHtml );
1149 config->Write ( _T ( "exportEpub" ), exportEpub );
1150 config->Write ( _T ( "exportRtf" ), exportRtf );
1151 config->Write ( _T ( "exportDoc" ), exportDoc );
1152 config->Write ( _T ( "exportFullDaisy" ), exportFullDaisy );
1153
1154 GetPosition ( &framePosX, &framePosY );
1155 config->Write ( _T ( "framePosX" ), framePosX );
1156 config->Write ( _T ( "framePosY" ), framePosY );
1157 GetSize ( &frameWidth, &frameHeight );
1158 config->Write ( _T ( "frameWidth" ), frameWidth );
1159 config->Write ( _T ( "frameHeight" ), frameHeight );
1160
1161 config->Write ( _T ( "rememberOpenTabs" ), rememberOpenTabs );
1162 config->Write ( _T ( "openTabsOnClose" ), openTabsOnClose );
1163 config->Write ( _T ( "libxmlNetAccess" ), libxmlNetAccess );
1164
1165 config->Write ( _T ( "singleInstanceCheck" ), singleInstanceCheck );
1166 config->Write ( _T ( "lang" ), lang );
1167 config->Write ( _T ( "notebookStyle" ), notebookStyle );
1168 config->Write ( _T ( "saveBom" ), saveBom );
1169 config->Write ( _T ( "unlimitedUndo" ), unlimitedUndo );
1170
1171 config->Write ( _T ( "lastSymbol" ), lastSymbol );
1172
1173 #if defined(XERCES_HAVE_SSE2_INTRINSIC) && defined(__WXDEBUG__)
1174 config->Write ( _T ( "xercescSSE2Warning" ), xercescSSE2Warning );
1175 #endif
1176
1177 manager.UnInit();
1178 wxTheClipboard->Flush();
1179 }
1180
showTopBars(bool b)1181 void MyFrame::showTopBars ( bool b )
1182 {
1183 if ( !menuBar )
1184 {
1185 SetToolBar ( NULL );
1186 menuBar = getMenuBar();
1187 SetMenuBar ( menuBar );
1188 }
1189 if ( b )
1190 {
1191 if ( !toolBar )
1192 toolBar = getToolBar();
1193 SetToolBar ( toolBar );
1194 }
1195 else
1196 {
1197 SetToolBar ( NULL );
1198 delete toolBar;
1199 toolBar = NULL;
1200 }
1201 }
1202
handleCommandLine()1203 void MyFrame::handleCommandLine()
1204 {
1205 bool wordFlag, styleFlag;
1206 wordFlag = styleFlag = false;
1207 wxChar c;
1208
1209 int argc = wxTheApp->argc;
1210 wxChar **argv = wxTheApp->argv;
1211
1212 while ( ( --argc > 0 && ( *++argv ) [0] == L'-' ) != 0 )
1213 {
1214 wxString wideVersion ( ABOUT_VERSION );
1215 std::string version = ( const char * ) wideVersion.mb_str ( wxConvUTF8 );
1216 const wxChar *s = argv[0];
1217 while ( ( c = *++s ) != 0 )
1218 {
1219 switch ( c )
1220 {
1221 case 'w':
1222 wordFlag = true;
1223 break;
1224 case 's':
1225 styleFlag = true;
1226 break;
1227 case '-':
1228 if ( *++s == 'v' )
1229 {
1230 std::cout << version.c_str() << std::endl;
1231 }
1232 else
1233 {
1234 std::cout << "Usage: xmlcopyeditor [--version --help -ws] [<file>] [<file2>]" << std::endl
1235 << "Options -w (import Microsoft Word document) and -s (open Spelling and style check) are provided for integration with Microsoft Office and only available on Windows" << std::endl;
1236 }
1237 exit ( 0 );
1238 default:
1239 messagePane ( _ ( "Unknown command line switch (expecting 'w', 's', --version or --help)" ),
1240 CONST_STOP );
1241 return;
1242 }
1243 }
1244 }
1245
1246 if ( argc <= 0 )
1247 {
1248 messagePane ( _ ( "Command line processing incomplete: no file specified" ),
1249 CONST_STOP );
1250 return;
1251 }
1252
1253 wxString fileName;
1254
1255 // no flags specified or not Windows
1256 #ifdef __WXMSW__
1257 if ( !styleFlag && !wordFlag )
1258 #endif
1259 {
1260 for ( ; argc > 0; --argc, ++argv )
1261 {
1262 fileName = wxString ( *argv, wxConvLocal );
1263 fileName = PathResolver::run ( fileName );
1264 if ( isOpen ( fileName ) )
1265 continue;
1266 else if ( !openFile ( fileName ) )
1267 break;
1268 }
1269 return;
1270 }
1271
1272 // options only available on Windows
1273 fileName = wxString ( *argv, wxConvLocal );
1274
1275 // fetch as many parameters as possible
1276 for ( ;; )
1277 {
1278 if ( --argc <= 0 )
1279 break;
1280 ++argv;
1281 ruleSetPreset = wxString ( *argv, wxConvLocal );
1282
1283 if ( --argc <= 0 )
1284 break;
1285 ++argv;
1286 filterPreset = wxString ( *argv, wxConvLocal );
1287
1288 if ( --argc <= 0 )
1289 break;
1290 ++argv;
1291 applicationDir = wxString ( *argv, wxConvLocal );
1292 updatePaths();
1293
1294 break;
1295 }
1296 if ( wordFlag )
1297 importMSWord ( fileName );
1298 else
1299 openFile ( fileName );
1300
1301 if ( styleFlag && !ruleSetPreset.empty() && !filterPreset.empty() )
1302 {
1303 wxCommandEvent e;
1304 OnSpelling ( e );
1305 }
1306 }
1307
isOpen(const wxString & fileName)1308 bool MyFrame::isOpen ( const wxString& fileName )
1309 {
1310 return ( openFileSet.find ( fileName ) != openFileSet.end() );
1311 }
1312
activateTab(const wxString & fileName)1313 bool MyFrame::activateTab ( const wxString& fileName )
1314 {
1315 int pageCount = mainBook->GetPageCount();
1316 XmlDoc *currentDoc;
1317 for ( int i = 0; i < pageCount; ++i )
1318 {
1319 currentDoc = ( XmlDoc * ) mainBook->GetPage ( i );
1320 if ( !currentDoc )
1321 break;
1322 if ( currentDoc->getFullFileName() == fileName )
1323 {
1324 mainBook->SetSelection ( i );
1325 return true;
1326 }
1327 }
1328 return false;
1329 }
1330
OnAbout(wxCommandEvent & WXUNUSED (event))1331 void MyFrame::OnAbout ( wxCommandEvent& WXUNUSED ( event ) )
1332 {
1333 wxString description;
1334 description = ABOUT_DESCRIPTION;
1335 description.Append ( ABOUT_CONTRIBUTORS );
1336 description.Append ( _T("\n\nFramework version: ") );
1337 description.Append ( wxVERSION_STRING );
1338 description.Append ( _T("\n") );
1339
1340 wxAboutDialogInfo info;
1341 info.SetName ( _ ( "XML Copy Editor" ) );
1342 info.SetWebSite ( _T ( "http://xml-copy-editor.sourceforge.net" ) );
1343 info.SetVersion ( ABOUT_VERSION );
1344 info.SetCopyright ( ABOUT_COPYRIGHT );
1345 info.AddDeveloper ( _T ( "Gerald Schmidt (development) <gnschmidt at users dot sourceforge dot net>" ) );
1346 info.AddDeveloper ( _T ( "Matt Smigielski (testing) <alectrus at users dot sourceforge dot net>" ) );
1347 info.AddDeveloper ( _T ( "Justin Dearing (development) <j-pimp at users dot sourceforge dot net>" ) );
1348 info.AddDeveloper ( _T ( "Kev James (development) <kmjames at users dot sourceforge dot net>" ) );
1349 info.AddDeveloper ( _T ( "Anh Trinh (development) <ant271 at users dot sourceforge dot net>" ) );
1350 info.AddDeveloper ( _T ( "Zane U. Ji (development) <zaneuji at users dot sourceforge dot net>" ) );
1351 info.AddDeveloper ( _T ( "Hugh McMaster (development) <hugh dot mcmaster at outlook dot com>" ) );
1352 info.AddDeveloper ( _T ( "Nikola Forró (development) <nforro at redhat dot com>" ) );
1353 info.AddTranslator ( _T ( "Viliam Búr (Slovak) <viliam at bur dot sk>" ) );
1354 info.AddTranslator ( _T ( "David Håsäther (Swedish) <hasather at gmail dot com>" ) );
1355 info.AddTranslator ( _T ( "François Badier (French) <frabad at gmail dot com>" ) );
1356 info.AddTranslator ( _T ( "Thomas Wenzel (German) <thowen at users dot sourceforge.net>" ) );
1357 info.AddTranslator ( _T ( "SHiNE CsyFeK (Chinese Simplified) <csyfek at gmail dot com>" ) );
1358 info.AddTranslator ( _T ( "HSU PICHAN, YANG SHUFUN, CHENG PAULIAN, CHUANG KUO-PING, Marcus Bingenheimer (Chinese Traditional)" ) );
1359 info.AddTranslator ( _T ( "Serhij Dubyk (Ukrainian) <dubyk at library dot lviv dot ua>" ) );
1360 info.AddTranslator ( _T ( "Antonio Angelo (Italian) <aangelo at users dot sourceforge dot net>" ) );
1361 info.AddTranslator ( _T ( "Siarhei Kuchuk (Russian) <Cuchuk dot Sergey at gmail dot com>" ) );
1362 info.AddTranslator ( _T ( "Marcos Pérez González (Spanish) <marcos_pg at yahoo dot com>" ) );
1363 info.AddTranslator ( _T ( "Rob Elemans (Dutch) <relemans at gmail dot com>" ) );
1364 info.AddTranslator ( _T ( "Robert Falcó Miramontes <rfalco at acett dot org>" ) );
1365 info.AddTranslator ( _T ( "Khoem Sokhem (Khmer) <sokhem at open dot org dot kh>" ) );
1366 info.AddTranslator ( _T ( "Roger Sperberg (Khmer) <rsperberg at gmail dot com>" ) );
1367 info.SetLicense ( ABOUT_LICENSE );
1368 info.SetDescription ( description );
1369 wxAboutBox ( info );
1370 XmlDoc *doc;
1371 if ( ( doc = getActiveDocument() ) == NULL )
1372 return;
1373 doc->SetFocus();
1374 }
1375
OnCheckWellformedness(wxCommandEvent & event)1376 void MyFrame::OnCheckWellformedness ( wxCommandEvent& event )
1377 {
1378 statusProgress ( wxEmptyString );
1379 XmlDoc *doc;
1380 if ( ( doc = getActiveDocument() ) == NULL )
1381 return;
1382
1383 std::string utf8Buffer;
1384 getRawText ( doc, utf8Buffer );
1385 if ( utf8Buffer.empty() )
1386 return;
1387
1388 doc->clearErrorIndicators();
1389 statusProgress ( _ ( "Parse in progress..." ) );
1390
1391 // check for well-formedness
1392 WrapExpat we ( "UTF-8" );
1393 if ( !we.parse ( utf8Buffer ) )
1394 {
1395 statusProgress ( wxEmptyString );
1396 messagePane ( we.getLastError(), CONST_WARNING );
1397 std::pair<int, int> posPair = we.getErrorPosition();
1398 -- ( posPair.first );
1399 int cursorPos =
1400 doc->PositionFromLine ( posPair.first );
1401 doc->SetSelection ( cursorPos, cursorPos );
1402
1403 doc->setErrorIndicator ( posPair.first, posPair.second );
1404 return;
1405 }
1406
1407 statusProgress ( wxEmptyString );
1408 documentOk ( _ ( "well-formed" ) );
1409 }
1410
OnPageClosing(wxAuiNotebookEvent & event)1411 void MyFrame::OnPageClosing ( wxAuiNotebookEvent& event ) //wxNotebookEvent& event)//wxFlatNotebookEvent& event)
1412 {
1413 deletePageVetoed = false;
1414
1415 if ( insertChildPanel && insertSiblingPanel && locationPanel )
1416 {
1417 insertChildPanel->update ( NULL, wxEmptyString );
1418 insertSiblingPanel->update ( NULL, wxEmptyString );
1419 locationPanel->update();
1420 manager.Update();
1421 }
1422
1423 XmlDoc *doc;
1424 doc = ( XmlDoc * ) mainBook->GetPage ( event.GetSelection() );
1425 if ( !doc )
1426 return;
1427
1428 statusProgress ( wxEmptyString );
1429 closeMessagePane();
1430
1431 if ( doc->GetModify() ) //CanUndo())
1432 {
1433 int selection;
1434 wxString fileName;
1435 selection = mainBook->GetSelection();
1436 if ( selection != -1 )
1437 fileName = doc->getShortFileName();
1438
1439 int answer = wxMessageBox (
1440 _ ( "Do you want to save the changes to " ) + fileName + _T ( "?" ),
1441 _ ( "XML Copy Editor" ),
1442 wxYES_NO | wxCANCEL | wxICON_QUESTION,
1443 this );
1444
1445 if ( answer == wxCANCEL )
1446 {
1447 event.Veto();
1448 deletePageVetoed = true;
1449 return;
1450 }
1451 else if ( answer == wxYES )
1452 {
1453 wxCommandEvent event;
1454 OnSave ( event );
1455 }
1456 }
1457 statusProgress ( wxEmptyString );
1458
1459 openFileSet.erase ( doc->getFullFileName() );
1460 event.Skip();
1461 }
1462
OnClose(wxCommandEvent & WXUNUSED (event))1463 void MyFrame::OnClose ( wxCommandEvent& WXUNUSED ( event ) )
1464 {
1465 closeActiveDocument();
1466 }
1467
OnCloseAll(wxCommandEvent & WXUNUSED (event))1468 void MyFrame::OnCloseAll ( wxCommandEvent& WXUNUSED ( event ) )
1469 {
1470 if ( !mainBook )
1471 return;
1472 openTabsOnClose = wxEmptyString;
1473
1474 // retain tab order
1475 if ( rememberOpenTabs && !openFileSet.empty() )
1476 {
1477 XmlDoc *doc;
1478 wxString fullPath;
1479 size_t maxTabs = mainBook->GetPageCount();
1480 for ( size_t i = 0; i < maxTabs; ++i )
1481 {
1482 doc = ( XmlDoc * ) mainBook->GetPage ( i );
1483 if ( doc && !doc->getDirectory().empty() )
1484 {
1485 fullPath = doc->getFullFileName();
1486 openTabsOnClose.Append ( fullPath );
1487 openTabsOnClose.Append ( _T ( "|" ) );
1488 }
1489 }
1490 }
1491
1492 while ( closeActiveDocument() )
1493 ;
1494 }
1495
OnCloseMessagePane(wxCommandEvent & WXUNUSED (event))1496 void MyFrame::OnCloseMessagePane ( wxCommandEvent& WXUNUSED ( event ) )
1497 {
1498 closeMessagePane();
1499 }
1500
OnCloseFindReplacePane(wxCommandEvent & WXUNUSED (event))1501 void MyFrame::OnCloseFindReplacePane ( wxCommandEvent& WXUNUSED ( event ) )
1502 {
1503 closeFindReplacePane();
1504 }
1505
OnCloseCommandPane(wxCommandEvent & WXUNUSED (event))1506 void MyFrame::OnCloseCommandPane ( wxCommandEvent& WXUNUSED ( event ) )
1507 {
1508 closeCommandPane();
1509 }
1510
closeMessagePane()1511 void MyFrame::closeMessagePane()
1512 {
1513 if ( !htmlReport )
1514 return;
1515 manager.GetPane ( htmlReport ).Hide();
1516 manager.Update();
1517
1518 XmlDoc *doc = getActiveDocument();
1519 if ( doc )
1520 doc->SetFocus();
1521 }
1522
closeFindReplacePane()1523 void MyFrame::closeFindReplacePane()
1524 {
1525 if ( manager.GetPane ( findReplacePanel ).IsShown() )
1526 manager.GetPane ( findReplacePanel ).Hide();
1527 manager.Update();
1528
1529 XmlDoc *doc = getActiveDocument();
1530 if ( doc != NULL )
1531 doc->SetFocus();
1532 }
1533
closeCommandPane()1534 void MyFrame::closeCommandPane()
1535 {
1536 if ( manager.GetPane ( commandPanel ).IsShown() )
1537 manager.GetPane ( commandPanel ).Hide();
1538 manager.Update();
1539
1540 XmlDoc *doc = getActiveDocument();
1541 if ( doc != NULL )
1542 doc->SetFocus();
1543 }
1544
panelHasFocus()1545 bool MyFrame::panelHasFocus()
1546 {
1547 XmlDoc *doc = getActiveDocument();
1548 return ( !doc || ( FindFocus() != ( wxWindow * ) doc ) );
1549 }
1550
OnCut(wxCommandEvent & event)1551 void MyFrame::OnCut ( wxCommandEvent& event )
1552 {
1553 if ( panelHasFocus() )
1554 {
1555 event.Skip();
1556 return;
1557 }
1558
1559 XmlDoc *doc;
1560 if ( ( doc = getActiveDocument() ) == NULL )
1561 return;
1562
1563 if ( protectTags )
1564 doc->adjustSelection();
1565
1566 doc->Cut();
1567 doc->setValidationRequired ( true );
1568 }
1569
OnCopy(wxCommandEvent & event)1570 void MyFrame::OnCopy ( wxCommandEvent& event )
1571 {
1572 if ( panelHasFocus() )
1573 {
1574 event.Skip();
1575 return;
1576 }
1577
1578 XmlDoc *doc;
1579 if ( ( doc = getActiveDocument() ) == NULL )
1580 return;
1581 doc->Copy();
1582 }
1583
OnPaste(wxCommandEvent & event)1584 void MyFrame::OnPaste ( wxCommandEvent& event )
1585 {
1586 if ( panelHasFocus() )
1587 {
1588 event.Skip();
1589 return;
1590 }
1591 XmlDoc *doc;
1592 if ( ( doc = getActiveDocument() ) == NULL )
1593 return;
1594
1595 // this has to be handled here to override Scintilla's default Ctrl+V support
1596 if ( protectTags )
1597 {
1598 if ( !wxTheClipboard->Open() || !wxTheClipboard->IsSupported ( wxDF_TEXT ) )
1599 return;
1600 wxTextDataObject data;
1601 wxTheClipboard->GetData ( data );
1602 wxString buffer = data.GetText();
1603 wxTheClipboard->Close();
1604 xmliseWideTextNode ( buffer );
1605 doc->adjustCursor();
1606 doc->AddText ( buffer );
1607 }
1608 else
1609 doc->Paste();
1610 }
1611
OnIdle(wxIdleEvent & event)1612 void MyFrame::OnIdle ( wxIdleEvent& event )
1613 {
1614 wxStatusBar *status = GetStatusBar();
1615 if ( !status )
1616 return;
1617
1618 /*
1619 // IPC handling: take one file from fileQueue at a time
1620 if ( !fileQueue.empty() )
1621 {
1622 openFile ( * ( fileQueue.begin() ) );
1623 fileQueue.erase( fileQueue.begin() );
1624 }
1625 */
1626
1627 // update attributes hidden field even if no document loaded
1628 wxString currentHiddenStatus = status->GetStatusText ( STATUS_HIDDEN );
1629 if ( visibilityState == HIDE_ATTRIBUTES )
1630 {
1631 if ( currentHiddenStatus != _ ( "Attributes hidden" ) )
1632 status->SetStatusText (
1633 _ ( "Attributes hidden" ),
1634 STATUS_HIDDEN );
1635 }
1636 else if ( visibilityState == HIDE_TAGS )
1637 {
1638 if ( currentHiddenStatus != _ ( "Tags hidden" ) )
1639 status->SetStatusText (
1640 _ ( "Tags hidden" ),
1641 STATUS_HIDDEN );
1642 }
1643 else
1644 {
1645 if ( !currentHiddenStatus.empty() )
1646 status->SetStatusText ( wxEmptyString, STATUS_HIDDEN );
1647 }
1648
1649 // update protected field even if no document loaded
1650 wxString currentProtectedStatus = status->GetStatusText ( STATUS_PROTECTED );
1651 if ( protectTags )
1652 {
1653 if ( currentProtectedStatus != _ ( "Tags locked" ) )
1654 status->SetStatusText (
1655 _ ( "Tags locked" ),
1656 STATUS_PROTECTED );
1657 }
1658 else
1659 {
1660 if ( !currentProtectedStatus.empty() )
1661 status->SetStatusText ( wxEmptyString, STATUS_PROTECTED );
1662 }
1663
1664 // check if document loaded
1665 wxString frameTitle = GetTitle();
1666
1667 XmlDoc *doc = getActiveDocument();
1668 if ( doc == NULL )
1669 {
1670 if ( lastDoc != NULL )
1671 {
1672 lastDoc = NULL;
1673 status->SetStatusText ( wxEmptyString, STATUS_MODIFIED );
1674 status->SetStatusText ( wxEmptyString, STATUS_POSITION );
1675 locationPanel->update ( NULL, wxEmptyString );
1676 insertChildPanel->update ( NULL, wxEmptyString );
1677 insertSiblingPanel->update ( NULL, wxEmptyString );
1678 insertEntityPanel->update ( NULL, wxEmptyString );
1679 wxString minimal = _ ( "XML Copy Editor" );
1680 if ( frameTitle != minimal )
1681 SetTitle ( minimal );
1682
1683 closeFindReplacePane();
1684
1685 event.Skip();
1686 manager.Update();
1687 }
1688 return;
1689 }
1690
1691 if ( restoreFocusToNotebook )
1692 {
1693 doc->SetFocus();
1694 restoreFocusToNotebook = false;
1695 }
1696
1697 // update modified field
1698 if ( !mainBook )
1699 return;
1700 int index = mainBook->GetSelection();
1701
1702 wxString currentModifiedStatus = status->GetStatusText ( STATUS_MODIFIED );
1703 wxString currentTabLabel = mainBook->GetPageText ( index );
1704 if ( doc->GetModify() )
1705 {
1706 if ( currentModifiedStatus != _ ( "Modified" ) )
1707 {
1708 status->SetStatusText ( _ ( "Modified" ), STATUS_MODIFIED );
1709
1710 if ( ! ( currentTabLabel.Mid ( 0, 1 ) == _T ( "*" ) ) )
1711 {
1712 currentTabLabel.Prepend ( _T ( "*" ) );
1713 mainBook->SetPageText ( index, currentTabLabel );
1714 }
1715 }
1716 }
1717 else
1718 {
1719 if ( !currentModifiedStatus.empty() )
1720 {
1721 status->SetStatusText ( _T ( "" ), STATUS_MODIFIED );
1722
1723 if ( currentTabLabel.Mid ( 0, 1 ) == _T ( "*" ) )
1724 {
1725 currentTabLabel.Remove ( 0, 1 );
1726 mainBook->SetPageText ( index, currentTabLabel );
1727 }
1728 }
1729 }
1730
1731 // update coordinates field
1732 int current = doc->GetCurrentPos();
1733 if ( current != lastPos )
1734 {
1735 wxString coordinates;
1736 coordinates.Printf (
1737 _ ( "Ln %i Col %i" ),
1738 doc->LineFromPosition ( current ) + 1,
1739 doc->GetColumn ( current ) + 1 );
1740 GetStatusBar()->SetStatusText ( coordinates, STATUS_POSITION );
1741 }
1742
1743 // update parent element field
1744 wxString parent, grandparent;
1745 if ( current == lastPos && doc == lastDoc )
1746 return;
1747
1748 lastPos = current;
1749 lastDoc = doc;
1750
1751 wxString docTitle;
1752 if ( doc->getFullFileName().empty() || !showFullPathOnFrame )
1753 docTitle = doc->getShortFileName();
1754 else
1755 docTitle = doc->getFullFileName();
1756
1757 docTitle += _T ( " - " );
1758 docTitle += _ ( "XML Copy Editor" );
1759
1760 if ( frameTitle != docTitle )
1761 SetTitle ( docTitle );
1762
1763 // don't try to find parent if pane is not shown
1764 if ( !manager.GetPane ( insertChildPanel ).IsShown() && !properties.validateAsYouType )
1765 return;
1766
1767 int parentCloseAngleBracket = -1;
1768 if ( !doc->canInsertAt ( current ) )
1769 parent = grandparent = wxEmptyString;
1770 else
1771 {
1772 parentCloseAngleBracket = doc->getParentCloseAngleBracket ( current );
1773 parent = doc->getLastElementName ( parentCloseAngleBracket );
1774 }
1775
1776 if ( !parent.empty() && properties.validateAsYouType && doc->getValidationRequired() )
1777 {
1778 // tbd: limit to parent element
1779 doc->backgroundValidate();
1780 }
1781
1782
1783 if ( parent == lastParent )
1784 return;
1785 lastParent = parent;
1786
1787 bool mustUpdate = false;
1788 if ( locationPanel && insertChildPanel && insertEntityPanel )
1789 {
1790 locationPanel->update ( doc, parent );
1791 insertChildPanel->update ( doc, parent );
1792 insertEntityPanel->update ( doc );
1793 mustUpdate = true;
1794 }
1795
1796 if ( parent.empty() )
1797 {
1798 if ( insertSiblingPanel )
1799 insertSiblingPanel->update ( doc, wxEmptyString );
1800 if ( mustUpdate )
1801 manager.Update();
1802 return;
1803 }
1804
1805 if ( !manager.GetPane ( insertSiblingPanel ).IsShown() )
1806 {
1807 if ( mustUpdate )
1808 manager.Update();
1809 return;
1810 }
1811
1812 // try to fetch grandparent if necessary/possible
1813 if ( !parent.empty() && parentCloseAngleBracket != -1 )
1814 {
1815 int grandParentCloseAngleBracket;
1816 grandParentCloseAngleBracket =
1817 doc->getParentCloseAngleBracket (
1818 doc->getTagStartPos ( parentCloseAngleBracket ) );
1819 grandparent = doc->getLastElementName ( grandParentCloseAngleBracket );
1820
1821 if ( insertSiblingPanel )
1822 insertSiblingPanel->update ( doc, parent, grandparent );
1823 if ( grandparent != lastGrandparent )
1824 {
1825 mustUpdate = true;
1826 lastGrandparent = grandparent;
1827 }
1828
1829 }
1830 if ( mustUpdate )
1831 manager.Update();
1832 }
1833
OnInsertChild(wxCommandEvent & event)1834 void MyFrame::OnInsertChild ( wxCommandEvent& event )
1835 {
1836 if ( !insertChildPanel )
1837 return;
1838
1839 wxAuiPaneInfo info = manager.GetPane ( insertChildPanel );
1840 if ( !info.IsOk() )
1841 {
1842 return;
1843 }
1844 if ( !info.IsShown() )
1845 {
1846 manager.GetPane ( insertChildPanel ).Show ( true );
1847 manager.Update();
1848 }
1849 insertChildPanel->setEditFocus();
1850 }
1851
OnInsertSibling(wxCommandEvent & event)1852 void MyFrame::OnInsertSibling ( wxCommandEvent& event )
1853 {
1854 if ( !insertSiblingPanel )
1855 return;
1856
1857 wxAuiPaneInfo info = manager.GetPane ( insertSiblingPanel );
1858 if ( !info.IsOk() )
1859 {
1860 return;
1861 }
1862
1863 if ( !info.IsShown() )
1864 {
1865 manager.GetPane ( insertSiblingPanel ).Show ( true );
1866 manager.Update();
1867 }
1868 insertSiblingPanel->setEditFocus();
1869 }
1870
OnInsertEntity(wxCommandEvent & event)1871 void MyFrame::OnInsertEntity ( wxCommandEvent& event )
1872 {
1873 if ( !insertEntityPanel )
1874 return;
1875
1876 wxAuiPaneInfo info = manager.GetPane ( insertEntityPanel );
1877 if ( !info.IsOk() )
1878 {
1879 return;
1880 }
1881
1882 if ( !info.IsShown() )
1883 {
1884 manager.GetPane ( insertEntityPanel ).Show ( true );
1885 manager.Update();
1886 }
1887 insertEntityPanel->setEditFocus();
1888 }
1889
OnInsertSymbol(wxCommandEvent & event)1890 void MyFrame::OnInsertSymbol ( wxCommandEvent& event )
1891 {
1892 XmlDoc *doc;
1893 if ( ( doc = getActiveDocument() ) == NULL )
1894 return;
1895
1896 wxSymbolPickerDialog dlg ( lastSymbol, wxEmptyString, properties.font, this );
1897 if ( dlg.ShowModal() == wxID_OK )
1898 {
1899 if ( dlg.HasSelection() )
1900 {
1901 lastSymbol = dlg.GetSymbol();
1902 doc->AddText ( lastSymbol );
1903 }
1904 }
1905 }
1906
OnInsertTwin(wxCommandEvent & event)1907 void MyFrame::OnInsertTwin ( wxCommandEvent& event )
1908 {
1909 XmlDoc *doc;
1910 if ( ( doc = getActiveDocument() ) == NULL )
1911 return;
1912
1913 wxString parent = doc->getParent();
1914 if ( !doc->insertSibling ( parent, parent ) )
1915 {
1916 wxString msg;
1917 msg.Printf ( _T ( "Cannot insert twin '%s'" ), parent.c_str() );
1918 messagePane ( msg, CONST_STOP );
1919 }
1920 doc->setValidationRequired ( true );
1921 doc->SetFocus();
1922 }
1923
OnPasteNewDocument(wxCommandEvent & event)1924 void MyFrame::OnPasteNewDocument ( wxCommandEvent& event )
1925 {
1926 if ( !wxTheClipboard->Open() )
1927 {
1928 messagePane ( _ ( "Cannot open clipboard" ), CONST_STOP );
1929 return;
1930 }
1931 if ( !wxTheClipboard->IsSupported ( wxDF_TEXT ) )
1932 {
1933 messagePane ( _ ( "Cannot paste as new document: no text on clipboard" ), CONST_STOP );
1934 return;
1935 }
1936 wxTextDataObject data;
1937 wxTheClipboard->GetData ( data );
1938
1939 wxString buffer = data.GetText();
1940 xmliseWideTextNode ( buffer );
1941
1942 buffer.Prepend ( _T ( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>" ) );
1943 buffer.Append ( _T ( "</root>\n" ) );
1944
1945 newDocument ( buffer );
1946 wxTheClipboard->Close();
1947 }
1948
OnDialogFind(wxFindDialogEvent & event)1949 void MyFrame::OnDialogFind ( wxFindDialogEvent& event )
1950 {
1951 findAgain ( event.GetFindString(), event.GetFlags() );
1952 }
1953
OnDialogReplace(wxFindDialogEvent & event)1954 void MyFrame::OnDialogReplace ( wxFindDialogEvent& event )
1955 {
1956 statusProgress ( wxEmptyString );
1957 XmlDoc *doc;
1958 if ( ( doc = getActiveDocument() ) == NULL )
1959 return;
1960
1961 int start = doc->GetTargetStart();
1962 int end = doc->GetTargetEnd();
1963 if ( start != end )
1964 {
1965 if ( findReplacePanel->getRegex() )
1966 {
1967 start += doc->ReplaceTargetRE ( event.GetReplaceString() );
1968 }
1969 else
1970 {
1971 start += doc->ReplaceTarget ( event.GetReplaceString() );
1972 }
1973 // Move to the next position
1974 doc->SetSelection ( start, start );
1975 }
1976 OnDialogFind ( event );
1977 }
1978
OnDialogReplaceAll(wxFindDialogEvent & event)1979 void MyFrame::OnDialogReplaceAll ( wxFindDialogEvent& event )
1980 {
1981 statusProgress ( wxEmptyString );
1982 XmlDoc *doc;
1983 if ( ( doc = getActiveDocument() ) == NULL )
1984 return;
1985
1986 int flags = 0;
1987 if ( event.GetFlags() & wxFR_WHOLEWORD )
1988 flags |= wxSTC_FIND_WHOLEWORD;
1989 if ( event.GetFlags() & wxFR_MATCHCASE )
1990 flags |= wxSTC_FIND_MATCHCASE;
1991 if ( findReplacePanel->getRegex() )
1992 flags |= wxSTC_FIND_REGEXP;
1993
1994 doc->SetTargetStart ( 0 );
1995 doc->SetTargetEnd ( doc->GetLength() );
1996 doc->SetSearchFlags ( flags );
1997
1998 doc->BeginUndoAction();
1999
2000 int newLocation, replacementCount, regexWidth;
2001 newLocation = replacementCount = regexWidth = 0;
2002
2003 while ( ( newLocation = doc->SearchInTarget ( event.GetFindString() ) ) != -1 )
2004 {
2005 if ( findReplacePanel->getRegex() )
2006 {
2007 regexWidth = doc->ReplaceTargetRE ( event.GetReplaceString() );
2008 doc->SetTargetStart ( newLocation + regexWidth );
2009 }
2010 else
2011 {
2012 doc->ReplaceTarget ( event.GetReplaceString() );
2013 doc->SetTargetStart ( newLocation + event.GetReplaceString().size() );
2014 }
2015 doc->SetTargetEnd ( doc->GetLength() );
2016 ++replacementCount;
2017 }
2018
2019 doc->EndUndoAction();
2020
2021 wxString msg;
2022 msg.Printf (
2023 wxPLURAL ( "%i replacement made", "%i replacements made", replacementCount ),
2024 replacementCount );
2025 statusProgress ( msg );
2026 }
2027
OnPrintSetup(wxCommandEvent & WXUNUSED (event))2028 void MyFrame::OnPrintSetup ( wxCommandEvent &WXUNUSED ( event ) )
2029 {
2030 if ( !htmlPrinting.get() )
2031 return;
2032 htmlPrinting->PageSetup();
2033 }
2034
OnPrintPreview(wxCommandEvent & WXUNUSED (event))2035 void MyFrame::OnPrintPreview ( wxCommandEvent &WXUNUSED ( event ) )
2036 {
2037 XmlDoc *doc;
2038 if ( !htmlPrinting.get() || ( doc = getActiveDocument() ) == NULL )
2039 return;
2040 wxString shortFileName, header;
2041 shortFileName = doc->getShortFileName();
2042 if ( !shortFileName.empty() )
2043 header = shortFileName + _T ( " " );
2044 header += _T ( "(@PAGENUM@/@PAGESCNT@)<hr>" );
2045
2046 htmlPrinting->SetHeader (
2047 header,
2048 wxPAGE_ALL );
2049 statusProgress ( _ ( "Preparing Print Preview..." ) );
2050 wxString htmlBuffer = getHtmlBuffer();
2051 statusProgress ( wxEmptyString );
2052 if ( ! ( htmlPrinting->PreviewText ( htmlBuffer ) ) )
2053 {}
2054 }
2055
OnPrint(wxCommandEvent & WXUNUSED (event))2056 void MyFrame::OnPrint ( wxCommandEvent &WXUNUSED ( event ) )
2057 {
2058 XmlDoc *doc;
2059 if ( !htmlPrinting.get() || ( doc = getActiveDocument() ) == NULL )
2060 return;
2061 wxString shortFileName, header;
2062 shortFileName = doc->getShortFileName();
2063 if ( !shortFileName.empty() )
2064 header = shortFileName + _T ( " " );
2065 header += _T ( "(@PAGENUM@/@PAGESCNT@)<hr>" );
2066
2067 htmlPrinting->SetHeader (
2068 header,
2069 wxPAGE_ALL );
2070 statusProgress ( _ ( "Preparing to print..." ) );
2071 wxString htmlBuffer = getHtmlBuffer();
2072 statusProgress ( wxEmptyString );
2073 if ( ! ( htmlPrinting->PrintText ( htmlBuffer ) ) )
2074 {}
2075 }
2076
getHtmlBuffer()2077 wxString MyFrame::getHtmlBuffer()
2078 {
2079 XmlDoc *doc;
2080 if ( ( doc = getActiveDocument() ) == NULL )
2081 return _T ( "<html><head></head><body></body></html>" );
2082 wxString buffer, htmlBuffer;
2083 buffer = doc->GetText();
2084 size_t size = buffer.size();
2085 htmlBuffer.reserve ( size * 2 );
2086
2087 htmlBuffer = _T ( "<html><body><p>" );
2088 bool startOfLine = true;
2089 for ( size_t i = 0; i < size; ++i )
2090 {
2091 wchar_t c = buffer[i];
2092 switch ( c )
2093 {
2094 case L' ':
2095 htmlBuffer += ( startOfLine ) ? _T ( " " ) : _T ( " " );
2096 break;
2097 case L'\t':
2098 htmlBuffer += _T ( " " );
2099 break;
2100 case L'<':
2101 htmlBuffer += _T ( "<" );
2102 startOfLine = false;
2103 break;
2104 case L'>':
2105 htmlBuffer += _T ( ">" );
2106 startOfLine = false;
2107 break;
2108 case L'\n':
2109 htmlBuffer += _T ( "<br>" );
2110 startOfLine = true;
2111 break;
2112 case L'&':
2113 htmlBuffer + _T ( "&" );
2114 startOfLine = false;
2115 break;
2116 default:
2117 htmlBuffer += c;
2118 startOfLine = false;
2119 break;
2120 }
2121 }
2122 htmlBuffer += _T ( "</p></body></html>" );
2123 return htmlBuffer;
2124 }
2125
OnFind(wxCommandEvent & WXUNUSED (event))2126 void MyFrame::OnFind ( wxCommandEvent& WXUNUSED ( event ) )
2127 {
2128 #ifdef NEWFINDREPLACE
2129 manager.GetPane ( findReplacePanel ).Caption ( _ ( "Find" ) );
2130 bool visible = manager.GetPane ( findReplacePanel ).IsShown();
2131 if ( !visible )
2132 {
2133 manager.GetPane ( findReplacePanel ).Show();
2134 }
2135 manager.Update();
2136 findReplacePanel->refresh();
2137 findReplacePanel->setReplaceVisible ( false );
2138 findReplacePanel->focusOnFind();
2139 return;
2140 #endif
2141
2142 findDialog.reset ( new wxFindReplaceDialog (
2143 this,
2144 &findData,
2145 _ ( "Find" ) ) );
2146 findDialog->Show();
2147 }
2148
OnImportMSWord(wxCommandEvent & event)2149 void MyFrame::OnImportMSWord ( wxCommandEvent& event )
2150 {
2151 #ifndef __WXMSW__
2152 messagePane ( _ ( "This functionality requires Microsoft Windows" ) );
2153 return;
2154 #endif
2155
2156 boost::scoped_ptr<wxFileDialog> fd ( new wxFileDialog (
2157 this,
2158 _ ( "Import Microsoft Word Document" ),
2159 mLastDir,
2160 _T ( "" ),
2161 _T ( "Microsoft Word (*.doc)|*.doc" ),
2162 #if wxCHECK_VERSION(2,9,0)
2163 wxFD_OPEN | wxFD_FILE_MUST_EXIST
2164 #else
2165 wxOPEN | wxFILE_MUST_EXIST
2166 #endif
2167 ) );
2168 if ( fd->ShowModal() == wxID_CANCEL )
2169 return;
2170
2171 mLastDir = fd->GetDirectory();
2172
2173 wxString path = fd->GetPath();
2174
2175 if ( path == _T ( "" ) )
2176 return;
2177
2178 importMSWord ( path );
2179 }
2180
OnExport(wxCommandEvent & event)2181 void MyFrame::OnExport ( wxCommandEvent& event )
2182 {
2183 statusProgress ( wxEmptyString );
2184 closeMessagePane();
2185
2186 XmlDoc *doc;
2187 if ( ( doc = getActiveDocument() ) == NULL )
2188 return;
2189
2190 wxString testDir = applicationDir + wxFileName::GetPathSeparator() + _T ( "daisy" );
2191 bool downloadLink = !wxDirExists ( testDir );
2192
2193 boost::scoped_ptr<ExportDialog> ed ( new ExportDialog (
2194 this,
2195 exportStylesheet,
2196 exportFolder,
2197 exportQuiet,
2198 exportSuppressOptional,
2199 exportHtml,
2200 exportEpub,
2201 exportRtf,
2202 exportDoc,
2203 exportFullDaisy,
2204 exportMp3Album,
2205 downloadLink ) );
2206 int ret = ed->ShowModal();
2207
2208 if ( ret != wxID_OK )
2209 return;
2210
2211 exportStylesheet = ed->getUrlString();
2212 exportFolder = ed->getFolderString();
2213 exportQuiet = ed->getQuiet();
2214 exportMp3Album = ed->getMp3Album();
2215 exportSuppressOptional = ed->getSuppressOptional();
2216 exportHtml = ed->getHtml();
2217 exportEpub = ed->getEpub();
2218 exportRtf = ed->getRtf();
2219 exportDoc = ed->getDoc();
2220 exportFullDaisy = ed->getFullDaisy();
2221
2222 std::string rawBufferUtf8;
2223 getRawText ( doc, rawBufferUtf8 );
2224 if ( !XmlEncodingHandler::setUtf8 ( rawBufferUtf8 ) )
2225 {
2226 encodingMessage();
2227 return;
2228 }
2229
2230 WrapTempFileName tempFileName ( doc->getFullFileName() );
2231
2232 ofstream rawBufferStream ( tempFileName.name().c_str() );
2233 if ( !rawBufferStream )
2234 return;
2235 rawBufferStream << rawBufferUtf8;
2236 rawBufferStream.close();
2237
2238 wxString tempFile= tempFileName.wideName();
2239
2240 WrapDaisy wd ( this, daisyDir, doc->getFullFileName() );
2241 if ( !wd.run (
2242 tempFile,
2243 exportStylesheet,
2244 exportFolder,
2245 exportQuiet,
2246 exportSuppressOptional,
2247 exportEpub,
2248 exportRtf,
2249 exportDoc,
2250 exportFullDaisy,
2251 exportMp3Album ) )
2252 {
2253 messagePane ( _ ("[b]DAISY export stopped[/b]: ") + wd.getLastError(), CONST_STOP );
2254 return;
2255 }
2256 messagePane ( _ ( "DAISY export completed. Output files are stored in: [b]" ) + exportFolder + _T ( "[/b]." ), CONST_INFO );
2257 }
2258
importMSWord(const wxString & path)2259 void MyFrame::importMSWord ( const wxString& path )
2260 {
2261 #ifndef __WXMSW__
2262 messagePane ( _ ( "This functionality requires Microsoft Windows" ) );
2263 return;
2264 #endif
2265
2266 WrapTempFileName tempFileName ( _T ( "" ) ), swapFileName ( _T ( "" ) );
2267 wxString completeSwapFileName = swapFileName.wideName() + _T ( ".doc" );
2268 if ( !wxCopyFile ( path, completeSwapFileName, true ) )
2269 {
2270 wxString message;
2271 message.Printf ( _ ( "Cannot open [b]%s[/b] for import" ), path.c_str() );
2272 messagePane ( message, CONST_STOP );
2273 return;
2274 }
2275
2276 wxString cmd = binDir +
2277 _T ( "doc2xml.exe \"" ) +
2278 completeSwapFileName + _T ( "\" \"" ) +
2279 tempFileName.wideName() + _T ( "\"" );
2280
2281 statusProgress ( _ ( "Import in progress..." ) );
2282 int result = wxExecute ( cmd, wxEXEC_SYNC );
2283
2284 wxRemoveFile ( completeSwapFileName ); // necessary because .doc extension added
2285
2286 statusProgress ( wxEmptyString );
2287 wxString message;
2288 wxString versionMessage (
2289 _ ( "(lossless conversion requires version 2003 or later)" ) );
2290
2291 switch ( result )
2292 {
2293 case 0:
2294 break;
2295 case 1:
2296 messagePane ( _ ( "Cannot start Microsoft Word" ), CONST_STOP );
2297 return;
2298 case 2:
2299 messagePane (
2300 _ ( "A more recent version of Microsoft Word is required" ), CONST_STOP );
2301 return;
2302 case 3:
2303 message.Printf ( _T ( "Microsoft Word cannot open [b]%s[/b]" ), path.c_str() );
2304 messagePane ( message + path, CONST_STOP );
2305 return;
2306 case 4:
2307 message.Printf ( _ ( "Microsoft Word cannot save [b]%s[/b] as XML" ), path.c_str() );
2308 messagePane ( message, CONST_STOP );
2309 return;
2310 case 5:
2311 messagePane (
2312 _ ( "Microsoft Word cannot save this document as WordprocessingML " ) +
2313 versionMessage,
2314 CONST_INFO );
2315 break;
2316 default:
2317 break;
2318 }
2319
2320 statusProgress ( _ ( "Opening imported file..." ) );
2321 std::string buffer;
2322
2323 wxString displayBuffer;
2324
2325 if ( result != 5 ) // Word 2003 or later
2326 {
2327 boost::scoped_ptr<WrapLibxml> prettyPrinter ( new WrapLibxml ( libxmlNetAccess ) );
2328 prettyPrinter->parse ( tempFileName.wideName(), true );
2329 buffer = prettyPrinter->getOutput();
2330 displayBuffer = wxString ( buffer.c_str(), wxConvUTF8, buffer.size() );
2331 }
2332 else // earlier versions
2333 {
2334 if ( !ReadFile::run ( tempFileName.name(), buffer ) )
2335 {
2336 statusProgress ( wxEmptyString );
2337 messagePane ( _ ( "Cannot open imported file" ), CONST_STOP );
2338 return;
2339 }
2340 displayBuffer = wxString ( buffer.c_str(), wxConvUTF8, buffer.size() );
2341 displayBuffer.Remove ( 0, 1 ); // remove byte order mark
2342 xmliseWideTextNode ( displayBuffer );
2343
2344 displayBuffer.Prepend (
2345 _T ( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>" ) );
2346 displayBuffer.Append ( _T ( "</root>\n" ) );
2347 }
2348
2349 newDocument ( displayBuffer, tempFileName.wideName() );
2350 statusProgress ( wxEmptyString );
2351 }
2352
OnExportMSWord(wxCommandEvent & event)2353 void MyFrame::OnExportMSWord ( wxCommandEvent& event )
2354 {
2355 #ifndef __WXMSW__
2356 messagePane ( _ ( "This functionality requires Microsoft Windows" ) );
2357 return;
2358 #endif
2359 statusProgress ( wxEmptyString );
2360
2361 // fetch document contents
2362 XmlDoc *doc;
2363 if ( ( doc = getActiveDocument() ) == NULL )
2364 return;
2365
2366 WrapTempFileName wtfn ( _T ( "" ) );
2367 wxString sourceFileName = doc->getFullFileName();
2368
2369 if ( doc->getDirectory().empty() )
2370 {
2371 sourceFileName = wtfn.wideName();
2372 std::fstream ofs ( wtfn.name().c_str() );
2373 if ( !ofs )
2374 return;
2375
2376 std::string utf8Buffer;
2377 getRawText ( doc, utf8Buffer );
2378 ofs << utf8Buffer;
2379 ofs.close();
2380 }
2381 else if ( doc->GetModify() ) //CanUndo())
2382 {
2383 modifiedMessage();
2384 return;
2385 }
2386
2387 boost::scoped_ptr<wxFileDialog> fd ( new wxFileDialog (
2388 this,
2389 _ ( "Export Microsoft Word Document" ),
2390 _T ( "" ),
2391 _T ( "" ),
2392 _T ( "Microsoft Word (*.doc)|*.doc" ),
2393 #if wxCHECK_VERSION(2,9,0)
2394 wxFD_SAVE | wxFD_OVERWRITE_PROMPT));
2395 #else
2396 wxSAVE | wxOVERWRITE_PROMPT ) );
2397 #endif
2398 fd->ShowModal();
2399
2400 wxString path = fd->GetPath();
2401
2402 if ( path == _T ( "" ) )
2403 return;
2404
2405 wxString cmd = binDir +
2406 _T ( "xml2doc.exe -v \"" ) +
2407 sourceFileName + _T ( "\" \"" ) +
2408 path + _T ( "\"" );
2409
2410 statusProgress ( _ ( "Export in progress..." ) );
2411 int result = wxExecute ( cmd, wxEXEC_SYNC );
2412 statusProgress ( wxEmptyString );
2413 wxString message;
2414 switch ( result )
2415 {
2416 case 1:
2417 messagePane ( _ ( "Cannot start Microsoft Word" ), CONST_STOP );
2418 return;
2419 case 2:
2420 messagePane (
2421 _ ( "A more recent version of Microsoft Word is required" ), CONST_STOP );
2422 return;
2423 case 3:
2424 message.Printf ( _ ( "Microsoft Word cannot save %s" ), path.c_str() );
2425 messagePane ( message, CONST_STOP );
2426 return;
2427 case 0:
2428 break;
2429 default:
2430 break;
2431 }
2432 }
2433
OnBrowser(wxCommandEvent & WXUNUSED (event))2434 void MyFrame::OnBrowser ( wxCommandEvent& WXUNUSED ( event ) )
2435 {
2436 statusProgress ( wxEmptyString );
2437
2438 // fetch document contents
2439 XmlDoc *doc;
2440 if ( ( doc = getActiveDocument() ) == NULL )
2441 return;
2442
2443 wxString sourceFileName = doc->getFullFileName();
2444 WrapTempFileName wtfn ( sourceFileName, _T ( ".html" ) );
2445
2446 if ( doc->getDirectory().empty() || doc->GetModify() )
2447 {
2448 sourceFileName = wtfn.wideName();
2449
2450 std::ofstream ofs ( ( const char * ) wtfn.name().c_str() );
2451 if ( !ofs )
2452 {
2453 messagePane ( _ ( "Cannot save temporary file" ), CONST_STOP );
2454 return;
2455 }
2456
2457 std::string utf8Buffer;
2458 getRawText ( doc, utf8Buffer );
2459 ofs << utf8Buffer;
2460 ofs.close();
2461
2462 // keep files until application closes
2463 tempFileVector.push_back ( sourceFileName );
2464 tempFileVector.push_back ( wtfn.originalWideName() );
2465 wtfn.setKeepFiles ( true );
2466 }
2467
2468 wxLaunchDefaultBrowser ( sourceFileName, wxBROWSER_NEW_WINDOW );
2469 }
2470
OnHelp(wxCommandEvent & event)2471 void MyFrame::OnHelp ( wxCommandEvent& event )
2472 {
2473 #ifdef __WXMSW__
2474 wxString cmd = _T ( "hh.exe \"" ) + helpDir + _T ( "xmlcopyeditor.chm\"" );
2475 wxExecute ( cmd );
2476 #else
2477 wxString helpFileName = helpDir + _T ( "xmlcopyeditor.hhp" );
2478 helpController->AddBook ( wxFileName ( helpFileName ) );
2479 helpController->DisplayContents();
2480 #endif
2481 }
2482
OnSplitTab(wxCommandEvent & event)2483 void MyFrame::OnSplitTab ( wxCommandEvent& event )
2484 {
2485 /*
2486 int id = event.GetId();
2487 XmlDoc *doc = getActiveDocument();
2488 if ( !doc )
2489 return;
2490 wxString fileName = doc->getFullFileName();
2491
2492 // mainBook->GetSelection() is currently unreliable, so fetch by title
2493
2494 int pageCount = mainBook->GetPageCount();
2495 XmlDoc *currentDoc;
2496 int currentSelection = -1;
2497 for ( int i = 0; i < pageCount; ++i )
2498 {
2499 currentDoc = ( XmlDoc * ) mainBook->GetPage ( i );
2500 if ( !currentDoc )
2501 break;
2502 if ( currentDoc->getFullFileName() == fileName )
2503 {
2504 currentSelection = i;
2505 }
2506 }
2507 if ( currentSelection == -1 )
2508 return;
2509 */
2510 int currentSelection, direction;
2511 currentSelection = mainBook->GetSelection();
2512 direction = wxAUI_NB_RIGHT;
2513 /*
2514 switch ( id )
2515 {
2516 ID_SPLIT_TAB_TOP:
2517 direction = wxAUI_NB_TOP;
2518 break;
2519 ID_SPLIT_TAB_RIGHT:
2520 direction = wxAUI_NB_RIGHT;
2521 break;
2522 ID_SPLIT_TAB_BOTTOM:
2523 direction = wxAUI_NB_BOTTOM;
2524 break;
2525 ID_SPLIT_TAB_LEFT:
2526 direction = wxAUI_NB_LEFT;
2527 break;
2528 default:
2529 direction = wxAUI_NB_RIGHT;
2530 break;
2531 }
2532 */
2533 mainBook->Split ( currentSelection, direction );
2534 }
2535
OnColorScheme(wxCommandEvent & event)2536 void MyFrame::OnColorScheme ( wxCommandEvent& event )
2537 {
2538 int id = event.GetId();
2539 switch ( id )
2540 {
2541 case ID_COLOR_SCHEME_DEFAULT:
2542 properties.colorScheme = COLOR_SCHEME_DEFAULT;
2543 break;
2544 case ID_COLOR_SCHEME_DEFAULT_BACKGROUND:
2545 properties.colorScheme = COLOR_SCHEME_DEFAULT_BACKGROUND;
2546 break;
2547 case ID_COLOR_SCHEME_REDUCED_GLARE:
2548 properties.colorScheme = COLOR_SCHEME_REDUCED_GLARE;
2549 break;
2550 case ID_COLOR_SCHEME_NONE:
2551 properties.colorScheme = COLOR_SCHEME_NONE;
2552 break;
2553 default:
2554 return;
2555 }
2556 colorSchemeMenu->Check ( id, true );
2557
2558 XmlDoc *doc;
2559 if ( ( doc = getActiveDocument() ) == NULL )
2560 return;
2561
2562 properties.zoom = doc->GetZoom(); // ensure temp changes to font size are kept
2563
2564 applyEditorProperties ( false );
2565 doc->SetFocus();
2566 }
2567
OnFontSmaller(wxCommandEvent & event)2568 void MyFrame::OnFontSmaller ( wxCommandEvent& event )
2569 {
2570 XmlDoc *doc;
2571 if ( ( doc = getActiveDocument() ) == NULL )
2572 return;
2573 doc->ZoomOut();
2574 properties.zoom = doc->GetZoom();
2575 applyEditorProperties ( true );
2576 doc->SetFocus();
2577 }
2578
OnFontMedium(wxCommandEvent & event)2579 void MyFrame::OnFontMedium ( wxCommandEvent& event )
2580 {
2581 XmlDoc *doc;
2582 if ( ( doc = getActiveDocument() ) == NULL )
2583 return;
2584 doc->SetZoom ( 0 );
2585 properties.zoom = doc->GetZoom();
2586 applyEditorProperties ( true );
2587 doc->SetFocus();
2588 }
2589
OnFontLarger(wxCommandEvent & event)2590 void MyFrame::OnFontLarger ( wxCommandEvent& event )
2591 {
2592 XmlDoc *doc;
2593 if ( ( doc = getActiveDocument() ) == NULL )
2594 return;
2595 doc->ZoomIn();
2596 properties.zoom = doc->GetZoom();
2597 applyEditorProperties ( true );
2598 doc->SetFocus();
2599 }
2600
OnOptions(wxCommandEvent & WXUNUSED (event))2601 void MyFrame::OnOptions ( wxCommandEvent& WXUNUSED ( event ) )
2602 {
2603 // ensure font size does not change after
2604 XmlDoc *doc = getActiveDocument();
2605 if ( doc )
2606 {
2607 properties.zoom = doc->GetZoom();
2608 }
2609
2610 wxString title
2611 #ifdef __WXMSW__
2612 ( _ ( "Options" ) );
2613 #else
2614 ( _ ( "Preferences" ) );
2615 #endif
2616 boost::scoped_ptr<MyPropertySheet> mpsd ( new MyPropertySheet (
2617 this,
2618 properties,
2619 applicationDir,
2620 rememberOpenTabs,
2621 libxmlNetAccess,
2622 singleInstanceCheck,
2623 saveBom,
2624 unlimitedUndo,
2625 restoreLayout,
2626 expandInternalEntities,
2627 showFullPathOnFrame,
2628 lang,
2629 wxGetApp().getAvailableTranslations(),
2630 wxID_ANY,
2631 title ) );
2632 if ( mpsd->ShowModal() == wxID_OK )
2633 {
2634 WrapXerces::enableNetwork ( libxmlNetAccess );
2635 applyEditorProperties();
2636 updatePaths();
2637 }
2638 if ( doc )
2639 doc->SetFocus();
2640 }
2641
OnHistoryFile(wxCommandEvent & event)2642 void MyFrame::OnHistoryFile ( wxCommandEvent& event )
2643 {
2644 wxString f ( history.GetHistoryFile ( event.GetId() - wxID_FILE1 ) );
2645 if ( !f.empty() )
2646 openFile ( f );
2647 }
2648
OnGoto(wxCommandEvent & WXUNUSED (event))2649 void MyFrame::OnGoto ( wxCommandEvent& WXUNUSED ( event ) )
2650 {
2651 statusProgress ( wxEmptyString );
2652
2653 XmlDoc *doc;
2654 if ( ( doc = getActiveDocument() ) == NULL )
2655 return;
2656
2657 wxTextEntryDialog *dlg = new wxTextEntryDialog (
2658 this,
2659 _ ( "Enter line number:" ),
2660 _ ( "Go To" ) );
2661 int ret = dlg->ShowModal();
2662 if ( ret == wxID_CANCEL )
2663 return;
2664 wxString val = dlg->GetValue();
2665 long line;
2666 if ( !val.ToLong ( &line ) || line < 1 )
2667 {
2668 wxString msg;
2669 msg.Printf ( _ ( "'%s' is not a valid line number" ), val.c_str() );
2670 messagePane ( msg, CONST_STOP );
2671 return;
2672 }
2673 --line;
2674 doc->GotoLine ( ( int ) line );
2675 doc->SetFocus();
2676 }
2677
OnFindAgain(wxCommandEvent & event)2678 void MyFrame::OnFindAgain ( wxCommandEvent& event )
2679 {
2680 //findAgain(findData.GetFindString(), findData.GetFlags());
2681 findReplacePanel->OnFindNext ( event );
2682 }
2683
OnCommand(wxCommandEvent & WXUNUSED (event))2684 void MyFrame::OnCommand ( wxCommandEvent& WXUNUSED ( event ) )
2685 {
2686 bool visible = manager.GetPane ( commandPanel ).IsShown();
2687 if ( !visible )
2688 {
2689 manager.GetPane ( commandPanel ).Show();
2690 }
2691 manager.Update();
2692 commandPanel->focusOnCommand();
2693 }
2694
OnFindReplace(wxCommandEvent & WXUNUSED (event))2695 void MyFrame::OnFindReplace ( wxCommandEvent& WXUNUSED ( event ) )
2696 {
2697 #ifdef NEWFINDREPLACE
2698 manager.GetPane ( findReplacePanel ).Caption ( _ ( "Replace" ) );
2699 bool visible = manager.GetPane ( findReplacePanel ).IsShown();
2700 if ( !visible )
2701 {
2702 manager.GetPane ( findReplacePanel ).Show();
2703 }
2704 manager.Update();
2705 findReplacePanel->refresh();
2706 findReplacePanel->setReplaceVisible ( true );
2707 findReplacePanel->focusOnFind();
2708 return;
2709 #endif
2710
2711
2712 findDialog.reset ( new wxFindReplaceDialog (
2713 this,
2714 &findData,
2715 _ ( "Find and Replace" ),
2716 wxFR_REPLACEDIALOG ) );
2717 findDialog->Show();
2718 }
2719
OnGlobalReplace(wxCommandEvent & event)2720 void MyFrame::OnGlobalReplace ( wxCommandEvent& event )
2721 {
2722 if ( getActiveDocument() == NULL )
2723 return;
2724
2725 size_t flags = findData.GetFlags();
2726 boost::scoped_ptr<GlobalReplaceDialog> grd ( new GlobalReplaceDialog (
2727 this,
2728 findData.GetFindString(),
2729 findData.GetReplaceString(),
2730 flags & wxFR_MATCHCASE,
2731 globalReplaceAllDocuments,
2732 findRegex ) );
2733 int res = grd->ShowModal();
2734
2735 flags = 0;
2736 flags |= wxFR_DOWN;
2737 if ( grd->getMatchCase() )
2738 flags |= wxFR_MATCHCASE;
2739 findRegex = grd->getRegex();
2740 globalReplaceAllDocuments = grd->getAllDocuments();
2741
2742 findData.SetFindString ( grd->getFindString() );
2743 findData.SetReplaceString ( grd->getReplaceString() );
2744 findData.SetFlags ( flags );
2745 findReplacePanel->setRegex ( findRegex );
2746 findReplacePanel->setMatchCase ( flags & wxFR_MATCHCASE );
2747 findReplacePanel->refresh();
2748
2749 if ( res != wxID_OK )
2750 {
2751 return;
2752 }
2753
2754 int globalMatchCount, pageCount;
2755 globalMatchCount = 0;
2756 pageCount = mainBook->GetPageCount();
2757 XmlDoc *currentDoc = getActiveDocument();
2758 if ( !currentDoc )
2759 return;
2760
2761 for ( int i = 0; i < pageCount; ++i )
2762 {
2763 std::string bufferUtf8;
2764 if ( !globalReplaceAllDocuments )
2765 {
2766 getRawText ( currentDoc, bufferUtf8 );
2767 }
2768 else
2769 {
2770 currentDoc = ( XmlDoc * ) mainBook->GetPage ( i );
2771 if ( !currentDoc )
2772 return;
2773 getRawText ( currentDoc, bufferUtf8 );
2774 }
2775
2776 size_t flags = findData.GetFlags();
2777 if ( !findRegex )
2778 {
2779 std::string findUtf8, replaceUtf8;
2780 findUtf8 =findData.GetFindString().mb_str ( wxConvUTF8 );
2781 replaceUtf8 = findData.GetReplaceString().mb_str ( wxConvUTF8 );
2782 globalMatchCount += Replace::run (
2783 bufferUtf8,
2784 findUtf8,
2785 replaceUtf8,
2786 flags & wxFR_MATCHCASE );
2787 currentDoc->SetTextRaw ( bufferUtf8.c_str() );
2788 currentDoc->setValidationRequired ( true );
2789 }
2790 else
2791 {
2792 try
2793 {
2794 boost::scoped_ptr<WrapRegex> wr ( new WrapRegex (
2795 ( const char * ) findData.GetFindString().mb_str ( wxConvUTF8 ),
2796 flags & wxFR_MATCHCASE,
2797 ( const char * ) findData.GetReplaceString().mb_str ( wxConvUTF8 ) ) );
2798
2799 int matchCount;
2800 std::string outputBuffer = wr->replaceGlobal ( bufferUtf8, &matchCount );
2801 globalMatchCount += matchCount;
2802 currentDoc->SetTextRaw ( outputBuffer.c_str() );
2803 currentDoc->setValidationRequired ( true );
2804 }
2805 catch ( std::exception& e )
2806 {
2807 wxString wideError = wxString ( e.what(), wxConvUTF8, strlen ( e.what() ) );
2808 messagePane ( _ ( "Cannot replace: " ) + wideError, CONST_STOP );
2809 return;
2810 }
2811 }
2812 if ( !globalReplaceAllDocuments )
2813 break;
2814 }
2815 wxString msg;
2816
2817 msg.Printf (
2818 wxPLURAL ( "%i replacement made", "%i replacements made", globalMatchCount ),
2819 globalMatchCount );
2820
2821 statusProgress ( msg );
2822 }
2823
OnToggleComment(wxCommandEvent & event)2824 void MyFrame::OnToggleComment ( wxCommandEvent& event )
2825 {
2826 XmlDoc *doc = getActiveDocument();
2827 if ( doc == NULL )
2828 return;
2829
2830 wxBusyCursor cursor;
2831 doc->toggleComment();
2832 }
2833
OnFrameClose(wxCloseEvent & event)2834 void MyFrame::OnFrameClose ( wxCloseEvent& event )
2835 {
2836 wxCommandEvent e;
2837 OnCloseAll ( e );
2838 if ( mainBook->GetPageCount() )
2839 {
2840 event.Veto();
2841 return;
2842 }
2843 event.Skip();
2844 }
2845
OnNew(wxCommandEvent & WXUNUSED (event))2846 void MyFrame::OnNew ( wxCommandEvent& WXUNUSED ( event ) )
2847 {
2848 wxString defaultSelection, typeSelection, templateFile;
2849 defaultSelection = _ ( "XML document (*.xml)" );
2850 if ( wxDirExists ( templateDir ) )
2851 {
2852 wxArrayString templateArray;
2853 wxString templateMask, name, extension, entry;
2854 wxFileName fn;
2855 templateMask = templateDir + wxFileName::GetPathSeparator() + _T ( "*.*" );
2856 templateFile = wxFindFirstFile ( templateMask, wxFILE );
2857 while ( !templateFile.empty() )
2858 {
2859 templateFile.Replace ( _T("_"), _T(" ") );
2860 fn.Assign ( templateFile );
2861 name = fn.GetName();
2862 extension = fn.GetExt();
2863
2864 entry.Printf ( _T ( "%s (*.%s)" ), name.c_str(), extension.c_str() );
2865 templateArray.Add ( entry );
2866
2867 templateFile = wxFindNextFile();
2868 }
2869 templateArray.Sort();
2870 templateArray.Insert ( defaultSelection, 0 );
2871
2872 wxSingleChoiceDialog scd (
2873 this, _ ( "Choose a document type:" ), _ ( "New Document" ), templateArray );
2874 if ( scd.ShowModal() == wxID_CANCEL )
2875 {
2876 XmlDoc *doc = getActiveDocument();
2877 if ( doc )
2878 doc->SetFocus();
2879 return;
2880 }
2881 typeSelection = scd.GetStringSelection();
2882 }
2883
2884 if ( typeSelection == defaultSelection )
2885 {
2886 wxString emptyString ( _T ( "" ) );
2887 newDocument ( emptyString );
2888 return;
2889 }
2890
2891 typeSelection.Replace ( _T ( " (*" ), wxEmptyString );
2892 typeSelection.Replace ( _T ( ")" ), wxEmptyString );
2893 typeSelection.Replace ( _T ( " " ), _T ( "_" ) );
2894 templateFile = templateDir + typeSelection;
2895 std::string templateFileLocal, buffer;
2896 templateFileLocal = templateFile.mb_str ( wxConvLocal );
2897 ReadFile::run ( templateFileLocal, buffer );
2898 wxString documentContents = wxString ( buffer.c_str(), wxConvUTF8, buffer.size() );
2899
2900 newDocument ( buffer, templateFile );
2901 }
2902
newDocument(const wxString & s,const wxString & path,bool canSave)2903 void MyFrame::newDocument ( const wxString& s, const wxString& path, bool canSave )
2904 {
2905 std::string bufferUtf8 = ( const char * ) s.mb_str ( wxConvUTF8 );
2906 newDocument ( bufferUtf8, path, canSave );
2907 }
2908
newDocument(const std::string & s,const wxString & path,bool canSave)2909 void MyFrame::newDocument ( const std::string& s, const wxString& path, bool canSave )
2910 {
2911 XmlDoc *doc;
2912
2913 wxString documentLabel;
2914 documentLabel.Printf ( _ ( "Document%i" ), documentCount++ );
2915
2916 wxString auxPath = getAuxPath ( path );
2917
2918 {
2919 wxWindowUpdateLocker noupdate (this);
2920
2921 doc = ( s.empty() ) ?
2922 new XmlDoc (
2923 mainBook,
2924 properties,
2925 &protectTags,
2926 visibilityState,
2927 FILE_TYPE_XML,
2928 wxID_ANY,
2929 NULL, 0 // new: NULL pointer leads to default document
2930 )
2931 : new XmlDoc (
2932 mainBook,
2933 properties,
2934 &protectTags,
2935 visibilityState,
2936 FILE_TYPE_XML,
2937 wxID_ANY,
2938 s.c_str(), // modified
2939 s.size(), // new
2940 path,
2941 auxPath );
2942 mainBook->AddPage ( ( wxWindow * ) doc, documentLabel );
2943 }
2944
2945 mainBook->Layout();
2946
2947 if ( properties.completion )
2948 doc->updatePromptMaps();
2949 doc->setShortFileName ( documentLabel );
2950 doc->SetFocus();
2951 manager.Update();
2952 if ( properties.validateAsYouType )
2953 doc->backgroundValidate();
2954 }
2955
OnOpen(wxCommandEvent & event)2956 void MyFrame::OnOpen ( wxCommandEvent& event )
2957 {
2958 bool largeFile;
2959 largeFile = ( event.GetId() == ID_OPEN_LARGE_FILE );
2960
2961 wxString file = event.GetString();
2962 if ( !file.empty() )
2963 {
2964 openFile ( file );
2965 return;
2966 }
2967
2968 wxString defaultFile, defaultDir;
2969 XmlDoc *doc;
2970 if ( ( doc = getActiveDocument() ) != NULL )
2971 {
2972 defaultDir = doc->getDirectory();
2973 if ( defaultDir.empty() )
2974 defaultDir = mLastDir;
2975 }
2976 else
2977 defaultDir = mLastDir;
2978
2979 wxFileDialog fd (
2980 this,
2981 ( largeFile ) ? _ ( "Open Large Document" ) : _ ( "Open" ),
2982 defaultDir,
2983 wxEmptyString,
2984 FILE_FILTER,
2985 #if wxCHECK_VERSION(2,9,0)
2986 wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST
2987 #else
2988 wxOPEN | wxMULTIPLE | wxFILE_MUST_EXIST
2989 #endif
2990 );
2991
2992
2993 if ( fd.ShowModal() == wxID_CANCEL )
2994 return;
2995
2996 mLastDir = fd.GetDirectory();
2997
2998 wxArrayString paths;
2999 fd.GetPaths ( paths );
3000 size_t count = paths.Count();
3001 if ( !count )
3002 return;
3003 for ( size_t i = 0; i < count; ++i )
3004 if ( !openFile ( paths[i], largeFile ) )
3005 break;
3006 }
3007
openFile(const wxString & file,bool largeFile)3008 bool MyFrame::openFile ( const wxString &file, bool largeFile )
3009 {
3010 wxFileName fn = WrapLibxml::URLToFileName ( file );
3011 fn.Normalize();
3012
3013 wxString fileName = fn.GetFullPath();
3014 if ( !fn.IsFileReadable() )
3015 {
3016 wxString message;
3017 message.Printf ( _ ( "Cannot open %s." ), fileName.c_str() );
3018 messagePane ( message, CONST_STOP );
3019 return false;
3020 }
3021
3022 if ( openFileSet.count ( fileName ) )
3023 {
3024 wxString message;
3025 message.Printf ( _ ( "%s is already open" ), fileName.c_str() );
3026 statusProgress ( message );
3027 activateTab ( fileName );
3028 return false;
3029 }
3030
3031 wxString wideError;
3032 pair<int, int> posPair;
3033 XmlDoc *doc;
3034
3035 int type = getFileType ( fileName );
3036 wxString auxPath = getAuxPath ( fileName );
3037
3038 char *docBuffer = NULL;
3039 size_t docBufferLen = 0;
3040 bool fileEmpty = false;
3041
3042 statusProgress ( _T ( "Opening file..." ) );
3043 BinaryFile binaryfile ( fileName );
3044 if ( !binaryfile.getData() )
3045 {
3046 wxString message;
3047 message.Printf ( _ ( "Cannot open %s" ), fileName.c_str() );
3048 messagePane ( message, CONST_STOP );
3049 statusProgress ( wxEmptyString );
3050 return false;
3051 }
3052 /*
3053 //wxMemoryMappedFile memorymap (
3054 fileName,
3055 true, // readOnly
3056 true // fread
3057 );
3058 */
3059
3060 /*
3061 catch (wxMemoryMappedFileEmptyException&)
3062 {
3063 fileEmpty = true;
3064 }
3065 */
3066
3067 bool isUtf8 = false;
3068
3069 if ( !fileEmpty )
3070 {
3071 docBuffer = ( char * ) binaryfile.getData();//memorymap->GetStream();
3072 docBufferLen = binaryfile.getDataLen();//memorymap->GetMapSize();
3073 }
3074 else
3075 {
3076 docBuffer = NULL;
3077 docBufferLen = 0;
3078 isUtf8 = true;
3079 }
3080
3081 statusProgress ( wxEmptyString );
3082
3083 wxCharBuffer iconvBuffer;
3084 size_t iconvBufferLen = 0;
3085
3086 char *finalBuffer;
3087 size_t finalBufferLen;
3088
3089 std::string encoding;
3090 if ( docBufferLen >= 4 && // UTF-32 BE
3091 ( unsigned char ) docBuffer[0] == 0x00 &&
3092 ( unsigned char ) docBuffer[1] == 0x00 &&
3093 ( unsigned char ) docBuffer[2] == 0xFE &&
3094 ( unsigned char ) docBuffer[3] == 0xFF )
3095 {
3096 docBuffer += 4;
3097 docBufferLen -= 4;
3098 encoding = "UTF-32BE";
3099 }
3100 else if ( docBufferLen >= 4 && // UTF-32 LE
3101 ( unsigned char ) docBuffer[0] == 0xFF &&
3102 ( unsigned char ) docBuffer[1] == 0xFE &&
3103 ( unsigned char ) docBuffer[2] == 0x00 &&
3104 ( unsigned char ) docBuffer[3] == 0x00 )
3105 {
3106 docBuffer += 4;
3107 docBufferLen -= 4;
3108 encoding = "UTF-32LE";
3109 }
3110 else if ( docBufferLen >= 2 && //UTF-16 BE
3111 ( unsigned char ) docBuffer[0] == 0xFE &&
3112 ( unsigned char ) docBuffer[1] == 0xFF )
3113 {
3114 docBuffer += 2;
3115 docBufferLen -= 2;
3116 encoding = "UTF-16BE";
3117 }
3118 else if ( docBufferLen >= 2 && //UTF-16 LE
3119 ( unsigned char ) docBuffer[0] == 0xFF &&
3120 ( unsigned char ) docBuffer[1] == 0xFE )
3121 {
3122 docBuffer += 2;
3123 docBufferLen -= 2;
3124 encoding = "UTF-16LE";
3125 }
3126 else if ( docBufferLen >= 3 && //UTF-8
3127 ( unsigned char ) docBuffer[0] == 0xEF &&
3128 ( unsigned char ) docBuffer[1] == 0xBB &&
3129 ( unsigned char ) docBuffer[2] == 0xBF )
3130 {
3131 docBuffer += 3;
3132 docBufferLen -= 3;
3133 encoding = "UTF-8";
3134 }
3135
3136 if ( encoding.empty() )
3137 {
3138 XmlEncodingSpy es;
3139 es.parse ( docBuffer, docBufferLen );
3140 encoding = es.getEncoding();
3141 if ( encoding.empty() ) // Expat couldn't parse file (e.g. UTF-32)
3142 {
3143 encoding = getApproximateEncoding ( docBuffer, docBufferLen );
3144 if ( encoding.empty() )
3145 encoding = "UTF-8";
3146 }
3147 }
3148
3149 // convert buffer if not UTF-8
3150 if ( encoding == "UTF-8" ||
3151 encoding == "utf-8" ||
3152 encoding == "US-ASCII" ||
3153 encoding == "us-ascii" || // US-ASCII is a subset of UTF-8
3154 docBufferLen == 0 )
3155 {
3156 finalBuffer = docBuffer;
3157 finalBufferLen = docBufferLen;
3158 isUtf8 = true;
3159 }
3160 else
3161 {
3162 wxString wideEncoding = wxString (
3163 encoding.c_str(),
3164 wxConvLocal,
3165 encoding.size() );
3166 iconv_t cd = iconv_open ( "UTF-8", encoding.c_str() );
3167 if ( cd == ( iconv_t )-1 )
3168 {
3169 wxString message;
3170 message.Printf ( _ ( "Cannot open %s: unknown encoding %s" ),
3171 fileName.c_str(),
3172 wideEncoding.c_str() );
3173 messagePane ( message, CONST_STOP );
3174 return false;
3175 };
3176
3177 int iconvLenMultiplier = 4; // worst case scenario
3178 if ( encoding == "ISO-8859-1" ||
3179 encoding == "UTF-16" ||
3180 encoding == "UTF-16BE" ||
3181 encoding == "UTF-16LE" )
3182 {
3183 iconvLenMultiplier = 2;
3184 }
3185 else if ( encoding == "UTF-32" ||
3186 encoding == "UTF-32BE" ||
3187 encoding == "UTF-32LE" )
3188 {
3189 iconvLenMultiplier = 1;
3190 }
3191
3192 size_t nconv;
3193 char *buffer;
3194 size_t iconvBufferLeft, docBufferLeft;
3195 iconvBufferLen = iconvBufferLeft = docBufferLen * iconvLenMultiplier + 1;
3196 docBufferLeft = docBufferLen;
3197 if ( ( ( ( size_t ) -1 ) - 1 ) / iconvLenMultiplier < docBufferLen
3198 || !iconvBuffer.extend ( iconvBufferLen ) )
3199 {
3200 wxString message;
3201 message.Printf ( _ ( "Cannot open %s: out of memory" ),
3202 fileName.c_str() );
3203 messagePane ( message, CONST_STOP );
3204 statusProgress ( wxEmptyString );
3205 return false;
3206 }
3207 finalBuffer = buffer = iconvBuffer.data(); // buffer will be incremented by iconv
3208 nconv = reinterpret_cast < universal_iconv & > ( iconv ) (
3209 cd,
3210 &docBuffer,
3211 &docBufferLeft,
3212 &buffer,
3213 &iconvBufferLeft );
3214
3215 *buffer = '\0';
3216
3217 iconv_close ( cd );
3218
3219 if ( nconv == ( size_t )-1 )
3220 {
3221 wxString message;
3222 message.Printf ( _ ( "Cannot open %s: conversion from encoding %s failed" ),
3223 fileName.c_str(),
3224 wideEncoding.c_str() );
3225 messagePane ( message, CONST_STOP );
3226 return false;
3227 }
3228 finalBufferLen = iconvBufferLen - iconvBufferLeft;
3229 }
3230
3231 statusProgress ( _ ( "Creating document view..." ) );
3232 {
3233 wxWindowUpdateLocker noupdate ( this );
3234
3235 doc = new XmlDoc (
3236 mainBook,
3237 ( largeFile ) ? largeFileProperties: properties,
3238 &protectTags,
3239 visibilityState,
3240 ( !binaryfile.getDataLen() ) ? FILE_TYPE_XML : type,
3241 wxID_ANY,
3242 finalBuffer,
3243 finalBufferLen,
3244 fileName,
3245 auxPath );
3246 #ifdef __WXMSW__
3247 doc->SetUndoCollection ( false );
3248 doc->SetUndoCollection ( true );
3249 #endif
3250
3251 doc->setFullFileName ( fileName );
3252 openFileSet.insert ( fileName );
3253 history.AddFileToHistory ( fileName );
3254 updateFileMenu();
3255
3256 mainBook->AddPage ( ( wxWindow * ) doc, fn.GetFullName(), _T ( "" ) );
3257 }
3258 statusProgress ( wxEmptyString );
3259
3260 mainBook->Layout();
3261
3262 doc->setLastModified ( fn.GetModificationTime() );
3263 doc->SetFocus();
3264
3265 if ( type != FILE_TYPE_XML || !binaryfile.getDataLen() )
3266 {
3267 return true;
3268 }
3269
3270 // NOW parse the document, but don't create a UTF-8 copy
3271 statusProgress ( _T ( "Parsing document..." ) );
3272 boost::scoped_ptr<WrapExpat> we ( new WrapExpat() );
3273
3274 // omit XML declaration
3275 if ( !isUtf8 && finalBufferLen > 5 &&
3276 finalBuffer[0] == '<' &&
3277 finalBuffer[1] == '?' &&
3278 finalBuffer[2] == 'x' &&
3279 finalBuffer[3] == 'm' &&
3280 finalBuffer[4] == 'l' )
3281 {
3282 for ( ; *finalBuffer && finalBufferLen; finalBuffer++ && finalBufferLen-- )
3283 {
3284 if ( *finalBuffer == '>' )
3285 {
3286 finalBuffer++;
3287 finalBufferLen--;
3288 break;
3289 }
3290 }
3291 }
3292
3293 bool optimisedParseSuccess = false;
3294 if ( finalBuffer )
3295 {
3296 optimisedParseSuccess = we->parse ( finalBuffer, finalBufferLen );
3297 statusProgress ( wxEmptyString );
3298 }
3299
3300 // NOW update prompt maps if necessary
3301 if ( !largeFile && ( properties.completion || properties.validateAsYouType ) )
3302 {
3303 statusProgress ( _T ( "Compiling autocompletion lists..." ) );
3304 doc->updatePromptMaps ( finalBuffer, finalBufferLen );
3305 statusProgress ( wxEmptyString );
3306 }
3307
3308 if ( !largeFile && ( properties.validateAsYouType && doc->getGrammarFound() ) )
3309 {
3310 statusProgress ( _T ( "Validating document..." ) );
3311 //doc->backgroundValidate ( finalBuffer, doc->getFullFileName().mb_str(wxConvUTF8), finalBufferLen );
3312 doc->backgroundValidate();
3313 statusProgress ( wxEmptyString );
3314 }
3315
3316 if ( !optimisedParseSuccess )
3317 {
3318 posPair = we->getErrorPosition();
3319 -- ( posPair.first );
3320 messagePane ( we->getLastError(), CONST_WARNING );
3321
3322 int newPosition = doc->PositionFromLine ( posPair.first );
3323 doc->SetSelection ( newPosition, newPosition );
3324 doc->SetFocus();
3325 doc->setErrorIndicator ( posPair.first, posPair.second );
3326 }
3327 else
3328 {
3329 closeMessagePane();
3330 }
3331 return true;
3332 }
3333
getApproximateEncoding(char * docBuffer,size_t docBufferLen)3334 std::string MyFrame::getApproximateEncoding ( char *docBuffer,
3335 size_t docBufferLen )
3336 {
3337 std::string line;
3338 char *it;
3339 size_t i;
3340
3341 // grab first line
3342 for (
3343 i = 0, it = docBuffer;
3344 i < docBufferLen && *it != '\n' && i < BUFSIZ;
3345 i++, it++ )
3346 {
3347 if ( *it )
3348 line += *it;
3349 }
3350
3351 std::pair<int, int> limits = XmlEncodingHandler::getEncodingValueLimits ( line );
3352
3353 if ( limits.first == -1 || limits.second == -1 )
3354 return "";
3355
3356 return line.substr ( limits.first, limits.second );
3357 }
3358
OnToggleFold(wxCommandEvent & WXUNUSED (event))3359 void MyFrame::OnToggleFold ( wxCommandEvent& WXUNUSED ( event ) )
3360 {
3361 XmlDoc *doc;
3362 if ( ( doc = getActiveDocument() ) == NULL )
3363 return;
3364 doc->toggleFold();
3365 }
3366
OnFoldAll(wxCommandEvent & WXUNUSED (event))3367 void MyFrame::OnFoldAll ( wxCommandEvent& WXUNUSED ( event ) )
3368 {
3369 XmlDoc *doc;
3370 if ( ( doc = getActiveDocument() ) == NULL )
3371 return;
3372 doc->foldAll();
3373 doc->SetFocus();
3374 }
3375
OnUnfoldAll(wxCommandEvent & WXUNUSED (event))3376 void MyFrame::OnUnfoldAll ( wxCommandEvent& WXUNUSED ( event ) )
3377 {
3378 XmlDoc *doc;
3379 if ( ( doc = getActiveDocument() ) == NULL )
3380 return;
3381 doc->unfoldAll();
3382 doc->SetFocus();
3383 }
3384
3385
OnQuit(wxCommandEvent & WXUNUSED (event))3386 void MyFrame::OnQuit ( wxCommandEvent& WXUNUSED ( event ) )
3387 {
3388 Close ( true );
3389 }
3390
OnUndo(wxCommandEvent & WXUNUSED (event))3391 void MyFrame::OnUndo ( wxCommandEvent& WXUNUSED ( event ) )
3392 {
3393 XmlDoc *doc;
3394 if ( ( doc = getActiveDocument() ) == NULL )
3395 return;
3396 doc->Undo();
3397 doc->setValidationRequired ( true );
3398 doc->SetFocus();
3399 }
3400
OnRedo(wxCommandEvent & WXUNUSED (event))3401 void MyFrame::OnRedo ( wxCommandEvent& WXUNUSED ( event ) )
3402 {
3403 XmlDoc *doc;
3404 if ( ( doc = getActiveDocument() ) == NULL )
3405 return;
3406 doc->Redo();
3407 doc->setValidationRequired ( true );
3408 doc->SetFocus();
3409 }
3410
OnRevert(wxCommandEvent & WXUNUSED (event))3411 void MyFrame::OnRevert ( wxCommandEvent& WXUNUSED ( event ) )
3412 {
3413 XmlDoc *doc;
3414 if ( ( doc = getActiveDocument() ) == NULL )
3415 return;
3416
3417 while ( doc->GetModify() )
3418 {
3419 if ( !doc->CanUndo() )
3420 return;
3421 doc->Undo();
3422 doc->setValidationRequired ( true );
3423 }
3424 doc->SetFocus();
3425 }
3426
OnSpelling(wxCommandEvent & event)3427 void MyFrame::OnSpelling ( wxCommandEvent& event )
3428 {
3429 XmlDoc *doc;
3430 if ( ( doc = getActiveDocument() ) == NULL )
3431 return;
3432
3433 statusProgress ( wxEmptyString );
3434 closeMessagePane();
3435
3436 #ifdef __WXMSW__
3437 doc->SetUndoCollection ( false );
3438 doc->SetUndoCollection ( true );
3439 #endif
3440
3441 int id, type;
3442 id = event.GetId();
3443 type = (id == ID_STYLE) ? ID_TYPE_STYLE : ID_TYPE_SPELL;
3444
3445
3446 std::string rawBufferUtf8;
3447 getRawText ( doc, rawBufferUtf8 );
3448 bool success = true; // always true for now: well-formedness not req'd
3449
3450 boost::scoped_ptr<StyleDialog> sd ( new StyleDialog (
3451 this,
3452 wxICON ( appicon ),
3453 rawBufferUtf8,
3454 doc->getShortFileName(),
3455 ruleSetDir,
3456 filterDir,
3457 ( type == ID_TYPE_SPELL ) ? dictionaryPreset : ruleSetPreset,
3458 filterPreset,
3459 #ifdef __WXMSW__
3460 aspellDataPath,
3461 aspellDictPath,
3462 #endif
3463 type,
3464 ( success ) ? false : true,
3465 stylePosition,
3466 styleSize ) );
3467
3468 if ( sd->ShowModal() == wxID_OK )
3469 {
3470 std::string bufferUtf8 = sd->getEditedString();
3471 if ( bufferUtf8.empty() )
3472 messagePane ( _ ( "Edited document empty" ), CONST_STOP );
3473 else
3474 doc->SetTextRaw ( bufferUtf8.c_str() );
3475 }
3476
3477 // update presets if report has been created (even if followed by cancel)
3478 if (type == ID_TYPE_STYLE)
3479 {
3480 ruleSetPreset = sd->getRuleSetPreset();
3481 filterPreset = sd->getFilterPreset();
3482 }
3483 else
3484 dictionaryPreset = sd->getRuleSetPreset();
3485
3486 #ifdef __WXMSW__
3487 stylePosition = sd->getPosition();
3488 styleSize = sd->getSize();
3489 #endif
3490 }
3491
OnPreviousDocument(wxCommandEvent & WXUNUSED (event))3492 void MyFrame::OnPreviousDocument ( wxCommandEvent& WXUNUSED ( event ) )
3493 {
3494 if ( !getActiveDocument() )
3495 return;
3496
3497 statusProgress ( wxEmptyString );
3498 closeMessagePane();
3499
3500 int currentSelection = mainBook->GetSelection();
3501 if ( currentSelection < 1 )
3502 return;
3503 mainBook->SetSelection ( --currentSelection );
3504 XmlDoc *doc = getActiveDocument();
3505 if ( doc )
3506 doc->SetFocus();
3507 }
3508
OnNextDocument(wxCommandEvent & WXUNUSED (event))3509 void MyFrame::OnNextDocument ( wxCommandEvent& WXUNUSED ( event ) )
3510 {
3511 if ( !getActiveDocument() )
3512 return;
3513
3514 statusProgress ( wxEmptyString );
3515 closeMessagePane();
3516
3517 int currentSelection = mainBook->GetSelection();
3518 int maxSelection = mainBook->GetPageCount();
3519 if ( currentSelection >= ( maxSelection - 1 ) )
3520 return;
3521 mainBook->SetSelection ( ++currentSelection );
3522 XmlDoc *doc = getActiveDocument();
3523 if ( doc )
3524 doc->SetFocus();
3525 }
3526
OnSave(wxCommandEvent & event)3527 void MyFrame::OnSave ( wxCommandEvent& event )
3528 {
3529 save();
3530 }
3531
save()3532 void MyFrame::save()
3533 {
3534 XmlDoc *doc;
3535 if ( ( doc = getActiveDocument() ) == NULL )
3536 return;
3537
3538 if ( doc->getDirectory().empty() )
3539 {
3540 wxCommandEvent event;
3541 OnSaveAs ( event );
3542 return;
3543 }
3544
3545 wxString fileName = doc->getFullFileName();
3546 if ( !saveFile ( doc, fileName, true ) )
3547 {} // handle messages in saveFile
3548 }
3549
OnReload(wxCommandEvent & event)3550 void MyFrame::OnReload ( wxCommandEvent& event )
3551 {
3552 reloadTab();
3553 }
3554
reloadTab()3555 void MyFrame::reloadTab()
3556 {
3557 XmlDoc *doc;
3558 if ( ( doc = getActiveDocument() ) == NULL )
3559 return;
3560 wxString fileName = doc->getFullFileName();
3561
3562 if ( closeActiveDocument() )
3563 openFile ( fileName );
3564 }
3565
OnSaveAs(wxCommandEvent & event)3566 void MyFrame::OnSaveAs ( wxCommandEvent& event )
3567 {
3568 saveAs();
3569 }
3570
saveAs()3571 void MyFrame::saveAs()
3572 {
3573 XmlDoc *doc;
3574 if ( ( doc = getActiveDocument() ) == NULL )
3575 return;
3576
3577 wxString defaultFile, defaultDir;
3578 defaultFile = doc->getShortFileName();
3579 defaultDir = doc->getDirectory();
3580 if ( defaultDir.empty() )
3581 defaultDir = mLastDir;
3582
3583 boost::scoped_ptr<wxFileDialog> fd ( new wxFileDialog (
3584 this,
3585 _ ( "Save As" ),
3586 defaultDir,
3587 defaultFile,
3588 FILE_FILTER,
3589 #if wxCHECK_VERSION(2,9,0)
3590 wxFD_SAVE | wxFD_OVERWRITE_PROMPT ) );
3591 #else
3592 wxSAVE | wxOVERWRITE_PROMPT ) );
3593 #endif
3594 if ( fd->ShowModal() == wxID_CANCEL )
3595 return;
3596
3597 wxString path = fd->GetPath();
3598
3599 if (
3600 openFileSet.count ( path ) &&
3601 path != doc->getFullFileName() )
3602 {
3603 wxString message;
3604 message.Printf ( _ ( "%s is already open" ), path.c_str() );
3605 messagePane ( message, CONST_STOP );
3606 return;
3607 }
3608
3609 wxString name = fd->GetFilename();
3610 wxString directory;
3611 wxFileName::SplitPath ( path, &directory, NULL, NULL );
3612 if ( path == _T ( "" ) )
3613 return;
3614
3615 if ( !saveFile ( doc, path, false ) )
3616 return;
3617
3618 // if already named, remove from set of open files
3619 openFileSet.erase ( doc->getFullFileName() );
3620
3621 doc->setFullFileName ( path );
3622
3623 history.AddFileToHistory ( path ); // update history
3624 updateFileMenu();
3625
3626 int selection = mainBook->GetSelection();
3627 if ( selection != -1 )
3628 mainBook->SetPageText ( selection, name );
3629
3630 wxString title = showFullPathOnFrame ? path : name;
3631 title += _T ( " - " );
3632 title += _ ( "XML Copy Editor" );
3633 SetTitle ( title );
3634 }
3635
OnUpdateCloseAll(wxUpdateUIEvent & event)3636 void MyFrame::OnUpdateCloseAll ( wxUpdateUIEvent& event )
3637 {
3638 event.Enable ( mainBook->GetPageCount() > 1 );
3639 }
3640
OnUpdateReload(wxUpdateUIEvent & event)3641 void MyFrame::OnUpdateReload ( wxUpdateUIEvent& event )
3642 {
3643 XmlDoc *doc;
3644 if ( ( doc = getActiveDocument() ) == NULL )
3645 {
3646 event.Enable ( false );
3647 return;
3648 }
3649 event.Enable ( !doc->getDirectory().empty() );
3650 }
3651
OnUpdateCutCopy(wxUpdateUIEvent & event)3652 void MyFrame::OnUpdateCutCopy ( wxUpdateUIEvent& event )
3653 {
3654 event.Enable ( getActiveDocument() != NULL );
3655 }
3656
OnUpdateLocationPaneVisible(wxUpdateUIEvent & event)3657 void MyFrame::OnUpdateLocationPaneVisible ( wxUpdateUIEvent& event )
3658 {
3659 if ( !viewMenu )
3660 return;
3661 wxAuiPaneInfo info = manager.GetPane ( locationPanel );
3662 event.Check ( info.IsShown() );
3663 }
3664
OnUpdateSavedOnly(wxUpdateUIEvent & event)3665 void MyFrame::OnUpdateSavedOnly ( wxUpdateUIEvent& event )
3666 {
3667 XmlDoc *doc;
3668 if ( ( doc = getActiveDocument() ) == NULL )
3669 {
3670 event.Enable ( false );
3671 return;
3672 }
3673 event.Enable ( !doc->getDirectory().empty() );
3674 }
3675
OnUpdateDocRange(wxUpdateUIEvent & event)3676 void MyFrame::OnUpdateDocRange ( wxUpdateUIEvent& event )
3677 {
3678 event.Enable ( getActiveDocument() != NULL );
3679 }
3680
OnUpdateReplaceRange(wxUpdateUIEvent & event)3681 void MyFrame::OnUpdateReplaceRange ( wxUpdateUIEvent& event )
3682 {
3683 event.Enable ( getActiveDocument() != NULL );
3684 }
3685
OnUpdateFindAgain(wxUpdateUIEvent & event)3686 void MyFrame::OnUpdateFindAgain ( wxUpdateUIEvent& event )
3687 {
3688 if ( !getActiveDocument() || findData.GetFindString().empty() )
3689 {
3690 event.Enable ( false );
3691 return;
3692 }
3693 event.Enable ( true );
3694 }
3695
OnUpdateUndo(wxUpdateUIEvent & event)3696 void MyFrame::OnUpdateUndo ( wxUpdateUIEvent& event )
3697 {
3698 XmlDoc *doc;
3699 if ( ( doc = getActiveDocument() ) == NULL )
3700 {
3701 event.Enable ( false );
3702 return;
3703 }
3704 #ifdef __WXMSW__
3705 event.Enable((doc->CanUndo()) ? true : false);
3706 #else
3707 event.Enable ( ( doc->GetModify() ) ? true : false );
3708 #endif
3709 }
3710
OnUpdateRedo(wxUpdateUIEvent & event)3711 void MyFrame::OnUpdateRedo ( wxUpdateUIEvent& event )
3712 {
3713 XmlDoc *doc;
3714 if ( ( doc = getActiveDocument() ) == NULL )
3715 {
3716 event.Enable ( false );
3717 return;
3718 }
3719 event.Enable ( doc->CanRedo() );
3720 }
3721
OnUpdatePaste(wxUpdateUIEvent & event)3722 void MyFrame::OnUpdatePaste ( wxUpdateUIEvent& event )
3723 {
3724 event.Enable ( getActiveDocument() != NULL );
3725 }
3726
OnUpdateToggleComment(wxUpdateUIEvent & event)3727 void MyFrame::OnUpdateToggleComment ( wxUpdateUIEvent& event )
3728 {
3729 XmlDoc *doc = getActiveDocument();
3730 if ( !doc )
3731 {
3732 event.Enable ( false );
3733 return;
3734 }
3735
3736 int from = doc->GetSelectionStart();
3737 int to = doc->GetSelectionEnd();
3738 event.Enable ( from != to || doc->getType() == FILE_TYPE_XML );
3739 }
3740
OnUpdatePreviousDocument(wxUpdateUIEvent & event)3741 void MyFrame::OnUpdatePreviousDocument ( wxUpdateUIEvent& event )
3742 {
3743 if ( !getActiveDocument() )
3744 {
3745 event.Enable ( false );
3746 return;
3747 }
3748 int currentDocument = mainBook->GetSelection();
3749 event.Enable ( ( currentDocument < 1 ) ? false : true );
3750 }
3751
OnUpdateNextDocument(wxUpdateUIEvent & event)3752 void MyFrame::OnUpdateNextDocument ( wxUpdateUIEvent& event )
3753 {
3754 if ( !getActiveDocument() )
3755 {
3756 event.Enable ( false );
3757 return;
3758 }
3759 int currentDocument = mainBook->GetSelection();
3760 int maxDocument = mainBook->GetPageCount();
3761 event.Enable ( ( currentDocument >= ( maxDocument - 1 ) ) ? false : true );
3762 }
3763
OnUpdateCloseMessagePane(wxUpdateUIEvent & event)3764 void MyFrame::OnUpdateCloseMessagePane ( wxUpdateUIEvent& event )
3765 {
3766 wxAuiPaneInfo &info = manager.GetPane ( htmlReport );
3767 event.Enable ( info.IsShown() );
3768 }
3769
OnUpdateCloseFindReplacePane(wxUpdateUIEvent & event)3770 void MyFrame::OnUpdateCloseFindReplacePane ( wxUpdateUIEvent& event )
3771 {
3772 wxAuiPaneInfo &info = manager.GetPane ( findReplacePanel );
3773 event.Enable ( info.IsShown() );
3774 }
3775
OnUpdateCloseCommandPane(wxUpdateUIEvent & event)3776 void MyFrame::OnUpdateCloseCommandPane ( wxUpdateUIEvent& event )
3777 {
3778 wxAuiPaneInfo &info = manager.GetPane ( commandPanel );
3779 event.Enable ( info.IsShown() );
3780 }
3781
OnValidateDTD(wxCommandEvent & event)3782 void MyFrame::OnValidateDTD ( wxCommandEvent& event )
3783 {
3784 statusProgress ( wxEmptyString );
3785
3786 // fetch document contents
3787 XmlDoc *doc;
3788 if ( ( doc = getActiveDocument() ) == NULL )
3789 return;
3790
3791
3792 doc->clearErrorIndicators();
3793 statusProgress ( _ ( "DTD Validation in progress..." ) );
3794
3795 boost::scoped_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
3796 wxString fname = doc->getFullFileName();
3797 if ( !wl->validate ( doc->myGetTextRaw(), fname ) )
3798 {
3799 wxString wideError = wl->getLastError();
3800 statusProgress ( wxEmptyString );
3801 messagePane ( wideError, CONST_WARNING );
3802
3803 std::pair<int, int> posPair = wl->getErrorPosition();
3804 -- ( posPair.first );
3805 int cursorPos =
3806 doc->PositionFromLine ( posPair.first );
3807 doc->SetSelection ( cursorPos, cursorPos );
3808
3809 // shallow validate all
3810 doc->backgroundValidate(); // has to come first as it deletes all indicators
3811 doc->setErrorIndicator ( posPair.first, posPair.second );
3812
3813 return;
3814 }
3815 statusProgress ( wxEmptyString );
3816 documentOk ( _ ( "valid" ) );
3817 }
3818
OnValidateRelaxNG(wxCommandEvent & event)3819 void MyFrame::OnValidateRelaxNG ( wxCommandEvent& event )
3820 {
3821 statusProgress ( wxEmptyString );
3822
3823 XmlDoc *doc;
3824 if ( ( doc = getActiveDocument() ) == NULL )
3825 return;
3826
3827 wxString fileName = doc->getFullFileName();
3828
3829 wxString defaultFile, defaultDir;
3830 defaultFile = doc->getFullFileName();
3831 defaultDir = doc->getDirectory();
3832 if ( defaultDir.empty() )
3833 defaultDir = mLastDir;
3834
3835 AssociateDialog ad (
3836 this,
3837 _ ( "Select RELAX NG grammar" ),
3838 _ ( "Choose a file:" ),
3839 _ ( "RELAX NG grammar" ),
3840 _T ( "*.*" ),
3841 lastRelaxNGSchema,
3842 &mLastDir );
3843 if ( ad.ShowModal() != wxID_OK )
3844 return;
3845
3846 const wxString &url = lastRelaxNGSchema = ad.getUrl();
3847 if ( url.empty() )
3848 {
3849 statusProgress ( wxEmptyString );
3850 return;
3851 }
3852
3853 validateRelaxNG ( doc, url, fileName );
3854 }
3855
validateRelaxNG(XmlDoc * doc,const wxString & schemaUrl,wxString & fileName)3856 void MyFrame::validateRelaxNG (
3857 XmlDoc *doc,
3858 const wxString& schemaUrl,
3859 wxString& fileName ) // not const: may change if empty/document modified
3860 {
3861 statusProgress ( wxEmptyString );
3862
3863 if ( !doc )
3864 return;
3865
3866 doc->clearErrorIndicators();
3867 statusProgress ( _ ( "RELAX NG validation in progress..." ) );
3868
3869 boost::scoped_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
3870 if ( !wl->validateRelaxNG ( schemaUrl, doc->myGetTextRaw(), fileName ) )
3871 {
3872 wxString wideError = wl->getLastError();
3873 statusProgress ( wxEmptyString );
3874
3875 std::pair<int, int> posPair = wl->getErrorPosition();
3876 -- ( posPair.first );
3877
3878 int cursorPos =
3879 doc->PositionFromLine ( posPair.first );
3880 doc->SetSelection ( cursorPos, cursorPos );
3881 doc->setErrorIndicator ( posPair.first, posPair.second );
3882 messagePane ( wideError, CONST_WARNING );
3883 doc->SetFocus();
3884 return;
3885 }
3886
3887 statusProgress ( wxEmptyString );
3888 documentOk ( _ ( "valid" ) );
3889 doc->SetFocus();
3890 }
3891
OnValidatePreset(wxCommandEvent & event)3892 void MyFrame::OnValidatePreset ( wxCommandEvent& event )
3893 {
3894 XmlDoc *doc;
3895 if ( ( doc = getActiveDocument() ) == NULL )
3896 return;
3897
3898 wxString fileName = doc->getFullFileName();
3899
3900 int id = event.GetId();
3901 const wxString &schemaUrl = validationPresetMap[id];
3902 if ( schemaUrl.empty() )
3903 return;
3904 validateRelaxNG ( doc, schemaUrl, fileName );
3905 }
3906
OnValidateSchema(wxCommandEvent & event)3907 void MyFrame::OnValidateSchema ( wxCommandEvent& event )
3908 {
3909 statusProgress ( wxEmptyString );
3910
3911 XmlDoc *doc;
3912 if ( ( doc = getActiveDocument() ) == NULL )
3913 return;
3914
3915 // branch: if no XML Schema found, use LibXML DTD parser instead
3916 // so the catalog is read - switch when Xerces-C implements
3917 // XMLCatalogResolver
3918 #if 0
3919 {
3920 std::string rawBuffer;
3921 getRawText ( doc, rawBuffer );
3922 XmlSchemaLocator xsl ( "UTF-8" );
3923 xsl.parse ( rawBuffer.c_str() );
3924 if ( ( xsl.getSchemaLocation() ).empty() )
3925 {
3926 OnValidateDTD ( event );
3927 return;
3928 }
3929 }
3930 #endif
3931
3932 statusProgress ( _ ( "Validation in progress..." ) );
3933 doc->clearErrorIndicators();
3934
3935 wxString fileName = doc->getFullFileName();
3936 std::string utf8Buffer = doc->myGetTextRaw();
3937 boost::scoped_ptr<WrapXerces> validator ( new WrapXerces() );
3938 int severity;
3939 wxString message;
3940 if ( validator->validateMemory ( utf8Buffer.c_str(), utf8Buffer.size(),
3941 fileName ) )
3942 {
3943 message.Printf ( _ ( "%s is valid" ),
3944 doc->getShortFileName().c_str() );
3945 if ( validator->getLastError().empty() )
3946 severity = CONST_INFO;
3947 else
3948 {
3949 severity = CONST_WARNING;
3950 message << _T ( "[br][br]" );
3951 }
3952 }
3953 else
3954 {
3955 severity = CONST_STOP;
3956 }
3957 statusProgress ( wxEmptyString );
3958 message << validator->getLastError();
3959 messagePane ( message, severity );
3960
3961 if ( severity != CONST_INFO )
3962 {
3963 std::pair<int, int> posPair = validator->getErrorPosition();
3964 int cursorPos =
3965 doc->PositionFromLine ( posPair.first - 1 );
3966 doc->SetSelection ( cursorPos, cursorPos );
3967 doc->setErrorIndicator ( posPair.first - 1, 0 );
3968 }
3969 }
3970
OnCreateSchema(wxCommandEvent & event)3971 void MyFrame::OnCreateSchema ( wxCommandEvent& event )
3972 {
3973 statusProgress ( wxEmptyString );
3974
3975 XmlDoc *doc = getActiveDocument();
3976 if ( doc == NULL )
3977 return;
3978
3979 std::string rawBufferUtf8;
3980 getRawText ( doc, rawBufferUtf8 );
3981
3982 const static wxString types[] = { _ ( "W3C Schema" ), _ ( "DTD" ) };
3983 const static wxString message = _ ( "Please choose a shema type");
3984 wxSingleChoiceDialog dlg ( this, message, _ ( "Schema type" ),
3985 ( int ) sizeof ( types ) / sizeof ( types[0] ), types );
3986 int ret = dlg.ShowModal();
3987 if ( ret == wxID_CANCEL ) return;
3988
3989 Grammar::GrammarType type = ( dlg.GetSelection() == 0 ) ?
3990 Grammar::SchemaGrammarType : Grammar::DTDGrammarType;
3991 XmlSchemaGenerator gen;
3992 const wxString &schema = gen.generate(type, doc->getFullFileName(),
3993 rawBufferUtf8.c_str(), rawBufferUtf8.size(), _T ( "UTF-8" ) );
3994 if (schema.IsEmpty()) {
3995 messagePane ( gen.getLastError(), CONST_WARNING );
3996 return;
3997 }
3998 newDocument ( schema );
3999 }
4000
OnDtd2Schema(wxCommandEvent & event)4001 void MyFrame::OnDtd2Schema ( wxCommandEvent& event )
4002 {
4003 closeMessagePane();
4004
4005 #if wxCHECK_VERSION(2,9,0)
4006 long style = wxFD_OPEN | wxFD_FILE_MUST_EXIST;
4007 #else
4008 long style = wxOPEN | wxFILE_MUST_EXIST;
4009 #endif
4010 wxFileDialog fd ( this, _ ( "Please select a DTD file" ), wxEmptyString,
4011 wxEmptyString, _T ( "DTD files (*.dtd)|*.dtd|All files (*.*)|*.*" ),
4012 style );
4013 if (fd.ShowModal() != wxID_OK)
4014 return;
4015
4016 statusProgress ( _ ( "Converting..." ) );
4017
4018 Dtd2Schema dtd2xsd;
4019 const wxString &schema = dtd2xsd.convert ( fd.GetPath() );
4020 const wxString &error = dtd2xsd.getErrors();
4021 if ( !error.empty() )
4022 messagePane ( error, CONST_STOP );
4023 if ( !schema.empty() )
4024 {
4025 statusProgress ( _ ( "Creating document view..." ) );
4026 newDocument ( schema );
4027 }
4028
4029 statusProgress ( wxEmptyString );
4030 }
4031
OnXPath(wxCommandEvent & event)4032 void MyFrame::OnXPath ( wxCommandEvent& event )
4033 {
4034 statusProgress ( wxEmptyString );
4035 closeMessagePane();
4036
4037 XmlDoc *doc;
4038 if ( ( doc = getActiveDocument() ) == NULL )
4039 return;
4040
4041 boost::scoped_ptr<wxTextEntryDialog> dlg ( new wxTextEntryDialog (
4042 this,
4043 _ ( "Enter XPath:" ),
4044 _ ( "Evaluate XPath" ),
4045 xpathExpression ) );
4046
4047 int ret = dlg->ShowModal();
4048 if ( ret == wxID_CANCEL )
4049 return;
4050 xpathExpression = dlg->GetValue();
4051
4052 // fetch document contents
4053 std::string utf8Buffer;
4054 getRawText ( doc, utf8Buffer );
4055
4056 boost::scoped_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
4057 bool success = wl->xpath ( xpathExpression, utf8Buffer,
4058 doc->getFullFileName() );
4059
4060 if ( !success )
4061 {
4062 wxString wideError = wl->getLastError();
4063 if ( !wideError.empty() )
4064 wideError.Prepend ( _T ( ": " ) );
4065 wideError.Prepend ( _ ( "Cannot evaluate XPath" ) );
4066
4067 messagePane ( wideError, CONST_WARNING );
4068 return;
4069 }
4070
4071 statusProgress ( wxEmptyString );
4072 std::string buffer = wl->getOutput();
4073
4074 if ( buffer.empty() )
4075 {
4076 messagePane ( _ ( "No matching nodes found" ), CONST_WARNING );
4077 return;
4078 }
4079 newDocument ( buffer );
4080 statusProgress ( wxEmptyString );
4081 }
4082
OnXslt(wxCommandEvent & event)4083 void MyFrame::OnXslt ( wxCommandEvent& event )
4084 {
4085 statusProgress ( wxEmptyString );
4086 closeMessagePane();
4087
4088 // fetch document contents
4089 XmlDoc *doc;
4090 if ( ( doc = getActiveDocument() ) == NULL )
4091 return;
4092
4093 std::string rawBufferUtf8 = doc->myGetTextRaw();
4094
4095 wxString path;
4096 int id = event.GetId();
4097 if ( id == ID_XSLT )
4098 {
4099 XslLocator xl ( "UTF-8" );
4100 xl.parse ( rawBufferUtf8 );
4101 std::string location = xl.getXslLocation();
4102
4103 path = wxString ( location.c_str(), wxConvUTF8, location.size() );
4104
4105 path = PathResolver::run ( path, doc->getFullFileName() );
4106
4107 if ( !wxFileExists ( path ) )
4108 {
4109 if ( !path.empty() )
4110 {
4111 wxString message;
4112 message.Printf ( _ ( "Cannot open stylesheet %s" ), path.c_str() );
4113 messagePane ( message, CONST_WARNING );
4114 }
4115
4116 wxString defaultFile, defaultDir;
4117 defaultFile = doc->getFullFileName();
4118 defaultDir = doc->getDirectory();
4119 if ( defaultDir.empty() )
4120 defaultDir = mLastDir;
4121
4122 AssociateDialog ad (
4123 this,
4124 _ ( "Select stylesheet" ),
4125 _ ( "Choose a file:" ),
4126 _ ( "XSLT stylesheet" ),
4127 _T ( "*.xsl;*.xslt" ),
4128 lastXslStylesheet,
4129 &mLastDir );
4130 if ( ad.ShowModal() != wxID_OK )
4131 return;
4132
4133 path = lastXslStylesheet = ad.getUrl();
4134
4135
4136 if ( path.empty() ) // Cancel selected
4137 {
4138 statusProgress ( wxEmptyString );
4139 return;
4140 }
4141 }
4142 }
4143 else
4144 {
4145 wxString sep;
4146 sep.Append ( wxFileName::GetPathSeparator() );
4147 switch ( id )
4148 {
4149 case ID_XSLT_TEI_FO:
4150 path = applicationDir + sep + _T ( "tei" ) + sep + _T ( "fo" ) + sep +
4151 _T ( "tei.xsl" );
4152 break;
4153 case ID_XSLT_TEI_HTML:
4154 path = applicationDir + sep + _T ( "tei" ) + sep + _T ( "html" ) + sep +
4155 _T ( "tei.xsl" );
4156 break;
4157 case ID_XSLT_TEI_XHTML:
4158 path = applicationDir + sep + _T ( "tei" ) + sep + _T ( "xhtml" ) + sep +
4159 _T ( "tei.xsl" );
4160 break;
4161 case ID_XSLT_TEI_LATEX:
4162 path = applicationDir + sep + _T ( "tei" ) + sep + _T ( "latex" ) + sep +
4163 _T ( "tei.xsl" );
4164 break;
4165 case ID_XSLT_DOCBOOK_FO:
4166 path = applicationDir + sep + _T ( "docbook" ) + sep + _T ( "fo" ) + sep +
4167 _T ( "docbook.xsl" );
4168 break;
4169 case ID_XSLT_DOCBOOK_HTML:
4170 path = applicationDir + sep + _T ( "docbook" ) + sep + _T ( "html" ) + sep +
4171 _T ( "docbook.xsl" );
4172 break;
4173 case ID_XSLT_DOCBOOK_XHTML:
4174 path = applicationDir + sep + _T ( "docbook" ) + sep + _T ( "xhtml" ) + sep +
4175 _T ( "docbook.xsl" );
4176 break;
4177 default:
4178 break;
4179 }
4180 }
4181 statusProgress ( _ ( "XSL transformation in progress..." ) );
4182
4183 boost::scoped_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
4184 wxString fileName = doc->getFullFileName();
4185 if ( !wl->xslt ( path, rawBufferUtf8, fileName ) )
4186 {
4187 wxString wideError = wl->getLastError();
4188 wideError.Prepend ( _ ( "Cannot transform: " ) );
4189 statusProgress ( wxEmptyString );
4190 messagePane ( wideError, CONST_WARNING );
4191 return;
4192 }
4193 std::string buffer = wl->getOutput();
4194 if ( buffer.empty() )
4195 {
4196 messagePane ( _ ( "Output document empty" ), CONST_WARNING );
4197 return;
4198 }
4199 statusProgress ( wxEmptyString );
4200 newDocument ( buffer );
4201 }
4202
OnPrettyPrint(wxCommandEvent & event)4203 void MyFrame::OnPrettyPrint ( wxCommandEvent& event )
4204 {
4205 statusProgress ( wxEmptyString );
4206 closeMessagePane();
4207
4208 // fetch document contents
4209 XmlDoc *doc;
4210 if ( ( doc = getActiveDocument() ) == NULL )
4211 return;
4212
4213 int line = doc->LineFromPosition ( doc->GetCurrentPos() );
4214
4215 std::string rawBufferUtf8;
4216 getRawText ( doc, rawBufferUtf8 );
4217
4218 std::string encoding = XmlEncodingHandler::get ( rawBufferUtf8 );
4219
4220 statusProgress ( _ ( "Pretty-printing in progress..." ) );
4221
4222 wxString fileName = doc->getFullFileName();
4223 boost::scoped_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
4224 for ( int i = 0; i < 2; i++ ) // perform two iterations
4225 {
4226
4227 if ( !wl->parse ( rawBufferUtf8, fileName, true ) )
4228 {
4229 wxString wideError = wl->getLastError();
4230 wideError.Prepend ( _ ( "Cannot pretty-print: " ) );
4231 statusProgress ( wxEmptyString );
4232 messagePane ( wideError, CONST_WARNING );
4233 return;
4234 }
4235 rawBufferUtf8 = wl->getOutput();
4236 }
4237
4238 statusProgress ( wxEmptyString );
4239 if ( rawBufferUtf8.empty() )
4240 messagePane (
4241 _ ( "Pretty-print unsuccessful: output document empty" ),
4242 CONST_STOP );
4243 else
4244 {
4245 if ( encoding != "UTF-8" && !encoding.empty() )
4246 {
4247 XmlEncodingHandler::set ( rawBufferUtf8, encoding );
4248 }
4249 doc->SetTextRaw ( rawBufferUtf8.c_str() );
4250 statusProgress ( wxEmptyString );
4251 }
4252
4253 doc->setValidationRequired ( true );
4254 doc->GotoLine ( line );
4255 doc->SetFocus();
4256 }
4257
OnEncoding(wxCommandEvent & event)4258 void MyFrame::OnEncoding ( wxCommandEvent& event )
4259 {
4260 statusProgress ( wxEmptyString );
4261 closeMessagePane();
4262
4263 // fetch document contents
4264 XmlDoc *doc;
4265 if ( ( doc = getActiveDocument() ) == NULL )
4266 return;
4267
4268 const static wxString encodings[] = {
4269 _T ( "UTF-8" ), _T ( "UTF-16" ), _T ( "UTF-16LE" ),
4270 _T ( "UTF-16BE" ), _T ( "ISO-8859-1" ), _T ( "US-ASCII" )
4271 };
4272 wxSingleChoiceDialog scd (
4273 this, _ ( "Choose an encoding:" ), _ ( "Encoding" ),
4274 sizeof ( encodings ) / sizeof ( encodings[0] ), encodings );
4275 if ( scd.ShowModal() == wxID_CANCEL )
4276 return;
4277
4278 int res;
4279 wxMemoryBuffer output;
4280 boost::scoped_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
4281 res = wl->saveEncoding ( doc->myGetTextRaw(), doc->getFullFileName(),
4282 wxEmptyString, &output, scd.GetStringSelection() );
4283 if ( res == -1 )
4284 {
4285 wxString wideError = wl->getLastError();
4286 wideError.Prepend ( _ ( "Cannot set encoding: " ) );
4287 messagePane ( wideError, CONST_STOP );
4288 return;
4289 }
4290
4291 boost::scoped_ptr<XmlUtf8Reader> xur ( new XmlUtf8Reader (
4292 false,
4293 expandInternalEntities,
4294 output.GetDataLen() ) );
4295 if ( !xur->parse ( ( const char * ) output.GetData(), output.GetDataLen() ) )
4296 {
4297 messagePane ( _ ( "Cannot set encoding (cannot parse temporary file)" ),
4298 CONST_STOP );
4299 return;
4300 }
4301
4302 doc->SetTextRaw ( xur->getBuffer().c_str() );
4303 doc->setValidationRequired ( true );
4304 doc->SetFocus();
4305 }
4306
OnHome(wxCommandEvent & event)4307 void MyFrame::OnHome ( wxCommandEvent& event )
4308 {
4309 wxLaunchDefaultBrowser ( _T ( "http://xml-copy-editor.sourceforge.net" ) );
4310 }
4311
OnDownloadSource(wxCommandEvent & event)4312 void MyFrame::OnDownloadSource ( wxCommandEvent& event )
4313 {
4314 wxLaunchDefaultBrowser ( _T ( "http://sourceforge.net/p/xml-copy-editor/code/" ) );
4315 }
4316
OnToolbarVisible(wxCommandEvent & event)4317 void MyFrame::OnToolbarVisible ( wxCommandEvent& event )
4318 {
4319 if ( !viewMenu )
4320 return;
4321 toolbarVisible = ( toolbarVisible ) ? false : true;
4322 viewMenu->Check ( ID_TOOLBAR_VISIBLE, toolbarVisible );
4323 showTopBars ( toolbarVisible );
4324 manager.Update();
4325 }
4326
OnWrapWords(wxCommandEvent & event)4327 void MyFrame::OnWrapWords ( wxCommandEvent& event )
4328 {
4329 if ( !viewMenu )
4330 return;
4331
4332 bool wrapWords;
4333 wrapWords = ( properties.wrap ) ? false : true;
4334
4335 viewMenu->Check ( ID_WRAP_WORDS, wrapWords );
4336 properties.wrap = wrapWords;
4337
4338 // update all documents
4339 int pageCount = mainBook->GetPageCount();
4340 XmlDoc *currentDoc;
4341 for ( int i = 0; i < pageCount; ++i )
4342 {
4343 currentDoc = ( XmlDoc * ) mainBook->GetPage ( i );
4344 if ( !currentDoc )
4345 break;
4346 currentDoc->SetWrapMode ( wrapWords );
4347 }
4348 }
4349
OnLocationPaneVisible(wxCommandEvent & event)4350 void MyFrame::OnLocationPaneVisible ( wxCommandEvent& event )
4351 {
4352 wxAuiPaneInfo info = manager.GetPane ( locationPanel );
4353 bool visible = ( info.IsShown() ) ? false : true;
4354 manager.GetPane ( locationPanel ).Show ( visible );
4355 manager.Update();
4356
4357 XmlDoc *doc;
4358 if ( ( doc = getActiveDocument() ) == NULL )
4359 return;
4360 doc->SetFocus();
4361 }
4362
OnProtectTags(wxCommandEvent & event)4363 void MyFrame::OnProtectTags ( wxCommandEvent& event )
4364 {
4365 if ( !xmlMenu )
4366 return;
4367 protectTags = ( protectTags ) ? false : true;
4368 if ( xmlMenu )
4369 xmlMenu->Check ( ID_PROTECT_TAGS, protectTags );
4370 if ( toolBar )
4371 toolBar->ToggleTool ( ID_PROTECT_TAGS, protectTags );
4372
4373 XmlDoc *doc;
4374 if ( ( doc = getActiveDocument() ) == NULL )
4375 return;
4376
4377 if ( protectTags )
4378 doc->adjustCursor(); // apply to all open docs?
4379
4380 doc->SetFocus();
4381 }
4382
OnVisibilityState(wxCommandEvent & event)4383 void MyFrame::OnVisibilityState ( wxCommandEvent& event )
4384 {
4385
4386 int id;
4387 id = event.GetId();
4388 switch ( id )
4389 {
4390 case ID_SHOW_TAGS:
4391 visibilityState = SHOW_TAGS;
4392 //GetStatusBar()->SetStatusText(wxEmptyString, STATUS_PARENT);
4393 break;
4394 case ID_HIDE_ATTRIBUTES:
4395 visibilityState = HIDE_ATTRIBUTES;
4396 //GetStatusBar()->SetStatusText(wxEmptyString, STATUS_PARENT);
4397 break;
4398 case ID_HIDE_TAGS:
4399 visibilityState = HIDE_TAGS;
4400 break;
4401 default:
4402 visibilityState = SHOW_TAGS;
4403 break;
4404 }
4405 if ( viewMenu )
4406 viewMenu->Check ( id, true );
4407
4408 // iterate over all open documents
4409 int pageCount = mainBook->GetPageCount();
4410 XmlDoc *currentDoc;
4411 for ( int i = 0; i < pageCount; ++i )
4412 {
4413 currentDoc = ( XmlDoc * ) mainBook->GetPage ( i );
4414 if ( !currentDoc )
4415 break;
4416 currentDoc->applyVisibilityState ( visibilityState );
4417 }
4418
4419 if ( visibilityState == HIDE_ATTRIBUTES || visibilityState == HIDE_TAGS )
4420 {
4421 if ( properties.protectHiddenElements && !protectTags )
4422 {
4423 wxCommandEvent e;
4424 OnProtectTags ( e );
4425 }
4426 }
4427
4428 // fetch current document
4429 XmlDoc *doc;
4430 if ( ( doc = getActiveDocument() ) == NULL )
4431 return;
4432
4433 // set focus for current document
4434 doc->SetFocus();
4435 }
4436
OnFeedback(wxCommandEvent & event)4437 void MyFrame::OnFeedback ( wxCommandEvent& event )
4438 {
4439 wxString forumUrl =
4440 _T ( "https://sourceforge.net/p/xml-copy-editor/discussion/475215/" );
4441 wxLaunchDefaultBrowser ( forumUrl );
4442 }
4443
findAgain(wxString s,int flags)4444 void MyFrame::findAgain ( wxString s, int flags )
4445 {
4446 findReplacePanel->flagNotFound ( false );
4447
4448 if ( s.empty() )
4449 return;
4450
4451 statusProgress ( wxEmptyString );
4452 XmlDoc *doc;
4453 if ( ( doc = getActiveDocument() ) == NULL )
4454 return;
4455
4456 // update regex parameter to keep global replace in sync
4457 findRegex = findReplacePanel->getRegex();
4458
4459 int newLocation;
4460 int myFlags = 0;
4461 if ( flags & wxFR_WHOLEWORD )
4462 myFlags |= wxSTC_FIND_WHOLEWORD;
4463 if ( flags & wxFR_MATCHCASE )
4464 myFlags |= wxSTC_FIND_MATCHCASE;
4465 if ( findReplacePanel->getRegex() )
4466 myFlags |= wxSTC_FIND_REGEXP;
4467
4468 //doc->SetYCaretPolicy(wxSTC_CARET_SLOP | wxSTC_CARET_STRICT, 10);
4469
4470 if ( flags & wxFR_DOWN ) // find next
4471 {
4472 doc->SetTargetStart ( findReplacePanel->getIncrementalFind()
4473 ? doc->GetSelectionStart() : doc->GetSelectionEnd() );
4474 doc->SetTargetEnd ( doc->GetLength() );
4475 doc->SetSearchFlags ( myFlags );
4476 newLocation = doc->SearchInTarget ( s );
4477
4478 // try once more from top
4479 if ( newLocation == -1 )
4480 {
4481 doc->SetTargetStart ( 0 );
4482 doc->SetTargetEnd ( doc->GetLength() );
4483 newLocation = doc->SearchInTarget ( s );
4484 }
4485 }
4486 else // find previous
4487 {
4488 doc->SetCurrentPos (
4489 ( doc->GetSelectionStart() ) ? doc->GetSelectionStart() - 1 : 0 );
4490 doc->SearchAnchor();
4491 newLocation = doc->SearchPrev ( myFlags, s );
4492 }
4493
4494 //doc->SetYCaretPolicy(wxSTC_CARET_SLOP, 0);
4495
4496
4497 if ( newLocation == -1 )
4498 {
4499 findReplacePanel->flagNotFound ( true );
4500 wxString err;
4501 err.Printf ( _ ( "Cannot find '%s'" ), s.c_str() );
4502 doc->SetSelectionEnd ( doc->GetSelectionStart() );
4503
4504 statusProgress ( err );
4505
4506 // must clear target to prevent replace affecting whole document
4507 doc->SetTargetStart ( 0 );
4508 doc->SetTargetEnd ( 0 );
4509
4510 return;
4511 }
4512
4513 doc->SetSelection ( doc->GetTargetStart(), doc->GetTargetEnd() );
4514 doc->EnsureCaretVisible();
4515 }
4516
closeActiveDocument()4517 bool MyFrame::closeActiveDocument()
4518 {
4519 statusProgress ( wxEmptyString );
4520 closeMessagePane();
4521
4522 int selection = mainBook->GetSelection();
4523 if ( selection == -1 || !mainBook->GetPageCount() ) // GetPageCount needed for wxAuiNotebook
4524 return false;
4525
4526 locationPanel->update ( NULL, wxEmptyString );
4527 insertChildPanel->update ( NULL, wxEmptyString );
4528 insertSiblingPanel->update ( NULL, wxEmptyString );
4529
4530 // workaround -- wxAuiNotebook: send virtual close event? DeletePage doesn't generate one
4531 wxAuiNotebookEvent e;
4532 e.SetSelection ( selection );
4533 OnPageClosing ( e );
4534 if ( deletePageVetoed )
4535 return false;
4536
4537 mainBook->DeletePage ( selection ); // check this is still correct
4538 return true;
4539
4540 // apparently fixed betw. 2.8.0 and 2.8.6, so from v. 1.1.0.3, BUT this is once more:
4541 // 1.1.0.5: reverted to above workaround - no confirmation dialog?
4542 // watch memory usage for DeletePage call
4543 //mainBook->DeletePage ( selection );
4544 //return ( !deletePageVetoed );
4545 }
4546
saveFile(XmlDoc * doc,wxString & fileName,bool checkLastModified)4547 bool MyFrame::saveFile ( XmlDoc *doc, wxString& fileName, bool checkLastModified )
4548 {
4549 if ( !doc )
4550 return false;
4551
4552 statusProgress ( wxEmptyString );
4553
4554 if ( checkLastModified )
4555 {
4556 wxFileName fn ( fileName );
4557 if ( fn.IsOk() )
4558 {
4559 wxDateTime myLastModified = fn.GetModificationTime();
4560 if ( !myLastModified.IsEqualTo ( doc->getLastModified() ) )
4561 {
4562 int choice = wxMessageBox (
4563 _ ( "File has been modified by another application.\nDo you want to proceed?" ),
4564 _ ( "Confirmation" ),
4565 wxICON_QUESTION | wxYES_NO | wxCANCEL );
4566 if ( choice != wxYES )
4567 return false;
4568 }
4569 }
4570 }
4571
4572 int bytes = 0;
4573 std::string utf8Buffer, encoding, fileNameLocal;
4574 wxString wideEncoding;
4575 bool isXml = true;
4576 try
4577 {
4578 getRawText ( doc, utf8Buffer );
4579 XmlEncodingSpy es ( "UTF-8" );
4580 es.parse ( utf8Buffer );
4581 encoding = es.getEncoding();
4582 wideEncoding = wxString ( encoding.c_str(), wxConvUTF8 );
4583
4584 fileNameLocal = fileName.mb_str ( wxConvLocal );
4585
4586 closeMessagePane();
4587 bool success;
4588 success = true;
4589 if ( getFileType ( fileName ) != FILE_TYPE_XML )
4590 {
4591 isXml = false;
4592 }
4593
4594 // raw file conditions
4595 if ( doc->getType() == FILE_TYPE_BINARY )
4596 {
4597 success = saveRawUtf8 ( fileNameLocal, utf8Buffer, true, isXml );
4598 if ( success )
4599 bytes = utf8Buffer.size();
4600 else
4601 {
4602 wxString message;
4603 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4604 messagePane ( message, CONST_STOP );
4605 return false;
4606 }
4607
4608 }
4609 else if ( !isXml && encoding.empty() )
4610 {
4611 success = saveRawUtf8 ( fileNameLocal, utf8Buffer, true, isXml );
4612 if ( success )
4613 bytes = utf8Buffer.size();
4614 else
4615 {
4616 wxString message;
4617 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4618 messagePane ( message, CONST_STOP );
4619 return false;
4620 }
4621 }
4622 else if ( encoding == "UTF-8" )
4623 {
4624 WrapExpat we ( "UTF-8" );
4625
4626 if ( !we.parse ( utf8Buffer ) )
4627 {
4628 //if ( we->isEncodingError() )
4629 // ;
4630 messagePane ( we.getLastError(), CONST_WARNING );
4631 }
4632 success = saveRawUtf8 ( fileNameLocal, utf8Buffer, true, isXml );
4633 if ( success )
4634 bytes = utf8Buffer.size();
4635 else
4636 {
4637 wxString message;
4638 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4639 messagePane ( message, CONST_STOP );
4640 return false;
4641 }
4642 }
4643 else
4644 {
4645 // IF Unicode, use iconv to convert buffer
4646 if ( encoding == "UTF-16" || encoding == "UTF-16LE" ||
4647 encoding == "UTF-16BE" || encoding == "UTF-32" || encoding == "UTF-32LE" ||
4648 encoding == "UTF-32BE" )
4649 {
4650 iconv_t cd = iconv_open ( encoding.c_str(), "UTF-8" );
4651 if ( cd == ( iconv_t )-1 )
4652 {
4653 success = saveRawUtf8 ( fileNameLocal, utf8Buffer, false, isXml );
4654 if ( success )
4655 {
4656 bytes = utf8Buffer.size();
4657 wxString message;
4658 message.Printf (
4659 _ ( "%s saved in default encoding UTF-8: unknown encoding %s" ),
4660 fileName.c_str(),
4661 wideEncoding.c_str() );
4662 messagePane ( message, CONST_WARNING );
4663 }
4664 else
4665 {
4666 wxString message;
4667 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4668 messagePane ( message, CONST_STOP );
4669 return false;
4670 }
4671 }
4672 else
4673 {
4674 size_t utf8BufferLen = utf8Buffer.size();
4675
4676 size_t iconvBufferLen, iconvBufferLeft, utf8BufferLeft;
4677 int iconvLenMultiplier = 4; // worst case scenario
4678 if ( encoding == "UTF-16" ||
4679 encoding == "UTF-16BE" ||
4680 encoding == "UTF-16LE" )
4681 {
4682 iconvLenMultiplier = 2;
4683 }
4684 else if ( encoding == "UTF-32" ||
4685 encoding == "UTF-32BE" ||
4686 encoding == "UTF-32LE" )
4687 {
4688 iconvLenMultiplier = 4;
4689 }
4690
4691 iconvBufferLen = iconvBufferLeft =
4692 utf8BufferLen * iconvLenMultiplier + 4; // worst case scenario
4693
4694 char *finalBuffer;
4695 char *iconvBuffer;
4696
4697 utf8BufferLeft = utf8BufferLen;
4698 iconvBuffer = new char[iconvBufferLen];
4699 finalBuffer = iconvBuffer; // iconvBuffer will be incremented by iconv
4700 size_t nconv;
4701
4702 char *utf8BufferPtr = ( char * ) utf8Buffer.c_str();
4703
4704 nconv = reinterpret_cast < universal_iconv & > ( iconv ) (
4705 cd,
4706 &utf8BufferPtr,
4707 &utf8BufferLeft,
4708 &iconvBuffer,
4709 &iconvBufferLeft );
4710
4711 iconv_close ( cd );
4712
4713 if ( nconv == ( size_t )-1 ) // conversion failed
4714 {
4715 delete[] finalBuffer;
4716 success = saveRawUtf8 ( fileNameLocal, utf8Buffer, false, isXml );
4717 if ( success )
4718 {
4719 bytes = utf8Buffer.size();
4720 wxString message;
4721 message.Printf (
4722 _ ( "%s saved in default encoding UTF-8: conversion to %s failed" ),
4723 fileName.c_str(),
4724 wideEncoding.c_str() );
4725 messagePane ( message, CONST_WARNING );
4726 }
4727 else
4728 {
4729 wxString message;
4730 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4731 messagePane ( message, CONST_STOP );
4732 return false;
4733 }
4734 }
4735 else
4736 {
4737 size_t finalBufferLen = iconvBufferLen - iconvBufferLeft;
4738
4739 std::ofstream ofs ( fileNameLocal.c_str(), std::ios::out | std::ios::binary );
4740 if ( !ofs )
4741 {
4742 delete[] finalBuffer;
4743 wxString message;
4744 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4745 messagePane ( message, CONST_STOP );
4746 return false;
4747 }
4748
4749 // iconv adds boms for UTF-16 & UTF-32 automatically
4750
4751 ofs.write ( finalBuffer, finalBufferLen );
4752 ofs.close();
4753 delete[] finalBuffer;
4754 bytes = finalBufferLen;
4755 }
4756 }
4757 }
4758 else // all other encodings handled by Libxml
4759 {
4760 boost::scoped_ptr<WrapLibxml> wl ( new WrapLibxml ( libxmlNetAccess ) );
4761 int result = wl->saveEncoding ( utf8Buffer,
4762 doc->getFullFileName(), fileName, NULL, wideEncoding );
4763 if ( result == -1 )
4764 {
4765 success = saveRawUtf8 ( fileNameLocal, utf8Buffer, false, isXml );
4766 if ( success )
4767 {
4768 wxString wideError = wl->getLastError();
4769 bytes = utf8Buffer.size();
4770 wxString msg;
4771 if ( wideError.empty() )
4772 wideError = _ ( "unknown error" );
4773
4774 msg.Printf ( _ ( "Cannot save document in %s: %s (saved in default encoding UTF-8)" ),
4775 wideEncoding.c_str(), wideError.c_str() );
4776 messagePane ( msg, CONST_INFO );
4777 }
4778 else
4779 {
4780 wxString message;
4781 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4782 messagePane ( message, CONST_STOP );
4783 return false;
4784 }
4785 }
4786 else
4787 bytes = result;
4788 }
4789 }
4790 } // try
4791 catch ( std::bad_alloc& )
4792 {
4793 if ( encoding != "UTF-8" )
4794 {
4795 int answer = wxMessageBox (
4796 _ ( "Out of memory: attempt to save in default encoding UTF-8?" ),
4797 _ ( "Out of memory" ),
4798 wxYES_NO | wxCANCEL | wxICON_QUESTION,
4799 this );
4800 if ( answer == wxCANCEL || answer == wxNO )
4801 return false;
4802
4803 bool success = saveRawUtf8 ( fileNameLocal, utf8Buffer, true, isXml );
4804 if ( success )
4805 {
4806 bytes = utf8Buffer.size();
4807 wxString message;
4808 message.Printf (
4809 _ ( "%s saved in default encoding UTF-8" ),
4810 fileName.c_str() );
4811 messagePane ( message, CONST_INFO );
4812 }
4813 else
4814 {
4815 wxString message;
4816 message.Printf ( _ ( "Cannot save %s" ), fileName.c_str() );
4817 messagePane ( message, CONST_STOP );
4818 return false;
4819 }
4820 }
4821 }
4822
4823 doc->SetFocus();
4824 doc->SetSavePoint();
4825
4826 if ( properties.validateAsYouType && isXml )
4827 {
4828 doc->clearErrorIndicators();
4829 //doc->backgroundValidate ( utf8Buffer.c_str(), doc->getFullFileName().mb_str(wxConvUTF8), utf8Buffer.size() );
4830 doc->backgroundValidate();
4831 }
4832
4833 if ( !unlimitedUndo )
4834 doc->EmptyUndoBuffer();
4835 wxFileName fn ( fileName );
4836 if ( fn.IsOk() )
4837 doc->setLastModified ( fn.GetModificationTime() );
4838 openFileSet.insert ( fileName );
4839 displaySavedStatus ( bytes );
4840 return true;
4841 }
4842
saveRawUtf8(const std::string & fileNameLocal,std::string & bufferUtf8,bool ignoreEncoding,bool isXml)4843 bool MyFrame::saveRawUtf8 (
4844 const std::string& fileNameLocal,
4845 std::string& bufferUtf8,
4846 bool ignoreEncoding,
4847 bool isXml )
4848 {
4849 ofstream ofs ( fileNameLocal.c_str(), std::ios::out | std::ios::binary );
4850 if ( !ofs )
4851 return false;
4852
4853 if ( !ignoreEncoding && isXml )
4854 XmlEncodingHandler::setUtf8 ( bufferUtf8, true );
4855
4856 if ( saveBom && isXml )
4857 {
4858 static const char bom[4] = "\xEF\xBB\xBF";
4859 ofs.write ( bom, 3 );
4860 }
4861 ofs.write ( bufferUtf8.c_str(), bufferUtf8.size() );
4862 ofs.close();
4863 return true;
4864 }
4865
displaySavedStatus(int bytes)4866 void MyFrame::displaySavedStatus ( int bytes )
4867 {
4868 wxString unit;
4869 float result = 0;
4870 if ( bytes > 1000000 )
4871 {
4872 result = bytes / 1000000;
4873 unit = _ ( "MB" );
4874 }
4875 else if ( bytes > 1000 )
4876 {
4877 result = bytes / 1000;
4878 unit = _ ( "kB" );
4879 }
4880 else if ( bytes >= 0 )
4881 {
4882 result = bytes;
4883 unit = wxPLURAL ( "byte", "bytes", bytes );
4884 }
4885 else
4886 return;
4887
4888 wxString msg;
4889
4890 msg.Printf (
4891 _ ( "%g %s saved" ),
4892 result,
4893 unit.c_str() );
4894 statusProgress ( msg );
4895 }
4896
getHandleCommandLineFlag()4897 bool MyFrame::getHandleCommandLineFlag()
4898 {
4899 return handleCommandLineFlag;
4900 }
4901
getMenuBar()4902 wxMenuBar *MyFrame::getMenuBar()
4903 {
4904 fileMenu = new wxMenu; // use class-wide data member
4905 updateFileMenu ( false );
4906
4907 // edit menu
4908 wxMenu *editMenu = new wxMenu;
4909
4910 wxMenuItem *undoItem =
4911 new wxMenuItem ( editMenu, wxID_UNDO, _ ( "&Undo\tCtrl+Z" ), _ ( "Undo" ) );
4912 undoItem->SetBitmap ( undo16Bitmap );
4913
4914 wxMenuItem *redoItem =
4915 new wxMenuItem ( editMenu, wxID_REDO, _ ( "&Redo\tCtrl+Y" ), _ ( "Redo" ) );
4916 redoItem->SetBitmap ( redo16Bitmap );
4917
4918 wxMenuItem *cutItem =
4919 new wxMenuItem ( editMenu, wxID_CUT, _ ( "&Cut\tCtrl+X" ), _ ( "Cut" ) );
4920 cutItem->SetBitmap ( cutBitmap );
4921
4922 wxMenuItem *copyItem =
4923 new wxMenuItem ( editMenu, wxID_COPY, _ ( "C&opy\tCtrl+C" ), _ ( "Copy" ) );
4924 copyItem->SetBitmap ( copyBitmap );
4925
4926 wxMenuItem *pasteItem =
4927 new wxMenuItem ( editMenu, wxID_PASTE, _ ( "&Paste\tCtrl+V" ), _ ( "Paste" ) );
4928 pasteItem->SetBitmap ( pasteBitmap );
4929
4930 wxMenuItem *pasteNewDocumentItem =
4931 new wxMenuItem (
4932 editMenu,
4933 ID_PASTE_NEW_DOCUMENT,
4934 _ ( "P&aste As New Document" ),
4935 _ ( "Paste As New Document" ) );
4936 pasteNewDocumentItem->SetBitmap ( wxNullBitmap );
4937
4938 wxMenuItem *findItem =
4939 new wxMenuItem ( editMenu, ID_FIND, _ ( "&Find...\tCtrl+F" ), _ ( "Find..." ) );
4940 findItem->SetBitmap ( searchBitmap );
4941
4942 wxMenuItem *findAgainItem =
4943 new wxMenuItem ( editMenu, ID_FIND_AGAIN, _ ( "F&ind Again\tF3" ), _ ( "Find Again" ) );
4944 findAgainItem->SetBitmap ( wxNullBitmap );
4945
4946 wxMenuItem *replaceItem =
4947 new wxMenuItem ( editMenu, ID_REPLACE, _ ( "&Replace...\tCtrl+R" ), _ ( "Replace..." ) );
4948 replaceItem->SetBitmap ( wxNullBitmap );
4949
4950 wxMenuItem *globalReplaceItem =
4951 new wxMenuItem (
4952 editMenu,
4953 ID_GLOBAL_REPLACE,
4954 _ ( "&Global Replace...\tCtrl+Shift+R" ),
4955 _ ( "Global Replace..." ) );
4956 globalReplaceItem->SetBitmap ( wxNullBitmap );
4957
4958 wxMenuItem *gotoItem =
4959 new wxMenuItem ( editMenu, ID_GOTO, _ ( "G&o To...\tCtrl+G" ), _ ( "Go To..." ) );
4960 gotoItem->SetBitmap ( wxNullBitmap );
4961
4962 wxMenuItem *commentItem =
4963 new wxMenuItem ( editMenu, ID_TOGGLE_COMMENT, _ ( "&Toggle Comment\tCtrl+/" ), _ ( "Toggle Comment" ) );
4964 commentItem->SetBitmap ( wxNullBitmap );
4965
4966 editMenu->Append ( undoItem );
4967 editMenu->Append ( redoItem );
4968 editMenu->AppendSeparator();
4969 editMenu->Append ( cutItem );
4970 editMenu->Append ( copyItem );
4971 editMenu->Append ( pasteItem );
4972 editMenu->Append ( pasteNewDocumentItem );
4973 editMenu->AppendSeparator();
4974 editMenu->Append ( findItem );
4975 editMenu->Append ( findAgainItem );
4976 editMenu->Append ( replaceItem );
4977 editMenu->Append ( globalReplaceItem );
4978 editMenu->Append ( gotoItem );
4979 editMenu->AppendSeparator();
4980 editMenu->Append ( commentItem );
4981
4982 #ifndef __WXMSW__
4983 wxMenuItem *preferencesItem =
4984 new wxMenuItem ( editMenu, ID_OPTIONS, _ ( "Pr&eferences..." ), _ ( "Preferences..." ) );
4985 editMenu->AppendSeparator();
4986 editMenu->Append ( preferencesItem );
4987 #endif
4988
4989 // font size menu
4990 wxMenu *fontSizeMenu = new wxMenu;
4991 fontSizeMenu->Append (
4992 ID_FONT_LARGER, _ ( "Increase\tCtrl+U" ), _ ( "Increase" ) );
4993 fontSizeMenu->Append (
4994 ID_FONT_SMALLER, _ ( "Decrease\tCtrl+D" ), _ ( "Decrease" ) );
4995 fontSizeMenu->AppendSeparator();
4996 fontSizeMenu->Append ( ID_FONT_NORMAL, _ ( "Normal\tCtrl+0" ), _ ( "Normal" ) );
4997
4998 // color scheme menu
4999 colorSchemeMenu = new wxMenu;
5000 colorSchemeMenu->AppendRadioItem (
5001 ID_COLOR_SCHEME_DEFAULT, _ ( "&Default" ), _ ( "Default" ) );
5002 colorSchemeMenu->AppendRadioItem (
5003 ID_COLOR_SCHEME_REDUCED_GLARE,
5004 _ ( "&Blue background, white text" ),
5005 _ ( "Blue background, white text" ) );
5006 colorSchemeMenu->AppendRadioItem (
5007 ID_COLOR_SCHEME_DEFAULT_BACKGROUND,
5008 _ ( "&Light" ),
5009 _ ( "Light" ) );
5010 colorSchemeMenu->AppendRadioItem (
5011 ID_COLOR_SCHEME_NONE,
5012 _ ( "&None" ),
5013 _ ( "None" ) );
5014
5015 switch ( properties.colorScheme )
5016 {
5017 case COLOR_SCHEME_DEFAULT:
5018 colorSchemeMenu->Check ( ID_COLOR_SCHEME_DEFAULT, true );
5019 break;
5020 case COLOR_SCHEME_DEFAULT_BACKGROUND:
5021 colorSchemeMenu->Check ( ID_COLOR_SCHEME_DEFAULT_BACKGROUND, true );
5022 break;
5023 case COLOR_SCHEME_REDUCED_GLARE:
5024 colorSchemeMenu->Check ( ID_COLOR_SCHEME_REDUCED_GLARE, true );
5025 break;
5026 case COLOR_SCHEME_NONE:
5027 colorSchemeMenu->Check ( ID_COLOR_SCHEME_NONE, true );
5028 break;
5029 default:
5030 break;
5031 }
5032
5033 /* WAIT FOR AUI LIBRARY TO SUPPORT THIS - currently always splits left
5034 wxMenu *splitTabMenu = new wxMenu;
5035 splitTabMenu->Append ( ID_SPLIT_TAB_TOP, _ ( "&Top" ), _ ( "Top" ));
5036 splitTabMenu->Append ( ID_SPLIT_TAB_RIGHT, _ ( "&Right" ), _ ( "Right" ));
5037 splitTabMenu->Append ( ID_SPLIT_TAB_BOTTOM, _ ( "&Bottom" ), _ ( "Bottom" ));
5038 splitTabMenu->Append ( ID_SPLIT_TAB_LEFT, _ ( "&Left" ), _ ( "Left" ));
5039 */
5040
5041 viewMenu = new wxMenu; // use class-wide data member
5042 viewMenu->Append ( ID_PREVIOUS_DOCUMENT, _ ( "&Previous Document\tCtrl+PgUp" ), _ ( "Previous Document" ) );
5043 viewMenu->Append ( ID_NEXT_DOCUMENT, _ ( "&Next Document\tCtrl+PgDn" ), _ ( "Next Document" ) );
5044
5045 //viewMenu->Append ( wxID_ANY, _ ( "&Split Tab" ), splitTabMenu );
5046
5047 viewMenu->Append ( ID_BROWSER, _ ( "&Browser\tCtrl+B" ), _ ( "Browser" ) );
5048 viewMenu->AppendSeparator();
5049 viewMenu->AppendRadioItem (
5050 ID_SHOW_TAGS,
5051 _ ( "&Show Tags and Attributes\tCtrl+T" ), _ ( "Show Tags and Attributes" ) );
5052 viewMenu->AppendRadioItem (
5053 ID_HIDE_ATTRIBUTES,
5054 _ ( "&Hide Attributes Only\tCtrl+Shift+A" ), _ ( "Hide Attributes Only" ) );
5055 viewMenu->AppendRadioItem (
5056 ID_HIDE_TAGS,
5057 _ ( "H&ide Tags and Attributes\tCtrl+Shift+T" ), _ ( "Hide Tags and Attributes" ) );
5058
5059 switch ( visibilityState )
5060 {
5061 case SHOW_TAGS:
5062 viewMenu->Check ( ID_SHOW_TAGS, true );
5063 break;
5064 case HIDE_TAGS:
5065 viewMenu->Check ( ID_HIDE_TAGS, true );
5066 break;
5067 case HIDE_ATTRIBUTES:
5068 viewMenu->Check ( ID_HIDE_ATTRIBUTES, true );
5069 break;
5070 default:
5071 viewMenu->Check ( ID_SHOW_TAGS, true );
5072 break;
5073 }
5074 viewMenu->AppendSeparator();
5075 viewMenu->Append (
5076 ID_TOGGLE_FOLD, _ ( "&Toggle Fold\tCtrl+Alt+T" ), _ ( "Toggle Fold" ) );
5077 viewMenu->Append (
5078 ID_FOLD_ALL, _ ( "&Fold Tags\tCtrl+Shift+F" ), _ ( "Fold Tags" ) );
5079 viewMenu->Append (
5080 ID_UNFOLD_ALL, _ ( "&Unfold Tags\tCtrl+Shift+U" ), _T ( "Unfold Tags" ) );
5081 viewMenu->AppendSeparator();
5082 viewMenu->AppendCheckItem (
5083 ID_WRAP_WORDS, _ ( "&Wrap Words" ), _T ( "Wrap Words" ) );
5084 viewMenu->Check ( ID_WRAP_WORDS, properties.wrap );
5085 viewMenu->Append ( wxID_ANY, _ ( "&Color Scheme" ), colorSchemeMenu );
5086 viewMenu->Append ( wxID_ANY, _ ( "&Text Size" ), fontSizeMenu );
5087 viewMenu->AppendSeparator();
5088
5089 viewMenu->AppendCheckItem (
5090 ID_LOCATION_PANE_VISIBLE,
5091 _ ( "S&how Current Element Pane" ),
5092 _ ( "Show Current Element Pane" ) );
5093 viewMenu->Check ( ID_LOCATION_PANE_VISIBLE, false );
5094 #ifndef __WXOSX__
5095 viewMenu->AppendCheckItem (
5096 ID_TOOLBAR_VISIBLE, _ ( "Sh&ow Toolbar" ), _ ( "Show Toolbar" ) );
5097 viewMenu->Check ( ID_TOOLBAR_VISIBLE, toolbarVisible );
5098 #endif
5099 viewMenu->Append ( ID_CLOSE_MESSAGE_PANE,
5100 _ ( "C&lose Message Pane\tAlt+C" ), _ ( "Close Message Pane" ) );
5101 viewMenu->Append ( ID_CLOSE_FIND_REPLACE_PANE,
5102 _ ( "Close Find/&Replace Pane" ), _ ( "Close Find/Replace Pane" ) );
5103 viewMenu->Append ( ID_CLOSE_COMMAND_PANE,
5104 _ ( "Close Co&mmand Pane" ), _ ( "Close Command Pane" ) );
5105
5106 // insert menu
5107 wxMenu *insertMenu = new wxMenu;
5108 insertMenu->Append ( ID_INSERT_CHILD, _ ( "&Element...\tCtrl+I" ), _ ( "Element..." ) );
5109 insertMenu->Append ( ID_INSERT_SIBLING, _ ( "&Sibling...\tCtrl+Shift+I" ), _ ( "Sibling..." ) );
5110 insertMenu->Append ( ID_INSERT_ENTITY, _ ( "&Entity...\tCtrl+E" ), _ ( "Entity..." ) );
5111 insertMenu->AppendSeparator();
5112 insertMenu->Append ( ID_INSERT_TWIN, _ ( "&Twin\tCtrl+Enter" ), _ ( "Twin" ) );
5113 insertMenu->AppendSeparator();
5114 insertMenu->Append ( ID_INSERT_SYMBOL, _ ( "S&ymbol..." ), _ ( "Symbol..." ) );
5115
5116 // validation menu
5117 wxMenu *validationMenu = new wxMenu;
5118 /*
5119 validationMenu->Append ( ID_VALIDATE_DTD, _ ( "&DTD\tF4" ), _ ( "DTD" ) );
5120 */
5121 validationMenu->Append (
5122 ID_VALIDATE_W3C_SCHEMA, _ ( "&DTD/XML Schema\tF5" ), _ ( "DTD/XML Schema" ) );
5123 validationMenu->AppendSeparator();
5124 validationMenu->Append (
5125 ID_VALIDATE_RELAX_NG, _ ( "&RELAX NG...\tF6" ), _ ( "RELAX NG..." ) );
5126
5127 wxMenu *associateMenu = new wxMenu;
5128 associateMenu->Append ( ID_ASSOCIATE_DTD_PUBLIC, _ ( "&Public DTD..." ), _ ( "Public DTD..." ) );
5129 associateMenu->Append ( ID_ASSOCIATE_DTD_SYSTEM, _ ( "&System DTD..." ), _ ( "System DTD..." ) );
5130 associateMenu->Append ( ID_ASSOCIATE_W3C_SCHEMA, _ ( "&XML Schema..." ), _ ( "XML Schema..." ) );
5131 associateMenu->Append ( ID_ASSOCIATE_XSL, _ ( "XS< stylesheet..." ), _ ( "XSLT stylesheet..." ) );
5132
5133 if ( wxDirExists ( rngDir ) )
5134 {
5135 wxString rngMask, rngFile, rngUrl, displayName, shortcutString;
5136 rngMask = rngDir + wxFileName::GetPathSeparator() + _T ( "*.rng" );
5137 rngFile = wxFindFirstFile ( rngMask, wxFILE );
5138
5139 int id = ID_VALIDATE_PRESET1;
5140
5141 while ( id <= ID_VALIDATE_PRESET9 && !rngFile.empty() )
5142 {
5143 rngUrl = WrapLibxml::FileNameToURL ( rngFile );
5144 validationPresetMap.insert ( make_pair ( id, rngUrl ) );
5145 wxFileName::SplitPath ( rngFile, NULL, NULL, &displayName, NULL );
5146 displayName.Replace ( _T ( ".rng" ), _T ( "" ) );
5147 shortcutString.Printf ( _ ( "\tCtrl+%i" ), ( id - ID_VALIDATE_PRESET1 ) + 1 );
5148
5149 validationMenu->Append ( id, displayName + shortcutString, displayName );
5150
5151 id++;
5152 rngFile = wxFindNextFile();
5153 }
5154 }
5155
5156 // xsl menu
5157 /*
5158 wxMenu *xslMenu = new wxMenu;
5159 xslMenu->Append ( ID_XSLT, _ ( "&XSL Transform...\tF8" ),
5160 _ ( "XSL Transform..." ) );
5161 xslMenu->AppendSeparator();
5162 xslMenu->Append (
5163 ID_XSLT_DOCBOOK_HTML,
5164 _ ( "&DocBook to HTML\tAlt+1" ), _ ( "DocBook to HTML" ) );
5165 xslMenu->Append (
5166 ID_XSLT_DOCBOOK_XHTML,
5167 _ ( "&DocBook to XHTML\tAlt+2" ), _ ( "DocBook to XHTML" ) );
5168 xslMenu->Append (
5169 ID_XSLT_DOCBOOK_FO,
5170 _ ( "D&ocBook to XSL-FO\tAlt+3" ), _ ( "DocBook to XSL-FO" ) );
5171 xslMenu->Append (
5172 ID_XSLT_TEI_HTML,
5173 _ ( "&TEI to HTML\tAlt+4" ), _ ( "TEI to HTML" ) );
5174 xslMenu->Append (
5175 ID_XSLT_TEI_LATEX,
5176 _ ( "T&EI to LaTeX\tAlt+5" ), _ ( "TEI to LaTeX" ) );
5177 xslMenu->Append (
5178 ID_XSLT_TEI_XHTML,
5179 _ ( "TE&I to XHTML\tAlt+6" ), _ ( "TEI to XHTML" ) );
5180 xslMenu->Append (
5181 ID_XSLT_TEI_FO,
5182 _ ( "TEI to &XSL-FO\tAlt+7" ), _ ( "TEI to XSL-FO" ) );
5183 */
5184
5185 // xml menu
5186 xmlMenu = new wxMenu; // use class-wide data member
5187 xmlMenu->Append (
5188 ID_CHECK_WELLFORMED,
5189 _ ( "&Check Well-formedness\tF2" ), _ ( "Check Well-formedness" ) );
5190 xmlMenu->Append (
5191 wxID_ANY,
5192 _ ( "&Validate" ),
5193 validationMenu );
5194 xmlMenu->Append ( ID_CREATE_SCHEMA, _ ( "Create &Schema...\tF10" ),
5195 _ ( "Create schema..." ) );
5196 xmlMenu->Append ( ID_DTD_TO_SCHEMA, _ ( "DTD -> Schema..." ),
5197 _ ( "DTD -> Schema..." ) );
5198 xmlMenu->AppendSeparator();
5199 xmlMenu->Append (
5200 wxID_ANY,
5201 _ ( "&Associate" ),
5202 associateMenu );
5203 xmlMenu->AppendSeparator();
5204 xmlMenu->Append ( ID_XSLT, _ ( "&XSL Transform...\tF8" ),
5205 _ ( "XSL Transform..." ) );
5206 xmlMenu->Append (
5207 ID_XPATH,
5208 _ ( "&Evaluate XPath...\tF9" ),
5209 _ ( "Evaluate XPath..." ) );
5210 xmlMenu->Append (
5211 ID_COPY_XPATH,
5212 _ ( "Copy &The Current XPath" ),
5213 _ ( "Copy The Current XPath" ) );
5214
5215 xmlMenu->AppendSeparator();
5216 xmlMenu->Append (
5217 ID_PRETTYPRINT,
5218 _ ( "&Pretty-print\tF11" ), _ ( "Pretty-print" ) );
5219 xmlMenu->AppendSeparator();
5220 xmlMenu->AppendCheckItem (
5221 ID_PROTECT_TAGS,
5222 _ ( "&Lock Tags\tCtrl+L" ),
5223 _ ( "Lock Tags" ) );
5224 xmlMenu->Check ( ID_PROTECT_TAGS, protectTags );
5225 xmlMenu->AppendSeparator();
5226 xmlMenu->Append (
5227 ID_ENCODING,
5228 _ ( "E&ncoding..." ), _ ( "Encoding..." ) );
5229
5230 // tools menu
5231 wxMenu *toolsMenu = new wxMenu;
5232
5233 wxMenuItem *spellingItem =
5234 new wxMenuItem (
5235 toolsMenu,
5236 ID_SPELL,
5237 _ ( "&Spelling...\tF7" ),
5238 _ ( "Spelling..." ) );
5239 spellingItem->SetBitmap ( spelling16Bitmap );
5240
5241 wxMenuItem *styleItem =
5242 new wxMenuItem (
5243 toolsMenu,
5244 ID_STYLE,
5245 _ ( "&Style...\tShift+F7" ),
5246 _ ( "Style..." ) );
5247 styleItem->SetBitmap ( wxNullBitmap );
5248
5249 wxMenuItem *wordCountItem =
5250 new wxMenuItem (
5251 toolsMenu,
5252 ID_WORD_COUNT,
5253 _ ( "&Word Count" ),
5254 _ ( "Word Count" ) );
5255 wordCountItem->SetBitmap ( wxNullBitmap );
5256
5257
5258 wxMenuItem *commandItem =
5259 new wxMenuItem (
5260 toolsMenu,
5261 ID_COMMAND,
5262 _ ( "&Command\tCtrl+Alt+C" ),
5263 _ ( "Command" ) );
5264 commandItem->SetBitmap ( wxNullBitmap );
5265
5266 toolsMenu->Append ( spellingItem );
5267 toolsMenu->Append ( styleItem );
5268 toolsMenu->Append ( wordCountItem );
5269 toolsMenu->AppendSeparator();
5270 toolsMenu->Append ( commandItem );
5271
5272 #ifdef __WXMSW__
5273 toolsMenu->AppendSeparator();
5274 wxMenuItem *optionsItem =
5275 new wxMenuItem (
5276 toolsMenu,
5277 ID_OPTIONS,
5278 _ ( "&Options..." ),
5279 _ ( "Options..." ) );
5280 optionsItem->SetBitmap ( wxNullBitmap );
5281 toolsMenu->Append ( optionsItem );
5282 #endif
5283
5284 // help menu
5285 wxMenu *helpMenu = new wxMenu;
5286
5287 wxMenuItem *helpItem =
5288 new wxMenuItem ( helpMenu, wxID_HELP,
5289 _ ( "&XML Copy Editor Help\tF1" ), _ ( "Help" ) );
5290 helpItem->SetBitmap ( helpBitmap );
5291
5292
5293 wxMenuItem *homeItem =
5294 new wxMenuItem ( helpMenu, ID_HOME,
5295 _ ( "&Home Page" ), _ ( "Home Page" ) );
5296 homeItem->SetBitmap ( wxNullBitmap );
5297 wxMenuItem *feedbackItem =
5298 new wxMenuItem ( helpMenu, ID_FEEDBACK, _ ( "&Forum" ), _ ( "Forum" ) );
5299 feedbackItem->SetBitmap ( wxNullBitmap );
5300 wxMenuItem *aboutItem =
5301 new wxMenuItem ( helpMenu, wxID_ABOUT,
5302 _ ( "&About XML Copy Editor" ), _ ( "About" ) );
5303 aboutItem->SetBitmap ( wxNullBitmap );
5304 wxMenuItem *downloadSourceItem =
5305 new wxMenuItem ( helpMenu, ID_DOWNLOAD_SOURCE,
5306 _ ( "&Browse Source" ), _ ( "Browse Source" ) );
5307 downloadSourceItem->SetBitmap ( wxNullBitmap );
5308 helpMenu->Append ( helpItem );
5309
5310 helpMenu->AppendSeparator();
5311 helpMenu->Append ( homeItem );
5312 helpMenu->Append ( feedbackItem );
5313 helpMenu->Append ( downloadSourceItem );
5314 helpMenu->AppendSeparator();
5315 helpMenu->Append ( aboutItem );
5316
5317 wxMenuBar *menuBar = new wxMenuBar ( wxMB_DOCKABLE );
5318 menuBar->Append ( fileMenu, _ ( "&File" ) );
5319 menuBar->Append ( editMenu, _ ( "&Edit" ) );
5320 menuBar->Append ( viewMenu, _ ( "&View" ) );
5321 menuBar->Append ( insertMenu, _ ( "&Insert" ) );
5322 menuBar->Append ( xmlMenu, _ ( "&XML" ) );
5323 menuBar->Append ( toolsMenu, _ ( "&Tools" ) );
5324 menuBar->Append ( helpMenu, _ ( "&Help" ) );
5325 return menuBar;
5326 }
5327
updateFileMenu(bool deleteExisting)5328 void MyFrame::updateFileMenu ( bool deleteExisting )
5329 {
5330 if ( deleteExisting )
5331 {
5332 wxMenuItemList list = fileMenu->GetMenuItems();
5333 size_t count = list.size();
5334 for ( size_t i = 0; i < count; ++i )
5335 fileMenu->Delete ( list[i] );
5336 }
5337
5338 wxMenuItem *newItem =
5339 new wxMenuItem ( fileMenu, wxID_NEW, _ ( "&New...\tCtrl+N" ), _ ( "New..." ) );
5340 newItem->SetBitmap ( new16Bitmap );
5341 wxMenuItem *openItem =
5342 new wxMenuItem ( fileMenu, wxID_OPEN, _ ( "&Open...\tCtrl+O" ), _ ( "Open..." ) );
5343 openItem->SetBitmap ( open16Bitmap );
5344 wxMenuItem *openLargeFileItem =
5345 new wxMenuItem ( fileMenu, ID_OPEN_LARGE_FILE,
5346 _ ( "O&pen Large Document...\tCtrl+Shift+O" ), _ ( "Open Large Document..." ) );
5347 openLargeFileItem->SetBitmap ( wxNullBitmap );
5348
5349 wxMenuItem *closeItem =
5350 new wxMenuItem ( fileMenu, wxID_CLOSE, _ ( "&Close\tCtrl+W" ), _ ( "Close" ) );
5351 closeItem->SetBitmap ( wxNullBitmap );
5352 wxMenuItem *closeAllItem =
5353 new wxMenuItem ( fileMenu, wxID_CLOSE_ALL, _ ( "C&lose All" ), _ ( "Close All" ) );
5354 closeAllItem->SetBitmap ( wxNullBitmap );
5355 wxMenuItem *saveItem =
5356 new wxMenuItem ( fileMenu, wxID_SAVE, _ ( "&Save\tCtrl+S" ), _ ( "Save" ) );
5357 saveItem->SetBitmap ( save16Bitmap );
5358 wxMenuItem *saveAsItem =
5359 new wxMenuItem ( fileMenu, wxID_SAVEAS, _ ( "S&ave As...\tF12" ), _ ( "Save As..." ) );
5360 saveAsItem->SetBitmap ( wxNullBitmap );
5361 #ifdef __WXMSW__
5362 wxMenuItem *exportItem =
5363 new wxMenuItem ( fileMenu, ID_EXPORT, _ ( "&DAISY Export..." ), _ ( "DAISY Export..." ) );
5364 exportItem->SetBitmap ( wxNullBitmap );
5365 #endif
5366 wxMenuItem *reloadItem =
5367 new wxMenuItem ( fileMenu, ID_RELOAD, _ ( "&Reload" ), _ ( "Reload" ) );
5368 reloadItem->SetBitmap ( wxNullBitmap );
5369 wxMenuItem *revertItem =
5370 new wxMenuItem ( fileMenu, wxID_REVERT, _ ( "&Revert" ), _ ( "Revert" ) );
5371 revertItem->SetBitmap ( wxNullBitmap );
5372 wxMenuItem *printSetupItem =
5373 new wxMenuItem ( fileMenu, ID_PRINT_SETUP, _ ( "Pa&ge Setup..." ), _ ( "Page Setup..." ) );
5374 printSetupItem->SetBitmap ( wxNullBitmap );
5375 wxMenuItem *printPreviewItem =
5376 new wxMenuItem ( fileMenu, ID_PRINT_PREVIEW, _ ( "Pr&int Preview..." ), _ ( "Print Preview..." ) );
5377 printPreviewItem->SetBitmap ( printPreviewBitmap );
5378 wxMenuItem *printItem =
5379 new wxMenuItem ( fileMenu, ID_PRINT, _ ( "Pri&nt...\tCtrl+P" ), _ ( "Print..." ) );
5380 printItem->SetBitmap ( print16Bitmap );
5381 wxMenuItem *importMSWordItem =
5382 new wxMenuItem (
5383 fileMenu, ID_IMPORT_MSWORD, _ ( "I&mport Microsoft Word Document..." ) );
5384 importMSWordItem->SetBitmap ( wxNullBitmap );
5385 wxMenuItem *exportMSWordItem =
5386 new wxMenuItem (
5387 fileMenu, ID_EXPORT_MSWORD, _ ( "Expor&t Microsoft Word Document..." ) );
5388 exportMSWordItem->SetBitmap ( wxNullBitmap );
5389
5390 wxMenuItem *exitItem =
5391 new wxMenuItem ( fileMenu, wxID_EXIT, _ ( "E&xit" ), _ ( "Exit" ) );
5392 exitItem->SetBitmap ( wxNullBitmap );
5393
5394 fileMenu->Append ( newItem );
5395 fileMenu->Append ( openItem );
5396 fileMenu->Append ( openLargeFileItem );
5397 fileMenu->AppendSeparator();
5398 fileMenu->Append ( closeItem );
5399 fileMenu->Append ( closeAllItem );
5400 fileMenu->Append ( saveItem );
5401 fileMenu->Append ( saveAsItem );
5402 fileMenu->AppendSeparator();
5403 fileMenu->Append ( reloadItem );
5404 fileMenu->Append ( revertItem );
5405 fileMenu->AppendSeparator();
5406 fileMenu->Append ( printSetupItem );
5407 fileMenu->Append ( printPreviewItem );
5408 fileMenu->Append ( printItem );
5409 #ifdef __WXMSW__
5410 fileMenu->AppendSeparator();
5411 fileMenu->Append ( exportItem );
5412 fileMenu->Append ( importMSWordItem );
5413 fileMenu->Append ( exportMSWordItem );
5414 #endif
5415 history.AddFilesToMenu ( fileMenu );
5416
5417 fileMenu->AppendSeparator();
5418 fileMenu->Append ( exitItem );
5419 }
5420
getToolBar()5421 wxToolBar *MyFrame::getToolBar()
5422 {
5423 wxToolBar *toolBar = new wxToolBar (
5424 this,
5425 ID_TOOLBAR,
5426 wxDefaultPosition,
5427 wxDefaultSize,
5428 wxTB_FLAT |
5429 wxTB_HORIZONTAL |
5430 wxTB_DOCKABLE );
5431 int w, h;
5432 w = saveBitmap.GetWidth(), h = saveBitmap.GetHeight();
5433 toolBar->SetToolBitmapSize ( wxSize ( w, h ) );
5434
5435 toolBar->AddTool (
5436 wxID_NEW,
5437 _ ( "New" ),
5438 newBitmap,
5439 _ ( "New" ) );
5440 toolBar->AddTool (
5441 wxID_OPEN,
5442 _ ( "Open" ),
5443 openBitmap,
5444 _ ( "Open" ) );
5445 toolBar->AddTool (
5446 wxID_SAVE,
5447 _ ( "Save" ),
5448 saveBitmap,
5449 wxNullBitmap,
5450 wxITEM_NORMAL,
5451 _ ( "Save" ) );
5452 #ifndef __WXOSX__
5453 toolBar->AddTool (
5454 ID_PRINT,
5455 _ ( "Print" ),
5456 printBitmap,
5457 wxNullBitmap,
5458 wxITEM_NORMAL,
5459 _ ( "Print" ) );
5460 toolBar->AddTool (
5461 ID_CHECK_WELLFORMED,
5462 _ ( "Check Well-formedness" ),
5463 checkWellformedBitmap,
5464 wxNullBitmap,
5465 wxITEM_NORMAL,
5466 _ ( "Check Well-formedness" ) );
5467 toolBar->AddTool (
5468 ID_VALIDATE_W3C_SCHEMA,
5469 _ ( "Validate" ),
5470 checkValidBitmap,
5471 wxNullBitmap,
5472 wxITEM_NORMAL,
5473 _ ( "Validate" ) );
5474 toolBar->AddTool (
5475 ID_BROWSER,
5476 _ ( "Browser" ),
5477 internetBitmap,
5478 wxNullBitmap,
5479 wxITEM_NORMAL,
5480 _ ( "Browser" ) );
5481 toolBar->AddTool (
5482 ID_SPELL,
5483 _ ( "Spelling" ),
5484 spellingBitmap,
5485 wxNullBitmap,
5486 wxITEM_NORMAL,
5487 _ ( "Spelling" ) );
5488 toolBar->AddCheckTool (
5489 ID_PROTECT_TAGS,
5490 _ ( "Lock Tags" ),
5491 hyperlinkBitmap,
5492 wxNullBitmap,
5493 _ ( "Lock Tags" ) );
5494 toolBar->ToggleTool (
5495 ID_PROTECT_TAGS, protectTags );
5496 #endif
5497
5498 toolBar->Realize();
5499 return toolBar;
5500 }
5501
getActiveDocument()5502 XmlDoc *MyFrame::getActiveDocument()
5503 {
5504 if ( !mainBook->GetPageCount() )
5505 return NULL;
5506 return ( XmlDoc * ) mainBook->GetPage ( mainBook->GetSelection() );
5507 }
5508
addSafeSeparator(wxToolBar * toolBar)5509 void MyFrame::addSafeSeparator ( wxToolBar *toolBar )
5510 {
5511 wxStaticText *staticControl = new wxStaticText (
5512 toolBar,
5513 wxID_ANY,
5514 _T ( " " ) );
5515 toolBar->AddControl ( staticControl );
5516 }
5517
statusProgress(const wxString & s)5518 void MyFrame::statusProgress ( const wxString& s )
5519 {
5520 wxStatusBar *status = GetStatusBar();
5521 if ( !status )
5522 return;
5523 status->SetStatusText ( s, 0 );
5524 }
5525
messagePane(const wxString & s,int iconType,bool forcePane)5526 void MyFrame::messagePane ( const wxString& s, int iconType, bool forcePane )
5527 {
5528 statusProgress ( wxEmptyString );
5529 wxString paneTitle;
5530 switch ( iconType )
5531 {
5532 case ( CONST_INFO ) :
5533 paneTitle = _ ( "Information" );
5534 break;
5535 case ( CONST_WARNING ) :
5536 paneTitle = _ ( "Warning" );
5537 break;
5538 case ( CONST_STOP ) :
5539 paneTitle = _ ( "Stopped" );
5540 break;
5541 case ( CONST_QUESTION ) :
5542 paneTitle = _ ( "Question" );
5543 break;
5544 default:
5545 paneTitle = _ ( "Message" );
5546 break;
5547 }
5548
5549 wxAuiPaneInfo &info = manager.GetPane ( htmlReport );
5550 if ( !info.IsShown() )
5551 {
5552 info.Show ( true );
5553 }
5554
5555 info.Caption ( paneTitle );
5556
5557 wxString htmlString = s;
5558 htmlString.Replace ( _T ( "&" ), _T ( "&" ), true );
5559 htmlString.Replace ( _T ( "<" ), _T ( "<" ), true );
5560 htmlString.Replace ( _T ( ">" ), _T ( ">" ), true );
5561
5562 // have to use <br> on Ubuntu
5563 htmlString.Replace ( _T("[br]"), _T("<br>"), true );
5564 htmlString.Replace ( _T("[br/]"), _T("<br/>"), true );
5565 htmlString.Replace ( _T("[b]"), _T("<b>"), true );
5566 htmlString.Replace ( _T("[/b]"), _T("</b>"), true );
5567 htmlString.Replace ( _T("[i]"), _T("<i>"), true );
5568 htmlString.Replace ( _T("[/i]"), _T("</i>"), true );
5569
5570 wxString htmlBuffer;
5571 htmlBuffer += _T ( "<html><body><table><tr><td width=\"5%\"><img src=\"" );
5572 switch ( iconType )
5573 {
5574 case ( CONST_INFO ) :
5575 htmlBuffer += pngDir;
5576 htmlBuffer += _T ( "stock_dialog-info-32.png" );
5577 break;
5578 case ( CONST_WARNING ) :
5579 htmlBuffer += pngDir;
5580 htmlBuffer += _T ( "stock_dialog-warning-32.png" );
5581 break;
5582 case ( CONST_STOP ) :
5583 htmlBuffer += pngDir;
5584 htmlBuffer += _T ( "stock_dialog-stop-32.png" );
5585 break;
5586 case ( CONST_QUESTION ) :
5587 htmlBuffer += pngDir;
5588 htmlBuffer += _T ( "stock_dialog-question-32.png" );
5589 break;
5590 default:
5591 break;
5592 }
5593 htmlBuffer += _T ( "\"></td><td width=\"95%\">" );
5594 htmlBuffer += htmlString;
5595 htmlBuffer += _T ( "</td></tr></table></body></html>" );
5596
5597 wxString file;
5598 XmlDoc *doc = getActiveDocument();
5599 if ( doc )
5600 file = doc->getFullFileName();
5601 htmlReport->setLastFile ( file );
5602 htmlReport->SetPage ( htmlBuffer );
5603
5604 manager.Update();
5605 }
5606
documentOk(const wxString & status)5607 void MyFrame::documentOk ( const wxString& status )
5608 {
5609 XmlDoc *doc;
5610 if ( ( doc = getActiveDocument() ) == NULL )
5611 return;
5612 wxString message;
5613 message.Printf ( _ ( "%s is %s" ),
5614 doc->getShortFileName().c_str(),
5615 status.c_str() );
5616 messagePane ( message, CONST_INFO );
5617 }
5618
applyEditorProperties(bool zoomOnly)5619 void MyFrame::applyEditorProperties ( bool zoomOnly )
5620 {
5621 XmlDoc *doc;
5622 size_t documentCount = mainBook->GetPageCount();
5623 for ( size_t i = 0; i < documentCount; i++ )
5624 {
5625 doc = ( XmlDoc * ) mainBook->GetPage ( i );
5626 if ( doc )
5627 {
5628 doc->applyProperties ( properties, zoomOnly );
5629 if ( !properties.validateAsYouType )
5630 doc->clearErrorIndicators();
5631 }
5632 }
5633 }
5634
modifiedMessage()5635 void MyFrame::modifiedMessage()
5636 {
5637 messagePane (
5638 _ ( "Document has been modified: save or discard changes" ),
5639 CONST_STOP );
5640 }
5641
xmliseWideTextNode(wxString & s)5642 void MyFrame::xmliseWideTextNode ( wxString& s )
5643 {
5644 s.Replace ( _T ( "&" ), _T ( "&" ), true );
5645 s.Replace ( _T ( "<" ), _T ( "<" ), true );
5646 s.Replace ( _T ( ">" ), _T ( ">" ), true );
5647 }
5648
getFileType(const wxString & fileName)5649 int MyFrame::getFileType ( const wxString& fileName )
5650 {
5651 wxString extension;
5652 wxFileName::SplitPath ( fileName, NULL/*Path*/, NULL/*Name*/, &extension );
5653 if ( extension.size() != 3 )
5654 return FILE_TYPE_XML;
5655
5656 extension.MakeLower();
5657
5658 if ( extension == _T ( "dtd" ) || extension == _T ( "ent" ) )
5659 return FILE_TYPE_DTD;
5660 else if ( extension == _T ( "css" ) )
5661 return FILE_TYPE_CSS;
5662 else if ( extension == _T ( "php" ) )
5663 return FILE_TYPE_PHP;
5664 else if ( extension == _T ( "exe" ) )
5665 return FILE_TYPE_BINARY;
5666 else if ( extension == _T ( "rnc" ) )
5667 return FILE_TYPE_RNC;
5668 return FILE_TYPE_XML;
5669 }
5670
getNotebookStyleMask()5671 long MyFrame::getNotebookStyleMask()
5672 {
5673 /*
5674 if (notebookStyleMenu->IsChecked(ID_NOTEBOOK_STYLE_FLAT))
5675 return wxFNB_FANCY_TABS | wxFNB_MOUSE_MIDDLE_CLOSES_TABS | wxFNB_X_ON_TAB;
5676 else if (notebookStyleMenu->IsChecked(ID_NOTEBOOK_STYLE_VC8))
5677 return wxFNB_BACKGROUND_GRADIENT | wxFNB_VC8 | wxFNB_MOUSE_MIDDLE_CLOSES_TABS |
5678 wxFNB_X_ON_TAB | wxFNB_DROPDOWN_TABS_LIST | wxFNB_NO_NAV_BUTTONS;
5679 else
5680 return wxFNB_BACKGROUND_GRADIENT | wxFNB_VC8 | wxFNB_MOUSE_MIDDLE_CLOSES_TABS | wxFNB_COLORFUL_TABS |
5681 wxFNB_X_ON_TAB | wxFNB_DROPDOWN_TABS_LIST | wxFNB_NO_NAV_BUTTONS;
5682 //wxFNB_BACKGROUND_GRADIENT | wxFNB_VC8 | wxFNB_MOUSE_MIDDLE_CLOSES_TABS | wxFNB_COLORFUL_TABS;
5683 */
5684 return 0;
5685 }
5686
isSpecialFileType(const wxString & fileName)5687 bool MyFrame::isSpecialFileType ( const wxString& fileName )
5688 {
5689 std::string fileNameLocal, fileNameLocalLC;
5690 fileNameLocal = fileName.mb_str ( wxConvLocal );
5691 fileNameLocalLC = CaseHandler::lowerCase ( fileNameLocal );
5692
5693 return (
5694 fileNameLocalLC.find ( ".dtd" ) != std::string::npos ||
5695 fileNameLocalLC.find ( ".css" ) != std::string::npos ||
5696 fileNameLocalLC.find ( ".php" ) != std::string::npos );
5697 }
5698
encodingMessage()5699 void MyFrame::encodingMessage()
5700 {
5701 wxString msg = _ ( "Encoding should be one of " );
5702 msg += ENCODING_INFO;
5703 messagePane ( msg, CONST_STOP );
5704 }
5705
updatePaths()5706 void MyFrame::updatePaths()
5707 {
5708 wxString sep = wxFileName::GetPathSeparator();
5709 ruleSetDir = applicationDir + sep + _T ( "rulesets" );
5710 filterDir = applicationDir + sep + _T ( "filters" );
5711 templateDir = applicationDir + sep + _T ( "templates" ) + sep;
5712 binDir = applicationDir + sep + _T ( "bin" ) + sep;
5713 helpDir = applicationDir + sep + _T ( "help" ) + sep;
5714 rngDir = applicationDir + sep + _T ( "rng" ) + sep;
5715 htmlDir = applicationDir + sep + _T ( "html" ) + sep;
5716 pngDir = applicationDir + sep + _T ( "png" ) + sep;
5717 xpmDir = applicationDir + sep + _T ( "xpm" ) + sep;
5718 daisyDir = applicationDir + sep + _T ( "daisy" ) + sep;
5719 catalogPath =
5720 applicationDir + sep + _T ( "catalog" ) + sep + _T ( "catalog" );
5721 xslDtdPath =
5722 applicationDir + sep + _T ( "dtd" ) + sep + _T ( "xslt10.dtd" );
5723 rssDtdPath =
5724 applicationDir + sep + _T ( "dtd" ) + sep + _T ( "rss2.dtd" );
5725 xtmDtdPath =
5726 applicationDir + sep + _T ( "dtd" ) + sep + _T ( "xtm1.dtd" );
5727 lzxDtdPath =
5728 applicationDir + sep + _T ( "dtd" ) + sep + _T ( "lzx.dtd" );
5729 xliffDtdPath =
5730 applicationDir + sep + _T ( "dtd" ) + sep + _T ( "xliff.dtd" );
5731 aspellDataPath = applicationDir + sep +
5732 _T ( "aspell" ) + sep + _T ( "data" );
5733 aspellDictPath = applicationDir + sep +
5734 _T ( "aspell" ) + sep + _T ( "dict" );
5735 }
5736
OnAssociate(wxCommandEvent & event)5737 void MyFrame::OnAssociate ( wxCommandEvent& event )
5738 {
5739 XmlDoc *doc;
5740 if ( ( doc = getActiveDocument() ) == NULL )
5741 return;
5742
5743 XmlTextInfo info ( doc->getFullFileName() );
5744 info.parse ( doc->myGetTextRaw() );
5745
5746 wxString title, label, type, extension, path, defaulturl, defaultaux;
5747 wxString auxiliaryLabel;
5748 int id = event.GetId();
5749 switch ( id )
5750 {
5751 case ID_ASSOCIATE_DTD_PUBLIC:
5752 type = _ ( "Public DTD" );
5753 extension = _T ( "*.dtd" );
5754 defaulturl = lastDtdPublic;
5755 defaultaux = info.mDtdFile.empty()
5756 ? lastDtdPublicAux : info.mDtdFile;
5757 break;
5758 case ID_ASSOCIATE_DTD_SYSTEM:
5759 type = _ ( "System DTD" );
5760 extension = _T ( "*.dtd" );
5761 defaulturl = info.mDtdFile.empty() ? lastDtdSystem : info.mDtdFile;
5762 defaultaux = _T ( "" );
5763 break;
5764 case ID_ASSOCIATE_W3C_SCHEMA:
5765 type = _ ( "XML Schema" );
5766 extension = _T ( "*.xsd" );
5767 defaulturl = info.mXsdFile.empty() ? lastSchema : info.mXsdFile;
5768 defaultaux = _T ( "" );
5769 break;
5770 case ID_ASSOCIATE_XSL:
5771 type = _ ( "XSLT stylesheet" );
5772 extension = _T ( "*.xsl;*.xslt" );
5773 defaulturl = info.mXslFile.empty()
5774 ? lastXslStylesheet : info.mXslFile;
5775 defaultaux = _T ( "" );
5776 break;
5777 default:
5778 return;
5779 }
5780
5781 std::string utf8Buffer;
5782 getRawText ( doc, utf8Buffer );
5783 std::string origEncoding = XmlEncodingHandler::get ( utf8Buffer );
5784 WrapExpat wellformedparser ( "UTF-8" );
5785 if ( !wellformedparser.parse ( utf8Buffer ) )
5786 {
5787 wxString message;
5788 message.Printf (
5789 _ ( "Cannot associate %s: %s" ),
5790 type.c_str(),
5791 wellformedparser.getLastError().c_str() );
5792 messagePane ( message, CONST_STOP );
5793 return;
5794 }
5795
5796 title.Printf ( _ ( "Associate %s" ), type.c_str() );
5797 label = _ ( "Choose a file:" );
5798
5799 bool auxiliaryBox =
5800 ( id == ID_ASSOCIATE_DTD_PUBLIC );
5801 //(id == ID_ASSOCIATE_W3C_SCHEMA_NS || id == ID_ASSOCIATE_DTD_PUBLIC);
5802 if ( auxiliaryBox )
5803 {
5804 auxiliaryLabel = _ ( "Choose a public identifier:" );
5805 /*
5806 (id == ID_ASSOCIATE_DTD_PUBLIC) ? _("Choose a public identifier:") :
5807 _("Choose a namespace:");
5808 */
5809 }
5810
5811 AssociateDialog ad (
5812 this,
5813 title,
5814 label,
5815 type,
5816 extension,
5817 defaulturl,
5818 &mLastDir,
5819 auxiliaryBox,
5820 auxiliaryLabel,
5821 defaultaux );
5822 if ( ad.ShowModal() != wxID_OK )
5823 return;
5824
5825 path = ad.getUrl();
5826
5827 wxString aux, schemaPathMemory;
5828
5829 if ( auxiliaryBox )
5830 {
5831 aux = ad.getAux();
5832 }
5833
5834 std::string modifiedBuffer;
5835
5836 // remember choice
5837 switch ( id )
5838 {
5839 case ID_ASSOCIATE_W3C_SCHEMA:
5840 lastSchema = path;
5841 break;
5842 case ID_ASSOCIATE_DTD_PUBLIC:
5843 lastDtdPublic = path;
5844 lastDtdPublicAux = aux;
5845 break;
5846 case ID_ASSOCIATE_DTD_SYSTEM:
5847 lastDtdSystem = path;
5848 break;
5849 case ID_ASSOCIATE_XSL:
5850 lastXslStylesheet = path;
5851 break;
5852 default:
5853 break;
5854 }
5855
5856 if ( id == ID_ASSOCIATE_W3C_SCHEMA )
5857 {
5858 XmlAssociateXsd parser ( path, "UTF-8" );
5859 if ( !parser.parse ( utf8Buffer ) )
5860 return;
5861 modifiedBuffer = parser.getBuffer();
5862 }
5863 else if ( id == ID_ASSOCIATE_DTD_SYSTEM || id == ID_ASSOCIATE_DTD_PUBLIC )
5864 {
5865 XmlAssociateDtd parser ( info, path, aux, "UTF-8" );
5866 if ( !parser.parse ( utf8Buffer ) )
5867 return;
5868 modifiedBuffer = parser.getBuffer();
5869 }
5870 else if ( id == ID_ASSOCIATE_XSL )
5871 {
5872 XmlAssociateXsl parser( info, path, "UTF-8" );
5873 if ( !parser.parse ( utf8Buffer ) )
5874 return;
5875 modifiedBuffer = parser.getBuffer();
5876 }
5877 else
5878 return;
5879
5880 XmlEncodingHandler::set ( modifiedBuffer, origEncoding );
5881 doc->SetTextRaw ( modifiedBuffer.c_str() );
5882 doc->SetFocus();
5883 }
5884
openRememberedTabs()5885 void MyFrame::openRememberedTabs()
5886 {
5887 wxStringTokenizer files ( openTabsOnClose, _T ( "|" ) );
5888 while ( files.HasMoreTokens() )
5889 {
5890 wxString file = files.GetNextToken();
5891 if ( file.IsEmpty() || !openFile ( file ) )
5892 continue; //break; // Ignore errors
5893 }
5894
5895 XmlDoc *doc;
5896 if ( ( doc = getActiveDocument() ) != NULL )
5897 doc->SetFocus();
5898 }
5899
getRawText(XmlDoc * doc,std::string & buffer)5900 void MyFrame::getRawText ( XmlDoc *doc, std::string& buffer )
5901 {
5902 if ( !doc )
5903 {
5904 buffer = "";
5905 return;
5906 }
5907 buffer = doc->myGetTextRaw();
5908 }
5909
OnWordCount(wxCommandEvent & event)5910 void MyFrame::OnWordCount ( wxCommandEvent& event )
5911 {
5912 XmlDoc *doc;
5913 if ( ( doc = getActiveDocument() ) == NULL )
5914 return;
5915
5916 std::string rawBufferUtf8;
5917 getRawText ( doc, rawBufferUtf8 );
5918
5919 XmlWordCount xwc ( "UTF-8" );
5920 wxString msg;
5921 if ( !xwc.parse ( rawBufferUtf8 ) )
5922 {
5923 statusProgress ( wxEmptyString );
5924 msg.Printf ( _ ( "Cannot count words: %s" ), xwc.getLastError().c_str() );
5925 messagePane ( msg, CONST_STOP );
5926 return;
5927 }
5928
5929 int count = xwc.getWordCount();
5930
5931 msg.Printf (
5932 wxPLURAL ( "%s contains %i word", "%s contains %i words", count ),
5933 doc->getShortFileName().c_str(), count );
5934
5935 messagePane ( msg, CONST_INFO, true );
5936 doc->SetFocus();
5937 }
5938
removeUtf8Bom(std::string & buffer)5939 void MyFrame::removeUtf8Bom ( std::string& buffer )
5940 {
5941 if ( buffer.size() > 3 &&
5942 ( unsigned char ) buffer[0] == 0xEF &&
5943 ( unsigned char ) buffer[1] == 0xBB &&
5944 ( unsigned char ) buffer[2] == 0xBF )
5945 {
5946 buffer.erase ( 0, 3 );
5947 }
5948 }
5949
loadBitmaps()5950 void MyFrame::loadBitmaps()
5951 {
5952 #ifdef __WXMSW__
5953 // toolbar icons
5954 newBitmap = wxBITMAP ( stock_new );
5955 openBitmap = wxBITMAP ( stock_open );
5956 saveBitmap = wxBITMAP ( stock_save );
5957 printBitmap = wxBITMAP ( stock_print );
5958 spellingBitmap = wxBITMAP ( stock_spellcheck );
5959 internetBitmap = wxBITMAP ( stock_internet );
5960 hyperlinkBitmap = wxBITMAP ( stock_hyperlink );
5961 filtersBitmap = wxBITMAP ( stock_filters );
5962 checkWellformedBitmap = wxBITMAP ( stock_calc-accept );
5963 checkValidBitmap = wxBITMAP ( stock_calc-accept-green );
5964
5965 // menu icons
5966 new16Bitmap = wxBITMAP ( stock_new_16 );
5967 open16Bitmap = wxBITMAP ( stock_open_16 );
5968 save16Bitmap = wxBITMAP ( stock_save_16 );
5969 printPreviewBitmap = wxBITMAP ( stock_print_preview_16 );
5970 print16Bitmap = wxBITMAP ( stock_print_16 );
5971 undo16Bitmap = wxBITMAP ( stock_undo_16 );
5972 redo16Bitmap = wxBITMAP ( stock_redo_16 );
5973 cutBitmap = wxBITMAP ( stock_cut_16 );
5974 copyBitmap = wxBITMAP ( stock_copy_16 );
5975 pasteBitmap = wxBITMAP ( stock_paste_16 );
5976 findBitmap = wxBITMAP ( stock_search_16 );
5977 spelling16Bitmap = wxBITMAP ( stock_spellcheck_16 );
5978 helpBitmap = wxBITMAP ( stock_help_16 );
5979 /*
5980 #elif __WXOSX__
5981 // toolbar icons
5982 newBitmap.LoadFile ( xpmDir + _T ( "stock_new.xpm" ), wxBITMAP_TYPE_XPM );
5983 openBitmap.LoadFile ( xpmDir + _T ( "stock_open.xpm" ), wxBITMAP_TYPE_XPM );
5984 saveBitmap.LoadFile ( xpmDir + _T ( "stock_save.xpm" ), wxBITMAP_TYPE_XPM );
5985
5986 // menu icons
5987 new16Bitmap = wxNullBitmap;
5988 open16Bitmap = wxNullBitmap;
5989 save16Bitmap = wxNullBitmap;
5990 printPreviewBitmap = wxNullBitmap;
5991 print16Bitmap = wxNullBitmap;
5992 undo16Bitmap = wxNullBitmap;
5993 redo16Bitmap = wxNullBitmap;
5994 cutBitmap = wxNullBitmap;
5995 copyBitmap = wxNullBitmap;
5996 pasteBitmap = wxNullBitmap;
5997 findBitmap = wxNullBitmap;
5998 spelling16Bitmap = wxNullBitmap;
5999 helpBitmap = wxNullBitmap;
6000 */
6001 #else
6002 // toolbar icons
6003 newBitmap = wxArtProvider::GetBitmap ( wxART_NEW, wxART_TOOLBAR );
6004 openBitmap = wxArtProvider::GetBitmap ( wxART_FILE_OPEN, wxART_TOOLBAR );
6005 saveBitmap = wxArtProvider::GetBitmap ( wxART_FILE_SAVE, wxART_TOOLBAR );
6006 #ifndef __WXOSX__
6007 printBitmap = wxArtProvider::GetBitmap ( wxART_PRINT, wxART_TOOLBAR );
6008 spellingBitmap = wxArtProvider::GetBitmap ( _T ( "gtk-spell-check" ), wxART_TOOLBAR );
6009
6010 // no stock icons for the following
6011 internetBitmap.LoadFile ( pngDir + _T ( "stock_internet.png" ), wxBITMAP_TYPE_PNG );
6012 hyperlinkBitmap.LoadFile ( pngDir + _T ( "stock_hyperlink.png" ), wxBITMAP_TYPE_PNG );
6013 checkWellformedBitmap.LoadFile ( pngDir + _T ( "stock_calc-accept.png" ), wxBITMAP_TYPE_PNG );
6014 checkValidBitmap.LoadFile ( pngDir + _T ( "stock_calc-accept-green.png" ), wxBITMAP_TYPE_PNG );
6015 #endif
6016
6017 // menu icons
6018 new16Bitmap = wxNullBitmap;
6019 open16Bitmap = wxNullBitmap;
6020 save16Bitmap = wxNullBitmap;
6021 printPreviewBitmap = wxNullBitmap;
6022 print16Bitmap = wxNullBitmap;
6023 undo16Bitmap = wxNullBitmap;
6024 redo16Bitmap = wxNullBitmap;
6025 cutBitmap = wxNullBitmap;
6026 copyBitmap = wxNullBitmap;
6027 pasteBitmap = wxNullBitmap;
6028 findBitmap = wxNullBitmap;
6029 spelling16Bitmap = wxNullBitmap;
6030 helpBitmap = wxNullBitmap;
6031 #endif
6032 }
6033
6034 #ifdef __WXMSW__
OnDropFiles(wxDropFilesEvent & event)6035 void MyFrame::OnDropFiles ( wxDropFilesEvent& event )
6036 {
6037 int no = event.GetNumberOfFiles();
6038 wxString *iterator = event.GetFiles();
6039
6040 if ( !no || !iterator )
6041 return;
6042
6043 for ( int i = 0; i < no; i++, iterator++ )
6044 {
6045 if ( !openFile ( *iterator ) )
6046 break;
6047 }
6048 }
6049 #endif
6050
OnPromptGenerated(wxNotifyEvent & event)6051 void MyFrame::OnPromptGenerated ( wxNotifyEvent &event )
6052 {
6053 XmlDoc *doc = this->getActiveDocument();
6054 locationPanel->update ( doc, lastParent );
6055 insertChildPanel->update ( doc, lastParent, wxEmptyString, true );
6056 insertSiblingPanel->update ( doc, lastParent, wxEmptyString, true );
6057 insertEntityPanel->update ( doc, wxEmptyString, wxEmptyString, true );
6058 }
6059
OnCopyXPath(wxCommandEvent & event)6060 void MyFrame::OnCopyXPath ( wxCommandEvent &event )
6061 {
6062 XmlDoc *doc = getActiveDocument();
6063 if ( !doc )
6064 return;
6065
6066 wxBusyCursor cursor;
6067
6068 wxString xpath = doc->getCurrentXPath();
6069 // Write the XPath to the clipboard
6070 if ( xpath.IsEmpty() )
6071 {
6072 messagePane ( _("The current XPath is empty."), CONST_WARNING );
6073 }
6074 else if ( wxTheClipboard->Open() )
6075 {
6076 // This data objects are held by the clipboard,
6077 // so do not delete them in the app.
6078 wxTheClipboard->SetData ( new wxTextDataObject ( xpath ) );
6079 wxTheClipboard->Close();
6080
6081 wxString message = wxString::Format
6082 ( _("The current XPath has been copied to the clipboard:[br][b]%s[/b]")
6083 , xpath.c_str()
6084 );
6085 messagePane ( message, CONST_INFO );
6086 }
6087 else
6088 {
6089 wxString message = wxString::Format
6090 ( _("Failed to copy the current XPath to the clipboard:[br][b]%s[/b]")
6091 , xpath.c_str()
6092 );
6093 messagePane ( message, CONST_STOP );
6094 htmlReport->SetFocus(); // This is needed to make Ctrl + C work
6095 }
6096 }
6097
OnUpdateCopyXPath(wxUpdateUIEvent & event)6098 void MyFrame::OnUpdateCopyXPath ( wxUpdateUIEvent& event )
6099 {
6100 event.Enable ( getActiveDocument() );
6101 }
6102
getAuxPath(const wxString & fileName)6103 wxString MyFrame::getAuxPath ( const wxString& fileName )
6104 {
6105 if ( fileName.Find ( _T ( ".xsl" ) ) != wxNOT_FOUND ||
6106 fileName.Find ( _T ( ".XSL" ) ) != wxNOT_FOUND )
6107 return xslDtdPath;
6108 else if ( fileName.Find ( _T ( ".rss" ) ) != wxNOT_FOUND ||
6109 fileName.Find ( _T ( ".RSS" ) ) != wxNOT_FOUND )
6110 return rssDtdPath;
6111 else if ( fileName.Find ( _T ( ".xtm" ) ) != wxNOT_FOUND ||
6112 fileName.Find ( _T ( ".xtmm" ) ) != wxNOT_FOUND ||
6113 fileName.Find ( _T ( ".XTM" ) ) != wxNOT_FOUND ||
6114 fileName.Find ( _T ( ".XTMM" ) ) != wxNOT_FOUND )
6115 return xtmDtdPath;
6116 else if ( fileName.Find ( _T ( ".lzx" ) ) != wxNOT_FOUND ||
6117 fileName.Find ( _T ( ".LZX" ) ) != wxNOT_FOUND )
6118 return lzxDtdPath;
6119 else if ( fileName.Find ( _T ( ".xlf" ) ) != wxNOT_FOUND ||
6120 fileName.Find ( _T ( ".XLF" ) ) != wxNOT_FOUND )
6121 return xliffDtdPath;
6122 return wxEmptyString;
6123 }
6124
OnActivateApp(wxActivateEvent & event)6125 void MyFrame::OnActivateApp ( wxActivateEvent& event )
6126 {
6127 event.Skip();
6128 if ( !mainBook || !event.GetActive() )
6129 return;
6130 restoreFocusToNotebook = true;
6131 }
6132
OnIconize(wxIconizeEvent & event)6133 void MyFrame::OnIconize ( wxIconizeEvent& event )
6134 {
6135 event.Skip();
6136 #if wxCHECK_VERSION(2,9,0)
6137 if (event.IsIconized())
6138 #else
6139 if ( event.Iconized() )
6140 #endif
6141 return;
6142 restoreFocusToNotebook = true;
6143 manager.Update();
6144 }
6145
OnKeyPressed(wxKeyEvent & event)6146 void MyFrame::OnKeyPressed ( wxKeyEvent& event )
6147 {
6148 event.Skip();
6149 }
6150
setStrictScrolling(bool b)6151 void MyFrame::setStrictScrolling ( bool b )
6152 {
6153 XmlDoc *doc;
6154 doc = getActiveDocument();
6155 if ( !doc )
6156 return;
6157 doc->SetYCaretPolicy ( ( b ) ? ( wxSTC_CARET_STRICT | wxSTC_CARET_SLOP ) : wxSTC_CARET_EVEN,
6158 ( b ) ? 10 : 0 );
6159 }
6160
addToFileQueue(wxString & fileName)6161 void MyFrame::addToFileQueue ( wxString& fileName )
6162 {
6163 fileQueue.push_back ( fileName );
6164 }
6165
validatePaths()6166 void MyFrame::validatePaths()
6167 {
6168 int invalid = 0;
6169 wxString msg;
6170
6171 // Warning: Don't put a space between 'CHECK' and '('
6172 #define CHECK( check, path ) \
6173 if ( !( check ) ( path ) )\
6174 {\
6175 invalid++;\
6176 msg << wxTextFile::GetEOL() << path;\
6177 }
6178 CHECK ( wxDirExists, ruleSetDir );
6179 //CHECK ( wxDirExists, filterDir );
6180 CHECK ( wxDirExists, templateDir );
6181 //CHECK ( wxDirExists, binDir );
6182 CHECK ( wxDirExists, helpDir );
6183 CHECK ( wxDirExists, rngDir );
6184 //CHECK ( wxDirExists, htmlDir );
6185 CHECK ( wxDirExists, pngDir );
6186 //CHECK ( wxDirExists, daisyDir );
6187 CHECK ( wxFileExists, catalogPath );
6188 CHECK ( wxFileExists, xslDtdPath );
6189 CHECK ( wxFileExists, rssDtdPath );
6190 CHECK ( wxFileExists, xtmDtdPath );
6191 CHECK ( wxFileExists, lzxDtdPath );
6192 CHECK ( wxFileExists, xliffDtdPath );
6193 #ifdef __WXMSW__
6194 CHECK ( wxDirExists, aspellDataPath );
6195 CHECK ( wxDirExists, aspellDictPath );
6196 #endif // __WXMSW__
6197 #undef CHECK
6198
6199 if ( !invalid )
6200 return;
6201
6202 msg = wxPLURAL ( "Invalid path: ", "Invalid paths: ", invalid ) + msg;
6203 msg << wxTextFile::GetEOL()
6204 << wxTextFile::GetEOL()
6205 #ifdef __WXMSW__
6206 << _ ( "To change the application directory setting, click "
6207 "Tools menu -> Options... after XML Copy Editor starts up." );
6208 #else
6209 << _ ( "To change the application directory setting, click "
6210 "Edit menu -> Preferences... after XML Copy Editor starts up." );
6211 #endif
6212 wxMessageBox ( msg, GetTitle(), wxOK | wxICON_ERROR, this );
6213 }
6214