Warning, file /plasma/oxygen-gtk/src/oxygengtkcellinfo.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 this file is part of the oxygen gtk engine 0003 SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "oxygengtkcellinfo.h" 0009 #include "oxygengeometry.h" 0010 #include "oxygengtkutils.h" 0011 0012 #include <iostream> 0013 #include <cassert> 0014 0015 namespace Oxygen 0016 { 0017 0018 //____________________________________________________________________________ 0019 Gtk::CellInfo::CellInfo( GtkTreeView* treeView, int x, int y, int w, int h ): 0020 _path(0L), 0021 _column(-1) 0022 { 0023 GtkTreeViewColumn *column( 0L ); 0024 0025 /* 0026 four attempts are made to get the path from any corner of the rectangle passed in arguments. 0027 This is necessary to handle half-hidden cells 0028 */ 0029 gtk_tree_view_get_path_at_pos( treeView, (gint)x+1, (gint)y+1, &_path, &column, 0L, 0L ); 0030 if( !_path ) { 0031 gtk_tree_view_get_path_at_pos( treeView, (gint)x+1, (gint)y+h-1, &_path, &column, 0L, 0L ); 0032 if( !_path ) { 0033 gtk_tree_view_get_path_at_pos( treeView, (gint)x+w-1, (gint)y+1, &_path, &column, 0L, 0L ); 0034 if( !_path ) { 0035 gtk_tree_view_get_path_at_pos( treeView, (gint)x+w-1, (gint)y+h-1, &_path, &column, 0L, 0L ); 0036 if( !_path ) return; 0037 } 0038 } 0039 } 0040 0041 _column = indexOfColumn( treeView, column ); 0042 } 0043 0044 //____________________________________________________________________________ 0045 bool Gtk::CellInfo::isLastVisibleColumn( GtkTreeView* treeView ) const 0046 { 0047 bool isLast( true ); 0048 GList* columns( gtk_tree_view_get_columns( treeView ) ); 0049 for( GList *child = g_list_nth( columns, _column ); ( child = g_list_next( child ) ); ) 0050 { 0051 if( !GTK_IS_TREE_VIEW_COLUMN( child->data ) ) continue; 0052 GtkTreeViewColumn* column( GTK_TREE_VIEW_COLUMN( child->data ) ); 0053 if( gtk_tree_view_column_get_visible( column ) ) 0054 { 0055 isLast = false; 0056 break; 0057 } 0058 0059 } 0060 0061 if( columns ) g_list_free( columns ); 0062 return isLast; 0063 } 0064 0065 //____________________________________________________________________________ 0066 bool Gtk::CellInfo::isFirstVisibleColumn( GtkTreeView* treeView ) const 0067 { 0068 bool isFirst( true ); 0069 GList* columns( gtk_tree_view_get_columns( treeView ) ); 0070 for( GList *child = g_list_nth( columns, _column ); ( child = g_list_previous( child ) ); ) 0071 { 0072 if( !GTK_IS_TREE_VIEW_COLUMN( child->data ) ) continue; 0073 GtkTreeViewColumn* column( GTK_TREE_VIEW_COLUMN( child->data ) ); 0074 if( gtk_tree_view_column_get_visible( column ) ) 0075 { 0076 isFirst = false; 0077 break; 0078 } 0079 0080 } 0081 0082 if( columns ) g_list_free( columns ); 0083 return isFirst; 0084 } 0085 0086 //____________________________________________________________________________ 0087 bool Gtk::CellInfo::isLeftOfExpanderColumn( GtkTreeView* treeView ) const 0088 { 0089 // check expander column 0090 GtkTreeViewColumn* expanderColumn( gtk_tree_view_get_expander_column( treeView ) ); 0091 return expanderColumn && _column < indexOfColumn( treeView, expanderColumn ); 0092 0093 } 0094 0095 //____________________________________________________________________________ 0096 bool Gtk::CellInfo::hasParent( GtkTreeView* treeView ) const 0097 { 0098 // check treeview and path 0099 if( !( treeView && _path ) ) return false; 0100 0101 // get model 0102 GtkTreeModel* model( gtk_tree_view_get_model( treeView ) ); 0103 if( !model ) return false; 0104 0105 // get iterator 0106 GtkTreeIter iter; 0107 if( !gtk_tree_model_get_iter( model, &iter, _path ) ) return false; 0108 0109 GtkTreeIter parent; 0110 return gtk_tree_model_iter_parent( model, &parent, &iter ); 0111 0112 } 0113 0114 //____________________________________________________________________________ 0115 Gtk::CellInfo Gtk::CellInfo::parent( void ) const 0116 { 0117 CellInfo out; 0118 out._column = _column; 0119 0120 // check path 0121 if( !_path ) return out; 0122 0123 GtkTreePath* parent( gtk_tree_path_copy( _path ) ); 0124 if( gtk_tree_path_up( parent ) ) out._path = parent; 0125 else gtk_tree_path_free( parent ); 0126 0127 return out; 0128 0129 } 0130 0131 //____________________________________________________________________________ 0132 bool Gtk::CellInfo::hasChildren( GtkTreeView* treeView ) const 0133 { 0134 // check treeview and path 0135 if( !( treeView && _path ) ) return false; 0136 0137 // get model 0138 GtkTreeModel* model( gtk_tree_view_get_model( treeView ) ); 0139 if( !model ) return false; 0140 0141 // get iterator 0142 GtkTreeIter iter; 0143 if( !gtk_tree_model_get_iter( model, &iter, _path ) ) return false; 0144 return gtk_tree_model_iter_has_child( model, &iter ); 0145 0146 } 0147 0148 //____________________________________________________________________________ 0149 bool Gtk::CellInfo::isLast( GtkTreeView* treeView ) const 0150 { 0151 // check treeview and path 0152 if( !( treeView && _path ) ) return false; 0153 0154 // get model 0155 GtkTreeModel* model( gtk_tree_view_get_model( treeView ) ); 0156 if( !model ) return false; 0157 0158 // get iterator 0159 GtkTreeIter iter; 0160 if( !gtk_tree_model_get_iter( model, &iter, _path ) ) return false; 0161 return !gtk_tree_model_iter_next( model, &iter ); 0162 } 0163 0164 //____________________________________________________________________________ 0165 GdkRectangle Gtk::CellInfo::backgroundRect( GtkTreeView* treeView ) const 0166 { 0167 GdkRectangle out( Gtk::gdk_rectangle() ); 0168 if( treeView && isValid() ) 0169 { gtk_tree_view_get_background_area( treeView, _path, gtk_tree_view_get_column( treeView, _column ), &out ); } 0170 0171 return out; 0172 0173 } 0174 0175 //____________________________________________________________________________ 0176 gint Gtk::CellInfo::indexOfColumn( GtkTreeView* treeView, GtkTreeViewColumn* column ) 0177 { 0178 GList* columns( gtk_tree_view_get_columns( treeView ) ); 0179 if( !columns ) return -1; 0180 gint index( g_list_index( columns, column ) ); 0181 g_list_free( columns ); 0182 return index; 0183 } 0184 0185 //____________________________________________________________________________ 0186 Gtk::CellInfoFlags::CellInfoFlags( GtkTreeView* treeView, const CellInfo& cellInfo ): 0187 _depth( cellInfo.depth() ), 0188 _expanderSize(0), 0189 _levelIndent(gtk_tree_view_get_level_indentation(treeView)) 0190 { 0191 if( cellInfo.hasParent( treeView ) ) _flags |= HasParent; 0192 if( cellInfo.hasChildren( treeView ) ) _flags |= HasChildren; 0193 if( cellInfo.isLast( treeView ) ) _flags |= IsLast; 0194 0195 gtk_widget_style_get( GTK_WIDGET( treeView ), "expander-size", &_expanderSize, NULL ); 0196 0197 /* 0198 for every parent of the current cell, one needs to know whether or not 0199 it is the last one at its level, to render the tree lines properly 0200 */ 0201 _isLast = std::vector<bool>(_depth, false); 0202 0203 int index( _depth-1 ); 0204 for( CellInfo parent = cellInfo; parent.isValid() && parent.depth() > 0; parent = parent.parent() ) 0205 { 0206 assert( index >= 0 ); 0207 _isLast[index] = parent.isLast( treeView ); 0208 --index; 0209 } 0210 0211 } 0212 0213 }