]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/datavgen.cpp
Merge r53510 from 2.8 branch
[wxWidgets.git] / src / generic / datavgen.cpp
index b509ac317da70849186de63b26fbfacb5ab8f335..53cde9cdc6cfa8ba9630934de5687e160e6f122d 100644 (file)
@@ -44,6 +44,7 @@
 #include "wx/icon.h"
 #include "wx/list.h"
 #include "wx/listimpl.cpp"
 #include "wx/icon.h"
 #include "wx/list.h"
 #include "wx/listimpl.cpp"
+#include "wx/imaglist.h"
 
 //-----------------------------------------------------------------------------
 // classes
 
 //-----------------------------------------------------------------------------
 // classes
@@ -159,9 +160,10 @@ protected:
     wxDataViewColumn *GetColumnFromHeader(NMHEADER *nmHDR)
         { return GetColumn(GetColumnIdxFromHeader(nmHDR)); }
 
     wxDataViewColumn *GetColumnFromHeader(NMHEADER *nmHDR)
         { return GetColumn(GetColumnIdxFromHeader(nmHDR)); }
 
-    int   m_scrollOffsetX;
-    int   m_buttonHeight;
-    bool  m_delayedUpdate;
+    int          m_scrollOffsetX;
+    int          m_buttonHeight;
+    bool         m_delayedUpdate;
+    wxImageList *m_imageList;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW)
 
 private:
     DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW)
@@ -641,6 +643,29 @@ wxDC *wxDataViewRenderer::GetDC()
     return m_dc;
 }
 
     return m_dc;
 }
 
+void wxDataViewRenderer::SetAlignment( int align )
+{ 
+    m_align=align;
+}
+
+int wxDataViewRenderer::GetAlignment() const
+{
+    return m_align;
+}
+
+int wxDataViewRenderer::CalculateAlignment() const
+{ 
+    if (m_align == wxDVR_DEFAULT_ALIGNMENT)
+    {
+        if (GetOwner() == NULL)
+           return wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL;
+           
+        return GetOwner()->GetAlignment() | wxALIGN_CENTRE_VERTICAL;
+    }
+    
+    return m_align;
+}
+
 // ---------------------------------------------------------
 // wxDataViewCustomRenderer
 // ---------------------------------------------------------
 // ---------------------------------------------------------
 // wxDataViewCustomRenderer
 // ---------------------------------------------------------
@@ -1162,7 +1187,7 @@ wxDataViewColumn::wxDataViewColumn( const wxBitmap &bitmap, wxDataViewRenderer *
     SetAlignment(align);
     SetFlags(flags);
 
     SetAlignment(align);
     SetFlags(flags);
 
-    Init(width < 0 ? wxDVC_TOGGLE_DEFAULT_WIDTH : width);
+    Init(width < 0 ? wxDVC_DEFAULT_WIDTH : width);
 }
 
 wxDataViewColumn::~wxDataViewColumn()
 }
 
 wxDataViewColumn::~wxDataViewColumn()
@@ -1323,6 +1348,9 @@ bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id,
         return false;
     }
 
         return false;
     }
 
+    m_imageList = new wxImageList( 16, 16 );
+    Header_SetImageList( (HWND) m_hWnd, m_imageList->GetHIMAGELIST() );
+
     // we need to subclass the m_hWnd to force wxWindow::HandleNotify
     // to call wxDataViewHeaderWindow::MSWOnNotify
     SubclassWin(m_hWnd);
     // we need to subclass the m_hWnd to force wxWindow::HandleNotify
     // to call wxDataViewHeaderWindow::MSWOnNotify
     SubclassWin(m_hWnd);
@@ -1336,6 +1364,7 @@ bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id,
 
 wxDataViewHeaderWindowMSW::~wxDataViewHeaderWindow()
 {
 
 wxDataViewHeaderWindowMSW::~wxDataViewHeaderWindow()
 {
+    delete m_imageList;
     UnsubclassWin();
 }
 
     UnsubclassWin();
 }
 
@@ -1358,6 +1387,8 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay()
     // remove old columns
     for (int j=0, max=Header_GetItemCount((HWND)m_hWnd); j < max; j++)
         Header_DeleteItem((HWND)m_hWnd, 0);
     // remove old columns
     for (int j=0, max=Header_GetItemCount((HWND)m_hWnd); j < max; j++)
         Header_DeleteItem((HWND)m_hWnd, 0);
+        
+    m_imageList->RemoveAll();
 
     // add the updated array of columns to the header control
     unsigned int cols = GetOwner()->GetColumnCount();
 
     // add the updated array of columns to the header control
     unsigned int cols = GetOwner()->GetColumnCount();
@@ -1370,10 +1401,19 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay()
 
         HDITEM hdi;
         hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
 
         HDITEM hdi;
         hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
+        if (col->GetBitmap().IsOk())
+        {
+           m_imageList->Add( col->GetBitmap() );
+           hdi.mask |= HDI_IMAGE;
+           hdi.iImage = m_imageList->GetImageCount()-1;
+        }
         hdi.pszText = (wxChar *) col->GetTitle().wx_str();
         hdi.cxy = col->GetWidth();
         hdi.cchTextMax = sizeof(hdi.pszText)/sizeof(hdi.pszText[0]);
         hdi.fmt = HDF_LEFT | HDF_STRING;
         hdi.pszText = (wxChar *) col->GetTitle().wx_str();
         hdi.cxy = col->GetWidth();
         hdi.cchTextMax = sizeof(hdi.pszText)/sizeof(hdi.pszText[0]);
         hdi.fmt = HDF_LEFT | HDF_STRING;
+        if (col->GetBitmap().IsOk())
+            hdi.fmt |= HDF_IMAGE;
+        
         //hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
 
         if (col->IsSortable() && GetOwner()->GetSortingColumn() == col)
         //hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
 
         if (col->IsSortable() && GetOwner()->GetSortingColumn() == col)
@@ -1464,7 +1504,7 @@ bool wxDataViewHeaderWindowMSW::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARA
 
         case HDN_BEGINDRAG:
             // user has started to reorder a column
 
         case HDN_BEGINDRAG:
             // user has started to reorder a column
-            if (!GetColumn(nmHDR->iItem)->IsReorderable())
+            if ((nmHDR->iItem != -1) && (!GetColumn(nmHDR->iItem)->IsReorderable()))
             {
                 // veto it!
                 *result = TRUE;
             {
                 // veto it!
                 *result = TRUE;
@@ -1921,7 +1961,7 @@ void wxDataViewRenameTimer::Notify()
 //-----------------------------------------------------------------------------
 
 //The tree building helper, declared firstly
 //-----------------------------------------------------------------------------
 
 //The tree building helper, declared firstly
-void BuildTreeHelper( wxDataViewModel * model,  wxDataViewItem & item, wxDataViewTreeNode * node);
+static void BuildTreeHelper( wxDataViewModel * model,  wxDataViewItem & item, wxDataViewTreeNode * node);
 
 int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 )
 {
 
 int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 )
 {
@@ -2196,19 +2236,15 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
                     else
                         wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag);
                 }
                     else
                         wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag);
                 }
-                else
-                {
-                     // I am wondering whether we should draw dot lines between tree nodes
-                     if (node)
-                         delete node;
-                     // Yes, if the node does not have any child, it must be a leaf which
-                     // mean that it is a temporarily created by GetTreeNodeByRow
-                }
-
                  //force the expander column to left-center align
                  cell->SetAlignment( wxALIGN_CENTER_VERTICAL );
             }
                  //force the expander column to left-center align
                  cell->SetAlignment( wxALIGN_CENTER_VERTICAL );
             }
-
+            if (node && !node->HasChildren())
+            {
+                // Yes, if the node does not have any child, it must be a leaf which
+                // mean that it is a temporarily created by GetTreeNodeByRow
+                wxDELETE(node)
+            }
 
             // cannot be bigger than allocated space
             wxSize size = cell->GetSize();
 
             // cannot be bigger than allocated space
             wxSize size = cell->GetSize();
@@ -2218,7 +2254,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
             size.y = cell_rect.height;
 
             wxRect item_rect(cell_rect.GetTopLeft(), size);
             size.y = cell_rect.height;
 
             wxRect item_rect(cell_rect.GetTopLeft(), size);
-            int align = cell->GetAlignment();
+            int align = cell->CalculateAlignment();
 
             // horizontal alignment:
             item_rect.x = cell_rect.x;
 
             // horizontal alignment:
             item_rect.x = cell_rect.x;
@@ -2399,7 +2435,7 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData
     return true;
 }
 
     return true;
 }
 
-void DestroyTreeHelper( wxDataViewTreeNode * node);
+static void DestroyTreeHelper( wxDataViewTreeNode * node);
 
 bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
                                        const wxDataViewItem& item)
 
 bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
                                        const wxDataViewItem& item)
@@ -2457,16 +2493,11 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
 
         node->GetNodes().Remove( n );
         sub -= n->GetSubTreeCount();
 
         node->GetNodes().Remove( n );
         sub -= n->GetSubTreeCount();
-        DestroyTreeHelper(n);
+        ::DestroyTreeHelper(n);
     }
     //Make the row number invalid and get a new valid one when user call GetRowCount
     m_count = -1;
     node->ChangeSubTreeCount(sub);
     }
     //Make the row number invalid and get a new valid one when user call GetRowCount
     m_count = -1;
     node->ChangeSubTreeCount(sub);
-    if( node->GetChildrenNumber() == 0)
-    {
-        node->GetParent()->GetNodes().Remove( node );
-        delete node;
-    }
 
     //Change the current row to the last row if the current exceed the max row number
     if( m_currentRow > GetRowCount() )
 
     //Change the current row to the last row if the current exceed the max row number
     if( m_currentRow > GetRowCount() )
@@ -3073,7 +3104,7 @@ void wxDataViewMainWindow::OnExpanding( unsigned int row )
                if( node->GetChildrenNumber() == 0 )
                {
                    SortPrepare();
                if( node->GetChildrenNumber() == 0 )
                {
                    SortPrepare();
-                   BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
+                   ::BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
                }
                m_count = -1;
                UpdateDisplay();
                }
                m_count = -1;
                UpdateDisplay();
@@ -3157,26 +3188,32 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item
             if( node->GetChildrenNumber() == 0 )
             {
                 SortPrepare();
             if( node->GetChildrenNumber() == 0 )
             {
                 SortPrepare();
-                BuildTreeHelper(model, node->GetItem(), node);
+                ::BuildTreeHelper(model, node->GetItem(), node);
             }
 
             wxDataViewTreeNodes nodes = node->GetNodes();
             }
 
             wxDataViewTreeNodes nodes = node->GetNodes();
-            unsigned int i = 0;
-            for (; i < nodes.GetCount(); i ++)
+            unsigned int i;
+            bool found = false;
+            
+            for (i = 0; i < nodes.GetCount(); i ++)
             {
                 if (nodes[i]->GetItem() == (**iter))
                 {
             {
                 if (nodes[i]->GetItem() == (**iter))
                 {
+                    if (nodes[i]->GetItem() == item)
+                       return nodes[i];
+                       
                     node = nodes[i];
                     node = nodes[i];
+                    found = true;
                     break;
                 }
             }
                     break;
                 }
             }
-            if (i == nodes.GetCount())
+            if (!found)
                 return NULL;
         }
         else
             return NULL;
     }
                 return NULL;
         }
         else
             return NULL;
     }
-    return node;
+    return NULL;
 }
 
 void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column )
 }
 
 void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column )
@@ -3320,7 +3357,7 @@ int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item)
     }
 }
 
     }
 }
 
-void BuildTreeHelper( wxDataViewModel * model,  wxDataViewItem & item, wxDataViewTreeNode * node)
+static void BuildTreeHelper( wxDataViewModel * model,  wxDataViewItem & item, wxDataViewTreeNode * node)
 {
     if( !model->IsContainer( item ) )
         return ;
 {
     if( !model->IsContainer( item ) )
         return ;
@@ -3354,7 +3391,7 @@ void wxDataViewMainWindow::BuildTree(wxDataViewModel * model)
 {
     DestroyTree();
 
 {
     DestroyTree();
 
-    if (GetOwner()->GetModel()->IsIndexListModel())
+    if (GetOwner()->GetModel()->IsVirtualListModel())
     {
         m_count = -1 ;
         return;
     {
         m_count = -1 ;
         return;
@@ -3370,13 +3407,13 @@ void wxDataViewMainWindow::BuildTree(wxDataViewModel * model)
     m_count = -1 ;
 }
 
     m_count = -1 ;
 }
 
-void DestroyTreeHelper( wxDataViewTreeNode * node )
+static void DestroyTreeHelper( wxDataViewTreeNode * node )
 {
     if( node->GetNodeNumber() != 0 )
     {
         int len = node->GetNodeNumber();
         int i = 0 ;
 {
     if( node->GetNodeNumber() != 0 )
     {
         int len = node->GetNodeNumber();
         int i = 0 ;
-        wxDataViewTreeNodes nodes = node->GetNodes();
+        wxDataViewTreeNodes& nodes = node->GetNodes();
         for( ; i < len; i ++ )
         {
             DestroyTreeHelper(nodes[i]);
         for( ; i < len; i ++ )
         {
             DestroyTreeHelper(nodes[i]);
@@ -3389,7 +3426,7 @@ void wxDataViewMainWindow::DestroyTree()
 {
     if (m_root)
     {
 {
     if (m_root)
     {
-        DestroyTreeHelper(m_root);
+       ::DestroyTreeHelper(m_root);
         m_count = 0;
         m_root = NULL;
     }
         m_count = 0;
         m_root = NULL;
     }
@@ -3666,12 +3703,14 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
                         OnExpanding( current );
                 }
             }
                         OnExpanding( current );
                 }
             }
+            if (node && !node->HasChildren())
+               delete node;
         }
         //If the user click the expander, we do not do editing even if the column with expander are editable
         if (m_lastOnSame && !expander && !ignore_other_columns)
         {
             if ((col == m_currentCol) && (current == m_currentRow) &&
         }
         //If the user click the expander, we do not do editing even if the column with expander are editable
         if (m_lastOnSame && !expander && !ignore_other_columns)
         {
             if ((col == m_currentCol) && (current == m_currentRow) &&
-                (cell->GetMode() == wxDATAVIEW_CELL_EDITABLE) )
+                (cell->GetMode() & wxDATAVIEW_CELL_EDITABLE) )
             {
                 m_renameTimer->Start( 100, true );
             }
             {
                 m_renameTimer->Start( 100, true );
             }
@@ -3704,28 +3743,18 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
             SendSelectionChangedEvent(GetItemByRow( m_currentRow ) );
         }
 
             SendSelectionChangedEvent(GetItemByRow( m_currentRow ) );
         }
 
-        // notify cell about right click
         wxVariant value;
         model->GetValue( value, item, col->GetModelColumn() );
         wxVariant value;
         model->GetValue( value, item, col->GetModelColumn() );
-        cell->SetValue( value );
-        wxRect cell_rect( xpos, current * m_lineHeight,
-                          col->GetWidth(), m_lineHeight );
-        if (!cell->RightClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn()))
-        {
-            wxWindow *parent = GetParent();
-            wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, parent->GetId());
-            le.SetItem( item );
-            le.SetEventObject(parent);
-            le.SetModel(GetOwner()->GetModel());
-            le.SetValue(value);
-
-            parent->GetEventHandler()->ProcessEvent(le);
-        }
+        wxWindow *parent = GetParent();
+        wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, parent->GetId());
+        le.SetItem( item );
+        le.SetEventObject(parent);
+        le.SetModel(GetOwner()->GetModel());
+        le.SetValue(value);
+        parent->GetEventHandler()->ProcessEvent(le);
     }
     else if (event.MiddleDown())
     {
     }
     else if (event.MiddleDown())
     {
-        // notify cell about middle click
-        // cell->...
     }
     if (event.LeftDown() || forceClick)
     {
     }
     if (event.LeftDown() || forceClick)
     {
@@ -3783,7 +3812,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
                 wxFAIL_MSG( _T("how did we get here?") );
             }
         }
                 wxFAIL_MSG( _T("how did we get here?") );
             }
         }
-
+        
         if (m_currentRow != oldCurrentRow)
             RefreshRow( oldCurrentRow );
 
         if (m_currentRow != oldCurrentRow)
             RefreshRow( oldCurrentRow );
 
@@ -3794,6 +3823,18 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
 
         m_lastOnSame = !forceClick && ((col == oldCurrentCol) &&
                         (current == oldCurrentRow)) && oldWasSelected;
 
         m_lastOnSame = !forceClick && ((col == oldCurrentCol) &&
                         (current == oldCurrentRow)) && oldWasSelected;
+
+        // Call LeftClick after everything else as under GTK+
+        if (cell->GetMode() & wxDATAVIEW_CELL_ACTIVATABLE)
+        {
+            // notify cell about right click
+            wxVariant value;
+            model->GetValue( value, item, col->GetModelColumn() );
+            cell->SetValue( value );
+            wxRect cell_rect( xpos, current * m_lineHeight,
+                          col->GetWidth(), m_lineHeight );
+            /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn());
+        }
     }
 }
 
     }
 }
 
@@ -3840,6 +3881,12 @@ wxDataViewCtrl::~wxDataViewCtrl()
 {
     if (m_notifier)
         GetModel()->RemoveNotifier( m_notifier );
 {
     if (m_notifier)
         GetModel()->RemoveNotifier( m_notifier );
+
+    wxDataViewColumnList::const_iterator iter;
+    for (iter = m_cols.begin(); iter!=m_cols.end(); iter++)
+    {
+        delete *iter;
+    }
 }
 
 void wxDataViewCtrl::Init()
 }
 
 void wxDataViewCtrl::Init()
@@ -3851,8 +3898,11 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
            const wxPoint& pos, const wxSize& size,
            long style, const wxValidator& validator )
 {
            const wxPoint& pos, const wxSize& size,
            long style, const wxValidator& validator )
 {
+    if ( (style & wxBORDER_MASK) == 0)
+        style |= wxBORDER_SUNKEN;
+    
     if (!wxControl::Create( parent, id, pos, size,
     if (!wxControl::Create( parent, id, pos, size,
-                            style | wxScrolledWindowStyle|wxBORDER_SUNKEN, validator))
+                            style | wxScrolledWindowStyle, validator))
         return false;
 
     SetInitialSize(size);
         return false;
 
     SetInitialSize(size);