diff --git a/Makefile.in b/Makefile.in
index baa823c0b9..4c29d715d0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -3597,7 +3597,15 @@ 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 \
+ 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 \
+ 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 =
@@ -5566,7 +5574,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 \
@@ -5760,7 +5768,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 \
@@ -7551,7 +7560,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 \
@@ -7745,7 +7754,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 \
@@ -9683,7 +9693,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 \
@@ -9877,7 +9887,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 \
@@ -11404,7 +11415,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 \
@@ -11598,7 +11609,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 \
@@ -16376,7 +16388,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)
@@ -16871,6 +16883,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
@@ -21641,7 +21656,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)
@@ -22136,6 +22151,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
@@ -27566,7 +27584,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)
@@ -28061,6 +28079,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
@@ -31820,7 +31841,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)
@@ -32315,6 +32336,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 fef9dcca65..5a9e7ec7eb 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,14 @@ 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
+ 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
+ wx/qt/private/utils.h
@@ -460,6 +467,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 9127a77413..49b3fa1e75 100644
--- a/build/cmake/files.cmake
+++ b/build/cmake/files.cmake
@@ -276,6 +276,14 @@ set(QT_HDR
wx/qt/dataview.h
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/treeitemdelegate.h
+ wx/qt/private/treeitemfactory.h
+ wx/qt/private/utils.h
)
set(QT_SRC
@@ -374,6 +382,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 9e48fc3ff9..b35dadaa1d 100644
--- a/build/files
+++ b/build/files
@@ -297,7 +297,17 @@ 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/treeitemdelegate.h
+ wx/qt/private/treeitemfactory.h
+ wx/qt/private/utils.h
QT_SRC=
$(QT_PLATFORM_SRC)
@@ -392,6 +402,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/listctrl.h b/include/wx/qt/listctrl.h
index e55b44ef98..f9818722cc 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;
@@ -282,7 +282,7 @@ protected:
m_ownsImageListSmall,
m_ownsImageListState;
private:
- wxQtTreeWidget *m_qtTreeWidget;
+ wxQtListTreeWidget *m_qtTreeWidget;
wxDECLARE_DYNAMIC_CLASS( wxListCtrl );
};
diff --git a/include/wx/qt/private/converter.h b/include/wx/qt/private/converter.h
index 7cdce58fad..fbb4250bd6 100644
--- a/include/wx/qt/private/converter.h
+++ b/include/wx/qt/private/converter.h
@@ -15,10 +15,12 @@
#include "wx/kbdstate.h"
#include "wx/gdicmn.h"
+#include "wx/colour.h"
#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 +56,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/private/treeitemdelegate.h b/include/wx/qt/private/treeitemdelegate.h
new file mode 100644
index 0000000000..65025de442
--- /dev/null
+++ b/include/wx/qt/private/treeitemdelegate.h
@@ -0,0 +1,76 @@
+/////////////////////////////////////////////////////////////////////////////
+// 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_QT_PRIVATE_TREEITEM_DELEGATE_H
+#define _WX_QT_PRIVATE_TREEITEM_DELEGATE_H
+
+#include
+
+#include "wx/app.h"
+#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
+ {
+ 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();
+ }
+
+ void destroyEditor(QWidget *WXUNUSED(editor), const QModelIndex &WXUNUSED(index)) const wxOVERRIDE
+ {
+ if ( m_textCtrl != NULL )
+ {
+ m_currentModelIndex = QModelIndex(); // invalidate the index
+ wxTheApp->ScheduleForDestruction(m_textCtrl);
+ m_textCtrl = NULL;
+ }
+ }
+
+ 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
+ }
+
+ wxTextCtrl* GetEditControl() const
+ {
+ return m_textCtrl;
+ }
+
+ QModelIndex GetCurrentModelIndex() const
+ {
+ return m_currentModelIndex;
+ }
+
+ 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_currentModelIndex;
+};
+
+#endif // _WX_QT_PRIVATE_TREEITEM_DELEGATE_H
diff --git a/include/wx/qt/private/treeitemfactory.h b/include/wx/qt/private/treeitemfactory.h
new file mode 100644
index 0000000000..42ea7e1abf
--- /dev/null
+++ b/include/wx/qt/private/treeitemfactory.h
@@ -0,0 +1,122 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/qt/private/treeitemfactory.h
+// Purpose: Factory to create text edit controls for the tree items
+// Author: Graham Dawes
+// Created: 2019-02-07
+// Copyright: Graham Dawes
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_QT_PRIVATE_TREEITEM_FACTORY_H_
+#define _WX_QT_PRIVATE_TREEITEM_FACTORY_H_
+
+#include
+#include
+#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 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(globalPos);
+
+ widget->move(eventPos + 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)
+ {
+ }
+
+ void AttachTo(QTreeWidget *tree)
+ {
+ QAbstractItemDelegate* delegate = tree->itemDelegate();
+ QItemDelegate *qItemDelegate = static_cast(delegate);
+ qItemDelegate->setItemEditorFactory(this);
+ }
+
+ 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();
+ }
+
+ wxTextCtrl* GetEditControl() const
+ {
+ return m_textCtrl;
+ }
+
+ void ClearEditor() const
+ {
+ delete m_textCtrl;
+ m_textCtrl = NULL;
+ }
+
+private:
+ wxWindow* m_parent;
+ mutable wxTextCtrl* m_textCtrl;
+
+ wxDECLARE_NO_COPY_CLASS(wxQtTreeItemEditorFactory);
+};
+
+#endif //_WX_QT_PRIVATE_TREEITEM_FACTORY_H_
diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h
index 9eb385b71d..3db3838f7d 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
{
@@ -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,
@@ -28,113 +30,116 @@ 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 void SetWindowStyleFlag(long styles) wxOVERRIDE;
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;
+ wxQTreeWidget *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/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 )
diff --git a/src/qt/listctrl.cpp b/src/qt/listctrl.cpp
index 587961d3da..d8f71b6fd5 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,110 +22,14 @@
#include "wx/listctrl.h"
#include "wx/imaglist.h"
-#include "wx/recguard.h"
#include "wx/qt/private/winevent.h"
+#include "wx/qt/private/treeitemfactory.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
+class wxQtListTreeWidget : public wxQtEventSignalHandler< QTreeWidget, wxListCtrl >
{
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 wxQtItemEditorFactory : public QItemEditorFactory
-{
-public:
- explicit wxQtItemEditorFactory(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(wxQtItemEditorFactory);
-};
-
-class wxQtTreeWidget : public wxQtEventSignalHandler< QTreeWidget, wxListCtrl >
-{
-public:
- wxQtTreeWidget( wxWindow *parent, wxListCtrl *handler );
+ wxQtListTreeWidget( wxWindow *parent, wxListCtrl *handler );
void EmitListEvent(wxEventType typ, QTreeWidgetItem *qitem, int column) const;
@@ -153,21 +56,21 @@ private:
qItemDelegate->setItemEditorFactory(&m_editorFactory);
}
- wxQtItemEditorFactory m_editorFactory;
+ wxQtTreeItemEditorFactory 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 +90,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 +161,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);
diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp
old mode 100644
new mode 100755
index f73a202612..2493744c4d
--- a/src/qt/treectrl.cpp
+++ b/src/qt/treectrl.cpp
@@ -8,11 +8,513 @@
// 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"
+#include "wx/settings.h"
+#include "wx/sharedptr.h"
+#include "wx/withimages.h"
+
+#include "wx/qt/private/winevent.h"
+#include "wx/qt/private/treeitemdelegate.h"
#include
+#include
+#include
-wxTreeCtrl::wxTreeCtrl()
+namespace
+{
+struct TreeItemDataQt
+{
+ TreeItemDataQt()
+ {
+ }
+
+ explicit TreeItemDataQt(wxTreeItemData* data) : data(data)
+ {
+ static bool s_registered = false;
+ if ( !s_registered )
+ {
+ qRegisterMetaTypeStreamOperators("TreeItemDataQt");
+ s_registered = true;
+ }
+ }
+
+ wxTreeItemData *getData() const
+ {
+ return data.get();
+ }
+
+private:
+ wxSharedPtr data;
+};
+
+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)
+ {
+ for ( int i = wxTreeItemIcon_Normal; i < wxTreeItemIcon_Max; ++i )
+ {
+ m_imageStates[i] = wxWithImages::NO_IMAGE;
+ }
+ }
+
+ int &operator[](size_t index)
+ {
+ wxASSERT(index < wxTreeItemIcon_Max);
+ return m_imageStates[index];
+ }
+
+ int operator[](size_t index) const
+ {
+ wxASSERT(index < wxTreeItemIcon_Max);
+ 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;
+};
+
+}
+
+Q_DECLARE_METATYPE(TreeItemDataQt)
+
+class wxQTreeWidget : public wxQtEventSignalHandler
+{
+public:
+ wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) :
+ wxQtEventSignalHandler(parent, handler),
+ m_item_delegate(handler),
+ m_closing_editor(0)
+ {
+ 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);
+
+ setItemDelegate(&m_item_delegate);
+ setDragEnabled(true);
+ viewport()->setAcceptDrops(true);
+ setDropIndicatorShown(true);
+ setEditTriggers(QAbstractItemView::SelectedClicked);
+ }
+
+ 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_item_delegate.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];
+ }
+
+ void SetItemState(QTreeWidgetItem *item, int state)
+ {
+ m_imageStates[item].SetState(state);
+ }
+
+ int GetItemState(QTreeWidgetItem *item) const
+ {
+ const ImageStateMap::const_iterator i = m_imageStates.find(item);
+ if ( i == m_imageStates.end() )
+ return wxTREE_ITEMSTATE_NONE;
+
+ 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;
+ }
+
+protected:
+ virtual void drawRow(
+ QPainter *painter,
+ const QStyleOptionViewItem &options,
+ const QModelIndex &index
+
+ ) const wxOVERRIDE
+ {
+ QTreeWidget::drawRow(painter, options, index);
+
+ QTreeWidgetItem *item = itemFromIndex(index);
+ const int imageIndex = ChooseBestImage(item);
+
+ if ( imageIndex != -1 )
+ {
+ const wxImageList *imageList = GetHandler()->GetImageList();
+ const wxBitmap bitmap = imageList->GetBitmap(imageIndex);
+ const QRect rect = visualRect(index);
+ painter->drawPixmap(rect.topLeft(), *bitmap.GetHandle());
+ }
+ }
+
+ 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)
+ {
+ 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
+ )
+ {
+ wxTreeCtrl* treeCtrl = GetHandler();
+
+ wxTreeEvent changingEvent(
+ wxEVT_TREE_SEL_CHANGING,
+ treeCtrl,
+ wxQtConvertTreeItem(current)
+ );
+
+ changingEvent.SetOldItem(wxQtConvertTreeItem(previous));
+ EmitEvent(changingEvent);
+
+ if ( !changingEvent.IsAllowed() )
+ {
+ blockSignals(true);
+ setCurrentItem(previous);
+ blockSignals(false);
+ return;
+ }
+
+ // 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)
+ );
+ changedEvent.SetOldItem(wxQtConvertTreeItem(previous));
+ wxPostEvent(treeCtrl, 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);
+ }
+
+ void tryStartDrag(const QMouseEvent *event)
+ {
+ wxEventType command = event->buttons() & 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() )
+ {
+ setState(DragSelectingState);
+ }
+ }
+
+ void endDrag(QPoint position)
+ {
+ QTreeWidgetItem *hitItem = itemAt(position);
+
+ wxTreeEvent tree_event(
+ wxEVT_TREE_END_DRAG,
+ GetHandler(),
+ wxQtConvertTreeItem(hitItem)
+ );
+
+ tree_event.SetPoint(wxQtConvertPoint(position));
+
+ EmitEvent(tree_event);
+ }
+
+ virtual void dropEvent(QDropEvent* event) wxOVERRIDE
+ {
+ endDrag(event->pos());
+
+ // 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);
+ }
+ }
+
+ 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;
+ }
+
+ wxQTTreeItemDelegate m_item_delegate;
+ wxRecursionGuardFlag m_closing_editor;
+
+ 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() :
+ m_qtTreeWidget(NULL)
{
}
@@ -23,7 +525,7 @@ wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id,
const wxValidator& validator,
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,16 +535,28 @@ 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);
+ m_qtTreeWidget->header()->hide();
- return QtCreateControl( parent, id, pos, size, style, validator, name );
+ SetWindowStyleFlag(style);
+
+ return QtCreateControl(parent, id, pos, size, style, validator, name);
+}
+
+wxTreeCtrl::~wxTreeCtrl()
+{
+ if ( m_qtTreeWidget != NULL )
+ m_qtTreeWidget->deleteLater();
}
unsigned wxTreeCtrl::GetCount() const
{
- return 0;
-}
+ QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem();
+ if ( root->childCount() == 0 )
+ return 0;
+ return CountChildren(root->child(0));
+}
unsigned wxTreeCtrl::GetIndent() const
{
@@ -56,275 +570,716 @@ 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->ResizeIcons(QSize(width, height));
+ m_qtTreeWidget->update();
}
void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
{
+ m_imageListState = imageList;
+ m_qtTreeWidget->update();
}
wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const
{
- return wxString();
+ if ( !item.IsOk() )
+ return wxString();
+
+ 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
{
- return 0;
+ wxCHECK_MSG(item.IsOk(), -1, "invalid tree item");
+ return m_qtTreeWidget->GetItemImage(wxQtConvertTreeItem(item), which);
}
wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
{
- return NULL;
+ wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item");
+
+ const QTreeWidgetItem* qTreeItem = wxQtConvertTreeItem(item);
+ const QVariant itemData = qTreeItem->data(0, Qt::UserRole);
+ const TreeItemDataQt value = itemData.value();
+ return value.getData();
}
wxColour wxTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const
{
- return wxColour();
+ wxCHECK_MSG(item.IsOk(), wxNullColour, "invalid tree item");
+
+ const 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");
+
+ const 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");
+
+ 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);
}
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);
+ const TreeItemDataQt treeItemData(data);
+ qTreeItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData));
}
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)
+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)
+void wxTreeCtrl::SetItemBackgroundColour(
+ const wxTreeItemId& item,
+ const wxColour& col
+)
{
+ wxCHECK_RET(item.IsOk(), "invalid tree item");
+
+ QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item);
+ qTreeItem->setBackgroundColor(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");
+
+ const 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");
+
+ const 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");
+
+ const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item);
+ return qTreeItem->isExpanded();
}
bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const
{
- return false;
+ wxCHECK_MSG(item.IsOk(), false, "invalid tree item");
+
+ const QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item);
+ return qTreeItem->isSelected();
}
bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const
{
- return false;
+ wxCHECK_MSG(item.IsOk(), false, "invalid tree item");
+
+ 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
{
- 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();
+ const QTreeWidgetItem *root = m_qtTreeWidget->invisibleRootItem();
+ 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.reserve(numberOfSelections);
+ for ( size_t i = 0; i < numberOfSelections; ++i )
+ {
+ QTreeWidgetItem *item = qtSelections[i];
+ selections.push_back(wxQtConvertTreeItem(item));
+ }
+
+ return numberOfSelections;
}
void wxTreeCtrl::SetFocusedItem(const wxTreeItemId& item)
{
-
+ wxCHECK_RET(item.IsOk(), "invalid tree item");
+ m_qtTreeWidget->setCurrentItem(wxQtConvertTreeItem(item), 0);
}
void wxTreeCtrl::ClearFocusedItem()
{
-
+ m_qtTreeWidget->setCurrentItem(NULL);
}
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
+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
+wxTreeItemId wxTreeCtrl::GetNextChild(
+ const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie
+) const
{
+ wxCHECK_MSG(item.IsOk(), wxTreeItemId(), "invalid tree item");
+
+ wxIntPtr currentIndex = reinterpret_cast(cookie);
+ ++currentIndex;
+
+ const 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");
+
+ const 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(), "invalid tree item");
+ wxASSERT_MSG(IsVisible(item), "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(), "invalid tree item");
+ wxASSERT_MSG(IsVisible(item), "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 *root = m_qtTreeWidget->invisibleRootItem();
+ 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;
}
void wxTreeCtrl::Delete(const wxTreeItemId& item)
{
+ wxCHECK_RET(item.IsOk(), "invalid tree item");
+
+ QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item);
+ QTreeWidgetItem *parent = qTreeItem->parent();
+
+ DeleteChildren(qTreeItem);
+
+ if ( parent != NULL )
+ {
+ parent->removeChild(qTreeItem);
+ }
+ else
+ {
+ m_qtTreeWidget->removeItemWidget(qTreeItem, 0);
+ }
+
+ SendDeleteEvent(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);
+ 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) )
+ {
+ m_qtTreeWidget->clearSelection();
+ }
+
+ 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)
+wxTextCtrl *wxTreeCtrl::EditLabel(
+ const wxTreeItemId& item,
+ wxClassInfo* WXUNUSED(textCtrlClass)
+)
{
- return NULL;
+ wxCHECK_MSG(item.IsOk(), NULL, "invalid tree item");
+ m_qtTreeWidget->editItem(wxQtConvertTreeItem(item));
+ return m_qtTreeWidget->GetEditControl();
}
wxTextCtrl *wxTreeCtrl::GetEditControl() const
{
- return NULL;
+ 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);
+ m_qtTreeWidget->closePersistentEditor(qTreeItem);
}
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
+bool wxTreeCtrl::GetBoundingRect(
+ const wxTreeItemId& item,
+ wxRect& rect,
+ bool WXUNUSED(textOnly)
+) const
{
- return false;
+ wxCHECK_MSG(item.IsOk(), false, "invalid tree item");
+
+ 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)
+{
+ wxControl::SetWindowStyleFlag(styles);
+
+ m_qtTreeWidget->setSelectionMode(
+ styles & wxTR_MULTIPLE
+ ? QTreeWidget::ExtendedSelection
+ : QTreeWidget::SingleSelection
+ );
}
int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const
{
- return 0;
+ wxCHECK_MSG(item.IsOk(), wxTREE_ITEMSTATE_NONE, "invalid tree item");
+ return m_qtTreeWidget->GetItemState(wxQtConvertTreeItem(item));
}
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,
@@ -333,7 +1288,37 @@ 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->setFlags(newItem->flags() | Qt::ItemIsEditable);
+
+ TreeItemDataQt treeItemData(data);
+ newItem->setData(0, Qt::UserRole, QVariant::fromValue(treeItemData));
+
+ m_qtTreeWidget->SetItemImage(newItem, image, wxTreeItemIcon_Normal);
+ m_qtTreeWidget->SetItemImage(newItem, selImage, wxTreeItemIcon_Selected);
+
+ newItem->setIcon(0, m_qtTreeWidget->GetPlaceHolderImage());
+
+ wxTreeItemId wxItem = wxQtConvertTreeItem(newItem);
+
+ if ( data != NULL )
+ data->SetId(wxItem);
+
+ if ( pos == static_cast(-1) )
+ {
+ qTreeItem->addChild(newItem);
+ }
+ else
+ {
+ qTreeItem->insertChild(pos, newItem);
+ }
+
+ return wxItem;
}
wxTreeItemId wxTreeCtrl::DoInsertAfter(const wxTreeItemId& parent,
@@ -342,15 +1327,67 @@ 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");
+
+ const 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;
+ 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));
+ flags = hitItem == NULL ? wxTREE_HITTEST_NOWHERE : wxTREE_HITTEST_ONITEM;
+ 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(), "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;
+}
diff --git a/tests/controls/treectrltest.cpp b/tests/controls/treectrltest.cpp
index 433c32ce61..2b1cd2e2ed 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
@@ -272,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()