1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/dataview.cpp 
   3 // Purpose:     wxDataViewCtrl GTK+2 implementation 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  13 #if wxUSE_DATAVIEWCTRL 
  15 #include "wx/dataview.h" 
  17 #ifndef wxUSE_GENERICDATAVIEWCTRL 
  21     #include "wx/dcclient.h" 
  25 #include "wx/stockitem.h" 
  26 #include "wx/calctrl.h" 
  27 #include "wx/popupwin.h" 
  31 #include "wx/gtk/private.h" 
  32 #include "wx/gtk/win_gtk.h" 
  34 #include <gobject/gvaluecollector.h> 
  35 #include <gtk/gtktreemodel.h> 
  36 #include <gtk/gtktreednd.h> 
  38 #include <gdk/gdkkeysyms.h> 
  40 //----------------------------------------------------------------------------- 
  42 //----------------------------------------------------------------------------- 
  46 //----------------------------------------------------------------------------- 
  48 //----------------------------------------------------------------------------- 
  50 extern bool   g_blockEventsOnDrag
; 
  52 //----------------------------------------------------------------------------- 
  53 // define new GTK+ class wxGtkListStore 
  54 //----------------------------------------------------------------------------- 
  58 #define GTK_TYPE_WX_LIST_STORE               (gtk_wx_list_store_get_type ()) 
  59 #define GTK_WX_LIST_STORE(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStore)) 
  60 #define GTK_WX_LIST_STORE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass)) 
  61 #define GTK_IS_WX_LIST_STORE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_LIST_STORE)) 
  62 #define GTK_IS_WX_LIST_STORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_LIST_STORE)) 
  63 #define GTK_WX_LIST_STORE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass)) 
  65 GType         
gtk_wx_list_store_get_type         (void); 
  67 typedef struct _GtkWxListStore       GtkWxListStore
; 
  68 typedef struct _GtkWxListStoreClass  GtkWxListStoreClass
; 
  70 struct _GtkWxListStore
 
  76   wxDataViewListModel 
*model
; 
  79 struct _GtkWxListStoreClass
 
  81   GObjectClass list_parent_class
; 
  84 static GtkWxListStore 
*wxgtk_list_store_new          (void); 
  85 static void         wxgtk_list_store_init            (GtkWxListStore      
*list_store
); 
  86 static void         wxgtk_list_store_class_init      (GtkWxListStoreClass 
*klass
); 
  87 static void         wxgtk_list_store_tree_model_init (GtkTreeModelIface 
*iface
); 
  88 static void         wxgtk_list_store_finalize        (GObject           
*object
); 
  89 static GtkTreeModelFlags 
wxgtk_list_store_get_flags  (GtkTreeModel      
*tree_model
); 
  90 static gint         
wxgtk_list_store_get_n_columns   (GtkTreeModel      
*tree_model
); 
  91 static GType        
wxgtk_list_store_get_column_type (GtkTreeModel      
*tree_model
, 
  93 static gboolean     
wxgtk_list_store_get_iter        (GtkTreeModel      
*tree_model
, 
  96 static GtkTreePath 
*wxgtk_list_store_get_path        (GtkTreeModel      
*tree_model
, 
  98 static void         wxgtk_list_store_get_value       (GtkTreeModel      
*tree_model
, 
 102 static gboolean     
wxgtk_list_store_iter_next       (GtkTreeModel      
*tree_model
, 
 104 static gboolean     
wxgtk_list_store_iter_children   (GtkTreeModel      
*tree_model
, 
 106                                                       GtkTreeIter       
*parent
); 
 107 static gboolean     
wxgtk_list_store_iter_has_child  (GtkTreeModel      
*tree_model
, 
 109 static gint         
wxgtk_list_store_iter_n_children (GtkTreeModel      
*tree_model
, 
 111 static gboolean     
wxgtk_list_store_iter_nth_child  (GtkTreeModel      
*tree_model
, 
 115 static gboolean     
wxgtk_list_store_iter_parent     (GtkTreeModel      
*tree_model
, 
 119 static GObjectClass 
*list_parent_class 
= NULL
; 
 122 gtk_wx_list_store_get_type (void) 
 124     static GType list_store_type 
= 0; 
 126     if (!list_store_type
) 
 128         const GTypeInfo list_store_info 
= 
 130             sizeof (GtkWxListStoreClass
), 
 131             NULL
,   /* base_init */ 
 132             NULL
,   /* base_finalize */ 
 133             (GClassInitFunc
) wxgtk_list_store_class_init
, 
 134             NULL
,   /* class_finalize */ 
 135             NULL
,   /* class_data */ 
 136             sizeof (GtkWxListStore
), 
 138             (GInstanceInitFunc
) wxgtk_list_store_init
, 
 141       static const GInterfaceInfo tree_model_info 
= 
 143           (GInterfaceInitFunc
) wxgtk_list_store_tree_model_init
, 
 148       list_store_type 
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxListStore", 
 149                                                 &list_store_info
, (GTypeFlags
)0 ); 
 151       g_type_add_interface_static (list_store_type
, 
 156   return list_store_type
; 
 159 static GtkWxListStore 
* 
 160 wxgtk_list_store_new(void) 
 162     GtkWxListStore 
*retval 
= (GtkWxListStore 
*) g_object_new (GTK_TYPE_WX_LIST_STORE
, NULL
); 
 167 wxgtk_list_store_class_init (GtkWxListStoreClass 
*klass
) 
 169     list_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 170     GObjectClass 
*object_class 
= (GObjectClass
*) klass
; 
 171     object_class
->finalize 
= wxgtk_list_store_finalize
; 
 175 wxgtk_list_store_tree_model_init (GtkTreeModelIface 
*iface
) 
 177     iface
->get_flags 
= wxgtk_list_store_get_flags
; 
 178     iface
->get_n_columns 
= wxgtk_list_store_get_n_columns
; 
 179     iface
->get_column_type 
= wxgtk_list_store_get_column_type
; 
 180     iface
->get_iter 
= wxgtk_list_store_get_iter
; 
 181     iface
->get_path 
= wxgtk_list_store_get_path
; 
 182     iface
->get_value 
= wxgtk_list_store_get_value
; 
 183     iface
->iter_next 
= wxgtk_list_store_iter_next
; 
 184     iface
->iter_children 
= wxgtk_list_store_iter_children
; 
 185     iface
->iter_has_child 
= wxgtk_list_store_iter_has_child
; 
 186     iface
->iter_n_children 
= wxgtk_list_store_iter_n_children
; 
 187     iface
->iter_nth_child 
= wxgtk_list_store_iter_nth_child
; 
 188     iface
->iter_parent 
= wxgtk_list_store_iter_parent
; 
 192 wxgtk_list_store_init (GtkWxListStore 
*list_store
) 
 194     list_store
->model 
= NULL
; 
 195     list_store
->stamp 
= g_random_int(); 
 199 wxgtk_list_store_finalize (GObject 
*object
) 
 201     /* GtkWxListStore *list_store = GTK_WX_LIST_STORE (object); */ 
 203     /* we need to sort out, which class deletes what */ 
 204     /* delete list_store->model; */ 
 207     (* list_parent_class
->finalize
) (object
); 
 212 //----------------------------------------------------------------------------- 
 213 // implement callbacks from wxGtkListStore class by letting 
 214 // them call the methods of wxWidgets' wxDataViewListModel 
 215 //----------------------------------------------------------------------------- 
 217 static GtkTreeModelFlags
 
 218 wxgtk_list_store_get_flags (GtkTreeModel 
*tree_model
) 
 220     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), (GtkTreeModelFlags
)0 ); 
 222     // GTK+ list store uses a linked list for storing the 
 223     // items and a pointer to a child is used as the member 
 224     // field of a GtkTreeIter. This means that the iter is 
 225     // valid in the GtkListStore as long as the child exists. 
 226     // We use the index of the row and since the index of a 
 227     // specific row will change if a row above is deleted, 
 228     // the iter does not persist 
 229     return /* GTK_TREE_MODEL_ITERS_PERSIST | */ GTK_TREE_MODEL_LIST_ONLY
; 
 233 wxgtk_list_store_get_n_columns (GtkTreeModel 
*tree_model
) 
 235     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 236     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), 0); 
 238     return list_store
->model
->GetColumnCount(); 
 242 wxgtk_list_store_get_column_type (GtkTreeModel 
*tree_model
, 
 245     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 246     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), G_TYPE_INVALID
); 
 248     GType gtype 
= G_TYPE_INVALID
; 
 250     wxString wxtype 
= list_store
->model
->GetColumnType( (unsigned int) index 
); 
 252     if (wxtype 
== wxT("string")) 
 253         gtype 
= G_TYPE_STRING
; 
 256         wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 263 wxgtk_list_store_get_iter (GtkTreeModel 
*tree_model
, 
 267     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 268     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 269     g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
); 
 271     unsigned int i 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
 273     if (i 
>= list_store
->model
->GetRowCount()) 
 276     iter
->stamp 
= list_store
->stamp
; 
 277     // user_data is just the index 
 278     iter
->user_data 
= (gpointer
) i
; 
 284 wxgtk_list_store_get_path (GtkTreeModel 
*tree_model
, 
 287     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), NULL
); 
 288     g_return_val_if_fail (iter
->stamp 
== GTK_WX_LIST_STORE (tree_model
)->stamp
, NULL
); 
 290     GtkTreePath 
*retval 
= gtk_tree_path_new (); 
 291     // user_data is just the index 
 292     int i 
= (wxUIntPtr
) iter
->user_data
; 
 293     gtk_tree_path_append_index (retval
, i
); 
 298 wxgtk_list_store_get_value (GtkTreeModel 
*tree_model
, 
 303     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 304     g_return_if_fail (GTK_IS_WX_LIST_STORE (tree_model
) ); 
 306     wxDataViewListModel 
*model 
= list_store
->model
; 
 307     wxString mtype 
= model
->GetColumnType( (unsigned int) column 
); 
 308     if (mtype 
== wxT("string")) 
 311         g_value_init( value
, G_TYPE_STRING 
); 
 312         model
->GetValue( variant
, 
 313                          (unsigned int) column
, 
 314                          (unsigned int) iter
->user_data 
); 
 316         // FIXME: we should support different encodings here 
 317         g_value_set_string( value
, wxGTK_CONV_SYS(variant
.GetString()) ); 
 321         wxFAIL_MSG( _T("non-string columns not supported yet") ); 
 326 wxgtk_list_store_iter_next (GtkTreeModel  
*tree_model
, 
 329     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 330     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 332     g_return_val_if_fail (list_store
->stamp 
== iter
->stamp
, FALSE
); 
 334     int n 
= (wxUIntPtr
) iter
->user_data
; 
 339     if (n 
>= (int) list_store
->model
->GetRowCount()-1) 
 342     iter
->user_data 
= (gpointer
) ++n
; 
 348 wxgtk_list_store_iter_children (GtkTreeModel 
*tree_model
, 
 352     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 353     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 355     // this is a list, nodes have no children 
 359     iter
->stamp 
= list_store
->stamp
; 
 360     iter
->user_data 
= (gpointer
) -1; 
 366 wxgtk_list_store_iter_has_child (GtkTreeModel 
*tree_model
, 
 373 wxgtk_list_store_iter_n_children (GtkTreeModel 
*tree_model
, 
 376     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), -1); 
 377     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 380         return (gint
) list_store
->model
->GetRowCount(); 
 382     g_return_val_if_fail (list_store
->stamp 
== iter
->stamp
, -1); 
 388 wxgtk_list_store_iter_nth_child (GtkTreeModel 
*tree_model
, 
 393     g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
); 
 394     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) tree_model
; 
 402     if (n 
>= (gint
) list_store
->model
->GetRowCount()) 
 405     iter
->stamp 
= list_store
->stamp
; 
 406     iter
->user_data 
= (gpointer
) n
; 
 412 wxgtk_list_store_iter_parent (GtkTreeModel 
*tree_model
, 
 419 //----------------------------------------------------------------------------- 
 420 // define new GTK+ class wxGtkRendererRenderer 
 421 //----------------------------------------------------------------------------- 
 425 #define GTK_TYPE_WX_CELL_RENDERER               (gtk_wx_cell_renderer_get_type ()) 
 426 #define GTK_WX_CELL_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) 
 427 #define GTK_WX_CELL_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 428 #define GTK_IS_WX_CELL_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) 
 429 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) 
 430 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) 
 432 GType            
gtk_wx_cell_renderer_get_type (void); 
 434 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
; 
 435 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
; 
 437 struct _GtkWxCellRenderer
 
 439   GtkCellRenderer parent
; 
 442   wxDataViewCustomRenderer 
*cell
; 
 446 struct _GtkWxCellRendererClass
 
 448   GtkCellRendererClass cell_parent_class
; 
 452 static GtkCellRenderer 
*gtk_wx_cell_renderer_new   (void); 
 453 static void gtk_wx_cell_renderer_init ( 
 454                         GtkWxCellRenderer      
*cell 
); 
 455 static void gtk_wx_cell_renderer_class_init( 
 456                         GtkWxCellRendererClass 
*klass 
); 
 457 static void gtk_wx_cell_renderer_finalize ( 
 459 static void gtk_wx_cell_renderer_get_size ( 
 460                         GtkCellRenderer         
*cell
, 
 462                         GdkRectangle            
*rectangle
, 
 467 static void gtk_wx_cell_renderer_render ( 
 468                         GtkCellRenderer         
*cell
, 
 471                         GdkRectangle            
*background_area
, 
 472                         GdkRectangle            
*cell_area
, 
 473                         GdkRectangle            
*expose_area
, 
 474                         GtkCellRendererState     flags 
); 
 475 static gboolean 
gtk_wx_cell_renderer_activate( 
 476                         GtkCellRenderer         
*cell
, 
 480                         GdkRectangle            
*background_area
, 
 481                         GdkRectangle            
*cell_area
, 
 482                         GtkCellRendererState     flags 
); 
 483 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 484                         GtkCellRenderer         
*cell
, 
 488                         GdkRectangle            
*background_area
, 
 489                         GdkRectangle            
*cell_area
, 
 490                         GtkCellRendererState     flags 
); 
 493 static GObjectClass 
*cell_parent_class 
= NULL
; 
 498 gtk_wx_cell_renderer_get_type (void) 
 500     static GType cell_wx_type 
= 0; 
 504         const GTypeInfo cell_wx_info 
= 
 506             sizeof (GtkWxCellRendererClass
), 
 507             NULL
, /* base_init */ 
 508             NULL
, /* base_finalize */ 
 509             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
 510             NULL
, /* class_finalize */ 
 511             NULL
, /* class_data */ 
 512             sizeof (GtkWxCellRenderer
), 
 514             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
 517         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
 518             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
 525 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
 528     cell
->last_click 
= 0; 
 532 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
 534     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
 535     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
 537     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 539     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
 541     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
 542     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
 543     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
 544     cell_class
->start_editing 
= gtk_wx_cell_renderer_start_editing
; 
 548 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
 551     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
 555 gtk_wx_cell_renderer_new (void) 
 557     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
 562 static GtkCellEditable 
*gtk_wx_cell_renderer_start_editing( 
 563                         GtkCellRenderer         
*renderer
, 
 567                         GdkRectangle            
*background_area
, 
 568                         GdkRectangle            
*cell_area
, 
 569                         GtkCellRendererState     flags 
) 
 571     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 572     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 573     if (!cell
->HasEditorCtrl()) 
 577     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 583     rect
.x 
+= cell_area
->x
; 
 584     rect
.y 
+= cell_area
->y
; 
 585 //    rect.width  -= renderer->xpad * 2; 
 586 //    rect.height -= renderer->ypad * 2; 
 588 //    wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); 
 589     wxRect 
renderrect( cell_area
->x
, cell_area
->y
, cell_area
->width
, cell_area
->height 
); 
 591     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 593     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 594     unsigned int model_row 
= (unsigned int)gtk_tree_path_get_indices (treepath
)[0]; 
 595     gtk_tree_path_free( treepath 
); 
 597     cell
->StartEditing( model_row
, renderrect 
); 
 603 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
 605                                GdkRectangle    
*cell_area
, 
 611     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 612     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 614     wxSize size 
= cell
->GetSize(); 
 616     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
 617     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
 624     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
 628             *x_offset 
= (gint
)((renderer
->xalign 
* 
 629                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
 630             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
 634             *y_offset 
= (gint
)((renderer
->yalign 
* 
 635                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
 636             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
 644         *height 
= calc_height
; 
 648 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
 651                              GdkRectangle         
*background_area
, 
 652                              GdkRectangle         
*cell_area
, 
 653                              GdkRectangle         
*expose_area
, 
 654                              GtkCellRendererState  flags
) 
 657     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 658     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 661     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 667     rect
.x 
+= cell_area
->x
; 
 668     rect
.y 
+= cell_area
->y
; 
 669     rect
.width  
-= renderer
->xpad 
* 2; 
 670     rect
.height 
-= renderer
->ypad 
* 2; 
 673     if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
)) 
 675         wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 676         wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
 677         if (dc
->m_window 
== NULL
) 
 679             dc
->m_window 
= window
; 
 684         if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
 685             state 
|= wxDATAVIEW_CELL_SELECTED
; 
 686         if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
 687             state 
|= wxDATAVIEW_CELL_PRELIT
; 
 688         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 689             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 690         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 691             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 692         if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
 693             state 
|= wxDATAVIEW_CELL_FOCUSED
; 
 694         cell
->Render( renderrect
, dc
, state 
); 
 699 gtk_wx_cell_renderer_activate( 
 700                         GtkCellRenderer         
*renderer
, 
 704                         GdkRectangle            
*background_area
, 
 705                         GdkRectangle            
*cell_area
, 
 706                         GtkCellRendererState     flags 
) 
 708     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 709     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 712     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 718     rect
.x 
+= cell_area
->x
; 
 719     rect
.y 
+= cell_area
->y
; 
 720     rect
.width  
-= renderer
->xpad 
* 2; 
 721     rect
.height 
-= renderer
->ypad 
* 2; 
 723     wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 725     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 727     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 728     unsigned int model_row 
= (unsigned int)gtk_tree_path_get_indices (treepath
)[0]; 
 729     gtk_tree_path_free( treepath 
); 
 731     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
 737         // activated by <ENTER> 
 738         if (cell
->Activate( renderrect
, model
, model_col
, model_row 
)) 
 743     else if (event
->type 
== GDK_BUTTON_PRESS
) 
 745         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
 746         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
 747                     ((int) button_event
->y
) - renderrect
.y 
); 
 750         if (button_event
->button 
== 1) 
 752             if (cell
->LeftClick( pt
, renderrect
, model
, model_col
, model_row 
)) 
 754             // TODO: query system double-click time 
 755             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
 756                 if (cell
->Activate( renderrect
, model
, model_col
, model_row 
)) 
 759         if (button_event
->button 
== 3) 
 761             if (cell
->RightClick( pt
, renderrect
, model
, model_col
, model_row 
)) 
 765         wxrenderer
->last_click 
= button_event
->time
; 
 773 // --------------------------------------------------------- 
 774 // wxGtkDataViewListModelNotifier 
 775 // --------------------------------------------------------- 
 777 class wxGtkDataViewListModelNotifier
: public wxDataViewListModelNotifier
 
 780     wxGtkDataViewListModelNotifier( GtkWxListStore
* gtk_store
, wxDataViewListModel 
*wx_model 
); 
 782     virtual bool RowAppended(); 
 783     virtual bool RowPrepended(); 
 784     virtual bool RowInserted( unsigned int before 
); 
 785     virtual bool RowDeleted( unsigned int row 
); 
 786     virtual bool RowChanged( unsigned int row 
); 
 787     virtual bool ValueChanged( unsigned int col
, unsigned int row 
); 
 788     virtual bool RowsReordered( unsigned int *new_order 
); 
 789     virtual bool Cleared(); 
 795         return wxDataViewListModelNotifier::Freed(); 
 798     GtkWxListStore      
*m_gtk_store
; 
 799     wxDataViewListModel 
*m_wx_model
; 
 802 // --------------------------------------------------------- 
 803 // wxGtkDataViewListModelNotifier 
 804 // --------------------------------------------------------- 
 806 wxGtkDataViewListModelNotifier::wxGtkDataViewListModelNotifier( 
 807     GtkWxListStore
* gtk_store
, wxDataViewListModel 
*wx_model 
) 
 809     m_gtk_store 
= gtk_store
; 
 810     m_wx_model 
= wx_model
; 
 813 bool wxGtkDataViewListModelNotifier::RowAppended() 
 815     unsigned int pos 
= m_wx_model
->GetRowCount()-1; 
 818     iter
.stamp 
= m_gtk_store
->stamp
; 
 819     iter
.user_data 
= (gpointer
) pos
; 
 821     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 822     gtk_tree_path_append_index (path
, (gint
) pos
); 
 823     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 824     gtk_tree_path_free (path
); 
 829 bool wxGtkDataViewListModelNotifier::RowPrepended() 
 832     iter
.stamp 
= m_gtk_store
->stamp
; 
 833     iter
.user_data 
= (gpointer
) 0; 
 835     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 836     gtk_tree_path_append_index (path
, (gint
) 0); 
 837     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 838     gtk_tree_path_free (path
); 
 843 bool wxGtkDataViewListModelNotifier::RowInserted( unsigned int before 
) 
 846     iter
.stamp 
= m_gtk_store
->stamp
; 
 847     iter
.user_data 
= (gpointer
) before
; 
 849     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 850     gtk_tree_path_append_index (path
, (gint
) before
); 
 851     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 852     gtk_tree_path_free (path
); 
 857 bool wxGtkDataViewListModelNotifier::RowDeleted( unsigned int row 
) 
 859     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 860     gtk_tree_path_append_index (path
, (gint
) row
); 
 861     gtk_tree_model_row_deleted (GTK_TREE_MODEL (m_gtk_store
), path
); 
 862     gtk_tree_path_free (path
); 
 867 bool wxGtkDataViewListModelNotifier::RowChanged( unsigned int row 
) 
 870     iter
.stamp 
= m_gtk_store
->stamp
; 
 871     iter
.user_data 
= (gpointer
) row
; 
 872     GtkTreePath 
*path 
= gtk_tree_model_get_path (GTK_TREE_MODEL (m_gtk_store
), &iter
); 
 873     gtk_tree_model_row_changed (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 874     gtk_tree_path_free (path
); 
 879 bool wxGtkDataViewListModelNotifier::ValueChanged( unsigned int model_col
, unsigned int model_row 
) 
 881     // This adds GTK+'s missing MVC logic for ValueChanged 
 882     wxObjectList::compatibility_iterator
 
 883         node 
= GetOwner()->m_viewingColumns
.GetFirst(); 
 886         wxDataViewViewingColumn
* viewing_column 
= (wxDataViewViewingColumn
*) node
->GetData(); 
 887         if (viewing_column
->m_modelColumn 
== model_col
) 
 889             GtkTreeView 
*widget 
= GTK_TREE_VIEW(viewing_column
->m_viewColumn
->GetOwner()->m_treeview
); 
 890             GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(viewing_column
->m_viewColumn
->GetGtkHandle()); 
 893             GtkTreePath 
*path 
= gtk_tree_path_new(); 
 894             gtk_tree_path_append_index( path
, model_row 
); 
 895             GdkRectangle cell_area
; 
 896             gtk_tree_view_get_cell_area( widget
, path
, column
, &cell_area 
); 
 897             gtk_tree_path_free( path 
); 
 899             GtkAdjustment
* hadjust 
= gtk_tree_view_get_hadjustment( widget 
); 
 900             double d 
= gtk_adjustment_get_value( hadjust 
); 
 903             int ydiff 
= column
->button
->allocation
.height
; 
 905             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
 906                 cell_area
.x 
- xdiff
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
 909         node 
= node
->GetNext(); 
 915 bool wxGtkDataViewListModelNotifier::RowsReordered( unsigned int *new_order 
) 
 917     // Assume sizeof(unsigned int)= == sizeof(gint) 
 919     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 920     gtk_tree_model_rows_reordered (GTK_TREE_MODEL (m_gtk_store
), path
, NULL
, (gint
*)new_order
); 
 921     gtk_tree_path_free (path
); 
 923     // This adds GTK+'s missing MVC logic for RowsReordered 
 924     wxObjectList::compatibility_iterator
 
 925         node 
= GetOwner()->m_viewingColumns
.GetFirst(); 
 928         wxDataViewViewingColumn
* viewing_column 
= (wxDataViewViewingColumn
*) node
->GetData(); 
 929         GtkTreeView 
*widget 
= GTK_TREE_VIEW(viewing_column
->m_viewColumn
->GetOwner()->m_treeview
); 
 930         // Doesn't work yet... 
 931         gtk_widget_queue_draw( GTK_WIDGET(widget
) ); 
 933         node 
= node
->GetNext(); 
 939 bool wxGtkDataViewListModelNotifier::Cleared() 
 944 // --------------------------------------------------------- 
 945 // wxDataViewRenderer 
 946 // --------------------------------------------------------- 
 948 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
) 
 950 wxDataViewRenderer::wxDataViewRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
 952     wxDataViewRendererBase( varianttype
, mode
, align 
) 
 956     // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor, 
 957     //       after the m_renderer pointer has been initialized 
 960 void wxDataViewRenderer::SetMode( wxDataViewCellMode mode 
) 
 962     GtkCellRendererMode gtkMode
; 
 965     case wxDATAVIEW_CELL_INERT
: 
 966         gtkMode 
= GTK_CELL_RENDERER_MODE_INERT
; 
 968     case wxDATAVIEW_CELL_ACTIVATABLE
: 
 969         gtkMode 
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
; 
 971     case wxDATAVIEW_CELL_EDITABLE
: 
 972         gtkMode 
= GTK_CELL_RENDERER_MODE_EDITABLE
; 
 976     GValue gvalue 
= { 0, }; 
 977     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
 978     g_value_set_enum( &gvalue
, gtkMode 
); 
 979     g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
 980     g_value_unset( &gvalue 
); 
 983 wxDataViewCellMode 
wxDataViewRenderer::GetMode() const 
 985     wxDataViewCellMode ret
; 
 988     g_object_get( G_OBJECT(m_renderer
), "mode", &gvalue
, NULL
); 
 990     switch (g_value_get_enum(&gvalue
)) 
 992     case GTK_CELL_RENDERER_MODE_INERT
: 
 993         ret 
= wxDATAVIEW_CELL_INERT
; 
 995     case GTK_CELL_RENDERER_MODE_ACTIVATABLE
: 
 996         ret 
= wxDATAVIEW_CELL_ACTIVATABLE
; 
 998     case GTK_CELL_RENDERER_MODE_EDITABLE
: 
 999         ret 
= wxDATAVIEW_CELL_EDITABLE
; 
1003     g_value_unset( &gvalue 
); 
1008 void wxDataViewRenderer::SetAlignment( int align 
) 
1010     // horizontal alignment: 
1012     gfloat xalign 
= 0.0; 
1013     if (align 
& wxALIGN_RIGHT
) 
1015     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1018     GValue gvalue 
= { 0, }; 
1019     g_value_init( &gvalue
, G_TYPE_FLOAT 
); 
1020     g_value_set_float( &gvalue
, xalign 
); 
1021     g_object_set_property( G_OBJECT(m_renderer
), "xalign", &gvalue 
); 
1022     g_value_unset( &gvalue 
); 
1024     // vertical alignment: 
1026     gfloat yalign 
= 0.0; 
1027     if (align 
& wxALIGN_BOTTOM
) 
1029     else if (align 
& wxALIGN_CENTER_VERTICAL
) 
1032     GValue gvalue2 
= { 0, }; 
1033     g_value_init( &gvalue2
, G_TYPE_FLOAT 
); 
1034     g_value_set_float( &gvalue2
, yalign 
); 
1035     g_object_set_property( G_OBJECT(m_renderer
), "yalign", &gvalue2 
); 
1036     g_value_unset( &gvalue2 
); 
1039 int wxDataViewRenderer::GetAlignment() const 
1044     // horizontal alignment: 
1046     g_object_get( G_OBJECT(m_renderer
), "xalign", &gvalue
, NULL 
); 
1047     float xalign 
= g_value_get_float( &gvalue 
); 
1049         ret 
|= wxALIGN_LEFT
; 
1050     else if (xalign 
== 0.5) 
1051         ret 
|= wxALIGN_CENTER_HORIZONTAL
; 
1053         ret 
|= wxALIGN_RIGHT
; 
1054     g_value_unset( &gvalue 
); 
1057     // vertical alignment: 
1059     g_object_get( G_OBJECT(m_renderer
), "yalign", &gvalue
, NULL 
); 
1060     float yalign 
= g_value_get_float( &gvalue 
); 
1063     else if (yalign 
== 0.5) 
1064         ret 
|= wxALIGN_CENTER_VERTICAL
; 
1066         ret 
|= wxALIGN_BOTTOM
; 
1067     g_value_unset( &gvalue 
); 
1074 // --------------------------------------------------------- 
1075 // wxDataViewTextRenderer 
1076 // --------------------------------------------------------- 
1079 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1080     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
); 
1083 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
1084     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
1086     wxDataViewTextRenderer 
*cell 
= (wxDataViewTextRenderer
*) user_data
; 
1088     wxString tmp 
= wxGTK_CONV_BACK_FONT(arg2
, cell
->GetOwner()->GetOwner()->GetFont()); 
1089     wxVariant value 
= tmp
; 
1090     if (!cell
->Validate( value 
)) 
1093     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1095     GtkTreePath 
*path 
= gtk_tree_path_new_from_string( arg1 
); 
1096     unsigned int model_row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
1097     gtk_tree_path_free( path 
); 
1099     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1101     model
->SetValue( value
, model_col
, model_row 
); 
1102     model
->ValueChanged( model_col
, model_row 
); 
1105 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
) 
1107 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1109     wxDataViewRenderer( varianttype
, mode
, align 
) 
1111     m_renderer 
= (GtkWidget
*) gtk_cell_renderer_text_new(); 
1113     if (mode 
& wxDATAVIEW_CELL_EDITABLE
) 
1115         GValue gvalue 
= { 0, }; 
1116         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1117         g_value_set_boolean( &gvalue
, true ); 
1118         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
1119         g_value_unset( &gvalue 
); 
1121         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
1125     SetAlignment(align
); 
1128 bool wxDataViewTextRenderer::SetValue( const wxVariant 
&value 
) 
1130     wxString tmp 
= value
; 
1132     GValue gvalue 
= { 0, }; 
1133     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1134     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( tmp
, GetOwner()->GetOwner()->GetFont() ) ); 
1135     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1136     g_value_unset( &gvalue 
); 
1141 bool wxDataViewTextRenderer::GetValue( wxVariant 
&value 
) const 
1143     GValue gvalue 
= { 0, }; 
1144     g_value_init( &gvalue
, G_TYPE_STRING 
); 
1145     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1146     wxString tmp 
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue 
), 
1147         wx_const_cast(wxDataViewTextRenderer
*, this)->GetOwner()->GetOwner()->GetFont() ); 
1148     g_value_unset( &gvalue 
); 
1155 void wxDataViewTextRenderer::SetAlignment( int align 
) 
1157     wxDataViewRenderer::SetAlignment(align
); 
1159     if (gtk_check_version(2,10,0)) 
1162     // horizontal alignment: 
1163     PangoAlignment pangoAlign 
= PANGO_ALIGN_LEFT
; 
1164     if (align 
& wxALIGN_RIGHT
) 
1165         pangoAlign 
= PANGO_ALIGN_RIGHT
; 
1166     else if (align 
& wxALIGN_CENTER_HORIZONTAL
) 
1167         pangoAlign 
= PANGO_ALIGN_CENTER
; 
1169     GValue gvalue 
= { 0, }; 
1170     g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1171     g_value_set_enum( &gvalue
, pangoAlign 
); 
1172     g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue 
); 
1173     g_value_unset( &gvalue 
); 
1176 // --------------------------------------------------------- 
1177 // wxDataViewBitmapRenderer 
1178 // --------------------------------------------------------- 
1180 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
) 
1182 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode
, 
1184     wxDataViewRenderer( varianttype
, mode
, align 
) 
1186     m_renderer 
= (GtkWidget
*) gtk_cell_renderer_pixbuf_new(); 
1189     SetAlignment(align
); 
1192 bool wxDataViewBitmapRenderer::SetValue( const wxVariant 
&value 
) 
1194     if (value
.GetType() == wxT("wxBitmap")) 
1199         // This may create a Pixbuf representation in the 
1200         // wxBitmap object (and it will stay there) 
1201         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1203         GValue gvalue 
= { 0, }; 
1204         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1205         g_value_set_object( &gvalue
, pixbuf 
); 
1206         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1207         g_value_unset( &gvalue 
); 
1212     if (value
.GetType() == wxT("wxIcon")) 
1217         // This may create a Pixbuf representation in the 
1218         // wxBitmap object (and it will stay there) 
1219         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1221         GValue gvalue 
= { 0, }; 
1222         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1223         g_value_set_object( &gvalue
, pixbuf 
); 
1224         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1225         g_value_unset( &gvalue 
); 
1233 bool wxDataViewBitmapRenderer::GetValue( wxVariant 
&value 
) const 
1238 // --------------------------------------------------------- 
1239 // wxDataViewToggleRenderer 
1240 // --------------------------------------------------------- 
1243 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1244     gchar 
*path
, gpointer user_data 
); 
1247 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1248     gchar 
*path
, gpointer user_data 
) 
1250     wxDataViewToggleRenderer 
*cell 
= (wxDataViewToggleRenderer
*) user_data
; 
1253     GValue gvalue 
= { 0, }; 
1254     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1255     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
1256     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1257     g_value_unset( &gvalue 
); 
1261     wxVariant value 
= tmp
; 
1262     if (!cell
->Validate( value 
)) 
1265     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1267     GtkTreePath 
*gtk_path 
= gtk_tree_path_new_from_string( path 
); 
1268     unsigned int model_row 
= (unsigned int)gtk_tree_path_get_indices (gtk_path
)[0]; 
1269     gtk_tree_path_free( gtk_path 
); 
1271     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1273     model
->SetValue( value
, model_col
, model_row 
); 
1274     model
->ValueChanged( model_col
, model_row 
); 
1277 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
) 
1279 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString 
&varianttype
, 
1280                                                     wxDataViewCellMode mode
, int align 
) : 
1281     wxDataViewRenderer( varianttype
, mode
, align 
) 
1283     m_renderer 
= (GtkWidget
*) gtk_cell_renderer_toggle_new(); 
1285     if (mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1287         g_signal_connect_after( m_renderer
, "toggled", 
1288                                 G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
1292         GValue gvalue 
= { 0, }; 
1293         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1294         g_value_set_boolean( &gvalue
, false ); 
1295         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
1296         g_value_unset( &gvalue 
); 
1300     SetAlignment(align
); 
1303 bool wxDataViewToggleRenderer::SetValue( const wxVariant 
&value 
) 
1307     GValue gvalue 
= { 0, }; 
1308     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1309     g_value_set_boolean( &gvalue
, tmp 
); 
1310     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1311     g_value_unset( &gvalue 
); 
1316 bool wxDataViewToggleRenderer::GetValue( wxVariant 
&value 
) const 
1318     GValue gvalue 
= { 0, }; 
1319     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1320     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1321     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1322     g_value_unset( &gvalue 
); 
1329 // --------------------------------------------------------- 
1330 // wxDataViewCustomRenderer 
1331 // --------------------------------------------------------- 
1333 class wxDataViewCtrlDC
: public wxWindowDC
 
1336     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) 
1338         GtkWidget 
*widget 
= window
->m_treeview
; 
1342         m_context 
= window
->GtkGetPangoDefaultContext(); 
1343         m_layout 
= pango_layout_new( m_context 
); 
1344         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
1346         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
1348         // Set m_window later 
1350         // m_owner = window; 
1354 // --------------------------------------------------------- 
1355 // wxDataViewCustomRenderer 
1356 // --------------------------------------------------------- 
1358 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
) 
1360 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString 
&varianttype
, 
1361                                                     wxDataViewCellMode mode
, int align
, 
1363     wxDataViewRenderer( varianttype
, mode
, align 
) 
1373 bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode
, int align
) 
1375     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
1376     renderer
->cell 
= this; 
1378     m_renderer 
= (GtkWidget
*) renderer
; 
1381     SetAlignment(align
); 
1386 wxDataViewCustomRenderer::~wxDataViewCustomRenderer() 
1392 wxDC 
*wxDataViewCustomRenderer::GetDC() 
1396         if (GetOwner() == NULL
) 
1398         if (GetOwner()->GetOwner() == NULL
) 
1400         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
1406 // --------------------------------------------------------- 
1407 // wxDataViewProgressRenderer 
1408 // --------------------------------------------------------- 
1410 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
) 
1412 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString 
&label
, 
1413     const wxString 
&varianttype
, wxDataViewCellMode mode
, int align 
) : 
1414     wxDataViewCustomRenderer( varianttype
, mode
, align
, true ) 
1420     if (!gtk_check_version(2,6,0)) 
1422         m_renderer 
= (GtkWidget
*) gtk_cell_renderer_progress_new(); 
1424         GValue gvalue 
= { 0, }; 
1425         g_value_init( &gvalue
, G_TYPE_STRING 
); 
1427         // FIXME: font encoding support 
1428         g_value_set_string( &gvalue
, wxGTK_CONV_SYS(m_label
) ); 
1429         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1430         g_value_unset( &gvalue 
); 
1433         SetAlignment(align
); 
1438         // Use custom cell code 
1439         wxDataViewCustomRenderer::Init(mode
, align
); 
1443 wxDataViewProgressRenderer::~wxDataViewProgressRenderer() 
1447 bool wxDataViewProgressRenderer::SetValue( const wxVariant 
&value 
) 
1450     if (!gtk_check_version(2,6,0)) 
1452         gint tmp 
= (long) value
; 
1453         GValue gvalue 
= { 0, }; 
1454         g_value_init( &gvalue
, G_TYPE_INT 
); 
1455         g_value_set_int( &gvalue
, tmp 
); 
1456         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
1457         g_value_unset( &gvalue 
); 
1462         m_value 
= (long) value
; 
1464         if (m_value 
< 0) m_value 
= 0; 
1465         if (m_value 
> 100) m_value 
= 100; 
1471 bool wxDataViewProgressRenderer::GetValue( wxVariant 
&value 
) const 
1476 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1478     double pct 
= (double)m_value 
/ 100.0; 
1480     bar
.width 
= (int)(cell
.width 
* pct
); 
1481     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
1482     dc
->SetBrush( *wxBLUE_BRUSH 
); 
1483     dc
->DrawRectangle( bar 
); 
1485     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
1486     dc
->SetPen( *wxBLACK_PEN 
); 
1487     dc
->DrawRectangle( cell 
); 
1492 wxSize 
wxDataViewProgressRenderer::GetSize() const 
1494     return wxSize(40,12); 
1497 // --------------------------------------------------------- 
1498 // wxDataViewDateRenderer 
1499 // --------------------------------------------------------- 
1501 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
 
1504     wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
1505         wxDataViewListModel 
*model
, unsigned int col
, unsigned int row 
) : 
1506         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
1511         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
1512         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1513         sizer
->Add( m_cal
, 1, wxGROW 
); 
1518     virtual void OnDismiss() 
1522     void OnCalendar( wxCalendarEvent 
&event 
); 
1524     wxCalendarCtrl      
*m_cal
; 
1525     wxDataViewListModel 
*m_model
; 
1530     DECLARE_EVENT_TABLE() 
1533 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
) 
1534     EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar 
) 
1537 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
1539     wxDateTime date 
= event
.GetDate(); 
1540     wxVariant value 
= date
; 
1541     m_model
->SetValue( value
, m_col
, m_row 
); 
1542     m_model
->ValueChanged( m_col
, m_row 
); 
1546 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
) 
1548 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString 
&varianttype
, 
1549                         wxDataViewCellMode mode
, int align 
) : 
1550     wxDataViewCustomRenderer( varianttype
, mode
, align 
) 
1553     SetAlignment(align
); 
1556 bool wxDataViewDateRenderer::SetValue( const wxVariant 
&value 
) 
1558     m_date 
= value
.GetDateTime(); 
1563 bool wxDataViewDateRenderer::GetValue( wxVariant 
&value 
) const 
1568 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1570     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
1571     wxString tmp 
= m_date
.FormatDate(); 
1572     dc
->DrawText( tmp
, cell
.x
, cell
.y 
); 
1577 wxSize 
wxDataViewDateRenderer::GetSize() const 
1579     wxString tmp 
= m_date
.FormatDate(); 
1581     GetView()->GetTextExtent( tmp
, &x
, &y
, &d 
); 
1582     return wxSize(x
,y
+d
); 
1585 bool wxDataViewDateRenderer::Activate( wxRect cell
, wxDataViewListModel 
*model
, 
1586                                        unsigned int col
, unsigned int row 
) 
1589     model
->GetValue( variant
, col
, row 
); 
1590     wxDateTime value 
= variant
.GetDateTime(); 
1592     wxDataViewDateRendererPopupTransient 
*popup 
= new wxDataViewDateRendererPopupTransient( 
1593         GetOwner()->GetOwner()->GetParent(), &value
, model
, col
, row 
); 
1594     wxPoint pos 
= wxGetMousePosition(); 
1597     popup
->Popup( popup
->m_cal 
); 
1602 // --------------------------------------------------------- 
1604 // --------------------------------------------------------- 
1608 gtk_dataview_header_button_press_callback( GtkWidget 
*widget
, 
1609                                            GdkEventButton 
*gdk_event
, 
1610                                            wxDataViewColumn 
*column 
) 
1612     if (gdk_event
->type 
!= GDK_BUTTON_PRESS
) 
1615     if (gdk_event
->button 
== 1) 
1617         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1618         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() ); 
1619         event
.SetDataViewColumn( column 
); 
1620         event
.SetModel( dv
->GetModel() ); 
1621         dv
->GetEventHandler()->ProcessEvent( event 
); 
1628 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1629                             GtkCellRenderer 
*cell
, 
1630                             GtkTreeModel 
*model
, 
1636 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1637                             GtkCellRenderer 
*renderer
, 
1638                             GtkTreeModel 
*model
, 
1642     g_return_if_fail (GTK_IS_WX_LIST_STORE (model
)); 
1643     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) model
; 
1645     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) data
; 
1647     unsigned int model_row 
= (unsigned int) iter
->user_data
; 
1650     list_store
->model
->GetValue( value
, cell
->GetOwner()->GetModelColumn(), model_row 
); 
1652     if (value
.GetType() != cell
->GetVariantType()) 
1653         wxLogError( wxT("Wrong type, required: %s but: %s"), 
1654                     value
.GetType().c_str(), 
1655                     cell
->GetVariantType().c_str() ); 
1657     cell
->SetValue( value 
); 
1660 IMPLEMENT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
) 
1662 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewRenderer 
*cell
, 
1663                                     unsigned int model_column
, int width
, 
1664                                     wxAlignment align
, int flags 
) : 
1665     wxDataViewColumnBase( title
, cell
, model_column
, width
, align
, flags 
) 
1667     Init( align
, flags
, width 
); 
1669     gtk_tree_view_column_set_clickable( GTK_TREE_VIEW_COLUMN(m_column
), TRUE 
); 
1673 wxDataViewColumn::wxDataViewColumn( const wxBitmap 
&bitmap
, wxDataViewRenderer 
*cell
, 
1674                                     unsigned int model_column
, int width
, 
1675                                     wxAlignment align
, int flags 
) : 
1676     wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, align
, flags 
) 
1678     Init( align
, flags
, width 
); 
1680     SetBitmap( bitmap 
); 
1683 void wxDataViewColumn::Init(wxAlignment align
, int flags
, int width
) 
1685     m_isConnected 
= false; 
1687     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) GetRenderer()->GetGtkHandle(); 
1688     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
1689     m_column 
= (GtkWidget
*) column
; 
1692     SetAlignment( align 
); 
1694     // NOTE: we prefer not to call SetMinWidth(wxDVC_DEFAULT_MINWIDTH); 
1695     //       as GTK+ is smart and unless explicitely told, will set the minimal 
1696     //       width to the title's lenght, which is a better default 
1698     // the GTK_TREE_VIEW_COLUMN_FIXED is required by the "fixed height" mode 
1699     // that we use for the wxDataViewCtrl 
1700     gtk_tree_view_column_set_fixed_width( column
, width 
< 0 ? wxDVC_DEFAULT_WIDTH 
: width 
); 
1701     gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_FIXED 
); 
1703     gtk_tree_view_column_pack_end( column
, renderer
, TRUE 
); 
1705     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
1706         wxGtkTreeCellDataFunc
, (gpointer
) GetRenderer(), NULL 
); 
1709 wxDataViewColumn::~wxDataViewColumn() 
1713 void wxDataViewColumn::OnInternalIdle() 
1718     if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
)) 
1720         GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1723             g_signal_connect(column
->button
, "button_press_event", 
1724                       G_CALLBACK (gtk_dataview_header_button_press_callback
), this); 
1726             m_isConnected 
= true; 
1731 void wxDataViewColumn::SetOwner( wxDataViewCtrl 
*owner 
) 
1733     wxDataViewColumnBase::SetOwner( owner 
); 
1735     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1737     gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) ); 
1740 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
1742     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1746         // disconnect before column->button gets recreated 
1747         g_signal_handlers_disconnect_by_func( column
->button
, 
1748                       (GtkWidget
*) gtk_dataview_header_button_press_callback
, this); 
1750         m_isConnected 
= false; 
1753     // FIXME: can it really happen that we don't have the owner here?? 
1754     wxDataViewCtrl 
*ctrl 
= GetOwner(); 
1755     gtk_tree_view_column_set_title( column
, ctrl 
? wxGTK_CONV_FONT(title
, ctrl
->GetFont()) 
1756                                                  : wxGTK_CONV_SYS(title
) ); 
1758     gtk_tree_view_column_set_widget( column
, NULL 
); 
1761 wxString 
wxDataViewColumn::GetTitle() const 
1763     const gchar 
*str 
= gtk_tree_view_column_get_title( GTK_TREE_VIEW_COLUMN(m_column
) ); 
1764     return wxConvFileName
->cMB2WX(str
); 
1767 void wxDataViewColumn::SetBitmap( const wxBitmap 
&bitmap 
) 
1769     wxDataViewColumnBase::SetBitmap( bitmap 
); 
1771     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1774         GtkImage 
*gtk_image 
= GTK_IMAGE( gtk_image_new() ); 
1776         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1777         if (bitmap
.GetMask()) 
1778             mask 
= bitmap
.GetMask()->GetBitmap(); 
1780         if (bitmap
.HasPixbuf()) 
1782             gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
), 
1783                                       bitmap
.GetPixbuf()); 
1787             gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
), 
1788                                       bitmap
.GetPixmap(), mask
); 
1790         gtk_widget_show( GTK_WIDGET(gtk_image
) ); 
1792         gtk_tree_view_column_set_widget( column
, GTK_WIDGET(gtk_image
) ); 
1796         gtk_tree_view_column_set_widget( column
, NULL 
); 
1800 void wxDataViewColumn::SetHidden( bool hidden 
) 
1802     gtk_tree_view_column_set_visible( GTK_TREE_VIEW_COLUMN(m_column
), !hidden 
); 
1805 void wxDataViewColumn::SetResizeable( bool resizeable 
) 
1807     gtk_tree_view_column_set_resizable( GTK_TREE_VIEW_COLUMN(m_column
), resizeable 
); 
1810 void wxDataViewColumn::SetAlignment( wxAlignment align 
) 
1812     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1814     gfloat xalign 
= 0.0; 
1815     if (align 
== wxALIGN_RIGHT
) 
1817     if (align 
== wxALIGN_CENTER_HORIZONTAL 
|| 
1818         align 
== wxALIGN_CENTER
) 
1821     gtk_tree_view_column_set_alignment( column
, xalign 
); 
1824 wxAlignment 
wxDataViewColumn::GetAlignment() const 
1826     gfloat xalign 
= gtk_tree_view_column_get_alignment( GTK_TREE_VIEW_COLUMN(m_column
) ); 
1829         return wxALIGN_RIGHT
; 
1831         return wxALIGN_CENTER_HORIZONTAL
; 
1833     return wxALIGN_LEFT
; 
1836 void wxDataViewColumn::SetSortable( bool sortable 
) 
1838     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1839     gtk_tree_view_column_set_sort_indicator( column
, sortable 
); 
1842 bool wxDataViewColumn::IsSortable() const 
1844     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1845     return gtk_tree_view_column_get_sort_indicator( column 
); 
1848 bool wxDataViewColumn::IsResizeable() const 
1850     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1851     return gtk_tree_view_column_get_resizable( column 
); 
1854 bool wxDataViewColumn::IsHidden() const 
1856     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1857     return !gtk_tree_view_column_get_visible( column 
); 
1860 void wxDataViewColumn::SetSortOrder( bool ascending 
) 
1862     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1865         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING 
); 
1867         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING 
); 
1870 bool wxDataViewColumn::IsSortOrderAscending() const 
1872     GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(m_column
); 
1874     return (gtk_tree_view_column_get_sort_order( column 
) != GTK_SORT_DESCENDING
); 
1877 void wxDataViewColumn::SetMinWidth( int width 
) 
1879     gtk_tree_view_column_set_min_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
1882 int wxDataViewColumn::GetMinWidth() const 
1884     return gtk_tree_view_column_get_min_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
1887 int wxDataViewColumn::GetWidth() const 
1889     return gtk_tree_view_column_get_width( GTK_TREE_VIEW_COLUMN(m_column
) ); 
1892 void wxDataViewColumn::SetWidth( int width 
) 
1894     gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), width 
); 
1898 //----------------------------------------------------------------------------- 
1899 // wxDataViewCtrl signal callbacks 
1900 //----------------------------------------------------------------------------- 
1903 wxdataview_selection_changed_callback( GtkTreeSelection
* selection
, wxDataViewCtrl 
*dv 
) 
1905     if (!GTK_WIDGET_REALIZED(dv
->m_widget
)) 
1908     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ROW_SELECTED
, dv
->GetId() ); 
1909     event
.SetRow( dv
->GetSelection() ); 
1910     event
.SetModel( dv
->GetModel() ); 
1911     dv
->GetEventHandler()->ProcessEvent( event 
); 
1915 wxdataview_row_activated_callback( GtkTreeView
* treeview
, GtkTreePath 
*path
, 
1916                                    GtkTreeViewColumn 
*column
, wxDataViewCtrl 
*dv 
) 
1918     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED
, dv
->GetId() ); 
1919     unsigned int row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
1920     event
.SetRow( row 
); 
1921     event
.SetModel( dv
->GetModel() ); 
1922     dv
->GetEventHandler()->ProcessEvent( event 
); 
1925 //----------------------------------------------------------------------------- 
1927 //----------------------------------------------------------------------------- 
1929 //----------------------------------------------------------------------------- 
1930 // InsertChild for wxDataViewCtrl 
1931 //----------------------------------------------------------------------------- 
1933 static void wxInsertChildInDataViewCtrl( wxWindowGTK
* parent
, wxWindowGTK
* child 
) 
1935     wxDataViewCtrl 
* dvc 
= (wxDataViewCtrl
*) parent
; 
1936     GtkWidget 
*treeview 
= dvc
->GtkGetTreeView(); 
1938     // Insert widget in GtkTreeView 
1939     if (GTK_WIDGET_REALIZED(treeview
)) 
1940         gtk_widget_set_parent_window( child
->m_widget
, 
1941           gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview
) ) ); 
1942     gtk_widget_set_parent( child
->m_widget
, treeview 
); 
1946 void gtk_dataviewctrl_size_callback( GtkWidget 
*WXUNUSED(widget
), 
1947                                      GtkAllocation 
*alloc
, 
1948                                      wxDataViewCtrl 
*win 
) 
1951     wxWindowList::Node 
*node 
= win
->GetChildren().GetFirst(); 
1954         wxWindow 
*child 
= node
->GetData(); 
1957         gtk_widget_size_request( child
->m_widget
, &req 
); 
1959         GtkAllocation alloc
; 
1960         alloc
.x 
= child
->m_x
; 
1961         alloc
.y 
= child
->m_y
; 
1962         alloc
.width 
= child
->m_width
; 
1963         alloc
.height 
= child
->m_height
; 
1964         gtk_widget_size_allocate( child
->m_widget
, &alloc 
); 
1966         node 
= node
->GetNext(); 
1972 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
1974 wxDataViewCtrl::~wxDataViewCtrl() 
1977         GetModel()->RemoveNotifier( m_notifier 
); 
1979     // remove the model from the GtkTreeView before it gets destroyed by the 
1980     // wxDataViewCtrlBase's dtor 
1981     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), NULL 
); 
1984 void wxDataViewCtrl::Init() 
1989 bool wxDataViewCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
1990            const wxPoint
& pos
, const wxSize
& size
, 
1991            long style
, const wxValidator
& validator 
) 
1995     if (!PreCreation( parent
, pos
, size 
) || 
1996         !CreateBase( parent
, id
, pos
, size
, style
, validator 
)) 
1998         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
2002     m_insertCallback 
= wxInsertChildInDataViewCtrl
; 
2004     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
2006     GtkScrolledWindowSetBorder(m_widget
, style
); 
2008     m_treeview 
= gtk_tree_view_new(); 
2009     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
2011     g_signal_connect (m_treeview
, "size_allocate", 
2012                      G_CALLBACK (gtk_dataviewctrl_size_callback
), this); 
2015     if (!gtk_check_version(2,6,0)) 
2016         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), TRUE 
); 
2019     if (style 
& wxDV_MULTIPLE
) 
2021         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2022         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
2025     gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_NO_HEADER
) == 0 ); 
2028     if (!gtk_check_version(2,10,0)) 
2030         GtkTreeViewGridLines grid 
= GTK_TREE_VIEW_GRID_LINES_NONE
; 
2032         if ((style 
& wxDV_HORIZ_RULES
) != 0 && 
2033             (style 
& wxDV_VERT_RULES
) != 0) 
2034             grid 
= GTK_TREE_VIEW_GRID_LINES_BOTH
; 
2035         else if (style 
& wxDV_VERT_RULES
) 
2036             grid 
= GTK_TREE_VIEW_GRID_LINES_VERTICAL
; 
2037         else if (style 
& wxDV_HORIZ_RULES
) 
2038             grid 
= GTK_TREE_VIEW_GRID_LINES_HORIZONTAL
; 
2040         gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview
), grid 
); 
2045         gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview
), (style 
& wxDV_HORIZ_RULES
) != 0 ); 
2048     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
2049         GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
); 
2050     gtk_widget_show (m_treeview
); 
2052     m_parent
->DoAddChild( this ); 
2056     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2057     g_signal_connect_after (selection
, "changed", 
2058                             G_CALLBACK (wxdataview_selection_changed_callback
), this); 
2059     g_signal_connect_after (m_treeview
, "row_activated", 
2060                             G_CALLBACK (wxdataview_row_activated_callback
), this); 
2065 void wxDataViewCtrl::OnInternalIdle() 
2067     wxWindow::OnInternalIdle(); 
2069     unsigned int cols 
= GetColumnCount(); 
2071     for (i 
= 0; i 
< cols
; i
++) 
2073         wxDataViewColumn 
*col 
= GetColumn( i 
); 
2074         col
->OnInternalIdle(); 
2078 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel 
*model 
) 
2080     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
2083     GtkWxListStore 
*gtk_store 
= wxgtk_list_store_new(); 
2084     gtk_store
->model 
= model
; 
2086     m_notifier 
= new wxGtkDataViewListModelNotifier( gtk_store
, model 
); 
2088     model
->AddNotifier( m_notifier 
); 
2090     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_store
) ); 
2091     g_object_unref( gtk_store 
); 
2096 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
2098     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
2101     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)col
->GetGtkHandle(); 
2103     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), column 
); 
2108 void wxDataViewCtrl::SetSelection( int row 
) 
2110     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2114         gtk_tree_selection_unselect_all( selection 
); 
2118         GtkTreePath 
*path 
= gtk_tree_path_new (); 
2119         gtk_tree_path_append_index( path
, row 
); 
2121         gtk_tree_selection_select_path( selection
, path 
); 
2123         gtk_tree_path_free( path 
); 
2127 void wxDataViewCtrl::Unselect( unsigned int row 
) 
2129     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2131     GtkTreePath 
*path 
= gtk_tree_path_new (); 
2132     gtk_tree_path_append_index( path
, row 
); 
2134     gtk_tree_selection_unselect_path( selection
, path 
); 
2136     gtk_tree_path_free( path 
); 
2139 void wxDataViewCtrl::SetSelectionRange( unsigned int from
, unsigned int to 
) 
2143 void wxDataViewCtrl::SetSelections( const wxArrayInt
& aSelections
) 
2147 bool wxDataViewCtrl::IsSelected( unsigned int row 
) const 
2149     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2151     GtkTreePath 
*path 
= gtk_tree_path_new (); 
2152     gtk_tree_path_append_index( path
, row 
); 
2154     gboolean ret 
=  gtk_tree_selection_path_is_selected( selection
, path 
); 
2156     gtk_tree_path_free( path 
); 
2161 int wxDataViewCtrl::GetSelection() const 
2163     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2164     if (HasFlag(wxDV_MULTIPLE
)) 
2166         GtkTreeModel 
*model
; 
2167         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
2172             // list = g_list_nth( list, 0 );  should be a noop 
2173             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
2175             unsigned int row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
2178             g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
2179             g_list_free( list 
); 
2187         GtkTreeModel 
*model
; 
2189         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
2192             unsigned int row 
= (wxUIntPtr
) iter
.user_data
; 
2200 int wxDataViewCtrl::GetSelections(wxArrayInt
& aSelections
) const 
2202     aSelections
.Clear(); 
2204     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
2205     if (HasFlag(wxDV_MULTIPLE
)) 
2207         GtkTreeModel 
*model
; 
2208         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
2214             // list = g_list_nth( list, 0 );  should be a noop 
2215             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
2217             unsigned int row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
2219             aSelections
.Add( (int) row 
); 
2221             list 
= g_list_next( list 
); 
2225         g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
2226         g_list_free( list 
); 
2232         GtkTreeModel 
*model
; 
2234         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
2237             unsigned int row 
= (wxUIntPtr
) iter
.user_data
; 
2238             aSelections
.Add( (int) row 
); 
2248 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
2250     return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
); 
2255     // !wxUSE_GENERICDATAVIEWCTRL 
2258     // wxUSE_DATAVIEWCTRL