"Fossies" - the Fresh Open Source Software Archive

Member "filezilla-3.45.1/src/interface/treectrlex.cpp" (25 Sep 2019, 5828 Bytes) of package /linux/misc/FileZilla_3.45.1_src.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "treectrlex.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.45.0_vs_3.45.1.

    1 #include <filezilla.h>
    2 #include "treectrlex.h"
    3 
    4 #ifdef __WXMAC__
    5 BEGIN_EVENT_TABLE(wxTreeCtrlEx, wxNavigationEnabled<wxTreeCtrl>)
    6 EVT_CHAR(wxTreeCtrlEx::OnChar)
    7 END_EVENT_TABLE()
    8 #endif
    9 
   10 // Needed for OnCompareItems to work on Windows. Bad library design, why not use normal RTTI?
   11 IMPLEMENT_CLASS(wxTreeCtrlEx, wxNavigationEnabled<wxTreeCtrl>)
   12 
   13 wxTreeCtrlEx::wxTreeCtrlEx()
   14 {
   15 #ifdef __WXMSW__
   16     sortFunction_ = CFileListCtrlSortBase::GetCmpFunction(CFileListCtrlSortBase::namesort_caseinsensitive);
   17 #else
   18     sortFunction_ = CFileListCtrlSortBase::GetCmpFunction(CFileListCtrlSortBase::namesort_casesensitive);
   19 #endif
   20 }
   21 
   22 wxTreeCtrlEx::wxTreeCtrlEx(wxWindow *parent, wxWindowID id /*=wxID_ANY*/,
   23                const wxPoint& pos /*=wxDefaultPosition*/,
   24                const wxSize& size /*=wxDefaultSize*/,
   25                long style /*=wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT*/)
   26 {
   27 #ifdef __WXMSW__
   28     sortFunction_ = CFileListCtrlSortBase::GetCmpFunction(CFileListCtrlSortBase::namesort_caseinsensitive);
   29 #else
   30     sortFunction_ = CFileListCtrlSortBase::GetCmpFunction(CFileListCtrlSortBase::namesort_casesensitive);
   31 #endif
   32 
   33     Create(parent, id, pos, size, style);
   34     SetBackgroundStyle(wxBG_STYLE_SYSTEM);
   35 
   36     Bind(wxEVT_CHAR, [this](wxKeyEvent& evt) {
   37         auto key = evt.GetUnicodeKey();
   38         if (key && key > 32) {
   39             inPrefixSearch_ = true;
   40         }
   41         evt.Skip();
   42     });
   43     Bind(wxEVT_KEY_UP, [this](wxKeyEvent& evt) {
   44         inPrefixSearch_ = false;
   45         evt.Skip();
   46     });
   47 }
   48 
   49 wxTreeItemId wxTreeCtrlEx::GetSelection() const
   50 {
   51     if (HasFlag(wxTR_MULTIPLE)) {
   52         auto const selections = GetSelections();
   53         if (selections.size() != 1) {
   54             return wxTreeItemId();
   55         }
   56         return selections.front();
   57     }
   58     else {
   59         return wxTreeCtrl::GetSelection();
   60     }
   61 }
   62 
   63 std::vector<wxTreeItemId> wxTreeCtrlEx::GetSelections() const
   64 {
   65     std::vector<wxTreeItemId> ret;
   66 
   67     // Not only does wxTreeCtrl::GetSelections have a terrible API, it also returns items in a really weird order.
   68     // Sadly on MSW, the native TreeView_GetNextSelected can't be used either, it uses a weird and also nodeterministic order.
   69     //
   70     // Traverse the tree ourselves, in a nice, deterministic depth-first approach.
   71     wxTreeItemId item = GetRootItem();
   72     if (item && HasFlag(wxTR_HIDE_ROOT)) {
   73         item = GetNextItemSimple(item, true);
   74     }
   75     while (item) {
   76         if (IsSelected(item)) {
   77             ret.push_back(item);
   78         }
   79         item = GetNextItemSimple(item, true);
   80     }
   81 
   82     return ret;
   83 }
   84 
   85 void wxTreeCtrlEx::SafeSelectItem(wxTreeItemId const& item, bool clearSelection)
   86 {
   87     if (!item) {
   88         ++m_setSelection;
   89         UnselectAll();
   90         --m_setSelection;
   91     }
   92     else {
   93         std::vector<wxTreeItemId> selections;
   94         if (HasFlag(wxTR_MULTIPLE)) {
   95             ++m_setSelection;
   96             selections = GetSelections();
   97             if (clearSelection) {
   98                 UnselectAll();
   99             }
  100             
  101             if (clearSelection || selections.empty()) {
  102                 SetFocusedItem(item);
  103             }
  104             --m_setSelection;
  105         }
  106         else {
  107             auto old = GetSelection();
  108             if (old) {
  109                 selections.push_back(old);
  110             }
  111         }
  112 
  113         ++m_setSelection;
  114         SelectItem(item);
  115         --m_setSelection;
  116 
  117         if (selections.empty()) {
  118             EnsureVisible(item);
  119         }
  120         else if (clearSelection) {
  121             bool found{};
  122             for (auto const& old : selections) {
  123                 if (item == old) {
  124                     found = true;
  125                 }
  126             }
  127             if (!found) {
  128                 EnsureVisible(item);
  129             }
  130         }
  131     }
  132 }
  133 
  134 #ifdef __WXMAC__
  135 void wxTreeCtrlEx::OnChar(wxKeyEvent& event)
  136 {
  137     if (event.GetKeyCode() != WXK_TAB) {
  138         event.Skip();
  139         return;
  140     }
  141 
  142     HandleAsNavigationKey(event);
  143 }
  144 #endif
  145 
  146 wxTreeItemId wxTreeCtrlEx::GetFirstItem() const
  147 {
  148     wxTreeItemId root = GetRootItem();
  149     if (root.IsOk() && GetWindowStyle() & wxTR_HIDE_ROOT) {
  150         wxTreeItemIdValue cookie;
  151         root = GetFirstChild(root, cookie);
  152     }
  153 
  154     return root;
  155 }
  156 
  157 wxTreeItemId wxTreeCtrlEx::GetLastItem() const
  158 {
  159     wxTreeItemId cur = GetRootItem();
  160     if (cur.IsOk() && GetWindowStyle() & wxTR_HIDE_ROOT) {
  161         cur = GetLastChild(cur);
  162     }
  163 
  164     while (cur.IsOk() && HasChildren(cur) && IsExpanded(cur)) {
  165         cur = GetLastChild(cur);
  166     }
  167 
  168     return cur;
  169 }
  170 
  171 wxTreeItemId wxTreeCtrlEx::GetBottomItem() const
  172 {
  173     wxTreeItemId cur = GetFirstVisibleItem();
  174     if (cur) {
  175         wxTreeItemId next;
  176         while ((next = GetNextVisible(cur)).IsOk()) {
  177             cur = next;
  178         }
  179     }
  180     return cur;
  181 }
  182 
  183 wxTreeItemId wxTreeCtrlEx::GetNextItemSimple(wxTreeItemId const& item, bool includeCollapsed) const
  184 {
  185     if (item.IsOk() && ItemHasChildren(item) && (includeCollapsed || IsExpanded(item))) {
  186         wxTreeItemIdValue cookie;
  187         return GetFirstChild(item, cookie);
  188     }
  189     else {
  190         wxTreeItemId cur = item;
  191         wxTreeItemId next = GetNextSibling(cur);
  192         while (!next.IsOk() && cur.IsOk()) {
  193             cur = GetItemParent(cur);
  194             if (cur.IsOk()) {
  195                 if (HasFlag(wxTR_HIDE_ROOT) && cur == GetRootItem()) {
  196                     break;
  197                 }
  198                 next = GetNextSibling(cur);
  199             }
  200         }
  201         return next;
  202     }
  203 }
  204 
  205 wxTreeItemId wxTreeCtrlEx::GetPrevItemSimple(wxTreeItemId const& item) const
  206 {
  207     wxTreeItemId cur = GetPrevSibling(item);
  208     if (cur.IsOk()) {
  209         while (cur.IsOk() && HasChildren(cur) && IsExpanded(cur)) {
  210             cur = GetLastChild(cur);
  211         }
  212     }
  213     else {
  214         cur = GetItemParent(item);
  215         if (cur.IsOk() && cur == GetRootItem() && (GetWindowStyle() & wxTR_HIDE_ROOT)) {
  216             cur = wxTreeItemId();
  217         }
  218     }
  219     return cur;
  220 }
  221 
  222 int wxTreeCtrlEx::OnCompareItems(wxTreeItemId const& item1, wxTreeItemId const& item2)
  223 {
  224     wxString const& label1 = GetItemText(item1);
  225     wxString const& label2 = GetItemText(item2);
  226     auto const label1v = std::wstring_view(label1.data(), label1.size());
  227     auto const label2v = std::wstring_view(label2.data(), label2.size());
  228 
  229     return sortFunction_(label1v, label2v);
  230 }
  231 
  232 void wxTreeCtrlEx::Resort()
  233 {
  234     std::vector<wxTreeItemId> work;
  235     if (!GetRootItem()) {
  236         return;
  237     }
  238     work.emplace_back(GetRootItem());
  239     while (!work.empty()) {
  240         wxTreeItemId item = work.back();
  241         work.pop_back();
  242         SortChildren(item);
  243         wxTreeItemIdValue cookie;
  244         for (wxTreeItemId child = GetFirstChild(item, cookie); child; child = GetNextSibling(child)) {
  245             work.push_back(child);
  246         }
  247     }
  248 }