1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\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
20 #include "SVNProperties.h"
\r
21 #include "MessageBox.h"
\r
22 #include "TortoiseProc.h"
\r
23 #include "EditPropertiesDlg.h"
\r
24 #include "EditPropertyValueDlg.h"
\r
25 #include "UnicodeUtils.h"
\r
26 #include "PathUtils.h"
\r
27 #include "AppUtils.h"
\r
28 #include "StringUtils.h"
\r
29 #include "ProgressDlg.h"
\r
30 #include "InputLogDlg.h"
\r
31 #include "XPTheme.h"
\r
34 IMPLEMENT_DYNAMIC(CEditPropertiesDlg, CResizableStandAloneDialog)
\r
36 CEditPropertiesDlg::CEditPropertiesDlg(CWnd* pParent /*=NULL*/)
\r
37 : CResizableStandAloneDialog(CEditPropertiesDlg::IDD, pParent)
\r
38 , m_bRecursive(FALSE)
\r
40 , m_revision(SVNRev::REV_WC)
\r
41 , m_bRevProps(false)
\r
45 CEditPropertiesDlg::~CEditPropertiesDlg()
\r
49 void CEditPropertiesDlg::DoDataExchange(CDataExchange* pDX)
\r
51 CResizableStandAloneDialog::DoDataExchange(pDX);
\r
52 DDX_Control(pDX, IDC_EDITPROPLIST, m_propList);
\r
56 BEGIN_MESSAGE_MAP(CEditPropertiesDlg, CResizableStandAloneDialog)
\r
57 ON_BN_CLICKED(IDHELP, &CEditPropertiesDlg::OnBnClickedHelp)
\r
58 ON_NOTIFY(NM_CUSTOMDRAW, IDC_EDITPROPLIST, &CEditPropertiesDlg::OnNMCustomdrawEditproplist)
\r
59 ON_BN_CLICKED(IDC_REMOVEPROPS, &CEditPropertiesDlg::OnBnClickedRemoveProps)
\r
60 ON_BN_CLICKED(IDC_EDITPROPS, &CEditPropertiesDlg::OnBnClickedEditprops)
\r
61 ON_NOTIFY(LVN_ITEMCHANGED, IDC_EDITPROPLIST, &CEditPropertiesDlg::OnLvnItemchangedEditproplist)
\r
62 ON_NOTIFY(NM_DBLCLK, IDC_EDITPROPLIST, &CEditPropertiesDlg::OnNMDblclkEditproplist)
\r
63 ON_BN_CLICKED(IDC_SAVEPROP, &CEditPropertiesDlg::OnBnClickedSaveprop)
\r
64 ON_BN_CLICKED(IDC_ADDPROPS, &CEditPropertiesDlg::OnBnClickedAddprops)
\r
65 ON_BN_CLICKED(IDC_EXPORT, &CEditPropertiesDlg::OnBnClickedExport)
\r
66 ON_BN_CLICKED(IDC_IMPORT, &CEditPropertiesDlg::OnBnClickedImport)
\r
69 void CEditPropertiesDlg::OnBnClickedHelp()
\r
74 BOOL CEditPropertiesDlg::OnInitDialog()
\r
76 CResizableStandAloneDialog::OnInitDialog();
\r
78 // fill in the path edit control
\r
79 if (m_pathlist.GetCount() == 1)
\r
81 if (m_pathlist[0].IsUrl())
\r
82 SetDlgItemText(IDC_PROPPATH, m_pathlist[0].GetSVNPathString());
\r
84 SetDlgItemText(IDC_PROPPATH, m_pathlist[0].GetWinPathString());
\r
89 sTemp.Format(IDS_EDITPROPS_NUMPATHS, m_pathlist.GetCount());
\r
90 SetDlgItemText(IDC_PROPPATH, sTemp);
\r
94 theme.SetWindowTheme(m_propList.GetSafeHwnd(), L"Explorer", NULL);
\r
96 // initialize the property list control
\r
97 m_propList.DeleteAllItems();
\r
98 DWORD exStyle = LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER;
\r
99 m_propList.SetExtendedStyle(exStyle);
\r
100 int c = ((CHeaderCtrl*)(m_propList.GetDlgItem(0)))->GetItemCount()-1;
\r
102 m_propList.DeleteColumn(c--);
\r
104 temp.LoadString(IDS_PROPPROPERTY);
\r
105 m_propList.InsertColumn(0, temp);
\r
106 temp.LoadString(IDS_PROPVALUE);
\r
107 m_propList.InsertColumn(1, temp);
\r
108 m_propList.SetRedraw(false);
\r
112 GetDlgItem(IDC_IMPORT)->ShowWindow(SW_HIDE);
\r
113 GetDlgItem(IDC_EXPORT)->ShowWindow(SW_HIDE);
\r
116 m_tooltips.Create(this);
\r
117 m_tooltips.AddTool(IDC_IMPORT, IDS_PROP_TT_IMPORT);
\r
118 m_tooltips.AddTool(IDC_EXPORT, IDS_PROP_TT_EXPORT);
\r
119 m_tooltips.AddTool(IDC_SAVEPROP, IDS_PROP_TT_SAVE);
\r
120 m_tooltips.AddTool(IDC_REMOVEPROPS, IDS_PROP_TT_REMOVE);
\r
121 m_tooltips.AddTool(IDC_EDITPROPS, IDS_PROP_TT_EDIT);
\r
122 m_tooltips.AddTool(IDC_ADDPROPS, IDS_PROP_TT_ADD);
\r
124 AddAnchor(IDC_GROUP, TOP_LEFT, BOTTOM_RIGHT);
\r
125 AddAnchor(IDC_PROPPATH, TOP_LEFT, TOP_RIGHT);
\r
126 AddAnchor(IDC_EDITPROPLIST, TOP_LEFT, BOTTOM_RIGHT);
\r
127 AddAnchor(IDC_IMPORT, BOTTOM_RIGHT);
\r
128 AddAnchor(IDC_EXPORT, BOTTOM_RIGHT);
\r
129 AddAnchor(IDC_SAVEPROP, BOTTOM_RIGHT);
\r
130 AddAnchor(IDC_REMOVEPROPS, BOTTOM_RIGHT);
\r
131 AddAnchor(IDC_EDITPROPS, BOTTOM_RIGHT);
\r
132 AddAnchor(IDC_ADDPROPS, BOTTOM_RIGHT);
\r
133 AddAnchor(IDOK, BOTTOM_RIGHT);
\r
134 AddAnchor(IDHELP, BOTTOM_RIGHT);
\r
136 CenterWindow(CWnd::FromHandle(hWndExplorer));
\r
137 EnableSaveRestore(_T("EditPropertiesDlg"));
\r
139 InterlockedExchange(&m_bThreadRunning, TRUE);
\r
140 if (AfxBeginThread(PropsThreadEntry, this)==NULL)
\r
142 InterlockedExchange(&m_bThreadRunning, FALSE);
\r
143 CMessageBox::Show(this->m_hWnd, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
\r
145 GetDlgItem(IDC_EDITPROPLIST)->SetFocus();
\r
150 void CEditPropertiesDlg::Refresh()
\r
152 if (m_bThreadRunning)
\r
154 m_propList.DeleteAllItems();
\r
155 InterlockedExchange(&m_bThreadRunning, TRUE);
\r
156 if (AfxBeginThread(PropsThreadEntry, this)==NULL)
\r
158 InterlockedExchange(&m_bThreadRunning, FALSE);
\r
159 CMessageBox::Show(this->m_hWnd, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
\r
163 UINT CEditPropertiesDlg::PropsThreadEntry(LPVOID pVoid)
\r
165 return ((CEditPropertiesDlg*)pVoid)->PropsThread();
\r
168 UINT CEditPropertiesDlg::PropsThread()
\r
170 // get all properties
\r
171 m_properties.clear();
\r
172 for (int i=0; i<m_pathlist.GetCount(); ++i)
\r
174 SVNProperties props(m_pathlist[i], m_revision, m_bRevProps);
\r
175 for (int p=0; p<props.GetCount(); ++p)
\r
177 wide_string prop_str = props.GetItemName(p);
\r
178 std::string prop_value = props.GetItemValue(p);
\r
179 std::map<stdstring,PropValue>::iterator it = m_properties.lower_bound(prop_str);
\r
180 if (it != m_properties.end() && it->first == prop_str)
\r
182 it->second.count++;
\r
183 if (it->second.value.compare(prop_value)!=0)
\r
184 it->second.allthesamevalue = false;
\r
188 it = m_properties.insert(it, std::make_pair(prop_str, PropValue()));
\r
189 stdstring value = MultibyteToWide((char *)prop_value.c_str());
\r
190 it->second.value = prop_value;
\r
191 CString stemp = value.c_str();
\r
192 stemp.Replace('\n', ' ');
\r
193 stemp.Replace(_T("\r"), _T(""));
\r
194 it->second.value_without_newlines = stdstring((LPCTSTR)stemp);
\r
195 it->second.count = 1;
\r
196 it->second.allthesamevalue = true;
\r
197 if (SVNProperties::IsBinary(prop_value))
\r
198 it->second.isbinary = true;
\r
203 // fill the property list control with the gathered information
\r
205 m_propList.SetRedraw(FALSE);
\r
206 for (std::map<stdstring,PropValue>::iterator it = m_properties.begin(); it != m_properties.end(); ++it)
\r
208 m_propList.InsertItem(index, it->first.c_str());
\r
209 if (it->second.isbinary)
\r
211 m_propList.SetItemText(index, 1, CString(MAKEINTRESOURCE(IDS_EDITPROPS_BINVALUE)));
\r
212 m_propList.SetItemData(index, FALSE);
\r
214 else if (it->second.count != m_pathlist.GetCount())
\r
216 // if the property values are the same for all paths they're set
\r
217 // but they're not set for *all* paths, then we show the entry grayed out
\r
218 m_propList.SetItemText(index, 1, it->second.value_without_newlines.c_str());
\r
219 m_propList.SetItemData(index, FALSE);
\r
221 else if (it->second.allthesamevalue)
\r
223 // if the property values are the same for all paths,
\r
224 // we show the value
\r
225 m_propList.SetItemText(index, 1, it->second.value_without_newlines.c_str());
\r
226 m_propList.SetItemData(index, TRUE);
\r
230 // if the property values aren't the same for all paths
\r
231 // then we show "values are different" instead of the value
\r
232 CString sTemp(MAKEINTRESOURCE(IDS_EDITPROPS_DIFFERENTPROPVALUES));
\r
233 m_propList.SetItemText(index, 1, sTemp);
\r
234 m_propList.SetItemData(index, FALSE);
\r
238 // select the first entry
\r
239 m_propList.SetItemState(index, LVIS_SELECTED, LVIS_SELECTED);
\r
240 m_propList.SetSelectionMark(index);
\r
244 int maxcol = ((CHeaderCtrl*)(m_propList.GetDlgItem(0)))->GetItemCount()-1;
\r
245 for (int col = 0; col <= maxcol; col++)
\r
247 m_propList.SetColumnWidth(col, LVSCW_AUTOSIZE_USEHEADER);
\r
250 InterlockedExchange(&m_bThreadRunning, FALSE);
\r
251 m_propList.SetRedraw(TRUE);
\r
255 void CEditPropertiesDlg::OnNMCustomdrawEditproplist(NMHDR *pNMHDR, LRESULT *pResult)
\r
257 NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
\r
258 // Take the default processing unless we set this to something else below.
\r
259 *pResult = CDRF_DODEFAULT;
\r
261 if (m_bThreadRunning)
\r
264 // First thing - check the draw stage. If it's the control's prepaint
\r
265 // stage, then tell Windows we want messages for every item.
\r
267 if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
\r
269 *pResult = CDRF_NOTIFYITEMDRAW;
\r
271 else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
\r
273 // This is the prepaint stage for an item. Here's where we set the
\r
274 // item's text color. Our return value will tell Windows to draw the
\r
275 // item itself, but it will use the new color we set here.
\r
277 // Tell Windows to paint the control itself.
\r
278 *pResult = CDRF_DODEFAULT;
\r
280 if ((int)pLVCD->nmcd.dwItemSpec > m_propList.GetItemCount())
\r
283 COLORREF crText = GetSysColor(COLOR_WINDOWTEXT);
\r
284 if (m_propList.GetItemData (static_cast<int>(pLVCD->nmcd.dwItemSpec))==FALSE)
\r
285 crText = GetSysColor(COLOR_GRAYTEXT);
\r
286 // Store the color back in the NMLVCUSTOMDRAW struct.
\r
287 pLVCD->clrText = crText;
\r
292 void CEditPropertiesDlg::OnLvnItemchangedEditproplist(NMHDR * /*pNMHDR*/, LRESULT *pResult)
\r
295 // disable the "remove" button if nothing
\r
296 // is selected, enable it otherwise
\r
297 int selCount = m_propList.GetSelectedCount();
\r
298 DialogEnableWindow(IDC_EXPORT, selCount >= 1);
\r
299 DialogEnableWindow(IDC_REMOVEPROPS, selCount >= 1);
\r
300 DialogEnableWindow(IDC_SAVEPROP, selCount == 1);
\r
301 DialogEnableWindow(IDC_EDITPROPS, selCount == 1);
\r
306 void CEditPropertiesDlg::OnBnClickedRemoveProps()
\r
309 POSITION pos = m_propList.GetFirstSelectedItemPosition();
\r
312 int selIndex = m_propList.GetNextSelectedItem(pos);
\r
314 bool bRecurse = false;
\r
315 CString sName = m_propList.GetItemText(selIndex, 0);
\r
316 if (m_pathlist[0].IsUrl())
\r
318 CInputLogDlg input(this);
\r
319 input.SetUUID(m_sUUID);
\r
320 input.SetProjectProperties(m_pProjectProperties);
\r
322 sHint.Format(IDS_INPUT_REMOVEPROP, (LPCTSTR)sName, (LPCTSTR)(m_pathlist[0].GetSVNPathString()));
\r
323 input.SetActionText(sHint);
\r
324 if (input.DoModal() != IDOK)
\r
326 sLogMsg = input.GetLogMessage();
\r
329 sQuestion.Format(IDS_EDITPROPS_RECURSIVEREMOVEQUESTION, (LPCTSTR)sName);
\r
330 CString sRecursive(MAKEINTRESOURCE(IDS_EDITPROPS_RECURSIVE));
\r
331 CString sNotRecursive(MAKEINTRESOURCE(IDS_EDITPROPS_NOTRECURSIVE));
\r
332 CString sCancel(MAKEINTRESOURCE(IDS_EDITPROPS_CANCEL));
\r
334 if ((m_pathlist.GetCount()>1)||((m_pathlist.GetCount()==1)&&(PathIsDirectory(m_pathlist[0].GetWinPath()))))
\r
336 int ret = CMessageBox::Show(m_hWnd, sQuestion, _T("TortoiseSVN"), MB_DEFBUTTON1, IDI_QUESTION, sRecursive, sNotRecursive, sCancel);
\r
347 sTemp.LoadString(IDS_SETPROPTITLE);
\r
348 prog.SetTitle(sTemp);
\r
349 sTemp.LoadString(IDS_PROPWAITCANCEL);
\r
350 prog.SetCancelMsg(sTemp);
\r
351 prog.SetTime(TRUE);
\r
352 prog.SetShowProgressBar(TRUE);
\r
353 prog.ShowModeless(m_hWnd);
\r
354 for (int i=0; i<m_pathlist.GetCount(); ++i)
\r
356 prog.SetLine(1, m_pathlist[i].GetWinPath(), true);
\r
357 SVNProperties props(m_pathlist[i], m_revision, m_bRevProps);
\r
358 if (!props.Remove(sName, bRecurse ? svn_depth_infinity : svn_depth_empty, (LPCTSTR)sLogMsg))
\r
360 CMessageBox::Show(m_hWnd, props.GetLastErrorMsg().c_str(), _T("TortoiseSVN"), MB_ICONERROR);
\r
365 if (m_revision.IsNumber())
\r
366 m_revision = LONG(m_revision)+1;
\r
371 DialogEnableWindow(IDC_REMOVEPROPS, FALSE);
\r
372 DialogEnableWindow(IDC_SAVEPROP, FALSE);
\r
376 void CEditPropertiesDlg::OnNMDblclkEditproplist(NMHDR * /*pNMHDR*/, LRESULT *pResult)
\r
378 if (m_propList.GetSelectedCount() == 1)
\r
384 void CEditPropertiesDlg::OnBnClickedEditprops()
\r
389 void CEditPropertiesDlg::OnBnClickedAddprops()
\r
394 void CEditPropertiesDlg::EditProps(bool bAdd /* = false*/)
\r
396 m_tooltips.Pop(); // hide the tooltips
\r
397 int selIndex = m_propList.GetSelectionMark();
\r
399 CEditPropertyValueDlg dlg;
\r
402 if ((!bAdd)&&(selIndex >= 0)&&(m_propList.GetSelectedCount()))
\r
404 sName = m_propList.GetItemText(selIndex, 0);
\r
405 PropValue& prop = m_properties[stdstring(sName)];
\r
406 dlg.SetPropertyName(sName);
\r
407 if (prop.allthesamevalue)
\r
408 dlg.SetPropertyValue(prop.value);
\r
409 dlg.SetDialogTitle(CString(MAKEINTRESOURCE(IDS_EDITPROPS_EDITTITLE)));
\r
413 dlg.SetPathList(m_pathlist); // this is the problem
\r
414 dlg.SetDialogTitle(CString(MAKEINTRESOURCE(IDS_EDITPROPS_ADDTITLE)));
\r
417 if (m_pathlist.GetCount() > 1)
\r
419 else if (m_pathlist.GetCount() == 1)
\r
421 if (PathIsDirectory(m_pathlist[0].GetWinPath()))
\r
425 dlg.RevProps(m_bRevProps);
\r
426 if ( dlg.DoModal()==IDOK )
\r
428 sName = dlg.GetPropertyName();
\r
429 if (!sName.IsEmpty())
\r
433 if (!m_bRevProps&&(m_pathlist.GetCount())&&(m_pathlist[0].IsUrl()))
\r
435 CInputLogDlg input(this);
\r
436 input.SetUUID(m_sUUID);
\r
437 input.SetProjectProperties(m_pProjectProperties);
\r
439 sHint.Format(IDS_INPUT_EDITPROP, (LPCTSTR)sName, (LPCTSTR)(m_pathlist[0].GetSVNPathString()));
\r
440 input.SetActionText(sHint);
\r
441 if (input.DoModal() == IDOK)
\r
443 sMsg = input.GetLogMessage();
\r
452 sTemp.LoadString(IDS_SETPROPTITLE);
\r
453 prog.SetTitle(sTemp);
\r
454 sTemp.LoadString(IDS_PROPWAITCANCEL);
\r
455 prog.SetCancelMsg(sTemp);
\r
456 prog.SetTime(TRUE);
\r
457 prog.SetShowProgressBar(TRUE);
\r
458 prog.ShowModeless(m_hWnd);
\r
459 for (int i=0; i<m_pathlist.GetCount(); ++i)
\r
461 prog.SetLine(1, m_pathlist[i].GetWinPath(), true);
\r
462 SVNProperties props(m_pathlist[i], m_revision, m_bRevProps);
\r
463 if (!props.Add(sName, dlg.IsBinary() ? dlg.GetPropertyValue() : dlg.GetPropertyValue().c_str(),
\r
464 dlg.GetRecursive() ? svn_depth_infinity : svn_depth_empty, sMsg))
\r
466 CMessageBox::Show(m_hWnd, props.GetLastErrorMsg().c_str(), _T("TortoiseSVN"), MB_ICONERROR);
\r
471 // bump the revision number since we just did a commit
\r
472 if (!m_bRevProps && m_revision.IsNumber())
\r
473 m_revision = LONG(m_revision)+1;
\r
483 void CEditPropertiesDlg::OnOK()
\r
485 if (m_bThreadRunning)
\r
487 CStandAloneDialogTmpl<CResizableDialog>::OnOK();
\r
490 void CEditPropertiesDlg::OnCancel()
\r
492 if (m_bThreadRunning)
\r
494 CStandAloneDialogTmpl<CResizableDialog>::OnCancel();
\r
497 BOOL CEditPropertiesDlg::PreTranslateMessage(MSG* pMsg)
\r
499 m_tooltips.RelayEvent(pMsg);
\r
501 if (pMsg->message == WM_KEYDOWN)
\r
503 switch (pMsg->wParam)
\r
507 if (m_bThreadRunning)
\r
508 return __super::PreTranslateMessage(pMsg);
\r
514 if (GetAsyncKeyState(VK_CONTROL)&0x8000)
\r
516 if ( GetDlgItem(IDOK)->IsWindowEnabled() )
\r
518 PostMessage(WM_COMMAND, IDOK);
\r
528 return __super::PreTranslateMessage(pMsg);
\r
531 void CEditPropertiesDlg::OnBnClickedSaveprop()
\r
533 m_tooltips.Pop(); // hide the tooltips
\r
534 int selIndex = m_propList.GetSelectionMark();
\r
538 if ((selIndex >= 0)&&(m_propList.GetSelectedCount()))
\r
540 sName = m_propList.GetItemText(selIndex, 0);
\r
541 PropValue& prop = m_properties[stdstring(sName)];
\r
542 sValue = prop.value.c_str();
\r
543 if (prop.allthesamevalue)
\r
546 if (!CAppUtils::FileOpenSave(savePath, NULL, IDS_REPOBROWSE_SAVEAS, 0, false, m_hWnd))
\r
551 if ((err = _tfopen_s(&stream, (LPCTSTR)savePath, _T("wbS")))==0)
\r
553 fwrite(prop.value.c_str(), sizeof(char), prop.value.size(), stream);
\r
558 TCHAR strErr[4096] = {0};
\r
559 _tcserror_s(strErr, 4096, err);
\r
560 CMessageBox::Show(m_hWnd, strErr, _T("TortoiseSVN"), MB_ICONERROR);
\r
566 void CEditPropertiesDlg::OnBnClickedExport()
\r
568 m_tooltips.Pop(); // hide the tooltips
\r
569 if (m_propList.GetSelectedCount() == 0)
\r
573 if (!CAppUtils::FileOpenSave(savePath, NULL, IDS_REPOBROWSE_SAVEAS, IDS_PROPSFILEFILTER, false, m_hWnd))
\r
576 if (CPathUtils::GetFileExtFromPath(savePath).Compare(_T(".svnprops")))
\r
578 // append the default ".svnprops" extension since the user did not specify it himself
\r
579 savePath += _T(".svnprops");
\r
581 // we save the list of selected properties not in a text file but in our own
\r
582 // binary format. That's because properties can be binary themselves, a text
\r
583 // or xml file just won't do it properly.
\r
589 if ((err = _tfopen_s(&stream, (LPCTSTR)savePath, _T("wbS")))==0)
\r
591 POSITION pos = m_propList.GetFirstSelectedItemPosition();
\r
592 int len = m_propList.GetSelectedCount();
\r
593 fwrite(&len, sizeof(int), 1, stream); // number of properties
\r
596 int index = m_propList.GetNextSelectedItem(pos);
\r
597 sName = m_propList.GetItemText(index, 0);
\r
598 PropValue& prop = m_properties[stdstring(sName)];
\r
599 sValue = prop.value.c_str();
\r
600 int len = sName.GetLength()*sizeof(TCHAR);
\r
601 fwrite(&len, sizeof(int), 1, stream); // length of property name in bytes
\r
602 fwrite(sName, sizeof(TCHAR), sName.GetLength(), stream); // property name
\r
603 len = static_cast<int>(prop.value.size());
\r
604 fwrite(&len, sizeof(int), 1, stream); // length of property value in bytes
\r
605 fwrite(prop.value.c_str(), sizeof(char), prop.value.size(), stream); // property value
\r
611 TCHAR strErr[4096] = {0};
\r
612 _tcserror_s(strErr, 4096, err);
\r
613 CMessageBox::Show(m_hWnd, strErr, _T("TortoiseSVN"), MB_ICONERROR);
\r
617 void CEditPropertiesDlg::OnBnClickedImport()
\r
619 m_tooltips.Pop(); // hide the tooltips
\r
621 if (!CAppUtils::FileOpenSave(openPath, NULL, IDS_REPOBROWSE_OPEN, IDS_PROPSFILEFILTER, true, m_hWnd))
\r
625 // first check the size of the file
\r
627 _tfopen_s(&stream, openPath, _T("rbS"));
\r
628 int nProperties = 0;
\r
629 if (fread(&nProperties, sizeof(int), 1, stream) == 1)
\r
631 bool bFailed = false;
\r
632 if ((nProperties < 0)||(nProperties > 4096))
\r
634 CMessageBox::Show(m_hWnd, IDS_EDITPROPS_ERRIMPORTFORMAT, IDS_APPNAME, MB_ICONERROR);
\r
639 sTemp.LoadString(IDS_SETPROPTITLE);
\r
640 prog.SetTitle(sTemp);
\r
641 sTemp.LoadString(IDS_PROPWAITCANCEL);
\r
642 prog.SetCancelMsg(sTemp);
\r
643 prog.SetTime(TRUE);
\r
644 prog.SetShowProgressBar(TRUE);
\r
645 prog.ShowModeless(m_hWnd);
\r
646 while ((nProperties-- > 0)&&(!bFailed))
\r
648 int nNameBytes = 0;
\r
649 if ((nNameBytes < 0)||(nNameBytes > 4096))
\r
652 CMessageBox::Show(m_hWnd, IDS_EDITPROPS_ERRIMPORTFORMAT, IDS_APPNAME, MB_ICONERROR);
\r
655 if (fread(&nNameBytes, sizeof(int), 1, stream) == 1)
\r
657 TCHAR * pNameBuf = new TCHAR[nNameBytes/sizeof(TCHAR)];
\r
658 if (fread(pNameBuf, 1, nNameBytes, stream) == (size_t)nNameBytes)
\r
660 CString sName = CString(pNameBuf, nNameBytes/sizeof(TCHAR));
\r
661 int nValueBytes = 0;
\r
662 if (fread(&nValueBytes, sizeof(int), 1, stream) == 1)
\r
664 BYTE * pValueBuf = new BYTE[nValueBytes];
\r
665 if (fread(pValueBuf, sizeof(char), nValueBytes, stream) == (size_t)nValueBytes)
\r
667 std::string propertyvalue;
\r
668 propertyvalue.assign((const char*)pValueBuf, nValueBytes);
\r
670 if (m_pathlist[0].IsUrl())
\r
672 CInputLogDlg input(this);
\r
673 input.SetUUID(m_sUUID);
\r
674 input.SetProjectProperties(m_pProjectProperties);
\r
676 sHint.Format(IDS_INPUT_SETPROP, (LPCTSTR)sName, (LPCTSTR)(m_pathlist[0].GetSVNPathString()));
\r
677 input.SetActionText(sHint);
\r
678 if (input.DoModal() == IDOK)
\r
680 sMsg = input.GetLogMessage();
\r
686 for (int i=0; i<m_pathlist.GetCount() && !bFailed; ++i)
\r
688 prog.SetLine(1, m_pathlist[i].GetWinPath(), true);
\r
689 SVNProperties props(m_pathlist[i], m_revision, m_bRevProps);
\r
690 if (!props.Add(sName, propertyvalue, svn_depth_empty, (LPCTSTR)sMsg))
\r
693 CMessageBox::Show(m_hWnd, props.GetLastErrorMsg().c_str(), _T("TortoiseSVN"), MB_ICONERROR);
\r
698 if (m_revision.IsNumber())
\r
699 m_revision = (LONG)m_revision + 1;
\r
706 CMessageBox::Show(m_hWnd, IDS_EDITPROPS_ERRIMPORTFORMAT, IDS_APPNAME, MB_ICONERROR);
\r
709 delete [] pValueBuf;
\r
714 CMessageBox::Show(m_hWnd, IDS_EDITPROPS_ERRIMPORTFORMAT, IDS_APPNAME, MB_ICONERROR);
\r
721 CMessageBox::Show(m_hWnd, IDS_EDITPROPS_ERRIMPORTFORMAT, IDS_APPNAME, MB_ICONERROR);
\r
724 delete [] pNameBuf;
\r
729 CMessageBox::Show(m_hWnd, IDS_EDITPROPS_ERRIMPORTFORMAT, IDS_APPNAME, MB_ICONERROR);
\r