OSDN Git Service

fcfc14ad754579bd9e474f2993aa1a4352c6f296
[tortoisegit/TortoiseGitJp.git] / src / TortoiseGitBlame / TortoiseGitBlameView.cpp
1 // TortoiseGitBlame - a Viewer for Git Blames\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 \r
19 // CTortoiseGitBlameView.cpp : implementation of the CTortoiseGitBlameView class\r
20 //\r
21 \r
22 #include "stdafx.h"\r
23 #include "TortoiseGitBlame.h"\r
24 \r
25 #include "TortoiseGitBlameDoc.h"\r
26 #include "TortoiseGitBlameView.h"\r
27 \r
28 #ifdef _DEBUG\r
29 #define new DEBUG_NEW\r
30 #endif\r
31 \r
32 \r
33 // CTortoiseGitBlameView\r
34 \r
35 IMPLEMENT_DYNCREATE(CTortoiseGitBlameView, CView)\r
36 \r
37 BEGIN_MESSAGE_MAP(CTortoiseGitBlameView, CView)\r
38         // Standard printing commands\r
39         ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)\r
40         ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)\r
41         ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CTortoiseGitBlameView::OnFilePrintPreview)\r
42 END_MESSAGE_MAP()\r
43 \r
44 // CTortoiseGitBlameView construction/destruction\r
45 \r
46 CTortoiseGitBlameView::CTortoiseGitBlameView()\r
47 {\r
48         // TODO: add construction code here\r
49         hInstance = 0;\r
50         hResource = 0;\r
51         currentDialog = 0;\r
52         wMain = 0;\r
53         wEditor = 0;\r
54         wLocator = 0;\r
55 \r
56         m_font = 0;\r
57         m_italicfont = 0;\r
58         m_blamewidth = 0;\r
59         m_revwidth = 0;\r
60         m_datewidth = 0;\r
61         m_authorwidth = 0;\r
62         m_pathwidth = 0;\r
63         m_linewidth = 0;\r
64 \r
65         m_windowcolor = ::GetSysColor(COLOR_WINDOW);\r
66         m_textcolor = ::GetSysColor(COLOR_WINDOWTEXT);\r
67         m_texthighlightcolor = ::GetSysColor(COLOR_HIGHLIGHTTEXT);\r
68         m_mouserevcolor = InterColor(m_windowcolor, m_textcolor, 20);\r
69         m_mouseauthorcolor = InterColor(m_windowcolor, m_textcolor, 10);\r
70         m_selectedrevcolor = ::GetSysColor(COLOR_HIGHLIGHT);\r
71         m_selectedauthorcolor = InterColor(m_selectedrevcolor, m_texthighlightcolor, 35);\r
72         m_mouserev = -2;\r
73 \r
74         m_selectedrev = -1;\r
75         m_selectedorigrev = -1;\r
76         m_SelectedLine = -1;\r
77         m_directPointer = 0;\r
78         m_directFunction = 0;\r
79 \r
80         m_lowestrev = LONG_MAX;\r
81         m_highestrev = 0;\r
82         m_colorage = true;\r
83 }\r
84 \r
85 CTortoiseGitBlameView::~CTortoiseGitBlameView()\r
86 {\r
87         if (m_font)\r
88                 DeleteObject(m_font);\r
89         if (m_italicfont)\r
90                 DeleteObject(m_italicfont);\r
91 }\r
92 \r
93 \r
94 \r
95 BOOL CTortoiseGitBlameView::PreCreateWindow(CREATESTRUCT& cs)\r
96 {\r
97         // TODO: Modify the Window class or styles here by modifying\r
98         //  the CREATESTRUCT cs\r
99 \r
100         return CView::PreCreateWindow(cs);\r
101 }\r
102 \r
103 // CTortoiseGitBlameView drawing\r
104 \r
105 void CTortoiseGitBlameView::OnDraw(CDC* /*pDC*/)\r
106 {\r
107         CTortoiseGitBlameDoc* pDoc = GetDocument();\r
108         ASSERT_VALID(pDoc);\r
109         if (!pDoc)\r
110                 return;\r
111 \r
112         // TODO: add draw code for native data here\r
113 }\r
114 \r
115 \r
116 // CTortoiseGitBlameView printing\r
117 \r
118 \r
119 void CTortoiseGitBlameView::OnFilePrintPreview()\r
120 {\r
121         AFXPrintPreview(this);\r
122 }\r
123 \r
124 BOOL CTortoiseGitBlameView::OnPreparePrinting(CPrintInfo* pInfo)\r
125 {\r
126         // default preparation\r
127         return DoPreparePrinting(pInfo);\r
128 }\r
129 \r
130 void CTortoiseGitBlameView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)\r
131 {\r
132         // TODO: add extra initialization before printing\r
133 }\r
134 \r
135 void CTortoiseGitBlameView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)\r
136 {\r
137         // TODO: add cleanup after printing\r
138 }\r
139 \r
140 void CTortoiseGitBlameView::OnRButtonUp(UINT nFlags, CPoint point)\r
141 {\r
142         ClientToScreen(&point);\r
143         OnContextMenu(this, point);\r
144 }\r
145 \r
146 void CTortoiseGitBlameView::OnContextMenu(CWnd* pWnd, CPoint point)\r
147 {\r
148         theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);\r
149 }\r
150 \r
151 \r
152 // CTortoiseGitBlameView diagnostics\r
153 \r
154 #ifdef _DEBUG\r
155 void CTortoiseGitBlameView::AssertValid() const\r
156 {\r
157         CView::AssertValid();\r
158 }\r
159 \r
160 void CTortoiseGitBlameView::Dump(CDumpContext& dc) const\r
161 {\r
162         CView::Dump(dc);\r
163 }\r
164 \r
165 CTortoiseGitBlameDoc* CTortoiseGitBlameView::GetDocument() const // non-debug version is inline\r
166 {\r
167         ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTortoiseGitBlameDoc)));\r
168         return (CTortoiseGitBlameDoc*)m_pDocument;\r
169 }\r
170 #endif //_DEBUG\r
171 \r
172 \r
173 // CTortoiseGitBlameView message handlers\r
174 CString CTortoiseGitBlameView::GetAppDirectory()\r
175 {\r
176         CString path;\r
177         DWORD len = 0;\r
178         DWORD bufferlen = MAX_PATH;             // MAX_PATH is not the limit here!\r
179         do \r
180         {\r
181                 bufferlen += MAX_PATH;          // MAX_PATH is not the limit here!\r
182                 TCHAR * pBuf = new TCHAR[bufferlen];\r
183                 len = GetModuleFileName(NULL, pBuf, bufferlen); \r
184                 path = CString(pBuf, len);\r
185                 delete [] pBuf;\r
186         } while(len == bufferlen);\r
187 \r
188         path = path.Left(path.ReverseFind(_T('\\')));\r
189         //path = path.substr(0, path.rfind('\\') + 1);\r
190 \r
191         return path;\r
192 }\r
193 \r
194 // Return a color which is interpolated between c1 and c2.\r
195 // Slider controls the relative proportions as a percentage:\r
196 // Slider = 0   represents pure c1\r
197 // Slider = 50  represents equal mixture\r
198 // Slider = 100 represents pure c2\r
199 COLORREF CTortoiseGitBlameView::InterColor(COLORREF c1, COLORREF c2, int Slider)\r
200 {\r
201         int r, g, b;\r
202         \r
203         // Limit Slider to 0..100% range\r
204         if (Slider < 0)\r
205                 Slider = 0;\r
206         if (Slider > 100)\r
207                 Slider = 100;\r
208         \r
209         // The color components have to be treated individually.\r
210         r = (GetRValue(c2) * Slider + GetRValue(c1) * (100 - Slider)) / 100;\r
211         g = (GetGValue(c2) * Slider + GetGValue(c1) * (100 - Slider)) / 100;\r
212         b = (GetBValue(c2) * Slider + GetBValue(c1) * (100 - Slider)) / 100;\r
213         \r
214         return RGB(r, g, b);\r
215 }\r
216 \r
217 LRESULT CTortoiseGitBlameView::SendEditor(UINT Msg, WPARAM wParam, LPARAM lParam)\r
218 {\r
219         if (m_directFunction)\r
220         {\r
221                 return ((SciFnDirect) m_directFunction)(m_directPointer, Msg, wParam, lParam);\r
222         }\r
223         return ::SendMessage(wEditor, Msg, wParam, lParam);     \r
224 }\r
225 \r
226 void CTortoiseGitBlameView::GetRange(int start, int end, char *text) \r
227 {\r
228 #if 0\r
229         TEXTRANGE tr;\r
230         tr.chrg.cpMin = start;\r
231         tr.chrg.cpMax = end;\r
232         tr.lpstrText = text;\r
233         SendMessage(wEditor, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr));\r
234 #endif\r
235 }\r
236 \r
237 void CTortoiseGitBlameView::SetTitle() \r
238 {\r
239 #if 0\r
240         char title[MAX_PATH + 100];\r
241         strcpy_s(title, MAX_PATH + 100, szTitle);\r
242         strcat_s(title, MAX_PATH + 100, " - ");\r
243         strcat_s(title, MAX_PATH + 100, szViewtitle);\r
244         ::SetWindowText(wMain, title);\r
245 #endif\r
246 }\r
247 \r
248 BOOL CTortoiseGitBlameView::OpenLogFile(const char *fileName)\r
249 {\r
250 #if 0\r
251         char logmsgbuf[10000+1];\r
252         FILE * File;\r
253         fopen_s(&File, fileName, "rb");\r
254         if (File == 0)\r
255         {\r
256                 return FALSE;\r
257         }\r
258         LONG rev = 0;\r
259         CString msg;\r
260         int slength = 0;\r
261         int reallength = 0;\r
262         size_t len = 0;\r
263         wchar_t wbuf[MAX_LOG_LENGTH+6];\r
264         for (;;)\r
265         {\r
266                 len = fread(&rev, sizeof(LONG), 1, File);\r
267                 if (len == 0)\r
268                 {\r
269                         fclose(File);\r
270             InitSize();\r
271                         return TRUE;\r
272                 }\r
273                 len = fread(&slength, sizeof(int), 1, File);\r
274                 if (len == 0)\r
275                 {\r
276                         fclose(File);\r
277             InitSize();\r
278                         return FALSE;\r
279                 }\r
280                 if (slength > MAX_LOG_LENGTH)\r
281                 {\r
282                         reallength = slength;\r
283                         slength = MAX_LOG_LENGTH;\r
284                 }\r
285                 else\r
286                         reallength = 0;\r
287                 len = fread(logmsgbuf, sizeof(char), slength, File);\r
288                 if (len < (size_t)slength)\r
289                 {\r
290                         fclose(File);\r
291             InitSize();\r
292                         return FALSE;\r
293                 }\r
294                 msg = CString(logmsgbuf, slength);\r
295                 if (reallength)\r
296                 {\r
297                         fseek(File, reallength-MAX_LOG_LENGTH, SEEK_CUR);\r
298                         msg = msg + _T("\n...");\r
299                 }\r
300                 int len2 = ::MultiByteToWideChar(CP_UTF8, NULL, msg.c_str(), min(msg.size(), MAX_LOG_LENGTH+5), wbuf, MAX_LOG_LENGTH+5);\r
301                 wbuf[len2] = 0;\r
302                 len2 = ::WideCharToMultiByte(CP_ACP, NULL, wbuf, len2, logmsgbuf, MAX_LOG_LENGTH+5, NULL, NULL);\r
303                 logmsgbuf[len2] = 0;\r
304                 msg = CString(logmsgbuf);\r
305                 logmessages[rev] = msg;\r
306         }\r
307 #endif\r
308         return TRUE;\r
309 }\r
310 \r
311 BOOL CTortoiseGitBlameView::OpenFile(const char *fileName) \r
312 {\r
313 #if 0\r
314         SendEditor(SCI_SETREADONLY, FALSE);\r
315         SendEditor(SCI_CLEARALL);\r
316         SendEditor(EM_EMPTYUNDOBUFFER);\r
317         SetTitle();\r
318         SendEditor(SCI_SETSAVEPOINT);\r
319         SendEditor(SCI_CANCEL);\r
320         SendEditor(SCI_SETUNDOCOLLECTION, 0);\r
321         ::ShowWindow(wEditor, SW_HIDE);\r
322         std::ifstream File;\r
323         File.open(fileName);\r
324         if (!File.good())\r
325         {\r
326                 return FALSE;\r
327         }\r
328         char line[100*1024];\r
329         char * lineptr = NULL;\r
330         char * trimptr = NULL;\r
331         //ignore the first two lines, they're of no interest to us\r
332         File.getline(line, sizeof(line)/sizeof(char));\r
333         File.getline(line, sizeof(line)/sizeof(char));\r
334         m_lowestrev = LONG_MAX;\r
335         m_highestrev = 0;\r
336         bool bUTF8 = true;\r
337         do\r
338         {\r
339                 File.getline(line, sizeof(line)/sizeof(TCHAR));\r
340                 if (File.gcount()>139)\r
341                 {\r
342                         mergelines.push_back((line[0] != ' '));\r
343                         lineptr = &line[9];\r
344                         long rev = _ttol(lineptr);\r
345                         revs.push_back(rev);\r
346                         m_lowestrev = min(m_lowestrev, rev);\r
347                         m_highestrev = max(m_highestrev, rev);\r
348                         lineptr += 7;\r
349                         rev = _ttol(lineptr);\r
350                         origrevs.push_back(rev);\r
351                         lineptr += 7;\r
352                         dates.push_back(CString(lineptr, 30));\r
353                         lineptr += 31;\r
354                         // unfortunately, the 'path' entry can be longer than the 60 chars\r
355                         // we made the column. We therefore have to step through the path\r
356                         // string until we find a space\r
357                         trimptr = lineptr;\r
358                         do \r
359                         {\r
360                                 // TODO: how can we deal with the situation where the path has\r
361                                 // a space in it, but the space is after the 60 chars reserved\r
362                                 // for it?\r
363                                 // The only way to deal with that would be to use a custom\r
364                                 // binary format for the blame file.\r
365                                 trimptr++;\r
366                                 trimptr = _tcschr(trimptr, ' ');\r
367                         } while ((trimptr)&&(trimptr+1 < lineptr+61));\r
368                         if (trimptr)\r
369                                 *trimptr = 0;\r
370                         else\r
371                                 trimptr = lineptr;\r
372                         paths.push_back(CString(lineptr));\r
373                         if (trimptr+1 < lineptr+61)\r
374                                 lineptr +=61;\r
375                         else\r
376                                 lineptr = (trimptr+1);\r
377                         trimptr = lineptr+30;\r
378                         while ((*trimptr == ' ')&&(trimptr > lineptr))\r
379                                 trimptr--;\r
380                         *(trimptr+1) = 0;\r
381                         authors.push_back(CString(lineptr));\r
382                         lineptr += 31;\r
383                         // in case we find an UTF8 BOM at the beginning of the line, we remove it\r
384                         if (((unsigned char)lineptr[0] == 0xEF)&&((unsigned char)lineptr[1] == 0xBB)&&((unsigned char)lineptr[2] == 0xBF))\r
385                         {\r
386                                 lineptr += 3;\r
387                         }\r
388                         if (((unsigned char)lineptr[0] == 0xBB)&&((unsigned char)lineptr[1] == 0xEF)&&((unsigned char)lineptr[2] == 0xBF))\r
389                         {\r
390                                 lineptr += 3;\r
391                         }\r
392                         // check each line for illegal utf8 sequences. If one is found, we treat\r
393                         // the file as ASCII, otherwise we assume an UTF8 file.\r
394                         char * utf8CheckBuf = lineptr;\r
395                         while ((bUTF8)&&(*utf8CheckBuf))\r
396                         {\r
397                                 if ((*utf8CheckBuf == 0xC0)||(*utf8CheckBuf == 0xC1)||(*utf8CheckBuf >= 0xF5))\r
398                                 {\r
399                                         bUTF8 = false;\r
400                                         break;\r
401                                 }\r
402                                 if ((*utf8CheckBuf & 0xE0)==0xC0)\r
403                                 {\r
404                                         utf8CheckBuf++;\r
405                                         if (*utf8CheckBuf == 0)\r
406                                                 break;\r
407                                         if ((*utf8CheckBuf & 0xC0)!=0x80)\r
408                                         {\r
409                                                 bUTF8 = false;\r
410                                                 break;\r
411                                         }\r
412                                 }\r
413                                 if ((*utf8CheckBuf & 0xF0)==0xE0)\r
414                                 {\r
415                                         utf8CheckBuf++;\r
416                                         if (*utf8CheckBuf == 0)\r
417                                                 break;\r
418                                         if ((*utf8CheckBuf & 0xC0)!=0x80)\r
419                                         {\r
420                                                 bUTF8 = false;\r
421                                                 break;\r
422                                         }\r
423                                         utf8CheckBuf++;\r
424                                         if (*utf8CheckBuf == 0)\r
425                                                 break;\r
426                                         if ((*utf8CheckBuf & 0xC0)!=0x80)\r
427                                         {\r
428                                                 bUTF8 = false;\r
429                                                 break;\r
430                                         }\r
431                                 }\r
432                                 if ((*utf8CheckBuf & 0xF8)==0xF0)\r
433                                 {\r
434                                         utf8CheckBuf++;\r
435                                         if (*utf8CheckBuf == 0)\r
436                                                 break;\r
437                                         if ((*utf8CheckBuf & 0xC0)!=0x80)\r
438                                         {\r
439                                                 bUTF8 = false;\r
440                                                 break;\r
441                                         }\r
442                                         utf8CheckBuf++;\r
443                                         if (*utf8CheckBuf == 0)\r
444                                                 break;\r
445                                         if ((*utf8CheckBuf & 0xC0)!=0x80)\r
446                                         {\r
447                                                 bUTF8 = false;\r
448                                                 break;\r
449                                         }\r
450                                         utf8CheckBuf++;\r
451                                         if (*utf8CheckBuf == 0)\r
452                                                 break;\r
453                                         if ((*utf8CheckBuf & 0xC0)!=0x80)\r
454                                         {\r
455                                                 bUTF8 = false;\r
456                                                 break;\r
457                                         }\r
458                                 }\r
459 \r
460                                 utf8CheckBuf++;\r
461                         }\r
462                         SendEditor(SCI_ADDTEXT, _tcslen(lineptr), reinterpret_cast<LPARAM>(static_cast<char *>(lineptr)));\r
463                         SendEditor(SCI_ADDTEXT, 2, (LPARAM)_T("\r\n"));\r
464                 }\r
465         } while (File.gcount() > 0);\r
466 \r
467         if (bUTF8)\r
468                 SendEditor(SCI_SETCODEPAGE, SC_CP_UTF8);\r
469 \r
470         SendEditor(SCI_SETUNDOCOLLECTION, 1);\r
471         ::SetFocus(wEditor);\r
472         SendEditor(EM_EMPTYUNDOBUFFER);\r
473         SendEditor(SCI_SETSAVEPOINT);\r
474         SendEditor(SCI_GOTOPOS, 0);\r
475         SendEditor(SCI_SETSCROLLWIDTHTRACKING, TRUE);\r
476         SendEditor(SCI_SETREADONLY, TRUE);\r
477 \r
478         //check which lexer to use, depending on the filetype\r
479         SetupLexer(fileName);\r
480         ::ShowWindow(wEditor, SW_SHOW);\r
481         m_blamewidth = 0;\r
482         ::InvalidateRect(wMain, NULL, TRUE);\r
483         RECT rc;\r
484         GetWindowRect(wMain, &rc);\r
485         SetWindowPos(wMain, 0, rc.left, rc.top, rc.right-rc.left-1, rc.bottom - rc.top, 0);\r
486 #endif\r
487         return TRUE;\r
488 }\r
489 \r
490 void CTortoiseGitBlameView::SetAStyle(int style, COLORREF fore, COLORREF back, int size, const char *face) \r
491 {\r
492         SendEditor(SCI_STYLESETFORE, style, fore);\r
493         SendEditor(SCI_STYLESETBACK, style, back);\r
494         if (size >= 1)\r
495                 SendEditor(SCI_STYLESETSIZE, style, size);\r
496         if (face) \r
497                 SendEditor(SCI_STYLESETFONT, style, reinterpret_cast<LPARAM>(face));\r
498 }\r
499 \r
500 void CTortoiseGitBlameView::InitialiseEditor() \r
501 {\r
502 #if 0\r
503         m_directFunction = SendMessage(wEditor, SCI_GETDIRECTFUNCTION, 0, 0);\r
504         m_directPointer = SendMessage(wEditor, SCI_GETDIRECTPOINTER, 0, 0);\r
505         // Set up the global default style. These attributes are used wherever no explicit choices are made.\r
506         SetAStyle(STYLE_DEFAULT, black, white, (DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\BlameFontSize"), 10), \r
507                 ((stdstring)(CRegStdString(_T("Software\\TortoiseGit\\BlameFontName"), _T("Courier New")))).c_str());\r
508         SendEditor(SCI_SETTABWIDTH, (DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\BlameTabSize"), 4));\r
509         SendEditor(SCI_SETREADONLY, TRUE);\r
510         LRESULT pix = SendEditor(SCI_TEXTWIDTH, STYLE_LINENUMBER, (LPARAM)_T("_99999"));\r
511         if (ShowLine)\r
512                 SendEditor(SCI_SETMARGINWIDTHN, 0, pix);\r
513         else\r
514                 SendEditor(SCI_SETMARGINWIDTHN, 0);\r
515         SendEditor(SCI_SETMARGINWIDTHN, 1);\r
516         SendEditor(SCI_SETMARGINWIDTHN, 2);\r
517         //Set the default windows colors for edit controls\r
518         SendEditor(SCI_STYLESETFORE, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOWTEXT));\r
519         SendEditor(SCI_STYLESETBACK, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOW));\r
520         SendEditor(SCI_SETSELFORE, TRUE, ::GetSysColor(COLOR_HIGHLIGHTTEXT));\r
521         SendEditor(SCI_SETSELBACK, TRUE, ::GetSysColor(COLOR_HIGHLIGHT));\r
522         SendEditor(SCI_SETCARETFORE, ::GetSysColor(COLOR_WINDOWTEXT));\r
523         m_regOldLinesColor = CRegStdWORD(_T("Software\\TortoiseGit\\BlameOldColor"), RGB(230, 230, 255));\r
524         m_regNewLinesColor = CRegStdWORD(_T("Software\\TortoiseGit\\BlameNewColor"), RGB(255, 230, 230));\r
525 #endif\r
526 }\r
527 \r
528 void CTortoiseGitBlameView::StartSearch()\r
529 {\r
530         if (currentDialog)\r
531                 return;\r
532         bool bCase = false;\r
533         // Initialize FINDREPLACE\r
534         if (fr.Flags & FR_MATCHCASE)\r
535                 bCase = true;\r
536         SecureZeroMemory(&fr, sizeof(fr));\r
537         fr.lStructSize = sizeof(fr);\r
538         fr.hwndOwner = wMain;\r
539         fr.lpstrFindWhat = szFindWhat;\r
540         fr.wFindWhatLen = 80;\r
541         fr.Flags = FR_HIDEUPDOWN | FR_HIDEWHOLEWORD;\r
542         fr.Flags |= bCase ? FR_MATCHCASE : 0;\r
543 \r
544         currentDialog = FindText(&fr);\r
545 }\r
546 \r
547 bool CTortoiseGitBlameView::DoSearch(LPSTR what, DWORD flags)\r
548 {\r
549 #if 0\r
550         TCHAR szWhat[80];\r
551         int pos = SendEditor(SCI_GETCURRENTPOS);\r
552         int line = SendEditor(SCI_LINEFROMPOSITION, pos);\r
553         bool bFound = false;\r
554         bool bCaseSensitive = !!(flags & FR_MATCHCASE);\r
555 \r
556         strcpy_s(szWhat, sizeof(szWhat), what);\r
557 \r
558         if(!bCaseSensitive)\r
559         {\r
560                 char *p;\r
561                 size_t len = strlen(szWhat);\r
562                 for (p = szWhat; p < szWhat + len; p++)\r
563                 {\r
564                         if (isupper(*p)&&__isascii(*p))\r
565                                 *p = _tolower(*p);\r
566                 }\r
567         }\r
568 \r
569         CString sWhat = CString(szWhat);\r
570         \r
571         char buf[20];\r
572         int i=0;\r
573         for (i=line; (i<(int)authors.size())&&(!bFound); ++i)\r
574         {\r
575                 int bufsize = SendEditor(SCI_GETLINE, i);\r
576                 char * linebuf = new char[bufsize+1];\r
577                 SecureZeroMemory(linebuf, bufsize+1);\r
578                 SendEditor(SCI_GETLINE, i, (LPARAM)linebuf);\r
579                 if (!bCaseSensitive)\r
580                 {\r
581                         char *p;\r
582                         for (p = linebuf; p < linebuf + bufsize; p++)\r
583                         {\r
584                                 if (isupper(*p)&&__isascii(*p))\r
585                                         *p = _tolower(*p);\r
586                         }\r
587                 }\r
588                 _stprintf_s(buf, 20, _T("%ld"), revs[i]);\r
589                 if (authors[i].compare(sWhat)==0)\r
590                         bFound = true;\r
591                 else if ((!bCaseSensitive)&&(_stricmp(authors[i].c_str(), szWhat)==0))\r
592                         bFound = true;\r
593                 else if (strcmp(buf, szWhat) == 0)\r
594                         bFound = true;\r
595                 else if (strstr(linebuf, szWhat))\r
596                         bFound = true;\r
597                 delete [] linebuf;\r
598         }\r
599         if (!bFound)\r
600         {\r
601                 for (i=0; (i<line)&&(!bFound); ++i)\r
602                 {\r
603                         int bufsize = SendEditor(SCI_GETLINE, i);\r
604                         char * linebuf = new char[bufsize+1];\r
605                         SecureZeroMemory(linebuf, bufsize+1);\r
606                         SendEditor(SCI_GETLINE, i, (LPARAM)linebuf);\r
607                         if (!bCaseSensitive)\r
608                         {\r
609                                 char *p;\r
610                                 for (p = linebuf; p < linebuf + bufsize; p++)\r
611                                 {\r
612                                         if (isupper(*p)&&__isascii(*p))\r
613                                                 *p = _tolower(*p);\r
614                                 }\r
615                         }\r
616                         _stprintf_s(buf, 20, _T("%ld"), revs[i]);\r
617                         if (authors[i].compare(sWhat)==0)\r
618                                 bFound = true;\r
619                         else if ((!bCaseSensitive)&&(_stricmp(authors[i].c_str(), szWhat)==0))\r
620                                 bFound = true;\r
621                         else if (strcmp(buf, szWhat) == 0)\r
622                                 bFound = true;\r
623                         else if (strstr(linebuf, szWhat))\r
624                                 bFound = true;\r
625                         delete [] linebuf;\r
626                 }\r
627         }\r
628         if (bFound)\r
629         {\r
630                 GotoLine(i);\r
631                 int selstart = SendEditor(SCI_GETCURRENTPOS);\r
632                 int selend = SendEditor(SCI_POSITIONFROMLINE, i);\r
633                 SendEditor(SCI_SETSELECTIONSTART, selstart);\r
634                 SendEditor(SCI_SETSELECTIONEND, selend);\r
635                 m_SelectedLine = i-1;\r
636         }\r
637         else\r
638         {\r
639                 ::MessageBox(wMain, searchstringnotfound, "CTortoiseGitBlameView", MB_ICONINFORMATION);\r
640         }\r
641 #endif\r
642         return true;\r
643 }\r
644 \r
645 bool CTortoiseGitBlameView::GotoLine(long line)\r
646 {\r
647         --line;\r
648         if (line < 0)\r
649                 return false;\r
650         if ((unsigned long)line >= authors.size())\r
651         {\r
652                 line = authors.size()-1;\r
653         }\r
654 \r
655         int nCurrentPos = SendEditor(SCI_GETCURRENTPOS);\r
656         int nCurrentLine = SendEditor(SCI_LINEFROMPOSITION,nCurrentPos);\r
657         int nFirstVisibleLine = SendEditor(SCI_GETFIRSTVISIBLELINE);\r
658         int nLinesOnScreen = SendEditor(SCI_LINESONSCREEN);\r
659 \r
660         if ( line>=nFirstVisibleLine && line<=nFirstVisibleLine+nLinesOnScreen)\r
661         {\r
662                 // no need to scroll\r
663                 SendEditor(SCI_GOTOLINE, line);\r
664         }\r
665         else\r
666         {\r
667                 // Place the requested line one third from the top\r
668                 if ( line > nCurrentLine )\r
669                 {\r
670                         SendEditor(SCI_GOTOLINE, (WPARAM)(line+(int)nLinesOnScreen*(2/3.0)));\r
671                 }\r
672                 else\r
673                 {\r
674                         SendEditor(SCI_GOTOLINE, (WPARAM)(line-(int)nLinesOnScreen*(1/3.0)));\r
675                 }\r
676         }\r
677 \r
678         // Highlight the line\r
679         int nPosStart = SendEditor(SCI_POSITIONFROMLINE,line);\r
680         int nPosEnd = SendEditor(SCI_GETLINEENDPOSITION,line);\r
681         SendEditor(SCI_SETSEL,nPosEnd,nPosStart);\r
682 \r
683         return true;\r
684 }\r
685 \r
686 bool CTortoiseGitBlameView::ScrollToLine(long line)\r
687 {\r
688         if (line < 0)\r
689                 return false;\r
690 \r
691         int nCurrentLine = SendEditor(SCI_GETFIRSTVISIBLELINE);\r
692 \r
693         int scrolldelta = line - nCurrentLine;\r
694         SendEditor(SCI_LINESCROLL, 0, scrolldelta);\r
695 \r
696         return true;\r
697 }\r
698 \r
699 void CTortoiseGitBlameView::CopySelectedLogToClipboard()\r
700 {\r
701 #if 0\r
702         if (m_selectedrev <= 0)\r
703                 return;\r
704         std::map<LONG, CString>::iterator iter;\r
705         if ((iter = app.logmessages.find(m_selectedrev)) != app.logmessages.end())\r
706         {\r
707                 CString msg;\r
708                 msg += m_selectedauthor;\r
709                 msg += "  ";\r
710                 msg += app.m_selecteddate;\r
711                 msg += '\n';\r
712                 msg += iter->second;\r
713                 msg += _T("\n");\r
714                 if (OpenClipboard(app.wBlame))\r
715                 {\r
716                         EmptyClipboard();\r
717                         HGLOBAL hClipboardData;\r
718                         hClipboardData = GlobalAlloc(GMEM_DDESHARE, msg.size()+1);\r
719                         char * pchData;\r
720                         pchData = (char*)GlobalLock(hClipboardData);\r
721                         strcpy_s(pchData, msg.size()+1, msg.c_str());\r
722                         GlobalUnlock(hClipboardData);\r
723                         SetClipboardData(CF_TEXT,hClipboardData);\r
724                         CloseClipboard();\r
725                 }\r
726         }\r
727 #endif\r
728 }\r
729 \r
730 void CTortoiseGitBlameView::BlamePreviousRevision()\r
731 {\r
732 #if 0\r
733         LONG nRevisionTo = m_selectedorigrev - 1;\r
734         if ( nRevisionTo<1 )\r
735         {\r
736                 return;\r
737         }\r
738 \r
739         // We now determine the smallest revision number in the blame file (but ignore "-1")\r
740         // We do this for two reasons:\r
741         // 1. we respect the "From revision" which the user entered\r
742         // 2. we speed up the call of "svn blame" because previous smaller revision numbers don't have any effect on the result\r
743         LONG nSmallestRevision = -1;\r
744         for (LONG line=0;line<(LONG)app.revs.size();line++)\r
745         {\r
746                 const LONG nRevision = app.revs[line];\r
747                 if ( nRevision > 0 )\r
748                 {\r
749                         if ( nSmallestRevision < 1 )\r
750                         {\r
751                                 nSmallestRevision = nRevision;\r
752                         }\r
753                         else\r
754                         {\r
755                                 nSmallestRevision = min(nSmallestRevision,nRevision);\r
756                         }\r
757                 }\r
758         }\r
759 \r
760         char bufStartRev[20];\r
761         _stprintf_s(bufStartRev, 20, _T("%d"), nSmallestRevision);\r
762 \r
763         char bufEndRev[20];\r
764         _stprintf_s(bufEndRev, 20, _T("%d"), nRevisionTo);\r
765 \r
766         char bufLine[20];\r
767         _stprintf_s(bufLine, 20, _T("%d"), m_SelectedLine+1); //using the current line is a good guess.\r
768 \r
769         STARTUPINFO startup;\r
770         PROCESS_INFORMATION process;\r
771         memset(&startup, 0, sizeof(startup));\r
772         startup.cb = sizeof(startup);\r
773         memset(&process, 0, sizeof(process));\r
774         stdstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");\r
775         stdstring svnCmd = _T(" /command:blame ");\r
776         svnCmd += _T(" /path:\"");\r
777         svnCmd += szOrigPath;\r
778         svnCmd += _T("\"");\r
779         svnCmd += _T(" /startrev:");\r
780         svnCmd += bufStartRev;\r
781         svnCmd += _T(" /endrev:");\r
782         svnCmd += bufEndRev;\r
783         svnCmd += _T(" /line:");\r
784         svnCmd += bufLine;\r
785         if (bIgnoreEOL)\r
786                 svnCmd += _T(" /ignoreeol");\r
787         if (bIgnoreSpaces)\r
788                 svnCmd += _T(" /ignorespaces");\r
789         if (bIgnoreAllSpaces)\r
790                 svnCmd += _T(" /ignoreallspaces");\r
791     if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))\r
792         {\r
793                 CloseHandle(process.hThread);\r
794                 CloseHandle(process.hProcess);\r
795         }\r
796 #endif\r
797 }\r
798 \r
799 void CTortoiseGitBlameView::DiffPreviousRevision()\r
800 {\r
801 #if 0\r
802         LONG nRevisionTo = m_selectedorigrev;\r
803         if ( nRevisionTo<1 )\r
804         {\r
805                 return;\r
806         }\r
807 \r
808         LONG nRevisionFrom = nRevisionTo-1;\r
809 \r
810         char bufStartRev[20];\r
811         _stprintf_s(bufStartRev, 20, _T("%d"), nRevisionFrom);\r
812 \r
813         char bufEndRev[20];\r
814         _stprintf_s(bufEndRev, 20, _T("%d"), nRevisionTo);\r
815 \r
816         STARTUPINFO startup;\r
817         PROCESS_INFORMATION process;\r
818         memset(&startup, 0, sizeof(startup));\r
819         startup.cb = sizeof(startup);\r
820         memset(&process, 0, sizeof(process));\r
821         stdstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");\r
822         stdstring svnCmd = _T(" /command:diff ");\r
823         svnCmd += _T(" /path:\"");\r
824         svnCmd += szOrigPath;\r
825         svnCmd += _T("\"");\r
826         svnCmd += _T(" /startrev:");\r
827         svnCmd += bufStartRev;\r
828         svnCmd += _T(" /endrev:");\r
829         svnCmd += bufEndRev;\r
830         if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))\r
831         {\r
832                 CloseHandle(process.hThread);\r
833                 CloseHandle(process.hProcess);\r
834         }\r
835 #endif\r
836 }\r
837 \r
838 void CTortoiseGitBlameView::ShowLog()\r
839 {\r
840 #if 0\r
841         char bufRev[20];\r
842         _stprintf_s(bufRev, 20, _T("%d"), m_selectedorigrev);\r
843 \r
844         STARTUPINFO startup;\r
845         PROCESS_INFORMATION process;\r
846         memset(&startup, 0, sizeof(startup));\r
847         startup.cb = sizeof(startup);\r
848         memset(&process, 0, sizeof(process));\r
849         stdstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");\r
850         stdstring svnCmd = _T(" /command:log ");\r
851         svnCmd += _T(" /path:\"");\r
852         svnCmd += szOrigPath;\r
853         svnCmd += _T("\"");\r
854         svnCmd += _T(" /startrev:");\r
855         svnCmd += bufRev;\r
856         svnCmd += _T(" /pegrev:");\r
857         svnCmd += bufRev;\r
858         if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))\r
859         {\r
860                 CloseHandle(process.hThread);\r
861                 CloseHandle(process.hProcess);\r
862         }\r
863 #endif\r
864 }\r
865 \r
866 void CTortoiseGitBlameView::Notify(SCNotification *notification) \r
867 {\r
868         switch (notification->nmhdr.code) \r
869         {\r
870         case SCN_SAVEPOINTREACHED:\r
871                 break;\r
872 \r
873         case SCN_SAVEPOINTLEFT:\r
874                 break;\r
875         case SCN_PAINTED:\r
876 //              InvalidateRect(wBlame, NULL, FALSE);\r
877 //              InvalidateRect(wLocator, NULL, FALSE);\r
878                 break;\r
879         case SCN_GETBKCOLOR:\r
880                 if ((m_colorage)&&(notification->line < (int)revs.size()))\r
881                 {\r
882                         notification->lParam = InterColor(DWORD(m_regOldLinesColor), DWORD(m_regNewLinesColor), (revs[notification->line]-m_lowestrev)*100/((m_highestrev-m_lowestrev)+1));\r
883                 }\r
884                 break;\r
885         }\r
886 }\r
887 \r
888 void CTortoiseGitBlameView::Command(int id)\r
889 {\r
890 #if 0\r
891         switch (id) \r
892         {\r
893 //      case IDM_EXIT:\r
894 //              ::PostQuitMessage(0);\r
895 //              break;\r
896         case ID_EDIT_FIND:\r
897                 StartSearch();\r
898                 break;\r
899         case ID_COPYTOCLIPBOARD:\r
900                 CopySelectedLogToClipboard();\r
901                 break;\r
902         case ID_BLAME_PREVIOUS_REVISION:\r
903                 BlamePreviousRevision();\r
904                 break;\r
905         case ID_DIFF_PREVIOUS_REVISION:\r
906                 DiffPreviousRevision();\r
907                 break;\r
908         case ID_SHOWLOG:\r
909                 ShowLog();\r
910                 break;\r
911         case ID_EDIT_GOTOLINE:\r
912                 GotoLineDlg();\r
913                 break;\r
914         case ID_VIEW_COLORAGEOFLINES:\r
915                 {\r
916                         m_colorage = !m_colorage;\r
917                         HMENU hMenu = GetMenu(wMain);\r
918                         UINT uCheck = MF_BYCOMMAND;\r
919                         uCheck |= m_colorage ? MF_CHECKED : MF_UNCHECKED;\r
920                         CheckMenuItem(hMenu, ID_VIEW_COLORAGEOFLINES, uCheck);\r
921                         m_blamewidth = 0;\r
922                         InitSize();\r
923                 }\r
924                 break;\r
925         case ID_VIEW_MERGEPATH:\r
926                 {\r
927                         ShowPath = !ShowPath;\r
928                         HMENU hMenu = GetMenu(wMain);\r
929                         UINT uCheck = MF_BYCOMMAND;\r
930                         uCheck |= ShowPath ? MF_CHECKED : MF_UNCHECKED;\r
931                         CheckMenuItem(hMenu, ID_VIEW_MERGEPATH, uCheck);\r
932                         m_blamewidth = 0;\r
933                         InitSize();\r
934                 }\r
935         default:\r
936                 break;\r
937         };\r
938 #endif\r
939 }\r
940 \r
941 void CTortoiseGitBlameView::GotoLineDlg()\r
942 {\r
943 #if 0\r
944         if (DialogBox(hResource, MAKEINTRESOURCE(IDD_GOTODLG), wMain, GotoDlgProc)==IDOK)\r
945         {\r
946                 GotoLine(m_gotoline);\r
947         }\r
948 #endif\r
949 }\r
950 \r
951 LONG CTortoiseGitBlameView::GetBlameWidth()\r
952 {\r
953 #if 0\r
954         if (m_blamewidth)\r
955                 return m_blamewidth;\r
956         LONG blamewidth = 0;\r
957         SIZE width;\r
958         CreateFont();\r
959         HDC hDC = ::GetDC(wBlame);\r
960         HFONT oldfont = (HFONT)::SelectObject(hDC, m_font);\r
961         TCHAR buf[MAX_PATH];\r
962         _stprintf_s(buf, MAX_PATH, _T("%8ld "), 88888888);\r
963         ::GetTextExtentPoint(hDC, buf, _tcslen(buf), &width);\r
964         m_revwidth = width.cx + BLAMESPACE;\r
965         blamewidth += m_revwidth;\r
966         if (ShowDate)\r
967         {\r
968                 _stprintf_s(buf, MAX_PATH, _T("%30s"), _T("31.08.2001 06:24:14"));\r
969                 ::GetTextExtentPoint32(hDC, buf, _tcslen(buf), &width);\r
970                 m_datewidth = width.cx + BLAMESPACE;\r
971                 blamewidth += m_datewidth;\r
972         }\r
973         if (ShowAuthor)\r
974         {\r
975                 SIZE maxwidth = {0};\r
976                 for (std::vector<CString>::iterator I = authors.begin(); I != authors.end(); ++I)\r
977                 {\r
978                         ::GetTextExtentPoint32(hDC, I->c_str(), I->size(), &width);\r
979                         if (width.cx > maxwidth.cx)\r
980                                 maxwidth = width;\r
981                 }\r
982                 m_authorwidth = maxwidth.cx + BLAMESPACE;\r
983                 blamewidth += m_authorwidth;\r
984         }\r
985         if (ShowPath)\r
986         {\r
987                 SIZE maxwidth = {0};\r
988                 for (std::vector<CString>::iterator I = paths.begin(); I != paths.end(); ++I)\r
989                 {\r
990                         ::GetTextExtentPoint32(hDC, I->c_str(), I->size(), &width);\r
991                         if (width.cx > maxwidth.cx)\r
992                                 maxwidth = width;\r
993                 }\r
994                 m_pathwidth = maxwidth.cx + BLAMESPACE;\r
995                 blamewidth += m_pathwidth;\r
996         }\r
997         ::SelectObject(hDC, oldfont);\r
998         POINT pt = {blamewidth, 0};\r
999         LPtoDP(hDC, &pt, 1);\r
1000         m_blamewidth = pt.x;\r
1001         ReleaseDC(wBlame, hDC);\r
1002 #endif\r
1003         //return m_blamewidth;\r
1004         return 100;\r
1005 }\r
1006 \r
1007 void CTortoiseGitBlameView::CreateFont()\r
1008 {\r
1009         if (m_font)\r
1010                 return;\r
1011         LOGFONT lf = {0};\r
1012         lf.lfWeight = 400;\r
1013         HDC hDC = ::GetDC(wBlame);\r
1014         lf.lfHeight = -MulDiv((DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\BlameFontSize"), 10), GetDeviceCaps(hDC, LOGPIXELSY), 72);\r
1015         lf.lfCharSet = DEFAULT_CHARSET;\r
1016         CRegStdString fontname = CRegStdString(_T("Software\\TortoiseGit\\BlameFontName"), _T("Courier New"));\r
1017         _tcscpy_s(lf.lfFaceName, 32, ((stdstring)fontname).c_str());\r
1018         m_font = ::CreateFontIndirect(&lf);\r
1019 \r
1020         lf.lfItalic = TRUE;\r
1021         m_italicfont = ::CreateFontIndirect(&lf);\r
1022 \r
1023         ::ReleaseDC(wBlame, hDC);\r
1024 \r
1025 }\r
1026 \r
1027 void CTortoiseGitBlameView::DrawBlame(HDC hDC)\r
1028 {\r
1029 #if 0\r
1030         if (hDC == NULL)\r
1031                 return;\r
1032         if (m_font == NULL)\r
1033                 return;\r
1034 \r
1035         HFONT oldfont = NULL;\r
1036         LONG_PTR line = SendEditor(SCI_GETFIRSTVISIBLELINE);\r
1037         LONG_PTR linesonscreen = SendEditor(SCI_LINESONSCREEN);\r
1038         LONG_PTR height = SendEditor(SCI_TEXTHEIGHT);\r
1039         LONG_PTR Y = 0;\r
1040         TCHAR buf[MAX_PATH];\r
1041         RECT rc;\r
1042         BOOL sel = FALSE;\r
1043         ::GetClientRect(wBlame, &rc);\r
1044         for (LRESULT i=line; i<(line+linesonscreen); ++i)\r
1045         {\r
1046                 sel = FALSE;\r
1047                 if (i < (int)revs.size())\r
1048                 {\r
1049                         if (mergelines[i])\r
1050                                 oldfont = (HFONT)::SelectObject(hDC, m_italicfont);\r
1051                         else\r
1052                                 oldfont = (HFONT)::SelectObject(hDC, m_font);\r
1053                         ::SetBkColor(hDC, m_windowcolor);\r
1054                         ::SetTextColor(hDC, m_textcolor);\r
1055                         if (authors[i].GetLength()>0)\r
1056                         {\r
1057                                 if (authors[i].Compare(m_mouseauthor)==0)\r
1058                                         ::SetBkColor(hDC, m_mouseauthorcolor);\r
1059                                 if (authors[i].Compare(m_selectedauthor)==0)\r
1060                                 {\r
1061                                         ::SetBkColor(hDC, m_selectedauthorcolor);\r
1062                                         ::SetTextColor(hDC, m_texthighlightcolor);\r
1063                                         sel = TRUE;\r
1064                                 }\r
1065                         }\r
1066                         if ((revs[i] == m_mouserev)&&(!sel))\r
1067                                 ::SetBkColor(hDC, m_mouserevcolor);\r
1068                         if (revs[i] == m_selectedrev)\r
1069                         {\r
1070                                 ::SetBkColor(hDC, m_selectedrevcolor);\r
1071                                 ::SetTextColor(hDC, m_texthighlightcolor);\r
1072                         }\r
1073                         _stprintf_s(buf, MAX_PATH, _T("%8ld       "), revs[i]);\r
1074                         rc.right = rc.left + m_revwidth;\r
1075                         ::ExtTextOut(hDC, 0, Y, ETO_CLIPPED, &rc, buf, _tcslen(buf), 0);\r
1076                         int Left = m_revwidth;\r
1077                         if (ShowDate)\r
1078                         {\r
1079                                 rc.right = rc.left + Left + m_datewidth;\r
1080                                 _stprintf_s(buf, MAX_PATH, _T("%30s            "), dates[i].c_str());\r
1081                                 ::ExtTextOut(hDC, Left, Y, ETO_CLIPPED, &rc, buf, _tcslen(buf), 0);\r
1082                                 Left += m_datewidth;\r
1083                         }\r
1084                         if (ShowAuthor)\r
1085                         {\r
1086                                 rc.right = rc.left + Left + m_authorwidth;\r
1087                                 _stprintf_s(buf, MAX_PATH, _T("%-30s            "), authors[i].c_str());\r
1088                                 ::ExtTextOut(hDC, Left, Y, ETO_CLIPPED, &rc, buf, _tcslen(buf), 0);\r
1089                                 Left += m_authorwidth;\r
1090                         }\r
1091                         if (ShowPath)\r
1092                         {\r
1093                                 rc.right = rc.left + Left + m_pathwidth;\r
1094                                 _stprintf_s(buf, MAX_PATH, _T("%-60s            "), paths[i].c_str());\r
1095                                 ::ExtTextOut(hDC, Left, Y, ETO_CLIPPED, &rc, buf, _tcslen(buf), 0);\r
1096                                 Left += m_authorwidth;\r
1097                         }\r
1098                         if ((i==m_SelectedLine)&&(currentDialog))\r
1099                         {\r
1100                                 LOGBRUSH brush;\r
1101                                 brush.lbColor = m_textcolor;\r
1102                                 brush.lbHatch = 0;\r
1103                                 brush.lbStyle = BS_SOLID;\r
1104                                 HPEN pen = ExtCreatePen(PS_SOLID | PS_GEOMETRIC, 2, &brush, 0, NULL);\r
1105                                 HGDIOBJ hPenOld = SelectObject(hDC, pen);\r
1106                                 RECT rc2 = rc;\r
1107                                 rc2.top = Y;\r
1108                                 rc2.bottom = Y + height;\r
1109                                 ::MoveToEx(hDC, rc2.left, rc2.top, NULL);\r
1110                                 ::LineTo(hDC, rc2.right, rc2.top);\r
1111                                 ::LineTo(hDC, rc2.right, rc2.bottom);\r
1112                                 ::LineTo(hDC, rc2.left, rc2.bottom);\r
1113                                 ::LineTo(hDC, rc2.left, rc2.top);\r
1114                                 SelectObject(hDC, hPenOld); \r
1115                                 DeleteObject(pen); \r
1116                         }\r
1117                         Y += height;\r
1118                         ::SelectObject(hDC, oldfont);\r
1119                 }\r
1120                 else\r
1121                 {\r
1122                         ::SetBkColor(hDC, m_windowcolor);\r
1123                         for (int j=0; j< MAX_PATH; ++j)\r
1124                                 buf[j]=' ';\r
1125                         ::ExtTextOut(hDC, 0, Y, ETO_CLIPPED, &rc, buf, MAX_PATH-1, 0);\r
1126                         Y += height;\r
1127                 }\r
1128         }\r
1129 #endif\r
1130 }\r
1131 \r
1132 void CTortoiseGitBlameView::DrawHeader(HDC hDC)\r
1133 {\r
1134 #if 0\r
1135         if (hDC == NULL)\r
1136                 return;\r
1137 \r
1138         RECT rc;\r
1139         HFONT oldfont = (HFONT)::SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));\r
1140         ::GetClientRect(wHeader, &rc);\r
1141 \r
1142         ::SetBkColor(hDC, ::GetSysColor(COLOR_BTNFACE));\r
1143 \r
1144         TCHAR szText[MAX_LOADSTRING];\r
1145         LoadString(app.hResource, IDS_HEADER_REVISION, szText, MAX_LOADSTRING);\r
1146         ::ExtTextOut(hDC, LOCATOR_WIDTH, 0, ETO_CLIPPED, &rc, szText, _tcslen(szText), 0);\r
1147         int Left = m_revwidth+LOCATOR_WIDTH;\r
1148         if (ShowDate)\r
1149         {\r
1150                 LoadString(app.hResource, IDS_HEADER_DATE, szText, MAX_LOADSTRING);\r
1151                 ::ExtTextOut(hDC, Left, 0, ETO_CLIPPED, &rc, szText, _tcslen(szText), 0);\r
1152                 Left += m_datewidth;\r
1153         }\r
1154         if (ShowAuthor)\r
1155         {\r
1156                 LoadString(app.hResource, IDS_HEADER_AUTHOR, szText, MAX_LOADSTRING);\r
1157                 ::ExtTextOut(hDC, Left, 0, ETO_CLIPPED, &rc, szText, _tcslen(szText), 0);\r
1158                 Left += m_authorwidth;\r
1159         }\r
1160         if (ShowPath)\r
1161         {\r
1162                 LoadString(app.hResource, IDS_HEADER_PATH, szText, MAX_LOADSTRING);\r
1163                 ::ExtTextOut(hDC, Left, 0, ETO_CLIPPED, &rc, szText, _tcslen(szText), 0);\r
1164                 Left += m_pathwidth;\r
1165         }\r
1166         LoadString(app.hResource, IDS_HEADER_LINE, szText, MAX_LOADSTRING);\r
1167         ::ExtTextOut(hDC, Left, 0, ETO_CLIPPED, &rc, szText, _tcslen(szText), 0);\r
1168 \r
1169         ::SelectObject(hDC, oldfont);\r
1170 #endif\r
1171 }\r
1172 \r
1173 void CTortoiseGitBlameView::DrawLocatorBar(HDC hDC)\r
1174 {\r
1175         if (hDC == NULL)\r
1176                 return;\r
1177 \r
1178         LONG_PTR line = SendEditor(SCI_GETFIRSTVISIBLELINE);\r
1179         LONG_PTR linesonscreen = SendEditor(SCI_LINESONSCREEN);\r
1180         LONG_PTR Y = 0;\r
1181         COLORREF blackColor = GetSysColor(COLOR_WINDOWTEXT);\r
1182 \r
1183         RECT rc;\r
1184         ::GetClientRect(wLocator, &rc);\r
1185         RECT lineRect = rc;\r
1186         LONG height = rc.bottom-rc.top;\r
1187         LONG currentLine = 0;\r
1188 \r
1189         // draw the colored bar\r
1190         for (std::vector<LONG>::const_iterator it = revs.begin(); it != revs.end(); ++it)\r
1191         {\r
1192                 currentLine++;\r
1193                 // get the line color\r
1194                 COLORREF cr = InterColor(DWORD(m_regOldLinesColor), DWORD(m_regNewLinesColor), (*it - m_lowestrev)*100/((m_highestrev-m_lowestrev)+1));\r
1195                 if ((currentLine > line)&&(currentLine <= (line + linesonscreen)))\r
1196                 {\r
1197                         cr = InterColor(cr, blackColor, 10);\r
1198                 }\r
1199                 SetBkColor(hDC, cr);\r
1200                 lineRect.top = Y;\r
1201                 lineRect.bottom = (currentLine * height / revs.size());\r
1202                 ::ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &lineRect, NULL, 0, NULL);\r
1203                 Y = lineRect.bottom;\r
1204         }\r
1205 \r
1206         if (revs.size())\r
1207         {\r
1208                 // now draw two lines indicating the scroll position of the source view\r
1209                 SetBkColor(hDC, blackColor);\r
1210                 lineRect.top = line * height / revs.size();\r
1211                 lineRect.bottom = lineRect.top+1;\r
1212                 ::ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &lineRect, NULL, 0, NULL);\r
1213                 lineRect.top = (line + linesonscreen) * height / revs.size();\r
1214                 lineRect.bottom = lineRect.top+1;\r
1215                 ::ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &lineRect, NULL, 0, NULL);\r
1216         }\r
1217 }\r
1218 \r
1219 void CTortoiseGitBlameView::StringExpand(LPSTR str)\r
1220 {\r
1221         char * cPos = str;\r
1222         do\r
1223         {\r
1224                 cPos = strchr(cPos, '\n');\r
1225                 if (cPos)\r
1226                 {\r
1227                         memmove(cPos+1, cPos, strlen(cPos)*sizeof(char));\r
1228                         *cPos = '\r';\r
1229                         cPos++;\r
1230                         cPos++;\r
1231                 }\r
1232         } while (cPos != NULL);\r
1233 }\r
1234 void CTortoiseGitBlameView::StringExpand(LPWSTR str)\r
1235 {\r
1236         wchar_t * cPos = str;\r
1237         do\r
1238         {\r
1239                 cPos = wcschr(cPos, '\n');\r
1240                 if (cPos)\r
1241                 {\r
1242                         memmove(cPos+1, cPos, wcslen(cPos)*sizeof(wchar_t));\r
1243                         *cPos = '\r';\r
1244                         cPos++;\r
1245                         cPos++;\r
1246                 }\r
1247         } while (cPos != NULL);\r
1248 }\r
1249 \r
1250 // Forward declarations of functions included in this code module:\r
1251 ATOM                            MyRegisterClass(HINSTANCE hResource);\r
1252 ATOM                            MyRegisterBlameClass(HINSTANCE hResource);\r
1253 ATOM                            MyRegisterHeaderClass(HINSTANCE hResource);\r
1254 ATOM                            MyRegisterLocatorClass(HINSTANCE hResource);\r
1255 BOOL                            InitInstance(HINSTANCE, int);\r
1256 LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);\r
1257 LRESULT CALLBACK        WndBlameProc(HWND, UINT, WPARAM, LPARAM);\r
1258 LRESULT CALLBACK        WndHeaderProc(HWND, UINT, WPARAM, LPARAM);\r
1259 LRESULT CALLBACK        WndLocatorProc(HWND, UINT, WPARAM, LPARAM);\r
1260 UINT                            uFindReplaceMsg;\r
1261 \r
1262 #if 0\r
1263 int APIENTRY _tWinMain(HINSTANCE hInstance,\r
1264                      HINSTANCE /*hPrevInstance*/,\r
1265                      LPTSTR    lpCmdLine,\r
1266                      int       nCmdShow)\r
1267 {\r
1268         app.hInstance = hInstance;\r
1269         MSG msg;\r
1270         HACCEL hAccelTable;\r
1271 \r
1272         if (::LoadLibrary("SciLexer.DLL") == NULL)\r
1273                 return FALSE;\r
1274 \r
1275         CRegStdWORD loc = CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);\r
1276         long langId = loc;\r
1277 \r
1278         CLangDll langDLL;\r
1279         app.hResource = langDLL.Init(_T("CTortoiseGitBlameView"), langId);\r
1280         if (app.hResource == NULL)\r
1281                 app.hResource = app.hInstance;\r
1282 \r
1283         // Initialize global strings\r
1284         LoadString(app.hResource, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);\r
1285         LoadString(app.hResource, IDC_TortoiseGitBlameView, szWindowClass, MAX_LOADSTRING);\r
1286         LoadString(app.hResource, IDS_SEARCHNOTFOUND, searchstringnotfound, MAX_LOADSTRING);\r
1287         MyRegisterClass(app.hResource);\r
1288         MyRegisterBlameClass(app.hResource);\r
1289         MyRegisterHeaderClass(app.hResource);\r
1290         MyRegisterLocatorClass(app.hResource);\r
1291 \r
1292         // Perform application initialization:\r
1293         if (!InitInstance (app.hResource, nCmdShow)) \r
1294         {\r
1295                 langDLL.Close();\r
1296                 return FALSE;\r
1297         }\r
1298 \r
1299         SecureZeroMemory(szViewtitle, MAX_PATH);\r
1300         SecureZeroMemory(szOrigPath, MAX_PATH);\r
1301         char blamefile[MAX_PATH] = {0};\r
1302         char logfile[MAX_PATH] = {0};\r
1303 \r
1304         CCmdLineParser parser(lpCmdLine);\r
1305 \r
1306 \r
1307         if (__argc > 1)\r
1308         {\r
1309                 _tcscpy_s(blamefile, MAX_PATH, __argv[1]);\r
1310         }\r
1311         if (__argc > 2)\r
1312         {\r
1313                 _tcscpy_s(logfile, MAX_PATH, __argv[2]);\r
1314         }\r
1315         if (__argc > 3)\r
1316         {\r
1317                 _tcscpy_s(szViewtitle, MAX_PATH, __argv[3]);\r
1318                 if (parser.HasVal(_T("revrange")))\r
1319                 {\r
1320                         _tcscat_s(szViewtitle, MAX_PATH, _T(" : "));\r
1321                         _tcscat_s(szViewtitle, MAX_PATH, parser.GetVal(_T("revrange")));\r
1322                 }\r
1323         }\r
1324         if ((_tcslen(blamefile)==0) || parser.HasKey(_T("?")) || parser.HasKey(_T("help")))\r
1325         {\r
1326                 TCHAR szInfo[MAX_LOADSTRING];\r
1327                 LoadString(app.hResource, IDS_COMMANDLINE_INFO, szInfo, MAX_LOADSTRING);\r
1328                 MessageBox(NULL, szInfo, _T("CTortoiseGitBlameView"), MB_ICONERROR);\r
1329                 langDLL.Close();\r
1330                 return 0;\r
1331         }\r
1332 \r
1333         if ( parser.HasKey(_T("path")) )\r
1334         {\r
1335                 _tcscpy_s(szOrigPath, MAX_PATH, parser.GetVal(_T("path")));\r
1336         }\r
1337         app.bIgnoreEOL = parser.HasKey(_T("ignoreeol"));\r
1338         app.bIgnoreSpaces = parser.HasKey(_T("ignorespaces"));\r
1339         app.bIgnoreAllSpaces = parser.HasKey(_T("ignoreallspaces"));\r
1340 \r
1341         app.SendEditor(SCI_SETCODEPAGE, GetACP());\r
1342         app.OpenFile(blamefile);\r
1343         if (_tcslen(logfile)>0)\r
1344                 app.OpenLogFile(logfile);\r
1345 \r
1346         if (parser.HasKey(_T("line")))\r
1347         {\r
1348                 app.GotoLine(parser.GetLongVal(_T("line")));\r
1349         }\r
1350 \r
1351         CheckMenuItem(GetMenu(app.wMain), ID_VIEW_COLORAGEOFLINES, MF_CHECKED|MF_BYCOMMAND);\r
1352 \r
1353 \r
1354         hAccelTable = LoadAccelerators(app.hResource, (LPCTSTR)IDC_TortoiseGitBlameView);\r
1355 \r
1356         BOOL going = TRUE;\r
1357         msg.wParam = 0;\r
1358         while (going) \r
1359         {\r
1360                 going = GetMessage(&msg, NULL, 0, 0);\r
1361                 if (app.currentDialog && going) \r
1362                 {\r
1363                         if (!IsDialogMessage(app.currentDialog, &msg)) \r
1364                         {\r
1365                                 if (TranslateAccelerator(msg.hwnd, hAccelTable, &msg) == 0) \r
1366                                 {\r
1367                                         TranslateMessage(&msg);\r
1368                                         DispatchMessage(&msg);\r
1369                                 }\r
1370                         }\r
1371                 } \r
1372                 else if (going) \r
1373                 {\r
1374                         if (TranslateAccelerator(app.wMain, hAccelTable, &msg) == 0) \r
1375                         {\r
1376                                 TranslateMessage(&msg);\r
1377                                 DispatchMessage(&msg);\r
1378                         }\r
1379                 }\r
1380         }\r
1381         langDLL.Close();\r
1382         return msg.wParam;\r
1383 }\r
1384 \r
1385 ATOM MyRegisterClass(HINSTANCE hResource)\r
1386 {\r
1387         WNDCLASSEX wcex;\r
1388 \r
1389         wcex.cbSize = sizeof(WNDCLASSEX); \r
1390 \r
1391         wcex.style                      = CS_HREDRAW | CS_VREDRAW;\r
1392         wcex.lpfnWndProc        = (WNDPROC)WndProc;\r
1393         wcex.cbClsExtra         = 0;\r
1394         wcex.cbWndExtra         = 0;\r
1395         wcex.hInstance          = hResource;\r
1396         wcex.hIcon                      = LoadIcon(hResource, (LPCTSTR)IDI_TortoiseGitBlameView);\r
1397         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);\r
1398         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);\r
1399         wcex.lpszMenuName       = (LPCTSTR)IDC_TortoiseGitBlameView;\r
1400         wcex.lpszClassName      = szWindowClass;\r
1401         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);\r
1402 \r
1403         return RegisterClassEx(&wcex);\r
1404 }\r
1405 \r
1406 ATOM MyRegisterBlameClass(HINSTANCE hResource)\r
1407 {\r
1408         WNDCLASSEX wcex;\r
1409 \r
1410         wcex.cbSize = sizeof(WNDCLASSEX); \r
1411 \r
1412         wcex.style                      = CS_HREDRAW | CS_VREDRAW;\r
1413         wcex.lpfnWndProc        = (WNDPROC)WndBlameProc;\r
1414         wcex.cbClsExtra         = 0;\r
1415         wcex.cbWndExtra         = 0;\r
1416         wcex.hInstance          = hResource;\r
1417         wcex.hIcon                      = LoadIcon(hResource, (LPCTSTR)IDI_TortoiseGitBlameView);\r
1418         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);\r
1419         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);\r
1420         wcex.lpszMenuName       = 0;\r
1421         wcex.lpszClassName      = _T("TortoiseGitBlameViewBlame");\r
1422         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);\r
1423 \r
1424         return RegisterClassEx(&wcex);\r
1425 }\r
1426 \r
1427 ATOM MyRegisterHeaderClass(HINSTANCE hResource)\r
1428 {\r
1429         WNDCLASSEX wcex;\r
1430 \r
1431         wcex.cbSize = sizeof(WNDCLASSEX); \r
1432 \r
1433         wcex.style                      = CS_HREDRAW | CS_VREDRAW;\r
1434         wcex.lpfnWndProc        = (WNDPROC)WndHeaderProc;\r
1435         wcex.cbClsExtra         = 0;\r
1436         wcex.cbWndExtra         = 0;\r
1437         wcex.hInstance          = hResource;\r
1438         wcex.hIcon                      = LoadIcon(hResource, (LPCTSTR)IDI_TortoiseGitBlameView);\r
1439         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);\r
1440         wcex.hbrBackground      = (HBRUSH)(COLOR_BTNFACE+1);\r
1441         wcex.lpszMenuName       = 0;\r
1442         wcex.lpszClassName      = _T("TortoiseGitBlameViewHeader");\r
1443         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);\r
1444 \r
1445         return RegisterClassEx(&wcex);\r
1446 }\r
1447 \r
1448 ATOM MyRegisterLocatorClass(HINSTANCE hResource)\r
1449 {\r
1450         WNDCLASSEX wcex;\r
1451 \r
1452         wcex.cbSize = sizeof(WNDCLASSEX); \r
1453 \r
1454         wcex.style                      = CS_HREDRAW | CS_VREDRAW;\r
1455         wcex.lpfnWndProc        = (WNDPROC)WndLocatorProc;\r
1456         wcex.cbClsExtra         = 0;\r
1457         wcex.cbWndExtra         = 0;\r
1458         wcex.hInstance          = hResource;\r
1459         wcex.hIcon                      = LoadIcon(hResource, (LPCTSTR)IDI_TortoiseGitBlameView);\r
1460         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);\r
1461         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);\r
1462         wcex.lpszMenuName       = 0;\r
1463         wcex.lpszClassName      = _T("TortoiseGitBlameViewLocator");\r
1464         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);\r
1465 \r
1466         return RegisterClassEx(&wcex);\r
1467 }\r
1468 \r
1469 BOOL InitInstance(HINSTANCE hResource, int nCmdShow)\r
1470 {\r
1471    app.wMain = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,\r
1472       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hResource, NULL);   \r
1473 \r
1474    if (!app.wMain)\r
1475    {\r
1476       return FALSE;\r
1477    }\r
1478 \r
1479    CRegStdWORD pos(_T("Software\\TortoiseGit\\TBlamePos"), 0);\r
1480    CRegStdWORD width(_T("Software\\TortoiseGit\\TBlameSize"), 0);\r
1481    CRegStdWORD state(_T("Software\\TortoiseGit\\TBlameState"), 0);\r
1482    if (DWORD(pos) && DWORD(width))\r
1483    {\r
1484            RECT rc;\r
1485            rc.left = LOWORD(DWORD(pos));\r
1486            rc.top = HIWORD(DWORD(pos));\r
1487            rc.right = rc.left + LOWORD(DWORD(width));\r
1488            rc.bottom = rc.top + HIWORD(DWORD(width));\r
1489            HMONITOR hMon = MonitorFromRect(&rc, MONITOR_DEFAULTTONULL);\r
1490            if (hMon)\r
1491            {\r
1492                    // only restore the window position if the monitor is valid\r
1493                    MoveWindow(app.wMain, LOWORD(DWORD(pos)), HIWORD(DWORD(pos)),\r
1494                            LOWORD(DWORD(width)), HIWORD(DWORD(width)), FALSE);\r
1495            }\r
1496    }\r
1497    if (DWORD(state) == SW_MAXIMIZE)\r
1498            ShowWindow(app.wMain, SW_MAXIMIZE);\r
1499    else\r
1500            ShowWindow(app.wMain, nCmdShow);\r
1501    UpdateWindow(app.wMain);\r
1502 \r
1503    //Create the tooltips\r
1504 \r
1505    INITCOMMONCONTROLSEX iccex; \r
1506    app.hwndTT;                 // handle to the ToolTip control\r
1507    TOOLINFO ti;\r
1508    RECT rect;                  // for client area coordinates\r
1509    iccex.dwICC = ICC_WIN95_CLASSES;\r
1510    iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);\r
1511    InitCommonControlsEx(&iccex);\r
1512 \r
1513    /* CREATE A TOOLTIP WINDOW */\r
1514    app.hwndTT = CreateWindowEx(WS_EX_TOPMOST,\r
1515            TOOLTIPS_CLASS,\r
1516            NULL,\r
1517            WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,             \r
1518            CW_USEDEFAULT,\r
1519            CW_USEDEFAULT,\r
1520            CW_USEDEFAULT,\r
1521            CW_USEDEFAULT,\r
1522            app.wBlame,\r
1523            NULL,\r
1524            app.hResource,\r
1525            NULL\r
1526            );\r
1527 \r
1528    SetWindowPos(app.hwndTT,\r
1529            HWND_TOPMOST,\r
1530            0,\r
1531            0,\r
1532            0,\r
1533            0,\r
1534            SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);\r
1535 \r
1536    /* GET COORDINATES OF THE MAIN CLIENT AREA */\r
1537    GetClientRect (app.wBlame, &rect);\r
1538 \r
1539    /* INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE */\r
1540    ti.cbSize = sizeof(TOOLINFO);\r
1541    ti.uFlags = TTF_TRACK | TTF_ABSOLUTE;//TTF_SUBCLASS | TTF_PARSELINKS;\r
1542    ti.hwnd = app.wBlame;\r
1543    ti.hinst = app.hResource;\r
1544    ti.uId = 0;\r
1545    ti.lpszText = LPSTR_TEXTCALLBACK;\r
1546    // ToolTip control will cover the whole window\r
1547    ti.rect.left = rect.left;    \r
1548    ti.rect.top = rect.top;\r
1549    ti.rect.right = rect.right;\r
1550    ti.rect.bottom = rect.bottom;\r
1551 \r
1552    /* SEND AN ADDTOOL MESSAGE TO THE TOOLTIP CONTROL WINDOW */\r
1553    SendMessage(app.hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);  \r
1554    SendMessage(app.hwndTT, TTM_SETMAXTIPWIDTH, 0, 600);\r
1555    //SendMessage(app.hwndTT, TTM_SETDELAYTIME, TTDT_AUTOPOP, MAKELONG(50000, 0));\r
1556    //SendMessage(app.hwndTT, TTM_SETDELAYTIME, TTDT_RESHOW, MAKELONG(1000, 0));\r
1557    \r
1558    uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);\r
1559    \r
1560    return TRUE;\r
1561 }\r
1562 #endif\r
1563 void CTortoiseGitBlameView::InitSize()\r
1564 {\r
1565     RECT rc;\r
1566     RECT blamerc;\r
1567     RECT sourcerc;\r
1568     ::GetClientRect(wMain, &rc);\r
1569     ::SetWindowPos(wHeader, 0, rc.left, rc.top, rc.right-rc.left, HEADER_HEIGHT, 0);\r
1570     rc.top += HEADER_HEIGHT;\r
1571     blamerc.left = rc.left;\r
1572     blamerc.top = rc.top;\r
1573         LONG w = GetBlameWidth();\r
1574     blamerc.right = w > abs(rc.right - rc.left) ? rc.right : w + rc.left;\r
1575     blamerc.bottom = rc.bottom;\r
1576     sourcerc.left = blamerc.right;\r
1577     sourcerc.top = rc.top;\r
1578     sourcerc.bottom = rc.bottom;\r
1579     sourcerc.right = rc.right;\r
1580         if (m_colorage)\r
1581         {\r
1582                 ::OffsetRect(&blamerc, LOCATOR_WIDTH, 0);\r
1583                 ::OffsetRect(&sourcerc, LOCATOR_WIDTH, 0);\r
1584                 sourcerc.right -= LOCATOR_WIDTH;\r
1585         }\r
1586         ::InvalidateRect(wMain, NULL, FALSE);\r
1587     ::SetWindowPos(wEditor, 0, sourcerc.left, sourcerc.top, sourcerc.right - sourcerc.left, sourcerc.bottom - sourcerc.top, 0);\r
1588         ::SetWindowPos(wBlame, 0, blamerc.left, blamerc.top, blamerc.right - blamerc.left, blamerc.bottom - blamerc.top, 0);\r
1589         if (m_colorage)\r
1590                 ::SetWindowPos(wLocator, 0, 0, blamerc.top, LOCATOR_WIDTH, blamerc.bottom - blamerc.top, SWP_SHOWWINDOW);\r
1591         else\r
1592                 ::ShowWindow(wLocator, SW_HIDE);\r
1593 }\r
1594 \r
1595 #if 0\r
1596 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
1597 {\r
1598         if (message == uFindReplaceMsg)\r
1599         {\r
1600                 LPFINDREPLACE lpfr = (LPFINDREPLACE)lParam;\r
1601 \r
1602                 // If the FR_DIALOGTERM flag is set, \r
1603                 // invalidate the handle identifying the dialog box. \r
1604                 if (lpfr->Flags & FR_DIALOGTERM)\r
1605                 {\r
1606                         app.currentDialog = NULL; \r
1607                         return 0; \r
1608                 } \r
1609                 if (lpfr->Flags & FR_FINDNEXT)\r
1610                 {\r
1611                         app.DoSearch(lpfr->lpstrFindWhat, lpfr->Flags);\r
1612                 }\r
1613                 return 0; \r
1614         }\r
1615         switch (message) \r
1616         {\r
1617         case WM_CREATE:\r
1618                 app.wEditor = ::CreateWindow(\r
1619                         "Scintilla",\r
1620                         "Source",\r
1621                         WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN,\r
1622                         0, 0,\r
1623                         100, 100,\r
1624                         hWnd,\r
1625                         0,\r
1626                         app.hResource,\r
1627                         0);\r
1628                 app.InitialiseEditor();\r
1629                 ::ShowWindow(app.wEditor, SW_SHOW);\r
1630                 ::SetFocus(app.wEditor);\r
1631                 app.wBlame = ::CreateWindow(\r
1632                         _T("TortoiseGitBlameViewBlame"), \r
1633                         _T("blame"), \r
1634                         WS_CHILD | WS_CLIPCHILDREN,\r
1635                         CW_USEDEFAULT, 0, \r
1636                         CW_USEDEFAULT, 0, \r
1637                         hWnd, \r
1638                         NULL, \r
1639                         app.hResource, \r
1640                         NULL);\r
1641                 ::ShowWindow(app.wBlame, SW_SHOW);\r
1642                 app.wHeader = ::CreateWindow(\r
1643                         _T("TortoiseGitBlameViewHeader"), \r
1644                         _T("header"), \r
1645                         WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,\r
1646                         CW_USEDEFAULT, 0, \r
1647                         CW_USEDEFAULT, 0, \r
1648                         hWnd, \r
1649                         NULL, \r
1650                         app.hResource, \r
1651                         NULL);\r
1652                 ::ShowWindow(app.wHeader, SW_SHOW);\r
1653                 app.wLocator = ::CreateWindow(\r
1654                         _T("TortoiseGitBlameViewLocator"), \r
1655                         _T("locator"), \r
1656                         WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,\r
1657                         CW_USEDEFAULT, 0, \r
1658                         CW_USEDEFAULT, 0, \r
1659                         hWnd, \r
1660                         NULL, \r
1661                         app.hResource, \r
1662                         NULL);\r
1663                 ::ShowWindow(app.wLocator, SW_SHOW);\r
1664                 return 0;\r
1665 \r
1666         case WM_SIZE:\r
1667                 if (wParam != 1) \r
1668                 {\r
1669             app.InitSize();\r
1670                 }\r
1671                 return 0;\r
1672 \r
1673         case WM_COMMAND:\r
1674                 app.Command(LOWORD(wParam));\r
1675                 break;\r
1676         case WM_NOTIFY:\r
1677                 app.Notify(reinterpret_cast<SCNotification *>(lParam));\r
1678                 return 0;\r
1679         case WM_DESTROY:\r
1680                 PostQuitMessage(0);\r
1681                 break;\r
1682         case WM_CLOSE:\r
1683                 {\r
1684                         CRegStdWORD pos(_T("Software\\TortoiseGit\\TBlamePos"), 0);\r
1685                         CRegStdWORD width(_T("Software\\TortoiseGit\\TBlameSize"), 0);\r
1686                         CRegStdWORD state(_T("Software\\TortoiseGit\\TBlameState"), 0);\r
1687                         RECT rc;\r
1688                         GetWindowRect(app.wMain, &rc);\r
1689                         if ((rc.left >= 0)&&(rc.top >= 0))\r
1690                         {\r
1691                                 pos = MAKELONG(rc.left, rc.top);\r
1692                                 width = MAKELONG(rc.right-rc.left, rc.bottom-rc.top);\r
1693                         }\r
1694                         WINDOWPLACEMENT wp = {0};\r
1695                         wp.length = sizeof(WINDOWPLACEMENT);\r
1696                         GetWindowPlacement(app.wMain, &wp);\r
1697                         state = wp.showCmd;\r
1698                         ::DestroyWindow(app.wEditor);\r
1699                         ::PostQuitMessage(0);\r
1700                 }\r
1701                 return 0;\r
1702         case WM_SETFOCUS:\r
1703                 ::SetFocus(app.wBlame);\r
1704                 break;\r
1705         default:\r
1706                 return DefWindowProc(hWnd, message, wParam, lParam);\r
1707         }\r
1708         return 0;\r
1709 }\r
1710 \r
1711 LRESULT CALLBACK WndBlameProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
1712 {\r
1713         PAINTSTRUCT ps;\r
1714         TRACKMOUSEEVENT mevt;\r
1715         HDC hDC;\r
1716         switch (message) \r
1717         {\r
1718         case WM_CREATE:\r
1719                 return 0;\r
1720         case WM_PAINT:\r
1721                 hDC = BeginPaint(app.wBlame, &ps);\r
1722                 app.DrawBlame(hDC);\r
1723                 EndPaint(app.wBlame, &ps);\r
1724                 break;\r
1725         case WM_COMMAND:\r
1726                 app.Command(LOWORD(wParam));\r
1727                 break;\r
1728         case WM_NOTIFY:\r
1729                 switch (((LPNMHDR)lParam)->code)\r
1730                 {\r
1731                 case TTN_GETDISPINFO:\r
1732                         {\r
1733                                 LPNMHDR pNMHDR = (LPNMHDR)lParam;\r
1734                                 NMTTDISPINFOA* pTTTA = (NMTTDISPINFOA*)pNMHDR;\r
1735                                 NMTTDISPINFOW* pTTTW = (NMTTDISPINFOW*)pNMHDR;\r
1736                                 POINT point;\r
1737                                 DWORD ptW = GetMessagePos();\r
1738                                 point.x = GET_X_LPARAM(ptW);\r
1739                                 point.y = GET_Y_LPARAM(ptW);\r
1740                                 ::ScreenToClient(app.wBlame, &point);\r
1741                                 LONG_PTR line = app.SendEditor(SCI_GETFIRSTVISIBLELINE);\r
1742                                 LONG_PTR height = app.SendEditor(SCI_TEXTHEIGHT);\r
1743                                 line = line + (point.y/height);\r
1744                                 if (line >= (LONG)app.revs.size())\r
1745                                         break;\r
1746                                 if (line < 0)\r
1747                                         break;\r
1748                                 LONG rev = app.revs[line];\r
1749                                 if (line >= (LONG)app.revs.size())\r
1750                                         break;\r
1751 \r
1752                                 SecureZeroMemory(app.m_szTip, sizeof(app.m_szTip));\r
1753                                 SecureZeroMemory(app.m_wszTip, sizeof(app.m_wszTip));\r
1754                                 std::map<LONG, CString>::iterator iter;\r
1755                                 if ((iter = app.logmessages.find(rev)) != app.logmessages.end())\r
1756                                 {\r
1757                                         CString msg;\r
1758                                         if (!ShowAuthor)\r
1759                                         {\r
1760                                                 msg += app.authors[line];\r
1761                                         }\r
1762                                         if (!ShowDate)\r
1763                                         {\r
1764                                                 if (!ShowAuthor) msg += "  ";\r
1765                                                 msg += app.dates[line];\r
1766                                         }\r
1767                                         if (!ShowAuthor || !ShowDate)\r
1768                                                 msg += '\n';\r
1769                                         msg += iter->second;\r
1770                                         // an empty tooltip string will deactivate the tooltips,\r
1771                                         // which means we must make sure that the tooltip won't\r
1772                                         // be empty.\r
1773                                         if (msg.empty())\r
1774                                                 msg = _T(" ");\r
1775                                         if (pNMHDR->code == TTN_NEEDTEXTA)\r
1776                                         {\r
1777                                                 lstrcpyn(app.m_szTip, msg.c_str(), MAX_LOG_LENGTH*2);\r
1778                                                 app.StringExpand(app.m_szTip);\r
1779                                                 pTTTA->lpszText = app.m_szTip;\r
1780                                         }\r
1781                                         else\r
1782                                         {\r
1783                                                 pTTTW->lpszText = app.m_wszTip;\r
1784                                                 ::MultiByteToWideChar( CP_ACP , 0, msg.c_str(), min(msg.size(), MAX_LOG_LENGTH*2), app.m_wszTip, MAX_LOG_LENGTH*2);\r
1785                                                 app.StringExpand(app.m_wszTip);\r
1786                                         }\r
1787                                 }\r
1788                         }\r
1789                         break;\r
1790                 }\r
1791                 return 0;\r
1792         case WM_DESTROY:\r
1793                 break;\r
1794         case WM_CLOSE:\r
1795                 return 0;\r
1796         case WM_MOUSELEAVE:\r
1797                 app.m_mouserev = -2;\r
1798                 app.m_mouseauthor.clear();\r
1799                 app.ttVisible = FALSE;\r
1800                 SendMessage(app.hwndTT, TTM_TRACKACTIVATE, FALSE, 0);\r
1801                 ::InvalidateRect(app.wBlame, NULL, FALSE);\r
1802                 break;\r
1803         case WM_MOUSEMOVE:\r
1804                 {\r
1805                         mevt.cbSize = sizeof(TRACKMOUSEEVENT);\r
1806                         mevt.dwFlags = TME_LEAVE;\r
1807                         mevt.dwHoverTime = HOVER_DEFAULT;\r
1808                         mevt.hwndTrack = app.wBlame;\r
1809                         ::TrackMouseEvent(&mevt);\r
1810                         POINT pt = {((int)(short)LOWORD(lParam)), ((int)(short)HIWORD(lParam))};\r
1811                         ClientToScreen(app.wBlame, &pt);\r
1812                         pt.x += 15;\r
1813                         pt.y += 15;\r
1814                         SendMessage(app.hwndTT, TTM_TRACKPOSITION, 0, MAKELONG(pt.x, pt.y));\r
1815                         if (!app.ttVisible)\r
1816                         {\r
1817                                 TOOLINFO ti;\r
1818                                 ti.cbSize = sizeof(TOOLINFO);\r
1819                                 ti.hwnd = app.wBlame;\r
1820                                 ti.uId = 0;\r
1821                                 SendMessage(app.hwndTT, TTM_TRACKACTIVATE, TRUE, (LPARAM)&ti);\r
1822                         }\r
1823                         int y = ((int)(short)HIWORD(lParam));\r
1824                         LONG_PTR line = app.SendEditor(SCI_GETFIRSTVISIBLELINE);\r
1825                         LONG_PTR height = app.SendEditor(SCI_TEXTHEIGHT);\r
1826                         line = line + (y/height);\r
1827                         app.ttVisible = (line < (LONG)app.revs.size());\r
1828                         if ( app.ttVisible )\r
1829                         {\r
1830                                 if (app.authors[line].compare(app.m_mouseauthor) != 0)\r
1831                                 {\r
1832                                         app.m_mouseauthor = app.authors[line];\r
1833                                 }\r
1834                                 if (app.revs[line] != app.m_mouserev)\r
1835                                 {\r
1836                                         app.m_mouserev = app.revs[line];\r
1837                                         ::InvalidateRect(app.wBlame, NULL, FALSE);\r
1838                                         SendMessage(app.hwndTT, TTM_UPDATE, 0, 0);\r
1839                                 }\r
1840                         }\r
1841                 }\r
1842                 break;\r
1843         case WM_RBUTTONDOWN:\r
1844                 // fall through\r
1845         case WM_LBUTTONDOWN:\r
1846                 {\r
1847                         int y = ((int)(short)HIWORD(lParam));\r
1848                         LONG_PTR line = app.SendEditor(SCI_GETFIRSTVISIBLELINE);\r
1849                         LONG_PTR height = app.SendEditor(SCI_TEXTHEIGHT);\r
1850                         line = line + (y/height);\r
1851                         if (line < (LONG)app.revs.size())\r
1852                         {\r
1853                                 app.SetSelectedLine(line);\r
1854                                 if (app.revs[line] != app.m_selectedrev)\r
1855                                 {\r
1856                                         app.m_selectedrev = app.revs[line];\r
1857                                         app.m_selectedorigrev = app.origrevs[line];\r
1858                                         app.m_selectedauthor = app.authors[line];\r
1859                                         app.m_selecteddate = app.dates[line];\r
1860                                 }\r
1861                                 else\r
1862                                 {\r
1863                                         app.m_selectedauthor.clear();\r
1864                                         app.m_selecteddate.clear();\r
1865                                         app.m_selectedrev = -2;\r
1866                                         app.m_selectedorigrev = -2;\r
1867                                 }\r
1868                                 ::InvalidateRect(app.wBlame, NULL, FALSE);\r
1869                         }\r
1870                         else\r
1871                         {\r
1872                                 app.SetSelectedLine(-1);\r
1873                         }\r
1874                 }\r
1875                 break;\r
1876         case WM_SETFOCUS:\r
1877                 ::SetFocus(app.wBlame);\r
1878                 app.SendEditor(SCI_GRABFOCUS);\r
1879                 break;\r
1880         case WM_CONTEXTMENU:\r
1881                 {\r
1882                         if (app.m_selectedrev <= 0)\r
1883                                 break;;\r
1884                         int xPos = GET_X_LPARAM(lParam);\r
1885                         int yPos = GET_Y_LPARAM(lParam);\r
1886                         if ((xPos < 0)||(yPos < 0))\r
1887                         {\r
1888                                 // requested from keyboard, not mouse pointer\r
1889                                 // use the center of the window\r
1890                                 RECT rect;\r
1891                                 GetClientRect(app.wBlame, &rect);\r
1892                                 xPos = rect.right-rect.left;\r
1893                                 yPos = rect.bottom-rect.top;\r
1894                         }\r
1895                         HMENU hMenu = LoadMenu(app.hResource, MAKEINTRESOURCE(IDR_BLAMEPOPUP));\r
1896                         HMENU hPopMenu = GetSubMenu(hMenu, 0);\r
1897 \r
1898                         if ( _tcslen(szOrigPath)==0 )\r
1899                         {\r
1900                                 // Without knowing the original path we cannot blame the previous revision\r
1901                                 // because we don't know which filename to pass to tortoiseproc.\r
1902                                 EnableMenuItem(hPopMenu,ID_BLAME_PREVIOUS_REVISION, MF_DISABLED|MF_GRAYED);\r
1903                         }\r
1904                         \r
1905                         TrackPopupMenu(hPopMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, xPos, yPos, 0, app.wBlame, NULL); \r
1906                         DestroyMenu(hMenu);\r
1907                 }\r
1908                 break;\r
1909         default:\r
1910                 return DefWindowProc(hWnd, message, wParam, lParam);\r
1911         }\r
1912         return 0;\r
1913 }\r
1914 \r
1915 LRESULT CALLBACK WndHeaderProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
1916 {\r
1917         PAINTSTRUCT ps;\r
1918         HDC hDC;\r
1919         switch (message) \r
1920         {\r
1921         case WM_CREATE:\r
1922                 return 0;\r
1923         case WM_PAINT:\r
1924                 hDC = BeginPaint(app.wHeader, &ps);\r
1925                 app.DrawHeader(hDC);\r
1926                 EndPaint(app.wHeader, &ps);\r
1927                 break;\r
1928         case WM_COMMAND:\r
1929                 break;\r
1930         case WM_DESTROY:\r
1931                 break;\r
1932         case WM_CLOSE:\r
1933                 return 0;\r
1934         default:\r
1935                 return DefWindowProc(hWnd, message, wParam, lParam);\r
1936         }\r
1937         return 0;\r
1938 }\r
1939 \r
1940 LRESULT CALLBACK WndLocatorProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
1941 {\r
1942         PAINTSTRUCT ps;\r
1943         HDC hDC;\r
1944         switch (message) \r
1945         {\r
1946         case WM_PAINT:\r
1947                 hDC = BeginPaint(app.wLocator, &ps);\r
1948                 app.DrawLocatorBar(hDC);\r
1949                 EndPaint(app.wLocator, &ps);\r
1950                 break;\r
1951         case WM_LBUTTONDOWN:\r
1952         case WM_MOUSEMOVE:\r
1953                 if (wParam & MK_LBUTTON)\r
1954                 {\r
1955                         RECT rect;\r
1956                         ::GetClientRect(hWnd, &rect); \r
1957                         int nLine = HIWORD(lParam)*app.revs.size()/(rect.bottom-rect.top);\r
1958 \r
1959                         if (nLine < 0)\r
1960                                 nLine = 0;\r
1961                         app.ScrollToLine(nLine);\r
1962                 }\r
1963                 break;\r
1964         default:\r
1965                 return DefWindowProc(hWnd, message, wParam, lParam);\r
1966         }\r
1967         return 0;\r
1968 }\r
1969 #endif\r
1970 \r
1971 void CTortoiseGitBlameView::SetupLexer(LPCSTR filename)\r
1972 {\r
1973 #if 0\r
1974         char line[20];\r
1975         const char * lineptr = _tcsrchr(filename, '.');\r
1976 \r
1977         if (lineptr)\r
1978         {\r
1979                 _tcscpy_s(line, 20, lineptr+1);\r
1980                 _tcslwr_s(line, 20);\r
1981                 if ((_tcscmp(line, _T("py"))==0)||\r
1982                         (_tcscmp(line, _T("pyw"))==0)||\r
1983                         (_tcscmp(line, _T("pyw"))==0))\r
1984                 {\r
1985                         SendEditor(SCI_SETLEXER, SCLEX_PYTHON);\r
1986                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("and assert break class continue def del elif \\r
1987 else except exec finally for from global if import in is lambda None \\r
1988 not or pass print raise return try while yield"));\r
1989                         SetAStyle(SCE_P_DEFAULT, black);\r
1990                         SetAStyle(SCE_P_COMMENTLINE, darkGreen);\r
1991                         SetAStyle(SCE_P_NUMBER, RGB(0, 0x80, 0x80));\r
1992                         SetAStyle(SCE_P_STRING, RGB(0, 0, 0x80));\r
1993                         SetAStyle(SCE_P_CHARACTER, RGB(0, 0, 0x80));\r
1994                         SetAStyle(SCE_P_WORD, RGB(0x80, 0, 0x80));\r
1995                         SetAStyle(SCE_P_TRIPLE, black);\r
1996                         SetAStyle(SCE_P_TRIPLEDOUBLE, black);\r
1997                         SetAStyle(SCE_P_CLASSNAME, darkBlue);\r
1998                         SetAStyle(SCE_P_DEFNAME, darkBlue);\r
1999                         SetAStyle(SCE_P_OPERATOR, darkBlue);\r
2000                         SetAStyle(SCE_P_IDENTIFIER, darkBlue);\r
2001                         SetAStyle(SCE_P_COMMENTBLOCK, darkGreen);\r
2002                         SetAStyle(SCE_P_STRINGEOL, red);\r
2003                 }\r
2004                 if ((_tcscmp(line, _T("c"))==0)||\r
2005                         (_tcscmp(line, _T("cc"))==0)||\r
2006                         (_tcscmp(line, _T("cpp"))==0)||\r
2007                         (_tcscmp(line, _T("cxx"))==0)||\r
2008                         (_tcscmp(line, _T("h"))==0)||\r
2009                         (_tcscmp(line, _T("hh"))==0)||\r
2010                         (_tcscmp(line, _T("hpp"))==0)||\r
2011                         (_tcscmp(line, _T("hxx"))==0)||\r
2012                         (_tcscmp(line, _T("dlg"))==0)||\r
2013                         (_tcscmp(line, _T("mak"))==0))\r
2014                 {\r
2015                         SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2016                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("and and_eq asm auto bitand bitor bool break \\r
2017 case catch char class compl const const_cast continue \\r
2018 default delete do double dynamic_cast else enum explicit export extern false float for \\r
2019 friend goto if inline int long mutable namespace new not not_eq \\r
2020 operator or or_eq private protected public \\r
2021 register reinterpret_cast return short signed sizeof static static_cast struct switch \\r
2022 template this throw true try typedef typeid typename union unsigned using \\r
2023 virtual void volatile wchar_t while xor xor_eq"));\r
2024                         SendEditor(SCI_SETKEYWORDS, 3, (LPARAM)_T("a addindex addtogroup anchor arg attention \\r
2025 author b brief bug c class code date def defgroup deprecated dontinclude \\r
2026 e em endcode endhtmlonly endif endlatexonly endlink endverbatim enum example exception \\r
2027 f$ f[ f] file fn hideinitializer htmlinclude htmlonly \\r
2028 if image include ingroup internal invariant interface latexonly li line link \\r
2029 mainpage name namespace nosubgrouping note overload \\r
2030 p page par param post pre ref relates remarks return retval \\r
2031 sa section see showinitializer since skip skipline struct subsection \\r
2032 test throw todo typedef union until \\r
2033 var verbatim verbinclude version warning weakgroup $ @ \\ & < > # { }"));\r
2034                         SetupCppLexer();\r
2035                 }\r
2036                 if (_tcscmp(line, _T("cs"))==0)\r
2037                 {\r
2038                         SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2039                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("abstract as base bool break byte case catch char checked class \\r
2040 const continue decimal default delegate do double else enum \\r
2041 event explicit extern false finally fixed float for foreach goto if \\r
2042 implicit in int interface internal is lock long namespace new null \\r
2043 object operator out override params private protected public \\r
2044 readonly ref return sbyte sealed short sizeof stackalloc static \\r
2045 string struct switch this throw true try typeof uint ulong \\r
2046 unchecked unsafe ushort using virtual void while"));\r
2047                         SetupCppLexer();\r
2048                 }\r
2049                 if ((_tcscmp(line, _T("rc"))==0)||\r
2050                         (_tcscmp(line, _T("rc2"))==0))\r
2051                 {\r
2052                         SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2053                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("ACCELERATORS ALT AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON \\r
2054 BEGIN BITMAP BLOCK BUTTON CAPTION CHARACTERISTICS CHECKBOX CLASS \\r
2055 COMBOBOX CONTROL CTEXT CURSOR DEFPUSHBUTTON DIALOG DIALOGEX DISCARDABLE \\r
2056 EDITTEXT END EXSTYLE FONT GROUPBOX ICON LANGUAGE LISTBOX LTEXT \\r
2057 MENU MENUEX MENUITEM MESSAGETABLE POPUP \\r
2058 PUSHBUTTON RADIOBUTTON RCDATA RTEXT SCROLLBAR SEPARATOR SHIFT STATE3 \\r
2059 STRINGTABLE STYLE TEXTINCLUDE VALUE VERSION VERSIONINFO VIRTKEY"));\r
2060                         SetupCppLexer();\r
2061                 }\r
2062                 if ((_tcscmp(line, _T("idl"))==0)||\r
2063                         (_tcscmp(line, _T("odl"))==0))\r
2064                 {\r
2065                         SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2066                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("aggregatable allocate appobject arrays async async_uuid \\r
2067 auto_handle \\r
2068 bindable boolean broadcast byte byte_count \\r
2069 call_as callback char coclass code comm_status \\r
2070 const context_handle context_handle_noserialize \\r
2071 context_handle_serialize control cpp_quote custom \\r
2072 decode default defaultbind defaultcollelem \\r
2073 defaultvalue defaultvtable dispinterface displaybind dllname \\r
2074 double dual \\r
2075 enable_allocate encode endpoint entry enum error_status_t \\r
2076 explicit_handle \\r
2077 fault_status first_is float \\r
2078 handle_t heap helpcontext helpfile helpstring \\r
2079 helpstringcontext helpstringdll hidden hyper \\r
2080 id idempotent ignore iid_as iid_is immediatebind implicit_handle \\r
2081 import importlib in include in_line int __int64 __int3264 interface \\r
2082 last_is lcid length_is library licensed local long \\r
2083 max_is maybe message methods midl_pragma \\r
2084 midl_user_allocate midl_user_free min_is module ms_union \\r
2085 ncacn_at_dsp ncacn_dnet_nsp ncacn_http ncacn_ip_tcp \\r
2086 ncacn_nb_ipx ncacn_nb_nb ncacn_nb_tcp ncacn_np \\r
2087 ncacn_spx ncacn_vns_spp ncadg_ip_udp ncadg_ipx ncadg_mq \\r
2088 ncalrpc nocode nonbrowsable noncreatable nonextensible notify \\r
2089 object odl oleautomation optimize optional out out_of_line \\r
2090 pipe pointer_default pragma properties propget propput propputref \\r
2091 ptr public \\r
2092 range readonly ref represent_as requestedit restricted retval \\r
2093 shape short signed size_is small source strict_context_handle \\r
2094 string struct switch switch_is switch_type \\r
2095 transmit_as typedef \\r
2096 uidefault union unique unsigned user_marshal usesgetlasterror uuid \\r
2097 v1_enum vararg version void wchar_t wire_marshal"));\r
2098                         SetupCppLexer();\r
2099                 }\r
2100                 if (_tcscmp(line, _T("java"))==0)\r
2101                 {\r
2102                         SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2103                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("abstract assert boolean break byte case catch char class \\r
2104 const continue default do double else extends final finally float for future \\r
2105 generic goto if implements import inner instanceof int interface long \\r
2106 native new null outer package private protected public rest \\r
2107 return short static super switch synchronized this throw throws \\r
2108 transient try var void volatile while"));\r
2109                         SetupCppLexer();\r
2110                 }\r
2111                 if (_tcscmp(line, _T("js"))==0)\r
2112                 {\r
2113                         SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2114                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("abstract boolean break byte case catch char class \\r
2115 const continue debugger default delete do double else enum export extends \\r
2116 final finally float for function goto if implements import in instanceof \\r
2117 int interface long native new package private protected public \\r
2118 return short static super switch synchronized this throw throws \\r
2119 transient try typeof var void volatile while with"));\r
2120                         SetupCppLexer();\r
2121                 }\r
2122                 if ((_tcscmp(line, _T("pas"))==0)||\r
2123                         (_tcscmp(line, _T("dpr"))==0)||\r
2124                         (_tcscmp(line, _T("pp"))==0))\r
2125                 {\r
2126                         SendEditor(SCI_SETLEXER, SCLEX_PASCAL);\r
2127                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("and array as begin case class const constructor \\r
2128 destructor div do downto else end except file finally \\r
2129 for function goto if implementation in inherited \\r
2130 interface is mod not object of on or packed \\r
2131 procedure program property raise record repeat \\r
2132 set shl shr then threadvar to try type unit \\r
2133 until uses var while with xor"));\r
2134                         SetupCppLexer();\r
2135                 }\r
2136                 if ((_tcscmp(line, _T("as"))==0)||\r
2137                         (_tcscmp(line, _T("asc"))==0)||\r
2138                         (_tcscmp(line, _T("jsfl"))==0))\r
2139                 {\r
2140                         SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2141                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("add and break case catch class continue default delete do \\r
2142 dynamic else eq extends false finally for function ge get gt if implements import in \\r
2143 instanceof interface intrinsic le lt ne new not null or private public return \\r
2144 set static super switch this throw true try typeof undefined var void while with"));\r
2145                         SendEditor(SCI_SETKEYWORDS, 1, (LPARAM)_T("Array Arguments Accessibility Boolean Button Camera Color \\r
2146 ContextMenu ContextMenuItem Date Error Function Key LoadVars LocalConnection Math \\r
2147 Microphone Mouse MovieClip MovieClipLoader NetConnection NetStream Number Object \\r
2148 PrintJob Selection SharedObject Sound Stage String StyleSheet System TextField \\r
2149 TextFormat TextSnapshot Video Void XML XMLNode XMLSocket \\r
2150 _accProps _focusrect _global _highquality _parent _quality _root _soundbuftime \\r
2151 arguments asfunction call capabilities chr clearInterval duplicateMovieClip \\r
2152 escape eval fscommand getProperty getTimer getURL getVersion gotoAndPlay gotoAndStop \\r
2153 ifFrameLoaded Infinity -Infinity int isFinite isNaN length loadMovie loadMovieNum \\r
2154 loadVariables loadVariablesNum maxscroll mbchr mblength mbord mbsubstring MMExecute \\r
2155 NaN newline nextFrame nextScene on onClipEvent onUpdate ord parseFloat parseInt play \\r
2156 prevFrame prevScene print printAsBitmap printAsBitmapNum printNum random removeMovieClip \\r
2157 scroll set setInterval setProperty startDrag stop stopAllSounds stopDrag substring \\r
2158 targetPath tellTarget toggleHighQuality trace unescape unloadMovie unLoadMovieNum updateAfterEvent"));\r
2159                         SetupCppLexer();\r
2160                 }\r
2161                 if ((_tcscmp(line, _T("html"))==0)||\r
2162                         (_tcscmp(line, _T("htm"))==0)||\r
2163                         (_tcscmp(line, _T("shtml"))==0)||\r
2164                         (_tcscmp(line, _T("htt"))==0)||\r
2165                         (_tcscmp(line, _T("xml"))==0)||\r
2166                         (_tcscmp(line, _T("asp"))==0)||\r
2167                         (_tcscmp(line, _T("xsl"))==0)||\r
2168                         (_tcscmp(line, _T("php"))==0)||\r
2169                         (_tcscmp(line, _T("xhtml"))==0)||\r
2170                         (_tcscmp(line, _T("phtml"))==0)||\r
2171                         (_tcscmp(line, _T("cfm"))==0)||\r
2172                         (_tcscmp(line, _T("tpl"))==0)||\r
2173                         (_tcscmp(line, _T("dtd"))==0)||\r
2174                         (_tcscmp(line, _T("hta"))==0)||\r
2175                         (_tcscmp(line, _T("htd"))==0)||\r
2176                         (_tcscmp(line, _T("wxs"))==0))\r
2177                 {\r
2178                         SendEditor(SCI_SETLEXER, SCLEX_HTML);\r
2179                         SendEditor(SCI_SETSTYLEBITS, 7);\r
2180                         SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)_T("a abbr acronym address applet area b base basefont \\r
2181 bdo big blockquote body br button caption center \\r
2182 cite code col colgroup dd del dfn dir div dl dt em \\r
2183 fieldset font form frame frameset h1 h2 h3 h4 h5 h6 \\r
2184 head hr html i iframe img input ins isindex kbd label \\r
2185 legend li link map menu meta noframes noscript \\r
2186 object ol optgroup option p param pre q s samp \\r
2187 script select small span strike strong style sub sup \\r
2188 table tbody td textarea tfoot th thead title tr tt u ul \\r
2189 var xml xmlns abbr accept-charset accept accesskey action align alink \\r
2190 alt archive axis background bgcolor border \\r
2191 cellpadding cellspacing char charoff charset checked cite \\r
2192 class classid clear codebase codetype color cols colspan \\r
2193 compact content coords \\r
2194 data datafld dataformatas datapagesize datasrc datetime \\r
2195 declare defer dir disabled enctype event \\r
2196 face for frame frameborder \\r
2197 headers height href hreflang hspace http-equiv \\r
2198 id ismap label lang language leftmargin link longdesc \\r
2199 marginwidth marginheight maxlength media method multiple \\r
2200 name nohref noresize noshade nowrap \\r
2201 object onblur onchange onclick ondblclick onfocus \\r
2202 onkeydown onkeypress onkeyup onload onmousedown \\r
2203 onmousemove onmouseover onmouseout onmouseup \\r
2204 onreset onselect onsubmit onunload \\r
2205 profile prompt readonly rel rev rows rowspan rules \\r
2206 scheme scope selected shape size span src standby start style \\r
2207 summary tabindex target text title topmargin type usemap \\r
2208 valign value valuetype version vlink vspace width \\r
2209 text password checkbox radio submit reset \\r
2210 file hidden image"));\r
2211                         SendEditor(SCI_SETKEYWORDS, 1, (LPARAM)_T("assign audio block break catch choice clear disconnect else elseif \\r
2212 emphasis enumerate error exit field filled form goto grammar help \\r
2213 if initial link log menu meta noinput nomatch object option p paragraph \\r
2214 param phoneme prompt property prosody record reprompt return s say-as \\r
2215 script sentence subdialog submit throw transfer value var voice vxml"));\r
2216                         SendEditor(SCI_SETKEYWORDS, 2, (LPARAM)_T("accept age alphabet anchor application base beep bridge category charset \\r
2217 classid cond connecttimeout content contour count dest destexpr dtmf dtmfterm \\r
2218 duration enctype event eventexpr expr expritem fetchtimeout finalsilence \\r
2219 gender http-equiv id level maxage maxstale maxtime message messageexpr \\r
2220 method mime modal mode name namelist next nextitem ph pitch range rate \\r
2221 scope size sizeexpr skiplist slot src srcexpr sub time timeexpr timeout \\r
2222 transferaudio type value variant version volume xml:lang"));\r
2223                         SendEditor(SCI_SETKEYWORDS, 3, (LPARAM)_T("and assert break class continue def del elif \\r
2224 else except exec finally for from global if import in is lambda None \\r
2225 not or pass print raise return try while yield"));\r
2226                         SendEditor(SCI_SETKEYWORDS, 4, (LPARAM)_T("and argv as argc break case cfunction class continue declare default do \\r
2227 die echo else elseif empty enddeclare endfor endforeach endif endswitch \\r
2228 endwhile e_all e_parse e_error e_warning eval exit extends false for \\r
2229 foreach function global http_cookie_vars http_get_vars http_post_vars \\r
2230 http_post_files http_env_vars http_server_vars if include include_once \\r
2231 list new not null old_function or parent php_os php_self php_version \\r
2232 print require require_once return static switch stdclass this true var \\r
2233 xor virtual while __file__ __line__ __sleep __wakeup"));\r
2234 \r
2235                         SetAStyle(SCE_H_TAG, darkBlue);\r
2236                         SetAStyle(SCE_H_TAGUNKNOWN, red);\r
2237                         SetAStyle(SCE_H_ATTRIBUTE, darkBlue);\r
2238                         SetAStyle(SCE_H_ATTRIBUTEUNKNOWN, red);\r
2239                         SetAStyle(SCE_H_NUMBER, RGB(0x80,0,0x80));\r
2240                         SetAStyle(SCE_H_DOUBLESTRING, RGB(0,0x80,0));\r
2241                         SetAStyle(SCE_H_SINGLESTRING, RGB(0,0x80,0));\r
2242                         SetAStyle(SCE_H_OTHER, RGB(0x80,0,0x80));\r
2243                         SetAStyle(SCE_H_COMMENT, RGB(0x80,0x80,0));\r
2244                         SetAStyle(SCE_H_ENTITY, RGB(0x80,0,0x80));\r
2245 \r
2246                         SetAStyle(SCE_H_TAGEND, darkBlue);\r
2247                         SetAStyle(SCE_H_XMLSTART, darkBlue);    // <?\r
2248                         SetAStyle(SCE_H_QUESTION, darkBlue);    // <?\r
2249                         SetAStyle(SCE_H_XMLEND, darkBlue);              // ?>\r
2250                         SetAStyle(SCE_H_SCRIPT, darkBlue);              // <script\r
2251                         SetAStyle(SCE_H_ASP, RGB(0x4F, 0x4F, 0), RGB(0xFF, 0xFF, 0));   // <% ... %>\r
2252                         SetAStyle(SCE_H_ASPAT, RGB(0x4F, 0x4F, 0), RGB(0xFF, 0xFF, 0)); // <%@ ... %>\r
2253 \r
2254                         SetAStyle(SCE_HB_DEFAULT, black);\r
2255                         SetAStyle(SCE_HB_COMMENTLINE, darkGreen);\r
2256                         SetAStyle(SCE_HB_NUMBER, RGB(0,0x80,0x80));\r
2257                         SetAStyle(SCE_HB_WORD, darkBlue);\r
2258                         SendEditor(SCI_STYLESETBOLD, SCE_HB_WORD, 1);\r
2259                         SetAStyle(SCE_HB_STRING, RGB(0x80,0,0x80));\r
2260                         SetAStyle(SCE_HB_IDENTIFIER, black);\r
2261 \r
2262                         // This light blue is found in the windows system palette so is safe to use even in 256 colour modes.\r
2263                         // Show the whole section of VBScript with light blue background\r
2264                         for (int bstyle=SCE_HB_DEFAULT; bstyle<=SCE_HB_STRINGEOL; bstyle++) {\r
2265                                 SendEditor(SCI_STYLESETFONT, bstyle, \r
2266                                         reinterpret_cast<LPARAM>("Lucida Console"));\r
2267                                 SendEditor(SCI_STYLESETBACK, bstyle, lightBlue);\r
2268                                 // This call extends the backround colour of the last style on the line to the edge of the window\r
2269                                 SendEditor(SCI_STYLESETEOLFILLED, bstyle, 1);\r
2270                         }\r
2271                         SendEditor(SCI_STYLESETBACK, SCE_HB_STRINGEOL, RGB(0x7F,0x7F,0xFF));\r
2272                         SendEditor(SCI_STYLESETFONT, SCE_HB_COMMENTLINE, \r
2273                                 reinterpret_cast<LPARAM>("Lucida Console"));\r
2274 \r
2275                         SetAStyle(SCE_HBA_DEFAULT, black);\r
2276                         SetAStyle(SCE_HBA_COMMENTLINE, darkGreen);\r
2277                         SetAStyle(SCE_HBA_NUMBER, RGB(0,0x80,0x80));\r
2278                         SetAStyle(SCE_HBA_WORD, darkBlue);\r
2279                         SendEditor(SCI_STYLESETBOLD, SCE_HBA_WORD, 1);\r
2280                         SetAStyle(SCE_HBA_STRING, RGB(0x80,0,0x80));\r
2281                         SetAStyle(SCE_HBA_IDENTIFIER, black);\r
2282 \r
2283                         // Show the whole section of ASP VBScript with bright yellow background\r
2284                         for (int bastyle=SCE_HBA_DEFAULT; bastyle<=SCE_HBA_STRINGEOL; bastyle++) {\r
2285                                 SendEditor(SCI_STYLESETFONT, bastyle, \r
2286                                         reinterpret_cast<LPARAM>("Lucida Console"));\r
2287                                 SendEditor(SCI_STYLESETBACK, bastyle, RGB(0xFF, 0xFF, 0));\r
2288                                 // This call extends the backround colour of the last style on the line to the edge of the window\r
2289                                 SendEditor(SCI_STYLESETEOLFILLED, bastyle, 1);\r
2290                         }\r
2291                         SendEditor(SCI_STYLESETBACK, SCE_HBA_STRINGEOL, RGB(0xCF,0xCF,0x7F));\r
2292                         SendEditor(SCI_STYLESETFONT, SCE_HBA_COMMENTLINE, \r
2293                                 reinterpret_cast<LPARAM>("Lucida Console"));\r
2294 \r
2295                         // If there is no need to support embedded Javascript, the following code can be dropped.\r
2296                         // Javascript will still be correctly processed but will be displayed in just the default style.\r
2297 \r
2298                         SetAStyle(SCE_HJ_START, RGB(0x80,0x80,0));\r
2299                         SetAStyle(SCE_HJ_DEFAULT, black);\r
2300                         SetAStyle(SCE_HJ_COMMENT, darkGreen);\r
2301                         SetAStyle(SCE_HJ_COMMENTLINE, darkGreen);\r
2302                         SetAStyle(SCE_HJ_COMMENTDOC, darkGreen);\r
2303                         SetAStyle(SCE_HJ_NUMBER, RGB(0,0x80,0x80));\r
2304                         SetAStyle(SCE_HJ_WORD, black);\r
2305                         SetAStyle(SCE_HJ_KEYWORD, darkBlue);\r
2306                         SetAStyle(SCE_HJ_DOUBLESTRING, RGB(0x80,0,0x80));\r
2307                         SetAStyle(SCE_HJ_SINGLESTRING, RGB(0x80,0,0x80));\r
2308                         SetAStyle(SCE_HJ_SYMBOLS, black);\r
2309 \r
2310                         SetAStyle(SCE_HJA_START, RGB(0x80,0x80,0));\r
2311                         SetAStyle(SCE_HJA_DEFAULT, black);\r
2312                         SetAStyle(SCE_HJA_COMMENT, darkGreen);\r
2313                         SetAStyle(SCE_HJA_COMMENTLINE, darkGreen);\r
2314                         SetAStyle(SCE_HJA_COMMENTDOC, darkGreen);\r
2315                         SetAStyle(SCE_HJA_NUMBER, RGB(0,0x80,0x80));\r
2316                         SetAStyle(SCE_HJA_WORD, black);\r
2317                         SetAStyle(SCE_HJA_KEYWORD, darkBlue);\r
2318                         SetAStyle(SCE_HJA_DOUBLESTRING, RGB(0x80,0,0x80));\r
2319                         SetAStyle(SCE_HJA_SINGLESTRING, RGB(0x80,0,0x80));\r
2320                         SetAStyle(SCE_HJA_SYMBOLS, black);\r
2321 \r
2322                         SetAStyle(SCE_HPHP_DEFAULT, black);\r
2323                         SetAStyle(SCE_HPHP_HSTRING,  RGB(0x80,0,0x80));\r
2324                         SetAStyle(SCE_HPHP_SIMPLESTRING,  RGB(0x80,0,0x80));\r
2325                         SetAStyle(SCE_HPHP_WORD, darkBlue);\r
2326                         SetAStyle(SCE_HPHP_NUMBER, RGB(0,0x80,0x80));\r
2327                         SetAStyle(SCE_HPHP_VARIABLE, red);\r
2328                         SetAStyle(SCE_HPHP_HSTRING_VARIABLE, red);\r
2329                         SetAStyle(SCE_HPHP_COMPLEX_VARIABLE, red);\r
2330                         SetAStyle(SCE_HPHP_COMMENT, darkGreen);\r
2331                         SetAStyle(SCE_HPHP_COMMENTLINE, darkGreen);\r
2332                         SetAStyle(SCE_HPHP_OPERATOR, darkBlue);\r
2333 \r
2334                         // Show the whole section of Javascript with off white background\r
2335                         for (int jstyle=SCE_HJ_DEFAULT; jstyle<=SCE_HJ_SYMBOLS; jstyle++) {\r
2336                                 SendEditor(SCI_STYLESETFONT, jstyle, \r
2337                                         reinterpret_cast<LPARAM>("Lucida Console"));\r
2338                                 SendEditor(SCI_STYLESETBACK, jstyle, offWhite);\r
2339                                 SendEditor(SCI_STYLESETEOLFILLED, jstyle, 1);\r
2340                         }\r
2341                         SendEditor(SCI_STYLESETBACK, SCE_HJ_STRINGEOL, RGB(0xDF, 0xDF, 0x7F));\r
2342                         SendEditor(SCI_STYLESETEOLFILLED, SCE_HJ_STRINGEOL, 1);\r
2343 \r
2344                         // Show the whole section of Javascript with brown background\r
2345                         for (int jastyle=SCE_HJA_DEFAULT; jastyle<=SCE_HJA_SYMBOLS; jastyle++) {\r
2346                                 SendEditor(SCI_STYLESETFONT, jastyle, \r
2347                                         reinterpret_cast<LPARAM>("Lucida Console"));\r
2348                                 SendEditor(SCI_STYLESETBACK, jastyle, RGB(0xDF, 0xDF, 0x7F));\r
2349                                 SendEditor(SCI_STYLESETEOLFILLED, jastyle, 1);\r
2350                         }\r
2351                         SendEditor(SCI_STYLESETBACK, SCE_HJA_STRINGEOL, RGB(0x0,0xAF,0x5F));\r
2352                         SendEditor(SCI_STYLESETEOLFILLED, SCE_HJA_STRINGEOL, 1);\r
2353                 }\r
2354         }\r
2355         else\r
2356         {\r
2357                 SendEditor(SCI_SETLEXER, SCLEX_CPP);\r
2358                 SetupCppLexer();\r
2359         }\r
2360         SendEditor(SCI_COLOURISE, 0, -1);\r
2361 #endif\r
2362 }\r
2363 \r
2364 void CTortoiseGitBlameView::SetupCppLexer()\r
2365 {\r
2366         SetAStyle(SCE_C_DEFAULT, RGB(0, 0, 0));\r
2367         SetAStyle(SCE_C_COMMENT, RGB(0, 0x80, 0));\r
2368         SetAStyle(SCE_C_COMMENTLINE, RGB(0, 0x80, 0));\r
2369         SetAStyle(SCE_C_COMMENTDOC, RGB(0, 0x80, 0));\r
2370         SetAStyle(SCE_C_COMMENTLINEDOC, RGB(0, 0x80, 0));\r
2371         SetAStyle(SCE_C_COMMENTDOCKEYWORD, RGB(0, 0x80, 0));\r
2372         SetAStyle(SCE_C_COMMENTDOCKEYWORDERROR, RGB(0, 0x80, 0));\r
2373         SetAStyle(SCE_C_NUMBER, RGB(0, 0x80, 0x80));\r
2374         SetAStyle(SCE_C_WORD, RGB(0, 0, 0x80));\r
2375         SendEditor(SCE_C_WORD, 1);\r
2376         SetAStyle(SCE_C_STRING, RGB(0x80, 0, 0x80));\r
2377         SetAStyle(SCE_C_IDENTIFIER, RGB(0, 0, 0));\r
2378         SetAStyle(SCE_C_PREPROCESSOR, RGB(0x80, 0, 0));\r
2379         SetAStyle(SCE_C_OPERATOR, RGB(0x80, 0x80, 0));\r
2380 }\r