diff --git a/docs/changes.txt b/docs/changes.txt index 20f8721e99..6ad30469d8 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -181,6 +181,7 @@ All (GUI): - Add wxEVT_SEARCH[_CANCEL] synonyms for wxSearchCtrl events. - Generate wxEVT_SEARCH on Enter under all platforms. - Extend wxRendererNative::DrawGauge() to work for vertical gauges too. +- Add wxHD_BITMAP_ON_RIGHT style to wxHeaderCtrl. wxGTK: @@ -249,6 +250,7 @@ wxMSW: - Fix focus-related problems when using native wxProgressDialog. - Fix crash when reparenting the currently focused window to another TLW. - Fix sending wxEVT_TEXT_ENTER when using auto-completion (Dubby). +- Fix missing selection event on click in multiselection wxDataViewCtrl (mikek). wxOSX: @@ -281,6 +283,7 @@ wxOSX: - Fix selecting RGB bitmaps (with no alpha channel) into wxMemoryDC. - Fix updating radio groups when menu item is inserted/removed from wxMenu. - Allow changing alignment styles after wxTextCtrl creation (Andreas Falkenhahn). +- Fix wxDataViewColumn::SetSortOrder() (hartwigw). wxQt diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 304864aab1..9162cd9d0d 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -27,6 +27,7 @@ #include "wx/dataobj.h" #include "wx/withimages.h" #include "wx/systhemectrl.h" +#include "wx/vector.h" class WXDLLIMPEXP_FWD_CORE wxImageList; class wxItemAttr; @@ -179,8 +180,7 @@ private: // wxDataViewModel // --------------------------------------------------------- -WX_DECLARE_LIST_WITH_DECL(wxDataViewModelNotifier, wxDataViewModelNotifiers, - class WXDLLIMPEXP_ADV); +typedef wxVector wxDataViewModelNotifiers; class WXDLLIMPEXP_ADV wxDataViewModel: public wxRefCounter { @@ -273,8 +273,9 @@ public: virtual bool IsVirtualListModel() const { return false; } protected: - // the user should not delete this class directly: he should use DecRef() instead! - virtual ~wxDataViewModel() { } + // Dtor is protected because the objects of this class must not be deleted, + // DecRef() must be used instead. + virtual ~wxDataViewModel(); // Helper function used by the default Compare() implementation to compare // values of types it is not aware about. Can be overridden in the derived @@ -285,7 +286,7 @@ protected: return 0; } - +private: wxDataViewModelNotifiers m_notifiers; }; @@ -1211,8 +1212,7 @@ private: wxClientData *m_data; }; -WX_DECLARE_LIST_WITH_DECL(wxDataViewTreeStoreNode, wxDataViewTreeStoreNodeList, - class WXDLLIMPEXP_ADV); +typedef wxVector wxDataViewTreeStoreNodes; class WXDLLIMPEXP_ADV wxDataViewTreeStoreContainerNode: public wxDataViewTreeStoreNode { @@ -1222,11 +1222,13 @@ public: wxClientData *data = NULL ); virtual ~wxDataViewTreeStoreContainerNode(); - const wxDataViewTreeStoreNodeList &GetChildren() const + const wxDataViewTreeStoreNodes &GetChildren() const { return m_children; } - wxDataViewTreeStoreNodeList &GetChildren() + wxDataViewTreeStoreNodes &GetChildren() { return m_children; } + wxDataViewTreeStoreNodes::iterator FindChild(wxDataViewTreeStoreNode* node); + void SetExpandedIcon( const wxIcon &icon ) { m_iconExpanded = icon; } const wxIcon &GetExpandedIcon() const @@ -1240,8 +1242,10 @@ public: virtual bool IsContainer() wxOVERRIDE { return true; } + void DestroyChildren(); + private: - wxDataViewTreeStoreNodeList m_children; + wxDataViewTreeStoreNodes m_children; wxIcon m_iconExpanded; bool m_isExpanded; }; diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index f4ebc64cae..5efc0e1eec 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -257,10 +257,10 @@ public: #if wxUSE_ACCESSIBILITY virtual bool Show(bool show = true) wxOVERRIDE; - virtual bool Enable(bool enable = true) wxOVERRIDE; virtual void SetName(const wxString &name) wxOVERRIDE; virtual bool Reparent(wxWindowBase *newParent) wxOVERRIDE; #endif // wxUSE_ACCESSIBILITY + virtual bool Enable(bool enable = true) wxOVERRIDE; virtual bool AllowMultiColumnSort(bool allow) wxOVERRIDE; virtual bool IsMultiColumnSortAllowed() const wxOVERRIDE { return m_allowMultiColumnSort; } diff --git a/include/wx/headerctrl.h b/include/wx/headerctrl.h index 928ed7aa5e..f491fcbc7a 100644 --- a/include/wx/headerctrl.h +++ b/include/wx/headerctrl.h @@ -37,6 +37,9 @@ enum // right clicking the header wxHD_ALLOW_HIDE = 0x0002, + // force putting column images on right + wxHD_BITMAP_ON_RIGHT = 0x0004, + // style used by default when creating the control wxHD_DEFAULT_STYLE = wxHD_ALLOW_REORDER }; diff --git a/interface/wx/dataview.h b/interface/wx/dataview.h index 8d087a9367..8c2b303bdc 100644 --- a/interface/wx/dataview.h +++ b/interface/wx/dataview.h @@ -155,7 +155,8 @@ public: @param column The column holding the items to be compared. @param ascending - The sort is being peformed in ascending or descending order. + Indicates whether the sort is being performed in ascending or + descending order. @return For an ascending comparison: a negative value if the item1 is less than (i.e. should appear above) item2, zero if the two items are @@ -163,11 +164,12 @@ public: appear below) the second one. The reverse for a descending comparison. @note If there can be multiple rows with the same value, consider - differentiating them form each other by their ID's rather than + differentiating them form each other by their IDs rather than returning zero. This to prevent rows with the same value jumping positions when items are added etc. For example: @code - // Differentiate items with the same value. + // Note that we need to distinguish between items with the same + // value. wxUIntPtr id1 = wxPtrToUInt(item1.GetID()), id2 = wxPtrToUInt(item2.GetID()); @@ -1440,6 +1442,16 @@ public: virtual wxRect GetItemRect(const wxDataViewItem& item, const wxDataViewColumn* col = NULL) const; + /** + Returns the window corresponding to the main area of the control. + + This is the window that actually shows the control items and may be + different from wxDataViewCtrl window itself in some ports (currently + this is only the case for the generic implementation used by default + under MSW). + */ + wxWindow* GetMainWindow(); + /** Returns pointer to the data model associated with the control (if any). */ @@ -1956,7 +1968,7 @@ public: /** Sets the alignment of the renderer's content. - The default value of @c wxDVR_DEFAULT_ALIGMENT indicates that the content + The default value of @c wxDVR_DEFAULT_ALIGNMENT indicates that the content should have the same alignment as the column header. The method is not implemented under OS X and the renderer always aligns @@ -3403,6 +3415,13 @@ public: without having to derive any class from it, but it is mostly used from within wxDataViewTreeCtrl. + Notice that by default this class sorts all items with children before the + leaf items. If this behaviour is inappropriate, you need to derive a custom + class from this one and override either its HasDefaultCompare() method to + return false, which would result in items being sorted just in the order in + which they were added, or its Compare() function to compare the items using + some other criterion, e.g. alphabetically. + @library{wxadv} @category{dvc} */ diff --git a/interface/wx/headerctrl.h b/interface/wx/headerctrl.h index 662d20df0e..8a9907d546 100644 --- a/interface/wx/headerctrl.h +++ b/interface/wx/headerctrl.h @@ -17,6 +17,9 @@ enum // right clicking the header wxHD_ALLOW_HIDE = 0x0002, + // force putting column images on right + wxHD_BITMAP_ON_RIGHT = 0x0004, + // style used by default when creating the control wxHD_DEFAULT_STYLE = wxHD_ALLOW_REORDER }; @@ -76,6 +79,11 @@ enum user to change the columns visibility on right mouse click. Notice that the program can always hide or show the columns, this style only affects the users capability to do it. + @style{wxHD_BITMAP_ON_RIGHT} + The column image, if any, will be shown on the right side if this style + is used. Note that this style is only implemented in wxMSW currently + and doesn't do anything under the other platforms. It is available + since wxWidgets 3.1.1. @style{wxHD_DEFAULT_STYLE} Symbolic name for the default control style, currently equal to @c wxHD_ALLOW_REORDER. diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index a53b1c7be3..26773c624d 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -23,6 +23,7 @@ #include "wx/wx.h" #endif +#include "wx/artprov.h" #include "wx/dataview.h" #include "wx/datetime.h" #include "wx/splitter.h" @@ -84,6 +85,7 @@ private: void OnCustomHeaderHeight(wxCommandEvent& event); #endif // wxHAS_GENERIC_DATAVIEWCTRL void OnGetPageInfo(wxCommandEvent& event); + void OnDisable(wxCommandEvent& event); void OnSetForegroundColour(wxCommandEvent& event); void OnIncIndent(wxCommandEvent& event); void OnDecIndent(wxCommandEvent& event); @@ -307,6 +309,7 @@ enum { ID_CLEARLOG = wxID_HIGHEST+1, ID_GET_PAGE_INFO, + ID_DISABLE, ID_BACKGROUND_COLOUR, ID_FOREGROUND_COLOUR, ID_CUSTOM_HEADER_ATTR, @@ -367,6 +370,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU( ID_CLEARLOG, MyFrame::OnClearLog ) EVT_MENU( ID_GET_PAGE_INFO, MyFrame::OnGetPageInfo ) + EVT_MENU( ID_DISABLE, MyFrame::OnDisable ) EVT_MENU( ID_FOREGROUND_COLOUR, MyFrame::OnSetForegroundColour ) EVT_MENU( ID_BACKGROUND_COLOUR, MyFrame::OnSetBackgroundColour ) EVT_MENU( ID_CUSTOM_HEADER_ATTR, MyFrame::OnCustomHeaderAttr ) @@ -460,6 +464,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int wxMenu *file_menu = new wxMenu; file_menu->Append(ID_CLEARLOG, "&Clear log\tCtrl-L"); file_menu->Append(ID_GET_PAGE_INFO, "Show current &page info"); + file_menu->AppendCheckItem(ID_DISABLE, "&Disable\tCtrl-D"); file_menu->Append(ID_FOREGROUND_COLOUR, "Set &foreground colour...\tCtrl-S"); file_menu->Append(ID_BACKGROUND_COLOUR, "Set &background colour...\tCtrl-B"); file_menu->AppendCheckItem(ID_CUSTOM_HEADER_ATTR, "C&ustom header attributes"); @@ -685,6 +690,7 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l wxDataViewColumn *column5 = new wxDataViewColumn( "custom", cr, 5, -1, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE ); + column5->SetBitmap(wxArtProvider::GetBitmap(wxART_INFORMATION, wxART_MENU)); m_ctrl[0]->AppendColumn( column5 ); @@ -830,6 +836,11 @@ void MyFrame::OnGetPageInfo(wxCommandEvent& WXUNUSED(event)) dvc->GetCountPerPage()); } +void MyFrame::OnDisable(wxCommandEvent& event) +{ + m_ctrl[m_notebook->GetSelection()]->Enable(!event.IsChecked()); +} + void MyFrame::OnSetForegroundColour(wxCommandEvent& WXUNUSED(event)) { wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()]; @@ -934,6 +945,8 @@ void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) ) GetMenuBar()->FindItem(id)->Check( m_ctrl[nPanel]->HasFlag(style) ); } + + GetMenuBar()->FindItem(ID_DISABLE)->Check(!m_ctrl[nPanel]->IsEnabled()); } void MyFrame::OnStyleChange( wxCommandEvent& WXUNUSED(event) ) diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index 008a61ad3d..df7ad9cd1f 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -95,9 +95,6 @@ wxFont wxDataViewItemAttr::GetEffectiveFont(const wxFont& font) const // wxDataViewModelNotifier // --------------------------------------------------------- -#include "wx/listimpl.cpp" -WX_DEFINE_LIST(wxDataViewModelNotifiers) - bool wxDataViewModelNotifier::ItemsAdded( const wxDataViewItem &parent, const wxDataViewItemArray &items ) { size_t count = items.GetCount(); @@ -134,7 +131,15 @@ bool wxDataViewModelNotifier::ItemsChanged( const wxDataViewItemArray &items ) wxDataViewModel::wxDataViewModel() { - m_notifiers.DeleteContents( true ); +} + +wxDataViewModel::~wxDataViewModel() +{ + wxDataViewModelNotifiers::const_iterator iter; + for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter) + { + delete *iter; + } } bool wxDataViewModel::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ) @@ -305,7 +310,20 @@ void wxDataViewModel::AddNotifier( wxDataViewModelNotifier *notifier ) void wxDataViewModel::RemoveNotifier( wxDataViewModelNotifier *notifier ) { - m_notifiers.DeleteObject( notifier ); + wxDataViewModelNotifiers::iterator iter; + for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter) + { + if ( *iter == notifier ) + { + delete notifier; + m_notifiers.erase(iter); + + // Skip the assert below. + return; + } + } + + wxFAIL_MSG(wxS("Removing non-registered notifier")); } int wxDataViewModel::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2, @@ -2408,9 +2426,6 @@ wxDataViewTreeStoreNode::~wxDataViewTreeStoreNode() delete m_data; } -#include "wx/listimpl.cpp" -WX_DEFINE_LIST(wxDataViewTreeStoreNodeList) - wxDataViewTreeStoreContainerNode::wxDataViewTreeStoreContainerNode( wxDataViewTreeStoreNode *parent, const wxString &text, const wxIcon &icon, const wxIcon &expanded, wxClientData *data ) @@ -2418,11 +2433,35 @@ wxDataViewTreeStoreContainerNode::wxDataViewTreeStoreContainerNode( , m_iconExpanded(expanded) { m_isExpanded = false; - m_children.DeleteContents(true); } wxDataViewTreeStoreContainerNode::~wxDataViewTreeStoreContainerNode() { + DestroyChildren(); +} + +wxDataViewTreeStoreNodes::iterator +wxDataViewTreeStoreContainerNode::FindChild(wxDataViewTreeStoreNode* node) +{ + wxDataViewTreeStoreNodes::iterator iter; + for (iter = m_children.begin(); iter != m_children.end(); ++iter) + { + if ( *iter == node ) + break; + } + + return iter; +} + +void wxDataViewTreeStoreContainerNode::DestroyChildren() +{ + wxDataViewTreeStoreNodes::const_iterator iter; + for (iter = m_children.begin(); iter != m_children.end(); ++iter) + { + delete *iter; + } + + m_children.clear(); } //----------------------------------------------------------------------------- @@ -2445,7 +2484,7 @@ wxDataViewItem wxDataViewTreeStore::AppendItem( const wxDataViewItem& parent, wxDataViewTreeStoreNode *node = new wxDataViewTreeStoreNode( parent_node, text, icon, data ); - parent_node->GetChildren().Append( node ); + parent_node->GetChildren().push_back( node ); return node->GetItem(); } @@ -2458,7 +2497,8 @@ wxDataViewItem wxDataViewTreeStore::PrependItem( const wxDataViewItem& parent, wxDataViewTreeStoreNode *node = new wxDataViewTreeStoreNode( parent_node, text, icon, data ); - parent_node->GetChildren().Insert( node ); + wxDataViewTreeStoreNodes& children = parent_node->GetChildren(); + children.insert(children.begin(), node); return node->GetItem(); } @@ -2474,12 +2514,13 @@ wxDataViewTreeStore::InsertItem(const wxDataViewItem& parent, if (!parent_node) return wxDataViewItem(0); wxDataViewTreeStoreNode *previous_node = FindNode( previous ); - int pos = parent_node->GetChildren().IndexOf( previous_node ); - if (pos == wxNOT_FOUND) return wxDataViewItem(0); + wxDataViewTreeStoreNodes& children = parent_node->GetChildren(); + const wxDataViewTreeStoreNodes::iterator iter = parent_node->FindChild( previous_node ); + if (iter == children.end()) return wxDataViewItem(0); wxDataViewTreeStoreNode *node = new wxDataViewTreeStoreNode( parent_node, text, icon, data ); - parent_node->GetChildren().Insert( (size_t) pos, node ); + children.insert(iter, node); return node->GetItem(); } @@ -2493,7 +2534,8 @@ wxDataViewItem wxDataViewTreeStore::PrependContainer( const wxDataViewItem& pare wxDataViewTreeStoreContainerNode *node = new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data ); - parent_node->GetChildren().Insert( node ); + wxDataViewTreeStoreNodes& children = parent_node->GetChildren(); + children.insert(children.begin(), node); return node->GetItem(); } @@ -2510,7 +2552,7 @@ wxDataViewTreeStore::AppendContainer(const wxDataViewItem& parent, wxDataViewTreeStoreContainerNode *node = new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data ); - parent_node->GetChildren().Append( node ); + parent_node->GetChildren().push_back( node ); return node->GetItem(); } @@ -2527,12 +2569,13 @@ wxDataViewTreeStore::InsertContainer(const wxDataViewItem& parent, if (!parent_node) return wxDataViewItem(0); wxDataViewTreeStoreNode *previous_node = FindNode( previous ); - int pos = parent_node->GetChildren().IndexOf( previous_node ); - if (pos == wxNOT_FOUND) return wxDataViewItem(0); + wxDataViewTreeStoreNodes& children = parent_node->GetChildren(); + const wxDataViewTreeStoreNodes::iterator iter = parent_node->FindChild( previous_node ); + if (iter == children.end()) return wxDataViewItem(0); wxDataViewTreeStoreContainerNode *node = new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data ); - parent_node->GetChildren().Insert( (size_t) pos, node ); + children.insert(iter, node); return node->GetItem(); } @@ -2550,7 +2593,7 @@ wxDataViewItem wxDataViewTreeStore::GetNthChild( const wxDataViewItem& parent, u wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent ); if (!parent_node) return wxDataViewItem(0); - wxDataViewTreeStoreNodeList::compatibility_iterator node = parent_node->GetChildren().Item( pos ); + wxDataViewTreeStoreNode* const node = parent_node->GetChildren()[pos]; if (node) return wxDataViewItem(node->GetData()); @@ -2566,7 +2609,7 @@ int wxDataViewTreeStore::GetChildCount( const wxDataViewItem& parent ) const return 0; wxDataViewTreeStoreContainerNode *container_node = (wxDataViewTreeStoreContainerNode*) node; - return (int) container_node->GetChildren().GetCount(); + return (int) container_node->GetChildren().size(); } void wxDataViewTreeStore::SetItemText( const wxDataViewItem& item, const wxString &text ) @@ -2642,7 +2685,13 @@ void wxDataViewTreeStore::DeleteItem( const wxDataViewItem& item ) wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent_item ); if (!parent_node) return; - parent_node->GetChildren().DeleteObject( FindNode(item) ); + const wxDataViewTreeStoreNodes::iterator + iter = parent_node->FindChild(FindNode(item)); + if ( iter != parent_node->GetChildren().end() ) + { + delete *iter; + parent_node->GetChildren().erase(iter); + } } void wxDataViewTreeStore::DeleteChildren( const wxDataViewItem& item ) @@ -2650,7 +2699,7 @@ void wxDataViewTreeStore::DeleteChildren( const wxDataViewItem& item ) wxDataViewTreeStoreContainerNode *node = FindContainerNode( item ); if (!node) return; - node->GetChildren().clear(); + node->DestroyChildren(); } void wxDataViewTreeStore::DeleteAllItems() @@ -2720,14 +2769,14 @@ unsigned int wxDataViewTreeStore::GetChildren( const wxDataViewItem &item, wxDat wxDataViewTreeStoreContainerNode *node = FindContainerNode( item ); if (!node) return 0; - wxDataViewTreeStoreNodeList::iterator iter; + wxDataViewTreeStoreNodes::iterator iter; for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); ++iter) { wxDataViewTreeStoreNode* child = *iter; children.Add( child->GetItem() ); } - return node->GetChildren().GetCount(); + return node->GetChildren().size(); } int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2, @@ -2736,19 +2785,14 @@ int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewI wxDataViewTreeStoreNode *node1 = FindNode( item1 ); wxDataViewTreeStoreNode *node2 = FindNode( item2 ); - if (!node1 || !node2) + if (!node1 || !node2 || (node1 == node2)) return 0; - wxDataViewTreeStoreContainerNode* parent1 = + wxDataViewTreeStoreContainerNode* const parent = (wxDataViewTreeStoreContainerNode*) node1->GetParent(); - wxDataViewTreeStoreContainerNode* parent2 = - (wxDataViewTreeStoreContainerNode*) node2->GetParent(); - if (parent1 != parent2) - { - wxLogError( wxT("Comparing items with different parent.") ); - return 0; - } + wxCHECK_MSG( node2->GetParent() == parent, 0, + wxS("Comparing items with different parent.") ); if (node1->IsContainer() && !node2->IsContainer()) return -1; @@ -2756,7 +2800,18 @@ int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewI if (node2->IsContainer() && !node1->IsContainer()) return 1; - return parent1->GetChildren().IndexOf( node1 ) - parent2->GetChildren().IndexOf( node2 ); + wxDataViewTreeStoreNodes::const_iterator iter; + for (iter = parent->GetChildren().begin(); iter != parent->GetChildren().end(); ++iter) + { + if ( *iter == node1 ) + return -1; + + if ( *iter == node2 ) + return 1; + } + + wxFAIL_MSG(wxS("Unreachable")); + return 0; } wxDataViewTreeStoreNode *wxDataViewTreeStore::FindNode( const wxDataViewItem &item ) const @@ -2925,7 +2980,7 @@ void wxDataViewTreeCtrl::DeleteChildren( const wxDataViewItem& item ) if (!node) return; wxDataViewItemArray array; - wxDataViewTreeStoreNodeList::iterator iter; + wxDataViewTreeStoreNodes::iterator iter; for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); ++iter) { wxDataViewTreeStoreNode* child = *iter; diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 9a4f08276e..d9840af8ab 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -75,15 +75,6 @@ static const int SCROLL_UNIT_X = 15; // the cell padding on the left/right static const int PADDING_RIGHTLEFT = 3; -// the expander space margin -static const int EXPANDER_MARGIN = 4; - -#ifdef __WXMSW__ -static const int EXPANDER_OFFSET = 4; -#else -static const int EXPANDER_OFFSET = 1; -#endif - namespace { @@ -273,7 +264,9 @@ class wxDataViewHeaderWindow : public wxHeaderCtrl { public: wxDataViewHeaderWindow(wxDataViewCtrl *parent) - : wxHeaderCtrl(parent) + : wxHeaderCtrl(parent, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + wxHD_DEFAULT_STYLE | wxHD_BITMAP_ON_RIGHT) { } @@ -939,9 +932,6 @@ private: // the pen used to draw horiz/vertical rules wxPen m_penRule; - // the pen used to draw the expander and the lines - wxPen m_penExpander; - // This is the tree structure of the model wxDataViewTreeNode * m_root; int m_count; @@ -1383,7 +1373,18 @@ wxString wxDataViewProgressRenderer::GetAccessibleDescription() const bool wxDataViewProgressRenderer::Render(wxRect rect, wxDC *dc, int WXUNUSED(state)) { - wxRendererNative::Get().DrawGauge( + const wxDataViewItemAttr& attr = GetAttr(); + if ( attr.HasColour() ) + dc->SetBackground(attr.GetColour()); + + // This is a hack, but native renderers don't support using custom colours, + // but typically gauge colour is important (e.g. it's commonly green/red to + // indicate some qualitative difference), so we fall back to the generic + // implementation which looks ugly but does support using custom colour. + wxRendererNative& renderer = attr.HasColour() + ? wxRendererNative::GetGeneric() + : wxRendererNative::Get(); + renderer.DrawGauge( GetOwner()->GetOwner(), *dc, rect, @@ -1966,10 +1967,6 @@ wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID i m_penRule = wxPen(GetRuleColour()); - // compose a pen whichcan draw black lines - // TODO: maybe there is something system colour to use - m_penExpander = wxPen(wxColour(0,0,0)); - m_root = wxDataViewTreeNode::CreateRootNode(); // Make m_count = -1 will cause the class recaculate the real displaying number of rows. @@ -2540,23 +2537,17 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // Calculate the indent first indent = GetOwner()->GetIndent() * node->GetIndentLevel(); - // we reserve m_lineHeight of horizontal space for the expander - // but leave EXPANDER_MARGIN around the expander itself - int exp_x = cell_rect.x + indent + EXPANDER_MARGIN; + // We don't have any method to return the size of the expander + // button currently (TODO: add one to wxRendererNative), so + // just guesstimate it. + const int expWidth = 3*dc.GetCharWidth(); - indent += m_lineHeight; - - // draw expander if needed and visible - if ( node->HasChildren() && exp_x < cell_rect.GetRight() ) + // draw expander if needed + if ( node->HasChildren() ) { - dc.SetPen( m_penExpander ); - dc.SetBrush( wxNullBrush ); - - int exp_size = m_lineHeight - 2*EXPANDER_MARGIN; - int exp_y = cell_rect.y + (cell_rect.height - exp_size)/2 - + EXPANDER_MARGIN - EXPANDER_OFFSET; - - const wxRect rect(exp_x, exp_y, exp_size, exp_size); + wxRect rect = cell_rect; + rect.x += indent; + rect.width = expWidth; int flag = 0; if ( m_underMouse == node ) @@ -2571,6 +2562,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag); } + indent += expWidth; + // force the expander column to left-center align cell->SetAlignment( wxALIGN_CENTER_VERTICAL ); } @@ -4728,9 +4721,9 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if ( UnselectAllRows(m_lineSelectSingleOnUp) ) { SelectRow( m_lineSelectSingleOnUp, true ); - SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) ); } - //else: it was already selected, nothing to do + + SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) ); } // If the user click the expander, we do not do editing even if the column @@ -5228,17 +5221,6 @@ bool wxDataViewCtrl::Show(bool show) return changed; } -bool wxDataViewCtrl::Enable(bool enable) -{ - bool changed = wxControl::Enable(enable); - if ( changed ) - { - wxAccessible::NotifyEvent(wxACC_EVENT_OBJECT_STATECHANGE, this, wxOBJID_CLIENT, wxACC_SELF); - } - - return changed; -} - void wxDataViewCtrl::SetName(const wxString &name) { wxControl::SetName(name); @@ -5257,6 +5239,20 @@ bool wxDataViewCtrl::Reparent(wxWindowBase *newParent) } #endif // wxUSE_ACCESIBILITY +bool wxDataViewCtrl::Enable(bool enable) +{ + bool changed = wxControl::Enable(enable); + if ( changed ) + { +#if wxUSE_ACCESSIBILITY + wxAccessible::NotifyEvent(wxACC_EVENT_OBJECT_STATECHANGE, this, wxOBJID_CLIENT, wxACC_SELF); +#endif // wxUSE_ACCESIBILITY + Refresh(); + } + + return changed; +} + bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) { if (!wxDataViewCtrlBase::AssociateModel( model )) diff --git a/src/generic/renderg.cpp b/src/generic/renderg.cpp index 5cf2656cef..fc2f39645d 100644 --- a/src/generic/renderg.cpp +++ b/src/generic/renderg.cpp @@ -912,6 +912,18 @@ void wxRendererGeneric::DrawGauge(wxWindow* win, int max, int flags) { + // This is a hack, but we want to allow customizing the colour used for the + // gauge body, as this is important for the generic wxDataViewCtrl + // implementation which uses this method. So we assume that if the caller + // had set up a brush using background colour different from the default, + // it should be used. Otherwise we use the default one. + const wxBrush& bg = dc.GetBackground(); + wxColour colBar; + if ( bg.IsOk() && bg.GetColour() != win->GetBackgroundColour() ) + colBar = bg.GetColour(); + else + colBar = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); + // Use same background as text controls. DrawTextCtrl(win, dc, rect); @@ -929,7 +941,7 @@ void wxRendererGeneric::DrawGauge(wxWindow* win, progRect.width = wxMulDivInt32(progRect.width, value, max); } - dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)); + dc.SetBrush(colBar); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(progRect); } diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index 267775f582..1694a8e288 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -314,6 +314,9 @@ void wxHeaderCtrl::DoInsertItem(const wxHeaderColumn& col, unsigned int idx) { hdi.mask |= HDI_IMAGE; + if ( HasFlag(wxHD_BITMAP_ON_RIGHT) ) + hdi.fmt |= HDF_BITMAP_ON_RIGHT; + if ( bmp.IsOk() ) { const int bmpWidth = bmp.GetWidth(), diff --git a/src/msw/window.cpp b/src/msw/window.cpp index ead90f0321..0082cef587 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -4169,6 +4169,14 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) return false; } + if ( ContainsHWND(hwnd) ) + { + // If another subwindow of this window already had focus before, this + // window should already have focus at wx level, no need for another + // event. + return false; + } + // notify the parent keeping track of focus for the kbd navigation // purposes that we got it wxChildFocusEvent eventFocus((wxWindow *)this); @@ -4193,6 +4201,20 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) bool wxWindowMSW::HandleKillFocus(WXHWND hwnd) { + // Don't send the event when in the process of being deleted. This can + // only cause problems if the event handler tries to access the object. + if ( m_isBeingDeleted ) + { + return false; + } + + if ( ContainsHWND(hwnd) ) + { + // If the focus switches to another HWND which is part of the same + // wxWindow, we must not generate a wxEVT_KILL_FOCUS. + return false; + } + #if wxUSE_CARET // Deal with caret if ( m_caret ) @@ -4201,13 +4223,6 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd) } #endif // wxUSE_CARET - // Don't send the event when in the process of being deleted. This can - // only cause problems if the event handler tries to access the object. - if ( m_isBeingDeleted ) - { - return false; - } - wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId); event.SetEventObject(this); diff --git a/src/osx/cocoa/dataview.mm b/src/osx/cocoa/dataview.mm index eac9a0fbda..0b1ee6b419 100644 --- a/src/osx/cocoa/dataview.mm +++ b/src/osx/cocoa/dataview.mm @@ -3507,23 +3507,27 @@ void wxDataViewColumn::SetSortable(bool sortable) void wxDataViewColumn::SetSortOrder(bool ascending) { - if (m_ascending != ascending) + NSTableColumn* const tableColumn = m_NativeDataPtr->GetNativeColumnPtr(); + NSTableView* tableView = [tableColumn tableView]; + + wxCHECK_RET( tableView, wxS("Column has to be associated with a table view when the sorting order is set") ); + + if ( (m_ascending != ascending) || ([tableColumn sortDescriptorPrototype] == nil) ) { m_ascending = ascending; - if (IsSortKey()) - { - // change sorting order: - NSArray* sortDescriptors; - NSSortDescriptor* sortDescriptor; - NSTableColumn* tableColumn; - tableColumn = m_NativeDataPtr->GetNativeColumnPtr(); - sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[[tableColumn sortDescriptorPrototype] key] ascending:m_ascending]; - sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; - [tableColumn setSortDescriptorPrototype:sortDescriptor]; - [[tableColumn tableView] setSortDescriptors:sortDescriptors]; - [sortDescriptor release]; - } + // change sorting order for the native implementation (this will + // trigger a call to outlineView:sortDescriptorsDidChange: where the + // wxWidget's sort descriptors are going to be set): + NSSortDescriptor* const + sortDescriptor = [[NSSortDescriptor alloc] + initWithKey:[NSString stringWithFormat:@"%ld",(long)[tableView columnWithIdentifier:[tableColumn identifier]]] + ascending:m_ascending]; + + NSArray* sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; + [tableColumn setSortDescriptorPrototype:sortDescriptor]; + [tableView setSortDescriptors:sortDescriptors]; + [sortDescriptor release]; } }