OSDN Git Service

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