]> git.saurik.com Git - wxWidgets.git/blob - contrib/samples/stc/edit.cpp
Applied compilation fix for memory.cpp.
[wxWidgets.git] / contrib / samples / stc / edit.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 // File: 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 = _T("");
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, wxColour (_T("BLACK")));
136 StyleSetBackground (wxSTC_STYLE_DEFAULT, wxColour (_T("WHITE")));
137 StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour (_T("DARK GREY")));
138 StyleSetBackground (wxSTC_STYLE_LINENUMBER, wxColour (_T("WHITE")));
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.IsEmpty()) {
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, wxColour (_T("WHITE")));
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, wxColour (_T("WHITE")));
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 // get filname
508 if (!m_filename) {
509 wxFileDialog dlg (this, _T("Open file"), _T(""), _T(""),
510 _T("Any file (*)|*"), wxOPEN | wxFILE_MUST_EXIST | wxCHANGE_DIR);
511 if (dlg.ShowModal() != wxID_OK) return false;
512 m_filename = dlg.GetPath();
513 }
514
515 // load file
516 return LoadFile (m_filename);
517 }
518
519 bool Edit::LoadFile (const wxString &filename) {
520
521 // load file in edit and clear undo
522 if (!filename.IsEmpty()) m_filename = filename;
523 // wxFile file (m_filename);
524 // if (!file.IsOpened()) return false;
525 ClearAll ();
526 // long lng = file.Length ();
527 // if (lng > 0) {
528 // wxString buf;
529 // wxChar *buff = buf.GetWriteBuf (lng);
530 // file.Read (buff, lng);
531 // buf.UngetWriteBuf ();
532 // InsertText (0, buf);
533 // }
534 // file.Close();
535
536 wxStyledTextCtrl::LoadFile(m_filename);
537
538 EmptyUndoBuffer();
539
540 // determine lexer language
541 wxFileName fname (m_filename);
542 InitializePrefs (DeterminePrefs (fname.GetFullName()));
543
544 return true;
545 }
546
547 bool Edit::SaveFile () {
548
549 // return if no change
550 if (!Modified()) return true;
551
552 // get filname
553 if (!m_filename) {
554 wxFileDialog dlg (this, _T("Save file"), _T(""), _T(""), _T("Any file (*)|*"),
555 wxSAVE | wxOVERWRITE_PROMPT);
556 if (dlg.ShowModal() != wxID_OK) return false;
557 m_filename = dlg.GetPath();
558 }
559
560 // save file
561 return SaveFile (m_filename);
562 }
563
564 bool Edit::SaveFile (const wxString &filename) {
565
566 // return if no change
567 if (!Modified()) return true;
568
569 // // save edit in file and clear undo
570 // if (!filename.IsEmpty()) m_filename = filename;
571 // wxFile file (m_filename, wxFile::write);
572 // if (!file.IsOpened()) return false;
573 // wxString buf = GetText();
574 // bool okay = file.Write (buf);
575 // file.Close();
576 // if (!okay) return false;
577 // EmptyUndoBuffer();
578 // SetSavePoint();
579
580 // return true;
581
582 return wxStyledTextCtrl::SaveFile(filename);
583
584 }
585
586 bool Edit::Modified () {
587
588 // return modified state
589 return (GetModify() && !GetReadOnly());
590 }
591
592 //----------------------------------------------------------------------------
593 // EditProperties
594 //----------------------------------------------------------------------------
595
596 EditProperties::EditProperties (Edit *edit,
597 long style)
598 : wxDialog (edit, wxID_ANY, wxEmptyString,
599 wxDefaultPosition, wxDefaultSize,
600 style | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
601
602 // sets the application title
603 SetTitle (_("Properties"));
604 wxString text;
605
606 // fullname
607 wxBoxSizer *fullname = new wxBoxSizer (wxHORIZONTAL);
608 fullname->Add (10, 0);
609 fullname->Add (new wxStaticText (this, wxID_ANY, _("Full filename"),
610 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
611 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
612 fullname->Add (new wxStaticText (this, wxID_ANY, edit->GetFilename()),
613 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
614
615 // text info
616 wxGridSizer *textinfo = new wxGridSizer (4, 0, 2);
617 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Language"),
618 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
619 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
620 textinfo->Add (new wxStaticText (this, wxID_ANY, edit->m_language->name),
621 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
622 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Lexer-ID: "),
623 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
624 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
625 text = wxString::Format (_T("%d"), edit->GetLexer());
626 textinfo->Add (new wxStaticText (this, wxID_ANY, text),
627 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
628 wxString EOLtype = _T("");
629 switch (edit->GetEOLMode()) {
630 case wxSTC_EOL_CR: {EOLtype = _T("CR (Unix)"); break; }
631 case wxSTC_EOL_CRLF: {EOLtype = _T("CRLF (Windows)"); break; }
632 case wxSTC_EOL_LF: {EOLtype = _T("CR (Macintosh)"); break; }
633 }
634 textinfo->Add (new wxStaticText (this, wxID_ANY, _("Line endings"),
635 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
636 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
637 textinfo->Add (new wxStaticText (this, wxID_ANY, EOLtype),
638 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
639
640 // text info box
641 wxStaticBoxSizer *textinfos = new wxStaticBoxSizer (
642 new wxStaticBox (this, wxID_ANY, _("Informations")),
643 wxVERTICAL);
644 textinfos->Add (textinfo, 0, wxEXPAND);
645 textinfos->Add (0, 6);
646
647 // statistic
648 wxGridSizer *statistic = new wxGridSizer (4, 0, 2);
649 statistic->Add (new wxStaticText (this, wxID_ANY, _("Total lines"),
650 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
651 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
652 text = wxString::Format (_T("%d"), edit->GetLineCount());
653 statistic->Add (new wxStaticText (this, wxID_ANY, text),
654 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
655 statistic->Add (new wxStaticText (this, wxID_ANY, _("Total chars"),
656 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
657 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
658 text = wxString::Format (_T("%d"), edit->GetTextLength());
659 statistic->Add (new wxStaticText (this, wxID_ANY, text),
660 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
661 statistic->Add (new wxStaticText (this, wxID_ANY, _("Current line"),
662 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
663 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
664 text = wxString::Format (_T("%d"), edit->GetCurrentLine());
665 statistic->Add (new wxStaticText (this, wxID_ANY, text),
666 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
667 statistic->Add (new wxStaticText (this, wxID_ANY, _("Current pos"),
668 wxDefaultPosition, wxSize(80, wxDefaultCoord)),
669 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
670 text = wxString::Format (_T("%d"), edit->GetCurrentPos());
671 statistic->Add (new wxStaticText (this, wxID_ANY, text),
672 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
673
674 // char/line statistics
675 wxStaticBoxSizer *statistics = new wxStaticBoxSizer (
676 new wxStaticBox (this, wxID_ANY, _("Statistics")),
677 wxVERTICAL);
678 statistics->Add (statistic, 0, wxEXPAND);
679 statistics->Add (0, 6);
680
681 // total pane
682 wxBoxSizer *totalpane = new wxBoxSizer (wxVERTICAL);
683 totalpane->Add (fullname, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 10);
684 totalpane->Add (0, 6);
685 totalpane->Add (textinfos, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
686 totalpane->Add (0, 10);
687 totalpane->Add (statistics, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
688 totalpane->Add (0, 6);
689 wxButton *okButton = new wxButton (this, wxID_OK, _("OK"));
690 okButton->SetDefault();
691 totalpane->Add (okButton, 0, wxALIGN_CENTER | wxALL, 10);
692
693 SetSizerAndFit (totalpane);
694
695 ShowModal();
696 }
697
698 //----------------------------------------------------------------------------
699 // EditPrint
700 //----------------------------------------------------------------------------
701
702 EditPrint::EditPrint (Edit *edit, wxChar *title)
703 : wxPrintout(title) {
704 m_edit = edit;
705 m_printed = 0;
706
707 }
708
709 bool EditPrint::OnPrintPage (int page) {
710
711 wxDC *dc = GetDC();
712 if (!dc) return false;
713
714 // scale DC
715 PrintScaling (dc);
716
717 // print page
718 if (page == 1) m_printed = 0;
719 m_printed = m_edit->FormatRange (1, m_printed, m_edit->GetLength(),
720 dc, dc, m_printRect, m_pageRect);
721
722 return true;
723 }
724
725 bool EditPrint::OnBeginDocument (int startPage, int endPage) {
726
727 if (!wxPrintout::OnBeginDocument (startPage, endPage)) {
728 return false;
729 }
730
731 return true;
732 }
733
734 void EditPrint::GetPageInfo (int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) {
735
736 // initialize values
737 *minPage = 0;
738 *maxPage = 0;
739 *selPageFrom = 0;
740 *selPageTo = 0;
741
742 // scale DC if possible
743 wxDC *dc = GetDC();
744 if (!dc) return;
745 PrintScaling (dc);
746
747 // get print page informations and convert to printer pixels
748 wxSize ppiScr;
749 GetPPIScreen (&ppiScr.x, &ppiScr.y);
750 wxSize page = g_pageSetupData->GetPaperSize();
751 page.x = static_cast<int> (page.x * ppiScr.x / 25.4);
752 page.y = static_cast<int> (page.y * ppiScr.y / 25.4);
753 m_pageRect = wxRect (0,
754 0,
755 page.x,
756 page.y);
757
758 // get margins informations and convert to printer pixels
759 int top = 25; // default 25
760 int bottom = 25; // default 25
761 int left = 20; // default 20
762 int right = 20; // default 20
763 wxPoint (top, left) = g_pageSetupData->GetMarginTopLeft();
764 wxPoint (bottom, right) = g_pageSetupData->GetMarginBottomRight();
765 top = static_cast<int> (top * ppiScr.y / 25.4);
766 bottom = static_cast<int> (bottom * ppiScr.y / 25.4);
767 left = static_cast<int> (left * ppiScr.x / 25.4);
768 right = static_cast<int> (right * ppiScr.x / 25.4);
769 m_printRect = wxRect (left,
770 top,
771 page.x - (left + right),
772 page.y - (top + bottom));
773
774 // count pages
775 while (HasPage (*maxPage)) {
776 m_printed = m_edit->FormatRange (0, m_printed, m_edit->GetLength(),
777 dc, dc, m_printRect, m_pageRect);
778 *maxPage += 1;
779 }
780 if (*maxPage > 0) *minPage = 1;
781 *selPageFrom = *minPage;
782 *selPageTo = *maxPage;
783 }
784
785 bool EditPrint::HasPage (int WXUNUSED(page)) {
786
787 return (m_printed < m_edit->GetLength());
788 }
789
790 bool EditPrint::PrintScaling (wxDC *dc){
791
792 // check for dc, return if none
793 if (!dc) return false;
794
795 // get printer and screen sizing values
796 wxSize ppiScr;
797 GetPPIScreen (&ppiScr.x, &ppiScr.y);
798 if (ppiScr.x == 0) { // most possible guess 96 dpi
799 ppiScr.x = 96;
800 ppiScr.y = 96;
801 }
802 wxSize ppiPrt;
803 GetPPIPrinter (&ppiPrt.x, &ppiPrt.y);
804 if (ppiPrt.x == 0) { // scaling factor to 1
805 ppiPrt.x = ppiScr.x;
806 ppiPrt.y = ppiScr.y;
807 }
808 wxSize dcSize = dc->GetSize();
809 wxSize pageSize;
810 GetPageSizePixels (&pageSize.x, &pageSize.y);
811
812 // set user scale
813 float scale_x = (float)(ppiPrt.x * dcSize.x) /
814 (float)(ppiScr.x * pageSize.x);
815 float scale_y = (float)(ppiPrt.y * dcSize.y) /
816 (float)(ppiScr.y * pageSize.y);
817 dc->SetUserScale (scale_x, scale_y);
818
819 return true;
820 }
821