X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1d3a930e82ed6eb40e8ddce64997a8a017f4f49d..b0ec002323e2a8b17fe2a9eb13db97d7ca8c1471:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index e8025a76a8..a44600da4e 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -34,6 +34,7 @@ #include "wx/gtk/private/gdkconv.h" #include "wx/gtk/private/list.h" +#include "wx/gtk/private/event.h" using namespace wxGTKImpl; class wxGtkDataViewModelNotifier; @@ -431,6 +432,20 @@ public: } } + // returns position of child node for given item in children list or wxNOT_FOUND + int FindChildByItem(const wxDataViewItem& item) const + { + const void* itemId = item.GetID(); + const wxGtkTreeModelChildren& nodes = m_children; + const int len = nodes.size(); + for ( int i = 0; i < len; i++ ) + { + if ( nodes[i] == itemId ) + return i; + } + return wxNOT_FOUND; + } + wxGtkTreeModelNode* GetParent() { return m_parent; } wxGtkTreeModelNodes &GetNodes() @@ -1209,7 +1224,6 @@ struct _GtkWxCellRenderer /*< private >*/ wxDataViewCustomRenderer *cell; - guint32 last_click; }; struct _GtkWxCellRendererClass @@ -1294,7 +1308,6 @@ static void gtk_wx_cell_renderer_init (GtkWxCellRenderer *cell) { cell->cell = NULL; - cell->last_click = 0; } static void @@ -1510,37 +1523,27 @@ gtk_wx_cell_renderer_activate( unsigned int model_col = cell->GetOwner()->GetModelColumn(); - if (!event) + if ( !event ) { - bool ret = false; - // activated by - if (cell->Activate( renderrect, model, item, model_col )) - ret = true; - - return ret; + return cell->ActivateCell(renderrect, model, item, model_col, NULL); } - else if (event->type == GDK_BUTTON_PRESS) + else if ( event->type == GDK_BUTTON_PRESS ) { - GdkEventButton *button_event = (GdkEventButton*) event; - wxPoint pt( ((int) button_event->x) - renderrect.x, - ((int) button_event->y) - renderrect.y ); - - bool ret = false; - if (button_event->button == 1) + GdkEventButton *button_event = (GdkEventButton*)event; + if ( button_event->button == 1 ) { - if (cell->LeftClick( pt, renderrect, model, item, model_col )) - ret = true; - // TODO: query system double-click time - if (button_event->time - wxrenderer->last_click < 400) - if (cell->Activate( renderrect, model, item, model_col )) - ret = true; - } - wxrenderer->last_click = button_event->time; + wxMouseEvent mouse_event(wxEVT_LEFT_DOWN); + InitMouseEvent(ctrl, mouse_event, button_event); + + mouse_event.m_x -= renderrect.x; + mouse_event.m_y -= renderrect.y; - return ret; + return cell->ActivateCell(renderrect, model, item, model_col, &mouse_event); + } } + wxLogDebug("unexpected event type in gtk_wx_cell_renderer_activate()"); return false; } @@ -2567,11 +2570,13 @@ void wxDataViewProgressRenderer::GTKSetLabel() // Take care to not use GetOwner() here if the label is empty, we can be // called from ctor when GetOwner() is still NULL in this case. - g_value_set_string( &gvalue, - m_label.empty() ? "" - : wxGTK_CONV_FONT(m_label, - GetOwner()->GetOwner()->GetFont()) - ); + wxScopedCharBuffer buf; + if ( m_label.empty() ) + buf = wxScopedCharBuffer::CreateNonOwned(""); + else + buf = wxGTK_CONV_FONT(m_label, GetOwner()->GetOwner()->GetFont()); + + g_value_set_string( &gvalue, buf); g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue ); g_value_unset( &gvalue ); @@ -3683,15 +3688,56 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa wxCHECK_MSG(parent_node, false, "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); - wxDataViewItemArray siblings; - m_wx_model->GetChildren(parent, siblings); - int itemPos = siblings.Index(item, /*fromEnd=*/true); - wxCHECK_MSG( itemPos != wxNOT_FOUND, false, "adding non-existent item?" ); + wxDataViewItemArray modelSiblings; + m_wx_model->GetChildren(parent, modelSiblings); + const int modelSiblingsSize = modelSiblings.size(); + + int posInModel = modelSiblings.Index(item, /*fromEnd=*/true); + wxCHECK_MSG( posInModel != wxNOT_FOUND, false, "adding non-existent item?" ); + + const wxGtkTreeModelChildren& nodeSiblings = parent_node->GetChildren(); + const int nodeSiblingsSize = nodeSiblings.size(); + + int nodePos = 0; + + if ( posInModel == modelSiblingsSize - 1 ) + { + nodePos = nodeSiblingsSize; + } + else if ( modelSiblingsSize == nodeSiblingsSize + 1 ) + { + // This is the simple case when our node tree already matches the + // model and only this one item is missing. + nodePos = posInModel; + } + else + { + // It's possible that a larger discrepancy between the model and + // our realization exists. This can happen e.g. when adding a bunch + // of items to the model and then calling ItemsAdded() just once + // afterwards. In this case, we must find the right position by + // looking at sibling items. + + // append to the end if we won't find a better position: + nodePos = nodeSiblingsSize; + + for ( int nextItemPos = posInModel + 1; + nextItemPos < modelSiblingsSize; + nextItemPos++ ) + { + int nextNodePos = parent_node->FindChildByItem(modelSiblings[nextItemPos]); + if ( nextNodePos != wxNOT_FOUND ) + { + nodePos = nextNodePos; + break; + } + } + } if (m_wx_model->IsContainer( item )) - parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), itemPos ); + parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), nodePos ); else - parent_node->InsertLeaf( item.GetID(), itemPos ); + parent_node->InsertLeaf( item.GetID(), nodePos ); } ScheduleRefresh();