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