OSDN Git Service

TortoiseGitBlame Add Next and Previous Function when choose one commit
[tortoisegit/TortoiseGitJp.git] / src / TortoiseGitBlame / TortoiseGitBlameView.cpp
index 98283f2..105f1ef 100644 (file)
@@ -27,6 +27,7 @@
 #include "MainFrm.h"\r
 #include "Balloon.h"\r
 #include "EditGotoDlg.h"\r
+#include "TortoiseGitBlameAppUtils.h"\r
 \r
 #ifdef _DEBUG\r
 #define new DEBUG_NEW\r
@@ -45,6 +46,9 @@ BEGIN_MESSAGE_MAP(CTortoiseGitBlameView, CView)
        ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CTortoiseGitBlameView::OnFilePrintPreview)\r
        ON_COMMAND(ID_EDIT_FIND,OnEditFind)\r
        ON_COMMAND(ID_EDIT_GOTO,OnEditGoto)\r
+       ON_COMMAND(ID_EDIT_COPY,CopySelectedLogToClipboard)\r
+       ON_COMMAND(ID_VIEW_NEXT,OnViewNext)\r
+       ON_COMMAND(ID_VIEW_PREV,OnViewPrev)\r
        ON_WM_CREATE()\r
        ON_WM_SIZE()\r
        ON_WM_MOUSEMOVE()\r
@@ -104,6 +108,17 @@ CTortoiseGitBlameView::CTortoiseGitBlameView()
        m_bShowDate=false;\r
 \r
     m_FindDialogMessage   =   ::RegisterWindowMessage(FINDMSGSTRING);   \r
+       m_pFindDialog = NULL;\r
+       // get short/long datetime setting from registry\r
+       DWORD RegUseShortDateFormat = CRegDWORD(_T("Software\\TortoiseGit\\LogDateFormat"), TRUE);\r
+       if ( RegUseShortDateFormat )\r
+       {\r
+               m_DateFormat = DATE_SHORTDATE;\r
+       }\r
+       else\r
+       {\r
+               m_DateFormat = DATE_LONGDATE;\r
+       }\r
 }\r
 \r
 CTortoiseGitBlameView::~CTortoiseGitBlameView()\r
@@ -134,7 +149,9 @@ int CTortoiseGitBlameView::OnCreate(LPCREATESTRUCT lpcs)
        m_ToolTip.Create(this->GetParent());    \r
        m_ToolTip.AddTool(this,_T("Test"));\r
        \r
+       ::AfxGetApp()->GetMainWnd();\r
        return CView::OnCreate(lpcs);\r
+       \r
 }\r
 \r
 void CTortoiseGitBlameView::OnSize(UINT nType,int cx, int cy)\r
@@ -593,7 +610,7 @@ void CTortoiseGitBlameView::InitialiseEditor()
 \r
 void CTortoiseGitBlameView::StartSearch()\r
 {\r
-       if (currentDialog)\r
+       if (m_pFindDialog)\r
                return;\r
        bool bCase = false;\r
        // Initialize FINDREPLACE\r
@@ -610,87 +627,53 @@ void CTortoiseGitBlameView::StartSearch()
        currentDialog = FindText(&fr);\r
 }\r
 \r
-bool CTortoiseGitBlameView::DoSearch(LPSTR what, DWORD flags)\r
+bool CTortoiseGitBlameView::DoSearch(CString what, DWORD flags)\r
 {\r
-#if 0\r
-       TCHAR szWhat[80];\r
+\r
+       //char szWhat[80];\r
        int pos = SendEditor(SCI_GETCURRENTPOS);\r
        int line = SendEditor(SCI_LINEFROMPOSITION, pos);\r
        bool bFound = false;\r
        bool bCaseSensitive = !!(flags & FR_MATCHCASE);\r
 \r
-       strcpy_s(szWhat, sizeof(szWhat), what);\r
+       //strcpy_s(szWhat, sizeof(szWhat), what);\r
 \r
        if(!bCaseSensitive)\r
        {\r
-               char *p;\r
-               size_t len = strlen(szWhat);\r
-               for (p = szWhat; p < szWhat + len; p++)\r
-               {\r
-                       if (isupper(*p)&&__isascii(*p))\r
-                               *p = _tolower(*p);\r
-               }\r
+               what=what.MakeLower();\r
        }\r
 \r
-       CString sWhat = CString(szWhat);\r
+       //CString sWhat = CString(szWhat);\r
        \r
-       char buf[20];\r
-       int i=0;\r
-       for (i=line; (i<(int)authors.size())&&(!bFound); ++i)\r
+       //char buf[20];\r
+       //int i=0;\r
+       int i=line;\r
+       do\r
        {\r
                int bufsize = SendEditor(SCI_GETLINE, i);\r
                char * linebuf = new char[bufsize+1];\r
                SecureZeroMemory(linebuf, bufsize+1);\r
                SendEditor(SCI_GETLINE, i, (LPARAM)linebuf);\r
+               CString oneline=this->m_TextView.StringFromControl(linebuf);\r
                if (!bCaseSensitive)\r
                {\r
-                       char *p;\r
-                       for (p = linebuf; p < linebuf + bufsize; p++)\r
-                       {\r
-                               if (isupper(*p)&&__isascii(*p))\r
-                                       *p = _tolower(*p);\r
-                       }\r
+                       oneline=oneline.MakeLower();\r
                }\r
-               _stprintf_s(buf, 20, _T("%ld"), revs[i]);\r
-               if (authors[i].compare(sWhat)==0)\r
+               //_stprintf_s(buf, 20, _T("%ld"), revs[i]);\r
+               if (this->m_Authors[i].Find(what)>=0)\r
                        bFound = true;\r
-               else if ((!bCaseSensitive)&&(_stricmp(authors[i].c_str(), szWhat)==0))\r
+               else if ((!bCaseSensitive)&&(this->m_Authors[i].MakeLower().Find(what)>=0))\r
                        bFound = true;\r
-               else if (strcmp(buf, szWhat) == 0)\r
-                       bFound = true;\r
-               else if (strstr(linebuf, szWhat))\r
+               else if (oneline.Find(what) >=0)\r
                        bFound = true;\r
+               \r
                delete [] linebuf;\r
-       }\r
-       if (!bFound)\r
-       {\r
-               for (i=0; (i<line)&&(!bFound); ++i)\r
-               {\r
-                       int bufsize = SendEditor(SCI_GETLINE, i);\r
-                       char * linebuf = new char[bufsize+1];\r
-                       SecureZeroMemory(linebuf, bufsize+1);\r
-                       SendEditor(SCI_GETLINE, i, (LPARAM)linebuf);\r
-                       if (!bCaseSensitive)\r
-                       {\r
-                               char *p;\r
-                               for (p = linebuf; p < linebuf + bufsize; p++)\r
-                               {\r
-                                       if (isupper(*p)&&__isascii(*p))\r
-                                               *p = _tolower(*p);\r
-                               }\r
-                       }\r
-                       _stprintf_s(buf, 20, _T("%ld"), revs[i]);\r
-                       if (authors[i].compare(sWhat)==0)\r
-                               bFound = true;\r
-                       else if ((!bCaseSensitive)&&(_stricmp(authors[i].c_str(), szWhat)==0))\r
-                               bFound = true;\r
-                       else if (strcmp(buf, szWhat) == 0)\r
-                               bFound = true;\r
-                       else if (strstr(linebuf, szWhat))\r
-                               bFound = true;\r
-                       delete [] linebuf;\r
-               }\r
-       }\r
+\r
+               i++;\r
+               if(i>=(signed int)m_CommitHash.size())\r
+                       i=0;\r
+       }while(i!=line &&(!bFound));\r
+\r
        if (bFound)\r
        {\r
                GotoLine(i);\r
@@ -702,9 +685,9 @@ bool CTortoiseGitBlameView::DoSearch(LPSTR what, DWORD flags)
        }\r
        else\r
        {\r
-               ::MessageBox(wMain, searchstringnotfound, "CTortoiseGitBlameView", MB_ICONINFORMATION);\r
+               ::MessageBox(wMain, what+_T(" not found"), _T("CTortoiseGitBlameView"), MB_ICONINFORMATION);\r
        }\r
-#endif\r
+\r
        return true;\r
 }\r
 \r
@@ -764,33 +747,7 @@ bool CTortoiseGitBlameView::ScrollToLine(long line)
 \r
 void CTortoiseGitBlameView::CopySelectedLogToClipboard()\r
 {\r
-#if 0\r
-       if (m_selectedrev <= 0)\r
-               return;\r
-       std::map<LONG, CString>::iterator iter;\r
-       if ((iter = app.logmessages.find(m_selectedrev)) != app.logmessages.end())\r
-       {\r
-               CString msg;\r
-               msg += m_selectedauthor;\r
-               msg += "  ";\r
-               msg += app.m_selecteddate;\r
-               msg += '\n';\r
-               msg += iter->second;\r
-               msg += _T("\n");\r
-               if (OpenClipboard(app.wBlame))\r
-               {\r
-                       EmptyClipboard();\r
-                       HGLOBAL hClipboardData;\r
-                       hClipboardData = GlobalAlloc(GMEM_DDESHARE, msg.size()+1);\r
-                       char * pchData;\r
-                       pchData = (char*)GlobalLock(hClipboardData);\r
-                       strcpy_s(pchData, msg.size()+1, msg.c_str());\r
-                       GlobalUnlock(hClipboardData);\r
-                       SetClipboardData(CF_TEXT,hClipboardData);\r
-                       CloseClipboard();\r
-               }\r
-       }\r
-#endif\r
+       this->GetLogList()->CopySelectionToClipBoard(FALSE);\r
 }\r
 \r
 void CTortoiseGitBlameView::BlamePreviousRevision()\r
@@ -1004,15 +961,6 @@ void CTortoiseGitBlameView::Command(int id)
 #endif\r
 }\r
 \r
-void CTortoiseGitBlameView::GotoLineDlg()\r
-{\r
-#if 0\r
-       if (DialogBox(hResource, MAKEINTRESOURCE(IDD_GOTODLG), wMain, GotoDlgProc)==IDOK)\r
-       {\r
-               GotoLine(m_gotoline);\r
-       }\r
-#endif\r
-}\r
 \r
 LONG CTortoiseGitBlameView::GetBlameWidth()\r
 {\r
@@ -1023,13 +971,9 @@ LONG CTortoiseGitBlameView::GetBlameWidth()
        HFONT oldfont = (HFONT)::SelectObject(hDC, m_font);\r
        \r
        TCHAR buf[MAX_PATH];\r
-       //_stprintf_s(buf, MAX_PATH, _T("%8ld "), 88888888);\r
-       //::GetTextExtentPoint(hDC, buf, _tcslen(buf), &width);\r
-       //m_revwidth = width.cx + BLAMESPACE;\r
-       //blamewidth += m_revwidth;\r
 \r
        int maxnum=0;\r
-       for (int i=0;i<this->m_Authors.size();i++)\r
+       for (unsigned int i=0;i<this->m_ID.size();i++)\r
        {\r
                if(m_ID[i]>maxnum)\r
                        maxnum=m_ID[i];\r
@@ -1057,7 +1001,7 @@ LONG CTortoiseGitBlameView::GetBlameWidth()
        {\r
                SIZE maxwidth = {0};\r
 \r
-               for (int i=0;i<this->m_Authors.size();i++)\r
+               for (unsigned int i=0;i<this->m_Authors.size();i++)\r
                //for (std::vector<CString>::iterator I = authors.begin(); I != authors.end(); ++I)\r
                {\r
                        ::GetTextExtentPoint32(hDC,m_Authors[i] , m_Authors[i].GetLength(), &width);\r
@@ -1165,7 +1109,8 @@ void CTortoiseGitBlameView::DrawBlame(HDC hDC)
                        //}\r
 \r
                        CString str;\r
-                       str.Format(_T("%d"),m_ID[i]);\r
+                       if(m_ID[i]>=0)\r
+                               str.Format(_T("%d"),m_ID[i]);\r
 \r
                        //_stprintf_s(buf, MAX_PATH, _T("%8ld       "), revs[i]);\r
                        rc.top=Y;\r
@@ -1201,7 +1146,7 @@ void CTortoiseGitBlameView::DrawBlame(HDC hDC)
                                Left += m_authorwidth;\r
                        }\r
 #endif\r
-                       if ((i==m_SelectedLine)&&(currentDialog))\r
+                       if ((i==m_SelectedLine)&&(m_pFindDialog))\r
                        {\r
                                LOGBRUSH brush;\r
                                brush.lbColor = m_textcolor;\r
@@ -2470,6 +2415,8 @@ void CTortoiseGitBlameView::UpdateInfo()
        CString &data = GetDocument()->m_BlameData;\r
        CString one;\r
        int pos=0;\r
+       \r
+       BYTE_VECTOR vector;\r
 \r
        CLogDataVector * pRevs= GetLogData();\r
 \r
@@ -2500,14 +2447,30 @@ void CTortoiseGitBlameView::UpdateInfo()
                        line=one.Right(one.GetLength()-start-2);\r
                        this->m_TextView.InsertText(line,true);\r
                }\r
-               int id=pRevs->m_HashMap[one.Left(40)];          \r
-               if(id>=0 && id <GetLogData()->size())\r
+               int id;\r
+               if(pRevs->m_HashMap.find(one.Left(40))!=pRevs->m_HashMap.end())\r
+               {\r
+                       id=pRevs->m_HashMap[one.Left(40)];      \r
+               }\r
+               else\r
+               {\r
+                       id=-1;\r
+                       if(this->m_NoListCommit.find(one.Left(40)) == m_NoListCommit.end() )\r
+                       {\r
+                               g_Git.GetLog(vector,one.Left(40),NULL,1);\r
+                               this->m_NoListCommit[one.Left(40)].ParserFromLog(vector);\r
+                       }\r
+                       \r
+               }\r
+\r
+               if(id>=0 && id <(int)GetLogData()->size())\r
                {\r
                        m_ID.push_back(pRevs->size()-id);\r
                        m_Authors.push_back(pRevs->at(id).m_AuthorName);\r
                }else\r
                {\r
-                       ASSERT(FALSE);\r
+                       m_ID.push_back(id);\r
+                       m_Authors.push_back(one.Left(6));\r
                }\r
        }\r
 \r
@@ -2563,25 +2526,24 @@ void CTortoiseGitBlameView::OnLButtonDown(UINT nFlags,CPoint point)
                if (m_CommitHash[line] != m_SelectedHash)\r
                {\r
                        m_SelectedHash = m_CommitHash[line];\r
-//                     app.m_selectedorigrev = app.origrevs[line];\r
-//                     app.m_selectedauthor = app.authors[line];\r
-//                     app.m_selecteddate = app.dates[line];\r
                        \r
-                       \r
-                       this->GetLogList()->SetItemState(this->GetLogList()->GetItemCount()-m_ID[line],\r
+                       if(m_ID[line]>=0)\r
+                       {\r
+                               this->GetLogList()->SetItemState(this->GetLogList()->GetItemCount()-m_ID[line],\r
                                                                                                                        LVIS_SELECTED,\r
                                                                                                                        LVIS_SELECTED);\r
 \r
-                       GitRev *pRev;\r
-                       pRev=&this->GetLogData()->at(this->GetLogList()->GetItemCount()-m_ID[line]);\r
-                       this->GetDocument()->GetMainFrame()->m_wndProperties.UpdateProperties(pRev);\r
+                               GitRev *pRev;\r
+                               pRev=&this->GetLogData()->at(this->GetLogList()->GetItemCount()-m_ID[line]);\r
+                               this->GetDocument()->GetMainFrame()->m_wndProperties.UpdateProperties(pRev);\r
+                       }else\r
+                       {\r
+                               this->GetDocument()->GetMainFrame()->m_wndProperties.UpdateProperties(&m_NoListCommit[m_CommitHash[line]]);\r
+                       }\r
                }\r
                else\r
                {\r
                        m_SelectedHash.Empty();\r
-//                     app.m_selecteddate.clear();\r
-//                     app.m_selectedrev = -2;\r
-//                     app.m_selectedorigrev = -2;\r
                }\r
                //::InvalidateRect( NULL, FALSE);\r
                this->Invalidate();\r
@@ -2620,6 +2582,14 @@ void CTortoiseGitBlameView::FocusOn(GitRev *pRev)
        this->GetDocument()->GetMainFrame()->m_wndProperties.UpdateProperties(pRev);\r
 \r
        this->Invalidate();\r
+\r
+       int i;\r
+       for(i=0;i<m_CommitHash.size();i++)\r
+       {\r
+               if( pRev->m_CommitHash == m_CommitHash[i] )\r
+                       break;\r
+       }\r
+       this->GotoLine(i);\r
        this->m_TextView.Invalidate();\r
 \r
 }\r
@@ -2636,27 +2606,26 @@ void CTortoiseGitBlameView::OnMouseHover(UINT nFlags, CPoint point)
                if (line != m_MouseLine)\r
                {\r
                        m_MouseLine = line;//m_CommitHash[line];\r
-//                     app.m_selectedorigrev = app.origrevs[line];\r
-//                     app.m_selectedauthor = app.authors[line];\r
-//                     app.m_selecteddate = app.dates[line];\r
-                       \r
-                       \r
                        GitRev *pRev;\r
-                       pRev=&this->GetLogData()->at(this->GetLogList()->GetItemCount()-m_ID[line]);\r
-                       //this->GetDocument()->GetMainFrame()->m_wndProperties.UpdateProperties(pRev);\r
+                       if(m_ID[line]<0)\r
+                       {\r
+                               pRev=&this->m_NoListCommit[m_CommitHash[line]];\r
+\r
+                       }else\r
+                       {\r
+                               pRev=&this->GetLogData()->at(this->GetLogList()->GetItemCount()-m_ID[line]);\r
+                       }\r
+\r
                        this->ClientToScreen(&point);\r
-                       //BALLOON_INFO bi;\r
-                       //if(m_ToolTip.GetTool(this, bi))\r
-                       //{\r
-                       //      bi.sBalloonTip=pRev->m_CommitHash;\r
-                               CString str;\r
-                               str.Format(_T("%s\n<b>%s</b>\n%s\n%s"),pRev->m_CommitHash,\r
+\r
+                       CString str;\r
+                       str.Format(_T("%s\n<b>%s</b>\n%s %s\n%s"),pRev->m_CommitHash,\r
                                                                                                           pRev->m_Subject,\r
-                                                                                                          pRev->m_AuthorDate.Format(_T("%Y-%m-%d %H:%M")),\r
+                                                                                                          pRev->m_AuthorName,\r
+                                                                                                          CAppUtils::FormatDateAndTime( pRev->m_AuthorDate, m_DateFormat ), \r
                                                                                                           pRev->m_Body);\r
-                               m_ToolTip.AddTool(this,str);\r
-                               m_ToolTip.DisplayToolTip(&point);\r
-                       //}\r
+                       m_ToolTip.AddTool(this,str);\r
+                       m_ToolTip.DisplayToolTip(&point);\r
        \r
                        CRect rect;\r
                        this->ScreenToClient(&point);\r
@@ -2670,19 +2639,8 @@ void CTortoiseGitBlameView::OnMouseHover(UINT nFlags, CPoint point)
                else\r
                {\r
                        m_MouseLine=-1;\r
-//                     app.m_selecteddate.clear();\r
-//                     app.m_selectedrev = -2;\r
-//                     app.m_selectedorigrev = -2;\r
                }\r
-               //::InvalidateRect( NULL, FALSE);\r
-               //this->Invalidate();\r
        }\r
-       \r
-//      const CString str=_T("this is a <b>Message Balloon</b>\n<hr=100%>\n<ct=0x0000FF>Warning! Warning!</ct>\nSomething unexpected happened");\r
-        //CBalloon::ShowBalloon(NULL, point, \r
-         //            str,\r
-         //             FALSE, (HICON)IDI_EXCLAMATION,\r
-               //                 (UINT)CBalloon ::BALLOON_RIGHT_TOP, (UINT)CBalloon ::BALLOON_EFFECT_SOLID,(COLORREF)NULL,  (COLORREF)NULL,  (COLORREF)NULL);\r
 }\r
 \r
 void CTortoiseGitBlameView::OnMouseMove(UINT nFlags, CPoint point)\r
@@ -2705,6 +2663,7 @@ BOOL CTortoiseGitBlameView::PreTranslateMessage(MSG* pMsg)
 void CTortoiseGitBlameView::OnEditFind()\r
 {\r
     m_pFindDialog=new CFindReplaceDialog();\r
+       \r
     m_pFindDialog->Create(TRUE,_T(""),NULL,FR_DOWN,this);  \r
 }\r
 \r
@@ -2739,7 +2698,8 @@ LRESULT CTortoiseGitBlameView::OnFindDialogMessage(WPARAM   wParam,   LPARAM   l
         bool   bMatchCase   =   m_pFindDialog->MatchCase()   ==   TRUE;   \r
         bool   bMatchWholeWord   =   m_pFindDialog->MatchWholeWord()   ==   TRUE;   \r
         bool   bSearchDown   =   m_pFindDialog->SearchDown()   ==   TRUE;   \r
-\r
+               \r
+               DoSearch(FindName,m_pFindDialog->m_fr.Flags);\r
             //with   given   name   do   search   \r
     //        *FindWhatYouNeed(FindName,   bMatchCase,   bMatchWholeWord,   bSearchDown);   \r
     }   \r
@@ -2747,3 +2707,47 @@ LRESULT CTortoiseGitBlameView::OnFindDialogMessage(WPARAM   wParam,   LPARAM   l
     return   0;   \r
 }   \r
 \r
+void CTortoiseGitBlameView::OnViewNext()\r
+{\r
+       FindNextLine(this->m_SelectedHash,false);\r
+}\r
+void CTortoiseGitBlameView::OnViewPrev()\r
+{\r
+       FindNextLine(this->m_SelectedHash,true);\r
+}\r
+\r
+int CTortoiseGitBlameView::FindNextLine(CString CommitHash,bool bUpOrDown)\r
+{\r
+       LONG_PTR line = SendEditor(SCI_GETFIRSTVISIBLELINE);\r
+       LONG_PTR startline =line;\r
+       bool findNoMatch =false;\r
+       while(line>=0 && line<m_CommitHash.size())\r
+       {\r
+               if(m_CommitHash[line]!=CommitHash)\r
+               {\r
+                       findNoMatch=true;\r
+               }\r
+\r
+               if(m_CommitHash[line] == CommitHash && findNoMatch)\r
+               {\r
+                       if( line == startline+2 )\r
+                       {\r
+                               findNoMatch=false;\r
+                       }\r
+                       else\r
+                       {\r
+                               if( bUpOrDown )\r
+                               {\r
+                                       line=FindFirstLine(CommitHash,line);\r
+                               }\r
+                               SendEditor(SCI_LINESCROLL,0,line-startline-2);\r
+                               return line;\r
+                       }\r
+               }\r
+               if(bUpOrDown)\r
+                       line--;\r
+               else\r
+                       line++;\r
+       }\r
+       return -1;\r
+}
\ No newline at end of file