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
->GetNumberOfCols(); 
 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
->GetColType( (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
->GetNumberOfRows()) 
 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
->GetColType( (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
->GetNumberOfRows()-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
->GetNumberOfRows(); 
 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
->GetNumberOfRows()) 
 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 
); 
 484 static GObjectClass 
*cell_parent_class 
= NULL
; 
 489 gtk_wx_cell_renderer_get_type (void) 
 491     static GType cell_wx_type 
= 0; 
 495         const GTypeInfo cell_wx_info 
= 
 497             sizeof (GtkWxCellRendererClass
), 
 498             NULL
, /* base_init */ 
 499             NULL
, /* base_finalize */ 
 500             (GClassInitFunc
) gtk_wx_cell_renderer_class_init
, 
 501             NULL
, /* class_finalize */ 
 502             NULL
, /* class_data */ 
 503             sizeof (GtkWxCellRenderer
), 
 505             (GInstanceInitFunc
) gtk_wx_cell_renderer_init
, 
 508         cell_wx_type 
= g_type_register_static( GTK_TYPE_CELL_RENDERER
, 
 509             "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 ); 
 516 gtk_wx_cell_renderer_init (GtkWxCellRenderer 
*cell
) 
 519     cell
->last_click 
= 0; 
 523 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass 
*klass
) 
 525     GObjectClass 
*object_class 
= G_OBJECT_CLASS (klass
); 
 526     GtkCellRendererClass 
*cell_class 
= GTK_CELL_RENDERER_CLASS (klass
); 
 528     cell_parent_class 
= (GObjectClass
*) g_type_class_peek_parent (klass
); 
 530     object_class
->finalize 
= gtk_wx_cell_renderer_finalize
; 
 532     cell_class
->get_size 
= gtk_wx_cell_renderer_get_size
; 
 533     cell_class
->render 
= gtk_wx_cell_renderer_render
; 
 534     cell_class
->activate 
= gtk_wx_cell_renderer_activate
; 
 538 gtk_wx_cell_renderer_finalize (GObject 
*object
) 
 541     (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
); 
 545 gtk_wx_cell_renderer_new (void) 
 547     return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
); 
 551 gtk_wx_cell_renderer_get_size (GtkCellRenderer 
*renderer
, 
 553                                GdkRectangle    
*cell_area
, 
 559     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 560     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 562     wxSize size 
= cell
->GetSize(); 
 564     gint calc_width  
= (gint
) renderer
->xpad 
* 2 + size
.x
; 
 565     gint calc_height 
= (gint
) renderer
->ypad 
* 2 + size
.y
; 
 572     if (cell_area 
&& size
.x 
> 0 && size
.y 
> 0) 
 576             *x_offset 
= (gint
)((renderer
->xalign 
* 
 577                                (cell_area
->width 
- calc_width 
- 2 * renderer
->xpad
))); 
 578             *x_offset 
= MAX (*x_offset
, 0) + renderer
->xpad
; 
 582             *y_offset 
= (gint
)((renderer
->yalign 
* 
 583                                (cell_area
->height 
- calc_height 
- 2 * renderer
->ypad
))); 
 584             *y_offset 
= MAX (*y_offset
, 0) + renderer
->ypad
; 
 592         *height 
= calc_height
; 
 596 gtk_wx_cell_renderer_render (GtkCellRenderer      
*renderer
, 
 599                              GdkRectangle         
*background_area
, 
 600                              GdkRectangle         
*cell_area
, 
 601                              GdkRectangle         
*expose_area
, 
 602                              GtkCellRendererState  flags
) 
 605     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 606     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 609     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 615     rect
.x 
+= cell_area
->x
; 
 616     rect
.y 
+= cell_area
->y
; 
 617     rect
.width  
-= renderer
->xpad 
* 2; 
 618     rect
.height 
-= renderer
->ypad 
* 2; 
 621     if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
)) 
 623         wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 624         wxWindowDC
* dc 
= (wxWindowDC
*) cell
->GetDC(); 
 625         if (dc
->m_window 
== NULL
) 
 627             dc
->m_window 
= window
; 
 632         if (flags 
& GTK_CELL_RENDERER_SELECTED
) 
 633             state 
|= wxDATAVIEW_CELL_SELECTED
; 
 634         if (flags 
& GTK_CELL_RENDERER_PRELIT
) 
 635             state 
|= wxDATAVIEW_CELL_PRELIT
; 
 636         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 637             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 638         if (flags 
& GTK_CELL_RENDERER_INSENSITIVE
) 
 639             state 
|= wxDATAVIEW_CELL_INSENSITIVE
; 
 640         if (flags 
& GTK_CELL_RENDERER_FOCUSED
) 
 641             state 
|= wxDATAVIEW_CELL_FOCUSED
; 
 642         cell
->Render( renderrect
, dc
, state 
); 
 647 gtk_wx_cell_renderer_activate( 
 648                         GtkCellRenderer         
*renderer
, 
 652                         GdkRectangle            
*background_area
, 
 653                         GdkRectangle            
*cell_area
, 
 654                         GtkCellRendererState     flags 
) 
 656     GtkWxCellRenderer 
*wxrenderer 
= (GtkWxCellRenderer 
*) renderer
; 
 657     wxDataViewCustomRenderer 
*cell 
= wxrenderer
->cell
; 
 660     gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
, 
 666     rect
.x 
+= cell_area
->x
; 
 667     rect
.y 
+= cell_area
->y
; 
 668     rect
.width  
-= renderer
->xpad 
* 2; 
 669     rect
.height 
-= renderer
->ypad 
* 2; 
 671     wxRect 
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 673     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 675     GtkTreePath 
*treepath 
= gtk_tree_path_new_from_string( path 
); 
 676     unsigned int model_row 
= (unsigned int)gtk_tree_path_get_indices (treepath
)[0]; 
 677     gtk_tree_path_free( treepath 
); 
 679     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
 681     if (event
->type 
== GDK_BUTTON_PRESS
) 
 683         GdkEventButton 
*button_event 
= (GdkEventButton
*) event
; 
 684         wxPoint 
pt( ((int) button_event
->x
) - renderrect
.x
, 
 685                     ((int) button_event
->y
) - renderrect
.y 
); 
 688         if (button_event
->button 
== 1) 
 690             if (cell
->LeftClick( pt
, renderrect
, model
, model_col
, model_row 
)) 
 692             // TODO: query system double-click time 
 693             if (button_event
->time 
- wxrenderer
->last_click 
< 400) 
 694                 if (cell
->Activate( renderrect
, model
, model_col
, model_row 
)) 
 697         if (button_event
->button 
== 3) 
 699             if (cell
->RightClick( pt
, renderrect
, model
, model_col
, model_row 
)) 
 703         wxrenderer
->last_click 
= button_event
->time
; 
 711 // --------------------------------------------------------- 
 712 // wxGtkDataViewListModelNotifier 
 713 // --------------------------------------------------------- 
 715 class wxGtkDataViewListModelNotifier
: public wxDataViewListModelNotifier
 
 718     wxGtkDataViewListModelNotifier( GtkWxListStore
* gtk_store
, wxDataViewListModel 
*wx_model 
); 
 720     virtual bool RowAppended(); 
 721     virtual bool RowPrepended(); 
 722     virtual bool RowInserted( unsigned int before 
); 
 723     virtual bool RowDeleted( unsigned int row 
); 
 724     virtual bool RowChanged( unsigned int row 
); 
 725     virtual bool ValueChanged( unsigned int col
, unsigned int row 
); 
 726     virtual bool RowsReordered( unsigned int *new_order 
); 
 727     virtual bool Cleared(); 
 733     return wxDataViewListModelNotifier::Freed(); 
 736     GtkWxListStore      
*m_gtk_store
; 
 737     wxDataViewListModel 
*m_wx_model
; 
 740 // --------------------------------------------------------- 
 741 // wxGtkDataViewListModelNotifier 
 742 // --------------------------------------------------------- 
 744 wxGtkDataViewListModelNotifier::wxGtkDataViewListModelNotifier( 
 745     GtkWxListStore
* gtk_store
, wxDataViewListModel 
*wx_model 
) 
 747     m_gtk_store 
= gtk_store
; 
 748     m_wx_model 
= wx_model
; 
 751 bool wxGtkDataViewListModelNotifier::RowAppended() 
 753     unsigned int pos 
= m_wx_model
->GetNumberOfRows()-1; 
 756     iter
.stamp 
= m_gtk_store
->stamp
; 
 757     iter
.user_data 
= (gpointer
) pos
; 
 759     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 760     gtk_tree_path_append_index (path
, (gint
) pos
); 
 761     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 762     gtk_tree_path_free (path
); 
 767 bool wxGtkDataViewListModelNotifier::RowPrepended() 
 770     iter
.stamp 
= m_gtk_store
->stamp
; 
 771     iter
.user_data 
= (gpointer
) 0; 
 773     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 774     gtk_tree_path_append_index (path
, (gint
) 0); 
 775     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 776     gtk_tree_path_free (path
); 
 781 bool wxGtkDataViewListModelNotifier::RowInserted( unsigned int before 
) 
 784     iter
.stamp 
= m_gtk_store
->stamp
; 
 785     iter
.user_data 
= (gpointer
) before
; 
 787     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 788     gtk_tree_path_append_index (path
, (gint
) before
); 
 789     gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 790     gtk_tree_path_free (path
); 
 795 bool wxGtkDataViewListModelNotifier::RowDeleted( unsigned int row 
) 
 797     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 798     gtk_tree_path_append_index (path
, (gint
) row
); 
 799     gtk_tree_model_row_deleted (GTK_TREE_MODEL (m_gtk_store
), path
); 
 800     gtk_tree_path_free (path
); 
 805 bool wxGtkDataViewListModelNotifier::RowChanged( unsigned int row 
) 
 808     iter
.stamp 
= m_gtk_store
->stamp
; 
 809     iter
.user_data 
= (gpointer
) row
; 
 810     GtkTreePath 
*path 
= gtk_tree_model_get_path (GTK_TREE_MODEL (m_gtk_store
), &iter
); 
 811     gtk_tree_model_row_changed (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
); 
 812     gtk_tree_path_free (path
); 
 817 bool wxGtkDataViewListModelNotifier::ValueChanged( unsigned int model_col
, unsigned int model_row 
) 
 819     // This adds GTK+'s missing MVC logic for ValueChanged 
 820     wxNode 
*node 
= GetOwner()->m_viewingColumns
.GetFirst(); 
 823         wxDataViewViewingColumn
* viewing_column 
= (wxDataViewViewingColumn
*) node
->GetData(); 
 824         if (viewing_column
->m_modelColumn 
== model_col
) 
 826             GtkTreeView 
*widget 
= GTK_TREE_VIEW(viewing_column
->m_viewColumn
->GetOwner()->m_treeview
); 
 827             GtkTreeViewColumn 
*column 
= GTK_TREE_VIEW_COLUMN(viewing_column
->m_viewColumn
->GetGtkHandle()); 
 830             GtkTreePath 
*path 
= gtk_tree_path_new(); 
 831             gtk_tree_path_append_index( path
, model_row 
); 
 832             GdkRectangle cell_area
; 
 833             gtk_tree_view_get_cell_area( widget
, path
, column
, &cell_area 
); 
 834             gtk_tree_path_free( path 
); 
 836             int ydiff 
= column
->button
->allocation
.height
; 
 838             gtk_widget_queue_draw_area( GTK_WIDGET(widget
), 
 839                 cell_area
.x
, ydiff 
+ cell_area
.y
, cell_area
.width
, cell_area
.height 
); 
 842         node 
= node
->GetNext(); 
 848 bool wxGtkDataViewListModelNotifier::RowsReordered( unsigned int *new_order 
) 
 850     // Assume sizeof(unsigned int)= == sizeof(gint) 
 852     GtkTreePath 
*path 
= gtk_tree_path_new (); 
 853     gtk_tree_model_rows_reordered (GTK_TREE_MODEL (m_gtk_store
), path
, NULL
, (gint
*)new_order
); 
 854     gtk_tree_path_free (path
); 
 856     // This adds GTK+'s missing MVC logic for RowsReordered 
 857     wxNode 
*node 
= GetOwner()->m_viewingColumns
.GetFirst(); 
 860         wxDataViewViewingColumn
* viewing_column 
= (wxDataViewViewingColumn
*) node
->GetData(); 
 861         GtkTreeView 
*widget 
= GTK_TREE_VIEW(viewing_column
->m_viewColumn
->GetOwner()->m_treeview
); 
 862         // Doesn't work yet... 
 863         gtk_widget_queue_draw( GTK_WIDGET(widget
) ); 
 865         node 
= node
->GetNext(); 
 871 bool wxGtkDataViewListModelNotifier::Cleared() 
 876 // --------------------------------------------------------- 
 877 // wxDataViewRenderer 
 878 // --------------------------------------------------------- 
 880 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
) 
 882 wxDataViewRenderer::wxDataViewRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode 
) : 
 883     wxDataViewRendererBase( varianttype
, mode 
) 
 888 // --------------------------------------------------------- 
 889 // wxDataViewTextRenderer 
 890 // --------------------------------------------------------- 
 893 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
 894     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
); 
 897 static void wxGtkTextRendererEditedCallback( GtkCellRendererText 
*renderer
, 
 898     gchar 
*arg1
, gchar 
*arg2
, gpointer user_data 
) 
 900     wxDataViewTextRenderer 
*cell 
= (wxDataViewTextRenderer
*) user_data
; 
 902     wxString tmp 
= wxGTK_CONV_BACK( arg2 
); 
 903     wxVariant value 
= tmp
; 
 904     if (!cell
->Validate( value 
)) 
 907     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
 909     GtkTreePath 
*path 
= gtk_tree_path_new_from_string( arg1 
); 
 910     unsigned int model_row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
 911     gtk_tree_path_free( path 
); 
 913     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
 915     model
->SetValue( value
, model_col
, model_row 
); 
 916     model
->ValueChanged( model_col
, model_row 
); 
 919 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
) 
 921 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode 
) : 
 922     wxDataViewRenderer( varianttype
, mode 
) 
 924     m_renderer 
= (void*) gtk_cell_renderer_text_new(); 
 926     if (m_mode 
& wxDATAVIEW_CELL_EDITABLE
) 
 928         GValue gvalue 
= { 0, }; 
 929         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
 930         g_value_set_boolean( &gvalue
, true ); 
 931         g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue 
); 
 932         g_value_unset( &gvalue 
); 
 934         g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this ); 
 938 bool wxDataViewTextRenderer::SetValue( const wxVariant 
&value 
) 
 940     wxString tmp 
= value
; 
 942     GValue gvalue 
= { 0, }; 
 943     g_value_init( &gvalue
, G_TYPE_STRING 
); 
 944     g_value_set_string( &gvalue
, wxGTK_CONV_FONT( tmp
, GetOwner()->GetOwner()->GetFont() ) ); 
 945     g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
 946     g_value_unset( &gvalue 
); 
 951 bool wxDataViewTextRenderer::GetValue( wxVariant 
&value 
) 
 953     GValue gvalue 
= { 0, }; 
 954     g_value_init( &gvalue
, G_TYPE_STRING 
); 
 955     g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
 956     wxString tmp 
= wxGTK_CONV_BACK( g_value_get_string( &gvalue 
) ); 
 957     g_value_unset( &gvalue 
); 
 964 // ---------------------------------------------------------  
 965 // wxDataViewBitmapRenderer 
 966 // ---------------------------------------------------------  
 968 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
) 
 970 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString 
&varianttype
, wxDataViewCellMode mode 
) : 
 971     wxDataViewRenderer( varianttype
, mode 
) 
 973     m_renderer 
= (void*) gtk_cell_renderer_pixbuf_new(); 
 976 bool wxDataViewBitmapRenderer::SetValue( const wxVariant 
&value 
) 
 978     if (value
.GetType() == wxT("wxBitmap")) 
 983         // This may create a Pixbuf representation in the 
 984         // wxBitmap object (and it will stay there) 
 985         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
 987         GValue gvalue 
= { 0, }; 
 988         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
 989         g_value_set_object( &gvalue
, pixbuf 
); 
 990         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
 991         g_value_unset( &gvalue 
); 
 996     if (value
.GetType() == wxT("wxIcon")) 
1001         // This may create a Pixbuf representation in the 
1002         // wxBitmap object (and it will stay there) 
1003         GdkPixbuf 
*pixbuf 
= bitmap
.GetPixbuf(); 
1005         GValue gvalue 
= { 0, }; 
1006         g_value_init( &gvalue
, G_TYPE_OBJECT 
); 
1007         g_value_set_object( &gvalue
, pixbuf 
); 
1008         g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue 
); 
1009         g_value_unset( &gvalue 
); 
1017 bool wxDataViewBitmapRenderer::GetValue( wxVariant 
&value 
) 
1022 // --------------------------------------------------------- 
1023 // wxDataViewToggleRenderer 
1024 // --------------------------------------------------------- 
1027 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1028     gchar 
*path
, gpointer user_data 
); 
1031 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle 
*renderer
, 
1032     gchar 
*path
, gpointer user_data 
) 
1034     wxDataViewToggleRenderer 
*cell 
= (wxDataViewToggleRenderer
*) user_data
; 
1037     GValue gvalue 
= { 0, }; 
1038     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1039     g_object_get_property( G_OBJECT(renderer
), "active", &gvalue 
); 
1040     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1041     g_value_unset( &gvalue 
); 
1045     wxVariant value 
= tmp
; 
1046     if (!cell
->Validate( value 
)) 
1049     wxDataViewListModel 
*model 
= cell
->GetOwner()->GetOwner()->GetModel(); 
1051     GtkTreePath 
*gtk_path 
= gtk_tree_path_new_from_string( path 
); 
1052     unsigned int model_row 
= (unsigned int)gtk_tree_path_get_indices (gtk_path
)[0]; 
1053     gtk_tree_path_free( gtk_path 
); 
1055     unsigned int model_col 
= cell
->GetOwner()->GetModelColumn(); 
1057     model
->SetValue( value
, model_col
, model_row 
); 
1058     model
->ValueChanged( model_col
, model_row 
); 
1061 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
) 
1063 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString 
&varianttype
, 
1064                         wxDataViewCellMode mode 
) : 
1065     wxDataViewRenderer( varianttype
, mode 
) 
1067     m_renderer 
= (void*) gtk_cell_renderer_toggle_new(); 
1069     if (m_mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1071         g_signal_connect_after( m_renderer
, "toggled", G_CALLBACK(wxGtkToggleRendererToggledCallback
), this ); 
1076         GValue gvalue 
= { 0, }; 
1077         g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1078         g_value_set_boolean( &gvalue
, false ); 
1079         g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue 
); 
1080         g_value_unset( &gvalue 
); 
1082         GValue gvalue2 
= { 0, }; 
1083         g_value_init( &gvalue2
, gtk_cell_renderer_mode_get_type() ); 
1084         g_value_set_enum( &gvalue2
, GTK_CELL_RENDERER_MODE_INERT 
); 
1085         g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue2 
); 
1086         g_value_unset( &gvalue2 
); 
1091 bool wxDataViewToggleRenderer::SetValue( const wxVariant 
&value 
) 
1095     GValue gvalue 
= { 0, }; 
1096     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1097     g_value_set_boolean( &gvalue
, tmp 
); 
1098     g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1099     g_value_unset( &gvalue 
); 
1104 bool wxDataViewToggleRenderer::GetValue( wxVariant 
&value 
) 
1106     GValue gvalue 
= { 0, }; 
1107     g_value_init( &gvalue
, G_TYPE_BOOLEAN 
); 
1108     g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue 
); 
1109     bool tmp 
= g_value_get_boolean( &gvalue 
); 
1110     g_value_unset( &gvalue 
); 
1117 // --------------------------------------------------------- 
1118 // wxDataViewCustomRenderer 
1119 // --------------------------------------------------------- 
1121 class wxDataViewCtrlDC
: public wxWindowDC
 
1124     wxDataViewCtrlDC( wxDataViewCtrl 
*window 
) 
1126         GtkWidget 
*widget 
= window
->m_treeview
; 
1130         m_context 
= window
->GtkGetPangoDefaultContext(); 
1131         m_layout 
= pango_layout_new( m_context 
); 
1132         m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
1134         m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
1136         // Set m_window later 
1138         // m_owner = window; 
1142 // --------------------------------------------------------- 
1143 // wxDataViewCustomRenderer 
1144 // --------------------------------------------------------- 
1146 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
) 
1148 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString 
&varianttype
, 
1149                           wxDataViewCellMode mode
, bool no_init 
) : 
1150     wxDataViewRenderer( varianttype
, mode 
) 
1160 bool wxDataViewCustomRenderer::Init() 
1162     GtkWxCellRenderer 
*renderer 
= (GtkWxCellRenderer 
*) gtk_wx_cell_renderer_new(); 
1163     renderer
->cell 
= this; 
1165     m_renderer 
= (void*) renderer
; 
1167     if (m_mode 
& wxDATAVIEW_CELL_ACTIVATABLE
) 
1169         GValue gvalue 
= { 0, }; 
1170         g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() ); 
1171         g_value_set_enum( &gvalue
, GTK_CELL_RENDERER_MODE_ACTIVATABLE 
); 
1172         g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue 
); 
1173         g_value_unset( &gvalue 
); 
1179 wxDataViewCustomRenderer::~wxDataViewCustomRenderer() 
1185 wxDC 
*wxDataViewCustomRenderer::GetDC() 
1189         if (GetOwner() == NULL
) 
1191         if (GetOwner()->GetOwner() == NULL
) 
1193         m_dc 
= new wxDataViewCtrlDC( GetOwner()->GetOwner() ); 
1199 // --------------------------------------------------------- 
1200 // wxDataViewProgressRenderer 
1201 // --------------------------------------------------------- 
1203 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
) 
1205 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString 
&label
, 
1206     const wxString 
&varianttype
, wxDataViewCellMode mode 
) : 
1207     wxDataViewCustomRenderer( varianttype
, mode
, true ) 
1213     if (!gtk_check_version(2,6,0)) 
1215         m_renderer 
= (void*) gtk_cell_renderer_progress_new(); 
1217         GValue gvalue 
= { 0, }; 
1218         g_value_init( &gvalue
, G_TYPE_STRING 
); 
1220         // FIXME: font encoding support 
1221         g_value_set_string( &gvalue
, wxGTK_CONV_SYS(m_label
) ); 
1222         g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue 
); 
1223         g_value_unset( &gvalue 
); 
1228         // Use custom cell code 
1229         wxDataViewCustomRenderer::Init(); 
1233 wxDataViewProgressRenderer::~wxDataViewProgressRenderer() 
1237 bool wxDataViewProgressRenderer::SetValue( const wxVariant 
&value 
) 
1240     if (!gtk_check_version(2,6,0)) 
1242         gint tmp 
= (long) value
; 
1243         GValue gvalue 
= { 0, }; 
1244         g_value_init( &gvalue
, G_TYPE_INT 
); 
1245         g_value_set_int( &gvalue
, tmp 
); 
1246         g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue 
); 
1247         g_value_unset( &gvalue 
); 
1252         m_value 
= (long) value
; 
1254         if (m_value 
< 0) m_value 
= 0; 
1255         if (m_value 
> 100) m_value 
= 100; 
1261 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1263     double pct 
= (double)m_value 
/ 100.0; 
1265     bar
.width 
= (int)(cell
.width 
* pct
); 
1266     dc
->SetPen( *wxTRANSPARENT_PEN 
); 
1267     dc
->SetBrush( *wxBLUE_BRUSH 
); 
1268     dc
->DrawRectangle( bar 
); 
1270     dc
->SetBrush( *wxTRANSPARENT_BRUSH 
); 
1271     dc
->SetPen( *wxBLACK_PEN 
); 
1272     dc
->DrawRectangle( cell 
); 
1277 wxSize 
wxDataViewProgressRenderer::GetSize() 
1279     return wxSize(40,12); 
1282 // --------------------------------------------------------- 
1283 // wxDataViewDateRenderer 
1284 // --------------------------------------------------------- 
1286 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
 
1289     wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime 
*value
, 
1290         wxDataViewListModel 
*model
, unsigned int col
, unsigned int row 
) : 
1291         wxPopupTransientWindow( parent
, wxBORDER_SIMPLE 
) 
1296         m_cal 
= new wxCalendarCtrl( this, -1, *value 
); 
1297         wxBoxSizer 
*sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1298         sizer
->Add( m_cal
, 1, wxGROW 
); 
1303     virtual void OnDismiss() 
1307     void OnCalendar( wxCalendarEvent 
&event 
); 
1309     wxCalendarCtrl      
*m_cal
; 
1310     wxDataViewListModel 
*m_model
; 
1315     DECLARE_EVENT_TABLE() 
1318 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
) 
1319     EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar 
) 
1322 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent 
&event 
) 
1324     wxDateTime date 
= event
.GetDate(); 
1325     wxVariant value 
= date
; 
1326     m_model
->SetValue( value
, m_col
, m_row 
); 
1327     m_model
->ValueChanged( m_col
, m_row 
); 
1331 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
) 
1333 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString 
&varianttype
, 
1334                         wxDataViewCellMode mode 
) : 
1335     wxDataViewCustomRenderer( varianttype
, mode 
) 
1339 bool wxDataViewDateRenderer::SetValue( const wxVariant 
&value 
) 
1341     m_date 
= value
.GetDateTime(); 
1346 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC 
*dc
, int state 
) 
1348     dc
->SetFont( GetOwner()->GetOwner()->GetFont() ); 
1349     wxString tmp 
= m_date
.FormatDate(); 
1350     dc
->DrawText( tmp
, cell
.x
, cell
.y 
); 
1355 wxSize 
wxDataViewDateRenderer::GetSize() 
1357     wxDataViewCtrl
* view 
= GetOwner()->GetOwner(); 
1358     wxString tmp 
= m_date
.FormatDate(); 
1360     view
->GetTextExtent( tmp
, &x
, &y
, &d 
); 
1361     return wxSize(x
,y
+d
); 
1364 bool wxDataViewDateRenderer::Activate( wxRect cell
, wxDataViewListModel 
*model
, unsigned int col
, unsigned int row 
) 
1367     model
->GetValue( variant
, col
, row 
); 
1368     wxDateTime value 
= variant
.GetDateTime(); 
1370     wxDataViewDateRendererPopupTransient 
*popup 
= new wxDataViewDateRendererPopupTransient( 
1371         GetOwner()->GetOwner()->GetParent(), &value
, model
, col
, row 
); 
1372     wxPoint pos 
= wxGetMousePosition(); 
1375     popup
->Popup( popup
->m_cal 
); 
1380 // --------------------------------------------------------- 
1382 // --------------------------------------------------------- 
1386 gtk_dataview_header_button_press_callback( GtkWidget 
*widget
, 
1387                                            GdkEventButton 
*gdk_event
, 
1388                                            wxDataViewColumn 
*column 
) 
1390     if (gdk_event
->type 
!= GDK_BUTTON_PRESS
) 
1393     if (gdk_event
->button 
== 1) 
1395         wxDataViewCtrl 
*dv 
= column
->GetOwner(); 
1396         wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() ); 
1397         event
.SetDataViewColumn( column 
); 
1398         event
.SetModel( dv
->GetModel() ); 
1399         dv
->GetEventHandler()->ProcessEvent( event 
); 
1406 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1407                             GtkCellRenderer 
*cell
, 
1408                             GtkTreeModel 
*model
, 
1414 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn 
*column
, 
1415                             GtkCellRenderer 
*renderer
, 
1416                             GtkTreeModel 
*model
, 
1420     g_return_if_fail (GTK_IS_WX_LIST_STORE (model
)); 
1421     GtkWxListStore 
*list_store 
= (GtkWxListStore 
*) model
; 
1423     wxDataViewRenderer 
*cell 
= (wxDataViewRenderer
*) data
; 
1425     unsigned int model_row 
= (unsigned int) iter
->user_data
; 
1428     list_store
->model
->GetValue( value
, cell
->GetOwner()->GetModelColumn(), model_row 
); 
1430     if (value
.GetType() != cell
->GetVariantType()) 
1431         wxLogError( wxT("Wrong type, required: %s but: %s"),  
1432                     value
.GetType().c_str(),  
1433                     cell
->GetVariantType().c_str() ); 
1435     cell
->SetValue( value 
); 
1438 IMPLEMENT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
) 
1440 wxDataViewColumn::wxDataViewColumn( const wxString 
&title
, wxDataViewRenderer 
*cell
,  
1441                                     unsigned int model_column
, int width
,  
1442                                     wxAlignment align
, int flags 
) : 
1443     wxDataViewColumnBase( title
, cell
, model_column
, width
, align
, flags 
) 
1445     m_isConnected 
= false; 
1447     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) cell
->GetGtkHandle(); 
1449     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
1450     m_column 
= (void*) column
; 
1452     gtk_tree_view_column_set_clickable( column
, true ); 
1456     if (flags 
& wxDATAVIEW_COL_RESIZABLE
) 
1457         gtk_tree_view_column_set_resizable( column
, true ); 
1458     if (flags 
& wxDATAVIEW_COL_HIDDEN
) 
1459         gtk_tree_view_column_set_visible( column
, false ); 
1460     if (flags 
& wxDATAVIEW_COL_SORTABLE
) 
1461         gtk_tree_view_column_set_sort_indicator( column
, true ); 
1464         gtk_tree_view_column_set_fixed_width( column
, width 
); 
1466         gtk_tree_view_column_set_fixed_width( column
, 70 );  // FIXME 
1468     gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_FIXED 
); 
1470     gtk_tree_view_column_pack_end( column
, renderer
, FALSE 
); 
1472     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
1473         wxGtkTreeCellDataFunc
, (gpointer
) cell
, NULL 
); 
1475     SetAlignment(align
); 
1478 wxDataViewColumn::wxDataViewColumn( const wxBitmap 
&bitmap
, wxDataViewRenderer 
*cell
,  
1479                                     unsigned int model_column
, int width
,  
1480                                     wxAlignment align
, int flags 
) : 
1481     wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, align
, flags 
) 
1483     m_isConnected 
= false; 
1485     GtkCellRenderer 
*renderer 
= (GtkCellRenderer 
*) cell
->GetGtkHandle(); 
1487     GtkTreeViewColumn 
*column 
= gtk_tree_view_column_new(); 
1488     m_column 
= (void*) column
; 
1490     SetBitmap( bitmap 
); 
1492     if (flags 
& wxDATAVIEW_COL_RESIZABLE
) 
1493         gtk_tree_view_column_set_resizable( column
, true ); 
1494     if (flags 
& wxDATAVIEW_COL_HIDDEN
) 
1495         gtk_tree_view_column_set_visible( column
, false ); 
1496     if (flags 
& wxDATAVIEW_COL_SORTABLE
) 
1497         gtk_tree_view_column_set_sort_indicator( column
, true ); 
1500         gtk_tree_view_column_set_fixed_width( column
, width 
); 
1502         gtk_tree_view_column_set_fixed_width( column
, 70 );  // FIXME 
1504     gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_FIXED 
); 
1506     gtk_tree_view_column_pack_end( column
, renderer
, FALSE 
); 
1508     gtk_tree_view_column_set_cell_data_func( column
, renderer
, 
1509         wxGtkTreeCellDataFunc
, (gpointer
) cell
, NULL 
); 
1511     SetAlignment(align
); 
1514 wxDataViewColumn::~wxDataViewColumn() 
1518 void wxDataViewColumn::OnInternalIdle() 
1523     if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
)) 
1525         GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1528             g_signal_connect(column
->button
, "button_press_event", 
1529                       G_CALLBACK (gtk_dataview_header_button_press_callback
), this); 
1531             m_isConnected 
= true; 
1536 void wxDataViewColumn::SetOwner( wxDataViewCtrl 
*owner 
) 
1538     wxDataViewColumnBase::SetOwner( owner 
); 
1540     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1542     gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) ); 
1545 void wxDataViewColumn::SetTitle( const wxString 
&title 
) 
1547     wxDataViewColumnBase::SetTitle( title 
); 
1549     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1553         // disconnect before column->button gets recreated 
1554         g_signal_handlers_disconnect_by_func( column
->button
,  
1555                       (void*) gtk_dataview_header_button_press_callback
, this); 
1557         m_isConnected 
= false; 
1560     // FIXME: can it really happen that we don't have the owner here?? 
1561     wxDataViewCtrl 
*ctrl 
= GetOwner(); 
1562     gtk_tree_view_column_set_title( column
, ctrl 
? wxGTK_CONV_FONT(title
, ctrl
->GetFont()) 
1563                                                  : wxGTK_CONV_SYS(title
) ); 
1565     gtk_tree_view_column_set_widget( column
, NULL 
); 
1568 void wxDataViewColumn::SetBitmap( const wxBitmap 
&bitmap 
) 
1570     wxDataViewColumnBase::SetBitmap( bitmap 
); 
1572     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1575         GtkImage 
*gtk_image 
= GTK_IMAGE( gtk_image_new() ); 
1577         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1578         if (bitmap
.GetMask()) 
1579             mask 
= bitmap
.GetMask()->GetBitmap(); 
1581         if (bitmap
.HasPixbuf()) 
1583             gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
), 
1584                                       bitmap
.GetPixbuf()); 
1588             gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
), 
1589                                       bitmap
.GetPixmap(), mask
); 
1591         gtk_widget_show( GTK_WIDGET(gtk_image
) ); 
1593         gtk_tree_view_column_set_widget( column
, GTK_WIDGET(gtk_image
) ); 
1597         gtk_tree_view_column_set_widget( column
, NULL 
); 
1601 void wxDataViewColumn::SetAlignment( wxAlignment align 
) 
1603     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1605     gfloat xalign 
= 0.0; 
1606     if (align 
== wxALIGN_RIGHT
) 
1608     if (align 
== wxALIGN_CENTER
) 
1611     gtk_tree_view_column_set_alignment( column
, xalign 
);     
1614 void wxDataViewColumn::SetSortable( bool sortable 
) 
1616     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1617     gtk_tree_view_column_set_sort_indicator( column
, sortable 
); 
1620 bool wxDataViewColumn::IsSortable() const 
1622     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1623     return gtk_tree_view_column_get_sort_indicator( column 
); 
1626 void wxDataViewColumn::SetSortOrder( bool ascending 
) 
1628     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1631         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING 
); 
1633         gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING 
); 
1636 bool wxDataViewColumn::IsSortOrderAscending() const 
1638     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)m_column
; 
1640     return (gtk_tree_view_column_get_sort_order( column 
) != GTK_SORT_DESCENDING
); 
1643 int wxDataViewColumn::GetWidth() const 
1645     return gtk_tree_view_column_get_width( (GtkTreeViewColumn 
*)m_column 
); 
1648 void wxDataViewColumn::SetFixedWidth( int width 
) 
1650     gtk_tree_view_column_set_fixed_width( (GtkTreeViewColumn 
*)m_column
, width 
); 
1653 int wxDataViewColumn::GetFixedWidth() const 
1655     return gtk_tree_view_column_get_fixed_width( (GtkTreeViewColumn 
*)m_column 
); 
1658 //----------------------------------------------------------------------------- 
1659 // wxDataViewCtrl signal callbacks 
1660 //----------------------------------------------------------------------------- 
1663 wxdataview_selection_changed_callback( GtkTreeSelection
* selection
, wxDataViewCtrl 
*dv 
) 
1665     if (!GTK_WIDGET_REALIZED(dv
->m_widget
)) 
1668     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ROW_SELECTED
, dv
->GetId() ); 
1669     event
.SetRow( dv
->GetSelection() ); 
1670     event
.SetModel( dv
->GetModel() ); 
1671     dv
->GetEventHandler()->ProcessEvent( event 
); 
1675 wxdataview_row_activated_callback( GtkTreeView
* treeview
, GtkTreePath 
*path
,  
1676                                    GtkTreeViewColumn 
*column
, wxDataViewCtrl 
*dv 
) 
1678     wxDataViewEvent 
event( wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED
, dv
->GetId() ); 
1679     unsigned int row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
1680     event
.SetRow( row 
); 
1681     event
.SetModel( dv
->GetModel() ); 
1682     dv
->GetEventHandler()->ProcessEvent( event 
); 
1685 //----------------------------------------------------------------------------- 
1687 //----------------------------------------------------------------------------- 
1689 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
) 
1691 wxDataViewCtrl::~wxDataViewCtrl() 
1694         GetModel()->RemoveNotifier( m_notifier 
); 
1696     // remove the model from the GtkTreeView before it gets destroyed by the 
1697     // wxDataViewCtrlBase's dtor 
1698     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), NULL 
); 
1701 void wxDataViewCtrl::Init() 
1706 bool wxDataViewCtrl::Create(wxWindow 
*parent
, wxWindowID id
, 
1707            const wxPoint
& pos
, const wxSize
& size
, 
1708            long style
, const wxValidator
& validator 
) 
1712     m_needParent 
= true; 
1713     m_acceptsFocus 
= true; 
1715     if (!PreCreation( parent
, pos
, size 
) || 
1716         !CreateBase( parent
, id
, pos
, size
, style
, validator 
)) 
1718         wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") ); 
1722     m_widget 
= gtk_scrolled_window_new (NULL
, NULL
); 
1724     GtkScrolledWindowSetBorder(m_widget
, style
); 
1726     m_treeview 
= gtk_tree_view_new(); 
1727     gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
); 
1730     if (!gtk_check_version(2,6,0)) 
1731         gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), TRUE 
); 
1734     if (style 
& wxDV_MULTIPLE
) 
1736         GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1737         gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE 
); 
1740     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
), 
1741         GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
); 
1742     gtk_widget_show (m_treeview
); 
1744     m_parent
->DoAddChild( this ); 
1748     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1749     g_signal_connect_after (selection
, "changed", 
1750                             G_CALLBACK (wxdataview_selection_changed_callback
), this); 
1751     g_signal_connect_after (m_treeview
, "row_activated", 
1752                             G_CALLBACK (wxdataview_row_activated_callback
), this); 
1757 void wxDataViewCtrl::OnInternalIdle() 
1759     wxWindow::OnInternalIdle(); 
1761     unsigned int cols 
= GetNumberOfColumns(); 
1763     for (i 
= 0; i 
< cols
; i
++) 
1765         wxDataViewColumn 
*col 
= GetColumn( i 
); 
1766         col
->OnInternalIdle(); 
1770 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel 
*model 
) 
1772     if (!wxDataViewCtrlBase::AssociateModel( model 
)) 
1775     GtkWxListStore 
*gtk_store 
= wxgtk_list_store_new(); 
1776     gtk_store
->model 
= model
; 
1778     m_notifier 
= new wxGtkDataViewListModelNotifier( gtk_store
, model 
); 
1780     model
->AddNotifier( m_notifier 
); 
1782     gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_store
) ); 
1783     g_object_unref( gtk_store 
); 
1788 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn 
*col 
) 
1790     if (!wxDataViewCtrlBase::AppendColumn(col
)) 
1793     GtkTreeViewColumn 
*column 
= (GtkTreeViewColumn 
*)col
->GetGtkHandle(); 
1795     gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), column 
); 
1800 void wxDataViewCtrl::SetSelection( int row 
) 
1802     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1806         gtk_tree_selection_unselect_all( selection 
); 
1810         GtkTreePath 
*path 
= gtk_tree_path_new (); 
1811         gtk_tree_path_append_index( path
, row 
); 
1813         gtk_tree_selection_select_path( selection
, path 
); 
1815         gtk_tree_path_free( path 
); 
1819 void wxDataViewCtrl::Unselect( unsigned int row 
) 
1821     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1823     GtkTreePath 
*path 
= gtk_tree_path_new (); 
1824     gtk_tree_path_append_index( path
, row 
); 
1826     gtk_tree_selection_unselect_path( selection
, path 
); 
1828     gtk_tree_path_free( path 
); 
1831 void wxDataViewCtrl::SetSelectionRange( unsigned int from
, unsigned int to 
) 
1835 void wxDataViewCtrl::SetSelections( const wxArrayInt
& aSelections
) 
1839 bool wxDataViewCtrl::IsSelected( unsigned int row 
) const 
1841     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1843     GtkTreePath 
*path 
= gtk_tree_path_new (); 
1844     gtk_tree_path_append_index( path
, row 
); 
1846     gboolean ret 
=  gtk_tree_selection_path_is_selected( selection
, path 
); 
1848     gtk_tree_path_free( path 
); 
1853 int wxDataViewCtrl::GetSelection() const 
1855     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1856     if (HasFlag(wxDV_MULTIPLE
)) 
1858         GtkTreeModel 
*model
; 
1859         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
1864             // list = g_list_nth( list, 0 );  should be a noop 
1865             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
1867             unsigned int row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
1870             g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
1871             g_list_free( list 
); 
1879         GtkTreeModel 
*model
; 
1881         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
1884             unsigned int row 
= (wxUIntPtr
) iter
.user_data
; 
1892 int wxDataViewCtrl::GetSelections(wxArrayInt
& aSelections
) const 
1894     aSelections
.Clear(); 
1896     GtkTreeSelection 
*selection 
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) ); 
1897     if (HasFlag(wxDV_MULTIPLE
)) 
1899         GtkTreeModel 
*model
; 
1900         GList 
*list 
= gtk_tree_selection_get_selected_rows( selection
, &model 
); 
1906             // list = g_list_nth( list, 0 );  should be a noop 
1907             GtkTreePath 
*path 
= (GtkTreePath
*) list
->data
; 
1909             unsigned int row 
= (unsigned int)gtk_tree_path_get_indices (path
)[0]; 
1911             aSelections
.Add( (int) row 
); 
1913             list 
= g_list_next( list 
);             
1917         g_list_foreach( list
, (GFunc
) gtk_tree_path_free
, NULL 
); 
1918         g_list_free( list 
); 
1924         GtkTreeModel 
*model
; 
1926         gboolean has_selection 
= gtk_tree_selection_get_selected( selection
, &model
, &iter 
); 
1929             unsigned int row 
= (wxUIntPtr
) iter
.user_data
; 
1930             aSelections
.Add( (int) row 
); 
1940 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
1942     return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
); 
1947     // !wxUSE_GENERICDATAVIEWCTRL 
1950     // wxUSE_DATAVIEWCTRL