OSDN Git Service

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