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