OSDN Git Service

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