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