OSDN Git Service

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