From eb00d7623acb1358ce45862f768d1f4d399f1bcd Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 08:06:26 +0000 Subject: [PATCH 01/53] Rename internal tree widget to something more appropriate for a wxListCtrl. --- include/wx/qt/listctrl.h | 4 ++-- src/qt/listctrl.cpp | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/wx/qt/listctrl.h b/include/wx/qt/listctrl.h index 5d3a135fa7..e0f2d1eacf 100644 --- a/include/wx/qt/listctrl.h +++ b/include/wx/qt/listctrl.h @@ -10,7 +10,7 @@ #include "wx/textctrl.h" -class wxQtTreeWidget; +class wxQtListTreeWidget; class QTreeWidgetItem; class WXDLLIMPEXP_FWD_CORE wxImageList; @@ -303,7 +303,7 @@ protected: m_ownsImageListSmall, m_ownsImageListState; private: - wxQtTreeWidget *m_qtTreeWidget; + wxQtListTreeWidget *m_qtTreeWidget; wxDECLARE_DYNAMIC_CLASS( wxListCtrl ); }; diff --git a/src/qt/listctrl.cpp b/src/qt/listctrl.cpp index 2c13dd1f40..500d7b1450 100644 --- a/src/qt/listctrl.cpp +++ b/src/qt/listctrl.cpp @@ -123,10 +123,10 @@ private: wxDECLARE_NO_COPY_CLASS(wxQtItemEditorFactory); }; -class wxQtTreeWidget : public wxQtEventSignalHandler< QTreeWidget, wxListCtrl > +class wxQtListTreeWidget : public wxQtEventSignalHandler< QTreeWidget, wxListCtrl > { public: - wxQtTreeWidget( wxWindow *parent, wxListCtrl *handler ); + wxQtListTreeWidget( wxWindow *parent, wxListCtrl *handler ); void EmitListEvent(wxEventType typ, QTreeWidgetItem *qitem, int column) const; @@ -156,18 +156,18 @@ private: wxQtItemEditorFactory m_editorFactory; }; -wxQtTreeWidget::wxQtTreeWidget( wxWindow *parent, wxListCtrl *handler ) +wxQtListTreeWidget::wxQtListTreeWidget( wxWindow *parent, wxListCtrl *handler ) : wxQtEventSignalHandler< QTreeWidget, wxListCtrl >( parent, handler ), m_editorFactory(handler) { - connect(this, &QTreeWidget::itemClicked, this, &wxQtTreeWidget::itemClicked); - connect(this, &QTreeWidget::itemPressed, this, &wxQtTreeWidget::itemPressed); - connect(this, &QTreeWidget::itemActivated, this, &wxQtTreeWidget::itemActivated); + connect(this, &QTreeWidget::itemClicked, this, &wxQtListTreeWidget::itemClicked); + connect(this, &QTreeWidget::itemPressed, this, &wxQtListTreeWidget::itemPressed); + connect(this, &QTreeWidget::itemActivated, this, &wxQtListTreeWidget::itemActivated); ChangeEditorFactory(); } -void wxQtTreeWidget::EmitListEvent(wxEventType typ, QTreeWidgetItem *qitem, int column) const +void wxQtListTreeWidget::EmitListEvent(wxEventType typ, QTreeWidgetItem *qitem, int column) const { wxListCtrl *handler = GetHandler(); if ( handler ) @@ -187,17 +187,17 @@ void wxQtTreeWidget::EmitListEvent(wxEventType typ, QTreeWidgetItem *qitem, int } } -void wxQtTreeWidget::itemClicked(QTreeWidgetItem *qitem, int column) +void wxQtListTreeWidget::itemClicked(QTreeWidgetItem *qitem, int column) { EmitListEvent(wxEVT_LIST_ITEM_SELECTED, qitem, column); } -void wxQtTreeWidget::itemPressed(QTreeWidgetItem *qitem, int column) +void wxQtListTreeWidget::itemPressed(QTreeWidgetItem *qitem, int column) { EmitListEvent(wxEVT_LIST_ITEM_SELECTED, qitem, column); } -void wxQtTreeWidget::itemActivated(QTreeWidgetItem *qitem, int column) +void wxQtListTreeWidget::itemActivated(QTreeWidgetItem *qitem, int column) { EmitListEvent(wxEVT_LIST_ITEM_ACTIVATED, qitem, column); } @@ -258,7 +258,7 @@ bool wxListCtrl::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { - m_qtTreeWidget = new wxQtTreeWidget( parent, this ); + m_qtTreeWidget = new wxQtListTreeWidget( parent, this ); if (style & wxLC_NO_HEADER) m_qtTreeWidget->setHeaderHidden(true); From 308ef18a6d54e9ea4ff7e6fdb888ab4922f14709 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 08:27:13 +0000 Subject: [PATCH 02/53] Start "native" implementation of wxTreeCtrl for wxQT --- Makefile.in | 43 ++- build/bakefiles/files.bkl | 3 +- build/cmake/files.cmake | 2 + build/files | 2 + include/wx/generic/treectlg.h | 2 +- include/wx/qt/private/converter.h | 11 + include/wx/qt/treectrl.h | 138 ++++---- include/wx/treectrl.h | 4 +- src/qt/treectrl.cpp | 535 +++++++++++++++++++++++++++--- 9 files changed, 616 insertions(+), 124 deletions(-) diff --git a/Makefile.in b/Makefile.in index 91d6281b53..4d55a924fa 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3575,7 +3575,8 @@ COND_TOOLKIT_QT_GUI_HDR = \ wx/generic/activityindicator.h \ wx/qt/dataview.h \ wx/qt/dvrenderers.h \ - $(QT_PLATFORM_HDR) + $(QT_PLATFORM_HDR) \ + wx/qt/treectrl.h @COND_TOOLKIT_QT@GUI_HDR = $(COND_TOOLKIT_QT_GUI_HDR) @COND_TOOLKIT_COCOA@MEDIA_PLATFORM_HDR = @COND_TOOLKIT_GTK@MEDIA_PLATFORM_HDR = @@ -5542,7 +5543,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS = \ monodll_msw_textctrl.o \ monodll_msw_textentry.o \ monodll_msw_tglbtn.o \ - monodll_treectrl.o \ + monodll_msw_treectrl.o \ monodll_systhemectrl.o \ monodll_customdraw.o \ monodll_animateg.o \ @@ -5736,7 +5737,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS = \ monodll_qt_uiaction.o \ monodll_qt_utils.o \ monodll_qt_window.o \ - $(__QT_PLATFORM_SRC_OBJECTS) + $(__QT_PLATFORM_SRC_OBJECTS) \ + monodll_qt_treectrl.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS) COND_PLATFORM_WIN32_1___QT_PLATFORM_SRC_OBJECTS = \ monodll_comimpl.o \ @@ -7521,7 +7523,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS_1 = \ monolib_msw_textctrl.o \ monolib_msw_textentry.o \ monolib_msw_tglbtn.o \ - monolib_treectrl.o \ + monolib_msw_treectrl.o \ monolib_systhemectrl.o \ monolib_customdraw.o \ monolib_animateg.o \ @@ -7715,7 +7717,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1 = \ monolib_qt_uiaction.o \ monolib_qt_utils.o \ monolib_qt_window.o \ - $(__QT_PLATFORM_SRC_OBJECTS_1) + $(__QT_PLATFORM_SRC_OBJECTS_1) \ + monolib_qt_treectrl.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_1 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1) COND_PLATFORM_WIN32_1___QT_PLATFORM_SRC_OBJECTS_1 = \ monolib_comimpl.o \ @@ -9647,7 +9650,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS_2 = \ coredll_msw_textctrl.o \ coredll_msw_textentry.o \ coredll_msw_tglbtn.o \ - coredll_treectrl.o \ + coredll_msw_treectrl.o \ coredll_systhemectrl.o \ coredll_customdraw.o \ coredll_animateg.o \ @@ -9841,7 +9844,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2 = \ coredll_qt_uiaction.o \ coredll_qt_utils.o \ coredll_qt_window.o \ - $(__QT_PLATFORM_SRC_OBJECTS_2) + $(__QT_PLATFORM_SRC_OBJECTS_2) \ + coredll_qt_treectrl.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_2 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2) COND_PLATFORM_WIN32_1___QT_PLATFORM_SRC_OBJECTS_2 = \ coredll_comimpl.o \ @@ -11368,7 +11372,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS_3 = \ corelib_msw_textctrl.o \ corelib_msw_textentry.o \ corelib_msw_tglbtn.o \ - corelib_treectrl.o \ + corelib_msw_treectrl.o \ corelib_systhemectrl.o \ corelib_customdraw.o \ corelib_animateg.o \ @@ -11562,7 +11566,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3 = \ corelib_qt_uiaction.o \ corelib_qt_utils.o \ corelib_qt_window.o \ - $(__QT_PLATFORM_SRC_OBJECTS_3) + $(__QT_PLATFORM_SRC_OBJECTS_3) \ + corelib_qt_treectrl.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_3 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3) COND_PLATFORM_WIN32_1___QT_PLATFORM_SRC_OBJECTS_3 = \ corelib_comimpl.o \ @@ -16338,7 +16343,7 @@ monodll_msw_textentry.o: $(srcdir)/src/msw/textentry.cpp $(MONODLL_ODEP) monodll_msw_tglbtn.o: $(srcdir)/src/msw/tglbtn.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/tglbtn.cpp -monodll_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(MONODLL_ODEP) +monodll_msw_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/treectrl.cpp monodll_systhemectrl.o: $(srcdir)/src/msw/systhemectrl.cpp $(MONODLL_ODEP) @@ -16833,6 +16838,9 @@ monodll_qt_window.o: $(srcdir)/src/qt/window.cpp $(MONODLL_ODEP) monodll_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp +monodll_qt_treectrl.o: $(srcdir)/src/qt/treectrl.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/treectrl.cpp + monodll_univ_anybutton.o: $(srcdir)/src/univ/anybutton.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/univ/anybutton.cpp @@ -21597,7 +21605,7 @@ monolib_msw_textentry.o: $(srcdir)/src/msw/textentry.cpp $(MONOLIB_ODEP) monolib_msw_tglbtn.o: $(srcdir)/src/msw/tglbtn.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/tglbtn.cpp -monolib_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(MONOLIB_ODEP) +monolib_msw_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/treectrl.cpp monolib_systhemectrl.o: $(srcdir)/src/msw/systhemectrl.cpp $(MONOLIB_ODEP) @@ -22092,6 +22100,9 @@ monolib_qt_window.o: $(srcdir)/src/qt/window.cpp $(MONOLIB_ODEP) monolib_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp +monolib_qt_treectrl.o: $(srcdir)/src/qt/treectrl.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/treectrl.cpp + monolib_univ_anybutton.o: $(srcdir)/src/univ/anybutton.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/univ/anybutton.cpp @@ -27516,7 +27527,7 @@ coredll_msw_textentry.o: $(srcdir)/src/msw/textentry.cpp $(COREDLL_ODEP) coredll_msw_tglbtn.o: $(srcdir)/src/msw/tglbtn.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/tglbtn.cpp -coredll_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(COREDLL_ODEP) +coredll_msw_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/treectrl.cpp coredll_systhemectrl.o: $(srcdir)/src/msw/systhemectrl.cpp $(COREDLL_ODEP) @@ -28011,6 +28022,9 @@ coredll_qt_window.o: $(srcdir)/src/qt/window.cpp $(COREDLL_ODEP) coredll_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp +coredll_qt_treectrl.o: $(srcdir)/src/qt/treectrl.cpp $(COREDLL_ODEP) + $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/treectrl.cpp + coredll_univ_anybutton.o: $(srcdir)/src/univ/anybutton.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/univ/anybutton.cpp @@ -31770,7 +31784,7 @@ corelib_msw_textentry.o: $(srcdir)/src/msw/textentry.cpp $(CORELIB_ODEP) corelib_msw_tglbtn.o: $(srcdir)/src/msw/tglbtn.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/tglbtn.cpp -corelib_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(CORELIB_ODEP) +corelib_msw_treectrl.o: $(srcdir)/src/msw/treectrl.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/treectrl.cpp corelib_systhemectrl.o: $(srcdir)/src/msw/systhemectrl.cpp $(CORELIB_ODEP) @@ -32265,6 +32279,9 @@ corelib_qt_window.o: $(srcdir)/src/qt/window.cpp $(CORELIB_ODEP) corelib_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp +corelib_qt_treectrl.o: $(srcdir)/src/qt/treectrl.cpp $(CORELIB_ODEP) + $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/treectrl.cpp + corelib_univ_anybutton.o: $(srcdir)/src/univ/anybutton.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/univ/anybutton.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index b7cc9e1699..d42f8d1621 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -347,7 +347,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/qt/toolbar.h wx/qt/tooltip.h wx/qt/toplevel.h - wx/qt/window.h wx/generic/fdrepdlg.h wx/generic/filepickerg.h @@ -362,6 +361,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/qt/dataview.h wx/qt/dvrenderers.h $(QT_PLATFORM_HDR) + wx/qt/treectrl.h @@ -460,6 +460,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/qt/utils.cpp src/qt/window.cpp $(QT_PLATFORM_SRC) + src/qt/treectrl.cpp diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 75cc4a916f..5d7319af7e 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -276,6 +276,7 @@ set(QT_HDR wx/qt/dataview.h wx/generic/activityindicator.h ${QT_PLATFORM_HDR} + wx/qt/treectrl.h ) set(QT_SRC @@ -374,6 +375,7 @@ set(QT_SRC src/qt/dataview.cpp src/qt/taskbar.cpp ${QT_PLATFORM_SRC} + src/qt/treectrl.cpp ) set(MEDIA_QT_SRC diff --git a/build/files b/build/files index 8df05a9460..fbadb0eb71 100644 --- a/build/files +++ b/build/files @@ -297,6 +297,7 @@ QT_HDR = wx/qt/toolbar.h wx/qt/tooltip.h wx/qt/toplevel.h + wx/qt/treectrl.h wx/qt/window.h QT_SRC= @@ -392,6 +393,7 @@ QT_SRC= src/qt/toolbar.cpp src/qt/tooltip.cpp src/qt/toplevel.cpp + src/qt/treectrl.cpp src/qt/uiaction.cpp src/qt/utils.cpp src/qt/window.cpp diff --git a/include/wx/generic/treectlg.h b/include/wx/generic/treectlg.h index 4fec700066..36843e3924 100644 --- a/include/wx/generic/treectlg.h +++ b/include/wx/generic/treectlg.h @@ -360,7 +360,7 @@ private: wxDECLARE_NO_COPY_CLASS(wxGenericTreeCtrl); }; -#if !defined(__WXMSW__) || defined(__WXUNIVERSAL__) +#if !defined(__WXMSW__) && ! defined(__WXQT__) || defined(__WXUNIVERSAL__) /* * wxTreeCtrl has to be a real class or we have problems with * the run-time information. diff --git a/include/wx/qt/private/converter.h b/include/wx/qt/private/converter.h index 7cdce58fad..c00149a47d 100644 --- a/include/wx/qt/private/converter.h +++ b/include/wx/qt/private/converter.h @@ -19,6 +19,7 @@ #include #include #include +#include // Rely on overloading and let the compiler pick the correct version, which makes // them easier to use then to write wxQtConvertQtRectToWxRect() or wxQtConvertWxRectToQtRect() @@ -54,6 +55,16 @@ inline QString wxQtConvertString( const wxString &str ) return QString( str.utf8_str() ); } +inline wxColour wxQtConvertColour(const QColor &colour) +{ + return wxColour(colour.red(), colour.green(), colour.blue(), colour.alpha()); +} + +inline QColor wxQtConvertColour(const wxColour &colour) +{ + return QColor(colour.Red(), colour.Green(), colour.Blue(), colour.Alpha()); +} + #if wxUSE_DATETIME class WXDLLIMPEXP_FWD_BASE wxDateTime; diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h index 5fdc125ce0..51ecd87ef8 100644 --- a/include/wx/qt/treectrl.h +++ b/include/wx/qt/treectrl.h @@ -28,113 +28,115 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTreeCtrlNameStr); - virtual unsigned int GetCount() const; + virtual unsigned int GetCount() const wxOVERRIDE; - virtual unsigned int GetIndent() const; - virtual void SetIndent(unsigned int indent); + virtual unsigned int GetIndent() const wxOVERRIDE; + virtual void SetIndent(unsigned int indent) wxOVERRIDE; - virtual void SetImageList(wxImageList *imageList); - virtual void SetStateImageList(wxImageList *imageList); + virtual void SetImageList(wxImageList *imageList) wxOVERRIDE; + virtual void SetStateImageList(wxImageList *imageList) wxOVERRIDE; - virtual wxString GetItemText(const wxTreeItemId& item) const; + virtual wxString GetItemText(const wxTreeItemId& item) const wxOVERRIDE; virtual int GetItemImage(const wxTreeItemId& item, - wxTreeItemIcon which = wxTreeItemIcon_Normal) const; - virtual wxTreeItemData *GetItemData(const wxTreeItemId& item) const; - virtual wxColour GetItemTextColour(const wxTreeItemId& item) const; - virtual wxColour GetItemBackgroundColour(const wxTreeItemId& item) const; - virtual wxFont GetItemFont(const wxTreeItemId& item) const; + wxTreeItemIcon which = wxTreeItemIcon_Normal) const wxOVERRIDE; + virtual wxTreeItemData *GetItemData(const wxTreeItemId& item) const wxOVERRIDE; + virtual wxColour GetItemTextColour(const wxTreeItemId& item) const wxOVERRIDE; + virtual wxColour GetItemBackgroundColour(const wxTreeItemId& item) const wxOVERRIDE; + virtual wxFont GetItemFont(const wxTreeItemId& item) const wxOVERRIDE; - virtual void SetItemText(const wxTreeItemId& item, const wxString& text); + virtual void SetItemText(const wxTreeItemId& item, const wxString& text) wxOVERRIDE; virtual void SetItemImage(const wxTreeItemId& item, int image, - wxTreeItemIcon which = wxTreeItemIcon_Normal); - virtual void SetItemData(const wxTreeItemId& item, wxTreeItemData *data); - virtual void SetItemHasChildren(const wxTreeItemId& item, bool has = true); - virtual void SetItemBold(const wxTreeItemId& item, bool bold = true); - virtual void SetItemDropHighlight(const wxTreeItemId& item, bool highlight = true); - virtual void SetItemTextColour(const wxTreeItemId& item, const wxColour& col); - virtual void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& col); - virtual void SetItemFont(const wxTreeItemId& item, const wxFont& font); + wxTreeItemIcon which = wxTreeItemIcon_Normal) wxOVERRIDE; + virtual void SetItemData(const wxTreeItemId& item, wxTreeItemData *data) wxOVERRIDE; + virtual void SetItemHasChildren(const wxTreeItemId& item, bool has = true) wxOVERRIDE; + virtual void SetItemBold(const wxTreeItemId& item, bool bold = true) wxOVERRIDE; + virtual void SetItemDropHighlight(const wxTreeItemId& item, bool highlight = true) wxOVERRIDE; + virtual void SetItemTextColour(const wxTreeItemId& item, const wxColour& col) wxOVERRIDE; + virtual void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& col) wxOVERRIDE; + virtual void SetItemFont(const wxTreeItemId& item, const wxFont& font) wxOVERRIDE; - virtual bool IsVisible(const wxTreeItemId& item) const; - virtual bool ItemHasChildren(const wxTreeItemId& item) const; - virtual bool IsExpanded(const wxTreeItemId& item) const; - virtual bool IsSelected(const wxTreeItemId& item) const; - virtual bool IsBold(const wxTreeItemId& item) const; + virtual bool IsVisible(const wxTreeItemId& item) const wxOVERRIDE; + virtual bool ItemHasChildren(const wxTreeItemId& item) const wxOVERRIDE; + virtual bool IsExpanded(const wxTreeItemId& item) const wxOVERRIDE; + virtual bool IsSelected(const wxTreeItemId& item) const wxOVERRIDE; + virtual bool IsBold(const wxTreeItemId& item) const wxOVERRIDE; - virtual size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = true) const; + virtual size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = true) const wxOVERRIDE; - virtual wxTreeItemId GetRootItem() const; - virtual wxTreeItemId GetSelection() const; - virtual size_t GetSelections(wxArrayTreeItemIds& selections) const; + virtual wxTreeItemId GetRootItem() const wxOVERRIDE; + virtual wxTreeItemId GetSelection() const wxOVERRIDE; + virtual size_t GetSelections(wxArrayTreeItemIds& selections) const wxOVERRIDE; - virtual void SetFocusedItem(const wxTreeItemId& item); - virtual void ClearFocusedItem(); - virtual wxTreeItemId GetFocusedItem() const; + virtual void SetFocusedItem(const wxTreeItemId& item) wxOVERRIDE; + virtual void ClearFocusedItem() wxOVERRIDE; + virtual wxTreeItemId GetFocusedItem() const wxOVERRIDE; - virtual wxTreeItemId GetItemParent(const wxTreeItemId& item) const; - - virtual wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; - virtual wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; - virtual wxTreeItemId GetLastChild(const wxTreeItemId& item) const; - virtual wxTreeItemId GetNextSibling(const wxTreeItemId& item) const; - virtual wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const; - virtual wxTreeItemId GetFirstVisibleItem() const; - virtual wxTreeItemId GetNextVisible(const wxTreeItemId& item) const; - virtual wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const; + virtual wxTreeItemId GetItemParent(const wxTreeItemId& item) const wxOVERRIDE; + + virtual wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const wxOVERRIDE; + virtual wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const wxOVERRIDE; + virtual wxTreeItemId GetLastChild(const wxTreeItemId& item) const wxOVERRIDE; + virtual wxTreeItemId GetNextSibling(const wxTreeItemId& item) const wxOVERRIDE; + virtual wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const wxOVERRIDE; + virtual wxTreeItemId GetFirstVisibleItem() const wxOVERRIDE; + virtual wxTreeItemId GetNextVisible(const wxTreeItemId& item) const wxOVERRIDE; + virtual wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const wxOVERRIDE; virtual wxTreeItemId AddRoot(const wxString& text, int image = -1, int selImage = -1, - wxTreeItemData *data = NULL); + wxTreeItemData *data = NULL) wxOVERRIDE; - virtual void Delete(const wxTreeItemId& item); - virtual void DeleteChildren(const wxTreeItemId& item); - virtual void DeleteAllItems(); + virtual void Delete(const wxTreeItemId& item) wxOVERRIDE; + virtual void DeleteChildren(const wxTreeItemId& item) wxOVERRIDE; + virtual void DeleteAllItems() wxOVERRIDE; - virtual void Expand(const wxTreeItemId& item); - virtual void Collapse(const wxTreeItemId& item); - virtual void CollapseAndReset(const wxTreeItemId& item); - virtual void Toggle(const wxTreeItemId& item); + virtual void Expand(const wxTreeItemId& item) wxOVERRIDE; + virtual void Collapse(const wxTreeItemId& item) wxOVERRIDE; + virtual void CollapseAndReset(const wxTreeItemId& item) wxOVERRIDE; + virtual void Toggle(const wxTreeItemId& item) wxOVERRIDE; - virtual void Unselect(); - virtual void UnselectAll(); - virtual void SelectItem(const wxTreeItemId& item, bool select = true); - virtual void SelectChildren(const wxTreeItemId& parent); + virtual void Unselect() wxOVERRIDE; + virtual void UnselectAll() wxOVERRIDE; + virtual void SelectItem(const wxTreeItemId& item, bool select = true) wxOVERRIDE; + virtual void SelectChildren(const wxTreeItemId& parent) wxOVERRIDE; - virtual void EnsureVisible(const wxTreeItemId& item); - virtual void ScrollTo(const wxTreeItemId& item); + virtual void EnsureVisible(const wxTreeItemId& item) wxOVERRIDE; + virtual void ScrollTo(const wxTreeItemId& item) wxOVERRIDE; - virtual wxTextCtrl *EditLabel(const wxTreeItemId& item, wxClassInfo* textCtrlClass = CLASSINFO(wxTextCtrl)); - virtual wxTextCtrl *GetEditControl() const; - virtual void EndEditLabel(const wxTreeItemId& item, bool discardChanges = false); + virtual wxTextCtrl *EditLabel(const wxTreeItemId& item, wxClassInfo* textCtrlClass = CLASSINFO(wxTextCtrl)) wxOVERRIDE; + virtual wxTextCtrl *GetEditControl() const wxOVERRIDE; + virtual void EndEditLabel(const wxTreeItemId& item, bool discardChanges = false) wxOVERRIDE; - virtual void SortChildren(const wxTreeItemId& item); + virtual void SortChildren(const wxTreeItemId& item) wxOVERRIDE; - virtual bool GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly = false) const; + virtual bool GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly = false) const wxOVERRIDE; - virtual QWidget *GetHandle() const; + virtual QWidget *GetHandle() const wxOVERRIDE; protected: - virtual int DoGetItemState(const wxTreeItemId& item) const; - virtual void DoSetItemState(const wxTreeItemId& item, int state); + virtual int DoGetItemState(const wxTreeItemId& item) const wxOVERRIDE; + virtual void DoSetItemState(const wxTreeItemId& item, int state) wxOVERRIDE; virtual wxTreeItemId DoInsertItem(const wxTreeItemId& parent, size_t pos, const wxString& text, int image, int selImage, - wxTreeItemData *data); + wxTreeItemData *data) wxOVERRIDE; virtual wxTreeItemId DoInsertAfter(const wxTreeItemId& parent, const wxTreeItemId& idPrevious, const wxString& text, int image = -1, int selImage = -1, - wxTreeItemData *data = NULL); + wxTreeItemData *data = NULL) wxOVERRIDE; - virtual wxTreeItemId DoTreeHitTest(const wxPoint& point, int& flags) const; + virtual wxTreeItemId DoTreeHitTest(const wxPoint& point, int& flags) const wxOVERRIDE; private: - QTreeWidget *m_qtTreeWidget; + void SendDeleteEvent(const wxTreeItemId &item); + wxTreeItemId GetNext(const wxTreeItemId &item) const; + QTreeWidget *m_qtTreeWidget; wxDECLARE_DYNAMIC_CLASS(wxTreeCtrl); }; diff --git a/include/wx/treectrl.h b/include/wx/treectrl.h index f73ade7b2a..055a5ad055 100644 --- a/include/wx/treectrl.h +++ b/include/wx/treectrl.h @@ -26,7 +26,7 @@ class WXDLLIMPEXP_FWD_CORE wxImageList; -#if !defined(__WXMSW__) || defined(__WXUNIVERSAL__) +#if !defined(__WXMSW__) && !defined(__WXQT__) || defined(__WXUNIVERSAL__) #define wxHAS_GENERIC_TREECTRL #endif @@ -465,6 +465,8 @@ private: #include "wx/generic/treectlg.h" #elif defined(__WXMSW__) #include "wx/msw/treectrl.h" +#elif defined(__WXQT__) + #include "wx/qt/treectrl.h" #else #error "unknown native wxTreeCtrl implementation" #endif diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index f73a202612..1a8377799f 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -7,12 +7,49 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" - #include "wx/treectrl.h" +#include "wx/qt/private/winevent.h" #include -wxTreeCtrl::wxTreeCtrl() +namespace +{ + class wxQTreeWidget : public wxQtEventSignalHandler + { + public: + wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : + wxQtEventSignalHandler(parent, handler) + { + } + }; + + QTreeWidgetItem *wxQtConvertTreeItem(const wxTreeItemId &item) + { + return static_cast(item.GetID()); + } + + wxTreeItemId wxQtConvertTreeItem(QTreeWidgetItem *item) + { + return wxTreeItemId(item); + } + + size_t CountChildren(QTreeWidgetItem *item) + { + const int currentCount = item->childCount(); + size_t totalCount = currentCount; + + for(int i = 0; i < totalCount; ++i) + { + totalCount += CountChildren(item->child(0)); + } + + return totalCount; + } + +} + +wxTreeCtrl::wxTreeCtrl() : + m_qtTreeWidget(NULL) { } @@ -21,9 +58,9 @@ wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id, const wxSize& size, long style, const wxValidator& validator, - const wxString& name) + const wxString& name) { - Create( parent, id, pos, size, style, validator, name ); + Create(parent, id, pos, size, style, validator, name); } bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, @@ -33,17 +70,16 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxValidator& validator, const wxString& name) { - m_qtTreeWidget = new QTreeWidget( parent->GetHandle() ); + m_qtTreeWidget = new wxQTreeWidget(parent, this); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return QtCreateControl(parent, id, pos, size, style, validator, name); } unsigned wxTreeCtrl::GetCount() const { - return 0; + return m_qtTreeWidget->topLevelItemCount(); } - unsigned wxTreeCtrl::GetIndent() const { return m_qtTreeWidget->columnCount(); @@ -56,247 +92,587 @@ void wxTreeCtrl::SetIndent(unsigned int indent) void wxTreeCtrl::SetImageList(wxImageList *imageList) { + m_imageListNormal = imageList; } void wxTreeCtrl::SetStateImageList(wxImageList *imageList) { + m_imageListState = imageList; } wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const { - return wxString(); + if (!item.IsOk()) + return ""; + + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + return wxQtConvertString(qTreeItem->text(0)); } -int wxTreeCtrl::GetItemImage(const wxTreeItemId& item, - wxTreeItemIcon which) const +int wxTreeCtrl::GetItemImage(const wxTreeItemId& item, wxTreeItemIcon WXUNUSED(which)) const { + wxCHECK_MSG(item.IsOk(), 0, "invalid tree item"); + return 0; } wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const { - return NULL; + wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); + + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + QVariant itemData = qTreeItem->data(0, Qt::UserRole); + void* value = itemData.value(); + return static_cast(value); } wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const { - return wxColour(); + wxCHECK_MSG(item.IsOk(), wxNullColour, "invalid tree item"); + + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + return wxQtConvertColour(qTreeItem->textColor(0)); + } wxColour wxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& item) const { - return wxColour(); + wxCHECK_MSG(item.IsOk(), wxNullColour, "invalid tree item"); + + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + return wxQtConvertColour(qTreeItem->backgroundColor(0)); } wxFont wxTreeCtrl::GetItemFont(const wxTreeItemId& item) const { - return wxFont(); + wxCHECK_MSG(item.IsOk(), wxNullFont, "invalid tree item"); + + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + return wxFont(qTreeItem->font(0)); } void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setText(0, wxQtConvertString(text)); } -void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, - int image, - wxTreeItemIcon which) +void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int WXUNUSED(image), wxTreeItemIcon WXUNUSED(which)) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); } void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + if (data != NULL) + data->SetId(item); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setData(0, Qt::UserRole, QVariant::fromValue(static_cast(data))); } void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setChildIndicatorPolicy(has ? QTreeWidgetItem::ShowIndicator : QTreeWidgetItem::DontShowIndicatorWhenChildless); } void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + QFont font = qTreeItem->font(0); + font.setBold(bold); + qTreeItem->setFont(0, font); } void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + + wxColour fg, bg; + + if (highlight) + { + bg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); + fg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + } + else + { + bg = GetBackgroundColour(); + fg = GetForegroundColour(); + } + + qTreeItem->setBackgroundColor(0, wxQtConvertColour(bg)); + qTreeItem->setTextColor(0, wxQtConvertColour(fg)); } void wxTreeCtrl::SetItemTextColour(const wxTreeItemId& item, const wxColour& col) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setTextColor(0, wxQtConvertColour(col)); } void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& col) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setTextColor(0, wxQtConvertColour(col)); } void wxTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setFont(0, font.GetHandle()); } bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const { - return false; + wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QRect visualRect = m_qtTreeWidget->visualItemRect(qTreeItem); + return visualRect.isValid(); } bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const { - return false; + wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + return qTreeItem->childCount() > 0; } bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const { - return false; + wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + return qTreeItem->isExpanded(); } bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const { - return false; + wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + return qTreeItem->isSelected(); } bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const { - return false; + wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + QFont font = qTreeItem->font(0); + return font.bold(); } size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) const { - return 0; + wxCHECK_MSG(item.IsOk(), 0, "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + + if (recursively) + return CountChildren(qTreeItem); + + return qTreeItem->childCount(); } wxTreeItemId wxTreeCtrl::GetRootItem() const { - return wxTreeItemId(); + QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); + if (HasFlag(wxTR_HIDE_ROOT)) + { + return wxQtConvertTreeItem(root); + } + + if (root->childCount() == 0) + return wxTreeItemId(); + + return wxQtConvertTreeItem(root->child(0)); } wxTreeItemId wxTreeCtrl::GetSelection() const { - return wxTreeItemId(); + QList selections = m_qtTreeWidget->selectedItems(); + return selections.isEmpty() ? wxTreeItemId() : wxQtConvertTreeItem(selections[0]); + } size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const { - return 0; + QList qtSelections = m_qtTreeWidget->selectedItems(); + + const size_t numberOfSelections = qtSelections.size(); + selections.SetCount(numberOfSelections); + + for (size_t i = 0; i < numberOfSelections; ++i) + { + selections[i] = qtSelections[i]; + } + + return numberOfSelections; } void wxTreeCtrl::SetFocusedItem(const wxTreeItemId& item) { - + wxCHECK_RET(item.IsOk(), "invalid tree item"); + m_qtTreeWidget->setCurrentItem(wxQtConvertTreeItem(item), 0); } void wxTreeCtrl::ClearFocusedItem() { - + QTreeWidgetItem *current = m_qtTreeWidget->currentItem(); + if (current != NULL) + current->setSelected(false); } wxTreeItemId wxTreeCtrl::GetFocusedItem() const { - return wxTreeItemId(); + return wxQtConvertTreeItem(m_qtTreeWidget->currentItem()); } wxTreeItemId wxTreeCtrl::GetItemParent(const wxTreeItemId& item) const { - return wxTreeItemId(); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + return wxQtConvertTreeItem(qTreeItem->parent()); } wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const { - return wxTreeItemId(); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + + cookie = 0; + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + + return qTreeItem->childCount() > 0 ? wxQtConvertTreeItem(qTreeItem->child(0)) : wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const { + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + + int currentIndex = reinterpret_cast(cookie); + ++currentIndex; + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + + if ( currentIndex < qTreeItem->childCount() ) + { + cookie = reinterpret_cast(currentIndex); + return wxQtConvertTreeItem(qTreeItem->child(currentIndex)); + } + return wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const { - return wxTreeItemId(); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const int childCount = qTreeItem->childCount(); + return childCount == 0 ? wxTreeItemId() : wxQtConvertTreeItem(qTreeItem->child(childCount - 1)); } wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const { - return wxTreeItemId(); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + QTreeWidgetItem *parent = qTreeItem->parent(); + + if ( parent != NULL ) + { + int index = parent->indexOfChild(qTreeItem); + wxASSERT(index != -1); + + ++index; + return index < parent->childCount() ? wxQtConvertTreeItem(parent->child(index)) : wxTreeItemId(); + } + + int index = m_qtTreeWidget->indexOfTopLevelItem(qTreeItem); + wxASSERT(index != -1); + + ++index; + return index < m_qtTreeWidget->topLevelItemCount() ? wxQtConvertTreeItem(m_qtTreeWidget->topLevelItem(index)) : wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const { - return wxTreeItemId(); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + QTreeWidgetItem *parent = qTreeItem->parent(); + + if (parent != NULL) + { + int index = parent->indexOfChild(qTreeItem); + wxASSERT(index != -1); + + --index; + return index >= 0 ? wxQtConvertTreeItem(parent->child(index)) : wxTreeItemId(); + } + + int index = m_qtTreeWidget->indexOfTopLevelItem(qTreeItem); + wxASSERT(index != -1); + + --index; + return index >= 0 ? wxQtConvertTreeItem(m_qtTreeWidget->topLevelItem(index)) : wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const { + wxTreeItemId itemid = GetRootItem(); + if (!itemid.IsOk()) + return itemid; + do + { + if (IsVisible(itemid)) + return itemid; + itemid = GetNext(itemid); + } while (itemid.IsOk()); + return wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const { + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), wxT("invalid tree item")); + wxASSERT_MSG(IsVisible(item), wxT("this item itself should be visible")); + + wxTreeItemId id = item; + if (id.IsOk()) + { + while (id = GetNext(id), id.IsOk()) + { + if (IsVisible(id)) + return id; + } + } return wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const { - return wxTreeItemId(); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), wxT("invalid tree item")); + wxASSERT_MSG(IsVisible(item), wxT("this item itself should be visible")); + + // find out the starting point + wxTreeItemId prevItem = GetPrevSibling(item); + if (!prevItem.IsOk()) + { + prevItem = GetItemParent(item); + } + + // find the first visible item after it + while (prevItem.IsOk() && !IsVisible(prevItem)) + { + prevItem = GetNext(prevItem); + if (!prevItem.IsOk() || prevItem == item) + { + // there are no visible items before item + return wxTreeItemId(); + } + } + + // from there we must be able to navigate until this item + while (prevItem.IsOk()) + { + const wxTreeItemId nextItem = GetNextVisible(prevItem); + if (!nextItem.IsOk() || nextItem == item) + break; + + prevItem = nextItem; + } + + return prevItem; } wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text, int image, int selImage, wxTreeItemData *data) { - return wxTreeItemId(); + QTreeWidgetItem *item = m_qtTreeWidget->invisibleRootItem(); + + if ( HasFlag(wxTR_HIDE_ROOT) ) + { + item->setText(0, wxQtConvertString(text)); + return wxQtConvertTreeItem(item); + } + + return DoInsertItem(wxQtConvertTreeItem(item), 0, text, image, selImage, data); } void wxTreeCtrl::Delete(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + QTreeWidgetItem *parent = qTreeItem->parent(); + + if ( parent != NULL ) + { + parent->removeChild(qTreeItem); + } + else + { + m_qtTreeWidget->removeItemWidget(qTreeItem, 0); + } + + SendDeleteEvent(item); + + delete qTreeItem; } void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + while (qTreeItem->childCount() > 0) + { + QTreeWidgetItem *child = qTreeItem->child(0); + DeleteChildren(wxQtConvertTreeItem(child)); + qTreeItem->removeChild(child); + + SendDeleteEvent(wxQtConvertTreeItem(child)); + + delete child; + } } void wxTreeCtrl::DeleteAllItems() { + DeleteChildren(wxQtConvertTreeItem(m_qtTreeWidget->invisibleRootItem())); } void wxTreeCtrl::Expand(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setExpanded(true); } void wxTreeCtrl::Collapse(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setExpanded(false); } void wxTreeCtrl::CollapseAndReset(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + Collapse(item); + DeleteChildren(item); } void wxTreeCtrl::Toggle(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setSelected(!qTreeItem->isSelected()); } void wxTreeCtrl::Unselect() { + QTreeWidgetItem *current = m_qtTreeWidget->currentItem(); + + if (current != NULL) + current->setSelected(false); } void wxTreeCtrl::UnselectAll() { + QList selections = m_qtTreeWidget->selectedItems(); + const size_t selectedCount = selections.size(); + for ( size_t i = 0; i < selectedCount; ++i) + { + selections[i]->setSelected(false); + } } void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + if ( !HasFlag(wxTR_MULTIPLE) ) + { + QList selections = m_qtTreeWidget->selectedItems(); + const size_t nSelections = selections.size(); + + for (size_t i = 0; i < nSelections; ++i) + { + selections[i]->setSelected(false); + } + } + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->setSelected(select); } void wxTreeCtrl::SelectChildren(const wxTreeItemId& parent) { + wxCHECK_RET(parent.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(parent); + const int childCount = qTreeItem->childCount(); + + for (int i = 0; i < childCount; ++i) + { + qTreeItem->child(i)->setSelected(true); + } } void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + QTreeWidgetItem *parent = qTreeItem->parent(); + + while ( parent != NULL ) + { + parent->setExpanded(true); + parent = parent->parent(); + } + + ScrollTo(item); } void wxTreeCtrl::ScrollTo(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + m_qtTreeWidget->scrollToItem(qTreeItem); } wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item, wxClassInfo* textCtrlClass) { + wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); return NULL; } @@ -307,24 +683,32 @@ wxTextCtrl *wxTreeCtrl::GetEditControl() const void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool discardChanges) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); } void wxTreeCtrl::SortChildren(const wxTreeItemId& item) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + qTreeItem->sortChildren(0, Qt::AscendingOrder); } bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly) const { + wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); return false; } int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const { + wxCHECK_MSG(item.IsOk(), wxTREE_ITEMSTATE_NONE, "invalid tree item"); return 0; } void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state) { + wxCHECK_RET(item.IsOk(), "invalid tree item"); } wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, @@ -333,7 +717,29 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, int image, int selImage, wxTreeItemData *data) { - return wxTreeItemId(); + wxCHECK_MSG(parent.IsOk(), wxTreeItemId(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(parent); + + QTreeWidgetItem *newItem = new QTreeWidgetItem; + newItem->setText(0, wxQtConvertString(text)); + newItem->setData(0, Qt::UserRole, QVariant::fromValue(static_cast(data))); + + if (pos == static_cast(-1)) + { + qTreeItem->addChild(newItem); + } + else + { + qTreeItem->insertChild(pos, newItem); + } + + wxTreeItemId wxItem = wxQtConvertTreeItem(newItem); + + if (data != NULL) + data->SetId(wxItem); + + return wxItem; } wxTreeItemId wxTreeCtrl::DoInsertAfter(const wxTreeItemId& parent, @@ -342,15 +748,64 @@ wxTreeItemId wxTreeCtrl::DoInsertAfter(const wxTreeItemId& parent, int image, int selImage, wxTreeItemData *data) { - return wxTreeItemId(); + wxCHECK_MSG(parent.IsOk(), wxTreeItemId(), "invalid tree item"); + wxCHECK_MSG(idPrevious.IsOk(), wxTreeItemId(), "invalid tree item"); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(parent); + const int index = qTreeItem->indexOfChild(wxQtConvertTreeItem(idPrevious)); + return DoInsertItem(parent, index + 1, text, image, selImage, data); } wxTreeItemId wxTreeCtrl::DoTreeHitTest(const wxPoint& point, int& flags) const { - return wxTreeItemId(); + int w, h; + GetSize(&w, &h); + flags = 0; + if (point.x < 0) flags |= wxTREE_HITTEST_TOLEFT; + if (point.x > w) flags |= wxTREE_HITTEST_TORIGHT; + if (point.y < 0) flags |= wxTREE_HITTEST_ABOVE; + if (point.y > h) flags |= wxTREE_HITTEST_BELOW; + if (flags) return wxTreeItemId(); + + QTreeWidgetItem *hitItem = m_qtTreeWidget->itemAt(wxQtConvertPoint(point)); + + if (hitItem == NULL) + flags |= wxTREE_HITTEST_NOWHERE; + + return wxQtConvertTreeItem(hitItem); } QWidget *wxTreeCtrl::GetHandle() const { return m_qtTreeWidget; } + +void wxTreeCtrl::SendDeleteEvent(const wxTreeItemId &item) +{ + wxTreeEvent event(wxEVT_TREE_DELETE_ITEM, GetId()); + event.SetItem(item); + HandleWindowEvent(event); +} + +wxTreeItemId wxTreeCtrl::GetNext(const wxTreeItemId &item) const +{ + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), wxT("invalid tree item")); + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + + if ( qTreeItem->childCount() > 0) + { + return qTreeItem->child(0); + } + + // Try a sibling of this or ancestor instead + wxTreeItemId p = item; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } while (p.IsOk() && !toFind.IsOk()); + return toFind; +} + From 8efe01bd8e8751e0bc4b4a781a047380d6bde552 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 13:46:32 +0000 Subject: [PATCH 03/53] Implement basic styles for wxTreeCtrl under wxQT --- include/wx/qt/treectrl.h | 2 ++ src/qt/treectrl.cpp | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h index 51ecd87ef8..88f503374c 100644 --- a/include/wx/qt/treectrl.h +++ b/include/wx/qt/treectrl.h @@ -112,6 +112,8 @@ public: virtual bool GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly = false) const wxOVERRIDE; + virtual void SetWindowStyleFlag(long styles) wxOVERRIDE; + virtual QWidget *GetHandle() const wxOVERRIDE; protected: diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 1a8377799f..c701fb98df 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -71,6 +71,7 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxString& name) { m_qtTreeWidget = new wxQTreeWidget(parent, this); + SetWindowStyleFlag(style); return QtCreateControl(parent, id, pos, size, style, validator, name); } @@ -337,9 +338,7 @@ void wxTreeCtrl::SetFocusedItem(const wxTreeItemId& item) void wxTreeCtrl::ClearFocusedItem() { - QTreeWidgetItem *current = m_qtTreeWidget->currentItem(); - if (current != NULL) - current->setSelected(false); + m_qtTreeWidget->setCurrentItem(NULL); } wxTreeItemId wxTreeCtrl::GetFocusedItem() const @@ -622,11 +621,7 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) { QList selections = m_qtTreeWidget->selectedItems(); const size_t nSelections = selections.size(); - - for (size_t i = 0; i < nSelections; ++i) - { - selections[i]->setSelected(false); - } + m_qtTreeWidget->clearSelection(); } QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); @@ -700,6 +695,13 @@ bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool te return false; } +void wxTreeCtrl::SetWindowStyleFlag(long styles) +{ + wxControl::SetWindowStyleFlag(styles); + m_qtTreeWidget->invisibleRootItem()->setHidden((styles & wxTR_HIDE_ROOT) != 0); + m_qtTreeWidget->setSelectionMode(styles & wxTR_MULTIPLE ? QTreeWidget::MultiSelection : QTreeWidget::SingleSelection); +} + int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), wxTREE_ITEMSTATE_NONE, "invalid tree item"); From 9f1f8636c5c70d68da18af37828785a01f6f1507 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 14:15:36 +0000 Subject: [PATCH 04/53] Fix root relationship --- src/qt/treectrl.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index c701fb98df..01a5efa62d 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -297,14 +297,6 @@ size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) wxTreeItemId wxTreeCtrl::GetRootItem() const { QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); - if (HasFlag(wxTR_HIDE_ROOT)) - { - return wxQtConvertTreeItem(root); - } - - if (root->childCount() == 0) - return wxTreeItemId(); - return wxQtConvertTreeItem(root->child(0)); } @@ -509,15 +501,8 @@ wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text, int image, int selImage, wxTreeItemData *data) { - QTreeWidgetItem *item = m_qtTreeWidget->invisibleRootItem(); - - if ( HasFlag(wxTR_HIDE_ROOT) ) - { - item->setText(0, wxQtConvertString(text)); - return wxQtConvertTreeItem(item); - } - - return DoInsertItem(wxQtConvertTreeItem(item), 0, text, image, selImage, data); + QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); + return DoInsertItem(wxQtConvertTreeItem(root), 0, text, image, selImage, data); } void wxTreeCtrl::Delete(const wxTreeItemId& item) From 2a91c00c1082b1d1d7e0ff27762c8d2487f987b2 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 14:17:45 +0000 Subject: [PATCH 05/53] Add missing d'tor --- include/wx/qt/treectrl.h | 2 ++ src/qt/treectrl.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h index 88f503374c..e256e768af 100644 --- a/include/wx/qt/treectrl.h +++ b/include/wx/qt/treectrl.h @@ -21,6 +21,8 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTreeCtrlNameStr); + virtual ~wxTreeCtrl(); + bool Create(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 01a5efa62d..01de3df9a4 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -76,6 +76,12 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, return QtCreateControl(parent, id, pos, size, style, validator, name); } +wxTreeCtrl::~wxTreeCtrl() +{ + if (m_qtTreeWidget != NULL) + m_qtTreeWidget->deleteLater(); +} + unsigned wxTreeCtrl::GetCount() const { return m_qtTreeWidget->topLevelItemCount(); From 9df2258397beb97a171703915b900c1749510251 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 19:05:40 +0000 Subject: [PATCH 06/53] Fix some failing TreeBookCtrl tests cases --- src/qt/treectrl.cpp | 48 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 01de3df9a4..4ed8960ccf 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -9,6 +9,7 @@ #include "wx/wxprec.h" #include "wx/treectrl.h" #include "wx/qt/private/winevent.h" +#include "wx/imaglist.h" #include @@ -38,14 +39,28 @@ namespace const int currentCount = item->childCount(); size_t totalCount = currentCount; - for(int i = 0; i < totalCount; ++i) + for(int i = 0; i < currentCount; ++i) { - totalCount += CountChildren(item->child(0)); + totalCount += CountChildren(item->child(i)); } return totalCount; } + QIcon::Mode TreeIconToQIconMode(wxTreeItemIcon icon) + { + switch (icon) + { + case wxTreeItemIcon_Normal: + return QIcon::Normal; + case wxTreeItemIcon_Selected: + return QIcon::Selected; + } + + wxFAIL_MSG("Unspported tree icon state"); + return QIcon::Normal; + } + } wxTreeCtrl::wxTreeCtrl() : @@ -84,7 +99,11 @@ wxTreeCtrl::~wxTreeCtrl() unsigned wxTreeCtrl::GetCount() const { - return m_qtTreeWidget->topLevelItemCount(); + QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); + if (root->childCount() == 0) + return 0; + + return CountChildren(root->child(0)); } unsigned wxTreeCtrl::GetIndent() const @@ -116,11 +135,11 @@ wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const return wxQtConvertString(qTreeItem->text(0)); } -int wxTreeCtrl::GetItemImage(const wxTreeItemId& item, wxTreeItemIcon WXUNUSED(which)) const +int wxTreeCtrl::GetItemImage(const wxTreeItemId& item, wxTreeItemIcon which) const { wxCHECK_MSG(item.IsOk(), 0, "invalid tree item"); - return 0; + } wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const @@ -165,9 +184,22 @@ void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text) qTreeItem->setText(0, wxQtConvertString(text)); } -void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int WXUNUSED(image), wxTreeItemIcon WXUNUSED(which)) +void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image, wxTreeItemIcon which) { - wxCHECK_RET(item.IsOk(), "invalid tree item"); + if (m_imageListNormal == NULL) + return; + + if (image == -1) + return; + + wxBitmap bitmap = m_imageListNormal->GetBitmap(image); + wxASSERT(bitmap.IsOk()); + + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + QIcon::Mode mode = TreeIconToQIconMode(which); + QIcon icon = qTreeItem->icon(0); + icon.addPixmap(*bitmap.GetHandle(), mode); + qTreeItem->setIcon(0, icon); } void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) @@ -728,6 +760,8 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, } wxTreeItemId wxItem = wxQtConvertTreeItem(newItem); + SetItemImage(wxItem, image, wxTreeItemIcon_Normal); + SetItemImage(wxItem, selImage, wxTreeItemIcon_Selected); if (data != NULL) data->SetId(wxItem); From c87e959a4a0e9558738d40cb512dfd9d6c889bb5 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 19:49:36 +0000 Subject: [PATCH 07/53] Add test for wxTreeCtrl::GetItemCount() --- tests/controls/treectrltest.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/controls/treectrltest.cpp b/tests/controls/treectrltest.cpp index 433c32ce61..3d03a768eb 100644 --- a/tests/controls/treectrltest.cpp +++ b/tests/controls/treectrltest.cpp @@ -70,6 +70,7 @@ private: CPPUNIT_TEST( SelectItemMulti ); CPPUNIT_TEST( PseudoTest_SetHiddenRoot ); CPPUNIT_TEST( HasChildren ); + CPPUNIT_TEST( GetCount ); CPPUNIT_TEST_SUITE_END(); void ItemClick(); @@ -94,6 +95,7 @@ private: void Sort(); void KeyNavigation(); void HasChildren(); + void GetCount(); void SelectItemSingle(); void SelectItemMulti(); void PseudoTest_MultiSelect() { ms_multiSelect = true; } @@ -175,6 +177,11 @@ void TreeCtrlTestCase::HasChildren() CPPUNIT_ASSERT( !m_tree->HasChildren(m_grandchild) ); } +void TreeCtrlTestCase::GetCount() +{ + CPPUNIT_ASSERT_EQUAL(3, m_tree->GetCount()); +} + void TreeCtrlTestCase::SelectItemSingle() { // this test should be only ran in single-selection control From c7f77ba7655a65ba822ffe878e040a3474b850b0 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 5 Feb 2019 19:50:16 +0000 Subject: [PATCH 08/53] Add signal handlers to generate wx events for wxTreeCtrl under wxQT --- src/qt/treectrl.cpp | 99 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 9 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 4ed8960ccf..4e12939906 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -15,15 +15,6 @@ namespace { - class wxQTreeWidget : public wxQtEventSignalHandler - { - public: - wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : - wxQtEventSignalHandler(parent, handler) - { - } - }; - QTreeWidgetItem *wxQtConvertTreeItem(const wxTreeItemId &item) { return static_cast(item.GetID()); @@ -34,6 +25,96 @@ namespace return wxTreeItemId(item); } + class wxQTreeWidget : public wxQtEventSignalHandler + { + public: + wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : + wxQtEventSignalHandler(parent, handler) + { + connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); + connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); + connect(this, &QTreeWidget::itemClicked, this, &wxQTreeWidget::OnItemClicked); + connect(this, &QTreeWidget::itemCollapsed, this, &wxQTreeWidget::OnItemCollapsed); + connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); + } + + private: + void OnCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) + { + wxTreeEvent changingEvent(wxEVT_TREE_SEL_CHANGING, GetHandler(), wxQtConvertTreeItem(current)); + EmitEvent(changingEvent); + + if ( !changingEvent.IsAllowed() ) + { + blockSignals(true); + setCurrentItem(previous); + blockSignals(false); + return; + } + + wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, GetHandler(), wxQtConvertTreeItem(current)); + EmitEvent(changedEvent); + } + + void OnItemActivated(QTreeWidgetItem *item, int WXUNUSED(column)) + { + wxTreeEvent event(wxEVT_TREE_ITEM_ACTIVATED, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(event); + } + + void OnItemClicked(QTreeWidgetItem *item) + { + wxMouseState mouseState = wxGetMouseState(); + + wxEventType eventType; + if (mouseState.RightIsDown()) + eventType = wxEVT_TREE_ITEM_RIGHT_CLICK; + else if (mouseState.MiddleIsDown()) + eventType = wxEVT_TREE_ITEM_MIDDLE_CLICK; + else + return; + + wxTreeEvent event(eventType, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(event); + } + + void OnItemCollapsed(QTreeWidgetItem *item) + { + wxTreeEvent collapsingEvent(wxEVT_TREE_ITEM_COLLAPSING, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(collapsingEvent); + + if (!collapsingEvent.IsAllowed()) + { + blockSignals(true); + item->setExpanded(true); + blockSignals(false); + return; + } + + wxTreeEvent collapsedEvent(wxEVT_TREE_ITEM_COLLAPSED, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(collapsedEvent); + } + + void OnItemExpanded(QTreeWidgetItem *item) + { + wxTreeEvent expandingEvent(wxEVT_TREE_ITEM_EXPANDING, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(expandingEvent); + + if (!expandingEvent.IsAllowed()) + { + blockSignals(true); + item->setExpanded(false); + blockSignals(false); + return; + } + + wxTreeEvent expandedEvent(wxEVT_TREE_ITEM_EXPANDED, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(expandedEvent); + + } + }; + + size_t CountChildren(QTreeWidgetItem *item) { const int currentCount = item->childCount(); From dee221e2a50cd824b84ef81f42c4a792aac51819 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Wed, 6 Feb 2019 08:32:41 +0000 Subject: [PATCH 09/53] Rename wxQtItemEditorFactory to wxQtTreeItemEditorFactory --- src/qt/listctrl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/listctrl.cpp b/src/qt/listctrl.cpp index 500d7b1450..5209a5db7e 100644 --- a/src/qt/listctrl.cpp +++ b/src/qt/listctrl.cpp @@ -89,10 +89,10 @@ private: // QT doesn't give us direct access to the editor within the QTreeWidget. // Instead, we'll supply a factory to create the widget for QT and keep track // of it ourselves. -class wxQtItemEditorFactory : public QItemEditorFactory +class wxQtTreeItemEditorFactory : public QItemEditorFactory { public: - explicit wxQtItemEditorFactory(wxWindow* parent) + explicit wxQtTreeItemEditorFactory(wxWindow* parent) : m_parent(parent), m_textCtrl(NULL) { @@ -120,7 +120,7 @@ private: wxWindow* m_parent; mutable wxTextCtrl* m_textCtrl; - wxDECLARE_NO_COPY_CLASS(wxQtItemEditorFactory); + wxDECLARE_NO_COPY_CLASS(wxQtTreeItemEditorFactory); }; class wxQtListTreeWidget : public wxQtEventSignalHandler< QTreeWidget, wxListCtrl > @@ -153,7 +153,7 @@ private: qItemDelegate->setItemEditorFactory(&m_editorFactory); } - wxQtItemEditorFactory m_editorFactory; + wxQtTreeItemEditorFactory m_editorFactory; }; wxQtListTreeWidget::wxQtListTreeWidget( wxWindow *parent, wxListCtrl *handler ) From cfe36f7ae75caba07de5978a4e08334fadb62c78 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Wed, 6 Feb 2019 08:57:29 +0000 Subject: [PATCH 10/53] Move wxQtTreeItemEditorFactory to its own header --- Makefile.in | 8 +- build/bakefiles/files.bkl | 6 ++ build/cmake/files.cmake | 6 ++ build/files | 10 ++- include/wx/qt/private/treeitemfactory.h | 100 ++++++++++++++++++++++++ src/qt/listctrl.cpp | 99 +---------------------- 6 files changed, 129 insertions(+), 100 deletions(-) create mode 100644 include/wx/qt/private/treeitemfactory.h diff --git a/Makefile.in b/Makefile.in index 4d55a924fa..2afb48ef2a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3576,7 +3576,13 @@ COND_TOOLKIT_QT_GUI_HDR = \ wx/qt/dataview.h \ wx/qt/dvrenderers.h \ $(QT_PLATFORM_HDR) \ - wx/qt/treectrl.h + wx/qt/treectrl.h \ + wx/qt/private/winevent.h \ + wx/qt/private/converter.h \ + wx/qt/private/treeitemfactory.h \ + wx/qt/private/pointer.h \ + wx/qt/private/timer.h \ + wx/qt/private/utils.h @COND_TOOLKIT_QT@GUI_HDR = $(COND_TOOLKIT_QT_GUI_HDR) @COND_TOOLKIT_COCOA@MEDIA_PLATFORM_HDR = @COND_TOOLKIT_GTK@MEDIA_PLATFORM_HDR = diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index d42f8d1621..f84b961111 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -362,6 +362,12 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/qt/dvrenderers.h $(QT_PLATFORM_HDR) wx/qt/treectrl.h + wx/qt/private/winevent.h + wx/qt/private/converter.h + wx/qt/private/treeitemfactory.h + wx/qt/private/pointer.h + wx/qt/private/timer.h + wx/qt/private/utils.h diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 5d7319af7e..799d7e5b6c 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -277,6 +277,12 @@ set(QT_HDR wx/generic/activityindicator.h ${QT_PLATFORM_HDR} wx/qt/treectrl.h + wx/qt/private/converter.h + wx/qt/private/winevent.h + wx/qt/private/timer.h + wx/qt/private/pointer.h + wx/qt/private/treeitemfactory.h + wx/qt/private/utils.h ) set(QT_SRC diff --git a/build/files b/build/files index fbadb0eb71..9c6e4966d0 100644 --- a/build/files +++ b/build/files @@ -298,7 +298,15 @@ QT_HDR = wx/qt/tooltip.h wx/qt/toplevel.h wx/qt/treectrl.h - wx/qt/window.h + wx/qt/window.h + wx/qt/private/converter.h + wx/qt/private/winevent.h + wx/qt/private/winevent.h + wx/qt/private/converter.h + wx/qt/private/pointer.h + wx/qt/private/timer.h + wx/qt/private/treeitemfactory.h + wx/qt/private/utils.h QT_SRC= $(QT_PLATFORM_SRC) diff --git a/include/wx/qt/private/treeitemfactory.h b/include/wx/qt/private/treeitemfactory.h new file mode 100644 index 0000000000..c2c91c34fa --- /dev/null +++ b/include/wx/qt/private/treeitemfactory.h @@ -0,0 +1,100 @@ +#ifndef _WX_TREEITEM_FACTORY_H_ +#define _WX_TREEITEM_FACTORY_H_ + +#include + +#include "wx/recguard.h" +#include "wx/textctrl.h" + +// wxQT Doesn't have a mechanism for "adopting" external widgets so we have to +// create an instance of wxTextCtrl rather than adopting the control QT would +// create. +// +// Unfortunately the factory is given an internal widget as the parent for +// editor. +// +// To work around these issues we create a wxTextCtl parented by the wxListCtrl +// then recalculate its position relative to the internal widget. +class wxQtListTextCtrl : public wxTextCtrl +{ +public: + wxQtListTextCtrl(wxWindow* parent, QWidget* actualParent) + : wxTextCtrl(parent, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + wxNO_BORDER), + m_actualParent(actualParent), + m_moving(0) + { + + Bind(wxEVT_MOVE, &wxQtListTextCtrl::onMove, this); + } + + void onMove(wxMoveEvent &event) + { + // QWidget::move generates a QMoveEvent so we need to guard against + // reentrant calls. + wxRecursionGuard guard(m_moving); + if (guard.IsInside()) + { + event.Skip(); + return; + } + + const QPoint eventPosition = wxQtConvertPoint(event.GetPosition()); + const QPoint globalPosition = m_actualParent->mapToGlobal(eventPosition); + + // For some reason this always gives us the offset from the header info + // the internal control. So we need to treat this as an offset rather + // than a position. + QWidget* widget = GetHandle(); + const QPoint offset = widget->mapFromGlobal(globalPosition); + + widget->move(eventPosition + offset); + } + +private: + QWidget* m_actualParent; + wxRecursionGuardFlag m_moving; + + wxDECLARE_NO_COPY_CLASS(wxQtListTextCtrl); +}; + +// QT doesn't give us direct access to the editor within the QTreeWidget. +// Instead, we'll supply a factory to create the widget for QT and keep track +// of it ourselves. +class wxQtTreeItemEditorFactory : public QItemEditorFactory +{ +public: + explicit wxQtTreeItemEditorFactory(wxWindow* parent) + : m_parent(parent), + m_textCtrl(NULL) + { + } + + QWidget* createEditor(int WXUNUSED(userType), QWidget* parent) const wxOVERRIDE + { + m_textCtrl = new wxQtListTextCtrl(m_parent, parent); + m_textCtrl->SetFocus(); + return m_textCtrl->GetHandle(); + } + + wxTextCtrl* GetEditControl() + { + return m_textCtrl; + } + + void ClearEditor() + { + delete m_textCtrl; + m_textCtrl = NULL; + } + +private: + wxWindow* m_parent; + mutable wxTextCtrl* m_textCtrl; + + wxDECLARE_NO_COPY_CLASS(wxQtTreeItemEditorFactory); +}; + +#endif //_WX_TREEITEM_FACTORY_H_ + diff --git a/src/qt/listctrl.cpp b/src/qt/listctrl.cpp index 5209a5db7e..e6bbb4d8a2 100644 --- a/src/qt/listctrl.cpp +++ b/src/qt/listctrl.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #ifndef WX_PRECOMP #include "wx/bitmap.h" @@ -23,105 +22,9 @@ #include "wx/listctrl.h" #include "wx/imaglist.h" -#include "wx/recguard.h" #include "wx/qt/private/winevent.h" - -namespace -{ - -// wxQT Doesn't have a mechanism for "adopting" external widgets so we have to -// create an instance of wxTextCtrl rather than adopting the control QT would -// create. -// -// Unfortunately the factory is given an internal widget as the parent for -// editor. -// -// To work around these issues we create a wxTextCtl parented by the wxListCtrl -// then recalculate its position relative to the internal widget. -class wxQtListTextCtrl : public wxTextCtrl -{ -public: - wxQtListTextCtrl(wxWindow* parent, QWidget* actualParent) - : wxTextCtrl(parent, wxID_ANY, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxNO_BORDER), - m_actualParent(actualParent), - m_moving(0) - { - - Bind(wxEVT_MOVE, &wxQtListTextCtrl::onMove, this); - } - - void onMove(wxMoveEvent &event) - { - // QWidget::move generates a QMoveEvent so we need to guard against - // reentrant calls. - wxRecursionGuard guard(m_moving); - if ( guard.IsInside() ) - { - event.Skip(); - return; - } - - const QPoint eventPosition = wxQtConvertPoint(event.GetPosition()); - const QPoint globalPosition = m_actualParent->mapToGlobal(eventPosition); - - // For some reason this always gives us the offset from the header info - // the internal control. So we need to treat this as an offset rather - // than a position. - QWidget* widget = GetHandle(); - const QPoint offset = widget->mapFromGlobal(globalPosition); - - widget->move(eventPosition + offset); - } - -private: - QWidget* m_actualParent; - wxRecursionGuardFlag m_moving; - - wxDECLARE_NO_COPY_CLASS(wxQtListTextCtrl); -}; - -} // anonymous namespace - - -// QT doesn't give us direct access to the editor within the QTreeWidget. -// Instead, we'll supply a factory to create the widget for QT and keep track -// of it ourselves. -class wxQtTreeItemEditorFactory : public QItemEditorFactory -{ -public: - explicit wxQtTreeItemEditorFactory(wxWindow* parent) - : m_parent(parent), - m_textCtrl(NULL) - { - } - - QWidget* createEditor(int WXUNUSED(userType), QWidget* parent) const wxOVERRIDE - { - m_textCtrl = new wxQtListTextCtrl(m_parent, parent); - m_textCtrl->SetFocus(); - return m_textCtrl->GetHandle(); - } - - wxTextCtrl* GetEditControl() - { - return m_textCtrl; - } - - void ClearEditor() - { - delete m_textCtrl; - m_textCtrl = NULL; - } - -private: - wxWindow* m_parent; - mutable wxTextCtrl* m_textCtrl; - - wxDECLARE_NO_COPY_CLASS(wxQtTreeItemEditorFactory); -}; +#include "wx/qt/private/treeitemfactory.h" class wxQtListTreeWidget : public wxQtEventSignalHandler< QTreeWidget, wxListCtrl > { From 57348b4a5914e217446dafcaac5db0906a4e95b3 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Wed, 6 Feb 2019 09:20:13 +0000 Subject: [PATCH 11/53] Add EditControl support for wxTreeCtrl under wxQT --- include/wx/qt/private/treeitemfactory.h | 8 + include/wx/qt/treectrl.h | 4 +- src/qt/treectrl.cpp | 205 +++++++++++++----------- 3 files changed, 120 insertions(+), 97 deletions(-) diff --git a/include/wx/qt/private/treeitemfactory.h b/include/wx/qt/private/treeitemfactory.h index c2c91c34fa..886af1e0a5 100644 --- a/include/wx/qt/private/treeitemfactory.h +++ b/include/wx/qt/private/treeitemfactory.h @@ -2,6 +2,8 @@ #define _WX_TREEITEM_FACTORY_H_ #include +#include +#include #include "wx/recguard.h" #include "wx/textctrl.h" @@ -71,6 +73,12 @@ public: { } + void AttachTo(QTreeWidget *tree) + { + QItemDelegate *qItemDelegate = static_cast(tree->itemDelegate()); + qItemDelegate->setItemEditorFactory(this); + } + QWidget* createEditor(int WXUNUSED(userType), QWidget* parent) const wxOVERRIDE { m_textCtrl = new wxQtListTextCtrl(m_parent, parent); diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h index e256e768af..47c3b1db5b 100644 --- a/include/wx/qt/treectrl.h +++ b/include/wx/qt/treectrl.h @@ -8,7 +8,7 @@ #ifndef _WX_QT_TREECTRL_H_ #define _WX_QT_TREECTRL_H_ -class QTreeWidget; +class wxQTreeWidget; class WXDLLIMPEXP_CORE wxTreeCtrl : public wxTreeCtrlBase { @@ -140,7 +140,7 @@ private: void SendDeleteEvent(const wxTreeItemId &item); wxTreeItemId GetNext(const wxTreeItemId &item) const; - QTreeWidget *m_qtTreeWidget; + wxQTreeWidget *m_qtTreeWidget; wxDECLARE_DYNAMIC_CLASS(wxTreeCtrl); }; diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 4e12939906..3db395ac13 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -8,9 +8,11 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #include "wx/treectrl.h" -#include "wx/qt/private/winevent.h" #include "wx/imaglist.h" +#include "wx/qt/private/winevent.h" +#include "wx/qt/private/treeitemfactory.h" + #include namespace @@ -25,102 +27,12 @@ namespace return wxTreeItemId(item); } - class wxQTreeWidget : public wxQtEventSignalHandler - { - public: - wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : - wxQtEventSignalHandler(parent, handler) - { - connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); - connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); - connect(this, &QTreeWidget::itemClicked, this, &wxQTreeWidget::OnItemClicked); - connect(this, &QTreeWidget::itemCollapsed, this, &wxQTreeWidget::OnItemCollapsed); - connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); - } - - private: - void OnCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) - { - wxTreeEvent changingEvent(wxEVT_TREE_SEL_CHANGING, GetHandler(), wxQtConvertTreeItem(current)); - EmitEvent(changingEvent); - - if ( !changingEvent.IsAllowed() ) - { - blockSignals(true); - setCurrentItem(previous); - blockSignals(false); - return; - } - - wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, GetHandler(), wxQtConvertTreeItem(current)); - EmitEvent(changedEvent); - } - - void OnItemActivated(QTreeWidgetItem *item, int WXUNUSED(column)) - { - wxTreeEvent event(wxEVT_TREE_ITEM_ACTIVATED, GetHandler(), wxQtConvertTreeItem(item)); - EmitEvent(event); - } - - void OnItemClicked(QTreeWidgetItem *item) - { - wxMouseState mouseState = wxGetMouseState(); - - wxEventType eventType; - if (mouseState.RightIsDown()) - eventType = wxEVT_TREE_ITEM_RIGHT_CLICK; - else if (mouseState.MiddleIsDown()) - eventType = wxEVT_TREE_ITEM_MIDDLE_CLICK; - else - return; - - wxTreeEvent event(eventType, GetHandler(), wxQtConvertTreeItem(item)); - EmitEvent(event); - } - - void OnItemCollapsed(QTreeWidgetItem *item) - { - wxTreeEvent collapsingEvent(wxEVT_TREE_ITEM_COLLAPSING, GetHandler(), wxQtConvertTreeItem(item)); - EmitEvent(collapsingEvent); - - if (!collapsingEvent.IsAllowed()) - { - blockSignals(true); - item->setExpanded(true); - blockSignals(false); - return; - } - - wxTreeEvent collapsedEvent(wxEVT_TREE_ITEM_COLLAPSED, GetHandler(), wxQtConvertTreeItem(item)); - EmitEvent(collapsedEvent); - } - - void OnItemExpanded(QTreeWidgetItem *item) - { - wxTreeEvent expandingEvent(wxEVT_TREE_ITEM_EXPANDING, GetHandler(), wxQtConvertTreeItem(item)); - EmitEvent(expandingEvent); - - if (!expandingEvent.IsAllowed()) - { - blockSignals(true); - item->setExpanded(false); - blockSignals(false); - return; - } - - wxTreeEvent expandedEvent(wxEVT_TREE_ITEM_EXPANDED, GetHandler(), wxQtConvertTreeItem(item)); - EmitEvent(expandedEvent); - - } - }; - - size_t CountChildren(QTreeWidgetItem *item) { const int currentCount = item->childCount(); size_t totalCount = currentCount; - for(int i = 0; i < currentCount; ++i) + for (int i = 0; i < currentCount; ++i) { totalCount += CountChildren(item->child(i)); } @@ -141,9 +53,107 @@ namespace wxFAIL_MSG("Unspported tree icon state"); return QIcon::Normal; } - } +class wxQTreeWidget : public wxQtEventSignalHandler +{ +public: + wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : + wxQtEventSignalHandler(parent, handler), + m_editorFactory(handler) + { + connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); + connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); + connect(this, &QTreeWidget::itemClicked, this, &wxQTreeWidget::OnItemClicked); + connect(this, &QTreeWidget::itemCollapsed, this, &wxQTreeWidget::OnItemCollapsed); + connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); + + m_editorFactory.AttachTo(this); + } + + wxTextCtrl *GetEditControl() + { + return m_editorFactory.GetEditControl(); + } + +private: + void OnCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) + { + wxTreeEvent changingEvent(wxEVT_TREE_SEL_CHANGING, GetHandler(), wxQtConvertTreeItem(current)); + EmitEvent(changingEvent); + + if ( !changingEvent.IsAllowed() ) + { + blockSignals(true); + setCurrentItem(previous); + blockSignals(false); + return; + } + + wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, GetHandler(), wxQtConvertTreeItem(current)); + EmitEvent(changedEvent); + } + + void OnItemActivated(QTreeWidgetItem *item, int WXUNUSED(column)) + { + wxTreeEvent event(wxEVT_TREE_ITEM_ACTIVATED, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(event); + } + + void OnItemClicked(QTreeWidgetItem *item) + { + wxMouseState mouseState = wxGetMouseState(); + + wxEventType eventType; + if ( mouseState.RightIsDown() ) + eventType = wxEVT_TREE_ITEM_RIGHT_CLICK; + else if ( mouseState.MiddleIsDown() ) + eventType = wxEVT_TREE_ITEM_MIDDLE_CLICK; + else + return; + + wxTreeEvent event(eventType, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(event); + } + + void OnItemCollapsed(QTreeWidgetItem *item) + { + wxTreeEvent collapsingEvent(wxEVT_TREE_ITEM_COLLAPSING, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(collapsingEvent); + + if ( !collapsingEvent.IsAllowed() ) + { + blockSignals(true); + item->setExpanded(true); + blockSignals(false); + return; + } + + wxTreeEvent collapsedEvent(wxEVT_TREE_ITEM_COLLAPSED, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(collapsedEvent); + } + + void OnItemExpanded(QTreeWidgetItem *item) + { + wxTreeEvent expandingEvent(wxEVT_TREE_ITEM_EXPANDING, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(expandingEvent); + + if ( !expandingEvent.IsAllowed() ) + { + blockSignals(true); + item->setExpanded(false); + blockSignals(false); + return; + } + + wxTreeEvent expandedEvent(wxEVT_TREE_ITEM_EXPANDED, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(expandedEvent); + + } + + wxQtTreeItemEditorFactory m_editorFactory; +}; + wxTreeCtrl::wxTreeCtrl() : m_qtTreeWidget(NULL) { @@ -772,17 +782,22 @@ void wxTreeCtrl::ScrollTo(const wxTreeItemId& item) wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item, wxClassInfo* textCtrlClass) { wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); - return NULL; + + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + m_qtTreeWidget->openPersistentEditor(qTreeItem); + return m_qtTreeWidget->GetEditControl(); } wxTextCtrl *wxTreeCtrl::GetEditControl() const { - return NULL; + return m_qtTreeWidget->GetEditControl(); } void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool discardChanges) { wxCHECK_RET(item.IsOk(), "invalid tree item"); + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + m_qtTreeWidget->closePersistentEditor(qTreeItem); } void wxTreeCtrl::SortChildren(const wxTreeItemId& item) From d2f1e1b61b8dbd67ac201828656ea78209cb01c7 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Wed, 6 Feb 2019 12:55:30 +0000 Subject: [PATCH 12/53] Better support for images in wxTreeCtrl under wxQT --- src/qt/treectrl.cpp | 139 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 32 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 3db395ac13..a213925d59 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -14,6 +14,7 @@ #include "wx/qt/private/treeitemfactory.h" #include +#include namespace { @@ -40,21 +41,34 @@ namespace return totalCount; } - QIcon::Mode TreeIconToQIconMode(wxTreeItemIcon icon) - { - switch (icon) - { - case wxTreeItemIcon_Normal: - return QIcon::Normal; - case wxTreeItemIcon_Selected: - return QIcon::Selected; - } - - wxFAIL_MSG("Unspported tree icon state"); - return QIcon::Normal; - } } + +class ImageState +{ +public: + ImageState() + { + for (int i = wxTreeItemIcon_Normal; i < wxTreeItemIcon_Max; ++i) + { + m_imageStates[i] = -1; + } + } + + int &operator[](size_t index) + { + return m_imageStates[index]; + } + + const int &operator[](size_t index) const + { + return m_imageStates[index]; + } + + int m_imageStates[wxTreeItemIcon_Max]; + +}; + class wxQTreeWidget : public wxQtEventSignalHandler { public: @@ -76,6 +90,34 @@ public: return m_editorFactory.GetEditControl(); } + void SetItemImage(QTreeWidgetItem *item, int image, wxTreeItemIcon which) + { + m_imageStates[item][which] = image; + } + + int GetItemImage(QTreeWidgetItem *item, wxTreeItemIcon which) + { + if (m_imageStates.find(item) == m_imageStates.end()) + return 0; + + return m_imageStates[item][which]; + } + +protected: + void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const wxOVERRIDE + { + QTreeWidgetItem *item = itemFromIndex(index); + + QTreeWidget::drawBranches(painter, rect, index); + const int imageIndex = ChooseBestImage(item); + if (imageIndex != -1 ) + { + wxImageList *imageList = GetHandler()->GetImageList(); + wxBitmap bitmap = imageList->GetBitmap(imageIndex); + painter->drawPixmap(rect.topRight(), *bitmap.GetHandle()); + } + } + private: void OnCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) { @@ -148,10 +190,45 @@ private: wxTreeEvent expandedEvent(wxEVT_TREE_ITEM_EXPANDED, GetHandler(), wxQtConvertTreeItem(item)); EmitEvent(expandedEvent); + } + int ChooseBestImage(QTreeWidgetItem *item) const + { + int imageIndex = -1; + + const ImageStateMap::const_iterator i = m_imageStates.find(item); + + if (i == m_imageStates.end()) + { + return -1; + } + + const ImageState &states = i->second; + + if ( item->isExpanded() ) + { + if ( item->isSelected() ) + imageIndex = states[wxTreeItemIcon_SelectedExpanded]; + + if (imageIndex == -1) + imageIndex = states[wxTreeItemIcon_Expanded]; + } + else + { + if (item->isSelected()) + imageIndex = states[wxTreeItemIcon_Selected]; + } + + if (imageIndex == -1) + imageIndex = states[wxTreeItemIcon_Normal]; + + return imageIndex; } wxQtTreeItemEditorFactory m_editorFactory; + + typedef std::map ImageStateMap; + ImageStateMap m_imageStates; }; wxTreeCtrl::wxTreeCtrl() : @@ -210,11 +287,17 @@ void wxTreeCtrl::SetIndent(unsigned int indent) void wxTreeCtrl::SetImageList(wxImageList *imageList) { m_imageListNormal = imageList; + + int width, height; + m_imageListNormal->GetSize(0, width, height); + m_qtTreeWidget->setIconSize(QSize(width, height)); + m_qtTreeWidget->update(); } void wxTreeCtrl::SetStateImageList(wxImageList *imageList) { m_imageListState = imageList; + m_qtTreeWidget->update(); } wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const @@ -228,9 +311,8 @@ wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const int wxTreeCtrl::GetItemImage(const wxTreeItemId& item, wxTreeItemIcon which) const { - wxCHECK_MSG(item.IsOk(), 0, "invalid tree item"); - return 0; - + wxCHECK_MSG(item.IsOk(), -1, "invalid tree item"); + return m_qtTreeWidget->GetItemImage(wxQtConvertTreeItem(item), which); } wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const @@ -277,20 +359,8 @@ void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text) void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image, wxTreeItemIcon which) { - if (m_imageListNormal == NULL) - return; - - if (image == -1) - return; - - wxBitmap bitmap = m_imageListNormal->GetBitmap(image); - wxASSERT(bitmap.IsOk()); - - QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); - QIcon::Mode mode = TreeIconToQIconMode(which); - QIcon icon = qTreeItem->icon(0); - icon.addPixmap(*bitmap.GetHandle(), mode); - qTreeItem->setIcon(0, icon); + wxCHECK_RET(item.IsOk(), "invalid tree item"); + m_qtTreeWidget->SetItemImage(wxQtConvertTreeItem(item), image, which); } void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) @@ -855,9 +925,14 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, qTreeItem->insertChild(pos, newItem); } + m_qtTreeWidget->SetItemImage(newItem, image, wxTreeItemIcon_Normal); + m_qtTreeWidget->SetItemImage(newItem, selImage, wxTreeItemIcon_Selected); + + QPixmap pixmap(m_qtTreeWidget->iconSize()); + pixmap.fill(Qt::transparent); + newItem->setIcon(0, pixmap); + wxTreeItemId wxItem = wxQtConvertTreeItem(newItem); - SetItemImage(wxItem, image, wxTreeItemIcon_Normal); - SetItemImage(wxItem, selImage, wxTreeItemIcon_Selected); if (data != NULL) data->SetId(wxItem); From 02d47aadfdda74b0f83c9adaf65490e737d53414 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Wed, 6 Feb 2019 13:23:17 +0000 Subject: [PATCH 13/53] Fix wxTreeCtrl::GetSelections for wxQT --- src/qt/treectrl.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index a213925d59..2f5b3c2c75 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -511,11 +511,10 @@ size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const QList qtSelections = m_qtTreeWidget->selectedItems(); const size_t numberOfSelections = qtSelections.size(); - selections.SetCount(numberOfSelections); - for (size_t i = 0; i < numberOfSelections; ++i) { - selections[i] = qtSelections[i]; + QTreeWidgetItem *item = qtSelections[i]; + selections.Add(wxQtConvertTreeItem(item)); } return numberOfSelections; From ab6f8e509236eceb302c320d042f0e6e0ea6fc5d Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Wed, 6 Feb 2019 16:49:43 +0000 Subject: [PATCH 14/53] Prevent "header" row from showing in wxTreeCtrl under wxQT. --- src/qt/treectrl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 2f5b3c2c75..7687714cad 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -14,6 +14,7 @@ #include "wx/qt/private/treeitemfactory.h" #include +#include #include namespace @@ -254,6 +255,8 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxString& name) { m_qtTreeWidget = new wxQTreeWidget(parent, this); + m_qtTreeWidget->header()->hide(); + SetWindowStyleFlag(style); return QtCreateControl(parent, id, pos, size, style, validator, name); From 3342695b9263e4b59a5a48d335f9de422a4f264d Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 08:39:04 +0000 Subject: [PATCH 15/53] Make wxQT wxTreeCtrl selection behave consistently with other wx ports. --- src/qt/treectrl.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 7687714cad..ee4dfcf882 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -122,7 +122,9 @@ protected: private: void OnCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) { - wxTreeEvent changingEvent(wxEVT_TREE_SEL_CHANGING, GetHandler(), wxQtConvertTreeItem(current)); + wxTreeCtrl* treeCtrl = GetHandler(); + + wxTreeEvent changingEvent(wxEVT_TREE_SEL_CHANGING, treeCtrl, wxQtConvertTreeItem(current)); EmitEvent(changingEvent); if ( !changingEvent.IsAllowed() ) @@ -133,8 +135,10 @@ private: return; } - wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, GetHandler(), wxQtConvertTreeItem(current)); - EmitEvent(changedEvent); + //QT doesnt update the selection until this singal has been processed. //Defering this event ensures + //that wxTreeCtrl::GetSelection returns the new selection in the wx event handler. + wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, treeCtrl, wxQtConvertTreeItem(current)); + wxPostEvent(treeCtrl, changedEvent); } void OnItemActivated(QTreeWidgetItem *item, int WXUNUSED(column)) @@ -703,7 +707,10 @@ wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text, wxTreeItemData *data) { QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); - return DoInsertItem(wxQtConvertTreeItem(root), 0, text, image, selImage, data); + wxTreeItemId newItem = DoInsertItem(wxQtConvertTreeItem(root), 0, text, image, selImage, data); + m_qtTreeWidget->setCurrentItem(NULL); + + return newItem; } void wxTreeCtrl::Delete(const wxTreeItemId& item) @@ -890,7 +897,7 @@ void wxTreeCtrl::SetWindowStyleFlag(long styles) { wxControl::SetWindowStyleFlag(styles); m_qtTreeWidget->invisibleRootItem()->setHidden((styles & wxTR_HIDE_ROOT) != 0); - m_qtTreeWidget->setSelectionMode(styles & wxTR_MULTIPLE ? QTreeWidget::MultiSelection : QTreeWidget::SingleSelection); + m_qtTreeWidget->setSelectionMode(styles & wxTR_MULTIPLE ? QTreeWidget::ExtendedSelection : QTreeWidget::SingleSelection); } int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const From 9ba41aecc13d4e90e8ec427c94e8a41fa2e32328 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 08:43:31 +0000 Subject: [PATCH 16/53] Fix build warnings in wxTreeCtrl --- src/qt/treectrl.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index ee4dfcf882..d9cf9e74ac 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -813,7 +813,6 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) if ( !HasFlag(wxTR_MULTIPLE) ) { QList selections = m_qtTreeWidget->selectedItems(); - const size_t nSelections = selections.size(); m_qtTreeWidget->clearSelection(); } @@ -858,7 +857,7 @@ void wxTreeCtrl::ScrollTo(const wxTreeItemId& item) m_qtTreeWidget->scrollToItem(qTreeItem); } -wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item, wxClassInfo* textCtrlClass) +wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item, wxClassInfo* WXUNUSED(textCtrlClass)) { wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); @@ -872,7 +871,7 @@ wxTextCtrl *wxTreeCtrl::GetEditControl() const return m_qtTreeWidget->GetEditControl(); } -void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool discardChanges) +void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool WXUNUSED(discardChanges)) { wxCHECK_RET(item.IsOk(), "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); @@ -887,7 +886,7 @@ void wxTreeCtrl::SortChildren(const wxTreeItemId& item) qTreeItem->sortChildren(0, Qt::AscendingOrder); } -bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly) const +bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& WXUNUSED(rect), bool WXUNUSED(textOnly)) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); return false; @@ -906,7 +905,7 @@ int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const return 0; } -void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state) +void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int WXUNUSED(state)) { wxCHECK_RET(item.IsOk(), "invalid tree item"); } From e8d39f3b5cc990b7906044366f16cebfbaacaccf Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 08:58:38 +0000 Subject: [PATCH 17/53] No buttons image list support for Qt as for MSW. --- samples/treectrl/treetest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 24a4186efd..b4840a6fa0 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -1055,7 +1055,7 @@ void MyTreeCtrl::CreateStateImageList(bool del) AssignStateImageList(states); } -#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) +#if USE_GENERIC_TREECTRL || (!defined(__WXMSW__) && !defined(__WXQT__)) void MyTreeCtrl::CreateButtonsImageList(int size) { if ( size == -1 ) From d9080cd791aa3501c1290be301c29996d44f210a Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 09:08:08 +0000 Subject: [PATCH 18/53] Get initial tree control drag and drop working. Create a new type for tree item data, as it needs to be serialisable for drag and drop, and void* is not. --- src/qt/treectrl.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 4e12939906..6c792050a0 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -15,6 +15,34 @@ namespace { + struct TreeItemDataQt + { + TreeItemDataQt() : data(NULL) + { + } + TreeItemDataQt(wxTreeItemData* data) : data(data) + { + if ( !registered ) + { + qRegisterMetaTypeStreamOperators("TreeItemDataQt"); + registered = true; + } + } + wxTreeItemData *data; + static bool registered; + }; + bool TreeItemDataQt::registered = false; + Q_DECLARE_METATYPE(TreeItemDataQt) + + QDataStream &operator<<(QDataStream &out, const TreeItemDataQt &myObj) + { + return out; + } + QDataStream &operator>>(QDataStream &in, TreeItemDataQt &myObj) + { + return in; + } + QTreeWidgetItem *wxQtConvertTreeItem(const wxTreeItemId &item) { return static_cast(item.GetID()); @@ -36,6 +64,10 @@ namespace connect(this, &QTreeWidget::itemClicked, this, &wxQTreeWidget::OnItemClicked); connect(this, &QTreeWidget::itemCollapsed, this, &wxQTreeWidget::OnItemCollapsed); connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); + + setDragEnabled(true); + viewport()->setAcceptDrops(true); + setDropIndicatorShown(true); } private: @@ -112,6 +144,50 @@ namespace EmitEvent(expandedEvent); } + + virtual void dragEnterEvent(QDragEnterEvent* event) wxOVERRIDE + { + wxEventType command = (event->mouseButtons() & Qt::RightButton) + ? wxEVT_TREE_BEGIN_RDRAG + : wxEVT_TREE_BEGIN_DRAG; + + + QTreeWidgetItem *hitItem = itemAt(event->pos()); + + wxTreeEvent tree_event( + command, + GetHandler(), + wxQtConvertTreeItem(hitItem) + ); + + tree_event.SetPoint(wxQtConvertPoint(event->pos())); + + // Vetoed unless explicitly accepted. + tree_event.Veto(); + + EmitEvent(tree_event); + + if ( tree_event.IsAllowed() ) + { + event->accept(); + } + } + + virtual void dropEvent(QDropEvent* event) wxOVERRIDE + { + const wxPoint pos = wxQtConvertPoint(event->pos()); + QTreeWidgetItem *hitItem = itemAt(event->pos()); + + wxTreeEvent tree_event( + wxEVT_TREE_END_DRAG, + GetHandler(), + wxQtConvertTreeItem(hitItem) + ); + + tree_event.SetPoint(wxQtConvertPoint(event->pos())); + + EmitEvent(tree_event); + } }; @@ -138,7 +214,6 @@ namespace return QIcon::Selected; } - wxFAIL_MSG("Unspported tree icon state"); return QIcon::Normal; } @@ -229,8 +304,8 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); QVariant itemData = qTreeItem->data(0, Qt::UserRole); - void* value = itemData.value(); - return static_cast(value); + TreeItemDataQt value = itemData.value(); + return value.data; } wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const @@ -239,7 +314,6 @@ wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); return wxQtConvertColour(qTreeItem->textColor(0)); - } wxColour wxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& item) const @@ -291,7 +365,8 @@ void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) data->SetId(item); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - qTreeItem->setData(0, Qt::UserRole, QVariant::fromValue(static_cast(data))); + TreeItemDataQt treeItemData(data); + qTreeItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData)); } void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) @@ -829,7 +904,9 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, QTreeWidgetItem *newItem = new QTreeWidgetItem; newItem->setText(0, wxQtConvertString(text)); - newItem->setData(0, Qt::UserRole, QVariant::fromValue(static_cast(data))); + TreeItemDataQt treeItemData(data); + + newItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData)); if (pos == static_cast(-1)) { From 5279d0bca5716c079e8b9c03f6e8b3263a71eb6e Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 10:13:05 +0000 Subject: [PATCH 19/53] Clean up the code after merges. --- src/qt/treectrl.cpp | 78 ++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index d4c9092ab1..c3879d0920 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -38,11 +38,11 @@ namespace bool TreeItemDataQt::registered = false; Q_DECLARE_METATYPE(TreeItemDataQt) - QDataStream &operator<<(QDataStream &out, const TreeItemDataQt &myObj) + QDataStream &operator<<(QDataStream &out, const TreeItemDataQt &) { return out; } - QDataStream &operator>>(QDataStream &in, TreeItemDataQt &myObj) + QDataStream &operator>>(QDataStream &in, TreeItemDataQt &) { return in; } @@ -228,49 +228,49 @@ private: EmitEvent(expandedEvent); } - virtual void dragEnterEvent(QDragEnterEvent* event) wxOVERRIDE + virtual void dragEnterEvent(QDragEnterEvent* event) wxOVERRIDE + { + wxEventType command = (event->mouseButtons() & Qt::RightButton) + ? wxEVT_TREE_BEGIN_RDRAG + : wxEVT_TREE_BEGIN_DRAG; + + + QTreeWidgetItem *hitItem = itemAt(event->pos()); + + wxTreeEvent tree_event( + command, + GetHandler(), + wxQtConvertTreeItem(hitItem) + ); + + tree_event.SetPoint(wxQtConvertPoint(event->pos())); + + // Vetoed unless explicitly accepted. + tree_event.Veto(); + + EmitEvent(tree_event); + + if ( tree_event.IsAllowed() ) { - wxEventType command = (event->mouseButtons() & Qt::RightButton) - ? wxEVT_TREE_BEGIN_RDRAG - : wxEVT_TREE_BEGIN_DRAG; - - - QTreeWidgetItem *hitItem = itemAt(event->pos()); - - wxTreeEvent tree_event( - command, - GetHandler(), - wxQtConvertTreeItem(hitItem) - ); - - tree_event.SetPoint(wxQtConvertPoint(event->pos())); - - // Vetoed unless explicitly accepted. - tree_event.Veto(); - - EmitEvent(tree_event); - - if ( tree_event.IsAllowed() ) - { - event->accept(); - } + event->accept(); } + } - virtual void dropEvent(QDropEvent* event) wxOVERRIDE - { - const wxPoint pos = wxQtConvertPoint(event->pos()); - QTreeWidgetItem *hitItem = itemAt(event->pos()); + virtual void dropEvent(QDropEvent* event) wxOVERRIDE + { + const wxPoint pos = wxQtConvertPoint(event->pos()); + QTreeWidgetItem *hitItem = itemAt(event->pos()); - wxTreeEvent tree_event( - wxEVT_TREE_END_DRAG, - GetHandler(), - wxQtConvertTreeItem(hitItem) - ); + wxTreeEvent tree_event( + wxEVT_TREE_END_DRAG, + GetHandler(), + wxQtConvertTreeItem(hitItem) + ); - tree_event.SetPoint(wxQtConvertPoint(event->pos())); + tree_event.SetPoint(wxQtConvertPoint(event->pos())); - EmitEvent(tree_event); - } + EmitEvent(tree_event); + } int ChooseBestImage(QTreeWidgetItem *item) const { From 5aba98353c837b7de165cad82393820e8ea4c39d Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 10:27:51 +0000 Subject: [PATCH 20/53] Generate event when begin editing tree item. --- src/qt/treectrl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index c3879d0920..1b177d4ad6 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -933,6 +933,10 @@ wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item, wxClassInfo* WXUNUSE { wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); + wxTreeEvent event(wxEVT_TREE_BEGIN_LABEL_EDIT, this, item); + if ( HandleWindowEvent(event) && !event.IsAllowed() ) + return NULL; + QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); m_qtTreeWidget->openPersistentEditor(qTreeItem); return m_qtTreeWidget->GetEditControl(); From 541e7af37452d35a8ccc21199b398528176d97d5 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 11:36:15 +0000 Subject: [PATCH 21/53] Fix wx drag events to actually be keyed off of the Qt dragging state instead of its "drop" events. Add "dropped" state to track whether a drop actually occurred or whether the drag ended unsuccessfully. --- src/qt/treectrl.cpp | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index c3879d0920..30549ed217 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -103,7 +103,8 @@ class wxQTreeWidget : public wxQtEventSignalHandler public: wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : wxQtEventSignalHandler(parent, handler), - m_editorFactory(handler) + m_editorFactory(handler), + m_dropped(false) { connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); @@ -142,7 +143,7 @@ protected: QTreeWidget::drawBranches(painter, rect, index); const int imageIndex = ChooseBestImage(item); - if (imageIndex != -1 ) + if ( imageIndex != -1 ) { wxImageList *imageList = GetHandler()->GetImageList(); wxBitmap bitmap = imageList->GetBitmap(imageIndex); @@ -228,13 +229,14 @@ private: EmitEvent(expandedEvent); } - virtual void dragEnterEvent(QDragEnterEvent* event) wxOVERRIDE + void tryStartDrag(const QMouseEvent *event) { - wxEventType command = (event->mouseButtons() & Qt::RightButton) + m_dropped = false; + + wxEventType command = (event->buttons() & Qt::RightButton) ? wxEVT_TREE_BEGIN_RDRAG : wxEVT_TREE_BEGIN_DRAG; - QTreeWidgetItem *hitItem = itemAt(event->pos()); wxTreeEvent tree_event( @@ -250,13 +252,13 @@ private: EmitEvent(tree_event); - if ( tree_event.IsAllowed() ) + if ( !tree_event.IsAllowed() ) { - event->accept(); + setState(DragSelectingState); } } - virtual void dropEvent(QDropEvent* event) wxOVERRIDE + void endDrag(const QMouseEvent* event) { const wxPoint pos = wxQtConvertPoint(event->pos()); QTreeWidgetItem *hitItem = itemAt(event->pos()); @@ -272,6 +274,32 @@ private: EmitEvent(tree_event); } + virtual void dropEvent(QDropEvent* event) wxOVERRIDE + { + m_dropped = true; + + // We don't want Qt to actually do the drop. + event->ignore(); + } + + virtual void mouseMoveEvent(QMouseEvent *event) wxOVERRIDE + { + const bool wasDragging = state() == DraggingState; + wxQtEventSignalHandler::mouseMoveEvent(event); + const bool nowDragging = state() == DraggingState; + if ( !wasDragging && nowDragging ) + { + tryStartDrag(event); + } + else if ( wasDragging && !nowDragging ) + { + // Only emit "end drag" if we have dropped + // (e.g. not hit escape to cancel). + if ( m_dropped ) + endDrag(event); + } + } + int ChooseBestImage(QTreeWidgetItem *item) const { int imageIndex = -1; @@ -306,6 +334,7 @@ private: typedef std::map ImageStateMap; ImageStateMap m_imageStates; + bool m_dropped; }; wxTreeCtrl::wxTreeCtrl() : From 6dfc243b275e48011655b4747d0db1984fb8bef2 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 11:39:26 +0000 Subject: [PATCH 22/53] Fix up a comment. --- src/qt/treectrl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 30549ed217..2aeabd62c0 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -167,8 +167,10 @@ private: return; } - //QT doesnt update the selection until this singal has been processed. //Defering this event ensures - //that wxTreeCtrl::GetSelection returns the new selection in the wx event handler. + // QT doesn't update the selection until this signal has been + // processed. Deferring this event ensures that + // wxTreeCtrl::GetSelection returns the new selection in the + // wx event handler. wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, treeCtrl, wxQtConvertTreeItem(current)); wxPostEvent(treeCtrl, changedEvent); } From 9566143b580d9d0e5f076c6131518e198913a272 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 12:05:34 +0000 Subject: [PATCH 23/53] Get rid of logic error - no need for state variables and all that, by just doing things at the right time. This fixes the problem of the mouse position being wrong during endDrag. --- src/qt/treectrl.cpp | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 037164aeda..899e63f8c9 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -103,8 +103,7 @@ class wxQTreeWidget : public wxQtEventSignalHandler public: wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : wxQtEventSignalHandler(parent, handler), - m_editorFactory(handler), - m_dropped(false) + m_editorFactory(handler) { connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); @@ -233,8 +232,6 @@ private: void tryStartDrag(const QMouseEvent *event) { - m_dropped = false; - wxEventType command = (event->buttons() & Qt::RightButton) ? wxEVT_TREE_BEGIN_RDRAG : wxEVT_TREE_BEGIN_DRAG; @@ -260,10 +257,11 @@ private: } } - void endDrag(const QMouseEvent* event) + void endDrag(QPoint position) { - const wxPoint pos = wxQtConvertPoint(event->pos()); - QTreeWidgetItem *hitItem = itemAt(event->pos()); + const wxPoint pos = wxQtConvertPoint(position); + QTreeWidgetItem *hitItem = itemAt(position); + OutputDebugStringA(hitItem->text(0).toUtf8().data()); wxTreeEvent tree_event( wxEVT_TREE_END_DRAG, @@ -271,14 +269,14 @@ private: wxQtConvertTreeItem(hitItem) ); - tree_event.SetPoint(wxQtConvertPoint(event->pos())); + tree_event.SetPoint(wxQtConvertPoint(position)); EmitEvent(tree_event); } virtual void dropEvent(QDropEvent* event) wxOVERRIDE { - m_dropped = true; + endDrag(event->pos()); // We don't want Qt to actually do the drop. event->ignore(); @@ -288,18 +286,12 @@ private: { const bool wasDragging = state() == DraggingState; wxQtEventSignalHandler::mouseMoveEvent(event); + const bool nowDragging = state() == DraggingState; if ( !wasDragging && nowDragging ) { tryStartDrag(event); } - else if ( wasDragging && !nowDragging ) - { - // Only emit "end drag" if we have dropped - // (e.g. not hit escape to cancel). - if ( m_dropped ) - endDrag(event); - } } int ChooseBestImage(QTreeWidgetItem *item) const @@ -336,7 +328,6 @@ private: typedef std::map ImageStateMap; ImageStateMap m_imageStates; - bool m_dropped; }; wxTreeCtrl::wxTreeCtrl() : From d8c3a14eee808f98f1e44d2a0727e581b95c95c2 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 13:34:10 +0000 Subject: [PATCH 24/53] Generate wxEVT_TREE_END_LABEL_EDIT when the user has finished editing an item in wxTreeCtrl --- src/qt/treectrl.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 1b177d4ad6..bcfd49cd3b 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -110,6 +110,7 @@ public: connect(this, &QTreeWidget::itemClicked, this, &wxQTreeWidget::OnItemClicked); connect(this, &QTreeWidget::itemCollapsed, this, &wxQTreeWidget::OnItemCollapsed); connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); + connect(this, &QTreeWidget::itemChanged, this, &wxQTreeWidget::OnItemChanged); m_editorFactory.AttachTo(this); setDragEnabled(true); @@ -228,6 +229,12 @@ private: EmitEvent(expandedEvent); } + void OnItemChanged(QTreeWidgetItem *item, int WXUNUSED(column)) + { + wxTreeEvent event(wxEVT_TREE_END_LABEL_EDIT, GetHandler(), wxQtConvertTreeItem(item)); + EmitEvent(event); + } + virtual void dragEnterEvent(QDragEnterEvent* event) wxOVERRIDE { wxEventType command = (event->mouseButtons() & Qt::RightButton) From d597787270277c9e5f2160226a35ee2a548ea4e1 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 13:46:20 +0000 Subject: [PATCH 25/53] Store item state in wxTreeCtrl for wxQT --- src/qt/treectrl.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index bcfd49cd3b..58ee72c1e4 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -76,7 +76,8 @@ namespace class ImageState { public: - ImageState() + ImageState() : + m_state(wxTREE_ITEMSTATE_NONE) { for (int i = wxTreeItemIcon_Normal; i < wxTreeItemIcon_Max; ++i) { @@ -94,7 +95,19 @@ public: return m_imageStates[index]; } + void SetState(int state) + { + m_state = state; + } + + int GetState() const + { + return m_state; + } + +private: int m_imageStates[wxTreeItemIcon_Max]; + int m_state; }; @@ -136,6 +149,20 @@ public: return m_imageStates[item][which]; } + void SetItemState(QTreeWidgetItem *item, int state) + { + m_imageStates[item].SetState(state); + } + + int GetItemState(QTreeWidgetItem *item) const + { + ImageStateMap::const_iterator i = m_imageStates.find(item); + if (i == m_imageStates.end()) + return wxTREE_ITEMSTATE_NONE; + + return i->second.GetState(); + } + protected: void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const wxOVERRIDE { @@ -985,12 +1012,13 @@ void wxTreeCtrl::SetWindowStyleFlag(long styles) int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), wxTREE_ITEMSTATE_NONE, "invalid tree item"); - return 0; + return m_qtTreeWidget->GetItemState(wxQtConvertTreeItem(item)); } -void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int WXUNUSED(state)) +void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state) { wxCHECK_RET(item.IsOk(), "invalid tree item"); + m_qtTreeWidget->SetItemState(wxQtConvertTreeItem(item), state); } wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, From 8c87a43f187510bb61d8e6c172446d6d629dacbe Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 14:04:21 +0000 Subject: [PATCH 26/53] Place holder image is only generated once.. --- src/qt/treectrl.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 927a924c00..702d1ae0b6 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -107,8 +107,7 @@ public: private: int m_imageStates[wxTreeItemIcon_Max]; - int m_state; - + int m_state; }; class wxQTreeWidget : public wxQtEventSignalHandler @@ -124,6 +123,7 @@ public: connect(this, &QTreeWidget::itemCollapsed, this, &wxQTreeWidget::OnItemCollapsed); connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); connect(this, &QTreeWidget::itemChanged, this, &wxQTreeWidget::OnItemChanged); + connect(this, &QTreeWidget::iconSizeChanged, this, &wxQTreeWidget::OnIconSizeChanged); m_editorFactory.AttachTo(this); setDragEnabled(true); @@ -163,6 +163,11 @@ public: return i->second.GetState(); } + QPixmap GetPlaceHolderImage() + { + return m_placeHolderImage; + } + protected: void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const wxOVERRIDE { @@ -265,6 +270,12 @@ private: EmitEvent(event); } + void OnIconSizeChanged(const QSize &size) + { + m_placeHolderImage = QPixmap(size); + m_placeHolderImage.fill(Qt::transparent); + } + void tryStartDrag(const QMouseEvent *event) { wxEventType command = (event->buttons() & Qt::RightButton) @@ -363,6 +374,8 @@ private: typedef std::map ImageStateMap; ImageStateMap m_imageStates; + //Place holder image to reserve enough space in a row for us to draw our icon + QPixmap m_placeHolderImage; }; wxTreeCtrl::wxTreeCtrl() : @@ -1072,9 +1085,7 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, m_qtTreeWidget->SetItemImage(newItem, image, wxTreeItemIcon_Normal); m_qtTreeWidget->SetItemImage(newItem, selImage, wxTreeItemIcon_Selected); - QPixmap pixmap(m_qtTreeWidget->iconSize()); - pixmap.fill(Qt::transparent); - newItem->setIcon(0, pixmap); + newItem->setIcon(0, m_qtTreeWidget->GetPlaceHolderImage()); wxTreeItemId wxItem = wxQtConvertTreeItem(newItem); From 3d89c1e9e85e5741773e876cbf48a7a51b7cb150 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 14:22:21 +0000 Subject: [PATCH 27/53] Set old tree item for selection change events. --- src/qt/treectrl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 702d1ae0b6..717a2cfdb2 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -189,6 +189,7 @@ private: wxTreeCtrl* treeCtrl = GetHandler(); wxTreeEvent changingEvent(wxEVT_TREE_SEL_CHANGING, treeCtrl, wxQtConvertTreeItem(current)); + changingEvent.SetOldItem(wxQtConvertTreeItem(previous)); EmitEvent(changingEvent); if ( !changingEvent.IsAllowed() ) @@ -204,6 +205,7 @@ private: // wxTreeCtrl::GetSelection returns the new selection in the // wx event handler. wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, treeCtrl, wxQtConvertTreeItem(current)); + changedEvent.SetOldItem(wxQtConvertTreeItem(previous)); wxPostEvent(treeCtrl, changedEvent); } From b96cc406f49517f25d2c3a823fdbe6567775a48f Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Thu, 7 Feb 2019 14:24:52 +0000 Subject: [PATCH 28/53] Don't add item to tree until its fully constructed (prevents itemChanged signal from firing). --- src/qt/treectrl.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 717a2cfdb2..fbf261a7a9 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -1075,15 +1075,6 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, newItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData)); - if (pos == static_cast(-1)) - { - qTreeItem->addChild(newItem); - } - else - { - qTreeItem->insertChild(pos, newItem); - } - m_qtTreeWidget->SetItemImage(newItem, image, wxTreeItemIcon_Normal); m_qtTreeWidget->SetItemImage(newItem, selImage, wxTreeItemIcon_Selected); @@ -1094,6 +1085,15 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, if (data != NULL) data->SetId(wxItem); + if (pos == static_cast(-1)) + { + qTreeItem->addChild(newItem); + } + else + { + qTreeItem->insertChild(pos, newItem); + } + return wxItem; } From 2a7d0eebccb8820a1c8aeb0064adb7caa7d48fb0 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 16:26:39 +0000 Subject: [PATCH 29/53] Implement "hide root" properly. --- src/qt/treectrl.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index fbf261a7a9..b693af978d 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -851,9 +851,14 @@ wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text, wxTreeItemData *data) { QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); - wxTreeItemId newItem = DoInsertItem(wxQtConvertTreeItem(root), 0, text, image, selImage, data); + wxTreeItemId newItem = DoInsertItem(wxQtConvertTreeItem(root), 0, text, image, selImage, data); m_qtTreeWidget->setCurrentItem(NULL); + if ( (GetWindowStyleFlag() & wxTR_HIDE_ROOT) != 0 ) + m_qtTreeWidget->setRootIndex(m_qtTreeWidget->model()->index(0, 0)); + else + m_qtTreeWidget->setRootIndex(QModelIndex()); + return newItem; } @@ -1043,7 +1048,7 @@ bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& WXUNUSED(rect void wxTreeCtrl::SetWindowStyleFlag(long styles) { wxControl::SetWindowStyleFlag(styles); - m_qtTreeWidget->invisibleRootItem()->setHidden((styles & wxTR_HIDE_ROOT) != 0); + m_qtTreeWidget->setSelectionMode(styles & wxTR_MULTIPLE ? QTreeWidget::ExtendedSelection : QTreeWidget::SingleSelection); } From 23f6be20c83db8087645abf1e876f51b2284974f Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 17:14:13 +0000 Subject: [PATCH 30/53] Fix SetItemBackgroundColour. --- src/qt/treectrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index b693af978d..03375b2974 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -579,7 +579,7 @@ void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item, const wxColou wxCHECK_RET(item.IsOk(), "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - qTreeItem->setTextColor(0, wxQtConvertColour(col)); + qTreeItem->setBackgroundColor(0, wxQtConvertColour(col)); } void wxTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font) From 99e7da303e9ee1a9657ec12df92e65e1568375af Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 17:37:14 +0000 Subject: [PATCH 31/53] Clean up code before pull request.. --- src/qt/treectrl.cpp | 417 ++++++++++++++++++++++++++++---------------- 1 file changed, 268 insertions(+), 149 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 03375b2974..3a2464a842 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -7,6 +7,11 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + #include "wx/treectrl.h" #include "wx/imaglist.h" @@ -19,79 +24,81 @@ namespace { - struct TreeItemDataQt +struct TreeItemDataQt +{ + TreeItemDataQt() : data(NULL) { - TreeItemDataQt() : data(NULL) + } + + TreeItemDataQt(wxTreeItemData* data) : data(data) + { + if ( !registered ) { + qRegisterMetaTypeStreamOperators("TreeItemDataQt"); + registered = true; } - TreeItemDataQt(wxTreeItemData* data) : data(data) - { - if ( !registered ) - { - qRegisterMetaTypeStreamOperators("TreeItemDataQt"); - registered = true; - } - } - wxTreeItemData *data; - static bool registered; - }; - bool TreeItemDataQt::registered = false; - Q_DECLARE_METATYPE(TreeItemDataQt) - - QDataStream &operator<<(QDataStream &out, const TreeItemDataQt &) - { - return out; - } - QDataStream &operator>>(QDataStream &in, TreeItemDataQt &) - { - return in; } - QTreeWidgetItem *wxQtConvertTreeItem(const wxTreeItemId &item) - { - return static_cast(item.GetID()); - } + wxTreeItemData *data; - wxTreeItemId wxQtConvertTreeItem(QTreeWidgetItem *item) - { - return wxTreeItemId(item); - } + private: + static bool registered; +}; - size_t CountChildren(QTreeWidgetItem *item) - { - const int currentCount = item->childCount(); - size_t totalCount = currentCount; - - for (int i = 0; i < currentCount; ++i) - { - totalCount += CountChildren(item->child(i)); - } - - return totalCount; - } +bool TreeItemDataQt::registered = false; +Q_DECLARE_METATYPE(TreeItemDataQt) +QDataStream &operator<<(QDataStream &out, const TreeItemDataQt &WXUNUSED(obj)) +{ + return out; +} +QDataStream &operator>>(QDataStream &in, TreeItemDataQt &WXUNUSED(obj)) +{ + return in; } +QTreeWidgetItem *wxQtConvertTreeItem(const wxTreeItemId &item) +{ + return static_cast(item.GetID()); +} +wxTreeItemId wxQtConvertTreeItem(QTreeWidgetItem *item) +{ + return wxTreeItemId(item); +} + +size_t CountChildren(QTreeWidgetItem *item) +{ + const int currentCount = item->childCount(); + size_t totalCount = currentCount; + + for ( int i = 0; i < currentCount; ++i ) + { + totalCount += CountChildren(item->child(i)); + } + + return totalCount; +} class ImageState { public: - ImageState() : - m_state(wxTREE_ITEMSTATE_NONE) + ImageState() : m_state(wxTREE_ITEMSTATE_NONE) { - for (int i = wxTreeItemIcon_Normal; i < wxTreeItemIcon_Max; ++i) + for ( int i = wxTreeItemIcon_Normal; i < wxTreeItemIcon_Max; ++i ) { m_imageStates[i] = -1; - } + } } int &operator[](size_t index) { + wxASSERT(index < wxTreeItemIcon_Max); return m_imageStates[index]; } const int &operator[](size_t index) const { + wxASSERT(index < wxTreeItemIcon_Max); return m_imageStates[index]; } @@ -107,9 +114,11 @@ public: private: int m_imageStates[wxTreeItemIcon_Max]; - int m_state; + int m_state; }; +} + class wxQTreeWidget : public wxQtEventSignalHandler { public: @@ -117,13 +126,20 @@ public: wxQtEventSignalHandler(parent, handler), m_editorFactory(handler) { - connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); - connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); - connect(this, &QTreeWidget::itemClicked, this, &wxQTreeWidget::OnItemClicked); - connect(this, &QTreeWidget::itemCollapsed, this, &wxQTreeWidget::OnItemCollapsed); - connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); - connect(this, &QTreeWidget::itemChanged, this, &wxQTreeWidget::OnItemChanged); - connect(this, &QTreeWidget::iconSizeChanged, this, &wxQTreeWidget::OnIconSizeChanged); + connect(this, &QTreeWidget::currentItemChanged, + this, &wxQTreeWidget::OnCurrentItemChanged); + connect(this, &QTreeWidget::itemActivated, + this, &wxQTreeWidget::OnItemActivated); + connect(this, &QTreeWidget::itemClicked, + this, &wxQTreeWidget::OnItemClicked); + connect(this, &QTreeWidget::itemCollapsed, + this, &wxQTreeWidget::OnItemCollapsed); + connect(this, &QTreeWidget::itemExpanded, + this, &wxQTreeWidget::OnItemExpanded); + connect(this, &QTreeWidget::itemChanged, + this, &wxQTreeWidget::OnItemChanged); + connect(this, &QTreeWidget::iconSizeChanged, + this, &wxQTreeWidget::OnIconSizeChanged); m_editorFactory.AttachTo(this); setDragEnabled(true); @@ -143,7 +159,7 @@ public: int GetItemImage(QTreeWidgetItem *item, wxTreeItemIcon which) { - if (m_imageStates.find(item) == m_imageStates.end()) + if ( m_imageStates.find(item) == m_imageStates.end() ) return 0; return m_imageStates[item][which]; @@ -156,39 +172,52 @@ public: int GetItemState(QTreeWidgetItem *item) const { - ImageStateMap::const_iterator i = m_imageStates.find(item); - if (i == m_imageStates.end()) + const ImageStateMap::const_iterator i = m_imageStates.find(item); + if ( i == m_imageStates.end() ) return wxTREE_ITEMSTATE_NONE; return i->second.GetState(); } - QPixmap GetPlaceHolderImage() + QPixmap GetPlaceHolderImage() const { return m_placeHolderImage; } protected: - void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const wxOVERRIDE + void drawBranches( + QPainter *painter, + const QRect &rect, + const QModelIndex &index + ) const wxOVERRIDE { QTreeWidgetItem *item = itemFromIndex(index); QTreeWidget::drawBranches(painter, rect, index); + const int imageIndex = ChooseBestImage(item); if ( imageIndex != -1 ) { - wxImageList *imageList = GetHandler()->GetImageList(); - wxBitmap bitmap = imageList->GetBitmap(imageIndex); + const wxImageList *imageList = GetHandler()->GetImageList(); + const wxBitmap bitmap = imageList->GetBitmap(imageIndex); painter->drawPixmap(rect.topRight(), *bitmap.GetHandle()); } } private: - void OnCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) + void OnCurrentItemChanged( + QTreeWidgetItem *current, + QTreeWidgetItem *previous + ) { wxTreeCtrl* treeCtrl = GetHandler(); - wxTreeEvent changingEvent(wxEVT_TREE_SEL_CHANGING, treeCtrl, wxQtConvertTreeItem(current)); + wxTreeEvent changingEvent( + wxEVT_TREE_SEL_CHANGING, + treeCtrl, + wxQtConvertTreeItem(current) + ); + changingEvent.SetOldItem(wxQtConvertTreeItem(previous)); EmitEvent(changingEvent); @@ -204,14 +233,23 @@ private: // processed. Deferring this event ensures that // wxTreeCtrl::GetSelection returns the new selection in the // wx event handler. - wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, treeCtrl, wxQtConvertTreeItem(current)); + wxTreeEvent changedEvent( + wxEVT_TREE_SEL_CHANGED, + treeCtrl, + wxQtConvertTreeItem(current) + ); changedEvent.SetOldItem(wxQtConvertTreeItem(previous)); wxPostEvent(treeCtrl, changedEvent); } void OnItemActivated(QTreeWidgetItem *item, int WXUNUSED(column)) { - wxTreeEvent event(wxEVT_TREE_ITEM_ACTIVATED, GetHandler(), wxQtConvertTreeItem(item)); + wxTreeEvent event( + wxEVT_TREE_ITEM_ACTIVATED, + GetHandler(), + wxQtConvertTreeItem(item) + ); + EmitEvent(event); } @@ -233,7 +271,11 @@ private: void OnItemCollapsed(QTreeWidgetItem *item) { - wxTreeEvent collapsingEvent(wxEVT_TREE_ITEM_COLLAPSING, GetHandler(), wxQtConvertTreeItem(item)); + wxTreeEvent collapsingEvent( + wxEVT_TREE_ITEM_COLLAPSING, + GetHandler(), + wxQtConvertTreeItem(item) + ); EmitEvent(collapsingEvent); if ( !collapsingEvent.IsAllowed() ) @@ -244,13 +286,21 @@ private: return; } - wxTreeEvent collapsedEvent(wxEVT_TREE_ITEM_COLLAPSED, GetHandler(), wxQtConvertTreeItem(item)); + wxTreeEvent collapsedEvent( + wxEVT_TREE_ITEM_COLLAPSED, + GetHandler(), + wxQtConvertTreeItem(item) + ); EmitEvent(collapsedEvent); } void OnItemExpanded(QTreeWidgetItem *item) { - wxTreeEvent expandingEvent(wxEVT_TREE_ITEM_EXPANDING, GetHandler(), wxQtConvertTreeItem(item)); + wxTreeEvent expandingEvent( + wxEVT_TREE_ITEM_EXPANDING, + GetHandler(), + wxQtConvertTreeItem(item) + ); EmitEvent(expandingEvent); if ( !expandingEvent.IsAllowed() ) @@ -261,14 +311,21 @@ private: return; } - wxTreeEvent expandedEvent(wxEVT_TREE_ITEM_EXPANDED, GetHandler(), wxQtConvertTreeItem(item)); + wxTreeEvent expandedEvent( + wxEVT_TREE_ITEM_EXPANDED, + GetHandler(), + wxQtConvertTreeItem(item) + ); EmitEvent(expandedEvent); } - void OnItemChanged(QTreeWidgetItem *item, int WXUNUSED(column)) { - wxTreeEvent event(wxEVT_TREE_END_LABEL_EDIT, GetHandler(), wxQtConvertTreeItem(item)); + wxTreeEvent event( + wxEVT_TREE_END_LABEL_EDIT, + GetHandler(), + wxQtConvertTreeItem(item) + ); EmitEvent(event); } @@ -280,7 +337,7 @@ private: void tryStartDrag(const QMouseEvent *event) { - wxEventType command = (event->buttons() & Qt::RightButton) + wxEventType command = event->buttons() & Qt::RightButton ? wxEVT_TREE_BEGIN_RDRAG : wxEVT_TREE_BEGIN_DRAG; @@ -309,7 +366,6 @@ private: { const wxPoint pos = wxQtConvertPoint(position); QTreeWidgetItem *hitItem = itemAt(position); - OutputDebugStringA(hitItem->text(0).toUtf8().data()); wxTreeEvent tree_event( wxEVT_TREE_END_DRAG, @@ -348,7 +404,7 @@ private: const ImageStateMap::const_iterator i = m_imageStates.find(item); - if (i == m_imageStates.end()) + if ( i == m_imageStates.end() ) { return -1; } @@ -365,7 +421,7 @@ private: } else { - if (item->isSelected()) + if ( item->isSelected() ) imageIndex = states[wxTreeItemIcon_Selected]; } @@ -376,7 +432,9 @@ private: typedef std::map ImageStateMap; ImageStateMap m_imageStates; - //Place holder image to reserve enough space in a row for us to draw our icon + + // Place holder image to reserve enough space in a row + // for us to draw our icon QPixmap m_placeHolderImage; }; @@ -412,14 +470,14 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, wxTreeCtrl::~wxTreeCtrl() { - if (m_qtTreeWidget != NULL) + if ( m_qtTreeWidget != NULL ) m_qtTreeWidget->deleteLater(); } unsigned wxTreeCtrl::GetCount() const { QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); - if (root->childCount() == 0) + if ( root->childCount() == 0 ) return 0; return CountChildren(root->child(0)); @@ -453,14 +511,17 @@ void wxTreeCtrl::SetStateImageList(wxImageList *imageList) wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const { - if (!item.IsOk()) + if ( !item.IsOk() ) return ""; - QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); return wxQtConvertString(qTreeItem->text(0)); } -int wxTreeCtrl::GetItemImage(const wxTreeItemId& item, wxTreeItemIcon which) const +int wxTreeCtrl::GetItemImage( + const wxTreeItemId& item, + wxTreeItemIcon which +) const { wxCHECK_MSG(item.IsOk(), -1, "invalid tree item"); return m_qtTreeWidget->GetItemImage(wxQtConvertTreeItem(item), which); @@ -470,9 +531,9 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); - QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); - QVariant itemData = qTreeItem->data(0, Qt::UserRole); - TreeItemDataQt value = itemData.value(); + const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + const QVariant itemData = qTreeItem->data(0, Qt::UserRole); + const TreeItemDataQt value = itemData.value(); return value.data; } @@ -480,7 +541,7 @@ wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), wxNullColour, "invalid tree item"); - QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); return wxQtConvertColour(qTreeItem->textColor(0)); } @@ -488,7 +549,7 @@ wxColour wxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), wxNullColour, "invalid tree item"); - QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); return wxQtConvertColour(qTreeItem->backgroundColor(0)); } @@ -496,20 +557,26 @@ wxFont wxTreeCtrl::GetItemFont(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), wxNullFont, "invalid tree item"); - QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); return wxFont(qTreeItem->font(0)); } void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text) { wxCHECK_RET(item.IsOk(), "invalid tree item"); + QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); qTreeItem->setText(0, wxQtConvertString(text)); } -void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image, wxTreeItemIcon which) +void wxTreeCtrl::SetItemImage( + const wxTreeItemId& item, + int image, + wxTreeItemIcon which +) { wxCHECK_RET(item.IsOk(), "invalid tree item"); + m_qtTreeWidget->SetItemImage(wxQtConvertTreeItem(item), image, which); } @@ -517,11 +584,11 @@ void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) { wxCHECK_RET(item.IsOk(), "invalid tree item"); - if (data != NULL) + if ( data != NULL ) data->SetId(item); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - TreeItemDataQt treeItemData(data); + const TreeItemDataQt treeItemData(data); qTreeItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData)); } @@ -530,7 +597,9 @@ void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) wxCHECK_RET(item.IsOk(), "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - qTreeItem->setChildIndicatorPolicy(has ? QTreeWidgetItem::ShowIndicator : QTreeWidgetItem::DontShowIndicatorWhenChildless); + qTreeItem->setChildIndicatorPolicy(has + ? QTreeWidgetItem::ShowIndicator + : QTreeWidgetItem::DontShowIndicatorWhenChildless); } void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold) @@ -551,7 +620,7 @@ void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight) wxColour fg, bg; - if (highlight) + if ( highlight ) { bg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); fg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); @@ -566,7 +635,10 @@ void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight) qTreeItem->setTextColor(0, wxQtConvertColour(fg)); } -void wxTreeCtrl::SetItemTextColour(const wxTreeItemId& item, const wxColour& col) +void wxTreeCtrl::SetItemTextColour( + const wxTreeItemId& item, + const wxColour& col +) { wxCHECK_RET(item.IsOk(), "invalid tree item"); @@ -574,7 +646,10 @@ void wxTreeCtrl::SetItemTextColour(const wxTreeItemId& item, const wxColour& col qTreeItem->setTextColor(0, wxQtConvertColour(col)); } -void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& col) +void wxTreeCtrl::SetItemBackgroundColour( + const wxTreeItemId& item, + const wxColour& col +) { wxCHECK_RET(item.IsOk(), "invalid tree item"); @@ -594,7 +669,7 @@ bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); const QRect visualRect = m_qtTreeWidget->visualItemRect(qTreeItem); return visualRect.isValid(); } @@ -603,7 +678,7 @@ bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); return qTreeItem->childCount() > 0; } @@ -611,7 +686,7 @@ bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); return qTreeItem->isExpanded(); } @@ -619,7 +694,7 @@ bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); return qTreeItem->isSelected(); } @@ -627,18 +702,21 @@ bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - QFont font = qTreeItem->font(0); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QFont font = qTreeItem->font(0); return font.bold(); } -size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) const +size_t wxTreeCtrl::GetChildrenCount( + const wxTreeItemId& item, + bool recursively +) const { wxCHECK_MSG(item.IsOk(), 0, "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - if (recursively) + if ( recursively ) return CountChildren(qTreeItem); return qTreeItem->childCount(); @@ -646,15 +724,16 @@ size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) wxTreeItemId wxTreeCtrl::GetRootItem() const { - QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); + const QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); return wxQtConvertTreeItem(root->child(0)); } wxTreeItemId wxTreeCtrl::GetSelection() const { QList selections = m_qtTreeWidget->selectedItems(); - return selections.isEmpty() ? wxTreeItemId() : wxQtConvertTreeItem(selections[0]); - + return selections.isEmpty() + ? wxTreeItemId() + : wxQtConvertTreeItem(selections[0]); } size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const @@ -662,7 +741,7 @@ size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const QList qtSelections = m_qtTreeWidget->selectedItems(); const size_t numberOfSelections = qtSelections.size(); - for (size_t i = 0; i < numberOfSelections; ++i) + for ( size_t i = 0; i < numberOfSelections; ++i ) { QTreeWidgetItem *item = qtSelections[i]; selections.Add(wxQtConvertTreeItem(item)); @@ -695,24 +774,32 @@ wxTreeItemId wxTreeCtrl::GetItemParent(const wxTreeItemId& item) const return wxQtConvertTreeItem(qTreeItem->parent()); } -wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeCtrl::GetFirstChild( + const wxTreeItemId& item, + wxTreeItemIdValue& cookie +) const { wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); cookie = 0; QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - return qTreeItem->childCount() > 0 ? wxQtConvertTreeItem(qTreeItem->child(0)) : wxTreeItemId(); + return qTreeItem->childCount() > 0 + ? wxQtConvertTreeItem(qTreeItem->child(0)) + : wxTreeItemId(); } -wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeCtrl::GetNextChild( + const wxTreeItemId& item, + wxTreeItemIdValue& cookie +) const { wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); int currentIndex = reinterpret_cast(cookie); ++currentIndex; - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); if ( currentIndex < qTreeItem->childCount() ) { @@ -727,9 +814,11 @@ wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const { wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); const int childCount = qTreeItem->childCount(); - return childCount == 0 ? wxTreeItemId() : wxQtConvertTreeItem(qTreeItem->child(childCount - 1)); + return childCount == 0 + ? wxTreeItemId() + : wxQtConvertTreeItem(qTreeItem->child(childCount - 1)); } wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const @@ -745,14 +834,18 @@ wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const wxASSERT(index != -1); ++index; - return index < parent->childCount() ? wxQtConvertTreeItem(parent->child(index)) : wxTreeItemId(); + return index < parent->childCount() + ? wxQtConvertTreeItem(parent->child(index)) + : wxTreeItemId(); } int index = m_qtTreeWidget->indexOfTopLevelItem(qTreeItem); wxASSERT(index != -1); ++index; - return index < m_qtTreeWidget->topLevelItemCount() ? wxQtConvertTreeItem(m_qtTreeWidget->topLevelItem(index)) : wxTreeItemId(); + return index < m_qtTreeWidget->topLevelItemCount() + ? wxQtConvertTreeItem(m_qtTreeWidget->topLevelItem(index)) + : wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const @@ -762,33 +855,38 @@ wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); QTreeWidgetItem *parent = qTreeItem->parent(); - if (parent != NULL) + if ( parent != NULL ) { int index = parent->indexOfChild(qTreeItem); wxASSERT(index != -1); --index; - return index >= 0 ? wxQtConvertTreeItem(parent->child(index)) : wxTreeItemId(); + return index >= 0 + ? wxQtConvertTreeItem(parent->child(index)) + : wxTreeItemId(); } int index = m_qtTreeWidget->indexOfTopLevelItem(qTreeItem); wxASSERT(index != -1); --index; - return index >= 0 ? wxQtConvertTreeItem(m_qtTreeWidget->topLevelItem(index)) : wxTreeItemId(); + return index >= 0 + ? wxQtConvertTreeItem(m_qtTreeWidget->topLevelItem(index)) + : wxTreeItemId(); } wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const { wxTreeItemId itemid = GetRootItem(); - if (!itemid.IsOk()) + if ( !itemid.IsOk() ) return itemid; + do { if (IsVisible(itemid)) return itemid; itemid = GetNext(itemid); - } while (itemid.IsOk()); + } while ( itemid.IsOk() ); return wxTreeItemId(); } @@ -799,11 +897,11 @@ wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const wxASSERT_MSG(IsVisible(item), wxT("this item itself should be visible")); wxTreeItemId id = item; - if (id.IsOk()) + if ( id.IsOk() ) { - while (id = GetNext(id), id.IsOk()) + while ( id = GetNext(id), id.IsOk() ) { - if (IsVisible(id)) + if ( IsVisible(id) ) return id; } } @@ -817,16 +915,16 @@ wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const // find out the starting point wxTreeItemId prevItem = GetPrevSibling(item); - if (!prevItem.IsOk()) + if ( !prevItem.IsOk() ) { prevItem = GetItemParent(item); } // find the first visible item after it - while (prevItem.IsOk() && !IsVisible(prevItem)) + while ( prevItem.IsOk() && !IsVisible(prevItem) ) { prevItem = GetNext(prevItem); - if (!prevItem.IsOk() || prevItem == item) + if ( !prevItem.IsOk() || prevItem == item ) { // there are no visible items before item return wxTreeItemId(); @@ -834,10 +932,10 @@ wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const } // from there we must be able to navigate until this item - while (prevItem.IsOk()) + while ( prevItem.IsOk() ) { const wxTreeItemId nextItem = GetNextVisible(prevItem); - if (!nextItem.IsOk() || nextItem == item) + if ( !nextItem.IsOk() || nextItem == item ) break; prevItem = nextItem; @@ -851,7 +949,15 @@ wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text, wxTreeItemData *data) { QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem(); - wxTreeItemId newItem = DoInsertItem(wxQtConvertTreeItem(root), 0, text, image, selImage, data); + wxTreeItemId newItem = DoInsertItem( + wxQtConvertTreeItem(root), + 0, + text, + image, + selImage, + data + ); + m_qtTreeWidget->setCurrentItem(NULL); if ( (GetWindowStyleFlag() & wxTR_HIDE_ROOT) != 0 ) @@ -888,7 +994,7 @@ void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item) wxCHECK_RET(item.IsOk(), "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - while (qTreeItem->childCount() > 0) + while ( qTreeItem->childCount() > 0 ) { QTreeWidgetItem *child = qTreeItem->child(0); DeleteChildren(wxQtConvertTreeItem(child)); @@ -941,7 +1047,7 @@ void wxTreeCtrl::Unselect() { QTreeWidgetItem *current = m_qtTreeWidget->currentItem(); - if (current != NULL) + if ( current != NULL ) current->setSelected(false); } @@ -961,7 +1067,6 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) if ( !HasFlag(wxTR_MULTIPLE) ) { - QList selections = m_qtTreeWidget->selectedItems(); m_qtTreeWidget->clearSelection(); } @@ -976,7 +1081,7 @@ void wxTreeCtrl::SelectChildren(const wxTreeItemId& parent) QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(parent); const int childCount = qTreeItem->childCount(); - for (int i = 0; i < childCount; ++i) + for ( int i = 0; i < childCount; ++i ) { qTreeItem->child(i)->setSelected(true); } @@ -1006,7 +1111,10 @@ void wxTreeCtrl::ScrollTo(const wxTreeItemId& item) m_qtTreeWidget->scrollToItem(qTreeItem); } -wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item, wxClassInfo* WXUNUSED(textCtrlClass)) +wxTextCtrl *wxTreeCtrl::EditLabel( + const wxTreeItemId& item, + wxClassInfo* WXUNUSED(textCtrlClass) +) { wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); @@ -1024,7 +1132,10 @@ wxTextCtrl *wxTreeCtrl::GetEditControl() const return m_qtTreeWidget->GetEditControl(); } -void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool WXUNUSED(discardChanges)) +void wxTreeCtrl::EndEditLabel( + const wxTreeItemId& item, + bool WXUNUSED(discardChanges) +) { wxCHECK_RET(item.IsOk(), "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); @@ -1039,7 +1150,11 @@ void wxTreeCtrl::SortChildren(const wxTreeItemId& item) qTreeItem->sortChildren(0, Qt::AscendingOrder); } -bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& WXUNUSED(rect), bool WXUNUSED(textOnly)) const +bool wxTreeCtrl::GetBoundingRect( + const wxTreeItemId& item, + wxRect& WXUNUSED(rect), + bool WXUNUSED(textOnly) +) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); return false; @@ -1049,7 +1164,11 @@ void wxTreeCtrl::SetWindowStyleFlag(long styles) { wxControl::SetWindowStyleFlag(styles); - m_qtTreeWidget->setSelectionMode(styles & wxTR_MULTIPLE ? QTreeWidget::ExtendedSelection : QTreeWidget::SingleSelection); + m_qtTreeWidget->setSelectionMode( + styles & wxTR_MULTIPLE + ? QTreeWidget::ExtendedSelection + : QTreeWidget::SingleSelection + ); } int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const @@ -1076,8 +1195,8 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, QTreeWidgetItem *newItem = new QTreeWidgetItem; newItem->setText(0, wxQtConvertString(text)); - TreeItemDataQt treeItemData(data); + TreeItemDataQt treeItemData(data); newItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData)); m_qtTreeWidget->SetItemImage(newItem, image, wxTreeItemIcon_Normal); @@ -1087,10 +1206,10 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, wxTreeItemId wxItem = wxQtConvertTreeItem(newItem); - if (data != NULL) + if ( data != NULL ) data->SetId(wxItem); - if (pos == static_cast(-1)) + if ( pos == static_cast(-1) ) { qTreeItem->addChild(newItem); } @@ -1111,7 +1230,7 @@ wxTreeItemId wxTreeCtrl::DoInsertAfter(const wxTreeItemId& parent, wxCHECK_MSG(parent.IsOk(), wxTreeItemId(), "invalid tree item"); wxCHECK_MSG(idPrevious.IsOk(), wxTreeItemId(), "invalid tree item"); - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(parent); + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(parent); const int index = qTreeItem->indexOfChild(wxQtConvertTreeItem(idPrevious)); return DoInsertItem(parent, index + 1, text, image, selImage, data); } @@ -1121,11 +1240,12 @@ wxTreeItemId wxTreeCtrl::DoTreeHitTest(const wxPoint& point, int& flags) const int w, h; GetSize(&w, &h); flags = 0; - if (point.x < 0) flags |= wxTREE_HITTEST_TOLEFT; - if (point.x > w) flags |= wxTREE_HITTEST_TORIGHT; - if (point.y < 0) flags |= wxTREE_HITTEST_ABOVE; - if (point.y > h) flags |= wxTREE_HITTEST_BELOW; - if (flags) return wxTreeItemId(); + if ( point.x < 0 ) flags |= wxTREE_HITTEST_TOLEFT; + else if ( point.x > w ) flags |= wxTREE_HITTEST_TORIGHT; + if ( point.y < 0 ) flags |= wxTREE_HITTEST_ABOVE; + else if ( point.y > h ) flags |= wxTREE_HITTEST_BELOW; + if ( flags != 0 ) + return wxTreeItemId(); QTreeWidgetItem *hitItem = m_qtTreeWidget->itemAt(wxQtConvertPoint(point)); @@ -1153,7 +1273,7 @@ wxTreeItemId wxTreeCtrl::GetNext(const wxTreeItemId &item) const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - if ( qTreeItem->childCount() > 0) + if ( qTreeItem->childCount() > 0 ) { return qTreeItem->child(0); } @@ -1165,7 +1285,6 @@ wxTreeItemId wxTreeCtrl::GetNext(const wxTreeItemId &item) const { toFind = GetNextSibling(p); p = GetItemParent(p); - } while (p.IsOk() && !toFind.IsOk()); + } while ( p.IsOk() && !toFind.IsOk() ); return toFind; } - From b7ff45799cf6baf1c5ac106c5c53f9c29b4ccf7a Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Fri, 8 Feb 2019 10:57:08 +0000 Subject: [PATCH 32/53] Clean up file. --- include/wx/qt/private/treeitemfactory.h | 37 +++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/include/wx/qt/private/treeitemfactory.h b/include/wx/qt/private/treeitemfactory.h index 886af1e0a5..94ea97a808 100644 --- a/include/wx/qt/private/treeitemfactory.h +++ b/include/wx/qt/private/treeitemfactory.h @@ -1,3 +1,13 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/treeitemfactory.h +// Purpose: Factory to create text edit controls for the tree items +// Author: Graham Dawes +// Modified by: +// Created: 02/2019 +// Copyright: Graham Dawes +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + #ifndef _WX_TREEITEM_FACTORY_H_ #define _WX_TREEITEM_FACTORY_H_ @@ -17,6 +27,7 @@ // // To work around these issues we create a wxTextCtl parented by the wxListCtrl // then recalculate its position relative to the internal widget. + class wxQtListTextCtrl : public wxTextCtrl { public: @@ -27,7 +38,6 @@ public: m_actualParent(actualParent), m_moving(0) { - Bind(wxEVT_MOVE, &wxQtListTextCtrl::onMove, this); } @@ -36,22 +46,23 @@ public: // QWidget::move generates a QMoveEvent so we need to guard against // reentrant calls. wxRecursionGuard guard(m_moving); - if (guard.IsInside()) + + if ( guard.IsInside() ) { event.Skip(); return; } - const QPoint eventPosition = wxQtConvertPoint(event.GetPosition()); - const QPoint globalPosition = m_actualParent->mapToGlobal(eventPosition); + const QPoint eventPos = wxQtConvertPoint(event.GetPosition()); + const QPoint globalPos = m_actualParent->mapToGlobal(eventPos); // For some reason this always gives us the offset from the header info // the internal control. So we need to treat this as an offset rather // than a position. QWidget* widget = GetHandle(); - const QPoint offset = widget->mapFromGlobal(globalPosition); + const QPoint offset = widget->mapFromGlobal(globalPos); - widget->move(eventPosition + offset); + widget->move(eventPos + offset); } private: @@ -64,29 +75,34 @@ private: // QT doesn't give us direct access to the editor within the QTreeWidget. // Instead, we'll supply a factory to create the widget for QT and keep track // of it ourselves. + class wxQtTreeItemEditorFactory : public QItemEditorFactory { public: explicit wxQtTreeItemEditorFactory(wxWindow* parent) : m_parent(parent), - m_textCtrl(NULL) + m_textCtrl(NULL) { } void AttachTo(QTreeWidget *tree) { - QItemDelegate *qItemDelegate = static_cast(tree->itemDelegate()); + QAbstractItemDelegate* delegate = tree->itemDelegate(); + QItemDelegate *qItemDelegate = static_cast(delegate); qItemDelegate->setItemEditorFactory(this); } - QWidget* createEditor(int WXUNUSED(userType), QWidget* parent) const wxOVERRIDE + virtual QWidget* createEditor( + int WXUNUSED(userType), + QWidget* parent + ) const wxOVERRIDE { m_textCtrl = new wxQtListTextCtrl(m_parent, parent); m_textCtrl->SetFocus(); return m_textCtrl->GetHandle(); } - wxTextCtrl* GetEditControl() + wxTextCtrl* GetEditControl() const { return m_textCtrl; } @@ -105,4 +121,3 @@ private: }; #endif //_WX_TREEITEM_FACTORY_H_ - From b0af9a12b6c88e3601b81d20b4a32a2b2b8c3ab9 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Fri, 8 Feb 2019 11:32:53 +0000 Subject: [PATCH 33/53] Mark a virtual function override as such. --- src/qt/treectrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 3a2464a842..a35efe8cad 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -185,7 +185,7 @@ public: } protected: - void drawBranches( + virtual void drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index From 5e28b51a663d04f5fcbf59b3d33a2c595482da59 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Fri, 8 Feb 2019 11:33:29 +0000 Subject: [PATCH 34/53] Create a simple implementation of GetBoundingRect. --- src/qt/treectrl.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index a35efe8cad..b983b90d29 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -1152,12 +1152,19 @@ void wxTreeCtrl::SortChildren(const wxTreeItemId& item) bool wxTreeCtrl::GetBoundingRect( const wxTreeItemId& item, - wxRect& WXUNUSED(rect), + wxRect& rect, bool WXUNUSED(textOnly) ) const { wxCHECK_MSG(item.IsOk(), false, "invalid tree item"); - return false; + + const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + const QRect visualRect = m_qtTreeWidget->visualItemRect(qTreeItem); + if ( !visualRect.isValid() ) + return false; + + rect = wxQtConvertRect(visualRect); + return true; } void wxTreeCtrl::SetWindowStyleFlag(long styles) From 4cfc55add8e85ee2ac99b139b94751452f4c6024 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Fri, 8 Feb 2019 13:53:21 +0000 Subject: [PATCH 35/53] Fix tab/spacing --- build/files | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/build/files b/build/files index 9c6e4966d0..78c5e6391c 100644 --- a/build/files +++ b/build/files @@ -297,16 +297,16 @@ QT_HDR = wx/qt/toolbar.h wx/qt/tooltip.h wx/qt/toplevel.h - wx/qt/treectrl.h - wx/qt/window.h - wx/qt/private/converter.h - wx/qt/private/winevent.h - wx/qt/private/winevent.h - wx/qt/private/converter.h - wx/qt/private/pointer.h - wx/qt/private/timer.h - wx/qt/private/treeitemfactory.h - wx/qt/private/utils.h + wx/qt/treectrl.h + wx/qt/window.h + wx/qt/private/converter.h + wx/qt/private/winevent.h + wx/qt/private/winevent.h + wx/qt/private/converter.h + wx/qt/private/pointer.h + wx/qt/private/timer.h + wx/qt/private/treeitemfactory.h + wx/qt/private/utils.h QT_SRC= $(QT_PLATFORM_SRC) @@ -401,7 +401,7 @@ QT_SRC= src/qt/toolbar.cpp src/qt/tooltip.cpp src/qt/toplevel.cpp - src/qt/treectrl.cpp + src/qt/treectrl.cpp src/qt/uiaction.cpp src/qt/utils.cpp src/qt/window.cpp From 8844e16b038e234e2c15667431379b501e05f19e Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Fri, 8 Feb 2019 14:03:32 +0000 Subject: [PATCH 36/53] Fix new header. --- include/wx/qt/private/treeitemfactory.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/wx/qt/private/treeitemfactory.h b/include/wx/qt/private/treeitemfactory.h index 94ea97a808..40fd2a343e 100644 --- a/include/wx/qt/private/treeitemfactory.h +++ b/include/wx/qt/private/treeitemfactory.h @@ -1,9 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: wx/treeitemfactory.h +// Name: wx/qt/private/treeitemfactory.h // Purpose: Factory to create text edit controls for the tree items // Author: Graham Dawes -// Modified by: -// Created: 02/2019 +// Created: 2019-02-07 // Copyright: Graham Dawes // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// From 6014eb37ea56ab5973eca3f62309453272f7424f Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Fri, 8 Feb 2019 14:04:27 +0000 Subject: [PATCH 37/53] Fix some stylistic and wxT issues. --- src/qt/treectrl.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index b983b90d29..59ed55fbca 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -883,7 +883,7 @@ wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const do { - if (IsVisible(itemid)) + if ( IsVisible(itemid) ) return itemid; itemid = GetNext(itemid); } while ( itemid.IsOk() ); @@ -893,8 +893,8 @@ wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const { - wxCHECK_MSG(item.IsOk(), wxTreeItemId(), wxT("invalid tree item")); - wxASSERT_MSG(IsVisible(item), wxT("this item itself should be visible")); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + wxASSERT_MSG(IsVisible(item), "this item itself should be visible"); wxTreeItemId id = item; if ( id.IsOk() ) @@ -910,8 +910,8 @@ wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const { - wxCHECK_MSG(item.IsOk(), wxTreeItemId(), wxT("invalid tree item")); - wxASSERT_MSG(IsVisible(item), wxT("this item itself should be visible")); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); + wxASSERT_MSG(IsVisible(item), "this item itself should be visible"); // find out the starting point wxTreeItemId prevItem = GetPrevSibling(item); @@ -1247,16 +1247,22 @@ wxTreeItemId wxTreeCtrl::DoTreeHitTest(const wxPoint& point, int& flags) const int w, h; GetSize(&w, &h); flags = 0; - if ( point.x < 0 ) flags |= wxTREE_HITTEST_TOLEFT; - else if ( point.x > w ) flags |= wxTREE_HITTEST_TORIGHT; - if ( point.y < 0 ) flags |= wxTREE_HITTEST_ABOVE; - else if ( point.y > h ) flags |= wxTREE_HITTEST_BELOW; + if ( point.x < 0 ) + flags |= wxTREE_HITTEST_TOLEFT; + else if ( point.x > w ) + flags |= wxTREE_HITTEST_TORIGHT; + + if ( point.y < 0 ) + flags |= wxTREE_HITTEST_ABOVE; + else if ( point.y > h ) + flags |= wxTREE_HITTEST_BELOW; + if ( flags != 0 ) return wxTreeItemId(); QTreeWidgetItem *hitItem = m_qtTreeWidget->itemAt(wxQtConvertPoint(point)); - if (hitItem == NULL) + if ( hitItem == NULL ) flags |= wxTREE_HITTEST_NOWHERE; return wxQtConvertTreeItem(hitItem); @@ -1276,7 +1282,7 @@ void wxTreeCtrl::SendDeleteEvent(const wxTreeItemId &item) wxTreeItemId wxTreeCtrl::GetNext(const wxTreeItemId &item) const { - wxCHECK_MSG(item.IsOk(), wxTreeItemId(), wxT("invalid tree item")); + wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); From 64826649559938ba10cd67c9841b5a97f0b1f121 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Fri, 8 Feb 2019 14:43:04 +0000 Subject: [PATCH 38/53] Fix build errors when building with gcc --- include/wx/qt/private/converter.h | 1 + src/qt/treectrl.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/wx/qt/private/converter.h b/include/wx/qt/private/converter.h index c00149a47d..fbb4250bd6 100644 --- a/include/wx/qt/private/converter.h +++ b/include/wx/qt/private/converter.h @@ -15,6 +15,7 @@ #include "wx/kbdstate.h" #include "wx/gdicmn.h" +#include "wx/colour.h" #include #include diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 59ed55fbca..b7bca683a6 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -14,6 +14,7 @@ #include "wx/treectrl.h" #include "wx/imaglist.h" +#include "wx/settings.h" #include "wx/qt/private/winevent.h" #include "wx/qt/private/treeitemfactory.h" @@ -46,7 +47,6 @@ struct TreeItemDataQt }; bool TreeItemDataQt::registered = false; -Q_DECLARE_METATYPE(TreeItemDataQt) QDataStream &operator<<(QDataStream &out, const TreeItemDataQt &WXUNUSED(obj)) { @@ -119,11 +119,13 @@ private: } +Q_DECLARE_METATYPE(TreeItemDataQt) + class wxQTreeWidget : public wxQtEventSignalHandler { public: wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : - wxQtEventSignalHandler(parent, handler), + wxQtEventSignalHandler(parent, handler), m_editorFactory(handler) { connect(this, &QTreeWidget::currentItemChanged, @@ -796,7 +798,7 @@ wxTreeItemId wxTreeCtrl::GetNextChild( { wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item"); - int currentIndex = reinterpret_cast(cookie); + wxIntPtr currentIndex = reinterpret_cast(cookie); ++currentIndex; const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); From 5d2663432e0156134db352da14477ae19863b703 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 11 Feb 2019 08:14:25 +0000 Subject: [PATCH 39/53] Delete child items in wxTreeCtrl::Delete under wxQT --- src/qt/treectrl.cpp | 2 ++ tests/controls/treectrltest.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index b7bca683a6..16600c43a9 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -977,6 +977,8 @@ void wxTreeCtrl::Delete(const wxTreeItemId& item) QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); QTreeWidgetItem *parent = qTreeItem->parent(); + DeleteChildren(qTreeItem); + if ( parent != NULL ) { parent->removeChild(qTreeItem); diff --git a/tests/controls/treectrltest.cpp b/tests/controls/treectrltest.cpp index 3d03a768eb..2b1cd2e2ed 100644 --- a/tests/controls/treectrltest.cpp +++ b/tests/controls/treectrltest.cpp @@ -279,9 +279,10 @@ void TreeCtrlTestCase::DeleteItem() EventCounter deleteitem(m_tree, wxEVT_TREE_DELETE_ITEM); wxTreeItemId todelete = m_tree->AppendItem(m_root, "deleteme"); + m_tree->AppendItem(todelete, "deleteme2"); m_tree->Delete(todelete); - CPPUNIT_ASSERT_EQUAL(1, deleteitem.GetCount()); + CPPUNIT_ASSERT_EQUAL(2, deleteitem.GetCount()); } void TreeCtrlTestCase::DeleteChildren() From d0f71da55b53a6938517d68a5d2e8618b84b63a1 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 11 Feb 2019 08:15:37 +0000 Subject: [PATCH 40/53] Fix build warning --- src/qt/treectrl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 16600c43a9..d83fa88673 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -366,7 +366,6 @@ private: void endDrag(QPoint position) { - const wxPoint pos = wxQtConvertPoint(position); QTreeWidgetItem *hitItem = itemAt(position); wxTreeEvent tree_event( From 8ab2d9c94492dfd46ff2436c6ef18329239746a2 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 11 Feb 2019 09:08:43 +0000 Subject: [PATCH 41/53] Fix incorrect icon being drawn in wxTreeCtrl --- src/qt/treectrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index d83fa88673..984b0d653e 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -426,7 +426,7 @@ private: imageIndex = states[wxTreeItemIcon_Selected]; } - return QIcon::Normal; + return imageIndex; } wxQtTreeItemEditorFactory m_editorFactory; From 814158610240cc43f94d0388e464849a94f16cb5 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 11 Feb 2019 13:00:42 +0000 Subject: [PATCH 42/53] Correct restoration of tree icon logic --- src/qt/treectrl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 984b0d653e..81e1b29145 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -426,6 +426,9 @@ private: imageIndex = states[wxTreeItemIcon_Selected]; } + if ( imageIndex == -1 ) + imageIndex = states[wxTreeItemIcon_Normal]; + return imageIndex; } From 6ead20624ac0ebb2f22065738fb0b39099f407cc Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 11 Feb 2019 13:50:55 +0000 Subject: [PATCH 43/53] Fix wxQT wxTreeCtrl drawing issues under Linux --- src/qt/treectrl.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 81e1b29145..721cae4356 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -149,6 +149,14 @@ public: setDropIndicatorShown(true); } + virtual void paintEvent (QPaintEvent * event) + { + //QT generates warnings if we try to paint to a QTreeWidget + //(perhaps because it's a compound widget) so we've disabled + //wx paint and erase background events + QTreeWidget::paintEvent(event); + } + wxTextCtrl *GetEditControl() { return m_editorFactory.GetEditControl(); @@ -187,22 +195,24 @@ public: } protected: - virtual void drawBranches( + virtual void drawRow( QPainter *painter, - const QRect &rect, + const QStyleOptionViewItem &options, const QModelIndex &index + ) const wxOVERRIDE { + QTreeWidget::drawRow(painter, options, index); + QTreeWidgetItem *item = itemFromIndex(index); - - QTreeWidget::drawBranches(painter, rect, index); - const int imageIndex = ChooseBestImage(item); + if ( imageIndex != -1 ) { const wxImageList *imageList = GetHandler()->GetImageList(); const wxBitmap bitmap = imageList->GetBitmap(imageIndex); - painter->drawPixmap(rect.topRight(), *bitmap.GetHandle()); + const QRect rect = visualRect(index); + painter->drawPixmap(rect.topLeft(), *bitmap.GetHandle()); } } From 78280428e95cf699acc2af14420713220afa47bb Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 12 Feb 2019 08:15:47 +0000 Subject: [PATCH 44/53] Replace use of QTreeWidget::setIcon and QTreeWidget::iconChanged with code that is compatible with our minimum suppported QT version --- src/qt/treectrl.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 721cae4356..ef9616733b 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -140,8 +140,6 @@ public: this, &wxQTreeWidget::OnItemExpanded); connect(this, &QTreeWidget::itemChanged, this, &wxQTreeWidget::OnItemChanged); - connect(this, &QTreeWidget::iconSizeChanged, - this, &wxQTreeWidget::OnIconSizeChanged); m_editorFactory.AttachTo(this); setDragEnabled(true); @@ -189,6 +187,13 @@ public: return i->second.GetState(); } + void ResizeIcons(const QSize &size) + { + m_placeHolderImage = QPixmap(size); + m_placeHolderImage.fill(Qt::transparent); + ReplaceIcons(invisibleRootItem()); + } + QPixmap GetPlaceHolderImage() const { return m_placeHolderImage; @@ -217,6 +222,16 @@ protected: } private: + void ReplaceIcons(QTreeWidgetItem *item) + { + item->setIcon(0, m_placeHolderImage); + const int childCount = item->childCount(); + for ( int i = 0; i < childCount; ++i ) + { + ReplaceIcons(item->child(i)); + } + } + void OnCurrentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous @@ -341,12 +356,6 @@ private: EmitEvent(event); } - void OnIconSizeChanged(const QSize &size) - { - m_placeHolderImage = QPixmap(size); - m_placeHolderImage.fill(Qt::transparent); - } - void tryStartDrag(const QMouseEvent *event) { wxEventType command = event->buttons() & Qt::RightButton @@ -513,7 +522,7 @@ void wxTreeCtrl::SetImageList(wxImageList *imageList) int width, height; m_imageListNormal->GetSize(0, width, height); - m_qtTreeWidget->setIconSize(QSize(width, height)); + m_qtTreeWidget->ResizeIcons(QSize(width, height)); m_qtTreeWidget->update(); } From b9382b99b4dc384f3ce6f9269c80319bd26aed11 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Tue, 12 Feb 2019 08:47:29 +0000 Subject: [PATCH 45/53] Ensure wxTreeCtrl::DoHitTest updates flag when item is successfully hit. --- src/qt/treectrl.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index ef9616733b..521a3238fd 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -1286,10 +1286,7 @@ wxTreeItemId wxTreeCtrl::DoTreeHitTest(const wxPoint& point, int& flags) const return wxTreeItemId(); QTreeWidgetItem *hitItem = m_qtTreeWidget->itemAt(wxQtConvertPoint(point)); - - if ( hitItem == NULL ) - flags |= wxTREE_HITTEST_NOWHERE; - + flags = hitItem == NULL ? wxTREE_HITTEST_NOWHERE : wxTREE_HITTEST_ONITEM; return wxQtConvertTreeItem(hitItem); } From 77d5d316909aa99cba2e2a0e224164399bc53890 Mon Sep 17 00:00:00 2001 From: Matthew Griffin <45285214+matthew-griffin@users.noreply.github.com> Date: Thu, 30 May 2019 10:47:09 +0100 Subject: [PATCH 46/53] Close the Tree Control editor correctly Ensure that wxTreeItemData is deleted. Use a QT delegate to create editor and perform custom model update. Connect to the closeEditor signal to send out end label edit events and decide whether to accept changes. --- Makefile.in | 1 + build/bakefiles/files.bkl | 1 + build/cmake/files.cmake | 1 + build/files | 1 + include/wx/qt/private/treeitemdelegate.h | 69 ++++++++++++++++++++++++ src/qt/treectrl.cpp | 59 +++++++++++++++----- 6 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 include/wx/qt/private/treeitemdelegate.h diff --git a/Makefile.in b/Makefile.in index 2afb48ef2a..d3829be762 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3579,6 +3579,7 @@ COND_TOOLKIT_QT_GUI_HDR = \ wx/qt/treectrl.h \ wx/qt/private/winevent.h \ wx/qt/private/converter.h \ + wx/qt/private/treeitemdelegate.h \ wx/qt/private/treeitemfactory.h \ wx/qt/private/pointer.h \ wx/qt/private/timer.h \ diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index f84b961111..21c0127c7a 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -364,6 +364,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/qt/treectrl.h wx/qt/private/winevent.h wx/qt/private/converter.h + wx/qt/private/treeitemdelegate.h wx/qt/private/treeitemfactory.h wx/qt/private/pointer.h wx/qt/private/timer.h diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 799d7e5b6c..bae2091acd 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -281,6 +281,7 @@ set(QT_HDR wx/qt/private/winevent.h wx/qt/private/timer.h wx/qt/private/pointer.h + wx/qt/private/treeitemdelegate.h wx/qt/private/treeitemfactory.h wx/qt/private/utils.h ) diff --git a/build/files b/build/files index 78c5e6391c..a5d2125aba 100644 --- a/build/files +++ b/build/files @@ -305,6 +305,7 @@ QT_HDR = wx/qt/private/converter.h wx/qt/private/pointer.h wx/qt/private/timer.h + wx/qt/private/treeitemdelegate.h wx/qt/private/treeitemfactory.h wx/qt/private/utils.h diff --git a/include/wx/qt/private/treeitemdelegate.h b/include/wx/qt/private/treeitemdelegate.h new file mode 100644 index 0000000000..a6d38df06d --- /dev/null +++ b/include/wx/qt/private/treeitemdelegate.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/qt/private/treeitemdelegate.h +// Purpose: Delegate to create text edit controls for the tree items +// Author: Matthew Griffin +// Created: 2019-05-29 +// Copyright: Matthew Griffin +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_TREEITEM_DELEGATE_H +#define _WX_TREEITEM_DELEGATE_H + +#include + +#include "wx/textctrl.h" + +#include "treeitemfactory.h" + +class wxQTTreeItemDelegate : public QStyledItemDelegate +{ +public: + explicit wxQTTreeItemDelegate(wxWindow* parent) + : m_parent(parent), + m_textCtrl(NULL) + { + } + + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &WXUNUSED(option), const QModelIndex &index) const wxOVERRIDE + { + m_current_model_index = index; + m_textCtrl = new wxQtListTextCtrl(m_parent, parent); + m_textCtrl->SetFocus(); + return m_textCtrl->GetHandle(); + } + + void destroyEditor(QWidget *WXUNUSED(editor), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE + { + m_current_model_index = QModelIndex(); + delete m_textCtrl; + m_textCtrl = NULL; + } + + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const wxOVERRIDE + { + // Don't set model data until wx has had a chance to send out events + } + + wxTextCtrl* GetEditControl() const + { + return m_textCtrl; + } + + QModelIndex GetCurrentModelIndex() const + { + return m_current_model_index; + } + + void AcceptModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const + { + QStyledItemDelegate::setModelData(editor, model, index); + } + +private: + wxWindow* m_parent; + mutable wxTextCtrl* m_textCtrl; + mutable QModelIndex m_current_model_index; +}; + +#endif // _WX_TREEITEM_DELEGATE_H diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 521a3238fd..107649dcfc 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -17,7 +17,7 @@ #include "wx/settings.h" #include "wx/qt/private/winevent.h" -#include "wx/qt/private/treeitemfactory.h" +#include "wx/qt/private/treeitemdelegate.h" #include #include @@ -27,7 +27,7 @@ namespace { struct TreeItemDataQt { - TreeItemDataQt() : data(NULL) + TreeItemDataQt() { } @@ -40,9 +40,13 @@ struct TreeItemDataQt } } - wxTreeItemData *data; + wxTreeItemData *getData() const + { + return data.get(); + } private: + wxSharedPtr data; static bool registered; }; @@ -126,7 +130,8 @@ class wxQTreeWidget : public wxQtEventSignalHandler public: wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : wxQtEventSignalHandler(parent, handler), - m_editorFactory(handler) + m_item_delegate(handler), + m_closing_editor(0) { connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); @@ -138,10 +143,11 @@ public: this, &wxQTreeWidget::OnItemCollapsed); connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); - connect(this, &QTreeWidget::itemChanged, - this, &wxQTreeWidget::OnItemChanged); - m_editorFactory.AttachTo(this); + connect(&m_item_delegate, &QAbstractItemDelegate::closeEditor, + this, &wxQTreeWidget::OnCloseEditor); + + setItemDelegate(&m_item_delegate); setDragEnabled(true); viewport()->setAcceptDrops(true); setDropIndicatorShown(true); @@ -157,7 +163,7 @@ public: wxTextCtrl *GetEditControl() { - return m_editorFactory.GetEditControl(); + return m_item_delegate.GetEditControl(); } void SetItemImage(QTreeWidgetItem *item, int image, wxTreeItemIcon which) @@ -346,14 +352,40 @@ private: EmitEvent(expandedEvent); } - void OnItemChanged(QTreeWidgetItem *item, int WXUNUSED(column)) + void OnCloseEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) { + // Close process can re-signal closeEditor so we need to guard against + // reentrant calls. + wxRecursionGuard guard(m_closing_editor); + + if (guard.IsInside()) + return; + + // There can be multiple calls to close editor when the item loses focus + const QModelIndex current_index = m_item_delegate.GetCurrentModelIndex(); + if (!current_index.isValid()) + return; + wxTreeEvent event( wxEVT_TREE_END_LABEL_EDIT, GetHandler(), - wxQtConvertTreeItem(item) + wxQtConvertTreeItem(itemFromIndex(current_index)) ); - EmitEvent(event); + if (hint == QAbstractItemDelegate::EndEditHint::RevertModelCache) + { + event.SetEditCanceled(true); + EmitEvent(event); + } + else + { + // Allow event handlers to decide whether to accept edited text + const wxString editor_text = m_item_delegate.GetEditControl()->GetLineText(0); + event.SetLabel(editor_text); + if (!GetHandler()->HandleWindowEvent(event) || event.IsAllowed()) + m_item_delegate.AcceptModelData(editor, model(), current_index); + } + + QAbstractItemView::closePersistentEditor(current_index); } void tryStartDrag(const QMouseEvent *event) @@ -451,7 +483,8 @@ private: return imageIndex; } - wxQtTreeItemEditorFactory m_editorFactory; + wxQTTreeItemDelegate m_item_delegate; + wxRecursionGuardFlag m_closing_editor; typedef std::map ImageStateMap; ImageStateMap m_imageStates; @@ -557,7 +590,7 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); const QVariant itemData = qTreeItem->data(0, Qt::UserRole); const TreeItemDataQt value = itemData.value(); - return value.data; + return value.getData(); } wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const From 3f4b74baea9accfd329c0eefdef662954f5edec0 Mon Sep 17 00:00:00 2001 From: Matthew Griffin <45285214+matthew-griffin@users.noreply.github.com> Date: Thu, 30 May 2019 11:45:16 +0100 Subject: [PATCH 47/53] Fixed build issues --- include/wx/qt/private/treeitemdelegate.h | 2 +- src/qt/treectrl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/wx/qt/private/treeitemdelegate.h b/include/wx/qt/private/treeitemdelegate.h index a6d38df06d..54463acdeb 100644 --- a/include/wx/qt/private/treeitemdelegate.h +++ b/include/wx/qt/private/treeitemdelegate.h @@ -40,7 +40,7 @@ public: m_textCtrl = NULL; } - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const wxOVERRIDE + void setModelData(QWidget *WXUNUSED(editor), QAbstractItemModel *WXUNUSED(model), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE { // Don't set model data until wx has had a chance to send out events } diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 107649dcfc..b951076393 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -371,7 +371,7 @@ private: GetHandler(), wxQtConvertTreeItem(itemFromIndex(current_index)) ); - if (hint == QAbstractItemDelegate::EndEditHint::RevertModelCache) + if (hint == QAbstractItemDelegate::RevertModelCache) { event.SetEditCanceled(true); EmitEvent(event); From 3e3f888582dcc3a1018783695b0ea9837f364d1c Mon Sep 17 00:00:00 2001 From: Matthew Griffin <45285214+matthew-griffin@users.noreply.github.com> Date: Thu, 30 May 2019 11:59:07 +0100 Subject: [PATCH 48/53] Removed spurious indent --- include/wx/qt/private/treeitemdelegate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/qt/private/treeitemdelegate.h b/include/wx/qt/private/treeitemdelegate.h index 54463acdeb..a2fc222e02 100644 --- a/include/wx/qt/private/treeitemdelegate.h +++ b/include/wx/qt/private/treeitemdelegate.h @@ -40,7 +40,7 @@ public: m_textCtrl = NULL; } - void setModelData(QWidget *WXUNUSED(editor), QAbstractItemModel *WXUNUSED(model), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE + void setModelData(QWidget *WXUNUSED(editor), QAbstractItemModel *WXUNUSED(model), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE { // Don't set model data until wx has had a chance to send out events } From bc8d5430c9ef240caac89f37eacb028b7379572d Mon Sep 17 00:00:00 2001 From: Matthew Griffin <45285214+matthew-griffin@users.noreply.github.com> Date: Fri, 31 May 2019 09:51:16 +0100 Subject: [PATCH 49/53] Support click on selected item to edit Make QTreeWidgetItems editable and add SelectedClicked as an edit trigger. Simplify closing the editor as QAbstractItemView already connects to its delegate closeEditor signal. --- src/qt/treectrl.cpp | 105 +++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 46 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index b951076393..016d7eb3f7 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -144,13 +144,11 @@ public: connect(this, &QTreeWidget::itemExpanded, this, &wxQTreeWidget::OnItemExpanded); - connect(&m_item_delegate, &QAbstractItemDelegate::closeEditor, - this, &wxQTreeWidget::OnCloseEditor); - setItemDelegate(&m_item_delegate); setDragEnabled(true); viewport()->setAcceptDrops(true); setDropIndicatorShown(true); + setEditTriggers(QAbstractItemView::SelectedClicked); } virtual void paintEvent (QPaintEvent * event) @@ -227,6 +225,62 @@ protected: } } + bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) wxOVERRIDE + { + // AllEditTriggers means that editor is about to open, not waiting for double click + if (trigger == AllEditTriggers) + { + // Allow event handlers to veto opening the editor + wxTreeEvent wx_event( + wxEVT_TREE_BEGIN_LABEL_EDIT, + GetHandler(), + wxQtConvertTreeItem(itemFromIndex(index)) + ); + if (GetHandler()->HandleWindowEvent(wx_event) && !wx_event.IsAllowed()) + return false; + } + return QTreeWidget::edit(index, trigger, event); + } + + void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) wxOVERRIDE + { + // Close process can re-signal closeEditor so we need to guard against + // reentrant calls. + wxRecursionGuard guard(m_closing_editor); + + if (guard.IsInside()) + return; + + // There can be multiple calls to close editor when the item loses focus + const QModelIndex current_index = m_item_delegate.GetCurrentModelIndex(); + if (!current_index.isValid()) + return; + + wxTreeEvent event( + wxEVT_TREE_END_LABEL_EDIT, + GetHandler(), + wxQtConvertTreeItem(itemFromIndex(current_index)) + ); + if (hint == QAbstractItemDelegate::RevertModelCache) + { + event.SetEditCanceled(true); + EmitEvent(event); + } + else + { + // Allow event handlers to decide whether to accept edited text + const wxString editor_text = m_item_delegate.GetEditControl()->GetLineText(0); + event.SetLabel(editor_text); + if (!GetHandler()->HandleWindowEvent(event) || event.IsAllowed()) + m_item_delegate.AcceptModelData(editor, model(), current_index); + } + // wx doesn't have hints to edit next/previous item + if (hint == QAbstractItemDelegate::EditNextItem || hint == QAbstractItemDelegate::EditPreviousItem) + hint = QAbstractItemDelegate::SubmitModelCache; + + QTreeWidget::closeEditor(editor, hint); + } + private: void ReplaceIcons(QTreeWidgetItem *item) { @@ -352,42 +406,6 @@ private: EmitEvent(expandedEvent); } - void OnCloseEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) - { - // Close process can re-signal closeEditor so we need to guard against - // reentrant calls. - wxRecursionGuard guard(m_closing_editor); - - if (guard.IsInside()) - return; - - // There can be multiple calls to close editor when the item loses focus - const QModelIndex current_index = m_item_delegate.GetCurrentModelIndex(); - if (!current_index.isValid()) - return; - - wxTreeEvent event( - wxEVT_TREE_END_LABEL_EDIT, - GetHandler(), - wxQtConvertTreeItem(itemFromIndex(current_index)) - ); - if (hint == QAbstractItemDelegate::RevertModelCache) - { - event.SetEditCanceled(true); - EmitEvent(event); - } - else - { - // Allow event handlers to decide whether to accept edited text - const wxString editor_text = m_item_delegate.GetEditControl()->GetLineText(0); - event.SetLabel(editor_text); - if (!GetHandler()->HandleWindowEvent(event) || event.IsAllowed()) - m_item_delegate.AcceptModelData(editor, model(), current_index); - } - - QAbstractItemView::closePersistentEditor(current_index); - } - void tryStartDrag(const QMouseEvent *event) { wxEventType command = event->buttons() & Qt::RightButton @@ -1175,13 +1193,7 @@ wxTextCtrl *wxTreeCtrl::EditLabel( ) { wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item"); - - wxTreeEvent event(wxEVT_TREE_BEGIN_LABEL_EDIT, this, item); - if ( HandleWindowEvent(event) && !event.IsAllowed() ) - return NULL; - - QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); - m_qtTreeWidget->openPersistentEditor(qTreeItem); + m_qtTreeWidget->editItem(wxQtConvertTreeItem(item)); return m_qtTreeWidget->GetEditControl(); } @@ -1260,6 +1272,7 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, QTreeWidgetItem *newItem = new QTreeWidgetItem; newItem->setText(0, wxQtConvertString(text)); + newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); TreeItemDataQt treeItemData(data); newItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData)); From 436edb6f283c8ec4a91552c636d0ab0b13e64b36 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Fri, 31 May 2019 14:21:27 +0100 Subject: [PATCH 50/53] Fix Linux build --- src/qt/treectrl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 016d7eb3f7..5962b888b1 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -15,6 +15,7 @@ #include "wx/treectrl.h" #include "wx/imaglist.h" #include "wx/settings.h" +#include "wx/sharedptr.h" #include "wx/qt/private/winevent.h" #include "wx/qt/private/treeitemdelegate.h" From 12c8741704c0e905b42451dc48733ac18d078138 Mon Sep 17 00:00:00 2001 From: Matthew Griffin <45285214+matthew-griffin@users.noreply.github.com> Date: Mon, 3 Jun 2019 10:58:56 +0100 Subject: [PATCH 51/53] Fix crash on Linux --- include/wx/qt/private/treeitemdelegate.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/wx/qt/private/treeitemdelegate.h b/include/wx/qt/private/treeitemdelegate.h index a2fc222e02..af5f939381 100644 --- a/include/wx/qt/private/treeitemdelegate.h +++ b/include/wx/qt/private/treeitemdelegate.h @@ -12,6 +12,7 @@ #include +#include "wx/app.h" #include "wx/textctrl.h" #include "treeitemfactory.h" @@ -35,9 +36,12 @@ public: void destroyEditor(QWidget *WXUNUSED(editor), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE { - m_current_model_index = QModelIndex(); - delete m_textCtrl; - m_textCtrl = NULL; + if (!wxTheApp->IsScheduledForDestruction(m_textCtrl)) + { + m_current_model_index = QModelIndex(); + wxTheApp->ScheduleForDestruction(m_textCtrl); + m_textCtrl = NULL; + } } void setModelData(QWidget *WXUNUSED(editor), QAbstractItemModel *WXUNUSED(model), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE From 9bb9bf5718ad5aca3b6e7316b8361a992a347905 Mon Sep 17 00:00:00 2001 From: Matthew Griffin <45285214+matthew-griffin@users.noreply.github.com> Date: Tue, 4 Jun 2019 10:29:17 +0100 Subject: [PATCH 52/53] Code review changes --- include/wx/qt/private/treeitemdelegate.h | 19 ++++++++++-------- include/wx/qt/private/treeitemfactory.h | 16 +++++++-------- include/wx/qt/treectrl.h | 1 - src/qt/treectrl.cpp | 25 ++++++++++++------------ 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/include/wx/qt/private/treeitemdelegate.h b/include/wx/qt/private/treeitemdelegate.h index af5f939381..65025de442 100644 --- a/include/wx/qt/private/treeitemdelegate.h +++ b/include/wx/qt/private/treeitemdelegate.h @@ -7,8 +7,8 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef _WX_TREEITEM_DELEGATE_H -#define _WX_TREEITEM_DELEGATE_H +#ifndef _WX_QT_PRIVATE_TREEITEM_DELEGATE_H +#define _WX_QT_PRIVATE_TREEITEM_DELEGATE_H #include @@ -28,7 +28,10 @@ public: QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &WXUNUSED(option), const QModelIndex &index) const wxOVERRIDE { - m_current_model_index = index; + if ( m_textCtrl != NULL ) + destroyEditor(m_textCtrl->GetHandle(), m_currentModelIndex); + + m_currentModelIndex = index; m_textCtrl = new wxQtListTextCtrl(m_parent, parent); m_textCtrl->SetFocus(); return m_textCtrl->GetHandle(); @@ -36,9 +39,9 @@ public: void destroyEditor(QWidget *WXUNUSED(editor), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE { - if (!wxTheApp->IsScheduledForDestruction(m_textCtrl)) + if ( m_textCtrl != NULL ) { - m_current_model_index = QModelIndex(); + m_currentModelIndex = QModelIndex(); // invalidate the index wxTheApp->ScheduleForDestruction(m_textCtrl); m_textCtrl = NULL; } @@ -56,7 +59,7 @@ public: QModelIndex GetCurrentModelIndex() const { - return m_current_model_index; + return m_currentModelIndex; } void AcceptModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const @@ -67,7 +70,7 @@ public: private: wxWindow* m_parent; mutable wxTextCtrl* m_textCtrl; - mutable QModelIndex m_current_model_index; + mutable QModelIndex m_currentModelIndex; }; -#endif // _WX_TREEITEM_DELEGATE_H +#endif // _WX_QT_PRIVATE_TREEITEM_DELEGATE_H diff --git a/include/wx/qt/private/treeitemfactory.h b/include/wx/qt/private/treeitemfactory.h index 40fd2a343e..42ea7e1abf 100644 --- a/include/wx/qt/private/treeitemfactory.h +++ b/include/wx/qt/private/treeitemfactory.h @@ -7,8 +7,8 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef _WX_TREEITEM_FACTORY_H_ -#define _WX_TREEITEM_FACTORY_H_ +#ifndef _WX_QT_PRIVATE_TREEITEM_FACTORY_H_ +#define _WX_QT_PRIVATE_TREEITEM_FACTORY_H_ #include #include @@ -91,11 +91,11 @@ public: qItemDelegate->setItemEditorFactory(this); } - virtual QWidget* createEditor( - int WXUNUSED(userType), - QWidget* parent - ) const wxOVERRIDE + QWidget* createEditor(int WXUNUSED(userType), QWidget* parent) const wxOVERRIDE { + if (m_textCtrl != NULL) + ClearEditor(); + m_textCtrl = new wxQtListTextCtrl(m_parent, parent); m_textCtrl->SetFocus(); return m_textCtrl->GetHandle(); @@ -106,7 +106,7 @@ public: return m_textCtrl; } - void ClearEditor() + void ClearEditor() const { delete m_textCtrl; m_textCtrl = NULL; @@ -119,4 +119,4 @@ private: wxDECLARE_NO_COPY_CLASS(wxQtTreeItemEditorFactory); }; -#endif //_WX_TREEITEM_FACTORY_H_ +#endif //_WX_QT_PRIVATE_TREEITEM_FACTORY_H_ diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h index 47c3b1db5b..3db3838f7d 100644 --- a/include/wx/qt/treectrl.h +++ b/include/wx/qt/treectrl.h @@ -75,7 +75,6 @@ public: virtual wxTreeItemId GetFocusedItem() const wxOVERRIDE; virtual wxTreeItemId GetItemParent(const wxTreeItemId& item) const wxOVERRIDE; - virtual wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const wxOVERRIDE; virtual wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const wxOVERRIDE; virtual wxTreeItemId GetLastChild(const wxTreeItemId& item) const wxOVERRIDE; diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 5962b888b1..71de613a14 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -16,6 +16,7 @@ #include "wx/imaglist.h" #include "wx/settings.h" #include "wx/sharedptr.h" +#include "wx/withimages.h" #include "wx/qt/private/winevent.h" #include "wx/qt/private/treeitemdelegate.h" @@ -32,12 +33,13 @@ struct TreeItemDataQt { } - TreeItemDataQt(wxTreeItemData* data) : data(data) + explicit TreeItemDataQt(wxTreeItemData* data) : data(data) { - if ( !registered ) + static bool s_registered = false; + if ( !s_registered ) { qRegisterMetaTypeStreamOperators("TreeItemDataQt"); - registered = true; + s_registered = true; } } @@ -46,13 +48,10 @@ struct TreeItemDataQt return data.get(); } - private: +private: wxSharedPtr data; - static bool registered; }; -bool TreeItemDataQt::registered = false; - QDataStream &operator<<(QDataStream &out, const TreeItemDataQt &WXUNUSED(obj)) { return out; @@ -84,6 +83,7 @@ size_t CountChildren(QTreeWidgetItem *item) return totalCount; } + class ImageState { public: @@ -91,7 +91,7 @@ public: { for ( int i = wxTreeItemIcon_Normal; i < wxTreeItemIcon_Max; ++i ) { - m_imageStates[i] = -1; + m_imageStates[i] = wxWithImages::NO_IMAGE; } } @@ -101,7 +101,7 @@ public: return m_imageStates[index]; } - const int &operator[](size_t index) const + int operator[](size_t index) const { wxASSERT(index < wxTreeItemIcon_Max); return m_imageStates[index]; @@ -523,7 +523,7 @@ wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id, const wxSize& size, long style, const wxValidator& validator, - const wxString& name) + const wxString& name) { Create(parent, id, pos, size, style, validator, name); } @@ -587,7 +587,7 @@ void wxTreeCtrl::SetStateImageList(wxImageList *imageList) wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const { if ( !item.IsOk() ) - return ""; + return wxString(); const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item); return wxQtConvertString(qTreeItem->text(0)); @@ -816,10 +816,11 @@ size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const QList qtSelections = m_qtTreeWidget->selectedItems(); const size_t numberOfSelections = qtSelections.size(); + selections.reserve(numberOfSelections); for ( size_t i = 0; i < numberOfSelections; ++i ) { QTreeWidgetItem *item = qtSelections[i]; - selections.Add(wxQtConvertTreeItem(item)); + selections.push_back(wxQtConvertTreeItem(item)); } return numberOfSelections; From af5b122b2b545a54257818c850550089b4d10824 Mon Sep 17 00:00:00 2001 From: Mick Waites Date: Wed, 19 Jun 2019 14:05:31 +0100 Subject: [PATCH 53/53] Stop multiple selection changed messages being sent when calling DeleteChildren on a TreeItem. --- src/qt/treectrl.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) mode change 100644 => 100755 src/qt/treectrl.cpp diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp old mode 100644 new mode 100755 index 71de613a14..2493744c4d --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -1067,11 +1067,31 @@ void wxTreeCtrl::Delete(const wxTreeItemId& item) delete qTreeItem; } +class wxQtEnsureSignalsBlocked +{ +public: + wxQtEnsureSignalsBlocked(QWidget *widget) : + m_widget(widget) + { + m_restore = m_widget->blockSignals(true); + } + + ~wxQtEnsureSignalsBlocked() + { + m_widget->blockSignals(m_restore); + } + +private: + QWidget *m_widget; + bool m_restore; +}; + void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item) { wxCHECK_RET(item.IsOk(), "invalid tree item"); QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item); + wxQtEnsureSignalsBlocked ensureSignalsBlock(m_qtTreeWidget); while ( qTreeItem->childCount() > 0 ) { QTreeWidgetItem *child = qTreeItem->child(0);