No changes, just make it easier to tweak splitter sample.
[wxWidgets.git] / samples / stc / edit.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 // File: contrib/samples/stc/edit.cpp
3 // Purpose: STC test module
4 // Maintainer: Wyo
5 // Created: 2003-09-01
6 // RCS-ID: $Id$
7 // Copyright: (c) wxGuide
8 // Licence: wxWindows licence
9 //////////////////////////////////////////////////////////////////////////////
10
11 //----------------------------------------------------------------------------
12 // informations
13 //----------------------------------------------------------------------------
14
15
16 //----------------------------------------------------------------------------
17 // headers
18 //----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all 'standard' wxWidgets headers)
29 #ifndef WX_PRECOMP
30 #include "wx/wx.h"
31 #endif
32
33 //! wxWidgets headers
34 #include "wx/file.h" // raw file io support
35 #include "wx/filename.h" // filename support
36
37 //! application headers
38 #include "defsext.h" // additional definitions
39
40 #include "edit.h" // edit module
41
42
43 //----------------------------------------------------------------------------
44 // resources
45 //----------------------------------------------------------------------------
46
47
48 //============================================================================
49 // declarations
50 //============================================================================
51
52
53 //============================================================================
54 // implementation
55 //============================================================================
56
57 //----------------------------------------------------------------------------
58 // Edit
59 //----------------------------------------------------------------------------
60
61 BEGIN_EVENT_TABLE (Edit, wxStyledTextCtrl)
62 // common
63 EVT_SIZE ( Edit::OnSize)
64 // edit
65 EVT_MENU (wxID_CLEAR, Edit::OnEditClear)
66 EVT_MENU (wxID_CUT, Edit::OnEditCut)
67 EVT_MENU (wxID_COPY, Edit::OnEditCopy)
68 EVT_MENU (wxID_PASTE, Edit::OnEditPaste)
69 EVT_MENU (myID_INDENTINC, Edit::OnEditIndentInc)
70 EVT_MENU (myID_INDENTRED, Edit::OnEditIndentRed)
71 EVT_MENU (wxID_SELECTALL, Edit::OnEditSelectAll)
72 EVT_MENU (myID_SELECTLINE, Edit::OnEditSelectLine)
73 EVT_MENU (wxID_REDO, Edit::OnEditRedo)
74 EVT_MENU (wxID_UNDO, Edit::OnEditUndo)
75 // find
76 EVT_MENU (wxID_FIND, Edit::OnFind)
77 EVT_MENU (myID_FINDNEXT, Edit::OnFindNext)
78 EVT_MENU (myID_REPLACE, Edit::OnReplace)
79 EVT_MENU (myID_REPLACENEXT, Edit::OnReplaceNext)
80 EVT_MENU (myID_BRACEMATCH, Edit::OnBraceMatch)
81 EVT_MENU (myID_GOTO, Edit::OnGoto)
82 // view
83 EVT_MENU_RANGE (myID_HILIGHTFIRST, myID_HILIGHTLAST,
84 Edit::OnHilightLang)
85 EVT_MENU (myID_DISPLAYEOL, Edit::OnDisplayEOL)
86 EVT_MENU (myID_INDENTGUIDE, Edit::OnIndentGuide)
87 EVT_MENU (myID_LINENUMBER, Edit::OnLineNumber)
88 EVT_MENU (myID_LONGLINEON, Edit::OnLongLineOn)
89 EVT_MENU (myID_WHITESPACE, Edit::OnWhiteSpace)
90 EVT_MENU (myID_FOLDTOGGLE, Edit::OnFoldToggle)
91 EVT_MENU (myID_OVERTYPE, Edit::OnSetOverType)
92 EVT_MENU (myID_READONLY, Edit::OnSetReadOnly)
93 EVT_MENU (myID_WRAPMODEON, Edit::OnWrapmodeOn)
94 EVT_MENU (myID_CHARSETANSI, Edit::OnUseCharset)
95 EVT_MENU (myID_CHARSETMAC, Edit::OnUseCharset)
96 // extra
97 EVT_MENU (myID_CHANGELOWER, Edit::OnChangeCase)
98 EVT_MENU (myID_CHANGEUPPER, Edit::OnChangeCase)
99 EVT_MENU (myID_CONVERTCR, Edit::OnConvertEOL)
100 EVT_MENU (myID_CONVERTCRLF, Edit::OnConvertEOL)
101 EVT_MENU (myID_CONVERTLF, Edit::OnConvertEOL)
102 // stc
103 EVT_STC_MARGINCLICK (wxID_ANY, Edit::OnMarginClick)
104 EVT_STC_CHARADDED (wxID_ANY, Edit::OnCharAdded)
105 EVT_STC_KEY( wxID_ANY , Edit::OnKey )
106 END_EVENT_TABLE()
107
108 Edit::Edit (wxWindow *parent, wxWindowID id,
109 const wxPoint &pos,
110 const wxSize &size,
111 long style)
112 : wxStyledTextCtrl (parent, id, pos, size, style) {
113
114 m_filename = wxEmptyString;
115
116 m_LineNrID = 0;
117 m_DividerID = 1;
118 m_FoldingID = 2;
119
120 // initialize language
121 m_language = NULL;
122
123 // Use all the bits in the style byte as styles, not indicators.
124 SetStyleBits(8);
125
126 // default font for all styles
127 SetViewEOL (g_CommonPrefs.displayEOLEnable);
128 SetIndentationGuides (g_CommonPrefs.indentGuideEnable);
129 SetEdgeMode (g_CommonPrefs.longLineOnEnable?
130 wxSTC_EDGE_LINE: wxSTC_EDGE_NONE);
131 SetViewWhiteSpace (g_CommonPrefs.whiteSpaceEnable?
132 wxSTC_WS_VISIBLEALWAYS: wxSTC_WS_INVISIBLE);
133 SetOvertype (g_CommonPrefs.overTypeInitial);
134 SetReadOnly (g_CommonPrefs.readOnlyInitial);
135 SetWrapMode (g_CommonPrefs.wrapModeInitial?
136 wxSTC_WRAP_WORD: wxSTC_WRAP_NONE);
137 wxFont font (10, wxMODERN, wxNORMAL, wxNORMAL);
138 StyleSetFont (wxSTC_STYLE_DEFAULT, font);
139 StyleSetForeground (wxSTC_STYLE_DEFAULT, *wxBLACK);
140 StyleSetBackground (wxSTC_STYLE_DEFAULT, *wxWHITE);
141 StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour (wxT("DARK GREY")));
142 StyleSetBackground (wxSTC_STYLE_LINENUMBER, *wxWHITE);
143 StyleSetForeground(wxSTC_STYLE_INDENTGUIDE, wxColour (wxT("DARK GREY")));
144 InitializePrefs (DEFAULT_LANGUAGE);
145
146 // set visibility
147 SetVisiblePolicy (wxSTC_VISIBLE_STRICT|wxSTC_VISIBLE_SLOP, 1);
148 SetXCaretPolicy (wxSTC_CARET_EVEN|wxSTC_VISIBLE_STRICT|wxSTC_CARET_SLOP, 1);
149 SetYCaretPolicy (wxSTC_CARET_EVEN|wxSTC_VISIBLE_STRICT|wxSTC_CARET_SLOP, 1);
150
151 // markers
152 MarkerDefine (wxSTC_MARKNUM_FOLDER, wxSTC_MARK_DOTDOTDOT, wxT("BLACK"), wxT("BLACK"));
153 MarkerDefine (wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_ARROWDOWN, wxT("BLACK"), wxT("BLACK"));
154 MarkerDefine (wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY, wxT("BLACK"), wxT("BLACK"));
155 MarkerDefine (wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_DOTDOTDOT, wxT("BLACK"), wxT("WHITE"));
156 MarkerDefine (wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_ARROWDOWN, wxT("BLACK"), wxT("WHITE"));
157 MarkerDefine (wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY, wxT("BLACK"), wxT("BLACK"));
158 MarkerDefine (wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY, wxT("BLACK"), wxT("BLACK"));
159
160 // miscelaneous
161 m_LineNrMargin = TextWidth (wxSTC_STYLE_LINENUMBER, wxT("_999999"));
162 m_FoldingMargin = 16;
163 CmdKeyClear (wxSTC_KEY_TAB, 0); // this is done by the menu accelerator key
164 SetLayoutCache (wxSTC_CACHE_PAGE);
165
166 }
167
168 Edit::~Edit () {}
169
170 //----------------------------------------------------------------------------
171 // common event handlers
172 void Edit::OnSize( wxSizeEvent& event ) {
173 int x = GetClientSize().x +
174 (g_CommonPrefs.lineNumberEnable? m_LineNrMargin: 0) +
175 (g_CommonPrefs.foldEnable? m_FoldingMargin: 0);
176 if (x > 0) SetScrollWidth (x);
177 event.Skip();
178 }
179
180 // edit event handlers
181 void Edit::OnEditRedo (wxCommandEvent &WXUNUSED(event)) {
182 if (!CanRedo()) return;
183 Redo ();
184 }
185
186 void Edit::OnEditUndo (wxCommandEvent &WXUNUSED(event)) {
187 if (!CanUndo()) return;
188 Undo ();
189 }
190
191 void Edit::OnEditClear (wxCommandEvent &WXUNUSED(event)) {
192 if (GetReadOnly()) return;
193 Clear ();
194 }
195
196 void Edit::OnKey (wxStyledTextEvent &WXUNUSED(event))
197 {
198 wxMessageBox("OnKey");
199 }
200
201 void Edit::OnEditCut (wxCommandEvent &WXUNUSED(event)) {
202 if (GetReadOnly() || (GetSelectionEnd()-GetSelectionStart() <= 0)) return;
203 Cut ();
204 }
205
206 void Edit::OnEditCopy (wxCommandEvent &WXUNUSED(event)) {
207 if (GetSelectionEnd()-GetSelectionStart() <= 0) return;
208 Copy ();
209 }
210
211 void Edit::OnEditPaste (wxCommandEvent &WXUNUSED(event)) {
212 if (!CanPaste()) return;
213 Paste ();
214 }
215
216 void Edit::OnFind (wxCommandEvent &WXUNUSED(event)) {
217 }
218
219 void Edit::OnFindNext (wxCommandEvent &WXUNUSED(event)) {
220 }
221
222 void Edit::OnReplace (wxCommandEvent &WXUNUSED(event)) {
223 }
224
225 void Edit::OnReplaceNext (wxCommandEvent &WXUNUSED(event)) {
226 }
227
228 void Edit::OnBraceMatch (wxCommandEvent &WXUNUSED(event)) {
229 int min = GetCurrentPos ();
230 int max = BraceMatch (min);
231 if (max > (min+1)) {
232 BraceHighlight (min+1, max);
233 SetSelection (min+1, max);
234 }else{
235 BraceBadLight (min);
236 }
237 }
238
239 void Edit::OnGoto (wxCommandEvent &WXUNUSED(event)) {
240 }
241
242 void Edit::OnEditIndentInc (wxCommandEvent &WXUNUSED(event)) {
243 CmdKeyExecute (wxSTC_CMD_TAB);
244 }
245
246 void Edit::OnEditIndentRed (wxCommandEvent &WXUNUSED(event)) {
247 CmdKeyExecute (wxSTC_CMD_DELETEBACK);
248 }
249
250 void Edit::OnEditSelectAll (wxCommandEvent &WXUNUSED(event)) {
251 SetSelection (0, GetTextLength ());
252 }
253
254 void Edit::OnEditSelectLine (wxCommandEvent &WXUNUSED(event)) {
255 int lineStart = PositionFromLine (GetCurrentLine());
256 int lineEnd = PositionFromLine (GetCurrentLine() + 1);
257 SetSelection (lineStart, lineEnd);
258 }
259
260 void Edit::OnHilightLang (wxCommandEvent &event) {
261 InitializePrefs (g_LanguagePrefs [event.GetId() - myID_HILIGHTFIRST].name);
262 }
263
264 void Edit::OnDisplayEOL (wxCommandEvent &WXUNUSED(event)) {
265 SetViewEOL (!GetViewEOL());
266 }
267
268 void Edit::OnIndentGuide (wxCommandEvent &WXUNUSED(event)) {
269 SetIndentationGuides (!GetIndentationGuides());
270 }
271
272 void Edit::OnLineNumber (wxCommandEvent &WXUNUSED(event)) {
273 SetMarginWidth (m_LineNrID,
274 GetMarginWidth (m_LineNrID) == 0? m_LineNrMargin: 0);
275 }
276
277 void Edit::OnLongLineOn (wxCommandEvent &WXUNUSED(event)) {
278 SetEdgeMode (GetEdgeMode() == 0? wxSTC_EDGE_LINE: wxSTC_EDGE_NONE);
279 }
280
281 void Edit::OnWhiteSpace (wxCommandEvent &WXUNUSED(event)) {
282 SetViewWhiteSpace (GetViewWhiteSpace() == 0?
283 wxSTC_WS_VISIBLEALWAYS: wxSTC_WS_INVISIBLE);
284 }
285
286 void Edit::OnFoldToggle (wxCommandEvent &WXUNUSED(event)) {
287 ToggleFold (GetFoldParent(GetCurrentLine()));
288 }
289
290 void Edit::OnSetOverType (wxCommandEvent &WXUNUSED(event)) {
291 SetOvertype (!GetOvertype());
292 }
293
294 void Edit::OnSetReadOnly (wxCommandEvent &WXUNUSED(event)) {
295 SetReadOnly (!GetReadOnly());
296 }
297
298 void Edit::OnWrapmodeOn (wxCommandEvent &WXUNUSED(event)) {
299 SetWrapMode (GetWrapMode() == 0? wxSTC_WRAP_WORD: wxSTC_WRAP_NONE);
300 }
301
302 void Edit::OnUseCharset (wxCommandEvent &event) {
303 int Nr;
304 int charset = GetCodePage();
305 switch (event.GetId()) {
306 case myID_CHARSETANSI: {charset = wxSTC_CHARSET_ANSI; break;}
307 case myID_CHARSETMAC: {charset = wxSTC_CHARSET_ANSI; break;}
308 }
309 for (Nr = 0; Nr < wxSTC_STYLE_LASTPREDEFINED; Nr++) {
310 StyleSetCharacterSet (Nr, charset);
311 }
312 SetCodePage (charset);
313 }
314
315 void Edit::OnChangeCase (wxCommandEvent &event) {
316 switch (event.GetId()) {
317 case myID_CHANGELOWER: {
318 CmdKeyExecute (wxSTC_CMD_LOWERCASE);
319 break;
320 }
321 case myID_CHANGEUPPER: {
322 CmdKeyExecute (wxSTC_CMD_UPPERCASE);
323 break;
324 }
325 }
326 }
327
328 void Edit::OnConvertEOL (wxCommandEvent &event) {
329 int eolMode = GetEOLMode();
330 switch (event.GetId()) {
331 case myID_CONVERTCR: { eolMode = wxSTC_EOL_CR; break;}
332 case myID_CONVERTCRLF: { eolMode = wxSTC_EOL_CRLF; break;}
333 case myID_CONVERTLF: { eolMode = wxSTC_EOL_LF; break;}
334 }
335 ConvertEOLs (eolMode);
336 SetEOLMode (eolMode);
337 }
338
339 //! misc
340 void Edit::OnMarginClick (wxStyledTextEvent &event) {
341 if (event.GetMargin() == 2) {
342 int lineClick = LineFromPosition (event.GetPosition());
343 int levelClick = GetFoldLevel (lineClick);
344 if ((levelClick & wxSTC_FOLDLEVELHEADERFLAG) > 0) {
345 ToggleFold (lineClick);
346 }
347 }
348 }
349
350 void Edit::OnCharAdded (wxStyledTextEvent &event) {
351 char chr = (char)event.GetKey();
352 int currentLine = GetCurrentLine();
353 // Change this if support for mac files with \r is needed
354 if (chr == '\n') {
355 int lineInd = 0;
356 if (currentLine > 0) {
357 lineInd = GetLineIndentation(currentLine - 1);
358 }
359 if (lineInd == 0) return;
360 SetLineIndentation (currentLine, lineInd);
361 GotoPos(PositionFromLine (currentLine) + lineInd);
362 }
363 }
364
365
366 //----------------------------------------------------------------------------
367 // private functions
368 wxString Edit::DeterminePrefs (const wxString &filename) {
369
370 LanguageInfo const* curInfo;
371
372 // determine language from filepatterns
373 int languageNr;
374 for (languageNr = 0; languageNr < g_LanguagePrefsSize; languageNr++) {
375 curInfo = &g_LanguagePrefs [languageNr];
376 wxString filepattern = curInfo->filepattern;
377 filepattern.Lower();
378 while (!filepattern.empty()) {
379 wxString cur = filepattern.BeforeFirst (';');
380 if ((cur == filename) ||
381 (cur == (filename.BeforeLast ('.') + wxT(".*"))) ||
382 (cur == (wxT("*.") + filename.AfterLast ('.')))) {
383 return curInfo->name;
384 }
385 filepattern = filepattern.AfterFirst (';');
386 }
387 }
388 return wxEmptyString;
389
390 }
391
392 bool Edit::InitializePrefs (const wxString &name) {
393
394 // initialize styles
395 StyleClearAll();
396 LanguageInfo const* curInfo = NULL;
397
398 // determine language
399 bool found = false;
400 int languageNr;
401 for (languageNr = 0; languageNr < g_LanguagePrefsSize; languageNr++) {
402 curInfo = &g_LanguagePrefs [languageNr];
403 if (curInfo->name == name) {
404 found = true;
405 break;
406 }
407 }
408 if (!found) return false;
409
410 // set lexer and language
411 SetLexer (curInfo->lexer);
412 m_language = curInfo;
413
414 // set margin for line numbers
415 SetMarginType (m_LineNrID, wxSTC_MARGIN_NUMBER);
416 StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour (wxT("DARK GREY")));
417 StyleSetBackground (wxSTC_STYLE_LINENUMBER, *wxWHITE);
418 SetMarginWidth (m_LineNrID, 0); // start out not visible
419
420 // default fonts for all styles!
421 int Nr;
422 for (Nr = 0; Nr < wxSTC_STYLE_LASTPREDEFINED; Nr++) {
423 wxFont font (10, wxMODERN, wxNORMAL, wxNORMAL);
424 StyleSetFont (Nr, font);
425 }
426
427 // set common styles
428 StyleSetForeground (wxSTC_STYLE_DEFAULT, wxColour (wxT("DARK GREY")));
429 StyleSetForeground (wxSTC_STYLE_INDENTGUIDE, wxColour (wxT("DARK GREY")));
430
431 // initialize settings
432 if (g_CommonPrefs.syntaxEnable) {
433 int keywordnr = 0;
434 for (Nr = 0; Nr < STYLE_TYPES_COUNT; Nr++) {
435 if (curInfo->styles[Nr].type == -1) continue;
436 const StyleInfo &curType = g_StylePrefs [curInfo->styles[Nr].type];
437 wxFont font (curType.fontsize, wxMODERN, wxNORMAL, wxNORMAL, false,
438 curType.fontname);
439 StyleSetFont (Nr, font);
440 if (curType.foreground) {
441 StyleSetForeground (Nr, wxColour (curType.foreground));
442 }
443 if (curType.background) {
444 StyleSetBackground (Nr, wxColour (curType.background));
445 }
446 StyleSetBold (Nr, (curType.fontstyle & mySTC_STYLE_BOLD) > 0);
447 StyleSetItalic (Nr, (curType.fontstyle & mySTC_STYLE_ITALIC) > 0);
448 StyleSetUnderline (Nr, (curType.fontstyle & mySTC_STYLE_UNDERL) > 0);
449 StyleSetVisible (Nr, (curType.fontstyle & mySTC_STYLE_HIDDEN) == 0);
450 StyleSetCase (Nr, curType.lettercase);
451 const char *pwords = curInfo->styles[Nr].words;
452 if (pwords) {
453 SetKeyWords (keywordnr, pwords);
454 keywordnr += 1;
455 }
456 }
457 }
458
459 // set margin as unused
460 SetMarginType (m_DividerID, wxSTC_MARGIN_SYMBOL);
461 SetMarginWidth (m_DividerID, 0);
462 SetMarginSensitive (m_DividerID, false);
463
464 // folding
465 SetMarginType (m_FoldingID, wxSTC_MARGIN_SYMBOL);
466 SetMarginMask (m_FoldingID, wxSTC_MASK_FOLDERS);
467 StyleSetBackground (m_FoldingID, *wxWHITE);
468 SetMarginWidth (m_FoldingID, 0);
469 SetMarginSensitive (m_FoldingID, false);
470 if (g_CommonPrefs.foldEnable) {
471 SetMarginWidth (m_FoldingID, curInfo->folds != 0? m_FoldingMargin: 0);
472 SetMarginSensitive (m_FoldingID, curInfo->folds != 0);
473 SetProperty (wxT("fold"), curInfo->folds != 0? wxT("1"): wxT("0"));
474 SetProperty (wxT("fold.comment"),
475 (curInfo->folds & mySTC_FOLD_COMMENT) > 0? wxT("1"): wxT("0"));
476 SetProperty (wxT("fold.compact"),
477 (curInfo->folds & mySTC_FOLD_COMPACT) > 0? wxT("1"): wxT("0"));
478 SetProperty (wxT("fold.preprocessor"),
479 (curInfo->folds & mySTC_FOLD_PREPROC) > 0? wxT("1"): wxT("0"));
480 SetProperty (wxT("fold.html"),
481 (curInfo->folds & mySTC_FOLD_HTML) > 0? wxT("1"): wxT("0"));
482 SetProperty (wxT("fold.html.preprocessor"),
483 (curInfo->folds & mySTC_FOLD_HTMLPREP) > 0? wxT("1"): wxT("0"));
484 SetProperty (wxT("fold.comment.python"),
485 (curInfo->folds & mySTC_FOLD_COMMENTPY) > 0? wxT("1"): wxT("0"));
486 SetProperty (wxT("fold.quotes.python"),
487 (curInfo->folds & mySTC_FOLD_QUOTESPY) > 0? wxT("1"): wxT("0"));
488 }
489 SetFoldFlags (wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED |
490 wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED);
491
492 // set spaces and indention
493 SetTabWidth (4);
494 SetUseTabs (false);
495 SetTabIndents (true);
496 SetBackSpaceUnIndents (true);
497 SetIndent (g_CommonPrefs.indentEnable? 4: 0);
498
499 // others
500 SetViewEOL (g_CommonPrefs.displayEOLEnable);
501 SetIndentationGuides (g_CommonPrefs.indentGuideEnable);
502 SetEdgeColumn (80);
503 SetEdgeMode (g_CommonPrefs.longLineOnEnable? wxSTC_EDGE_LINE: wxSTC_EDGE_NONE);
504 SetViewWhiteSpace (g_CommonPrefs.whiteSpaceEnable?
505 wxSTC_WS_VISIBLEALWAYS: wxSTC_WS_INVISIBLE);
506 SetOvertype (g_CommonPrefs.overTypeInitial);
507 SetReadOnly (g_CommonPrefs.readOnlyInitial);
508 SetWrapMode (g_CommonPrefs.wrapModeInitial?
509 wxSTC_WRAP_WORD: wxSTC_WRAP_NONE);
510
511 return true;
512 }
513
514 bool Edit::LoadFile ()
515 {
516 #if wxUSE_FILEDLG
517 // get filname
518 if (!m_filename) {
519 wxFileDialog dlg (this, wxT("Open file"), wxEmptyString, wxEmptyString,
520 wxT("Any file (*)|*"), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR);
521 if (dlg.ShowModal() != wxID_OK) return false;
522 m_filename = dlg.GetPath();
523 }
524
525 // load file
526 return LoadFile (m_filename);
527 #else
528 return false;
529 #endif // wxUSE_FILEDLG
530 }
531
532 bool Edit::LoadFile (const wxString &filename) {
533
534 // load file in edit and clear undo
535 if (!filename.empty()) m_filename = filename;
536
537 wxStyledTextCtrl::LoadFile(m_filename);
538
539 EmptyUndoBuffer();
540
541 // determine lexer language
542 wxFileName fname (m_filename);
543 InitializePrefs (DeterminePrefs (fname.GetFullName()));
544
545 return true;
546 }
547
548 bool Edit::SaveFile ()
549 {
550 #if wxUSE_FILEDLG
551 // return if no change
552 if (!Modified()) return true;
553
554 // get filname
555 if (!m_filename) {
556 wxFileDialog dlg (this, wxT("Save file"), wxEmptyString, wxEmptyString, wxT("Any file (*)|*"),
557 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
558 if (dlg.ShowModal() != wxID_OK) return false;
559 m_filename = dlg.GetPath();
560 }
561
562 // save file
563 return SaveFile (m_filename);
564 #else
565 return false;
566 #endif // wxUSE_FILEDLG
567 }
568
569 bool Edit::SaveFile (const wxString &filename) {
570
571 // return if no change
572 if (!Modified()) return true;
573
574 // // save edit in file and clear undo
575 // if (!filename.empty()) m_filename = filename;
576 // wxFile file (m_filename, wxFile::write);
577 // if (!file.IsOpened()) return false;
578 // wxString buf = GetText();
579 // bool okay = file.Write (buf);
580 // file.Close();
581 // if (!okay) return false;
582 // EmptyUndoBuffer();
583 // SetSavePoint();
584
585 // return true;
586
587 return wxStyledTextCtrl::SaveFile(filename);
588
589 }
590
591 bool Edit::Modified () {
592
593 // return modified state
594 return (GetModify() && !GetReadOnly());
595 }
596
597 //----------------------------------------------------------------------------
598 // EditProperties
599 //----------------------------------------------------------------------------
600
601 EditProperties::EditProperties (Edit *edit,
602 long style)
603 : wxDialog (edit, wxID_ANY, wxEmptyString,
604 wxDefaultPosition, wxDefaultSize,
605 style | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
606
607 // sets the application title
608 SetTitle (_("Properties"));
609 wxString text;
610
611 // fullname
612 wxBoxSizer *fullname = new wxBoxSizer (wxHORIZONTAL);
613 fullname->Add (10, 0);
614 fullname->Add (new wxStaticText (this, wxID_ANY, _("Full filename"),
615 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
616 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
617 fullname->Add (new wxStaticText (this, wxID_ANY, edit->GetFilename()),
618 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
619
620 // text info
621 wxGridSizer *textinfo = new wxGridSizer (4, 0, 2);
622 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Language"),
623 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
624 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
625 textinfo->Add (new wxStaticText (this, wxID_ANY, edit->m_language->name),
626 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
627 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Lexer-ID: "),
628 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
629 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
630 text = wxString::Format (wxT("%d"), edit->GetLexer());
631 textinfo->Add (new wxStaticText (this, wxID_ANY, text),
632 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
633 wxString EOLtype = wxEmptyString;
634 switch (edit->GetEOLMode()) {
635 case wxSTC_EOL_CR: {EOLtype = wxT("CR (Unix)"); break; }
636 case wxSTC_EOL_CRLF: {EOLtype = wxT("CRLF (Windows)"); break; }
637 case wxSTC_EOL_LF: {EOLtype = wxT("CR (Macintosh)"); break; }
638 }
639 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Line endings"),
640 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
641 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
642 textinfo->Add (new wxStaticText (this, wxID_ANY, EOLtype),
643 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
644
645 // text info box
646 wxStaticBoxSizer *textinfos = new wxStaticBoxSizer (
647 new wxStaticBox (this, wxID_ANY, _("Informations")),
648 wxVERTICAL);
649 textinfos->Add (textinfo, 0, wxEXPAND);
650 textinfos->Add (0, 6);
651
652 // statistic
653 wxGridSizer *statistic = new wxGridSizer (4, 0, 2);
654 statistic->Add (new wxStaticText (this, wxID_ANY, _("Total lines"),
655 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
656 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
657 text = wxString::Format (wxT("%d"), edit->GetLineCount());
658 statistic->Add (new wxStaticText (this, wxID_ANY, text),
659 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
660 statistic->Add (new wxStaticText (this, wxID_ANY, _("Total chars"),
661 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
662 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
663 text = wxString::Format (wxT("%d"), edit->GetTextLength());
664 statistic->Add (new wxStaticText (this, wxID_ANY, text),
665 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
666 statistic->Add (new wxStaticText (this, wxID_ANY, _("Current line"),
667 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
668 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
669 text = wxString::Format (wxT("%d"), edit->GetCurrentLine());
670 statistic->Add (new wxStaticText (this, wxID_ANY, text),
671 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
672 statistic->Add (new wxStaticText (this, wxID_ANY, _("Current pos"),
673 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
674 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
675 text = wxString::Format (wxT("%d"), edit->GetCurrentPos());
676 statistic->Add (new wxStaticText (this, wxID_ANY, text),
677 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
678
679 // char/line statistics
680 wxStaticBoxSizer *statistics = new wxStaticBoxSizer (
681 new wxStaticBox (this, wxID_ANY, _("Statistics")),
682 wxVERTICAL);
683 statistics->Add (statistic, 0, wxEXPAND);
684 statistics->Add (0, 6);
685
686 // total pane
687 wxBoxSizer *totalpane = new wxBoxSizer (wxVERTICAL);
688 totalpane->Add (fullname, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 10);
689 totalpane->Add (0, 6);
690 totalpane->Add (textinfos, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
691 totalpane->Add (0, 10);
692 totalpane->Add (statistics, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
693 totalpane->Add (0, 6);
694 wxButton *okButton = new wxButton (this, wxID_OK, _("OK"));
695 okButton->SetDefault();
696 totalpane->Add (okButton, 0, wxALIGN_CENTER | wxALL, 10);
697
698 SetSizerAndFit (totalpane);
699
700 ShowModal();
701 }
702
703 #if wxUSE_PRINTING_ARCHITECTURE
704
705 //----------------------------------------------------------------------------
706 // EditPrint
707 //----------------------------------------------------------------------------
708
709 EditPrint::EditPrint (Edit *edit, const wxChar *title)
710 : wxPrintout(title) {
711 m_edit = edit;
712 m_printed = 0;
713
714 }
715
716 bool EditPrint::OnPrintPage (int page) {
717
718 wxDC *dc = GetDC();
719 if (!dc) return false;
720
721 // scale DC
722 PrintScaling (dc);
723
724 // print page
725 if (page == 1) m_printed = 0;
726 m_printed = m_edit->FormatRange (1, m_printed, m_edit->GetLength(),
727 dc, dc, m_printRect, m_pageRect);
728
729 return true;
730 }
731
732 bool EditPrint::OnBeginDocument (int startPage, int endPage) {
733
734 if (!wxPrintout::OnBeginDocument (startPage, endPage)) {
735 return false;
736 }
737
738 return true;
739 }
740
741 void EditPrint::GetPageInfo (int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) {
742
743 // initialize values
744 *minPage = 0;
745 *maxPage = 0;
746 *selPageFrom = 0;
747 *selPageTo = 0;
748
749 // scale DC if possible
750 wxDC *dc = GetDC();
751 if (!dc) return;
752 PrintScaling (dc);
753
754 // get print page informations and convert to printer pixels
755 wxSize ppiScr;
756 GetPPIScreen (&ppiScr.x, &ppiScr.y);
757 wxSize page = g_pageSetupData->GetPaperSize();
758 page.x = static_cast<int> (page.x * ppiScr.x / 25.4);
759 page.y = static_cast<int> (page.y * ppiScr.y / 25.4);
760 m_pageRect = wxRect (0,
761 0,
762 page.x,
763 page.y);
764
765 // get margins informations and convert to printer pixels
766 wxPoint pt = g_pageSetupData->GetMarginTopLeft();
767 int left = pt.x;
768 int top = pt.y;
769 pt = g_pageSetupData->GetMarginBottomRight();
770 int right = pt.x;
771 int bottom = pt.y;
772
773 top = static_cast<int> (top * ppiScr.y / 25.4);
774 bottom = static_cast<int> (bottom * ppiScr.y / 25.4);
775 left = static_cast<int> (left * ppiScr.x / 25.4);
776 right = static_cast<int> (right * ppiScr.x / 25.4);
777
778 m_printRect = wxRect (left,
779 top,
780 page.x - (left + right),
781 page.y - (top + bottom));
782
783 // count pages
784 while (HasPage (*maxPage)) {
785 m_printed = m_edit->FormatRange (0, m_printed, m_edit->GetLength(),
786 dc, dc, m_printRect, m_pageRect);
787 *maxPage += 1;
788 }
789 if (*maxPage > 0) *minPage = 1;
790 *selPageFrom = *minPage;
791 *selPageTo = *maxPage;
792 }
793
794 bool EditPrint::HasPage (int WXUNUSED(page)) {
795
796 return (m_printed < m_edit->GetLength());
797 }
798
799 bool EditPrint::PrintScaling (wxDC *dc){
800
801 // check for dc, return if none
802 if (!dc) return false;
803
804 // get printer and screen sizing values
805 wxSize ppiScr;
806 GetPPIScreen (&ppiScr.x, &ppiScr.y);
807 if (ppiScr.x == 0) { // most possible guess 96 dpi
808 ppiScr.x = 96;
809 ppiScr.y = 96;
810 }
811 wxSize ppiPrt;
812 GetPPIPrinter (&ppiPrt.x, &ppiPrt.y);
813 if (ppiPrt.x == 0) { // scaling factor to 1
814 ppiPrt.x = ppiScr.x;
815 ppiPrt.y = ppiScr.y;
816 }
817 wxSize dcSize = dc->GetSize();
818 wxSize pageSize;
819 GetPageSizePixels (&pageSize.x, &pageSize.y);
820
821 // set user scale
822 float scale_x = (float)(ppiPrt.x * dcSize.x) /
823 (float)(ppiScr.x * pageSize.x);
824 float scale_y = (float)(ppiPrt.y * dcSize.y) /
825 (float)(ppiScr.y * pageSize.y);
826 dc->SetUserScale (scale_x, scale_y);
827
828 return true;
829 }
830
831 #endif // wxUSE_PRINTING_ARCHITECTURE