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