OSDN Git Service

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