1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - Stefan Kueng
\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
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
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
24 #include "resource.h"
\r
25 #include "TGitPath.h"
\r
26 #include "RepositoryBar.h"
\r
27 #include "StandAloneDlg.h"
\r
28 #include "ProjectProperties.h"
\r
30 #include "HintListCtrl.h"
\r
32 #define REPOBROWSER_CTRL_MIN_WIDTH 20
\r
33 #define REPOBROWSER_FETCHTIMER 101
\r
35 using namespace std;
\r
38 class CTreeDropTarget;
\r
39 class CListDropTarget;
\r
42 * \ingroup TortoiseProc
\r
43 * helper class which holds all the information of an item (file or folder)
\r
44 * in the repository. The information gets filled by the svn_client_list()
\r
50 CItem() : kind(svn_node_none)
\r
55 , is_dav_comment(false)
\r
56 , lock_creationdate(0)
\r
57 , lock_expirationdate(0)
\r
60 CItem(const CString& _path,
\r
61 svn_node_kind_t _kind,
\r
62 svn_filesize_t _size,
\r
64 svn_revnum_t _created_rev,
\r
66 const CString& _author,
\r
67 const CString& _locktoken,
\r
68 const CString& _lockowner,
\r
69 const CString& _lockcomment,
\r
70 bool _is_dav_comment,
\r
71 apr_time_t _lock_creationdate,
\r
72 apr_time_t _lock_expirationdate,
\r
73 const CString& _absolutepath)
\r
78 has_props = _has_props;
\r
79 created_rev = _created_rev;
\r
82 locktoken = _locktoken;
\r
83 lockowner = _lockowner;
\r
84 lockcomment = _lockcomment;
\r
85 is_dav_comment = _is_dav_comment;
\r
86 lock_creationdate = _lock_creationdate;
\r
87 lock_expirationdate = _lock_expirationdate;
\r
88 absolutepath = _absolutepath;
\r
92 svn_node_kind_t kind;
\r
93 svn_filesize_t size;
\r
95 svn_revnum_t created_rev;
\r
100 CString lockcomment;
\r
101 bool is_dav_comment;
\r
102 apr_time_t lock_creationdate;
\r
103 apr_time_t lock_expirationdate;
\r
104 CString absolutepath; ///< unescaped url stripped of repository root
\r
108 * \ingroup TortoiseProc
\r
109 * helper class which holds the information for a tree item
\r
110 * in the repository browser.
\r
115 CTreeItem() : children_fetched(false), has_child_folders(false) {}
\r
117 CString unescapedname;
\r
118 CString url; ///< unescaped url
\r
119 bool children_fetched; ///< whether the contents of the folder are known/fetched or not
\r
120 deque<CItem> children;
\r
121 bool has_child_folders;
\r
126 * \ingroup TortoiseProc
\r
127 * Dialog to browse a repository.
\r
129 class CRepositoryBrowser : public CResizableStandAloneDialog, public SVN, public IRepo
\r
131 DECLARE_DYNAMIC(CRepositoryBrowser)
\r
132 friend class CTreeDropTarget;
\r
133 friend class CListDropTarget;
\r
136 CRepositoryBrowser(const CString& url, const SVNRev& rev); ///< standalone repository browser
\r
137 CRepositoryBrowser(const CString& url, const SVNRev& rev, CWnd* pParent); ///< dependent repository browser
\r
138 virtual ~CRepositoryBrowser();
\r
140 /// Returns the currently displayed revision only (for convenience)
\r
141 SVNRev GetRevision() const;
\r
142 /// Returns the currently displayed URL's path only (for convenience)
\r
143 CString GetPath() const;
\r
145 /// switches to the \c url at \c rev. If the url is valid and exists,
\r
146 /// the repository browser will show the content of that url.
\r
147 bool ChangeToUrl(CString& url, SVNRev& rev, bool bAlreadyChecked);
\r
149 CString GetRepoRoot() { return m_strReposRoot; }
\r
151 enum { IDD = IDD_REPOSITORY_BROWSER };
\r
153 /// the project properties if the repository browser was started from a working copy
\r
154 ProjectProperties m_ProjectProperties;
\r
155 /// the local path of the working copy
\r
158 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
\r
159 virtual BOOL OnInitDialog();
\r
160 virtual void OnOK();
\r
161 virtual void OnCancel();
\r
162 virtual BOOL PreTranslateMessage(MSG* pMsg);
\r
163 virtual BOOL Cancel() {return m_bCancelled;}
\r
165 afx_msg void OnBnClickedHelp();
\r
166 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
\r
167 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
\r
168 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
\r
169 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
\r
170 afx_msg void OnTvnSelchangedRepotree(NMHDR *pNMHDR, LRESULT *pResult);
\r
171 afx_msg void OnTvnItemexpandingRepotree(NMHDR *pNMHDR, LRESULT *pResult);
\r
172 afx_msg void OnNMDblclkRepolist(NMHDR *pNMHDR, LRESULT *pResult);
\r
173 afx_msg void OnHdnItemclickRepolist(NMHDR *pNMHDR, LRESULT *pResult);
\r
174 afx_msg void OnLvnItemchangedRepolist(NMHDR *pNMHDR, LRESULT *pResult);
\r
175 afx_msg void OnLvnBegindragRepolist(NMHDR *pNMHDR, LRESULT *pResult);
\r
176 afx_msg void OnLvnBeginrdragRepolist(NMHDR *pNMHDR, LRESULT *pResult);
\r
177 afx_msg void OnTvnBegindragRepotree(NMHDR *pNMHDR, LRESULT *pResult);
\r
178 afx_msg void OnTvnBeginrdragRepotree(NMHDR *pNMHDR, LRESULT *pResult);
\r
179 afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
\r
180 afx_msg void OnLvnEndlabeleditRepolist(NMHDR *pNMHDR, LRESULT *pResult);
\r
181 afx_msg void OnTvnEndlabeleditRepotree(NMHDR *pNMHDR, LRESULT *pResult);
\r
182 afx_msg void OnTimer(UINT_PTR nIDEvent);
\r
184 afx_msg void OnUrlFocus();
\r
185 afx_msg void OnCopy();
\r
186 afx_msg void OnInlineedit();
\r
187 afx_msg void OnRefresh();
\r
188 afx_msg void OnDelete();
\r
189 afx_msg void OnGoUp();
\r
191 DECLARE_MESSAGE_MAP()
\r
193 /// called after the init thread has finished
\r
194 LRESULT OnAfterInitDialog(WPARAM /*wParam*/, LPARAM /*lParam*/);
\r
195 /// draws the bar when the tree and list control are resized
\r
196 void DrawXorBar(CDC * pDC, int x1, int y1, int width, int height);
\r
197 /// callback from the SVN::List() method which stores all the information
\r
198 virtual BOOL ReportList(const CString& path, svn_node_kind_t kind,
\r
199 svn_filesize_t size, bool has_props, svn_revnum_t created_rev,
\r
200 apr_time_t time, const CString& author, const CString& locktoken,
\r
201 const CString& lockowner, const CString& lockcomment,
\r
202 bool is_dav_comment, apr_time_t lock_creationdate,
\r
203 apr_time_t lock_expirationdate, const CString& absolutepath);
\r
205 /// recursively removes all items from \c hItem on downwards.
\r
206 void RecursiveRemove(HTREEITEM hItem, bool bChildrenOnly = false);
\r
207 /// searches the tree item for the specified \c fullurl.
\r
208 HTREEITEM FindUrl(const CString& fullurl, bool create = true);
\r
209 /// searches the tree item for the specified \c fullurl.
\r
210 HTREEITEM FindUrl(const CString& fullurl, const CString& url, bool create = true, HTREEITEM hItem = TVI_ROOT);
\r
212 * Refetches the information for \c url. If \c force is true, then the list
\r
213 * control is refilled again.
\r
214 * \param recursive if true, the information is fetched recursively.
\r
216 bool RefreshNode(const CString& url, bool force = false, bool recursive = false);
\r
218 * Refetches the information for \c hNode. If \c force is true, then the list
\r
219 * control is refilled again.
\r
220 * \param recursive if true, the information is fetched recursively.
\r
222 bool RefreshNode(HTREEITEM hNode, bool force = false, bool recursive = false);
\r
223 /// Fills the list control with all the items in \c pItems.
\r
224 void FillList(deque<CItem> * pItems);
\r
225 /// Sets the sort arrow in the list view header according to the currently used sorting.
\r
226 void SetSortArrow();
\r
227 /// called when a drag-n-drop operation starts
\r
228 void OnBeginDrag(NMHDR *pNMHDR);
\r
229 void OnBeginDragTree(NMHDR *pNMHDR);
\r
230 /// called when a drag-n-drop operation ends and the user dropped something on us.
\r
231 bool OnDrop(const CTSVNPath& target, const CTSVNPathList& pathlist, const SVNRev& srcRev, DWORD dwEffect, POINTL pt);
\r
233 * Since all urls we store and use are not properly escaped but "UI friendly", this
\r
234 * method converts those urls to a properly escaped url which we can use in
\r
235 * Subversion API calls.
\r
237 CString EscapeUrl(const CTSVNPath& url);
\r
238 /// Initializes the repository browser with a new root url
\r
240 /// Helper function to show the "File Save" dialog
\r
241 bool AskForSavePath(const CTSVNPathList& urlList, CTSVNPath &tempfile, bool bFolder);
\r
243 /// Saves the column widths
\r
244 void SaveColumnWidths(bool bSaveToRegistry = false);
\r
245 /// converts a string to an array of column widths
\r
246 bool StringToWidthArray(const CString& WidthString, int WidthArray[]);
\r
247 /// converts an array of column widths to a string
\r
248 CString WidthArrayToString(int WidthArray[]);
\r
251 static UINT InitThreadEntry(LPVOID pVoid);
\r
254 static int CALLBACK ListSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParam3);
\r
258 CRepositoryBar m_barRepository;
\r
259 CRepositoryBarCnr m_cnrRepositoryBar;
\r
261 CTreeCtrl m_RepoTree;
\r
262 CHintListCtrl m_RepoList;
\r
264 CString m_strReposRoot;
\r
270 bool m_bStandAlone;
\r
271 CString m_InitialUrl;
\r
272 SVNRev m_initialRev;
\r
273 bool m_bThreadRunning;
\r
274 static const UINT m_AfterInitMessage;
\r
277 int m_nOpenIconFolder;
\r
279 volatile bool m_blockEvents;
\r
281 bool m_bSortAscending;
\r
282 int m_nSortedColumn;
\r
283 int m_arColumnWidths[7];
\r
284 int m_arColumnAutoWidths[7];
\r
286 CTreeDropTarget * m_pTreeDropTarget;
\r
287 CListDropTarget * m_pListDropTarget;
\r
295 svn_node_kind_t m_diffKind;
\r
296 CTSVNPath m_diffURL;
\r
298 CString m_origDlgTitle;
\r
301 static UINT WM_AFTERINIT = RegisterWindowMessage(_T("TORTOISESVN_AFTERINIT_MSG"));
\r