From fd0853d2623dd278b08288331ed42e3be59252fb Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:00:17 +0200 Subject: 2.2 --- shared/dragAndDrop.cpp | 216 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 shared/dragAndDrop.cpp (limited to 'shared/dragAndDrop.cpp') diff --git a/shared/dragAndDrop.cpp b/shared/dragAndDrop.cpp new file mode 100644 index 00000000..9261d604 --- /dev/null +++ b/shared/dragAndDrop.cpp @@ -0,0 +1,216 @@ +#include "dragAndDrop.h" +#include +#include +#include +#include +#include +#include + + +//define new event type +const wxEventType FFS_DROP_FILE_EVENT = wxNewEventType(); + +typedef void (wxEvtHandler::*FFSFileDropEventFunction)(FFSFileDropEvent&); + +#define FFSFileDropEventHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(FFSFileDropEventFunction, &func) + +class FFSFileDropEvent : public wxCommandEvent +{ +public: + FFSFileDropEvent(const wxString& nameDropped, const wxWindow* dropWindow) : + wxCommandEvent(FFS_DROP_FILE_EVENT), + nameDropped_(nameDropped), + dropWindow_(dropWindow) {} + + virtual wxEvent* Clone() const + { + return new FFSFileDropEvent(nameDropped_, dropWindow_); + } + + const wxString nameDropped_; + const wxWindow* dropWindow_; +}; + +//############################################################################################################## + + +class WindowDropTarget : public wxFileDropTarget +{ +public: + WindowDropTarget(wxWindow* dropWindow) : + dropWindow_(dropWindow) {} + + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) + { + if (!filenames.IsEmpty()) + { + const wxString droppedFileName = filenames[0]; + + //create a custom event on drop window: execute event after file dropping is completed! (e.g. after mouse is released) + FFSFileDropEvent evt(droppedFileName, dropWindow_); + dropWindow_->AddPendingEvent(evt); + } + return false; + } + +private: + wxWindow* dropWindow_; +}; + + + +//############################################################################################################## + +using FreeFileSync::DragDropOnMainDlg; + +DragDropOnMainDlg::DragDropOnMainDlg(wxWindow* dropWindow1, + wxWindow* dropWindow2, + wxDirPickerCtrl* dirPicker, + wxComboBox* dirName) : + dropWindow1_(dropWindow1), + dropWindow2_(dropWindow2), + dirPicker_(dirPicker), + dirName_(dirName) +{ + //prepare drag & drop + dropWindow1->SetDropTarget(new WindowDropTarget(dropWindow1)); //takes ownership + dropWindow2->SetDropTarget(new WindowDropTarget(dropWindow2)); //takes ownership + + //redirect drag & drop event back to this class + dropWindow1->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DragDropOnMainDlg::OnFilesDropped), NULL, this); + dropWindow2->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DragDropOnMainDlg::OnFilesDropped), NULL, this); + + //keep dirPicker and dirName synchronous + dirName->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DragDropOnMainDlg::OnWriteDirManually ), NULL, this ); + dirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DragDropOnMainDlg::OnDirSelected ), NULL, this ); +} + + +void DragDropOnMainDlg::OnFilesDropped(FFSFileDropEvent& event) +{ + if ( this->dropWindow1_ == event.dropWindow_ || //file may be dropped on window 1 or 2 + this->dropWindow2_ == event.dropWindow_) + { + if (AcceptDrop(event.nameDropped_)) + { + wxString fileName = event.nameDropped_; + if (wxDirExists(fileName)) + { + dirName_->SetSelection(wxNOT_FOUND); + dirName_->SetValue(fileName); + dirPicker_->SetPath(fileName); + } + else + { + fileName = wxFileName(fileName).GetPath(); + if (wxDirExists(fileName)) + { + dirName_->SetSelection(wxNOT_FOUND); + dirName_->SetValue(fileName); + dirPicker_->SetPath(fileName); + } + } + } + } + else //should never be reached + event.Skip(); +}; + + +wxString formatDirectory(const wxString& dirname) +{ + wxString dirnameTmp = dirname; + dirnameTmp.Trim(true); //remove whitespace characters from right + dirnameTmp.Trim(false); //remove whitespace characters from left + + return dirnameTmp; +} + + +void DragDropOnMainDlg::OnWriteDirManually(wxCommandEvent& event) +{ + const wxString newDir = formatDirectory(event.GetString()); + if (wxDirExists(newDir)) + dirPicker_->SetPath(newDir); + + event.Skip(); +} + + +void DragDropOnMainDlg::OnDirSelected(wxFileDirPickerEvent& event) +{ + const wxString newPath = event.GetPath(); + dirName_->SetSelection(wxNOT_FOUND); + dirName_->SetValue(newPath); + + event.Skip(); +} + +//############################################################################################################## + + +using FreeFileSync::DragDropOnDlg; + +DragDropOnDlg::DragDropOnDlg(wxWindow* dropWindow, + wxDirPickerCtrl* dirPicker, + wxTextCtrl* dirName) : + dropWindow_(dropWindow), + dirPicker_(dirPicker), + dirName_(dirName) +{ + //prepare drag & drop + dropWindow->SetDropTarget(new WindowDropTarget(dropWindow)); //takes ownership + + //redirect drag & drop event back to this class + dropWindow->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DragDropOnDlg::OnFilesDropped), NULL, this); + + //keep dirPicker and dirName synchronous + dirName->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DragDropOnDlg::OnWriteDirManually ), NULL, this ); + dirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DragDropOnDlg::OnDirSelected ), NULL, this ); +} + + +void DragDropOnDlg::OnFilesDropped(FFSFileDropEvent& event) +{ + if (this->dropWindow_ == event.dropWindow_) + { + wxString fileName = event.nameDropped_; + if (wxDirExists(fileName)) + { + dirName_->SetValue(fileName); + dirPicker_->SetPath(fileName); + } + else + { + fileName = wxFileName(fileName).GetPath(); + if (wxDirExists(fileName)) + { + dirName_->SetValue(fileName); + dirPicker_->SetPath(fileName); + } + } + } + else //should never be reached + event.Skip(); +}; + + +void DragDropOnDlg::OnWriteDirManually(wxCommandEvent& event) +{ + const wxString newDir = formatDirectory(event.GetString()); + if (wxDirExists(newDir)) + dirPicker_->SetPath(newDir); + + event.Skip(); +} + + +void DragDropOnDlg::OnDirSelected(wxFileDirPickerEvent& event) +{ + const wxString newPath = event.GetPath(); + dirName_->SetValue(newPath); + + event.Skip(); +} + -- cgit