OSDN Git Service

Version browse in switch, export, new branch/tag and merge dialogs
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / RepoDrags.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\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 #include "StdAfx.h"\r
20 #include "RepoDrags.h"\r
21 #include "RepositoryBrowser.h"\r
22 #include "SVNDataObject.h"\r
23 \r
24 CTreeDropTarget::CTreeDropTarget(CRepositoryBrowser * pRepoBrowser) : CIDropTarget(pRepoBrowser->m_RepoTree.GetSafeHwnd())\r
25         , m_pRepoBrowser(pRepoBrowser)\r
26         , m_bFiles(false)\r
27 {\r
28 }\r
29 \r
30 bool CTreeDropTarget::OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium, DWORD *pdwEffect, POINTL pt)\r
31 {\r
32         // find the target\r
33         CString targetUrl;\r
34         HTREEITEM hDropTarget = m_pRepoBrowser->m_RepoTree.GetNextItem(TVI_ROOT, TVGN_DROPHILITE);\r
35         if (hDropTarget)\r
36         {\r
37                 CTreeItem * pItem = (CTreeItem*)m_pRepoBrowser->m_RepoTree.GetItemData(hDropTarget);\r
38                 if (pItem == NULL)\r
39                         return false;\r
40                 targetUrl = pItem->url;\r
41         }\r
42         if (pFmtEtc->cfFormat == CF_UNICODETEXT && medium.tymed == TYMED_HGLOBAL)\r
43         {\r
44                 TCHAR* pStr = (TCHAR*)GlobalLock(medium.hGlobal);\r
45                 CString urls;\r
46                 if(pStr != NULL)\r
47                 {\r
48                         urls = pStr;\r
49                 }\r
50                 GlobalUnlock(medium.hGlobal);\r
51                 urls.Replace(_T("\r\n"), _T("*"));\r
52                 CTSVNPathList urlList;\r
53                 urlList.LoadFromAsteriskSeparatedString(urls);\r
54 \r
55                 m_pRepoBrowser->OnDrop(CTSVNPath(targetUrl), urlList, m_pRepoBrowser->GetRevision(), *pdwEffect, pt);\r
56         }\r
57 \r
58         if (pFmtEtc->cfFormat == CF_SVNURL && medium.tymed == TYMED_HGLOBAL)\r
59         {\r
60                 TCHAR* pStr = (TCHAR*)GlobalLock(medium.hGlobal);\r
61                 CString urls;\r
62                 if(pStr != NULL)\r
63                 {\r
64                         urls = pStr;\r
65                 }\r
66                 GlobalUnlock(medium.hGlobal);\r
67                 urls.Replace(_T("\r\n"), _T("*"));\r
68                 CTSVNPathList urlListRevs;\r
69                 urlListRevs.LoadFromAsteriskSeparatedString(urls);\r
70                 CTSVNPathList urlList;\r
71                 SVNRev srcRev;\r
72                 for (int i=0; i<urlListRevs.GetCount(); ++i)\r
73                 {\r
74                         int pos = urlListRevs[i].GetSVNPathString().Find('?');\r
75                         if (pos > 0)\r
76                         {\r
77                                 if (!srcRev.IsValid())\r
78                                         srcRev = SVNRev(urlListRevs[i].GetSVNPathString().Mid(pos+1));\r
79                                 urlList.AddPath(CTSVNPath(urlListRevs[i].GetSVNPathString().Left(pos)));\r
80                         }\r
81                         else\r
82                                 urlList.AddPath(urlListRevs[i]);\r
83                 }\r
84 \r
85                 m_pRepoBrowser->OnDrop(CTSVNPath(targetUrl), urlList, srcRev, *pdwEffect, pt);\r
86         }\r
87 \r
88         if(pFmtEtc->cfFormat == CF_HDROP && medium.tymed == TYMED_HGLOBAL)\r
89         {\r
90                 HDROP hDrop = (HDROP)GlobalLock(medium.hGlobal);\r
91                 if(hDrop != NULL)\r
92                 {\r
93                         CTSVNPathList urlList;\r
94                         TCHAR szFileName[MAX_PATH];\r
95 \r
96                         UINT cFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); \r
97                         for(UINT i = 0; i < cFiles; ++i)\r
98                         {\r
99                                 DragQueryFile(hDrop, i, szFileName, sizeof(szFileName));\r
100                                 urlList.AddPath(CTSVNPath(szFileName));\r
101                         }\r
102                         m_pRepoBrowser->OnDrop(CTSVNPath(targetUrl), urlList, m_pRepoBrowser->GetRevision(), *pdwEffect, pt);\r
103                 }\r
104                 GlobalUnlock(medium.hGlobal);\r
105         }\r
106         TreeView_SelectDropTarget(m_hTargetWnd, NULL);\r
107         return true;\r
108 }\r
109 \r
110 HRESULT CTreeDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)\r
111 {\r
112         FORMATETC ftetc={0}; \r
113         ftetc.dwAspect = DVASPECT_CONTENT; \r
114         ftetc.lindex = -1; \r
115         ftetc.tymed = TYMED_HGLOBAL; \r
116         ftetc.cfFormat=CF_HDROP; \r
117         if (pDataObj->QueryGetData(&ftetc) == S_OK)\r
118                 m_bFiles = true;\r
119         else\r
120                 m_bFiles = false;\r
121         m_dwHoverStartTicks = 0;\r
122         hLastItem = NULL;\r
123         return CIDropTarget::DragEnter(pDataObj, grfKeyState, pt, pdwEffect);\r
124 }\r
125 \r
126 HRESULT CTreeDropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)\r
127 {\r
128         TVHITTESTINFO hit;\r
129         hit.pt = (POINT&)pt;\r
130         ScreenToClient(m_hTargetWnd,&hit.pt);\r
131         hit.flags = TVHT_ONITEM;\r
132         HTREEITEM hItem = TreeView_HitTest(m_hTargetWnd,&hit);\r
133         if (hItem != hLastItem)\r
134                 m_dwHoverStartTicks = 0;\r
135         hLastItem = hItem;\r
136 \r
137         *pdwEffect = DROPEFFECT_MOVE;\r
138         if (grfKeyState & MK_CONTROL)\r
139                 *pdwEffect = DROPEFFECT_COPY;\r
140 \r
141         if (hItem != NULL)\r
142         {\r
143                 if (m_bFiles)\r
144                         *pdwEffect = DROPEFFECT_COPY;\r
145                 TreeView_SelectDropTarget(m_hTargetWnd, hItem);\r
146                 if ((m_pRepoBrowser->m_RepoTree.GetItemState(hItem, TVIS_EXPANDED)&TVIS_EXPANDED) != TVIS_EXPANDED)\r
147                 {\r
148                         if (m_dwHoverStartTicks == 0)\r
149                                 m_dwHoverStartTicks = GetTickCount();\r
150                         UINT timeout = 0;\r
151                         //SystemParametersInfo(SPI_GETMOUSEHOVERTIME, 0, &timeout, 0);\r
152                         timeout = 2000;\r
153                         if ((GetTickCount() - m_dwHoverStartTicks) > timeout)\r
154                         {\r
155                                 // expand the item\r
156                                 m_pRepoBrowser->m_RepoTree.Expand(hItem, TVE_EXPAND);\r
157                                 m_dwHoverStartTicks = 0;\r
158                         }\r
159                 }\r
160                 else\r
161                         m_dwHoverStartTicks = 0;\r
162         }\r
163         else\r
164         {\r
165                 TreeView_SelectDropTarget(m_hTargetWnd, NULL);\r
166                 *pdwEffect = DROPEFFECT_NONE;\r
167                 m_dwHoverStartTicks = 0;\r
168         }\r
169         CRect rect;\r
170         m_pRepoBrowser->m_RepoTree.GetWindowRect(&rect);\r
171         if (rect.PtInRect((POINT&)pt))\r
172         {\r
173                 if (pt.y > (rect.bottom-20))\r
174                 {\r
175                         m_pRepoBrowser->m_RepoTree.SendMessage(WM_VSCROLL, MAKEWPARAM (SB_LINEDOWN, 0), NULL);\r
176                         m_dwHoverStartTicks = 0;\r
177                 }\r
178                 if (pt.y < (rect.top+20))\r
179                 {\r
180                         m_pRepoBrowser->m_RepoTree.SendMessage(WM_VSCROLL, MAKEWPARAM (SB_LINEUP, 0), NULL);\r
181                         m_dwHoverStartTicks = 0;\r
182                 }\r
183         }\r
184 \r
185         return CIDropTarget::DragOver(grfKeyState, pt, pdwEffect);\r
186 }\r
187 \r
188 HRESULT CTreeDropTarget::DragLeave(void)\r
189 {\r
190         TreeView_SelectDropTarget(m_hTargetWnd, NULL);\r
191         m_dwHoverStartTicks = 0;\r
192         return CIDropTarget::DragLeave();\r
193 }\r
194 \r
195 CListDropTarget::CListDropTarget(CRepositoryBrowser * pRepoBrowser):CIDropTarget(pRepoBrowser->m_RepoList.GetSafeHwnd())\r
196         , m_pRepoBrowser(pRepoBrowser)\r
197         , m_bFiles(false)\r
198 {\r
199 }       \r
200 \r
201 bool CListDropTarget::OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium, DWORD *pdwEffect, POINTL pt)\r
202 {\r
203         // find the target url\r
204         CString targetUrl;\r
205         int targetIndex = m_pRepoBrowser->m_RepoList.GetNextItem(-1, LVNI_DROPHILITED);\r
206         if (targetIndex >= 0)\r
207         {\r
208                 targetUrl = ((CItem*)m_pRepoBrowser->m_RepoList.GetItemData(targetIndex))->absolutepath;\r
209         }\r
210         else\r
211         {\r
212                 HTREEITEM hDropTarget = m_pRepoBrowser->m_RepoTree.GetSelectedItem();\r
213                 if (hDropTarget)\r
214                 {\r
215                         targetUrl = ((CTreeItem*)m_pRepoBrowser->m_RepoTree.GetItemData(hDropTarget))->url;\r
216                 }\r
217         }\r
218         if(pFmtEtc->cfFormat == CF_UNICODETEXT && medium.tymed == TYMED_HGLOBAL)\r
219         {\r
220                 TCHAR* pStr = (TCHAR*)GlobalLock(medium.hGlobal);\r
221                 CString urls;\r
222                 if(pStr != NULL)\r
223                 {\r
224                         urls = pStr;\r
225                 }\r
226                 GlobalUnlock(medium.hGlobal);\r
227                 urls.Replace(_T("\r\n"), _T("*"));\r
228                 CTSVNPathList urlList;\r
229                 urlList.LoadFromAsteriskSeparatedString(urls);\r
230                 m_pRepoBrowser->OnDrop(CTSVNPath(targetUrl), urlList, m_pRepoBrowser->GetRevision(), *pdwEffect, pt);\r
231         }\r
232         if(pFmtEtc->cfFormat == CF_SVNURL && medium.tymed == TYMED_HGLOBAL)\r
233         {\r
234                 TCHAR* pStr = (TCHAR*)GlobalLock(medium.hGlobal);\r
235                 CString urls;\r
236                 if(pStr != NULL)\r
237                 {\r
238                         urls = pStr;\r
239                 }\r
240                 GlobalUnlock(medium.hGlobal);\r
241                 urls.Replace(_T("\r\n"), _T("*"));\r
242                 CTSVNPathList urlListRevs;\r
243                 urlListRevs.LoadFromAsteriskSeparatedString(urls);\r
244                 CTSVNPathList urlList;\r
245                 SVNRev srcRev;\r
246                 for (int i=0; i<urlListRevs.GetCount(); ++i)\r
247                 {\r
248                         int pos = urlListRevs[i].GetSVNPathString().Find('?');\r
249                         if (pos > 0)\r
250                         {\r
251                                 if (!srcRev.IsValid())\r
252                                         srcRev = SVNRev(urlListRevs[i].GetSVNPathString().Mid(pos+1));\r
253                                 urlList.AddPath(CTSVNPath(urlListRevs[i].GetSVNPathString().Left(pos)));\r
254                         }\r
255                         else\r
256                                 urlList.AddPath(urlListRevs[i]);\r
257                 }\r
258 \r
259                 m_pRepoBrowser->OnDrop(CTSVNPath(targetUrl), urlList, srcRev, *pdwEffect, pt);\r
260         }\r
261 \r
262         if(pFmtEtc->cfFormat == CF_HDROP && medium.tymed == TYMED_HGLOBAL)\r
263         {\r
264                 HDROP hDrop = (HDROP)GlobalLock(medium.hGlobal);\r
265                 if(hDrop != NULL)\r
266                 {\r
267                         CTSVNPathList urlList;\r
268                         TCHAR szFileName[MAX_PATH];\r
269 \r
270                         UINT cFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); \r
271                         for(UINT i = 0; i < cFiles; ++i)\r
272                         {\r
273                                 DragQueryFile(hDrop, i, szFileName, sizeof(szFileName));\r
274                                 urlList.AddPath(CTSVNPath(szFileName));\r
275                         }\r
276                         m_pRepoBrowser->OnDrop(CTSVNPath(targetUrl), urlList, m_pRepoBrowser->GetRevision(), *pdwEffect, pt);\r
277                 }\r
278                 GlobalUnlock(medium.hGlobal);\r
279         }\r
280         ListView_SetItemState(m_hTargetWnd, -1, 0, LVIS_DROPHILITED);\r
281         return true; //let base free the medium\r
282 }\r
283 \r
284 HRESULT CListDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)\r
285 {\r
286         FORMATETC ftetc={0}; \r
287         ftetc.dwAspect = DVASPECT_CONTENT; \r
288         ftetc.lindex = -1; \r
289         ftetc.tymed = TYMED_HGLOBAL; \r
290         ftetc.cfFormat=CF_HDROP; \r
291         if (pDataObj->QueryGetData(&ftetc) == S_OK)\r
292         {\r
293                 m_bFiles = true;\r
294         }\r
295         else\r
296         {\r
297                 m_bFiles = false;\r
298         }\r
299         return CIDropTarget::DragEnter(pDataObj, grfKeyState, pt, pdwEffect);\r
300 }\r
301 \r
302 \r
303 HRESULT CListDropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)\r
304 {\r
305         LVHITTESTINFO hit;\r
306         hit.pt = (POINT&)pt;\r
307         ScreenToClient(m_hTargetWnd,&hit.pt);\r
308         hit.flags = LVHT_ONITEM;\r
309         int iItem = ListView_HitTest(m_hTargetWnd,&hit);\r
310 \r
311         *pdwEffect = DROPEFFECT_MOVE;\r
312         if (grfKeyState & MK_CONTROL)\r
313                 *pdwEffect = DROPEFFECT_COPY;\r
314 \r
315         if (iItem >= 0)\r
316         {\r
317                 CItem * pItem = (CItem*)m_pRepoBrowser->m_RepoList.GetItemData(iItem);\r
318                 if (pItem)\r
319                 {\r
320                         if (pItem->kind != svn_node_dir)\r
321                         {\r
322                                 *pdwEffect = DROPEFFECT_NONE;\r
323                                 ListView_SetItemState(m_hTargetWnd, -1, 0, LVIS_DROPHILITED);\r
324                         }\r
325                         else\r
326                         {\r
327                                 if (m_bFiles)\r
328                                         *pdwEffect = DROPEFFECT_COPY;\r
329                                 ListView_SetItemState(m_hTargetWnd, -1, 0, LVIS_DROPHILITED);\r
330                                 ListView_SetItemState(m_hTargetWnd, iItem, LVIS_DROPHILITED, LVIS_DROPHILITED);\r
331                         }\r
332                 }\r
333         }\r
334         else\r
335         {\r
336                 ListView_SetItemState(m_hTargetWnd, -1, 0, LVIS_DROPHILITED);\r
337         }\r
338 \r
339         CRect rect;\r
340         m_pRepoBrowser->m_RepoList.GetWindowRect(&rect);\r
341         if (rect.PtInRect((POINT&)pt))\r
342         {\r
343                 if (pt.y > (rect.bottom-20))\r
344                 {\r
345                         m_pRepoBrowser->m_RepoList.SendMessage(WM_VSCROLL, MAKEWPARAM (SB_LINEDOWN, 0), NULL);\r
346                 }\r
347                 if (pt.y < (rect.top+20))\r
348                 {\r
349                         m_pRepoBrowser->m_RepoList.SendMessage(WM_VSCROLL, MAKEWPARAM (SB_LINEUP, 0), NULL);\r
350                 }\r
351         }\r
352 \r
353         return CIDropTarget::DragOver(grfKeyState, pt, pdwEffect);\r
354 }\r
355 \r
356 HRESULT CListDropTarget::DragLeave(void)\r
357 {\r
358         ListView_SetItemState(m_hTargetWnd, -1, 0, LVIS_DROPHILITED);\r
359         return CIDropTarget::DragLeave();\r
360 }\r