summaryrefslogtreecommitdiff
path: root/ui/dir_name.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/dir_name.cpp')
-rw-r--r--ui/dir_name.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/ui/dir_name.cpp b/ui/dir_name.cpp
new file mode 100644
index 00000000..7d747609
--- /dev/null
+++ b/ui/dir_name.cpp
@@ -0,0 +1,174 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+
+#include "dir_name.h"
+#include <wx/dnd.h>
+#include <wx/window.h>
+#include <wx/textctrl.h>
+#include <wx/statbox.h>
+#include <zen/thread.h>
+#include <zen/file_handling.h>
+#include "../lib/resolve_path.h"
+#include <wx+/string_conv.h>
+#include "folder_history_box.h"
+
+using namespace zen;
+
+
+namespace
+{
+void setDirectoryNameImpl(const wxString& dirname, wxDirPickerCtrl* dirPicker, wxWindow& tooltipWnd, wxStaticBoxSizer* staticBox, size_t timeout)
+{
+ const wxString dirFormatted = toWx(getFormattedDirectoryName(toZ(dirname)));
+
+ tooltipWnd.SetToolTip(dirFormatted); //wxComboBox bug: the edit control is not updated... http://trac.wxwidgets.org/ticket/12659
+
+ if (staticBox)
+ {
+ //change static box label only if there is a real difference to what is shown in wxTextCtrl anyway
+ wxString dirNormalized = dirname;
+ trim(dirNormalized);
+ if (!dirNormalized.empty() && !endsWith(dirNormalized, FILE_NAME_SEPARATOR))
+ dirNormalized += FILE_NAME_SEPARATOR;
+
+ staticBox->GetStaticBox()->SetLabel(dirNormalized == dirFormatted ? wxString(_("Drag && drop")) : dirFormatted);
+ }
+
+ if (dirPicker && !dirFormatted.empty())
+ {
+ Zstring dir = toZ(dirFormatted); //convert to Zstring first: we don't want to pass wxString by value and risk MT issues!
+ auto ft = async([=] { return zen::dirExists(dir); });
+
+ if (ft.timed_wait(boost::posix_time::milliseconds(timeout)) && ft.get()) //potentially slow network access: wait 200ms at most
+ dirPicker->SetPath(dirFormatted);
+ }
+}
+
+
+void setDirectoryName(const wxString& dirname,
+ wxTextCtrl* txtCtrl,
+ wxDirPickerCtrl* dirPicker,
+ wxWindow& tooltipWnd,
+ wxStaticBoxSizer* staticBox,
+ size_t timeout = 200) //pointers are optional
+{
+ if (txtCtrl)
+ txtCtrl->ChangeValue(dirname);
+ setDirectoryNameImpl(dirname, dirPicker, tooltipWnd, staticBox, timeout);
+}
+
+
+void setDirectoryName(const wxString& dirname,
+ FolderHistoryBox* comboBox,
+ wxDirPickerCtrl* dirPicker,
+ wxWindow& tooltipWnd,
+ wxStaticBoxSizer* staticBox,
+ size_t timeout = 200) //pointers are optional
+{
+ if (comboBox)
+ comboBox->setValue(dirname);
+ setDirectoryNameImpl(dirname, dirPicker, tooltipWnd, staticBox, timeout);
+}
+}
+//##############################################################################################################
+
+template <class NameControl>
+DirectoryName<NameControl>::DirectoryName(wxWindow& dropWindow,
+ wxDirPickerCtrl& dirPicker,
+ NameControl& dirName,
+ wxStaticBoxSizer* staticBox,
+ wxWindow* dropWindow2) :
+ dropWindow_(dropWindow),
+ dropWindow2_(dropWindow2),
+ dirPicker_(dirPicker),
+ dirName_(dirName),
+ staticBox_(staticBox)
+{
+ //prepare drag & drop
+ setupFileDrop(dropWindow);
+ if (dropWindow2)
+ setupFileDrop(*dropWindow2);
+
+ //redirect drag & drop event back to this class
+ dropWindow.Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DirectoryName::OnFilesDropped), NULL, this);
+ if (dropWindow2)
+ dropWindow2->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DirectoryName::OnFilesDropped), NULL, this);
+
+ //keep dirPicker and dirName synchronous
+ dirName_ .Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), NULL, this);
+ dirPicker_.Connect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), NULL, this);
+}
+
+
+template <class NameControl>
+DirectoryName<NameControl>::~DirectoryName()
+{
+ dirName_ .Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), NULL, this);
+ dirPicker_.Disconnect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), NULL, this);
+}
+
+
+template <class NameControl>
+void DirectoryName<NameControl>::OnFilesDropped(FFSFileDropEvent& event)
+{
+ if (event.getFiles().empty())
+ return;
+
+ if (acceptDrop(event.getFiles()))
+ {
+ const wxString fileName = event.getFiles()[0];
+ if (dirExists(toZ(fileName)))
+ setDirectoryName(fileName, &dirName_, &dirPicker_, dirName_, staticBox_);
+ else
+ {
+ wxString parentName = beforeLast(fileName, utf8CvrtTo<wxString>(FILE_NAME_SEPARATOR)); //returns empty string if ch not found
+#ifdef FFS_WIN
+ if (endsWith(parentName, L":")) //volume name
+ parentName += FILE_NAME_SEPARATOR;
+#endif
+ if (dirExists(toZ(parentName)))
+ setDirectoryName(parentName, &dirName_, &dirPicker_, dirName_, staticBox_);
+ else //set original name unconditionally: usecase: inactive mapped network shares
+ setDirectoryName(fileName, &dirName_, &dirPicker_, dirName_, staticBox_);
+ }
+ }
+}
+
+
+template <class NameControl>
+void DirectoryName<NameControl>::OnWriteDirManually(wxCommandEvent& event)
+{
+ setDirectoryName(event.GetString(), static_cast<NameControl*>(NULL), &dirPicker_, dirName_, staticBox_, 100); //potentially slow network access: wait 100 ms at most
+ event.Skip();
+}
+
+
+template <class NameControl>
+void DirectoryName<NameControl>::OnDirSelected(wxFileDirPickerEvent& event)
+{
+ const wxString newPath = event.GetPath();
+ setDirectoryName(newPath, &dirName_, NULL, dirName_, staticBox_);
+ event.Skip();
+}
+
+
+template <class NameControl>
+wxString DirectoryName<NameControl>::getName() const
+{
+ return dirName_.GetValue();
+}
+
+
+template <class NameControl>
+void DirectoryName<NameControl>::setName(const wxString& dirname)
+{
+ setDirectoryName(dirname, &dirName_, &dirPicker_, dirName_, staticBox_);
+}
+
+
+//explicit template instantiations
+template class DirectoryName<wxTextCtrl>;
+template class DirectoryName<FolderHistoryBox>;
bgstack15