OSDN Git Service

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