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