1 /********************************************************************
2 * Module: editor.cpp. This is part of Visual-MinGW.
4 * Purpose: Procedures to manage Scintilla editor.
6 * Authors: These classes are based on SciTE release 1.39.
7 * http://www.scintilla.org/
8 * SciTE original code by Neil Hodgson.
9 * Present revised code by Manu B.
11 * License: Both SciTE and Scintilla are covered by
12 * "License for Scintilla and SciTE" agreement terms detailed in license.htm.
13 * Present revised code is covered by GNU General Public License.
17 ********************************************************************/
25 extern CMessageBox MsgBox
;
27 int Minimum(int a
, int b
);
28 int Maximum(int a
, int b
);
30 int Minimum(int a
, int b
){
37 int Maximum(int a
, int b
){
44 void EnsureRangeVisible(HWND hwndCtrl
, int posStart
, int posEnd
, bool enforcePolicy
){
45 int lineStart
= SendMessage(hwndCtrl
, SCI_LINEFROMPOSITION
, Minimum(posStart
, posEnd
), 0);
46 int lineEnd
= SendMessage(hwndCtrl
, SCI_LINEFROMPOSITION
, Maximum(posStart
, posEnd
), 0);
47 for (int line
= lineStart
; line
<= lineEnd
; line
++){
49 enforcePolicy
? SCI_ENSUREVISIBLEENFORCEPOLICY
: SCI_ENSUREVISIBLE
, line
, 0);
53 int LengthDocument(HWND hwndCtrl
){
54 return SendMessage(hwndCtrl
, SCI_GETLENGTH
, 0, 0);
57 CharacterRange
GetSelection(HWND hwndCtrl
){
58 CharacterRange crange
;
59 crange
.cpMin
= SendMessage(hwndCtrl
, SCI_GETSELECTIONSTART
, 0, 0);
60 crange
.cpMax
= SendMessage(hwndCtrl
, SCI_GETSELECTIONEND
, 0, 0);
65 /********************************************************************
66 * Class: CChooseFontDlg.
72 ********************************************************************/
73 CChooseFontDlg::CChooseFontDlg(){
74 ZeroMemory(&lf
, sizeof(LOGFONT
));
88 lf.lfFaceName[LF_FACESIZE];*/
90 cf
.lStructSize
= sizeof(CHOOSEFONT
);
93 cf
.lpLogFont
= &lf
;//&(Profile.LogFont);
95 cf
.Flags
= /*CF_INITTOLOGFONTSTRUCT
96 |*/ CF_SCREENFONTS
| CF_EFFECTS
98 cf
.rgbColors
= 0;//Profile.rgbForeColor;
101 cf
.lpTemplateName
= NULL
;
104 cf
.nFontType
= SCREEN_FONTTYPE
;
109 CChooseFontDlg::~CChooseFontDlg(){
112 bool CChooseFontDlg::Create(CWindow
* pWindow
){
113 cf
.hwndOwner
= pWindow
->_hWnd
;
114 return ChooseFont(&cf
);
118 /*bool ChooseNewFont(HWND hWndListBox){
119 static CHOOSEFONT cf;
120 static BOOL bFirstTime = TRUE;
127 hFont = CreateFontIndirect( &(Profile.LogFont) );
128 hDC = GetDC( hWndListBox );
129 SelectObject( hDC, hFont );
130 Profile.rgbForeColor = cf.rgbColors;
131 InvalidateRect( hWndListBox, NULL, TRUE );
132 SendMessage( hWndListBox, WM_CTLCOLORLISTBOX, (DWORD) hDC, (LONG) hWndListBox );
133 SendMessage( hWndListBox, WM_SETFONT, (DWORD) hFont, TRUE );
134 ReleaseDC( hWndListBox, hDC );
140 /********************************************************************
141 * Class: CFindReplaceDlg.
147 ********************************************************************/
148 CFindReplaceDlg::CFindReplaceDlg(){
160 bReverseFind
= false;
164 CFindReplaceDlg::~CFindReplaceDlg(){
167 HWND
CFindReplaceDlg::Find(CScintilla
* pEditor
){
168 if (_hWnd
|| !pEditor
)
170 return CreateParam(pEditor
, IDD_FIND
, (long) IDD_FIND
);
173 HWND
CFindReplaceDlg::Replace(CScintilla
* pEditor
){
174 if (_hWnd
|| !pEditor
)
176 return CreateParam(pEditor
, IDD_REPLACE
, (long) IDD_REPLACE
);
179 LRESULT CALLBACK
CFindReplaceDlg::CDlgProc(UINT Message
, WPARAM wParam
, LPARAM lParam
){
182 return OnInitDialog((HWND
) wParam
, lParam
);
185 OnCommand(HIWORD(wParam
), LOWORD(wParam
), (HWND
) lParam
);
195 BOOL
CFindReplaceDlg::OnInitDialog(HWND
, LPARAM lInitParam
){
197 pEditor
= (CEditor
*) _pParent
;
201 hEditor
= pEditor
->_hWnd
;
204 hFindWhat
= GetItem(IDC_FINDWHAT
);
205 hWholeWord
= GetItem(IDC_WHOLEWORD
);
206 hMatchCase
= GetItem(IDC_MATCHCASE
);
207 hRegExp
= GetItem(IDC_REGEXP
);
208 hWrap
= GetItem(IDC_WRAP
);
209 hUnSlash
= GetItem(IDC_UNSLASH
);
211 if (resId
== IDD_FIND
)
212 return Find_OnInitDialog();
213 else if (resId
== IDD_REPLACE
)
214 return Replace_OnInitDialog();
218 BOOL
CFindReplaceDlg::Find_OnInitDialog(void){
220 hUp
= GetItem(IDC_DIRECTIONUP
);
221 hDown
= GetItem(IDC_DIRECTIONDOWN
);
223 SetItemText(hFindWhat
, findWhat
);
224 //FillComboFromMemory(wFindWhat, memFinds);
226 ::SendMessage(hWholeWord
, BM_SETCHECK
, BST_CHECKED
, 0);
228 ::SendMessage(hMatchCase
, BM_SETCHECK
, BST_CHECKED
, 0);
230 ::SendMessage(hRegExp
, BM_SETCHECK
, BST_CHECKED
, 0);
232 ::SendMessage(hWrap
, BM_SETCHECK
, BST_CHECKED
, 0);
234 ::SendMessage(hUnSlash
, BM_SETCHECK
, BST_CHECKED
, 0);
237 ::SendMessage(hUp
, BM_SETCHECK
, BST_CHECKED
, 0);
239 ::SendMessage(hDown
, BM_SETCHECK
, BST_CHECKED
, 0);
244 BOOL
CFindReplaceDlg::Replace_OnInitDialog(void){
245 SetItemText(hFindWhat
, findWhat
);
246 //FillComboFromMemory(wFindWhat, sci->memFinds);
248 hReplaceWith
= GetItem(IDC_REPLACEWITH
);
249 SetItemText(hReplaceWith
, replaceWhat
);
250 //FillComboFromMemory(wReplaceWith, sci->memReplaces);
253 ::SendMessage(hWholeWord
, BM_SETCHECK
, BST_CHECKED
, 0);
255 ::SendMessage(hMatchCase
, BM_SETCHECK
, BST_CHECKED
, 0);
257 ::SendMessage(hRegExp
, BM_SETCHECK
, BST_CHECKED
, 0);
259 ::SendMessage(hWrap
, BM_SETCHECK
, BST_CHECKED
, 0);
261 ::SendMessage(hUnSlash
, BM_SETCHECK
, BST_CHECKED
, 0);
262 if ((findWhat
) != '\0'){
263 ::SetFocus(hReplaceWith
);
269 BOOL
CFindReplaceDlg::OnCommand(WORD
, WORD wID
, HWND
){
270 if (resId
== IDD_FIND
)
271 return Find_OnCommand(wID
);
272 else if (resId
== IDD_REPLACE
)
273 return Replace_OnCommand(wID
);
277 BOOL
CFindReplaceDlg::Find_OnCommand(WORD wID
){
281 GetItemText(hFindWhat
, s
, sizeof(s
));
283 //memFinds.Insert(s);
284 bWholeWord
= BST_CHECKED
==
285 ::SendMessage(hWholeWord
, BM_GETCHECK
, 0, 0);
286 bMatchCase
= BST_CHECKED
==
287 ::SendMessage(hMatchCase
, BM_GETCHECK
, 0, 0);
288 bRegExp
= BST_CHECKED
==
289 ::SendMessage(hRegExp
, BM_GETCHECK
, 0, 0);
290 bWrapFind
= BST_CHECKED
==
291 ::SendMessage(hWrap
, BM_GETCHECK
, 0, 0);
292 bUnSlash
= BST_CHECKED
==
293 ::SendMessage(hUnSlash
, BM_GETCHECK
, 0, 0);
294 bReverseFind
= BST_CHECKED
==
295 ::SendMessage(hUp
, BM_GETCHECK
, 0, 0);
297 FindNext(bReverseFind
, true);
307 BOOL
CFindReplaceDlg::Replace_OnCommand(WORD wID
){
308 if (wID
== IDCANCEL
){
312 return HandleReplaceCommand(wID
);
317 void CFindReplaceDlg::FindNext(bool reverseDirection
, bool showWarnings
){
319 MsgBox
.DisplayWarning("Can't get editor handle");
323 if (!findWhat
[0]) { // nothing to found
327 char findTarget
[FR_MAX_LEN
+ 1];
328 strcpy(findTarget
, findWhat
);
330 // for C conversions -> int lenFind = UnSlashAsNeeded(findTarget, unSlash, regExp);
331 int lenFind
= strlen(findTarget
); // normal return of UnSlashAsNeeded
336 CharacterRange cr
= GetSelection(hEditor
);
337 int startPosition
= cr
.cpMax
;
338 int endPosition
= LengthDocument(hEditor
);
340 if (reverseDirection
){
341 startPosition
= cr
.cpMin
- 1;
345 int flags
= (bWholeWord
? SCFIND_WHOLEWORD
: 0) |
346 (bMatchCase
? SCFIND_MATCHCASE
: 0) |
347 (bRegExp
? SCFIND_REGEXP
: 0);
349 ::SendMessage(hEditor
, SCI_SETTARGETSTART
, startPosition
, 0);
350 ::SendMessage(hEditor
, SCI_SETTARGETEND
, endPosition
, 0);
351 ::SendMessage(hEditor
, SCI_SETSEARCHFLAGS
, flags
, 0);
352 int posFind
= ::SendMessage(hEditor
, SCI_SEARCHINTARGET
, lenFind
, (LPARAM
) findTarget
);
354 if (posFind
== -1 && bWrapFind
){ // not found with wrapFind
356 // Failed to find in indicated direction
357 // so search from the beginning (forward) or from the end (reverse)
358 // unless wrapFind is false
359 if (reverseDirection
){
360 startPosition
= LengthDocument(hEditor
);
364 endPosition
= LengthDocument(hEditor
);
366 ::SendMessage(hEditor
, SCI_SETTARGETSTART
, startPosition
, 0);
367 ::SendMessage(hEditor
, SCI_SETTARGETEND
, endPosition
, 0);
368 posFind
= ::SendMessage(hEditor
, SCI_SEARCHINTARGET
, lenFind
, (LPARAM
) findTarget
);
370 if (posFind
== -1){ // not found
374 /*warn that not found
375 WarnUser(warnNotFound);*/
377 if (strlen(findWhat
) > FR_MAX_LEN
)
378 findWhat
[FR_MAX_LEN
] = '\0';
379 char msg
[FR_MAX_LEN
+ 50];
380 strcpy(msg
, "Cannot find the string \"");
381 strcat(msg
, findWhat
);
384 MsgBox
.DisplayWarning(msg
);
386 MessageBox(0, msg
, "Message", MB_OK
);
391 int start
= ::SendMessage(hEditor
, SCI_GETTARGETSTART
, 0, 0);
392 int end
= ::SendMessage(hEditor
, SCI_GETTARGETEND
, 0, 0);
393 EnsureRangeVisible(hEditor
, start
, end
, true);
394 ::SendMessage(hEditor
, SCI_SETSEL
, start
, end
);
398 BOOL
CFindReplaceDlg::HandleReplaceCommand(int cmd
){
400 MsgBox
.DisplayWarning("Can't get editor handle");
404 if ((cmd
== IDOK
) || (cmd
== IDC_REPLACE
) || (cmd
== IDC_REPLACEALL
) || (cmd
== IDC_REPLACEINSEL
)) {
405 GetItemText(hFindWhat
, findWhat
, sizeof(findWhat
));
406 //props.Set("find.what", findWhat);
407 //memFinds.Insert(findWhat);
409 bWholeWord
= BST_CHECKED
==
410 ::SendMessage(hWholeWord
, BM_GETCHECK
, 0, 0);
411 bMatchCase
= BST_CHECKED
==
412 ::SendMessage(hMatchCase
, BM_GETCHECK
, 0, 0);
413 bRegExp
= BST_CHECKED
==
414 ::SendMessage(hRegExp
, BM_GETCHECK
, 0, 0);
415 bWrapFind
= BST_CHECKED
==
416 ::SendMessage(hWrap
, BM_GETCHECK
, 0, 0);
417 bUnSlash
= BST_CHECKED
==
418 ::SendMessage(hUnSlash
, BM_GETCHECK
, 0, 0);
420 if ((cmd
== IDC_REPLACE
) || (cmd
== IDC_REPLACEALL
) || (cmd
== IDC_REPLACEINSEL
)) {
421 GetItemText(hReplaceWith
, replaceWhat
, sizeof(replaceWhat
));
422 //memReplaces.Insert(replaceWhat);
426 FindNext(bReverseFind
, true); // Find next
427 } else if (cmd
== IDC_REPLACE
) {
431 CharacterRange crange
= GetSelection(hEditor
);
432 ::SendMessage(hEditor
, SCI_SETSEL
, crange
.cpMin
, crange
.cpMin
);
433 FindNext(bReverseFind
, true);
438 } else if ((cmd
== IDC_REPLACEALL
) || (cmd
== IDC_REPLACEINSEL
)){
439 ReplaceAll(cmd
== IDC_REPLACEINSEL
);
444 void CFindReplaceDlg::ReplaceOnce(void){
446 char replaceTarget
[FR_MAX_LEN
+ 1];
447 strcpy(replaceTarget
, replaceWhat
);
448 // for C conversions -> int replaceLen = UnSlashAsNeeded(replaceTarget, unSlash, regExp);
449 int replaceLen
= strlen(replaceTarget
); // normal return of UnSlashAsNeeded
451 CharacterRange cr
= GetSelection(hEditor
);
452 ::SendMessage(hEditor
, SCI_SETTARGETSTART
, cr
.cpMin
, 0);
453 ::SendMessage(hEditor
, SCI_SETTARGETEND
, cr
.cpMax
, 0);
454 int lenReplaced
= replaceLen
;
456 lenReplaced
= ::SendMessage(hEditor
, SCI_REPLACETARGETRE
, replaceLen
, (LPARAM
) replaceTarget
);
457 else // Allow \0 in replacement
458 ::SendMessage(hEditor
, SCI_REPLACETARGET
, replaceLen
, (LPARAM
) replaceTarget
);
459 ::SendMessage(hEditor
, SCI_SETSEL
, cr
.cpMin
+ lenReplaced
, cr
.cpMin
);
462 FindNext(bReverseFind
, true);
465 void CFindReplaceDlg::ReplaceAll(bool inSelection
){
466 char findTarget
[FR_MAX_LEN
+ 1];
467 strcpy(findTarget
, findWhat
);
469 // for C conversions -> int findLen = UnSlashAsNeeded(findTarget, unSlash, regExp);
470 int findLen
= strlen(findTarget
); // normal return of UnSlashAsNeeded
473 MessageBox(_hWnd
, "Find string for \"Replace All\" must not be empty.", "Message", MB_OK
| MB_ICONWARNING
);
477 CharacterRange cr
= GetSelection(hEditor
);
478 int startPosition
= cr
.cpMin
;
479 int endPosition
= cr
.cpMax
;
481 if (startPosition
== endPosition
) {
482 MessageBox(_hWnd
, "Selection for \"Replace in Selection\" must not be empty.", "Message", MB_OK
| MB_ICONWARNING
);
486 endPosition
= LengthDocument(hEditor
);
491 // If not wrapFind, replace all only from caret to end of document
494 char replaceTarget
[FR_MAX_LEN
+ 1];
495 strcpy(replaceTarget
, replaceWhat
);
497 // for C conversions -> int replaceLen = UnSlashAsNeeded(replaceTarget, unSlash, regExp);
498 int replaceLen
= strlen(replaceTarget
); // normal return of UnSlashAsNeeded
500 int flags
= (bWholeWord
? SCFIND_WHOLEWORD
: 0) |
501 (bMatchCase
? SCFIND_MATCHCASE
: 0) |
502 (bRegExp
? SCFIND_REGEXP
: 0);
503 ::SendMessage(hEditor
, SCI_SETTARGETSTART
, startPosition
, 0);
504 ::SendMessage(hEditor
, SCI_SETTARGETEND
, endPosition
, 0);
505 ::SendMessage(hEditor
, SCI_SETSEARCHFLAGS
, flags
, 0);
506 int posFind
= ::SendMessage(hEditor
, SCI_SEARCHINTARGET
, findLen
, (LPARAM
) findTarget
);
507 if ((findLen
== 1) && bRegExp
&& (findTarget
[0] == '^')) {
508 // Special case for replace all start of line so it hits the first line
509 posFind
= startPosition
;
510 ::SendMessage(hEditor
, SCI_SETTARGETSTART
, startPosition
, 0);
511 ::SendMessage(hEditor
, SCI_SETTARGETEND
, startPosition
, 0);
513 if ((posFind
!= -1) && (posFind
<= endPosition
)) {
514 int lastMatch
= posFind
;
515 ::SendMessage(hEditor
, SCI_BEGINUNDOACTION
, 0, 0);
516 while (posFind
!= -1) {
517 int lenTarget
= ::SendMessage(hEditor
, SCI_GETTARGETEND
, 0, 0) - ::SendMessage(hEditor
, SCI_GETTARGETSTART
, 0, 0);
518 int lenReplaced
= replaceLen
;
520 lenReplaced
= ::SendMessage(hEditor
, SCI_REPLACETARGETRE
, replaceLen
, (LPARAM
) replaceTarget
);
522 ::SendMessage(hEditor
, SCI_REPLACETARGET
, replaceLen
, (LPARAM
) replaceTarget
);
523 // Modify for change caused by replacement
524 endPosition
+= lenReplaced
- lenTarget
;
525 lastMatch
= posFind
+ lenReplaced
;
526 // For the special cases of start of line and end of line
527 // Something better could be done but there are too many special cases
530 ::SendMessage(hEditor
, SCI_SETTARGETSTART
, lastMatch
, 0);
531 ::SendMessage(hEditor
, SCI_SETTARGETEND
, endPosition
, 0);
532 posFind
= ::SendMessage(hEditor
, SCI_SEARCHINTARGET
, findLen
, (LPARAM
) findTarget
);
535 ::SendMessage(hEditor
, SCI_SETSEL
, startPosition
, endPosition
);
537 ::SendMessage(hEditor
, SCI_SETSEL
, lastMatch
, lastMatch
);
538 ::SendMessage(hEditor
, SCI_ENDUNDOACTION
, 0, 0);
540 if (strlen(findWhat
) > FR_MAX_LEN
)
541 findWhat
[FR_MAX_LEN
] = '\0';
542 char msg
[FR_MAX_LEN
+ 50];
543 strcpy(msg
, "No replacements because string \"");
544 strcat(msg
, findWhat
);
545 strcat(msg
, "\" was not present.");
546 MessageBox(_hWnd
, msg
, "Message", MB_OK
| MB_ICONWARNING
);
551 /********************************************************************
558 ********************************************************************/
566 void CEditor::LoadFile(CFileItem
* file
){
570 if (file
->nFileOffset
== 0)
571 return; // Untitled file.
573 SetLexer(file
->type
);
574 ::SendMessage(_hWnd
, SCI_CANCEL
, 0, 0);
575 ::SendMessage(_hWnd
, SCI_SETUNDOCOLLECTION
, 0, 0);
577 FILE *fp
= fopen(file
->szFileName
, "rb");
579 char data
[blockSize
];
580 int lenFile
= fread(data
, 1, sizeof(data
), fp
);
583 ::SendMessage(_hWnd
, SCI_ADDTEXT
, lenFile
, (LPARAM
) data
);
584 lenFile
= fread(data
, 1, sizeof(data
), fp
);
590 MsgBox
.DisplayWarning("Can't load file %s", file
->szFileName
);
593 ::SendMessage(_hWnd
, SCI_SETUNDOCOLLECTION
, 1, 0);
594 ::SendMessage(_hWnd
, EM_EMPTYUNDOBUFFER
, 0, 0);
595 ::SendMessage(_hWnd
, SCI_SETSAVEPOINT
, 0 , 0);
596 ::SendMessage(_hWnd
, SCI_GOTOPOS
, 0, 0);
599 void GetFileType(CFileItem
* file
){
603 if (file
->nFileExtension
){
604 char * ext
= file
->szFileName
+ file
->nFileExtension
;
606 if (!stricmp(ext
, "h")){
609 }else if (!stricmp(ext
, "hpp")){
612 }else if (!stricmp(ext
, "hxx")){
616 }else if (!stricmp(ext
, "c")){
619 }else if (!stricmp(ext
, "cpp")){
622 }else if (!stricmp(ext
, "cxx")){
626 }else if (!stricmp(ext
, "rc")){
627 file
->type
= RC_FILE
;
635 void CEditor::SaveFile(char * fullPath
){
639 FILE *fp
= fopen(fullPath
, "wb");
641 char data
[blockSize
+ 1];
642 int lengthDoc
= ::SendMessage(_hWnd
, SCI_GETLENGTH
, 0, 0);
643 for (int i
= 0; i
< lengthDoc
; i
+= blockSize
) {
644 int grabSize
= lengthDoc
- i
;
645 if (grabSize
> blockSize
)
646 grabSize
= blockSize
;
647 GetRange(i
, i
+ grabSize
, data
);
648 fwrite(data
, grabSize
, 1, fp
);
651 ::SendMessage(_hWnd
, SCI_SETSAVEPOINT
, 0, 0);
654 MsgBox
.DisplayWarning("Can't save file %s", fullPath
);
658 int CEditor::GetCurrentPos(void){
659 int currentPos
= ::SendMessage(_hWnd
, SCI_GETCURRENTPOS
, 0,0);
660 caretPos
= ::SendMessage(_hWnd
, SCI_LINEFROMPOSITION
, currentPos
, 0) + 1;
664 void CEditor::GetRange(int start
, int end
, char *text
){
666 tr
.chrg
.cpMin
= start
;
669 ::SendMessage(_hWnd
, SCI_GETTEXTRANGE
, 0, (LPARAM
) &tr
);
672 void CEditor::SetAStyle(int style
, COLORREF fore
, COLORREF back
, int size
, const char *face
){
673 ::SendMessage(_hWnd
, SCI_STYLESETFORE
, style
, fore
);
674 ::SendMessage(_hWnd
, SCI_STYLESETBACK
, style
, back
);
676 ::SendMessage(_hWnd
, SCI_STYLESETSIZE
, style
, size
);
678 ::SendMessage(_hWnd
, SCI_STYLESETFONT
, style
, (LPARAM
) face
);
681 void CEditor::DefineMarker(int marker
, int markerType
, COLORREF fore
, COLORREF back
) {
682 ::SendMessage(_hWnd
, SCI_MARKERDEFINE
, marker
, markerType
);
683 ::SendMessage(_hWnd
, SCI_MARKERSETFORE
, marker
, fore
);
684 ::SendMessage(_hWnd
, SCI_MARKERSETBACK
, marker
, back
);
687 void CEditor::SetLexer(int fileType
){
697 // Global default style.
698 SetAStyle(STYLE_DEFAULT
, black
, white
, 10, "Verdana");
699 ::SendMessage(_hWnd
, SCI_STYLECLEARALL
, 0, 0); // Copies to all other styles.
704 void CEditor::SetCppLexer(void){
705 ::SendMessage(_hWnd
, SCI_SETLEXER
, SCLEX_CPP
, 0);
706 ::SendMessage(_hWnd
, SCI_SETSTYLEBITS
, 5, 0);
708 ::SendMessage(_hWnd
, SCI_SETKEYWORDS
, 0, (LPARAM
) cppKeyWords
);
710 // Global default style.
711 SetAStyle(STYLE_DEFAULT
, black
, white
, 10, "Verdana");
712 ::SendMessage(_hWnd
, SCI_STYLECLEARALL
, 0, 0); // Copies to all other styles.
715 SetAStyle(SCE_C_DEFAULT
, black
, white
, 10, "Verdana"); //0
716 SetAStyle(SCE_C_COMMENT
, Green
, white
, 0, 0); //1
717 SetAStyle(SCE_C_COMMENTLINE
, Green
, white
, 0, 0); //2
718 SetAStyle(SCE_C_COMMENTDOC
, darkGreen
, white
, 0, 0); //3
719 SetAStyle(SCE_C_NUMBER
, Ice
, white
, 0, 0); //4
720 SetAStyle(SCE_C_WORD
, darkBlue
, white
, 0, 0); //5
721 ::SendMessage(_hWnd
, SCI_STYLESETBOLD
, SCE_C_WORD
, 1);
722 SetAStyle(SCE_C_STRING
, Purple
, white
, 0, 0); //6
723 SetAStyle(SCE_C_CHARACTER
, Purple
, white
, 0, 0); //7
724 SetAStyle(SCE_C_PREPROCESSOR
, Olive
, white
, 0, 0); //9
725 SetAStyle(SCE_C_OPERATOR
, black
, white
, 0, 0); //10
726 ::SendMessage(_hWnd
, SCI_STYLESETBOLD
, SCE_C_OPERATOR
, 1);
727 // SetAStyle(SCE_C_STRINGEOL, darkBlue, white, 0, 0); //12
728 // SetAStyle(SCE_C_COMMENTLINEDOC, darkBlue, white, 0, 0); //15
729 // SetAStyle(SCE_C_WORD2, darkBlue, white, 0, 0); //16
730 ::SendMessage(_hWnd
, SCI_SETPROPERTY
, (long)"fold", (long)"1");
731 ::SendMessage(_hWnd
, SCI_SETPROPERTY
, (long)"fold.compact", (long)"1");
732 ::SendMessage(_hWnd
, SCI_SETPROPERTY
, (long)"fold.symbols", (long)"1");
734 ::SendMessage(_hWnd
, SCI_SETFOLDFLAGS
, 16, 0);
736 // To put the folder markers in the line number region
737 //SendEditor(SCI_SETMARGINMASKN, 0, SC_MASK_FOLDERS);
739 ::SendMessage(_hWnd
, SCI_SETMODEVENTMASK
, SC_MOD_CHANGEFOLD
, 0);
741 // Create a margin column for the folding symbols
742 ::SendMessage(_hWnd
, SCI_SETMARGINTYPEN
, 2, SC_MARGIN_SYMBOL
);
744 ::SendMessage(_hWnd
, SCI_SETMARGINWIDTHN
, 2, /*foldMargin ? foldMarginWidth :*/ 16);
746 ::SendMessage(_hWnd
, SCI_SETMARGINMASKN
, 2, SC_MASK_FOLDERS
);
747 ::SendMessage(_hWnd
, SCI_SETMARGINSENSITIVEN
, 2, 1);
749 DefineMarker(SC_MARKNUM_FOLDEROPEN
, SC_MARK_MINUS
, white
, black
);
750 DefineMarker(SC_MARKNUM_FOLDER
, SC_MARK_PLUS
, white
, black
);
751 DefineMarker(SC_MARKNUM_FOLDERSUB
, SC_MARK_EMPTY
, white
, black
);
752 DefineMarker(SC_MARKNUM_FOLDERTAIL
, SC_MARK_EMPTY
, white
, black
);
753 DefineMarker(SC_MARKNUM_FOLDEREND
, SC_MARK_EMPTY
, white
, black
);
754 DefineMarker(SC_MARKNUM_FOLDEROPENMID
, SC_MARK_EMPTY
, white
, black
);
755 DefineMarker(SC_MARKNUM_FOLDERMIDTAIL
, SC_MARK_EMPTY
, white
, black
);
760 void CEditor::GotoLine(int line
, char * /*fileName*/){
761 ::SendMessage(_hWnd
, SCI_ENSUREVISIBLEENFORCEPOLICY
, line
, 0);
762 ::SendMessage(_hWnd
, SCI_GOTOLINE
, line
, 0);
765 bool CEditor::MarginClick(int position
, int modifiers
){
766 int lineClick
= ::SendMessage(_hWnd
, SCI_LINEFROMPOSITION
, position
, 0);
767 //Platform::DebugPrintf("Margin click %d %d %x\n", position, lineClick,
768 // ::SendMessage(_hWnd, SCI_GETFOLDLEVEL, lineClick) & SC_FOLDLEVELHEADERFLAG);
769 /* if ((modifiers & SCMOD_SHIFT) && (modifiers & SCMOD_CTRL)) {
772 int levelClick
= ::SendMessage(_hWnd
, SCI_GETFOLDLEVEL
, lineClick
, 0);
773 if (levelClick
& SC_FOLDLEVELHEADERFLAG
) {
774 if (modifiers
& SCMOD_SHIFT
) {
775 // Ensure all children visible
776 ::SendMessage(_hWnd
, SCI_SETFOLDEXPANDED
, lineClick
, 1);
777 Expand(lineClick
, true, true, 100, levelClick
);
778 } else if (modifiers
& SCMOD_CTRL
) {
779 if (::SendMessage(_hWnd
, SCI_GETFOLDEXPANDED
, lineClick
, 0)) {
780 // Contract this line and all children
781 ::SendMessage(_hWnd
, SCI_SETFOLDEXPANDED
, lineClick
, 0);
782 Expand(lineClick
, false, true, 0, levelClick
);
784 // Expand this line and all children
785 ::SendMessage(_hWnd
, SCI_SETFOLDEXPANDED
, lineClick
, 1);
786 Expand(lineClick
, true, true, 100, levelClick
);
790 ::SendMessage(_hWnd
, SCI_TOGGLEFOLD
, lineClick
, 0);
797 void CEditor::Expand(int &line
, bool doExpand
, bool force
, int visLevels
, int level
){
798 int lineMaxSubord
= ::SendMessage(_hWnd
, SCI_GETLASTCHILD
, line
, level
& SC_FOLDLEVELNUMBERMASK
);
800 while (line
<= lineMaxSubord
) {
803 ::SendMessage(_hWnd
, SCI_SHOWLINES
, line
, line
);
805 ::SendMessage(_hWnd
, SCI_HIDELINES
, line
, line
);
808 ::SendMessage(_hWnd
, SCI_SHOWLINES
, line
, line
);
810 int levelLine
= level
;
812 levelLine
= ::SendMessage(_hWnd
, SCI_GETFOLDLEVEL
, line
, 0);
813 if (levelLine
& SC_FOLDLEVELHEADERFLAG
) {
816 ::SendMessage(_hWnd
, SCI_SETFOLDEXPANDED
, line
, 1);
818 ::SendMessage(_hWnd
, SCI_SETFOLDEXPANDED
, line
, 0);
819 Expand(line
, doExpand
, force
, visLevels
- 1);
822 if (!::SendMessage(_hWnd
, SCI_GETFOLDEXPANDED
, line
, 0))
823 ::SendMessage(_hWnd
, SCI_SETFOLDEXPANDED
, line
, 1);
824 Expand(line
, true, force
, visLevels
- 1);
826 Expand(line
, false, force
, visLevels
- 1);