From 54cc8bcc413df93c90b610a012a51e22a834115d Mon Sep 17 00:00:00 2001 From: Frank Li Date: Sat, 22 Nov 2008 15:59:38 +0800 Subject: [PATCH] Add TortoiseUDiff Code --- TortoiseProc/Commands/ShowCompareCommand.cpp | 5 +- TortoiseProc/LogDlg.cpp | 158 ++++++--- TortoiseProc/TortoiseProc.vcproj | 40 ++- TortoiseUDiff/FindBar.cpp | 97 ++++++ TortoiseUDiff/FindBar.h | 44 +++ TortoiseUDiff/MainWindow.cpp | 471 +++++++++++++++++++++++++++ TortoiseUDiff/MainWindow.h | 75 +++++ TortoiseUDiff/Readme.txt | 7 + TortoiseUDiff/TortoiseUDiff.cpp | 92 ++++++ TortoiseUDiff/TortoiseUDiff.h | 21 ++ TortoiseUDiff/TortoiseUDiff.ico | Bin 0 -> 67895 bytes TortoiseUDiff/TortoiseUDiff.rc | 173 ++++++++++ TortoiseUDiff/TortoiseUDiff.rc2 | 50 +++ TortoiseUDiff/TortoiseUDiff.vcproj | 467 ++++++++++++++++++++++++++ TortoiseUDiff/resource.h | 38 +++ TortoiseUDiff/stdafx.cpp | 5 + TortoiseUDiff/stdafx.h | 40 +++ 17 files changed, 1723 insertions(+), 60 deletions(-) create mode 100644 TortoiseUDiff/FindBar.cpp create mode 100644 TortoiseUDiff/FindBar.h create mode 100644 TortoiseUDiff/MainWindow.cpp create mode 100644 TortoiseUDiff/MainWindow.h create mode 100644 TortoiseUDiff/Readme.txt create mode 100644 TortoiseUDiff/TortoiseUDiff.cpp create mode 100644 TortoiseUDiff/TortoiseUDiff.h create mode 100644 TortoiseUDiff/TortoiseUDiff.ico create mode 100644 TortoiseUDiff/TortoiseUDiff.rc create mode 100644 TortoiseUDiff/TortoiseUDiff.rc2 create mode 100644 TortoiseUDiff/TortoiseUDiff.vcproj create mode 100644 TortoiseUDiff/resource.h create mode 100644 TortoiseUDiff/stdafx.cpp create mode 100644 TortoiseUDiff/stdafx.h diff --git a/TortoiseProc/Commands/ShowCompareCommand.cpp b/TortoiseProc/Commands/ShowCompareCommand.cpp index 1c1e913..f850ce4 100644 --- a/TortoiseProc/Commands/ShowCompareCommand.cpp +++ b/TortoiseProc/Commands/ShowCompareCommand.cpp @@ -18,11 +18,12 @@ // #include "StdAfx.h" #include "ShowCompareCommand.h" -#include "SVNDiff.h" +//#include "SVNDiff.h" bool ShowCompareCommand::Execute() { +#if 0 bool bRet = false; SVNDiff diff(NULL, hwndExplorer); @@ -53,4 +54,6 @@ bool ShowCompareCommand::Execute() bRet = diff.ShowCompare(url1, rev1, url2, rev2, pegrev, ignoreancestry, blame); return bRet; +#endif + return 0; } diff --git a/TortoiseProc/LogDlg.cpp b/TortoiseProc/LogDlg.cpp index b5678c3..553d5a9 100644 --- a/TortoiseProc/LogDlg.cpp +++ b/TortoiseProc/LogDlg.cpp @@ -3789,7 +3789,7 @@ void CLogDlg::UpdateLogInfoLabel() void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) { -#if 0 + int selIndex = m_LogList.GetSelectionMark(); if (selIndex < 0) return; // nothing selected, nothing to do with a context menu @@ -3812,12 +3812,15 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) m_bCancelled = FALSE; // calculate some information the context menu commands can use - CString pathURL = GetURLFromPath(m_path); +// CString pathURL = GetURLFromPath(m_path); + POSITION pos = m_LogList.GetFirstSelectedItemPosition(); int indexNext = m_LogList.GetNextSelectedItem(pos); if (indexNext < 0) return; - PLOGENTRYDATA pSelLogEntry = reinterpret_cast(m_arShownList.GetAt(indexNext)); + + GitRev* pSelLogEntry = reinterpret_cast(m_arShownList.GetAt(indexNext)); +#if 0 GitRev revSelected = pSelLogEntry->Rev; GitRev revPrevious = git_revnum_t(revSelected)-1; if ((pSelLogEntry->pArChangedPaths)&&(pSelLogEntry->pArChangedPaths->GetCount() <= 2)) @@ -3860,14 +3863,22 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) } } +#endif - + int FirstSelect=-1, LastSelect=-1; + pos = m_LogList.GetFirstSelectedItemPosition(); + FirstSelect = m_LogList.GetNextSelectedItem(pos); + while(pos) + { + LastSelect = m_LogList.GetNextSelectedItem(pos); + } //entry is selected, now show the popup menu CIconMenu popup; if (popup.CreatePopupMenu()) { if (m_LogList.GetSelectedCount() == 1) { +#if 0 if (!m_path.IsDirectory()) { if (m_hasWC) @@ -3885,6 +3896,7 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) popup.AppendMenu(MF_SEPARATOR, NULL); } else +#endif { if (m_hasWC) { @@ -3902,30 +3914,31 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) popup.AppendMenuIcon(ID_BLAMEWITHPREVIOUS, IDS_LOG_POPUP_BLAMEWITHPREVIOUS, IDI_BLAME); popup.AppendMenu(MF_SEPARATOR, NULL); } - if (!m_ProjectProperties.sWebViewerRev.IsEmpty()) - { - popup.AppendMenuIcon(ID_VIEWREV, IDS_LOG_POPUP_VIEWREV); - } - if (!m_ProjectProperties.sWebViewerPathRev.IsEmpty()) - { - popup.AppendMenuIcon(ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV); - } - if ((!m_ProjectProperties.sWebViewerPathRev.IsEmpty())|| - (!m_ProjectProperties.sWebViewerRev.IsEmpty())) - { - popup.AppendMenu(MF_SEPARATOR, NULL); - } - popup.AppendMenuIcon(ID_REPOBROWSE, IDS_LOG_BROWSEREPO, IDI_REPOBROWSE); - popup.AppendMenuIcon(ID_COPY, IDS_LOG_POPUP_COPY); - if (m_hasWC) - popup.AppendMenuIcon(ID_UPDATE, IDS_LOG_POPUP_UPDATE, IDI_UPDATE); +// if (!m_ProjectProperties.sWebViewerRev.IsEmpty()) +// { +// popup.AppendMenuIcon(ID_VIEWREV, IDS_LOG_POPUP_VIEWREV); +// } +// if (!m_ProjectProperties.sWebViewerPathRev.IsEmpty()) +// { +// popup.AppendMenuIcon(ID_VIEWPATHREV, IDS_LOG_POPUP_VIEWPATHREV); +// } +// if ((!m_ProjectProperties.sWebViewerPathRev.IsEmpty())|| +// (!m_ProjectProperties.sWebViewerRev.IsEmpty())) +// { +// popup.AppendMenu(MF_SEPARATOR, NULL); +// } + +// popup.AppendMenuIcon(ID_REPOBROWSE, IDS_LOG_BROWSEREPO, IDI_REPOBROWSE); +// popup.AppendMenuIcon(ID_COPY, IDS_LOG_POPUP_COPY); +// if (m_hasWC) +// popup.AppendMenuIcon(ID_UPDATE, IDS_LOG_POPUP_UPDATE, IDI_UPDATE); if (m_hasWC) popup.AppendMenuIcon(ID_REVERTTOREV, IDS_LOG_POPUP_REVERTTOREV, IDI_REVERT); if (m_hasWC) popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREV, IDI_REVERT); - if (m_hasWC) - popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREV, IDI_MERGE); +// if (m_hasWC) +// popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREV, IDI_MERGE); popup.AppendMenuIcon(ID_CHECKOUT, IDS_MENUCHECKOUT, IDI_CHECKOUT); popup.AppendMenuIcon(ID_EXPORT, IDS_MENUEXPORT, IDI_EXPORT); popup.AppendMenu(MF_SEPARATOR, NULL); @@ -3946,24 +3959,25 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) if (m_hasWC) { popup.AppendMenuIcon(ID_REVERTREV, IDS_LOG_POPUP_REVERTREVS, IDI_REVERT); - if (m_hasWC) - popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREVS, IDI_MERGE); +// if (m_hasWC) +// popup.AppendMenuIcon(ID_MERGEREV, IDS_LOG_POPUP_MERGEREVS, IDI_MERGE); bAddSeparator = true; } if (bAddSeparator) popup.AppendMenu(MF_SEPARATOR, NULL); } - - if ((selEntries.size() > 0)&&(bAllFromTheSameAuthor)) - { - popup.AppendMenuIcon(ID_EDITAUTHOR, IDS_LOG_POPUP_EDITAUTHOR); - } - if (m_LogList.GetSelectedCount() == 1) - { - popup.AppendMenuIcon(ID_EDITLOG, IDS_LOG_POPUP_EDITLOG); - popup.AppendMenuIcon(ID_REVPROPS, IDS_REPOBROWSE_SHOWREVPROP, IDI_PROPERTIES); // "Show Revision Properties" - popup.AppendMenu(MF_SEPARATOR, NULL); - } +#if 0 +// if ((selEntries.size() > 0)&&(bAllFromTheSameAuthor)) +// { +// popup.AppendMenuIcon(ID_EDITAUTHOR, IDS_LOG_POPUP_EDITAUTHOR); +// } +// if (m_LogList.GetSelectedCount() == 1) +// { +// popup.AppendMenuIcon(ID_EDITLOG, IDS_LOG_POPUP_EDITLOG); +// popup.AppendMenuIcon(ID_REVPROPS, IDS_REPOBROWSE_SHOWREVPROP, IDI_PROPERTIES); // "Show Revision Properties" +// popup.AppendMenu(MF_SEPARATOR, NULL); +// } +#endif if (m_LogList.GetSelectedCount() != 0) { popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD); @@ -3972,11 +3986,61 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); DialogEnableWindow(IDOK, FALSE); - SetPromptApp(&theApp); +// SetPromptApp(&theApp); theApp.DoWaitCursor(1); bool bOpenWith = false; + switch (cmd) { + case ID_GNUDIFF1: + { +// if (PromptShown()) +// { +// GitDiff diff(this, this->m_hWnd, true); +// diff.SetHEADPeg(m_LogRevision); +// diff.ShowUnifiedDiff(m_path, revPrevious, m_path, revSelected); +// } +// else +// CAppUtils::StartShowUnifiedDiff(m_hWnd, m_path, revPrevious, m_path, revSelected, GitRev(), m_LogRevision); + } + break; + + case ID_GNUDIFF2: + { +// if (PromptShown()) +// { +// GitDiff diff(this, this->m_hWnd, true); +// diff.SetHEADPeg(m_LogRevision); +// diff.ShowUnifiedDiff(m_path, revSelected2, m_path, revSelected); +// } +// else +// CAppUtils::StartShowUnifiedDiff(m_hWnd, m_path, revSelected2, m_path, revSelected, GitRev(), m_LogRevision); + } + break; + + case ID_COMPARETWO: + { + //GitRev * r1 = reinterpret_cast((*m_arShownList)[FirstSelect]); + //GitRev * r2 = reinterpret_cast((*m_arShownList)[LastSelect]); + //if (m_LogList.GetSelectedCount() > 2) + //{ + // r1 = revHighest; + // r2 = revLowest; + //} + //user clicked on the menu item "compare revisions" + //if (PromptShown()) + //{ + // GitDiff diff(this, m_hWnd, true); + // diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000)); + // diff.SetHEADPeg(m_LogRevision); + // diff.ShowCompare(CTGitPath(pathURL), r2, CTGitPath(pathURL), r1); + //} + //else + // CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), r2, CTGitPath(pathURL), r1, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000)); + } + break; + +#if 0 case ID_GNUDIFF1: { if (PromptShown()) @@ -3989,6 +4053,7 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) CAppUtils::StartShowUnifiedDiff(m_hWnd, m_path, revPrevious, m_path, revSelected, GitRev(), m_LogRevision); } break; + case ID_GNUDIFF2: { if (PromptShown()) @@ -4433,18 +4498,18 @@ void CLogDlg::ShowContextMenuForRevisions(CWnd* /*pWnd*/, CPoint point) ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT); } break; +#endif default: break; } // switch (cmd) theApp.DoWaitCursor(-1); EnableOKButton(); } // if (popup.CreatePopupMenu()) -#endif } void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point) { -#if 0 + int selIndex = m_ChangedFileListCtrl.GetSelectionMark(); if ((point.x == -1) && (point.y == -1)) { @@ -4464,8 +4529,10 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point) if (pos == NULL) return; // nothing is selected, get out of here - PLOGENTRYDATA pLogEntry = reinterpret_cast(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos))); - git_revnum_t rev1 = pLogEntry->Rev; + bool bOneRev = true; +#if 0 + GitRev * pLogEntry = reinterpret_cast(m_arShownList.GetAt(m_LogList.GetNextSelectedItem(pos))); + git_revnum_t rev1 = pLogEntry; git_revnum_t rev2 = rev1; bool bOneRev = true; if (pos) @@ -4544,7 +4611,7 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point) } } } - +#endif //entry is selected, now show the popup menu CIconMenu popup; if (popup.CreatePopupMenu()) @@ -4552,7 +4619,7 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point) bool bEntryAdded = false; if (m_ChangedFileListCtrl.GetSelectedCount() == 1) { - if ((!bOneRev)||(IsDiffPossible(changedlogpaths[0], rev1))) +// if ((!bOneRev)||(IsDiffPossible(changedlogpaths[0], rev1))) { popup.AppendMenuIcon(ID_DIFF, IDS_LOG_POPUP_DIFF, IDI_DIFF); popup.AppendMenuIcon(ID_BLAMEDIFF, IDS_LOG_POPUP_BLAMEDIFF, IDI_BLAME); @@ -4560,7 +4627,7 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point) popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF); bEntryAdded = true; } - if (rev2 == rev1-1) +// if (rev2 == rev1-1) { if (bEntryAdded) popup.AppendMenu(MF_SEPARATOR, NULL); @@ -4597,6 +4664,7 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point) bool bOpenWith = false; bool bMergeLog = false; m_bCancelled = false; +#if 0 switch (cmd) { case ID_DIFF: @@ -4968,8 +5036,8 @@ void CLogDlg::ShowContextMenuForChangedpaths(CWnd* /*pWnd*/, CPoint point) default: break; } // switch (cmd) - } // if (popup.CreatePopupMenu()) #endif + } // if (popup.CreatePopupMenu()) } void CLogDlg::OnDtnDropdownDatefrom(NMHDR * /*pNMHDR*/, LRESULT *pResult) diff --git a/TortoiseProc/TortoiseProc.vcproj b/TortoiseProc/TortoiseProc.vcproj index 0a497c5..35a6d43 100644 --- a/TortoiseProc/TortoiseProc.vcproj +++ b/TortoiseProc/TortoiseProc.vcproj @@ -518,11 +518,11 @@ > + + + + + + +#include + +using namespace std; + +CFindBar::CFindBar() +{ +} + +CFindBar::~CFindBar(void) +{ + DestroyIcon(m_hIcon); +} + +LRESULT CFindBar::DlgFunc(HWND /*hwndDlg*/, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + switch (uMsg) + { + case WM_INITDIALOG: + { + m_hIcon = (HICON)::LoadImage(hResource, MAKEINTRESOURCE(IDI_CANCELNORMAL), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR); + SendMessage(GetDlgItem(*this, IDC_FINDEXIT), BM_SETIMAGE, IMAGE_ICON, (LPARAM)m_hIcon); + } + return TRUE; + case WM_COMMAND: + return DoCommand(LOWORD(wParam), HIWORD(wParam)); + default: + return FALSE; + } +} + +LRESULT CFindBar::DoCommand(int id, int msg) +{ + bool bFindPrev = false; + switch (id) + { + case IDC_FINDPREV: + bFindPrev = true; + case IDC_FINDNEXT: + { + DoFind(bFindPrev); + } + break; + case IDC_FINDEXIT: + { + ::SendMessage(m_hParent, COMMITMONITOR_FINDEXIT, 0, 0); + } + break; + case IDC_FINDTEXT: + { + if (msg == EN_CHANGE) + { + SendMessage(m_hParent, COMMITMONITOR_FINDRESET, 0, 0); + DoFind(false); + } + } + break; + } + return 1; +} + +void CFindBar::DoFind(bool bFindPrev) +{ + int len = ::GetWindowTextLength(GetDlgItem(*this, IDC_FINDTEXT)); + TCHAR * findtext = new TCHAR[len+1]; + ::GetWindowText(GetDlgItem(*this, IDC_FINDTEXT), findtext, len+1); + wstring ft = wstring(findtext); + delete [] findtext; + bool bCaseSensitive = !!SendMessage(GetDlgItem(*this, IDC_MATCHCASECHECK), BM_GETCHECK, 0, NULL); + if (bFindPrev) + ::SendMessage(m_hParent, COMMITMONITOR_FINDMSGPREV, (WPARAM)bCaseSensitive, (LPARAM)ft.c_str()); + else + ::SendMessage(m_hParent, COMMITMONITOR_FINDMSGNEXT, (WPARAM)bCaseSensitive, (LPARAM)ft.c_str()); +} \ No newline at end of file diff --git a/TortoiseUDiff/FindBar.h b/TortoiseUDiff/FindBar.h new file mode 100644 index 0000000..7230ee8 --- /dev/null +++ b/TortoiseUDiff/FindBar.h @@ -0,0 +1,44 @@ +// TortoiseSVN - a Windows shell extension for easy version control + +// Copyright (C) 2007 - TortoiseSVN + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#pragma once +#include "basedialog.h" + + +/** + * \ingroup TortoiseUDiff + * FindBar. + * A search bar similar to the one found in FireFox + */ +class CFindBar : public CDialog +{ +public: + CFindBar(); + ~CFindBar(void); + + void SetParent(HWND hParent) {m_hParent = hParent;} +protected: + LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + LRESULT DoCommand(int id, int msg); + + void DoFind(bool bFindPrev); + +private: + HWND m_hParent; + HICON m_hIcon; +}; diff --git a/TortoiseUDiff/MainWindow.cpp b/TortoiseUDiff/MainWindow.cpp new file mode 100644 index 0000000..9b43c26 --- /dev/null +++ b/TortoiseUDiff/MainWindow.cpp @@ -0,0 +1,471 @@ +// TortoiseSVN - a Windows shell extension for easy version control + +// Copyright (C) 2003-2008 - TortoiseSVN + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#include "StdAfx.h" +#include "MainWindow.h" +#include "UnicodeUtils.h" + +CMainWindow::CMainWindow(HINSTANCE hInst, const WNDCLASSEX* wcx /* = NULL*/) + : CWindow(hInst, wcx) + , m_bShowFindBar(false) +{ + SetWindowTitle(_T("TortoiseUDiff")); +} + +CMainWindow::~CMainWindow(void) +{ +} + +bool CMainWindow::RegisterAndCreateWindow() +{ + WNDCLASSEX wcx; + + // Fill in the window class structure with default parameters + wcx.cbSize = sizeof(WNDCLASSEX); + wcx.style = CS_HREDRAW | CS_VREDRAW; + wcx.lpfnWndProc = CWindow::stWinMsgHandler; + wcx.cbClsExtra = 0; + wcx.cbWndExtra = 0; + wcx.hInstance = hResource; + wcx.hCursor = NULL; + wcx.lpszClassName = ResString(hResource, IDS_APP_TITLE); + wcx.hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_TORTOISEUDIFF)); + wcx.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); + wcx.lpszMenuName = MAKEINTRESOURCE(IDC_TORTOISEUDIFF); + wcx.hIconSm = LoadIcon(wcx.hInstance, MAKEINTRESOURCE(IDI_TORTOISEUDIFF)); + if (RegisterWindow(&wcx)) + { + if (Create(WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN, NULL)) + { + m_FindBar.SetParent(*this); + m_FindBar.Create(hResource, IDD_FINDBAR, *this); + ShowWindow(*this, SW_SHOW); + UpdateWindow(*this); + return true; + } + } + return false; +} + +LRESULT CALLBACK CMainWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_CREATE: + { + m_hwnd = hwnd; + Initialize(); + } + break; + case WM_COMMAND: + { + return DoCommand(LOWORD(wParam)); + } + break; + case WM_MOUSEWHEEL: + { + if (GET_KEYSTATE_WPARAM(wParam) == MK_SHIFT) + { + // scroll sideways + SendEditor(SCI_LINESCROLL, -GET_WHEEL_DELTA_WPARAM(wParam)/40, 0); + } + else + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + break; + case WM_SIZE: + { + RECT rect; + GetClientRect(*this, &rect); + if (m_bShowFindBar) + { + ::SetWindowPos(m_hWndEdit, HWND_TOP, + rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top-30, + SWP_SHOWWINDOW); + ::SetWindowPos(m_FindBar, HWND_TOP, + rect.left, rect.bottom-30, + rect.right-rect.left, 30, + SWP_SHOWWINDOW); + } + else + { + ::SetWindowPos(m_hWndEdit, HWND_TOP, + rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top, + SWP_SHOWWINDOW); + ::ShowWindow(m_FindBar, SW_HIDE); + } + } + break; + case WM_GETMINMAXINFO: + { + MINMAXINFO * mmi = (MINMAXINFO*)lParam; + mmi->ptMinTrackSize.x = 100; + mmi->ptMinTrackSize.y = 100; + return 0; + } + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + case WM_CLOSE: + { + CRegStdWORD w = CRegStdWORD(_T("Software\\TortoiseSVN\\UDiffViewerWidth"), (DWORD)CW_USEDEFAULT); + CRegStdWORD h = CRegStdWORD(_T("Software\\TortoiseSVN\\UDiffViewerHeight"), (DWORD)CW_USEDEFAULT); + CRegStdWORD p = CRegStdWORD(_T("Software\\TortoiseSVN\\UDiffViewerPos"), 0); + + RECT rect; + ::GetWindowRect(*this, &rect); + w = rect.right-rect.left; + h = rect.bottom-rect.top; + p = MAKELONG(rect.left, rect.top); + } + ::DestroyWindow(m_hwnd); + break; + case WM_SETFOCUS: + SetFocus(m_hWndEdit); + break; + case COMMITMONITOR_FINDMSGNEXT: + { + SendEditor(SCI_CHARRIGHT); + SendEditor(SCI_SEARCHANCHOR); + m_bMatchCase = !!wParam; + m_findtext = (LPCTSTR)lParam; + SendEditor(SCI_SEARCHNEXT, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str()); + SendEditor(SCI_SCROLLCARET); + } + break; + case COMMITMONITOR_FINDMSGPREV: + { + SendEditor(SCI_SEARCHANCHOR); + m_bMatchCase = !!wParam; + m_findtext = (LPCTSTR)lParam; + SendEditor(SCI_SEARCHPREV, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str()); + SendEditor(SCI_SCROLLCARET); + } + break; + case COMMITMONITOR_FINDEXIT: + { + RECT rect; + GetClientRect(*this, &rect); + m_bShowFindBar = false; + ::ShowWindow(m_FindBar, SW_HIDE); + ::SetWindowPos(m_hWndEdit, HWND_TOP, + rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top, + SWP_SHOWWINDOW); + } + break; + case COMMITMONITOR_FINDRESET: + SendEditor(SCI_SETSELECTIONSTART, 0); + SendEditor(SCI_SETSELECTIONEND, 0); + SendEditor(SCI_SEARCHANCHOR); + break; + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + + return 0; +}; + +LRESULT CMainWindow::DoCommand(int id) +{ + switch (id) + { + case ID_FILE_EXIT: + ::PostQuitMessage(0); + return 0; + case IDM_SHOWFINDBAR: + { + m_bShowFindBar = true; + ::ShowWindow(m_FindBar, SW_SHOW); + RECT rect; + GetClientRect(*this, &rect); + ::SetWindowPos(m_hWndEdit, HWND_TOP, + rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top-30, + SWP_SHOWWINDOW); + ::SetWindowPos(m_FindBar, HWND_TOP, + rect.left, rect.bottom-30, + rect.right-rect.left, 30, + SWP_SHOWWINDOW); + ::SetFocus(m_FindBar); + SendEditor(SCI_SETSELECTIONSTART, 0); + SendEditor(SCI_SETSELECTIONEND, 0); + SendEditor(SCI_SEARCHANCHOR); + } + break; + case IDM_FINDNEXT: + SendEditor(SCI_CHARRIGHT); + SendEditor(SCI_SEARCHANCHOR); + SendEditor(SCI_SEARCHNEXT, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str()); + SendEditor(SCI_SCROLLCARET); + break; + case IDM_FINDPREV: + SendEditor(SCI_SEARCHANCHOR); + SendEditor(SCI_SEARCHPREV, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str()); + SendEditor(SCI_SCROLLCARET); + break; + case IDM_FINDEXIT: + { + if (IsWindowVisible(m_FindBar)) + { + RECT rect; + GetClientRect(*this, &rect); + m_bShowFindBar = false; + ::ShowWindow(m_FindBar, SW_HIDE); + ::SetWindowPos(m_hWndEdit, HWND_TOP, + rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top, + SWP_SHOWWINDOW); + } + else + PostQuitMessage(0); + } + break; + default: + break; + }; + return 1; +} + + +LRESULT CMainWindow::SendEditor(UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if (m_directFunction) + { + return ((SciFnDirect) m_directFunction)(m_directPointer, Msg, wParam, lParam); + } + return ::SendMessage(m_hWndEdit, Msg, wParam, lParam); +} + +bool CMainWindow::Initialize() +{ + CRegStdWORD pos(_T("Software\\TortoiseSVN\\UDiffViewerPos"), 0); + CRegStdWORD width(_T("Software\\TortoiseSVN\\UDiffViewerWidth"), (DWORD)640); + CRegStdWORD height(_T("Software\\TortoiseSVN\\UDiffViewerHeight"), (DWORD)480); + if (DWORD(pos) && DWORD(width) && DWORD(height)) + { + RECT rc; + rc.left = LOWORD(DWORD(pos)); + rc.top = HIWORD(DWORD(pos)); + rc.right = rc.left + DWORD(width); + rc.bottom = rc.top + DWORD(height); + HMONITOR hMon = MonitorFromRect(&rc, MONITOR_DEFAULTTONULL); + if (hMon) + { + // only restore the window position if the monitor is valid + MoveWindow(*this, LOWORD(DWORD(pos)), HIWORD(DWORD(pos)), + DWORD(width), DWORD(height), FALSE); + } + } + + m_hWndEdit = ::CreateWindow( + _T("Scintilla"), + _T("Source"), + WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + *this, + 0, + hResource, + 0); + if (m_hWndEdit == NULL) + return false; + + RECT rect; + GetClientRect(*this, &rect); + ::SetWindowPos(m_hWndEdit, HWND_TOP, + rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top, + SWP_SHOWWINDOW); + + m_directFunction = SendMessage(m_hWndEdit, SCI_GETDIRECTFUNCTION, 0, 0); + m_directPointer = SendMessage(m_hWndEdit, SCI_GETDIRECTPOINTER, 0, 0); + + // Set up the global default style. These attributes are used wherever no explicit choices are made. + SetAStyle(STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOWTEXT), ::GetSysColor(COLOR_WINDOW), + // Reusing TortoiseBlame's setting which already have an user friendly + // pane in TortoiseSVN's Settings dialog, while there is no such + // pane for TortoiseUDiff. + CRegStdWORD(_T("Software\\TortoiseSVN\\BlameFontSize"), 10), + WideToMultibyte(CRegStdString(_T("Software\\TortoiseSVN\\BlameFontName"), _T("Courier New"))).c_str()); + SendEditor(SCI_SETTABWIDTH, 4); + SendEditor(SCI_SETREADONLY, TRUE); + LRESULT pix = SendEditor(SCI_TEXTWIDTH, STYLE_LINENUMBER, (LPARAM)"_99999"); + SendEditor(SCI_SETMARGINWIDTHN, 0, pix); + SendEditor(SCI_SETMARGINWIDTHN, 1); + SendEditor(SCI_SETMARGINWIDTHN, 2); + //Set the default windows colors for edit controls + SendEditor(SCI_STYLESETFORE, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOWTEXT)); + SendEditor(SCI_STYLESETBACK, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOW)); + SendEditor(SCI_SETSELFORE, TRUE, ::GetSysColor(COLOR_HIGHLIGHTTEXT)); + SendEditor(SCI_SETSELBACK, TRUE, ::GetSysColor(COLOR_HIGHLIGHT)); + SendEditor(SCI_SETCARETFORE, ::GetSysColor(COLOR_WINDOWTEXT)); + + return true; +} + +bool CMainWindow::LoadFile(LPCTSTR filename) +{ + SendEditor(SCI_SETREADONLY, FALSE); + SendEditor(SCI_CLEARALL); + SendEditor(EM_EMPTYUNDOBUFFER); + SendEditor(SCI_SETSAVEPOINT); + SendEditor(SCI_CANCEL); + SendEditor(SCI_SETUNDOCOLLECTION, 0); + + FILE *fp = NULL; + _tfopen_s(&fp, filename, _T("rb")); + if (fp) + { + //SetTitle(); + char data[4096]; + int lenFile = fread(data, 1, sizeof(data), fp); + bool bUTF8 = IsUTF8(data, lenFile); + while (lenFile > 0) + { + SendEditor(SCI_ADDTEXT, lenFile, + reinterpret_cast(static_cast(data))); + lenFile = fread(data, 1, sizeof(data), fp); + } + fclose(fp); + SendEditor(SCI_SETCODEPAGE, bUTF8 ? SC_CP_UTF8 : GetACP()); + } + else + { + return false; + } + + SendEditor(SCI_SETUNDOCOLLECTION, 1); + ::SetFocus(m_hWndEdit); + SendEditor(EM_EMPTYUNDOBUFFER); + SendEditor(SCI_SETSAVEPOINT); + SendEditor(SCI_GOTOPOS, 0); + SendEditor(SCI_SETREADONLY, TRUE); + + SendEditor(SCI_CLEARDOCUMENTSTYLE, 0, 0); + SendEditor(SCI_SETSTYLEBITS, 5, 0); + + //SetAStyle(SCE_DIFF_DEFAULT, RGB(0, 0, 0)); + SetAStyle(SCE_DIFF_COMMAND, RGB(0x0A, 0x24, 0x36)); + SetAStyle(SCE_DIFF_POSITION, RGB(0xFF, 0, 0)); + SetAStyle(SCE_DIFF_HEADER, RGB(0x80, 0, 0), RGB(0xFF, 0xFF, 0x80)); + SetAStyle(SCE_DIFF_COMMENT, RGB(0, 0x80, 0)); + SendEditor(SCI_STYLESETBOLD, SCE_DIFF_COMMENT, TRUE); + SetAStyle(SCE_DIFF_DELETED, ::GetSysColor(COLOR_WINDOWTEXT), RGB(0xFF, 0x80, 0x80)); + SetAStyle(SCE_DIFF_ADDED, ::GetSysColor(COLOR_WINDOWTEXT), RGB(0x80, 0xFF, 0x80)); + + SendEditor(SCI_SETLEXER, SCLEX_DIFF); + SendEditor(SCI_SETKEYWORDS, 0, (LPARAM)"revision"); + SendEditor(SCI_COLOURISE, 0, -1); + ::ShowWindow(m_hWndEdit, SW_SHOW); + return true; +} + +void CMainWindow::SetTitle(LPCTSTR title) +{ + int len = _tcslen(title); + TCHAR * pBuf = new TCHAR[len+40]; + _stprintf_s(pBuf, len+40, _T("%s - TortoiseUDiff"), title); + SetWindowTitle(std::wstring(pBuf)); + delete [] pBuf; +} + +void CMainWindow::SetAStyle(int style, COLORREF fore, COLORREF back, int size, const char *face) +{ + SendEditor(SCI_STYLESETFORE, style, fore); + SendEditor(SCI_STYLESETBACK, style, back); + if (size >= 1) + SendEditor(SCI_STYLESETSIZE, style, size); + if (face) + SendEditor(SCI_STYLESETFONT, style, reinterpret_cast(face)); +} + +bool CMainWindow::IsUTF8(LPVOID pBuffer, int cb) +{ + if (cb < 2) + return true; + UINT16 * pVal = (UINT16 *)pBuffer; + UINT8 * pVal2 = (UINT8 *)(pVal+1); + // scan the whole buffer for a 0x0000 sequence + // if found, we assume a binary file + for (int i=0; i<(cb-2); i=i+2) + { + if (0x0000 == *pVal++) + return false; + } + pVal = (UINT16 *)pBuffer; + if (*pVal == 0xFEFF) + return false; + if (cb < 3) + return false; + if (*pVal == 0xBBEF) + { + if (*pVal2 == 0xBF) + return true; + } + // check for illegal UTF8 chars + pVal2 = (UINT8 *)pBuffer; + for (int i=0; i= 0xF5)) + return false; + pVal2++; + } + pVal2 = (UINT8 *)pBuffer; + bool bUTF8 = false; + for (int i=0; i<(cb-3); ++i) + { + if ((*pVal2 & 0xE0)==0xC0) + { + pVal2++;i++; + if ((*pVal2 & 0xC0)!=0x80) + return false; + bUTF8 = true; + } + if ((*pVal2 & 0xF0)==0xE0) + { + pVal2++;i++; + if ((*pVal2 & 0xC0)!=0x80) + return false; + pVal2++;i++; + if ((*pVal2 & 0xC0)!=0x80) + return false; + bUTF8 = true; + } + if ((*pVal2 & 0xF8)==0xF0) + { + pVal2++;i++; + if ((*pVal2 & 0xC0)!=0x80) + return false; + pVal2++;i++; + if ((*pVal2 & 0xC0)!=0x80) + return false; + pVal2++;i++; + if ((*pVal2 & 0xC0)!=0x80) + return false; + bUTF8 = true; + } + pVal2++; + } + if (bUTF8) + return true; + return false; +} diff --git a/TortoiseUDiff/MainWindow.h b/TortoiseUDiff/MainWindow.h new file mode 100644 index 0000000..820ae09 --- /dev/null +++ b/TortoiseUDiff/MainWindow.h @@ -0,0 +1,75 @@ +// TortoiseSVN - a Windows shell extension for easy version control + +// Copyright (C) 2007 - TortoiseUDiff + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#pragma once +#include "BaseWindow.h" +#include "SciLexer.h" +#include "Scintilla.h" +#include "Registry.h" +#include "resource.h" +#include "FindBar.h" +#include +#include + +using namespace std; + +/** + * \ingroup TortoiseUDiff + * Main window of TortoiseUDiff. Handles the child windows (Scintilla control, + * CFindBar, ...). + */ +class CMainWindow : public CWindow +{ +public: + CMainWindow(HINSTANCE hInst, const WNDCLASSEX* wcx = NULL); + ~CMainWindow(void); + + /** + * Registers the window class and creates the window. + */ + bool RegisterAndCreateWindow(); + + LRESULT SendEditor(UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0); + HWND GetHWNDEdit() { return m_hWndEdit; } + bool LoadFile(LPCTSTR filename); + void SetTitle(LPCTSTR title); + +protected: + /// the message handler for this window + LRESULT CALLBACK WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + /// Handles all the WM_COMMAND window messages (e.g. menu commands) + LRESULT DoCommand(int id); + + bool Initialize(); + +private: + void SetAStyle(int style, COLORREF fore, COLORREF back=::GetSysColor(COLOR_WINDOW), + int size=-1, const char *face=0); + bool IsUTF8(LPVOID pBuffer, int cb); + +private: + LRESULT m_directFunction; + LRESULT m_directPointer; + + HWND m_hWndEdit; + + CFindBar m_FindBar; + bool m_bShowFindBar; + bool m_bMatchCase; + wstring m_findtext; +}; diff --git a/TortoiseUDiff/Readme.txt b/TortoiseUDiff/Readme.txt new file mode 100644 index 0000000..d2cc96b --- /dev/null +++ b/TortoiseUDiff/Readme.txt @@ -0,0 +1,7 @@ +TortoiseUDiff : a unified diff viewer for TortoiseSVN + +This unified diff viewer is basically a simple wrapper around the +Scintilla edit control with the udiff lexer. + +This is a by-product of the CommitMonitor, released under GPL for +TortoiseSVN. \ No newline at end of file diff --git a/TortoiseUDiff/TortoiseUDiff.cpp b/TortoiseUDiff/TortoiseUDiff.cpp new file mode 100644 index 0000000..8c8ddb0 --- /dev/null +++ b/TortoiseUDiff/TortoiseUDiff.cpp @@ -0,0 +1,92 @@ +// TortoiseSVN - a Windows shell extension for easy version control + +// Copyright (C) 2003-2008 - Stefan Kueng + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#include "stdafx.h" +#include "TortoiseUDiff.h" +#include "MainWindow.h" +#include "CmdLineParser.h" + +#include +#pragma comment(lib, "comctl32.lib") + + +#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + + +int APIENTRY _tWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(nCmdShow); + + MSG msg; + HACCEL hAccelTable; + + CCmdLineParser parser(lpCmdLine); + + if (parser.HasKey(_T("?")) || parser.HasKey(_T("help")) || !parser.HasKey(_T("patchfile"))) + { + TCHAR buf[1024]; + LoadString(hInstance, IDS_COMMANDLINEHELP, buf, sizeof(buf)/sizeof(TCHAR)); + MessageBox(NULL, buf, _T("TortoiseUDiff"), MB_ICONINFORMATION); + return 0; + } + + INITCOMMONCONTROLSEX used = { + sizeof(INITCOMMONCONTROLSEX), + ICC_STANDARD_CLASSES | ICC_BAR_CLASSES + }; + InitCommonControlsEx(&used); + + + if (::LoadLibrary(_T("SciLexer.DLL")) == NULL) + return FALSE; + + CMainWindow mainWindow(hInstance); + if (parser.HasVal(_T("title"))) + mainWindow.SetTitle(parser.GetVal(_T("title"))); + else + mainWindow.SetTitle(parser.GetVal(_T("patchfile"))); + if (mainWindow.RegisterAndCreateWindow()) + { + if (mainWindow.LoadFile(parser.GetVal(_T("patchfile")))) + { + ::ShowWindow(mainWindow.GetHWNDEdit(), SW_SHOW); + ::SetFocus(mainWindow.GetHWNDEdit()); + + hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TORTOISEUDIFF)); + + // Main message loop: + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(mainWindow, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + return (int) msg.wParam; + } + } + return 0; +} + + + diff --git a/TortoiseUDiff/TortoiseUDiff.h b/TortoiseUDiff/TortoiseUDiff.h new file mode 100644 index 0000000..afedd2e --- /dev/null +++ b/TortoiseUDiff/TortoiseUDiff.h @@ -0,0 +1,21 @@ +// TortoiseSVN - a Windows shell extension for easy version control + +// Copyright (C) 2003-2007 - Stefan Kueng + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#pragma once + +#include "resource.h" diff --git a/TortoiseUDiff/TortoiseUDiff.ico b/TortoiseUDiff/TortoiseUDiff.ico new file mode 100644 index 0000000000000000000000000000000000000000..46606edb67b4f68f2bd8e1d6317e56b285d07622 GIT binary patch literal 67895 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%0DpNH^ENV(e6Mde8VhuAjaYdCOOurfYAejNpj7&61 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 literal 0 HcmV?d00001 diff --git a/TortoiseUDiff/TortoiseUDiff.rc b/TortoiseUDiff/TortoiseUDiff.rc new file mode 100644 index 0000000..7b8b7d1 --- /dev/null +++ b/TortoiseUDiff/TortoiseUDiff.rc @@ -0,0 +1,173 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#ifndef APSTUDIO_INVOKED +#include "TortoiseUDiff.rc2" +#endif +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_CANCELNORMAL ICON "..\\Resources\\cancel-normal.ico" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_TORTOISEUDIFF ICON "TortoiseUDiff.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_TORTOISEUDIFF ACCELERATORS +BEGIN + VK_ESCAPE, IDM_FINDEXIT, VIRTKEY, NOINVERT + VK_F3, IDM_FINDNEXT, VIRTKEY, NOINVERT + VK_F3, IDM_FINDPREV, VIRTKEY, SHIFT, NOINVERT + "F", IDM_SHOWFINDBAR, VIRTKEY, CONTROL, NOINVERT + "W", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDC_TORTOISEUDIFF MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Exit", ID_FILE_EXIT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_FINDBAR DIALOGEX 0, 0, 246, 21 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "",IDC_FINDEXIT,0,3,15,14,BS_ICON | NOT WS_TABSTOP,WS_EX_TRANSPARENT + LTEXT "Find:",IDC_STATIC,19,5,17,8 + EDITTEXT IDC_FINDTEXT,40,2,55,14,ES_AUTOHSCROLL + PUSHBUTTON "< &Previous",IDC_FINDPREV,100,2,58,14 + PUSHBUTTON "&Next >",IDC_FINDNEXT,160,2,58,14 + CONTROL "Mat&ch case",IDC_MATCHCASECHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,222,4,52,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "TortoiseUDiff" + IDS_COMMANDLINEHELP "TortoiseUDiff: the unified diff viewer for TortoiseSVN\n\nAvailable command line parameters are:\n/patchfile:""path to unified diff file""\n/title:""title to show for the viewer""" + IDC_TORTOISEUDIFF "TORTOISEUDIFF" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// German (Switzerland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DES) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_SWISS +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#ifndef APSTUDIO_INVOKED\r\n" + "#include ""TortoiseUDiff.rc2""\r\n" + "#endif\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // German (Switzerland) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/TortoiseUDiff/TortoiseUDiff.rc2 b/TortoiseUDiff/TortoiseUDiff.rc2 new file mode 100644 index 0000000..d845b12 --- /dev/null +++ b/TortoiseUDiff/TortoiseUDiff.rc2 @@ -0,0 +1,50 @@ +// +// TortoiseUDiff.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +#include "..\version.h" +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILEVER + PRODUCTVERSION PRODUCTVER + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040004e4" + BEGIN + VALUE "CompanyName", "http://tortoisesvn.net\0" + VALUE "FileDescription", "TortoiseUDiff\0" + VALUE "FileVersion", STRFILEVER + VALUE "InternalName", "TortoiseUDiff.exe\0" + VALUE "LegalCopyright", "Copyright (C) 2007-2008 - TortoiseSVN\0" + VALUE "OriginalFilename", "TortoiseUDiff.exe\0" + VALUE "ProductName", "TortoiseUDiff\0" + VALUE "ProductVersion", STRPRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x400, 1252 + END +END + +///////////////////////////////////////////////////////////////////////////// diff --git a/TortoiseUDiff/TortoiseUDiff.vcproj b/TortoiseUDiff/TortoiseUDiff.vcproj new file mode 100644 index 0000000..1cb4b64 --- /dev/null +++ b/TortoiseUDiff/TortoiseUDiff.vcproj @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TortoiseUDiff/resource.h b/TortoiseUDiff/resource.h new file mode 100644 index 0000000..b8979f7 --- /dev/null +++ b/TortoiseUDiff/resource.h @@ -0,0 +1,38 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by TortoiseUDiff.rc +// +#define IDD_TORTOISEUDIFF_DIALOG 102 +#define IDS_APP_TITLE 103 +#define IDM_ABOUT 104 +#define IDS_COMMANDLINEHELP 104 +#define IDI_TORTOISEUDIFF 107 +#define IDC_TORTOISEUDIFF 109 +#define IDR_MAINFRAME 128 +#define IDB_CANCELNORMAL 130 +#define IDI_ICON1 132 +#define IDI_CANCELNORMAL 132 +#define IDD_FINDBAR 144 +#define IDC_FINDNEXT 1014 +#define IDC_FINDTEXT 1019 +#define IDC_FINDPREV 1020 +#define IDC_MATCHCASECHECK 1021 +#define IDC_FINDEXIT 1022 +#define ID_FILE_EXIT 32771 +#define IDM_SHOWFINDBAR 32787 +#define IDM_FINDNEXT 32789 +#define IDM_FINDPREV 32790 +#define IDM_FINDEXIT 32793 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 133 +#define _APS_NEXT_COMMAND_VALUE 32773 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/TortoiseUDiff/stdafx.cpp b/TortoiseUDiff/stdafx.cpp new file mode 100644 index 0000000..85c3d25 --- /dev/null +++ b/TortoiseUDiff/stdafx.cpp @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// TortoiseUDiff.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/TortoiseUDiff/stdafx.h b/TortoiseUDiff/stdafx.h new file mode 100644 index 0000000..73823ba --- /dev/null +++ b/TortoiseUDiff/stdafx.h @@ -0,0 +1,40 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + +// C RunTime Header Files +#include +#include +#include +#include + + +#define COMMITMONITOR_FINDMSGPREV (WM_APP+1) +#define COMMITMONITOR_FINDMSGNEXT (WM_APP+2) +#define COMMITMONITOR_FINDEXIT (WM_APP+3) +#define COMMITMONITOR_FINDRESET (WM_APP+4) -- 2.11.0