]> git.saurik.com Git - wxWidgets.git/blame - samples/stc/edit.cpp
Extract wxFDIOEventLoopSourceHandler in its own header.
[wxWidgets.git] / samples / stc / edit.cpp
CommitLineData
88a8b04e 1//////////////////////////////////////////////////////////////////////////////
f4ec6bd2 2// File: contrib/samples/stc/edit.cpp
88a8b04e
RD
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
f4ec6bd2 20// For compilers that support precompilation, includes "wx/wx.h".
c40691a0 21#include "wx/wxprec.h"
88a8b04e
RD
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27// for all others, include the necessary headers (this file is usually all you
be5a51fb 28// need because it includes almost all 'standard' wxWidgets headers)
88a8b04e 29#ifndef WX_PRECOMP
c40691a0 30 #include "wx/wx.h"
2fb4e3cb 31 #include "wx/textdlg.h"
88a8b04e
RD
32#endif
33
be5a51fb 34//! wxWidgets headers
c40691a0
WS
35#include "wx/file.h" // raw file io support
36#include "wx/filename.h" // filename support
88a8b04e
RD
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
2fb4e3cb
VZ
53// The (uniform) style used for the annotations.
54const int ANNOTATION_STYLE = wxSTC_STYLE_LASTPREDEFINED + 1;
88a8b04e
RD
55
56//============================================================================
57// implementation
58//============================================================================
59
60//----------------------------------------------------------------------------
61// Edit
62//----------------------------------------------------------------------------
63
64BEGIN_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)
2fb4e3cb
VZ
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)
88a8b04e
RD
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
7e126a07
WS
113 EVT_STC_MARGINCLICK (wxID_ANY, Edit::OnMarginClick)
114 EVT_STC_CHARADDED (wxID_ANY, Edit::OnCharAdded)
9e96e16f 115 EVT_STC_KEY( wxID_ANY , Edit::OnKey )
88a8b04e
RD
116END_EVENT_TABLE()
117
118Edit::Edit (wxWindow *parent, wxWindowID id,
119 const wxPoint &pos,
120 const wxSize &size,
121 long style)
122 : wxStyledTextCtrl (parent, id, pos, size, style) {
123
c8547e17 124 m_filename = wxEmptyString;
88a8b04e
RD
125
126 m_LineNrID = 0;
127 m_DividerID = 1;
128 m_FoldingID = 2;
129
130 // initialize language
131 m_language = NULL;
132
d0c8c55a
RD
133 // Use all the bits in the style byte as styles, not indicators.
134 SetStyleBits(8);
135
88a8b04e
RD
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);
c8547e17
WS
149 StyleSetForeground (wxSTC_STYLE_DEFAULT, *wxBLACK);
150 StyleSetBackground (wxSTC_STYLE_DEFAULT, *wxWHITE);
9a83f860 151 StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour (wxT("DARK GREY")));
c8547e17 152 StyleSetBackground (wxSTC_STYLE_LINENUMBER, *wxWHITE);
9a83f860 153 StyleSetForeground(wxSTC_STYLE_INDENTGUIDE, wxColour (wxT("DARK GREY")));
88a8b04e
RD
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
9a83f860
VZ
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"));
88a8b04e 169
2fb4e3cb
VZ
170 // annotations
171 AnnotationSetVisible(wxSTC_ANNOTATION_BOXED);
172
173 // miscellaneous
9a83f860 174 m_LineNrMargin = TextWidth (wxSTC_STYLE_LINENUMBER, wxT("_999999"));
88a8b04e 175 m_FoldingMargin = 16;
88a8b04e 176 CmdKeyClear (wxSTC_KEY_TAB, 0); // this is done by the menu accelerator key
88a8b04e
RD
177 SetLayoutCache (wxSTC_CACHE_PAGE);
178
179}
180
181Edit::~Edit () {}
182
183//----------------------------------------------------------------------------
184// common event handlers
185void 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
194void Edit::OnEditRedo (wxCommandEvent &WXUNUSED(event)) {
195 if (!CanRedo()) return;
196 Redo ();
197}
198
199void Edit::OnEditUndo (wxCommandEvent &WXUNUSED(event)) {
200 if (!CanUndo()) return;
201 Undo ();
202}
203
204void Edit::OnEditClear (wxCommandEvent &WXUNUSED(event)) {
205 if (GetReadOnly()) return;
206 Clear ();
207}
208
be8332eb 209void Edit::OnKey (wxStyledTextEvent &WXUNUSED(event))
9e96e16f
RD
210{
211 wxMessageBox("OnKey");
212}
213
88a8b04e
RD
214void Edit::OnEditCut (wxCommandEvent &WXUNUSED(event)) {
215 if (GetReadOnly() || (GetSelectionEnd()-GetSelectionStart() <= 0)) return;
216 Cut ();
217}
218
219void Edit::OnEditCopy (wxCommandEvent &WXUNUSED(event)) {
220 if (GetSelectionEnd()-GetSelectionStart() <= 0) return;
221 Copy ();
222}
223
224void Edit::OnEditPaste (wxCommandEvent &WXUNUSED(event)) {
225 if (!CanPaste()) return;
226 Paste ();
227}
228
229void Edit::OnFind (wxCommandEvent &WXUNUSED(event)) {
230}
231
232void Edit::OnFindNext (wxCommandEvent &WXUNUSED(event)) {
233}
234
235void Edit::OnReplace (wxCommandEvent &WXUNUSED(event)) {
236}
237
238void Edit::OnReplaceNext (wxCommandEvent &WXUNUSED(event)) {
239}
240
241void 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
252void Edit::OnGoto (wxCommandEvent &WXUNUSED(event)) {
253}
254
0e974385 255void Edit::OnEditIndentInc (wxCommandEvent &WXUNUSED(event)) {
88a8b04e
RD
256 CmdKeyExecute (wxSTC_CMD_TAB);
257}
258
0e974385 259void Edit::OnEditIndentRed (wxCommandEvent &WXUNUSED(event)) {
88a8b04e
RD
260 CmdKeyExecute (wxSTC_CMD_DELETEBACK);
261}
262
263void Edit::OnEditSelectAll (wxCommandEvent &WXUNUSED(event)) {
264 SetSelection (0, GetTextLength ());
265}
266
267void Edit::OnEditSelectLine (wxCommandEvent &WXUNUSED(event)) {
268 int lineStart = PositionFromLine (GetCurrentLine());
269 int lineEnd = PositionFromLine (GetCurrentLine() + 1);
270 SetSelection (lineStart, lineEnd);
271}
272
273void Edit::OnHilightLang (wxCommandEvent &event) {
274 InitializePrefs (g_LanguagePrefs [event.GetId() - myID_HILIGHTFIRST].name);
275}
276
277void Edit::OnDisplayEOL (wxCommandEvent &WXUNUSED(event)) {
278 SetViewEOL (!GetViewEOL());
279}
280
281void Edit::OnIndentGuide (wxCommandEvent &WXUNUSED(event)) {
282 SetIndentationGuides (!GetIndentationGuides());
283}
284
285void Edit::OnLineNumber (wxCommandEvent &WXUNUSED(event)) {
286 SetMarginWidth (m_LineNrID,
287 GetMarginWidth (m_LineNrID) == 0? m_LineNrMargin: 0);
288}
289
290void Edit::OnLongLineOn (wxCommandEvent &WXUNUSED(event)) {
291 SetEdgeMode (GetEdgeMode() == 0? wxSTC_EDGE_LINE: wxSTC_EDGE_NONE);
292}
293
294void Edit::OnWhiteSpace (wxCommandEvent &WXUNUSED(event)) {
295 SetViewWhiteSpace (GetViewWhiteSpace() == 0?
296 wxSTC_WS_VISIBLEALWAYS: wxSTC_WS_INVISIBLE);
297}
298
299void Edit::OnFoldToggle (wxCommandEvent &WXUNUSED(event)) {
300 ToggleFold (GetFoldParent(GetCurrentLine()));
301}
302
303void Edit::OnSetOverType (wxCommandEvent &WXUNUSED(event)) {
304 SetOvertype (!GetOvertype());
305}
306
307void Edit::OnSetReadOnly (wxCommandEvent &WXUNUSED(event)) {
308 SetReadOnly (!GetReadOnly());
309}
310
311void Edit::OnWrapmodeOn (wxCommandEvent &WXUNUSED(event)) {
312 SetWrapMode (GetWrapMode() == 0? wxSTC_WRAP_WORD: wxSTC_WRAP_NONE);
313}
314
315void 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
2fb4e3cb
VZ
328void 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
371void Edit::OnAnnotationRemove(wxCommandEvent& WXUNUSED(event))
372{
373 AnnotationSetText(GetCurrentLine(), wxString());
374}
375
376void Edit::OnAnnotationClear(wxCommandEvent& WXUNUSED(event))
377{
378 AnnotationClearAll();
379}
380
381void 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
88a8b04e
RD
401void 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
414void 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
426void 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
436void Edit::OnCharAdded (wxStyledTextEvent &event) {
c193de84 437 char chr = (char)event.GetKey();
88a8b04e
RD
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
454wxString Edit::DeterminePrefs (const wxString &filename) {
455
1e545382 456 LanguageInfo const* curInfo;
88a8b04e
RD
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();
c8547e17 464 while (!filepattern.empty()) {
88a8b04e
RD
465 wxString cur = filepattern.BeforeFirst (';');
466 if ((cur == filename) ||
9a83f860
VZ
467 (cur == (filename.BeforeLast ('.') + wxT(".*"))) ||
468 (cur == (wxT("*.") + filename.AfterLast ('.')))) {
88a8b04e
RD
469 return curInfo->name;
470 }
471 filepattern = filepattern.AfterFirst (';');
472 }
473 }
474 return wxEmptyString;
475
476}
477
478bool 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);
9a83f860 502 StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour (wxT("DARK GREY")));
c8547e17 503 StyleSetBackground (wxSTC_STYLE_LINENUMBER, *wxWHITE);
e411268c 504 SetMarginWidth (m_LineNrID, 0); // start out not visible
88a8b04e 505
2fb4e3cb
VZ
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
88a8b04e
RD
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
9a83f860
VZ
520 StyleSetForeground (wxSTC_STYLE_DEFAULT, wxColour (wxT("DARK GREY")));
521 StyleSetForeground (wxSTC_STYLE_INDENTGUIDE, wxColour (wxT("DARK GREY")));
88a8b04e
RD
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);
1153f54c 543 const char *pwords = curInfo->styles[Nr].words;
88a8b04e
RD
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);
c8547e17 559 StyleSetBackground (m_FoldingID, *wxWHITE);
88a8b04e
RD
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);
9a83f860
VZ
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"));
88a8b04e
RD
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
71307412
WS
606bool Edit::LoadFile ()
607{
608#if wxUSE_FILEDLG
88a8b04e
RD
609 // get filname
610 if (!m_filename) {
9a83f860
VZ
611 wxFileDialog dlg (this, wxT("Open file"), wxEmptyString, wxEmptyString,
612 wxT("Any file (*)|*"), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR);
88a8b04e
RD
613 if (dlg.ShowModal() != wxID_OK) return false;
614 m_filename = dlg.GetPath();
615 }
616
617 // load file
618 return LoadFile (m_filename);
71307412
WS
619#else
620 return false;
621#endif // wxUSE_FILEDLG
88a8b04e
RD
622}
623
624bool Edit::LoadFile (const wxString &filename) {
625
626 // load file in edit and clear undo
c8547e17 627 if (!filename.empty()) m_filename = filename;
7e126a07 628
88a8b04e 629 wxStyledTextCtrl::LoadFile(m_filename);
7e126a07 630
88a8b04e
RD
631 EmptyUndoBuffer();
632
633 // determine lexer language
634 wxFileName fname (m_filename);
635 InitializePrefs (DeterminePrefs (fname.GetFullName()));
636
637 return true;
638}
639
71307412
WS
640bool Edit::SaveFile ()
641{
642#if wxUSE_FILEDLG
88a8b04e
RD
643 // return if no change
644 if (!Modified()) return true;
645
646 // get filname
647 if (!m_filename) {
9a83f860 648 wxFileDialog dlg (this, wxT("Save file"), wxEmptyString, wxEmptyString, wxT("Any file (*)|*"),
ff3e84ff 649 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
88a8b04e
RD
650 if (dlg.ShowModal() != wxID_OK) return false;
651 m_filename = dlg.GetPath();
652 }
653
654 // save file
655 return SaveFile (m_filename);
71307412
WS
656#else
657 return false;
658#endif // wxUSE_FILEDLG
88a8b04e
RD
659}
660
661bool 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
c8547e17 667// if (!filename.empty()) m_filename = filename;
88a8b04e
RD
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);
7e126a07 680
88a8b04e
RD
681}
682
683bool Edit::Modified () {
684
685 // return modified state
686 return (GetModify() && !GetReadOnly());
687}
688
689//----------------------------------------------------------------------------
690// EditProperties
691//----------------------------------------------------------------------------
692
693EditProperties::EditProperties (Edit *edit,
694 long style)
7e126a07 695 : wxDialog (edit, wxID_ANY, wxEmptyString,
88a8b04e 696 wxDefaultPosition, wxDefaultSize,
0e974385 697 style | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
88a8b04e
RD
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);
7e126a07
WS
706 fullname->Add (new wxStaticText (this, wxID_ANY, _("Full filename"),
707 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 708 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
7e126a07 709 fullname->Add (new wxStaticText (this, wxID_ANY, edit->GetFilename()),
88a8b04e
RD
710 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
711
712 // text info
713 wxGridSizer *textinfo = new wxGridSizer (4, 0, 2);
7e126a07
WS
714 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Language"),
715 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 716 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
7e126a07 717 textinfo->Add (new wxStaticText (this, wxID_ANY, edit->m_language->name),
88a8b04e 718 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
7e126a07
WS
719 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Lexer-ID: "),
720 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 721 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
9a83f860 722 text = wxString::Format (wxT("%d"), edit->GetLexer());
7e126a07 723 textinfo->Add (new wxStaticText (this, wxID_ANY, text),
88a8b04e 724 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
c8547e17 725 wxString EOLtype = wxEmptyString;
88a8b04e 726 switch (edit->GetEOLMode()) {
9a83f860
VZ
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; }
88a8b04e 730 }
7e126a07
WS
731 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Line endings"),
732 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 733 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
7e126a07 734 textinfo->Add (new wxStaticText (this, wxID_ANY, EOLtype),
88a8b04e
RD
735 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
736
737 // text info box
738 wxStaticBoxSizer *textinfos = new wxStaticBoxSizer (
7e126a07 739 new wxStaticBox (this, wxID_ANY, _("Informations")),
88a8b04e
RD
740 wxVERTICAL);
741 textinfos->Add (textinfo, 0, wxEXPAND);
742 textinfos->Add (0, 6);
743
744 // statistic
745 wxGridSizer *statistic = new wxGridSizer (4, 0, 2);
7e126a07
WS
746 statistic->Add (new wxStaticText (this, wxID_ANY, _("Total lines"),
747 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 748 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
9a83f860 749 text = wxString::Format (wxT("%d"), edit->GetLineCount());
7e126a07 750 statistic->Add (new wxStaticText (this, wxID_ANY, text),
88a8b04e 751 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
7e126a07
WS
752 statistic->Add (new wxStaticText (this, wxID_ANY, _("Total chars"),
753 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 754 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
9a83f860 755 text = wxString::Format (wxT("%d"), edit->GetTextLength());
7e126a07 756 statistic->Add (new wxStaticText (this, wxID_ANY, text),
88a8b04e 757 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
7e126a07
WS
758 statistic->Add (new wxStaticText (this, wxID_ANY, _("Current line"),
759 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 760 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
9a83f860 761 text = wxString::Format (wxT("%d"), edit->GetCurrentLine());
7e126a07 762 statistic->Add (new wxStaticText (this, wxID_ANY, text),
88a8b04e 763 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
7e126a07
WS
764 statistic->Add (new wxStaticText (this, wxID_ANY, _("Current pos"),
765 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
88a8b04e 766 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
9a83f860 767 text = wxString::Format (wxT("%d"), edit->GetCurrentPos());
7e126a07 768 statistic->Add (new wxStaticText (this, wxID_ANY, text),
88a8b04e
RD
769 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
770
771 // char/line statistics
772 wxStaticBoxSizer *statistics = new wxStaticBoxSizer (
7e126a07 773 new wxStaticBox (this, wxID_ANY, _("Statistics")),
88a8b04e
RD
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
71307412
WS
795#if wxUSE_PRINTING_ARCHITECTURE
796
88a8b04e
RD
797//----------------------------------------------------------------------------
798// EditPrint
799//----------------------------------------------------------------------------
800
522a028a 801EditPrint::EditPrint (Edit *edit, const wxChar *title)
88a8b04e
RD
802 : wxPrintout(title) {
803 m_edit = edit;
804 m_printed = 0;
805
806}
807
808bool 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
824bool EditPrint::OnBeginDocument (int startPage, int endPage) {
825
826 if (!wxPrintout::OnBeginDocument (startPage, endPage)) {
827 return false;
828 }
829
830 return true;
831}
832
833void 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
c8547e17
WS
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
88a8b04e
RD
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);
c8547e17 869
88a8b04e
RD
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
0e974385 886bool EditPrint::HasPage (int WXUNUSED(page)) {
88a8b04e
RD
887
888 return (m_printed < m_edit->GetLength());
889}
890
891bool 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
71307412 923#endif // wxUSE_PRINTING_ARCHITECTURE