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