summaryrefslogtreecommitdiff
path: root/ui/folder_history_box.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/folder_history_box.cpp')
-rw-r--r--ui/folder_history_box.cpp116
1 files changed, 24 insertions, 92 deletions
diff --git a/ui/folder_history_box.cpp b/ui/folder_history_box.cpp
index 466fbba1..c5400272 100644
--- a/ui/folder_history_box.cpp
+++ b/ui/folder_history_box.cpp
@@ -7,18 +7,13 @@
#include "folder_history_box.h"
#include <list>
#include <zen/scope_guard.h>
-#include <wx/scrolwin.h>
+//#include <wx/scrolwin.h>
#include <wx+/string_conv.h>
#include "../lib/resolve_path.h"
using namespace zen;
-namespace
-{
-const wxEventType wxEVT_VALIDATE_USER_SELECTION = wxNewEventType();
-}
-
FolderHistoryBox::FolderHistoryBox(wxWindow* parent,
wxWindowID id,
const wxString& value,
@@ -30,113 +25,73 @@ FolderHistoryBox::FolderHistoryBox(wxWindow* parent,
const wxValidator& validator,
const wxString& name) :
wxComboBox(parent, id, value, pos, size, n, choices, style, validator, name)
-#if wxCHECK_VERSION(2, 9, 1)
- ,dropDownShown(false)
-#endif
{
//#####################################
/*##*/ SetMinSize(wxSize(150, -1)); //## workaround yet another wxWidgets bug: default minimum size is much too large for a wxComboBox
//#####################################
- Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (FolderHistoryBox::OnKeyEvent ), nullptr, this);
- Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(FolderHistoryBox::OnSelection ), nullptr, this);
- Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler (FolderHistoryBox::OnMouseWheel), nullptr, this);
+ Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (FolderHistoryBox::OnKeyEvent ), nullptr, this);
warn_static("mac")
+ warn_static("linux")
#if defined FFS_WIN
//on Win, this mouse click event only fires, when clicking on the small down arrow, NOT when clicking on the text field
//thanks to wxWidgets' non-portability it's exactly the converse on Linux!
- Connect(wxEVT_LEFT_DOWN, wxEventHandler(FolderHistoryBox::OnMouseClick), nullptr, this);
-#elif defined FFS_LINUX //update on each text change: maybe a little too often, but we have no choice as long as we don't have an event right before showing the drop-down list
- Connect(wxEVT_COMMAND_TEXT_UPDATED, wxEventHandler(FolderHistoryBox::OnMouseClick), nullptr, this);
-#elif defined FFS_MAC
+ Connect(wxEVT_LEFT_DOWN, wxEventHandler(FolderHistoryBox::OnRequireHistoryUpdate), nullptr, this);
+#elif defined FFS_LINUX || defined FFS_MAC
/*
- calling setValueAndUpdateList()...
- - on wxEVT_COMMAND_TEXT_UPDATED leads to endless loop (SetValue() seems to emit another wxEVT_COMMAND_TEXT_UPDATED asychronously)
- - on wxEVT_LEFT_DOWN leads to occasional crashes, especially when double-clicking
+ we can't attach to wxEVT_COMMAND_TEXT_UPDATED, since setValueAndUpdateList() will implicitly emit wxEVT_COMMAND_TEXT_UPDATED again when calling Clear()!
+ => Crash on Suse/X11/wxWidgets 2.9.4 on startup (setting a flag to guard against recursion does not work, still crash)
+ On OS attaching to wxEVT_LEFT_DOWN leads to occasional crashes, especially when double-clicking
*/
#endif
-
-#if wxCHECK_VERSION(2, 9, 1)
- Connect(wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEventHandler(FolderHistoryBox::OnShowDropDown), nullptr, this); //only supported on Win/GTK
- Connect(wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEventHandler(FolderHistoryBox::OnHideDropDown), nullptr, this); //
-#endif
-
- Connect(wxEVT_VALIDATE_USER_SELECTION, wxCommandEventHandler(FolderHistoryBox::OnValidateSelection), nullptr, this);
}
-#if wxCHECK_VERSION(2, 9, 1)
-void FolderHistoryBox::OnShowDropDown(wxCommandEvent& event)
+void FolderHistoryBox::OnRequireHistoryUpdate(wxEvent& event)
{
- dropDownShown = true;
+ setValueAndUpdateList(GetValue());
event.Skip();
}
-
-void FolderHistoryBox::OnHideDropDown(wxCommandEvent& event)
-{
- dropDownShown = false;
- event.Skip();
-}
-#endif
-
//set value and update list are technically entangled: see potential bug description below
void FolderHistoryBox::setValueAndUpdateList(const wxString& dirname)
{
- //it may be a little lame to update the list on each mouse-button click, but it should be working and we dont't have to manipulate wxComboBox internals
-
- std::list<Zstring> dirList;
-
- //add some aliases to allow user changing to volume name and back, if possible
- std::vector<Zstring> aliases = getDirectoryAliases(toZ(dirname));
- dirList.insert(dirList.end(), aliases.begin(), aliases.end());
-
+ //populate selection list....
+ std::vector<wxString> dirList;
+ {
+ //add some aliases to allow user changing to volume name and back, if possible
+ std::vector<Zstring> aliases = getDirectoryAliases(toZ(dirname));
+ std::transform(aliases.begin(), aliases.end(), std::back_inserter(dirList), [](const Zstring& str) { return utfCvrtTo<wxString>(str); });
+ }
if (sharedHistory_.get())
{
std::vector<Zstring> tmp = sharedHistory_->getList();
std::sort(tmp.begin(), tmp.end(), LessFilename());
if (!dirList.empty() && !tmp.empty())
- dirList.push_back(toZ(FolderHistory::separationLine()));
+ dirList.push_back(FolderHistory::separationLine());
- dirList.insert(dirList.end(), tmp.begin(), tmp.end());
+ std::transform(tmp.begin(), tmp.end(), std::back_inserter(dirList), [](const Zstring& str) { return utfCvrtTo<wxString>(str); });
}
+
//###########################################################################################
//attention: if the target value is not part of the dropdown list, SetValue() will look for a string that *starts with* this value:
//e.g. if the dropdown list contains "222" SetValue("22") will erroneously set and select "222" instead, while "111" would be set correctly!
// -> by design on Windows!
- if (std::find(dirList.begin(), dirList.end(), toZ(dirname)) == dirList.end())
- dirList.push_front(toZ(dirname));
+ if (std::find(dirList.begin(), dirList.end(), dirname) == dirList.end())
+ dirList.insert(dirList.begin(), dirname);
- Clear();
- std::for_each(dirList.begin(), dirList.end(), [&](const Zstring& dir) { this->Append(toWx(dir)); });
+ Clear(); //emits yet another wxEVT_COMMAND_TEXT_UPDATED on Suse/X11/wxWidgets 2.9.4!!!
+ std::for_each(dirList.begin(), dirList.end(), [&](const wxString& dir) { this->Append(dir); });
//this->SetSelection(wxNOT_FOUND); //don't select anything
this->SetValue(dirname); //preserve main text!
}
-void FolderHistoryBox::OnSelection(wxCommandEvent& event)
-{
- wxCommandEvent dummy2(wxEVT_VALIDATE_USER_SELECTION); //we cannot replace built-in commands at this position in call stack, so defer to a later time!
- if (wxEvtHandler* handler = GetEventHandler())
- handler->AddPendingEvent(dummy2);
-
- event.Skip();
-}
-
-
-void FolderHistoryBox::OnValidateSelection(wxCommandEvent& event)
-{
- //const auto& value = GetValue();
- //if (value == FolderHistory::separationLine())
- // setValueAndUpdateList(wxString()); -> not good enough (resolved folder name not updated)
-}
-
-
void FolderHistoryBox::OnKeyEvent(wxKeyEvent& event)
{
const int keyCode = event.GetKeyCode();
@@ -145,13 +100,9 @@ void FolderHistoryBox::OnKeyEvent(wxKeyEvent& event)
//try to delete the currently selected config history item
int pos = this->GetCurrentSelection();
if (0 <= pos && pos < static_cast<int>(this->GetCount()) &&
-#if wxCHECK_VERSION(2, 9, 1)
- dropDownShown)
-#else
//what a mess...:
(GetValue() != GetString(pos) || //avoid problems when a character shall be deleted instead of list item
GetValue() == wxEmptyString)) //exception: always allow removing empty entry
-#endif
{
//save old (selected) value: deletion seems to have influence on this
const wxString currentVal = this->GetValue();
@@ -172,22 +123,3 @@ void FolderHistoryBox::OnKeyEvent(wxKeyEvent& event)
}
event.Skip();
}
-
-
-void FolderHistoryBox::OnMouseWheel(wxMouseEvent& event)
-{
- //although switching to available items is wxWidgets default, this is NOT windows default, e.g. explorer
- //additionally this will delete manual entries, although all the users wanted is scroll the parent window!
-
- //redirect to parent scrolled window!
- wxWindow* wnd = this;
- while ((wnd = wnd->GetParent()) != nullptr) //silence MSVC warning
- if (dynamic_cast<wxScrolledWindow*>(wnd) != nullptr)
- if (wxEvtHandler* evtHandler = wnd->GetEventHandler())
- {
- evtHandler->AddPendingEvent(event);
- break;
- }
-
- // event.Skip();
-}
bgstack15