1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2016 - TortoiseGit
4 // Copyright (C) 2003-2014, 2016 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "BrowseFolder.h"
23 #include "SmartHandle.h"
24 #include "FileDlgEventHandler.h"
27 BOOL
CBrowseFolder::m_bCheck
= FALSE
;
28 BOOL
CBrowseFolder::m_bCheck2
= FALSE
;
29 CString
CBrowseFolder::m_sDefaultPath
;
31 class BrowseFolderDlgEventHandler
: public CFileDlgEventHandler
34 BrowseFolderDlgEventHandler()
35 : m_DisableCheckbox2WhenCheckbox1IsChecked(false)
39 bool m_DisableCheckbox2WhenCheckbox1IsChecked
;
41 STDMETHODIMP
OnCheckButtonToggled(IFileDialogCustomize
*pfdc
, DWORD dwIDCtl
, BOOL bChecked
) override
43 if (m_DisableCheckbox2WhenCheckbox1IsChecked
&& dwIDCtl
== 101)
46 pfdc
->SetControlState(102, CDCS_VISIBLE
| CDCS_INACTIVE
);
48 pfdc
->SetControlState(102, CDCS_VISIBLE
| CDCS_ENABLED
);
54 CBrowseFolder::CBrowseFolder(void)
56 , m_DisableCheckbox2WhenCheckbox1IsChecked(false)
58 SecureZeroMemory(&m_title
, sizeof(m_title
));
61 CBrowseFolder::~CBrowseFolder(void)
66 CBrowseFolder::retVal
CBrowseFolder::Show(HWND parent
, LPTSTR path
, size_t pathlen
, LPCTSTR szDefaultPath
/* = nullptr */)
72 sDefault
= szDefaultPath
;
73 CBrowseFolder::retVal ret
= Show(parent
, temp
, sDefault
);
74 wcscpy_s(path
, pathlen
, temp
);
77 CBrowseFolder::retVal
CBrowseFolder::Show(HWND parent
, CString
& path
, const CString
& sDefaultPath
/* = CString() */)
79 m_sDefaultPath
= sDefaultPath
;
80 if (m_sDefaultPath
.IsEmpty() && !path
.IsEmpty())
82 while (!PathFileExists(path
) && !path
.IsEmpty())
84 CString p
= path
.Left(path
.ReverseFind(L
'\\'));
85 if ((p
.GetLength() == 2) && (p
[1] == L
':'))
88 if (p
.Compare(path
) == 0)
91 if (p
.GetLength() < 2)
95 // if the result path already contains a path, use that as the default path
96 m_sDefaultPath
= path
;
99 // Create a new common open file dialog
100 CComPtr
<IFileOpenDialog
> pfd
;
101 if (FAILED(pfd
.CoCreateInstance(CLSID_FileOpenDialog
, nullptr, CLSCTX_INPROC_SERVER
)))
104 // Set the dialog as a folder picker
106 if (FAILED(pfd
->GetOptions(&dwOptions
)))
108 if (FAILED(pfd
->SetOptions(dwOptions
| FOS_PICKFOLDERS
| FOS_FORCEFILESYSTEM
| FOS_PATHMUSTEXIST
)))
112 TCHAR
* nl
= wcschr(m_title
, L
'\n');
115 pfd
->SetTitle(m_title
);
117 // set the default folder
118 CComPtr
<IShellItem
> psiDefault
;
119 if (FAILED(SHCreateItemFromParsingName(m_sDefaultPath
, nullptr, IID_PPV_ARGS(&psiDefault
))))
121 if (FAILED(pfd
->SetFolder(psiDefault
)))
124 CComObjectStackEx
<BrowseFolderDlgEventHandler
> cbk
;
125 cbk
.m_DisableCheckbox2WhenCheckbox1IsChecked
= m_DisableCheckbox2WhenCheckbox1IsChecked
;
126 CComQIPtr
<IFileDialogEvents
> pEvents
= cbk
.GetUnknown();
128 if (!m_CheckText
.IsEmpty())
130 CComPtr
<IFileDialogCustomize
> pfdCustomize
;
131 if (FAILED(pfd
.QueryInterface(&pfdCustomize
)))
134 pfdCustomize
->StartVisualGroup(100, L
"");
135 pfdCustomize
->AddCheckButton(101, m_CheckText
, FALSE
);
136 if (!m_CheckText2
.IsEmpty())
137 pfdCustomize
->AddCheckButton(102, m_CheckText2
, FALSE
);
138 pfdCustomize
->EndVisualGroup();
142 if (FAILED(pfd
->Advise(pEvents
, &eventsCookie
)))
144 SCOPE_EXIT
{ pfd
->Unadvise(eventsCookie
); };
146 // Show the open file dialog
147 if (FAILED(pfd
->Show(parent
)))
150 // Get the selection from the user
151 CComPtr
<IShellItem
> psiResult
;
152 if (FAILED(pfd
->GetResult(&psiResult
)))
155 PWSTR pszPath
= nullptr;
156 if (SUCCEEDED(psiResult
->GetDisplayName(SIGDN_FILESYSPATH
, &pszPath
)))
159 CoTaskMemFree(pszPath
);
162 CComPtr
<IFileDialogCustomize
> pfdCustomize
;
163 if (SUCCEEDED(pfd
.QueryInterface(&pfdCustomize
)))
165 pfdCustomize
->GetCheckButtonState(101, &m_bCheck
);
166 pfdCustomize
->GetCheckButtonState(102, &m_bCheck2
);
172 void CBrowseFolder::SetInfo(LPCTSTR title
)
177 wcscpy_s(m_title
, title
);
180 void CBrowseFolder::SetCheckBoxText(LPCTSTR checktext
)
185 m_CheckText
= checktext
;
188 void CBrowseFolder::SetCheckBoxText2(LPCTSTR checktext
)
193 m_CheckText2
= checktext
;