talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 07f70e41a3ab138ff466839067eee4bea0c98022
parent a2cc09350747a90ea58d331208330eed3cb1b607
Author: Colin Leroy <colin@colino.net>
Date:   Sun, 23 Oct 2011 20:50:48 +0000

2011-10-23 [colin]	3.7.10cvs44

	* src/addressadd.c
	* src/addressbook.c
	* src/addressbook_foldersel.c
	* src/editgroup.c
	* src/foldersel.c
	* src/folderview.c
	* src/grouplistdialog.c
	* src/prefs_common.c
	* src/prefs_common.h
	* src/summaryview.c
	* src/gtk/gtkcmclist.c
	* src/gtk/gtkcmclist.h
	* src/gtk/gtkcmctree.c
	* src/gtk/gtkcmctree.h
	* src/gtk/gtksctree.c
		Refactor some tree stuff (lots of code duplication there)
		and switch to cairo for tree rendering.

Diffstat:
MChangeLog | 20++++++++++++++++++++
MPATCHSETS | 1+
Mconfigure.ac | 2+-
Msrc/addressadd.c | 10++--------
Msrc/addressbook.c | 26+++++++-------------------
Msrc/addressbook_foldersel.c | 12+++---------
Msrc/editgroup.c | 24++++++------------------
Msrc/foldersel.c | 3+--
Msrc/folderview.c | 14++++----------
Msrc/grouplistdialog.c | 14++++----------
Msrc/gtk/gtkcmclist.c | 6+++---
Msrc/gtk/gtkcmclist.h | 7-------
Msrc/gtk/gtkcmctree.c | 2770++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/gtk/gtkcmctree.h | 11++---------
Msrc/gtk/gtksctree.c | 1234+------------------------------------------------------------------------------
Msrc/prefs_common.c | 2--
Msrc/prefs_common.h | 1-
Msrc/summaryview.c | 14++++----------
18 files changed, 1172 insertions(+), 2999 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,23 @@ +2011-10-23 [colin] 3.7.10cvs44 + + * src/addressadd.c + * src/addressbook.c + * src/addressbook_foldersel.c + * src/editgroup.c + * src/foldersel.c + * src/folderview.c + * src/grouplistdialog.c + * src/prefs_common.c + * src/prefs_common.h + * src/summaryview.c + * src/gtk/gtkcmclist.c + * src/gtk/gtkcmclist.h + * src/gtk/gtkcmctree.c + * src/gtk/gtkcmctree.h + * src/gtk/gtksctree.c + Refactor some tree stuff (lots of code duplication there) + and switch to cairo for tree rendering. + 2011-10-23 [holger] 3.7.10cvs43 * src/filtering.c diff --git a/PATCHSETS b/PATCHSETS @@ -4247,3 +4247,4 @@ ( cvs diff -u -r 1.61.2.100 -r 1.61.2.101 src/account.c; cvs diff -u -r 1.27.2.57 -r 1.27.2.58 src/addr_compl.c; cvs diff -u -r 1.5.10.35 -r 1.5.10.36 src/addrgather.c; cvs diff -u -r 1.382.2.586 -r 1.382.2.587 src/compose.c; cvs diff -u -r 1.8.2.42 -r 1.8.2.43 src/editldap.c; cvs diff -u -r 1.1.4.34 -r 1.1.4.35 src/expldifdlg.c; cvs diff -u -r 1.207.2.222 -r 1.207.2.223 src/folderview.c; cvs diff -u -r 1.14.2.30 -r 1.14.2.31 src/grouplistdialog.c; cvs diff -u -r 1.8.2.33 -r 1.8.2.34 src/headerview.c; cvs diff -u -r 1.14.2.27 -r 1.14.2.28 src/importldif.c; cvs diff -u -r 1.115.2.242 -r 1.115.2.243 src/main.c; cvs diff -u -r 1.274.2.331 -r 1.274.2.332 src/mainwindow.c; cvs diff -u -r 1.83.2.173 -r 1.83.2.174 src/mimeview.c; cvs diff -u -r 1.5.2.26 -r 1.5.2.27 src/noticeview.c; cvs diff -u -r 1.105.2.169 -r 1.105.2.170 src/prefs_account.c; cvs diff -u -r 1.60.2.74 -r 1.60.2.75 src/prefs_actions.c; cvs diff -u -r 1.3.2.26 -r 1.3.2.27 src/prefs_ext_prog.c; cvs diff -u -r 1.59.2.83 -r 1.59.2.84 src/prefs_filtering.c; cvs diff -u -r 1.52.2.84 -r 1.52.2.85 src/prefs_folder_item.c; cvs diff -u -r 1.1.2.16 -r 1.1.2.17 src/prefs_image_viewer.c; cvs diff -u -r 1.1.2.20 -r 1.1.2.21 src/prefs_logging.c; cvs diff -u -r 1.1.2.45 -r 1.1.2.46 src/prefs_msg_colors.c; cvs diff -u -r 1.1.2.43 -r 1.1.2.44 src/prefs_other.c; cvs diff -u -r 1.1.2.28 -r 1.1.2.29 src/prefs_send.c; cvs diff -u -r 1.5.2.42 -r 1.5.2.43 src/prefs_spelling.c; cvs diff -u -r 1.1.2.68 -r 1.1.2.69 src/prefs_summaries.c; cvs diff -u -r 1.12.2.76 -r 1.12.2.77 src/prefs_template.c; cvs diff -u -r 1.1.2.34 -r 1.1.2.35 src/printing.c; cvs diff -u -r 1.8.2.44 -r 1.8.2.45 src/quote_fmt.c; cvs diff -u -r 1.17.2.60 -r 1.17.2.61 src/send_message.c; cvs diff -u -r 1.5.2.30 -r 1.5.2.31 src/statusbar.c; cvs diff -u -r 1.15.2.67 -r 1.15.2.68 src/summary_search.c; cvs diff -u -r 1.395.2.432 -r 1.395.2.433 src/summaryview.c; cvs diff -u -r 1.1.2.85 -r 1.1.2.86 src/wizard.c; cvs diff -u -r 1.1.2.17 -r 1.1.2.18 src/gtk/gtkcmclist.c; cvs diff -u -r 1.1.2.19 -r 1.1.2.20 src/gtk/gtkcmctree.c; cvs diff -u -r 1.1.2.8 -r 1.1.2.9 src/gtk/gtkcmoptionmenu.c; cvs diff -u -r 1.1.4.61 -r 1.1.4.62 src/gtk/gtksctree.c; cvs diff -u -r 1.5.2.99 -r 1.5.2.100 src/gtk/gtkutils.c; cvs diff -u -r 1.4.2.62 -r 1.4.2.63 src/gtk/gtkutils.h; cvs diff -u -r 1.5.2.22 -r 1.5.2.23 src/gtk/gtkvscrollbutton.c; cvs diff -u -r 1.2.2.44 -r 1.2.2.45 src/gtk/inputdialog.c; cvs diff -u -r 1.5.2.60 -r 1.5.2.61 src/gtk/pluginwindow.c; cvs diff -u -r 1.1.2.105 -r 1.1.2.106 src/gtk/quicksearch.c; cvs diff -u -r 1.1.2.12 -r 1.1.2.13 src/gtk/spell_entry.c; cvs diff -u -r 1.1.2.39 -r 1.1.2.40 src/plugins/bogofilter/bogofilter_gtk.c; cvs diff -u -r 1.5.2.26 -r 1.5.2.27 src/plugins/dillo_viewer/dillo_prefs.c; cvs diff -u -r 1.1.2.35 -r 1.1.2.36 src/plugins/pgpcore/prefs_gpg.c; cvs diff -u -r 1.23.2.56 -r 1.23.2.57 src/plugins/spamassassin/spamassassin_gtk.c; cvs diff -u -r 1.14.2.78 -r 1.14.2.79 src/plugins/trayicon/trayicon.c; cvs diff -u -r 1.1.2.9 -r 1.1.2.10 src/plugins/trayicon/trayicon_prefs.c; ) > 3.7.10cvs41.patchset ( cvs diff -u -r 1.1.2.35 -r 1.1.2.36 src/printing.c; cvs diff -u -r 1.1.4.20 -r 1.1.4.21 src/gtk/gtkshruler.c; cvs diff -u -r 1.4.2.63 -r 1.4.2.64 src/gtk/gtkutils.h; ) > 3.7.10cvs42.patchset ( cvs diff -u -r 1.60.2.57 -r 1.60.2.58 src/filtering.c; ) > 3.7.10cvs43.patchset +( cvs diff -u -r 1.9.2.33 -r 1.9.2.34 src/addressadd.c; cvs diff -u -r 1.60.2.145 -r 1.60.2.146 src/addressbook.c; cvs diff -u -r 1.1.2.20 -r 1.1.2.21 src/addressbook_foldersel.c; cvs diff -u -r 1.11.2.27 -r 1.11.2.28 src/editgroup.c; cvs diff -u -r 1.26.2.47 -r 1.26.2.48 src/foldersel.c; cvs diff -u -r 1.207.2.223 -r 1.207.2.224 src/folderview.c; cvs diff -u -r 1.14.2.31 -r 1.14.2.32 src/grouplistdialog.c; cvs diff -u -r 1.204.2.202 -r 1.204.2.203 src/prefs_common.c; cvs diff -u -r 1.103.2.133 -r 1.103.2.134 src/prefs_common.h; cvs diff -u -r 1.395.2.433 -r 1.395.2.434 src/summaryview.c; cvs diff -u -r 1.1.2.18 -r 1.1.2.19 src/gtk/gtkcmclist.c; cvs diff -u -r 1.1.2.6 -r 1.1.2.7 src/gtk/gtkcmclist.h; cvs diff -u -r 1.1.2.20 -r 1.1.2.21 src/gtk/gtkcmctree.c; cvs diff -u -r 1.1.2.4 -r 1.1.2.5 src/gtk/gtkcmctree.h; cvs diff -u -r 1.1.4.62 -r 1.1.4.63 src/gtk/gtksctree.c; ) > 3.7.10cvs44.patchset diff --git a/configure.ac b/configure.ac @@ -12,7 +12,7 @@ MINOR_VERSION=7 MICRO_VERSION=10 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=43 +EXTRA_VERSION=44 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/addressadd.c b/src/addressadd.c @@ -233,15 +233,9 @@ static void addressadd_create( void ) { tree_folder = gtk_sctree_new_with_titles( 1, 0, titles ); gtk_container_add( GTK_CONTAINER(tree_win), tree_folder ); gtk_cmclist_column_titles_show( GTK_CMCLIST(tree_folder) ); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(tree_folder), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(tree_folder), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(tree_folder), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(tree_folder), + gtk_cmctree_set_line_style(GTK_CMCTREE(tree_folder), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(tree_folder), GTK_CMCTREE_EXPANDER_TRIANGLE); - } gtk_sctree_set_stripes(GTK_SCTREE(tree_folder), prefs_common.use_stripes_everywhere); gtk_cmclist_set_selection_mode( GTK_CMCLIST(tree_folder), GTK_SELECTION_BROWSE ); gtk_cmctree_set_indent( GTK_CMCTREE(tree_folder), CTREE_INDENT ); diff --git a/src/addressbook.c b/src/addressbook.c @@ -1019,15 +1019,9 @@ static void addressbook_create(void) gtk_container_add(GTK_CONTAINER(ctree_swin), ctree); gtk_cmclist_set_selection_mode(GTK_CMCLIST(ctree), GTK_SELECTION_BROWSE); gtk_cmclist_set_column_width(GTK_CMCLIST(ctree), 0, COL_FOLDER_WIDTH); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), + GTK_CMCTREE_EXPANDER_TRIANGLE); gtk_sctree_set_stripes(GTK_SCTREE(ctree), prefs_common.use_stripes_in_summaries); gtk_cmctree_set_indent(GTK_CMCTREE(ctree), CTREE_INDENT); gtk_cmclist_set_compare_func(GTK_CMCLIST(ctree), @@ -1074,15 +1068,9 @@ static void addressbook_create(void) clist = gtk_sctree_new_with_titles(N_LIST_COLS, 0, list_titles); gtk_container_add(GTK_CONTAINER(clist_swin), clist); gtk_cmclist_set_selection_mode(GTK_CMCLIST(clist), GTK_SELECTION_EXTENDED); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(clist), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(clist), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(clist), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(clist), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(clist), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(clist), + GTK_CMCTREE_EXPANDER_TRIANGLE); gtk_sctree_set_stripes(GTK_SCTREE(ctree), prefs_common.use_stripes_in_summaries); gtk_cmctree_set_indent(GTK_CMCTREE(clist), CTREE_INDENT); gtk_cmclist_set_column_width(GTK_CMCLIST(clist), COL_NAME, @@ -2743,7 +2731,7 @@ static void addressbook_change_node_name(GtkCMCTreeNode *node, const gchar *name gtk_cmctree_get_node_info(ctree, node, text, &spacing, &pix_cl, &pix_op, &is_leaf, &expanded); - gtk_sctree_set_node_info(ctree, node, name, spacing, + gtk_cmctree_set_node_info(ctree, node, name, spacing, pix_cl, pix_op, is_leaf, expanded); } diff --git a/src/addressbook_foldersel.c b/src/addressbook_foldersel.c @@ -183,15 +183,9 @@ static void addressbook_foldersel_create( void ) tree_folder = gtk_sctree_new_with_titles( 1, 0, titles ); gtk_container_add( GTK_CONTAINER(tree_win), tree_folder ); gtk_cmclist_column_titles_show( GTK_CMCLIST(tree_folder) ); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(tree_folder), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(tree_folder), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(tree_folder), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(tree_folder), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(tree_folder), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(tree_folder), + GTK_CMCTREE_EXPANDER_TRIANGLE); gtk_sctree_set_stripes(GTK_SCTREE(tree_folder), prefs_common.use_stripes_everywhere); gtk_cmclist_set_selection_mode( GTK_CMCLIST(tree_folder), GTK_SELECTION_BROWSE ); gtk_cmctree_set_indent( GTK_CMCTREE(tree_folder), CTREE_INDENT ); diff --git a/src/editgroup.c b/src/editgroup.c @@ -351,15 +351,9 @@ static void addressbook_edit_group_create( gboolean *cancelled ) { clist_group = gtk_sctree_new_with_titles( GROUP_N_COLS, 0, titles ); gtk_container_add( GTK_CONTAINER(clist_swin), clist_group ); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(clist_group), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(clist_group), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(clist_group), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(clist_group), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(clist_group), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(clist_group), + GTK_CMCTREE_EXPANDER_TRIANGLE); gtk_sctree_set_stripes(GTK_SCTREE(clist_group), prefs_common.use_stripes_in_summaries); gtk_cmclist_set_selection_mode( GTK_CMCLIST(clist_group), GTK_SELECTION_EXTENDED ); gtk_cmclist_set_column_width( GTK_CMCLIST(clist_group), GROUP_COL_NAME, GROUP_COL_WIDTH_NAME ); @@ -390,15 +384,9 @@ static void addressbook_edit_group_create( gboolean *cancelled ) { clist_avail = gtk_sctree_new_with_titles( GROUP_N_COLS, 0, titles ); gtk_container_add( GTK_CONTAINER(clist_swin), clist_avail ); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(clist_avail), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(clist_avail), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(clist_avail), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(clist_avail), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(clist_avail), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(clist_avail), + GTK_CMCTREE_EXPANDER_TRIANGLE); gtk_cmclist_set_selection_mode( GTK_CMCLIST(clist_avail), GTK_SELECTION_EXTENDED ); gtk_cmclist_set_column_width( GTK_CMCLIST(clist_avail), GROUP_COL_NAME, GROUP_COL_WIDTH_NAME ); gtk_cmclist_set_column_width( GTK_CMCLIST(clist_avail), GROUP_COL_EMAIL, GROUP_COL_WIDTH_EMAIL ); diff --git a/src/foldersel.c b/src/foldersel.c @@ -261,8 +261,7 @@ static void foldersel_create(void) gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), prefs_common.use_stripes_everywhere); - gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(treeview), - prefs_common.enable_dotted_lines); + gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(treeview), FALSE); gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), FOLDERSEL_FOLDERNAME); diff --git a/src/folderview.c b/src/folderview.c @@ -445,15 +445,9 @@ static GtkWidget *folderview_ctree_create(FolderView *folderview) gtk_cmclist_set_column_justification(GTK_CMCLIST(ctree), col_pos[F_COL_TOTAL], GTK_JUSTIFY_RIGHT); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), + GTK_CMCTREE_EXPANDER_TRIANGLE); gtk_sctree_set_stripes(GTK_SCTREE(ctree), prefs_common.use_stripes_in_summaries); gtk_sctree_set_recursive_expand(GTK_SCTREE(ctree), FALSE); @@ -1595,7 +1589,7 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node) str = g_strdup_printf("%s", name); } } - gtk_sctree_set_node_info(ctree, node, str, FOLDER_SPACING, + gtk_cmctree_set_node_info(ctree, node, str, FOLDER_SPACING, xpm, openxpm, FALSE, GTK_CMCTREE_ROW(node)->expanded); g_free(str); diff --git a/src/grouplistdialog.c b/src/grouplistdialog.c @@ -211,15 +211,9 @@ static void grouplist_dialog_create(void) gtk_cmclist_set_column_auto_resize(GTK_CMCLIST(ctree), 0, TRUE); gtk_cmclist_set_selection_mode(GTK_CMCLIST(ctree), GTK_SELECTION_MULTIPLE); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), + GTK_CMCTREE_EXPANDER_TRIANGLE); for (i = 0; i < 3; i++) gtkut_widget_set_can_focus(GTK_CMCLIST(ctree)->column[i].button, FALSE); @@ -360,7 +354,7 @@ static GtkCMCTreeNode *grouplist_create_branch(NewsGroupInfo *ginfo, parent = grouplist_create_parent(parent_name, pattern); node = grouplist_hash_get_branch_node(name); if (node) { - gtk_sctree_set_node_info(GTK_CMCTREE(ctree), node, cols[0], 0, + gtk_cmctree_set_node_info(GTK_CMCTREE(ctree), node, cols[0], 0, NULL, NULL, FALSE, FALSE); gtk_cmctree_node_set_text(GTK_CMCTREE(ctree), node, 1, cols[1]); gtk_cmctree_node_set_text(GTK_CMCTREE(ctree), node, 2, cols[2]); diff --git a/src/gtk/gtkcmclist.c b/src/gtk/gtkcmclist.c @@ -3134,17 +3134,17 @@ gtk_cmclist_set_row_height (GtkCMCList *clist, metrics = pango_context_get_metrics (context, style->font_desc, pango_context_get_language (context)); - + if (!GTK_CMCLIST_ROW_HEIGHT_SET(clist)) { clist->row_height = (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)); - clist->row_height = PANGO_PIXELS (clist->row_height); + clist->row_height = PANGO_PIXELS (clist->row_height) + 2; } pango_font_metrics_unref (metrics); } - + CLIST_REFRESH (clist); } diff --git a/src/gtk/gtkcmclist.h b/src/gtk/gtkcmclist.h @@ -206,13 +206,6 @@ struct _GtkCMCList GtkAdjustment *hadjustment; GtkAdjustment *vadjustment; - /* xor GC for the vertical drag line */ - GdkGC *xor_gc; - - /* gc for drawing unselected cells */ - GdkGC *fg_gc; - GdkGC *bg_gc; - /* cursor used to indicate dragging */ GdkCursor *cursor_drag; diff --git a/src/gtk/gtkcmctree.c b/src/gtk/gtkcmctree.c @@ -80,9 +80,6 @@ gtk_cmctree_line_style_get_type (void) if (etype == 0) { static const GEnumValue values[] = { { GTK_CMCTREE_LINES_NONE, "GTK_CMCTREE_LINES_NONE", "none" }, - { GTK_CMCTREE_LINES_SOLID, "GTK_CMCTREE_LINES_SOLID", "solid" }, - { GTK_CMCTREE_LINES_DOTTED, "GTK_CMCTREE_LINES_DOTTED", "dotted" }, - { GTK_CMCTREE_LINES_TABBED, "GTK_CMCTREE_LINES_TABBED", "tabbed" }, { 0, NULL, NULL } }; #if GLIB_CHECK_VERSION(2,10,0) @@ -100,9 +97,7 @@ gtk_cmctree_expander_style_get_type (void) if (etype == 0) { static const GEnumValue values[] = { { GTK_CMCTREE_EXPANDER_NONE, "GTK_CMCTREE_EXPANDER_NONE", "none" }, - { GTK_CMCTREE_EXPANDER_SQUARE, "GTK_CMCTREE_EXPANDER_SQUARE", "square" }, { GTK_CMCTREE_EXPANDER_TRIANGLE, "GTK_CMCTREE_EXPANDER_TRIANGLE", "triangle" }, - { GTK_CMCTREE_EXPANDER_CIRCULAR, "GTK_CMCTREE_EXPANDER_CIRCULAR", "circular" }, { 0, NULL, NULL } }; #if GLIB_CHECK_VERSION(2,10,0) @@ -199,46 +194,10 @@ static void ctree_attach_styles (GtkCMCTree *ctree, static void ctree_detach_styles (GtkCMCTree *ctree, GtkCMCTreeNode *node, gpointer data); -static gint draw_cell_pixbuf (GdkWindow *window, - GdkRectangle *clip_rectangle, - GdkGC *fg_gc, - GdkPixbuf *pixbuf, - gint x, - gint y, - gint width, - gint height); -static void get_cell_style (GtkCMCList *clist, - GtkCMCListRow *clist_row, - gint state, - gint column, - GtkStyle **style, - GdkGC **fg_gc, - GdkGC **bg_gc); -static gint gtk_cmctree_draw_expander (GtkCMCTree *ctree, - GtkCMCTreeRow *ctree_row, - GtkStyle *style, - GdkRectangle *clip_rectangle, - gint x); -static gint gtk_cmctree_draw_lines (GtkCMCTree *ctree, - GtkCMCTreeRow *ctree_row, - gint row, - gint column, - gint state, - GdkRectangle *clip_rectangle, - GdkRectangle *cell_rectangle, - GdkRectangle *crect, - GdkRectangle *area, - GtkStyle *style); -static void draw_row (GtkCMCList *clist, - GdkRectangle *area, - gint row, - GtkCMCListRow *clist_row); static void draw_drag_highlight (GtkCMCList *clist, GtkCMCListRow *dest_row, gint dest_row_number, GtkCMCListDragPos drag_pos); -static void tree_draw_node (GtkCMCTree *ctree, - GtkCMCTreeNode *node); static void set_cell_contents (GtkCMCList *clist, GtkCMCListRow *clist_row, gint column, @@ -430,1740 +389,1263 @@ gtk_cmctree_get_type (void) return ctree_type; } -static void -gtk_cmctree_class_init (GtkCMCTreeClass *klass) +static gint +draw_cell_pixbuf (GdkWindow *window, + GdkRectangle *clip_rectangle, + cairo_t *cr, + GdkPixbuf *pixbuf, + gint x, + gint y, + gint width, + gint height) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkCMCListClass *clist_class; - GtkBindingSet *binding_set; + gint xsrc = 0; + gint ysrc = 0; - gobject_class->constructor = gtk_cmctree_constructor; + if (!pixbuf || (width == 0 && height == 0)) + return x; - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - container_class = (GtkContainerClass *) klass; - clist_class = (GtkCMCListClass *) klass; + if (x < clip_rectangle->x) + { + xsrc = clip_rectangle->x - x; + width -= xsrc; + x = clip_rectangle->x; + } + if (x + width > clip_rectangle->x + clip_rectangle->width) + width = clip_rectangle->x + clip_rectangle->width - x; - parent_class = g_type_class_peek (GTK_TYPE_CMCLIST); - container_class = g_type_class_peek (GTK_TYPE_CONTAINER); + if (y < clip_rectangle->y) + { + ysrc = clip_rectangle->y - y; + height -= ysrc; + y = clip_rectangle->y; + } - gobject_class->set_property = gtk_cmctree_set_arg; - gobject_class->get_property = gtk_cmctree_get_arg; + if (y + height > clip_rectangle->y + clip_rectangle->height) + height = clip_rectangle->y + clip_rectangle->height - y; - widget_class->realize = gtk_cmctree_realize; - widget_class->unrealize = gtk_cmctree_unrealize; - widget_class->button_press_event = gtk_cmctree_button_press; + gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); + cairo_paint(cr); - widget_class->drag_begin = gtk_cmctree_drag_begin; - widget_class->drag_motion = gtk_cmctree_drag_motion; - widget_class->drag_data_received = gtk_cmctree_drag_data_received; + return x + MAX (width, 0); +} - clist_class->select_row = real_select_row; - clist_class->unselect_row = real_unselect_row; - clist_class->row_move = real_row_move; - clist_class->undo_selection = real_undo_selection; - clist_class->resync_selection = resync_selection; - clist_class->selection_find = selection_find; - clist_class->click_column = NULL; - clist_class->draw_row = draw_row; - clist_class->draw_drag_highlight = draw_drag_highlight; - clist_class->clear = real_clear; - clist_class->select_all = real_select_all; - clist_class->unselect_all = real_unselect_all; - clist_class->fake_unselect_all = fake_unselect_all; - clist_class->insert_row = real_insert_row; - clist_class->remove_row = real_remove_row; - clist_class->sort_list = real_sort_list; - clist_class->set_cell_contents = set_cell_contents; - clist_class->cell_size_request = cell_size_request; +static gint +draw_expander (GtkCMCTree *ctree, + GtkCMCTreeRow *ctree_row, + GtkStyle *style, + GdkRectangle *clip_rectangle, + cairo_t *cr, + gint x) +{ + GtkCMCList *clist; + GdkPoint points[3]; + gint justification_factor; + gint y; - klass->tree_select_row = real_tree_select; - klass->tree_unselect_row = real_tree_unselect; - klass->tree_expand = real_tree_expand; - klass->tree_collapse = real_tree_collapse; - klass->tree_move = real_tree_move; - klass->change_focus_row_expansion = change_focus_row_expansion; + if (ctree->expander_style == GTK_CMCTREE_EXPANDER_NONE) + return x; - g_object_class_install_property (gobject_class, - ARG_N_COLUMNS, - g_param_spec_uint ("n-columns", - "N-Columns", - "N-Columns", - 1, - G_MAXINT, - 1, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (gobject_class, - ARG_TREE_COLUMN, - g_param_spec_uint ("tree-column", - "tree-column", - "tree-column", - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (gobject_class, - ARG_INDENT, - g_param_spec_uint ("indent", - "indent", - "indent", - 1, - G_MAXINT, - 1, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - ARG_SPACING, - g_param_spec_uint ("spacing", - "spacing", - "spacing", - 1, - G_MAXINT, - 1, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - ARG_SHOW_STUB, - g_param_spec_boolean ("show-stub", - "show-stub", - "show-stub", - TRUE, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - ARG_LINE_STYLE, - g_param_spec_enum ("line-style", - "line-style", - "line-style", - GTK_TYPE_CMCTREE_LINE_STYLE, 0, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - ARG_EXPANDER_STYLE, - g_param_spec_enum ("expander-style", - "expander-style", - "expander-style", - GTK_TYPE_CMCTREE_EXPANDER_STYLE, 0, - G_PARAM_READWRITE)); + clist = GTK_CMCLIST (ctree); + if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) + justification_factor = -1; + else + justification_factor = 1; + if (!GTK_CMCLIST_ROW_HEIGHT_SET(GTK_CMCLIST(clist))) + y = (clip_rectangle->y + (clip_rectangle->height - PM_SIZE) / 2 - + (clip_rectangle->height + 1) % 2) + 1; + else + y = (clip_rectangle->y + (clip_rectangle->height/2 - PM_SIZE) / 2 - + (clip_rectangle->height/2 + 1) % 2) + 1; - ctree_signals[TREE_SELECT_ROW] = - g_signal_new ("tree_select_row", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkCMCTreeClass, tree_select_row), - NULL, NULL, - claws_marshal_VOID__POINTER_INT, - G_TYPE_NONE, 2, - GTK_TYPE_CMCTREE_NODE, - G_TYPE_INT); - ctree_signals[TREE_UNSELECT_ROW] = - g_signal_new ("tree_unselect_row", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkCMCTreeClass, tree_unselect_row), - NULL, NULL, - claws_marshal_VOID__POINTER_INT, - G_TYPE_NONE, 2, - GTK_TYPE_CMCTREE_NODE, - G_TYPE_INT); - ctree_signals[TREE_EXPAND] = - g_signal_new ("tree_expand", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkCMCTreeClass, tree_expand), - NULL, NULL, - claws_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - GTK_TYPE_CMCTREE_NODE); - ctree_signals[TREE_COLLAPSE] = - g_signal_new ("tree_collapse", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkCMCTreeClass, tree_collapse), - NULL, NULL, - claws_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - GTK_TYPE_CMCTREE_NODE); - ctree_signals[TREE_MOVE] = - g_signal_new ("tree_move", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkCMCTreeClass, tree_move), - NULL, NULL, - claws_marshal_VOID__POINTER_POINTER_POINTER, - G_TYPE_NONE, 3, - GTK_TYPE_CMCTREE_NODE,GTK_TYPE_CMCTREE_NODE,GTK_TYPE_CMCTREE_NODE); - ctree_signals[CHANGE_FOCUS_ROW_EXPANSION] = - g_signal_new ("change_focus_row_expansion", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GtkCMCTreeClass, change_focus_row_expansion), - NULL, NULL, - claws_marshal_VOID__ENUM, - G_TYPE_NONE, 1, GTK_TYPE_CMCTREE_EXPANSION_TYPE); + if (!ctree_row->children) + { + return x + justification_factor * (PM_SIZE + 3); + } - binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_plus, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_plus, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND_RECURSIVE); + if (ctree_row->expanded) + { + points[0].x = x; + points[0].y = y + (PM_SIZE + 2) / 6; + points[1].x = points[0].x + justification_factor * (PM_SIZE + 2); + points[1].y = points[0].y; + points[2].x = (points[0].x + + justification_factor * (PM_SIZE + 2) / 2); + points[2].y = y + 2 * (PM_SIZE + 2) / 3; + } + else + { + points[0].x = x + justification_factor * ((PM_SIZE + 2) / 6 + 2); + points[0].y = y - 1; + points[1].x = points[0].x; + points[1].y = points[0].y + (PM_SIZE + 2); + points[2].x = (points[0].x + + justification_factor * (2 * (PM_SIZE + 2) / 3 - 1)); + points[2].y = points[0].y + (PM_SIZE + 2) / 2; + } - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Add, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Add, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND_RECURSIVE); - - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_minus, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_COLLAPSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_minus, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, - GTK_CMCTREE_EXPANSION_COLLAPSE_RECURSIVE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Subtract, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_COLLAPSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Subtract, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, - GTK_CMCTREE_EXPANSION_COLLAPSE_RECURSIVE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_equal, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Equal, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Multiply, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_asterisk, 0, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Multiply, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, - GTK_CMCTREE_EXPANSION_TOGGLE_RECURSIVE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_asterisk, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - G_TYPE_ENUM, - GTK_CMCTREE_EXPANSION_TOGGLE_RECURSIVE); + + cairo_new_path(cr); + cairo_set_source_rgb(cr, 255, 255, 255); + cairo_set_line_width(cr, 1); + cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); + cairo_move_to(cr, points[0].x, points[0].y); + cairo_line_to(cr, points[1].x, points[1].y); + cairo_line_to(cr, points[2].x, points[2].y); + cairo_close_path(cr); + cairo_fill(cr); + + cairo_new_path(cr); + gdk_cairo_set_source_color(cr, &gtk_widget_get_style(ctree)->fg[GTK_STATE_NORMAL]); + cairo_set_line_width(cr, 1); + cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); + cairo_move_to(cr, points[0].x, points[0].y); + cairo_line_to(cr, points[1].x, points[1].y); + cairo_line_to(cr, points[2].x, points[2].y); + cairo_close_path(cr); + cairo_stroke(cr); + cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); + + x += justification_factor * (PM_SIZE + 3); + + return x; } -static void -gtk_cmctree_set_arg (GObject *object, - guint arg_id, - const GValue *value, - GParamSpec *spec) +static gint +get_offset(GtkCMCTree *ctree, + GtkCMCTreeRow *ctree_row, + gint column, + GdkRectangle *clip_rectangle) { - GtkCMCTree *ctree; - GtkCMCList *clist; + gint justify_right; + justify_right = (GTK_CMCLIST (ctree)->column[column].justification == GTK_JUSTIFY_RIGHT); - ctree = GTK_CMCTREE (object); - clist = GTK_CMCLIST (ctree); + if (justify_right) + return (clip_rectangle->x + clip_rectangle->width - 1 - + ctree->tree_indent * (ctree_row->level - 1)); - switch (arg_id) - { - case ARG_N_COLUMNS: /* construct-only arg, only set at construction time */ -#if !GLIB_CHECK_VERSION(2,10,0) - cm_return_if_fail (clist->row_mem_chunk == NULL); -#endif - clist->columns = MAX (1, g_value_get_uint (value)); -#if !GLIB_CHECK_VERSION(2,10,0) - clist->row_mem_chunk = g_mem_chunk_new ("ctree row mem chunk", - sizeof (GtkCMCTreeRow), - sizeof (GtkCMCTreeRow) - * CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); - clist->cell_mem_chunk = g_mem_chunk_new ("ctree cell mem chunk", - sizeof (GtkCMCell) * clist->columns, - sizeof (GtkCMCell) * clist->columns - * CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); -#endif - ctree->tree_column = CLAMP (ctree->tree_column, 0, clist->columns); - break; - case ARG_TREE_COLUMN: /* construct-only arg, only set at construction time */ - ctree->tree_column = g_value_get_uint (value); -#if !GLIB_CHECK_VERSION(2,10,0) - if (clist->row_mem_chunk) -#endif - ctree->tree_column = CLAMP (ctree->tree_column, 0, clist->columns); - break; - case ARG_INDENT: - gtk_cmctree_set_indent (ctree, g_value_get_uint (value)); - break; - case ARG_SPACING: - gtk_cmctree_set_spacing (ctree, g_value_get_uint (value)); - break; - case ARG_SHOW_STUB: - gtk_cmctree_set_show_stub (ctree, g_value_get_boolean (value)); - break; - case ARG_LINE_STYLE: - gtk_cmctree_set_line_style (ctree, g_value_get_enum (value)); - break; - case ARG_EXPANDER_STYLE: - gtk_cmctree_set_expander_style (ctree, g_value_get_enum (value)); - break; - default: - break; - } + return clip_rectangle->x + ctree->tree_indent * (ctree_row->level - 1); } -static void -gtk_cmctree_get_arg (GObject *object, - guint arg_id, - GValue *value, - GParamSpec *spec) + static void +get_cell_style (GtkCMCList *clist, + GtkCMCListRow *clist_row, + gint state, + gint column, + GtkStyle **style) { - GtkCMCTree *ctree; + GtkStyle *gtkstyle; - ctree = GTK_CMCTREE (object); + gtkstyle = gtk_widget_get_style (GTK_WIDGET (clist)); - switch (arg_id) + if (clist_row->cell[column].style) { - case ARG_N_COLUMNS: - g_value_set_uint(value, GTK_CMCLIST (ctree)->columns); - break; - case ARG_TREE_COLUMN: - g_value_set_uint(value, ctree->tree_column); - break; - case ARG_INDENT: - g_value_set_uint(value, ctree->tree_indent); - break; - case ARG_SPACING: - g_value_set_uint(value, ctree->tree_spacing); - break; - case ARG_SHOW_STUB: - g_value_set_boolean(value, ctree->show_stub); - break; - case ARG_LINE_STYLE: - g_value_set_enum(value, ctree->line_style); - break; - case ARG_EXPANDER_STYLE: - g_value_set_enum(value, ctree->expander_style); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, arg_id, spec); - break; + if (style) + *style = clist_row->cell[column].style; + } + else if (clist_row->style) + { + if (style) + *style = clist_row->style; + } + else + { + if (style) + *style = gtkstyle; } } -static void -gtk_cmctree_init (GtkCMCTree *ctree) +static gboolean filter_fg (PangoAttribute *attribute, gpointer data) { - GtkCMCList *clist; - - GTK_CMCLIST_SET_FLAG (ctree, CMCLIST_DRAW_DRAG_RECT); - GTK_CMCLIST_SET_FLAG (ctree, CMCLIST_DRAW_DRAG_LINE); - - clist = GTK_CMCLIST (ctree); - - ctree->tree_indent = 20; - ctree->tree_spacing = 5; - ctree->tree_column = 0; - ctree->line_style = GTK_CMCTREE_LINES_SOLID; - ctree->expander_style = GTK_CMCTREE_EXPANDER_SQUARE; - ctree->drag_compare = NULL; - ctree->show_stub = TRUE; + const PangoAttrClass *klass = attribute->klass; + if (klass->type == PANGO_ATTR_FOREGROUND) + return TRUE; - clist->button_actions[0] |= GTK_CMBUTTON_EXPANDS; + return FALSE; } -static void -ctree_attach_styles (GtkCMCTree *ctree, - GtkCMCTreeNode *node, - gpointer data) +static PangoLayout * +create_cell_layout (GtkCMCList *clist, + GtkCMCListRow *clist_row, + gint column) { - GtkCMCList *clist; - gint i; + PangoLayout *layout; + GtkStyle *style; + GtkCMCell *cell; + gchar *text; - clist = GTK_CMCLIST (ctree); + get_cell_style (clist, clist_row, GTK_STATE_NORMAL, column, &style); - if (GTK_CMCTREE_ROW (node)->row.style) - GTK_CMCTREE_ROW (node)->row.style = - gtk_style_attach (GTK_CMCTREE_ROW (node)->row.style, clist->clist_window); - if (GTK_CMCTREE_ROW (node)->row.fg_set || GTK_CMCTREE_ROW (node)->row.bg_set) + cell = &clist_row->cell[column]; + switch (cell->type) { - GdkColormap *colormap; + case GTK_CMCELL_TEXT: + case GTK_CMCELL_PIXTEXT: + text = ((cell->type == GTK_CMCELL_PIXTEXT) ? + GTK_CMCELL_PIXTEXT (*cell)->text : + GTK_CMCELL_TEXT (*cell)->text); - colormap = gtk_widget_get_colormap (GTK_WIDGET (ctree)); - if (GTK_CMCTREE_ROW (node)->row.fg_set) - gdk_colormap_alloc_color (colormap, &(GTK_CMCTREE_ROW (node)->row.foreground), TRUE, TRUE); - if (GTK_CMCTREE_ROW (node)->row.bg_set) - gdk_colormap_alloc_color (colormap, &(GTK_CMCTREE_ROW (node)->row.background), TRUE, TRUE); + if (!text) + return NULL; + + if (!GTK_SCTREE(clist)->use_markup[column]) { + layout = gtk_widget_create_pango_layout (GTK_WIDGET (clist), + ((cell->type == GTK_CMCELL_PIXTEXT) ? + GTK_CMCELL_PIXTEXT (*cell)->text : + GTK_CMCELL_TEXT (*cell)->text)); + pango_layout_set_font_description (layout, style->font_desc); + } else { + PangoContext *context = gtk_widget_get_pango_context (GTK_WIDGET(clist)); + layout = pango_layout_new (context); + pango_layout_set_markup (layout, text, -1); + pango_layout_set_font_description (layout, style->font_desc); + if (clist_row->state == GTK_STATE_SELECTED) { + /* for selected row, we should remove any forced foreground color + * or it looks like shit */ + PangoAttrList *list = pango_layout_get_attributes(layout); + PangoAttrList *rem = pango_attr_list_filter(list, filter_fg, NULL); + if (rem) + pango_attr_list_unref(rem); + } + } + + return layout; + + default: + return NULL; } - - for (i = 0; i < clist->columns; i++) - if (GTK_CMCTREE_ROW (node)->row.cell[i].style) - GTK_CMCTREE_ROW (node)->row.cell[i].style = - gtk_style_attach (GTK_CMCTREE_ROW (node)->row.cell[i].style, - clist->clist_window); } -static void -ctree_detach_styles (GtkCMCTree *ctree, - GtkCMCTreeNode *node, - gpointer data) -{ - GtkCMCList *clist; - gint i; - - clist = GTK_CMCLIST (ctree); - - if (GTK_CMCTREE_ROW (node)->row.style) - gtk_style_detach (GTK_CMCTREE_ROW (node)->row.style); - for (i = 0; i < clist->columns; i++) - if (GTK_CMCTREE_ROW (node)->row.cell[i].style) - gtk_style_detach (GTK_CMCTREE_ROW (node)->row.cell[i].style); -} static void -gtk_cmctree_realize (GtkWidget *widget) +draw_row (GtkCMCList *clist, + GdkRectangle *area, + gint row, + GtkCMCListRow *clist_row) { - GtkCMCTree *ctree; - GtkCMCList *clist; - GdkGCValues values; - GtkCMCTreeNode *node; - GtkCMCTreeNode *child; + GtkWidget *widget; GtkStyle *style; + GtkCMCTree *ctree; + GdkRectangle *rect; + GdkRectangle *crect; + GdkRectangle row_rectangle; + GdkRectangle cell_rectangle; + GdkRectangle clip_rectangle; + GdkRectangle intersect_rectangle; + gint last_column; + gint column_left = 0; + gint column_right = 0; + gint offset = 0; + gint state; gint i; + static GdkColor greybg={0, 0, 0, 0}; + static gboolean color_change = TRUE; + cairo_t *cr; + GdkColor *fgcolor, *bgcolor, *focuscolor; - cm_return_if_fail (GTK_IS_CMCTREE (widget)); + cm_return_if_fail (clist != NULL); + widget = GTK_WIDGET (clist); + style = gtk_widget_get_style (widget); - GTK_WIDGET_CLASS (parent_class)->realize (widget); + if (greybg.pixel == 0 && + greybg.red == 0 && + greybg.green == 0 && + greybg.blue == 0) { + GdkColor normalbg = {0, 0xffff, 0xffff, 0xffff}; + if (style) { + normalbg = style->base[GTK_STATE_NORMAL]; + } + if (normalbg.red > 0x8888 && normalbg.green > 0x8888 && normalbg.blue > 0x8888) { + greybg.pixel = normalbg.pixel; + greybg.red = normalbg.red - prefs_common.stripes_color_offset; + greybg.green = normalbg.green - prefs_common.stripes_color_offset; + greybg.blue = normalbg.blue - prefs_common.stripes_color_offset; + } else if (normalbg.red < 0x8888 && normalbg.green < 0x8888 && normalbg.blue < 0x8888) { + greybg.pixel = normalbg.pixel; + greybg.red = normalbg.red + prefs_common.stripes_color_offset; + greybg.green = normalbg.green + prefs_common.stripes_color_offset; + greybg.blue = normalbg.blue + prefs_common.stripes_color_offset; + } else { + color_change = FALSE; + } + } - ctree = GTK_CMCTREE (widget); - clist = GTK_CMCLIST (widget); + /* bail now if we arn't drawable yet */ + if (!gtk_widget_is_drawable (GTK_WIDGET(clist)) || row < 0 || row >= clist->rows) + return; - node = GTK_CMCTREE_NODE (clist->row_list); - for (i = 0; i < clist->rows; i++) - { - if (GTK_CMCTREE_ROW (node)->children && !GTK_CMCTREE_ROW (node)->expanded) - for (child = GTK_CMCTREE_ROW (node)->children; child; - child = GTK_CMCTREE_ROW (child)->sibling) - gtk_cmctree_pre_recursive (ctree, child, ctree_attach_styles, NULL); - node = GTK_CMCTREE_NODE_NEXT (node); - } + ctree = GTK_CMCTREE (clist); - style = gtk_widget_get_style(widget); + /* if the function is passed the pointer to the row instead of null, + * it avoids this expensive lookup */ + if (!clist_row) + clist_row = (g_list_nth (clist->row_list, row))->data; - values.foreground = style->fg[GTK_STATE_NORMAL]; - values.background = style->base[GTK_STATE_NORMAL]; - values.subwindow_mode = GDK_INCLUDE_INFERIORS; - values.line_style = GDK_LINE_SOLID; - ctree->lines_gc = gdk_gc_new_with_values (GTK_CMCLIST(widget)->clist_window, - &values, - GDK_GC_FOREGROUND | - GDK_GC_BACKGROUND | - GDK_GC_SUBWINDOW | - GDK_GC_LINE_STYLE); + /* rectangle of the entire row */ + row_rectangle.x = 0; + row_rectangle.y = ROW_TOP_YPIXEL (clist, row); + row_rectangle.width = clist->clist_window_width; + row_rectangle.height = clist->row_height; - if (ctree->line_style == GTK_CMCTREE_LINES_DOTTED) - { - gdk_gc_set_line_attributes (ctree->lines_gc, 1, - GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER); - gdk_gc_set_dashes (ctree->lines_gc, 0, "\1\1", 2); - } -} + /* rectangle of the cell spacing above the row */ + cell_rectangle.x = 0; + cell_rectangle.y = row_rectangle.y - CELL_SPACING; + cell_rectangle.width = row_rectangle.width; + cell_rectangle.height = CELL_SPACING; -static void -gtk_cmctree_unrealize (GtkWidget *widget) -{ - GtkCMCTree *ctree; - GtkCMCList *clist; + /* rectangle used to clip drawing operations, its y and height + * positions only need to be set once, so we set them once here. + * the x and width are set withing the drawing loop below once per + * column */ + clip_rectangle.y = row_rectangle.y; + clip_rectangle.height = row_rectangle.height; - cm_return_if_fail (GTK_IS_CMCTREE (widget)); + if (prefs_common.use_stripes_everywhere && GTK_SCTREE(ctree)->show_stripes + && color_change && row % 2) { + bgcolor = &greybg; + focuscolor = &greybg; + } else { + bgcolor = &style->base[GTK_STATE_NORMAL]; + focuscolor = &style->base[GTK_STATE_NORMAL]; + } + state = clist_row->state; - GTK_WIDGET_CLASS (parent_class)->unrealize (widget); + cr = gdk_cairo_create(clist->clist_window); + fgcolor = &style->fg[clist_row->state]; + /* draw the cell borders */ + if (area) + { + rect = &intersect_rectangle; + crect = &intersect_rectangle; - ctree = GTK_CMCTREE (widget); - clist = GTK_CMCLIST (widget); + if (gdk_rectangle_intersect (area, &cell_rectangle, crect)) { + gdk_cairo_rectangle(cr, crect); + gdk_cairo_set_source_color(cr, &style->base[GTK_STATE_NORMAL]); + cairo_fill(cr); + } + } + else + { + rect = &clip_rectangle; + crect = &cell_rectangle; - if (gtk_widget_get_realized (widget)) + gdk_cairo_rectangle(cr, crect); + gdk_cairo_set_source_color(cr, &style->base[GTK_STATE_NORMAL]); + cairo_fill(cr); + } + + /* the last row has to clear its bottom cell spacing too */ + if (clist_row == clist->row_list_end->data) { - GtkCMCTreeNode *node; - GtkCMCTreeNode *child; - gint i; + cell_rectangle.y += clist->row_height + CELL_SPACING; - node = GTK_CMCTREE_NODE (clist->row_list); - for (i = 0; i < clist->rows; i++) + if (!area || gdk_rectangle_intersect (area, &cell_rectangle, crect)) { - if (GTK_CMCTREE_ROW (node)->children && - !GTK_CMCTREE_ROW (node)->expanded) - for (child = GTK_CMCTREE_ROW (node)->children; child; - child = GTK_CMCTREE_ROW (child)->sibling) - gtk_cmctree_pre_recursive(ctree, child, ctree_detach_styles, NULL); - node = GTK_CMCTREE_NODE_NEXT (node); + gdk_cairo_rectangle(cr, crect); + gdk_cairo_set_source_color(cr, &style->base[GTK_STATE_NORMAL]); + cairo_fill(cr); } - } - - g_object_unref (ctree->lines_gc); -} + } -static gint -gtk_cmctree_button_press (GtkWidget *widget, - GdkEventButton *event) -{ - GtkCMCTree *ctree; - GtkCMCList *clist; - gint button_actions; + for (last_column = clist->columns - 1; + last_column >= 0 && !clist->column[last_column].visible; last_column--) + ; - cm_return_val_if_fail (GTK_IS_CMCTREE (widget), FALSE); - cm_return_val_if_fail (event != NULL, FALSE); + /* iterate and draw all the columns (row cells) and draw their contents */ + for (i = 0; i < clist->columns; i++) + { + GtkStyle *style; + PangoLayout *layout = NULL; + PangoRectangle logical_rect; - ctree = GTK_CMCTREE (widget); - clist = GTK_CMCLIST (widget); + gint width; + gint height; + gint pixbuf_width; + gint string_width; + gint old_offset; - button_actions = clist->button_actions[event->button - 1]; + if (!clist->column[i].visible) + continue; - if (button_actions == GTK_CMBUTTON_IGNORED) - return FALSE; + get_cell_style (clist, clist_row, state, i, &style); - if (event->window == clist->clist_window) - { - GtkCMCTreeNode *work; - gint x; - gint y; - gint row; - gint column; + /* calculate clipping region */ + clip_rectangle.x = clist->column[i].area.x + clist->hoffset; + clip_rectangle.width = clist->column[i].area.width; - x = event->x; - y = event->y; + cell_rectangle.x = clip_rectangle.x - COLUMN_INSET - CELL_SPACING; + cell_rectangle.width = (clip_rectangle.width + 2 * COLUMN_INSET + + (1 + (i == last_column)) * CELL_SPACING); + cell_rectangle.y = clip_rectangle.y; + cell_rectangle.height = clip_rectangle.height; - if (!gtk_cmclist_get_selection_info (clist, x, y, &row, &column)) - return FALSE; + string_width = 0; + pixbuf_width = 0; + height = 0; - work = GTK_CMCTREE_NODE (g_list_nth (clist->row_list, row)); - - if (button_actions & GTK_CMBUTTON_EXPANDS && - (GTK_CMCTREE_ROW (work)->children && !GTK_CMCTREE_ROW (work)->is_leaf && - (event->type == GDK_2BUTTON_PRESS || - ctree_is_hot_spot (ctree, work, row, x, y)))) + gdk_cairo_rectangle(cr, &cell_rectangle); + if (state == GTK_STATE_NORMAL) + gdk_cairo_set_source_color(cr, bgcolor); + else + gdk_cairo_set_source_color(cr, &style->base[state]); + cairo_fill(cr); + if (area && !gdk_rectangle_intersect (area, &cell_rectangle, + &intersect_rectangle)) { - if (GTK_CMCTREE_ROW (work)->expanded) - gtk_cmctree_collapse (ctree, work); + if (i != ctree->tree_column) + continue; + } + else + { + layout = create_cell_layout (clist, clist_row, i); + if (layout) + { + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + width = logical_rect.width; + } else - gtk_cmctree_expand (ctree, work); + width = 0; - return TRUE; - } - } - - return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event); -} + switch (clist_row->cell[i].type) + { + case GTK_CMCELL_PIXBUF: + pixbuf_width = gdk_pixbuf_get_width(GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf); + height = gdk_pixbuf_get_height(GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf); + width += pixbuf_width; + break; + case GTK_CMCELL_PIXTEXT: + if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) + { + pixbuf_width = gdk_pixbuf_get_width(GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf); + height = gdk_pixbuf_get_height(GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf); + width += pixbuf_width; + } -static void -draw_drag_highlight (GtkCMCList *clist, - GtkCMCListRow *dest_row, - gint dest_row_number, - GtkCMCListDragPos drag_pos) -{ - GtkAllocation allocation; - GtkCMCTree *ctree; - GdkPoint points[4]; - gint level; - gint i; - gint y = 0; + if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->text && + GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) + width += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - cm_return_if_fail (GTK_IS_CMCTREE (clist)); + if (i == ctree->tree_column) + width += (ctree->tree_indent * + ((GtkCMCTreeRow *)clist_row)->level); + break; + default: + break; + } - ctree = GTK_CMCTREE (clist); - gtk_widget_get_allocation(GTK_WIDGET(ctree), &allocation); + switch (clist->column[i].justification) + { + case GTK_JUSTIFY_LEFT: + offset = clip_rectangle.x + clist_row->cell[i].horizontal; + break; + case GTK_JUSTIFY_RIGHT: + offset = (clip_rectangle.x + clist_row->cell[i].horizontal + + clip_rectangle.width - width); + break; + case GTK_JUSTIFY_CENTER: + case GTK_JUSTIFY_FILL: + offset = (clip_rectangle.x + clist_row->cell[i].horizontal + + (clip_rectangle.width / 2) - (width / 2)); + break; + }; - level = ((GtkCMCTreeRow *)(dest_row))->level; + if (i != ctree->tree_column) + { + int start_y = (clip_rectangle.height - height) / 2; + if (GTK_CMCLIST_ROW_HEIGHT_SET(GTK_CMCLIST(clist))) + start_y = (clip_rectangle.height/2 - height) / 2; - y = ROW_TOP_YPIXEL (clist, dest_row_number) - 1; + offset += clist_row->cell[i].horizontal; + switch (clist_row->cell[i].type) + { + case GTK_CMCELL_PIXBUF: + draw_cell_pixbuf + (clist->clist_window, &clip_rectangle, cr, + GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf, + offset, + clip_rectangle.y + clist_row->cell[i].vertical + + start_y, + pixbuf_width, height); + break; + case GTK_CMCELL_PIXTEXT: + offset = draw_cell_pixbuf + (clist->clist_window, &clip_rectangle, cr, + GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf, + offset, + clip_rectangle.y + clist_row->cell[i].vertical + + start_y, + pixbuf_width, height); + offset += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - switch (drag_pos) - { - case GTK_CMCLIST_DRAG_NONE: - break; - case GTK_CMCLIST_DRAG_AFTER: - y += clist->row_height + 1; - case GTK_CMCLIST_DRAG_BEFORE: - - if (clist->column[ctree->tree_column].visible) - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - if (ctree->tree_column > 0) - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, 0), y, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1)+ - clist->column[ctree->tree_column - 1].area.width, - y); + /* Fall through */ + case GTK_CMCELL_TEXT: + if (layout) + { + gint row_center_offset = (clist->row_height - logical_rect.height) / 2; + gdk_cairo_set_source_color(cr, fgcolor); + cairo_move_to(cr, offset, row_rectangle.y + row_center_offset + clist_row->cell[i].vertical); + pango_cairo_show_layout(cr, layout); + g_object_unref (G_OBJECT (layout)); + } + break; + default: + break; + } + continue; + } + } - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + - ctree->tree_indent * level - - (ctree->tree_indent - PM_SIZE) / 2, y, - allocation.width, y); - break; - case GTK_JUSTIFY_RIGHT: - if (ctree->tree_column < clist->columns - 1) - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1), - y, - COLUMN_LEFT_XPIXEL(clist, clist->columns - 1) + - clist->column[clist->columns - 1].area.width, y); - - gdk_draw_line (clist->clist_window, clist->xor_gc, - 0, y, COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - + clist->column[ctree->tree_column].area.width - - ctree->tree_indent * level + - (ctree->tree_indent - PM_SIZE) / 2, y); - break; - } - else - gdk_draw_line (clist->clist_window, clist->xor_gc, - 0, y, clist->clist_window_width, y); - break; - case GTK_CMCLIST_DRAG_INTO: - y = ROW_TOP_YPIXEL (clist, dest_row_number) + clist->row_height; - - if (clist->column[ctree->tree_column].visible) - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + - ctree->tree_indent * level - (ctree->tree_indent - PM_SIZE) / 2; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = clist->clist_window_width - 1; - points[1].y = points[0].y; - points[2].x = points[1].x; - points[2].y = points[3].y; + /* draw ctree->tree_column */ + cell_rectangle.y -= CELL_SPACING; + cell_rectangle.height += CELL_SPACING; - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); + if (area && !gdk_rectangle_intersect (area, &cell_rectangle, + &intersect_rectangle)) + { + if (layout) + g_object_unref (G_OBJECT (layout)); + continue; + } - if (ctree->tree_column > 0) - { - points[0].x = COLUMN_LEFT_XPIXEL(clist, - ctree->tree_column - 1) + - clist->column[ctree->tree_column - 1].area.width ; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = 0; - points[1].y = points[0].y; - points[2].x = 0; - points[2].y = points[3].y; - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, points[i+1].x, - points[i+1].y); - } - break; - case GTK_JUSTIFY_RIGHT: - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - - ctree->tree_indent * level + (ctree->tree_indent - PM_SIZE) / 2 + - clist->column[ctree->tree_column].area.width; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = 0; - points[1].y = points[0].y; - points[2].x = 0; - points[2].y = points[3].y; + /* draw lines */ + offset = get_offset (ctree, (GtkCMCTreeRow *)clist_row, i, + &clip_rectangle); - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); + /* draw expander */ + offset = draw_expander (ctree, (GtkCMCTreeRow *)clist_row, + style, &clip_rectangle, cr, offset); - if (ctree->tree_column < clist->columns - 1) - { - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column +1); - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = clist->clist_window_width - 1; - points[1].y = points[0].y; - points[2].x = points[1].x; - points[2].y = points[3].y; + if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) + offset -= ctree->tree_spacing; + else + offset += ctree->tree_spacing; - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); - } - break; - } + if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) + offset -= (pixbuf_width + clist_row->cell[i].horizontal); else - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - 0, y - clist->row_height, - clist->clist_window_width - 1, clist->row_height); - break; + offset += clist_row->cell[i].horizontal; + + old_offset = offset; + offset = draw_cell_pixbuf (clist->clist_window, &clip_rectangle, cr, + GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf, + offset, + clip_rectangle.y + clist_row->cell[i].vertical + + (clip_rectangle.height - height) / 2, + pixbuf_width, height); + + if (layout) + { + gint row_center_offset = (clist->row_height - logical_rect.height) / 2; + + if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) + { + offset = (old_offset - string_width); + if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) + offset -= GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; + } + else + { + if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) + offset += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; + } + + cairo_move_to(cr, offset, row_rectangle.y + row_center_offset + clist_row->cell[i].vertical); + gdk_cairo_set_source_color(cr, fgcolor); + pango_cairo_show_layout(cr, layout); + + g_object_unref (G_OBJECT (layout)); + } } + cairo_destroy(cr); } -static gint -draw_cell_pixbuf (GdkWindow *window, - GdkRectangle *clip_rectangle, - GdkGC *fg_gc, - GdkPixbuf *pixbuf, - gint x, - gint y, - gint width, - gint height) +static void +gtk_cmctree_class_init (GtkCMCTreeClass *klass) { - gint xsrc = 0; - gint ysrc = 0; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkCMCListClass *clist_class; + GtkBindingSet *binding_set; - gdk_gc_set_clip_origin (fg_gc, x, y); - if (x < clip_rectangle->x) - { - xsrc = clip_rectangle->x - x; - width -= xsrc; - x = clip_rectangle->x; - } - if (x + width > clip_rectangle->x + clip_rectangle->width) - width = clip_rectangle->x + clip_rectangle->width - x; + gobject_class->constructor = gtk_cmctree_constructor; - if (y < clip_rectangle->y) - { - ysrc = clip_rectangle->y - y; - height -= ysrc; - y = clip_rectangle->y; - } - if (y + height > clip_rectangle->y + clip_rectangle->height) - height = clip_rectangle->y + clip_rectangle->height - y; + object_class = (GtkObjectClass *) klass; + widget_class = (GtkWidgetClass *) klass; + container_class = (GtkContainerClass *) klass; + clist_class = (GtkCMCListClass *) klass; - if (width > 0 && height > 0) - gdk_draw_pixbuf (window, fg_gc, pixbuf, xsrc, ysrc, x, y, width, height, GDK_RGB_DITHER_NONE, 0, 0); + parent_class = g_type_class_peek (GTK_TYPE_CMCLIST); + container_class = g_type_class_peek (GTK_TYPE_CONTAINER); - gdk_gc_set_clip_origin (fg_gc, 0, 0); + gobject_class->set_property = gtk_cmctree_set_arg; + gobject_class->get_property = gtk_cmctree_get_arg; - return x + MAX (width, 0); -} + widget_class->realize = gtk_cmctree_realize; + widget_class->unrealize = gtk_cmctree_unrealize; + widget_class->button_press_event = gtk_cmctree_button_press; -static void -get_cell_style (GtkCMCList *clist, - GtkCMCListRow *clist_row, - gint state, - gint column, - GtkStyle **style, - GdkGC **fg_gc, - GdkGC **bg_gc) -{ - GtkStyle *gtkstyle; - gint fg_state; + widget_class->drag_begin = gtk_cmctree_drag_begin; + widget_class->drag_motion = gtk_cmctree_drag_motion; + widget_class->drag_data_received = gtk_cmctree_drag_data_received; - gtkstyle = gtk_widget_get_style (GTK_WIDGET (clist)); - if ((state == GTK_STATE_NORMAL) && - (gtk_widget_get_state(GTK_WIDGET (clist)) == GTK_STATE_INSENSITIVE)) - fg_state = GTK_STATE_INSENSITIVE; - else - fg_state = state; + clist_class->select_row = real_select_row; + clist_class->unselect_row = real_unselect_row; + clist_class->row_move = real_row_move; + clist_class->undo_selection = real_undo_selection; + clist_class->resync_selection = resync_selection; + clist_class->selection_find = selection_find; + clist_class->click_column = NULL; + clist_class->draw_row = draw_row; + clist_class->draw_drag_highlight = draw_drag_highlight; + clist_class->clear = real_clear; + clist_class->select_all = real_select_all; + clist_class->unselect_all = real_unselect_all; + clist_class->fake_unselect_all = fake_unselect_all; + clist_class->insert_row = real_insert_row; + clist_class->remove_row = real_remove_row; + clist_class->sort_list = real_sort_list; + clist_class->set_cell_contents = set_cell_contents; + clist_class->cell_size_request = cell_size_request; - if (clist_row->cell[column].style) - { - if (style) - *style = clist_row->cell[column].style; - if (fg_gc) - *fg_gc = clist_row->cell[column].style->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = clist_row->cell[column].style->bg_gc[state]; - else - *bg_gc = clist_row->cell[column].style->base_gc[state]; - } - } - else if (clist_row->style) - { - if (style) - *style = clist_row->style; - if (fg_gc) - *fg_gc = clist_row->style->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = clist_row->style->bg_gc[state]; - else - *bg_gc = clist_row->style->base_gc[state]; - } - } - else - { - if (style) - *style = gtkstyle; - if (fg_gc) - *fg_gc = gtkstyle->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = gtkstyle->bg_gc[state]; - else - *bg_gc = gtkstyle->base_gc[state]; - } + klass->tree_select_row = real_tree_select; + klass->tree_unselect_row = real_tree_unselect; + klass->tree_expand = real_tree_expand; + klass->tree_collapse = real_tree_collapse; + klass->tree_move = real_tree_move; + klass->change_focus_row_expansion = change_focus_row_expansion; - if (state != GTK_STATE_SELECTED) - { - if (fg_gc && clist_row->fg_set) - *fg_gc = clist->fg_gc; - if (bg_gc && clist_row->bg_set) - *bg_gc = clist->bg_gc; - } - } + g_object_class_install_property (gobject_class, + ARG_N_COLUMNS, + g_param_spec_uint ("n-columns", + "N-Columns", + "N-Columns", + 1, + G_MAXINT, + 1, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + ARG_TREE_COLUMN, + g_param_spec_uint ("tree-column", + "tree-column", + "tree-column", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + ARG_INDENT, + g_param_spec_uint ("indent", + "indent", + "indent", + 1, + G_MAXINT, + 1, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + ARG_SPACING, + g_param_spec_uint ("spacing", + "spacing", + "spacing", + 1, + G_MAXINT, + 1, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + ARG_SHOW_STUB, + g_param_spec_boolean ("show-stub", + "show-stub", + "show-stub", + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + ARG_LINE_STYLE, + g_param_spec_enum ("line-style", + "line-style", + "line-style", + GTK_TYPE_CMCTREE_LINE_STYLE, 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + ARG_EXPANDER_STYLE, + g_param_spec_enum ("expander-style", + "expander-style", + "expander-style", + GTK_TYPE_CMCTREE_EXPANDER_STYLE, 0, + G_PARAM_READWRITE)); + + ctree_signals[TREE_SELECT_ROW] = + g_signal_new ("tree_select_row", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkCMCTreeClass, tree_select_row), + NULL, NULL, + claws_marshal_VOID__POINTER_INT, + G_TYPE_NONE, 2, + GTK_TYPE_CMCTREE_NODE, + G_TYPE_INT); + ctree_signals[TREE_UNSELECT_ROW] = + g_signal_new ("tree_unselect_row", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkCMCTreeClass, tree_unselect_row), + NULL, NULL, + claws_marshal_VOID__POINTER_INT, + G_TYPE_NONE, 2, + GTK_TYPE_CMCTREE_NODE, + G_TYPE_INT); + ctree_signals[TREE_EXPAND] = + g_signal_new ("tree_expand", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkCMCTreeClass, tree_expand), + NULL, NULL, + claws_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + GTK_TYPE_CMCTREE_NODE); + ctree_signals[TREE_COLLAPSE] = + g_signal_new ("tree_collapse", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkCMCTreeClass, tree_collapse), + NULL, NULL, + claws_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + GTK_TYPE_CMCTREE_NODE); + ctree_signals[TREE_MOVE] = + g_signal_new ("tree_move", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkCMCTreeClass, tree_move), + NULL, NULL, + claws_marshal_VOID__POINTER_POINTER_POINTER, + G_TYPE_NONE, 3, + GTK_TYPE_CMCTREE_NODE,GTK_TYPE_CMCTREE_NODE,GTK_TYPE_CMCTREE_NODE); + ctree_signals[CHANGE_FOCUS_ROW_EXPANSION] = + g_signal_new ("change_focus_row_expansion", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkCMCTreeClass, change_focus_row_expansion), + NULL, NULL, + claws_marshal_VOID__ENUM, + G_TYPE_NONE, 1, GTK_TYPE_CMCTREE_EXPANSION_TYPE); + + binding_set = gtk_binding_set_by_class (klass); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_plus, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_plus, GDK_CONTROL_MASK, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND_RECURSIVE); + + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_KP_Add, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_KP_Add, GDK_CONTROL_MASK, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_EXPAND_RECURSIVE); + + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_minus, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_COLLAPSE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_minus, GDK_CONTROL_MASK, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, + GTK_CMCTREE_EXPANSION_COLLAPSE_RECURSIVE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_KP_Subtract, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_COLLAPSE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_KP_Subtract, GDK_CONTROL_MASK, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, + GTK_CMCTREE_EXPANSION_COLLAPSE_RECURSIVE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_equal, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_KP_Equal, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_KP_Multiply, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_asterisk, 0, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, GTK_CMCTREE_EXPANSION_TOGGLE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_KP_Multiply, GDK_CONTROL_MASK, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, + GTK_CMCTREE_EXPANSION_TOGGLE_RECURSIVE); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_asterisk, GDK_CONTROL_MASK, + "change_focus_row_expansion", 1, + G_TYPE_ENUM, + GTK_CMCTREE_EXPANSION_TOGGLE_RECURSIVE); } -static gint -gtk_cmctree_draw_expander (GtkCMCTree *ctree, - GtkCMCTreeRow *ctree_row, - GtkStyle *style, - GdkRectangle *clip_rectangle, - gint x) +static void +gtk_cmctree_set_arg (GObject *object, + guint arg_id, + const GValue *value, + GParamSpec *spec) { + GtkCMCTree *ctree; GtkCMCList *clist; - GdkPoint points[3]; - gint justification_factor; - gint y; - - if (ctree->expander_style == GTK_CMCTREE_EXPANDER_NONE) - return x; + ctree = GTK_CMCTREE (object); clist = GTK_CMCLIST (ctree); - if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) - justification_factor = -1; - else - justification_factor = 1; - y = (clip_rectangle->y + (clip_rectangle->height - PM_SIZE) / 2 - - (clip_rectangle->height + 1) % 2); - if (!ctree_row->children) - { - switch (ctree->expander_style) - { - case GTK_CMCTREE_EXPANDER_NONE: - return x; - case GTK_CMCTREE_EXPANDER_TRIANGLE: - return x + justification_factor * (PM_SIZE + 3); - case GTK_CMCTREE_EXPANDER_SQUARE: - case GTK_CMCTREE_EXPANDER_CIRCULAR: - return x + justification_factor * (PM_SIZE + 1); - } - } - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], clip_rectangle); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], clip_rectangle); - - switch (ctree->expander_style) + switch (arg_id) { - case GTK_CMCTREE_EXPANDER_NONE: - break; - case GTK_CMCTREE_EXPANDER_TRIANGLE: - if (ctree_row->expanded) - { - points[0].x = x; - points[0].y = y + (PM_SIZE + 2) / 6; - points[1].x = points[0].x + justification_factor * (PM_SIZE + 2); - points[1].y = points[0].y; - points[2].x = (points[0].x + - justification_factor * (PM_SIZE + 2) / 2); - points[2].y = y + 2 * (PM_SIZE + 2) / 3; - } - else - { - points[0].x = x + justification_factor * ((PM_SIZE + 2) / 6 + 2); - points[0].y = y - 1; - points[1].x = points[0].x; - points[1].y = points[0].y + (PM_SIZE + 2); - points[2].x = (points[0].x + - justification_factor * (2 * (PM_SIZE + 2) / 3 - 1)); - points[2].y = points[0].y + (PM_SIZE + 2) / 2; - } - - gdk_draw_polygon (clist->clist_window, style->base_gc[GTK_STATE_NORMAL], - TRUE, points, 3); - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - FALSE, points, 3); - - x += justification_factor * (PM_SIZE + 3); + case ARG_N_COLUMNS: /* construct-only arg, only set at construction time */ +#if !GLIB_CHECK_VERSION(2,10,0) + cm_return_if_fail (clist->row_mem_chunk == NULL); +#endif + clist->columns = MAX (1, g_value_get_uint (value)); +#if !GLIB_CHECK_VERSION(2,10,0) + clist->row_mem_chunk = g_mem_chunk_new ("ctree row mem chunk", + sizeof (GtkCMCTreeRow), + sizeof (GtkCMCTreeRow) + * CLIST_OPTIMUM_SIZE, + G_ALLOC_AND_FREE); + clist->cell_mem_chunk = g_mem_chunk_new ("ctree cell mem chunk", + sizeof (GtkCMCell) * clist->columns, + sizeof (GtkCMCell) * clist->columns + * CLIST_OPTIMUM_SIZE, + G_ALLOC_AND_FREE); +#endif + ctree->tree_column = CLAMP (ctree->tree_column, 0, clist->columns); break; - case GTK_CMCTREE_EXPANDER_SQUARE: - case GTK_CMCTREE_EXPANDER_CIRCULAR: - if (justification_factor == -1) - x += justification_factor * (PM_SIZE + 1); - - if (ctree->expander_style == GTK_CMCTREE_EXPANDER_CIRCULAR) - { - gdk_draw_arc (clist->clist_window, style->base_gc[GTK_STATE_NORMAL], - TRUE, x, y, PM_SIZE, PM_SIZE, 0, 360 * 64); - gdk_draw_arc (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - FALSE, x, y, PM_SIZE, PM_SIZE, 0, 360 * 64); - } - else - { - gdk_draw_rectangle (clist->clist_window, - style->base_gc[GTK_STATE_NORMAL], TRUE, - x, y, PM_SIZE, PM_SIZE); - gdk_draw_rectangle (clist->clist_window, - style->fg_gc[GTK_STATE_NORMAL], FALSE, - x, y, PM_SIZE, PM_SIZE); - } - - gdk_draw_line (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - x + 2, y + PM_SIZE / 2, x + PM_SIZE - 2, y + PM_SIZE / 2); - - if (!ctree_row->expanded) - gdk_draw_line (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - x + PM_SIZE / 2, y + 2, - x + PM_SIZE / 2, y + PM_SIZE - 2); - - if (justification_factor == 1) - x += justification_factor * (PM_SIZE + 1); + case ARG_TREE_COLUMN: /* construct-only arg, only set at construction time */ + ctree->tree_column = g_value_get_uint (value); +#if !GLIB_CHECK_VERSION(2,10,0) + if (clist->row_mem_chunk) +#endif + ctree->tree_column = CLAMP (ctree->tree_column, 0, clist->columns); + break; + case ARG_INDENT: + gtk_cmctree_set_indent (ctree, g_value_get_uint (value)); + break; + case ARG_SPACING: + gtk_cmctree_set_spacing (ctree, g_value_get_uint (value)); + break; + case ARG_SHOW_STUB: + gtk_cmctree_set_show_stub (ctree, g_value_get_boolean (value)); + break; + case ARG_LINE_STYLE: + gtk_cmctree_set_line_style (ctree, g_value_get_enum (value)); + break; + case ARG_EXPANDER_STYLE: + gtk_cmctree_set_expander_style (ctree, g_value_get_enum (value)); + break; + default: break; } - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL); - - return x; } - -static gint -gtk_cmctree_draw_lines (GtkCMCTree *ctree, - GtkCMCTreeRow *ctree_row, - gint row, - gint column, - gint state, - GdkRectangle *clip_rectangle, - GdkRectangle *cell_rectangle, - GdkRectangle *crect, - GdkRectangle *area, - GtkStyle *style) +static void +gtk_cmctree_get_arg (GObject *object, + guint arg_id, + GValue *value, + GParamSpec *spec) { - GtkCMCList *clist; - GtkCMCTreeNode *node; - GtkCMCTreeNode *parent; - GdkRectangle tree_rectangle; - GdkRectangle tc_rectangle; - GdkGC *bg_gc; - gint offset; - gint offset_x; - gint offset_y; - gint xcenter; - gint ycenter; - gint next_level; - gint column_right; - gint column_left; - gint justify_right; - gint justification_factor; - - clist = GTK_CMCLIST (ctree); - ycenter = clip_rectangle->y + (clip_rectangle->height / 2); - justify_right = (clist->column[column].justification == GTK_JUSTIFY_RIGHT); + GtkCMCTree *ctree; - if (justify_right) - { - offset = (clip_rectangle->x + clip_rectangle->width - 1 - - ctree->tree_indent * (ctree_row->level - 1)); - justification_factor = -1; - } - else - { - offset = clip_rectangle->x + ctree->tree_indent * (ctree_row->level - 1); - justification_factor = 1; - } + ctree = GTK_CMCTREE (object); - switch (ctree->line_style) + switch (arg_id) { - case GTK_CMCTREE_LINES_NONE: + case ARG_N_COLUMNS: + g_value_set_uint(value, GTK_CMCLIST (ctree)->columns); break; - case GTK_CMCTREE_LINES_TABBED: - xcenter = offset + justification_factor * TAB_SIZE; - - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - CELL_SPACING); - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter; - tree_rectangle.width = column_right - xcenter; - } - else - { - tree_rectangle.x = column_left; - tree_rectangle.width = xcenter - column_left; - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - { - offset += justification_factor * 3; - break; - } - } - - gdk_gc_set_clip_rectangle (ctree->lines_gc, crect); - - next_level = ctree_row->level; - - if (!ctree_row->sibling || (ctree_row->children && ctree_row->expanded)) - { - node = gtk_cmctree_find_node_ptr (ctree, ctree_row); - if (GTK_CMCTREE_NODE_NEXT (node)) - next_level = GTK_CMCTREE_ROW (GTK_CMCTREE_NODE_NEXT (node))->level; - else - next_level = 0; - } - - if (ctree->tree_indent > 0) - { - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if ((justify_right && xcenter < column_left) || - (!justify_right && xcenter > column_right)) - { - node = GTK_CMCTREE_ROW (node)->parent; - continue; - } - - tree_rectangle.y = cell_rectangle->y; - tree_rectangle.height = cell_rectangle->height; - if (justify_right) - { - tree_rectangle.x = MAX (xcenter - ctree->tree_indent + 1, - column_left); - tree_rectangle.width = MIN (xcenter - column_left, - ctree->tree_indent); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - ctree->tree_indent); - } - - if (!area || gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - get_cell_style (clist, &GTK_CMCTREE_ROW (node)->row, - state, column, NULL, NULL, &bg_gc); - - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &GTK_CMCTREE_ROW (node)->row.background); - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - if (next_level > GTK_CMCTREE_ROW (node)->level) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, crect->y, - xcenter, crect->y + crect->height); - else - { - gint width; - - offset_x = MIN (ctree->tree_indent, 2 * TAB_SIZE); - width = offset_x / 2 + offset_x % 2; - - parent = GTK_CMCTREE_ROW (node)->parent; - - tree_rectangle.y = ycenter; - tree_rectangle.height = (cell_rectangle->y - ycenter + - cell_rectangle->height); - - if (justify_right) - { - tree_rectangle.x = MAX(xcenter + 1 - width, column_left); - tree_rectangle.width = MIN (xcenter + 1 - column_left, - width); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - width); - } - - if (!area || - gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - if (parent) - { - get_cell_style (clist, &GTK_CMCTREE_ROW (parent)->row, - state, column, NULL, NULL, &bg_gc); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, - &GTK_CMCTREE_ROW (parent)->row.background); - } - else if (state == GTK_STATE_SELECTED) - bg_gc = style->base_gc[state]; - else - bg_gc = gtk_widget_get_style (GTK_WIDGET (clist))->base_gc[state]; - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, - bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - get_cell_style (clist, &GTK_CMCTREE_ROW (node)->row, - state, column, NULL, NULL, &bg_gc); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &GTK_CMCTREE_ROW (node)->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - xcenter - (justify_right * offset_x), - cell_rectangle->y, - offset_x, clist->row_height, - (180 + (justify_right * 90)) * 64, 90 * 64); - gdk_gc_set_clip_rectangle (bg_gc, NULL); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y, xcenter, ycenter); - - if (justify_right) - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter - offset_x, cell_rectangle->y, - offset_x, clist->row_height, - 270 * 64, 90 * 64); - else - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter, cell_rectangle->y, - offset_x, clist->row_height, - 180 * 64, 90 * 64); - } - node = GTK_CMCTREE_ROW (node)->parent; - } - } - - if (state != GTK_STATE_SELECTED) - { - tree_rectangle.y = clip_rectangle->y; - tree_rectangle.height = clip_rectangle->height; - tree_rectangle.width = COLUMN_INSET + CELL_SPACING + - MIN (clist->column[ctree->tree_column].area.width + COLUMN_INSET, - TAB_SIZE); - - if (justify_right) - tree_rectangle.x = MAX (xcenter + 1, column_left); - else - tree_rectangle.x = column_left; - - if (!area) - gdk_draw_rectangle (clist->clist_window, - gtk_widget_get_style (GTK_WIDGET - (ctree))->base_gc[GTK_STATE_NORMAL], - TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else if (gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - gdk_draw_rectangle (clist->clist_window, - gtk_widget_get_style (GTK_WIDGET - (ctree))->base_gc[GTK_STATE_NORMAL], - TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - xcenter = offset + (justification_factor * ctree->tree_indent / 2); - - get_cell_style (clist, &ctree_row->row, state, column, NULL, NULL, - &bg_gc); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground (clist->bg_gc, &ctree_row->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - if (ctree_row->is_leaf) - { - GdkPoint points[6]; - - points[0].x = offset + justification_factor * TAB_SIZE; - points[0].y = cell_rectangle->y; - - points[1].x = points[0].x - justification_factor * 4; - points[1].y = points[0].y; - - points[2].x = points[1].x - justification_factor * 2; - points[2].y = points[1].y + 3; - - points[3].x = points[2].x; - points[3].y = points[2].y + clist->row_height - 5; - - points[4].x = points[3].x + justification_factor * 2; - points[4].y = points[3].y + 3; - - points[5].x = points[4].x + justification_factor * 4; - points[5].y = points[4].y; - - gdk_draw_polygon (clist->clist_window, bg_gc, TRUE, points, 6); - gdk_draw_lines (clist->clist_window, ctree->lines_gc, points, 6); - } - else - { - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - } - gdk_gc_set_clip_rectangle (bg_gc, NULL); - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - - offset += justification_factor * 3; + case ARG_TREE_COLUMN: + g_value_set_uint(value, ctree->tree_column); + break; + case ARG_INDENT: + g_value_set_uint(value, ctree->tree_indent); + break; + case ARG_SPACING: + g_value_set_uint(value, ctree->tree_spacing); + break; + case ARG_SHOW_STUB: + g_value_set_boolean(value, ctree->show_stub); + break; + case ARG_LINE_STYLE: + g_value_set_enum(value, ctree->line_style); + break; + case ARG_EXPANDER_STYLE: + g_value_set_enum(value, ctree->expander_style); break; default: - xcenter = offset + justification_factor * PM_SIZE / 2; - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter - PM_SIZE / 2 - 2; - tree_rectangle.width = (clip_rectangle->x + - clip_rectangle->width -tree_rectangle.x); - } - else - { - tree_rectangle.x = clip_rectangle->x + PM_SIZE / 2; - tree_rectangle.width = (xcenter + PM_SIZE / 2 + 2 - - clip_rectangle->x); - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - break; - } - - offset_x = 1; - offset_y = 0; - if (ctree->line_style == GTK_CMCTREE_LINES_DOTTED) - { - offset_x += abs((clip_rectangle->x + clist->hoffset) % 2); - offset_y = abs((cell_rectangle->y + clist->voffset) % 2); - } - - clip_rectangle->y--; - clip_rectangle->height++; - gdk_gc_set_clip_rectangle (ctree->lines_gc, clip_rectangle); - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, - (ctree->show_stub || clist->row_list->data != ctree_row) ? - cell_rectangle->y + offset_y : ycenter, - xcenter, - (ctree_row->sibling) ? crect->y +crect->height : ycenter); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter + (justification_factor * offset_x), ycenter, - xcenter + (justification_factor * (PM_SIZE / 2 + 2)), - ycenter); - - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if (GTK_CMCTREE_ROW (node)->sibling) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y + offset_y, - xcenter, crect->y + crect->height); - node = GTK_CMCTREE_ROW (node)->parent; - } - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - clip_rectangle->y++; - clip_rectangle->height--; + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, arg_id, spec); break; } - return offset; } static void -draw_row (GtkCMCList *clist, - GdkRectangle *area, - gint row, - GtkCMCListRow *clist_row) +gtk_cmctree_init (GtkCMCTree *ctree) { - GtkStyle *style; - GtkWidget *widget; - GtkCMCTree *ctree; - GdkRectangle *crect; - GdkRectangle row_rectangle; - GdkRectangle cell_rectangle; - GdkRectangle clip_rectangle; - GdkRectangle intersect_rectangle; - gint last_column; - gint column_left = 0; - gint column_right = 0; - gint offset = 0; - gint state; - gint i; - - cm_return_if_fail (clist != NULL); - - /* bail now if we arn't drawable yet */ - if (!gtk_widget_is_drawable (GTK_WIDGET(clist)) || row < 0 || row >= clist->rows) - return; - - widget = GTK_WIDGET (clist); - ctree = GTK_CMCTREE (clist); - - /* if the function is passed the pointer to the row instead of null, - * it avoids this expensive lookup */ - if (!clist_row) - clist_row = (g_list_nth (clist->row_list, row))->data; + GtkCMCList *clist; - /* rectangle of the entire row */ - row_rectangle.x = 0; - row_rectangle.y = ROW_TOP_YPIXEL (clist, row); - row_rectangle.width = clist->clist_window_width; - row_rectangle.height = clist->row_height; + GTK_CMCLIST_SET_FLAG (ctree, CMCLIST_DRAW_DRAG_RECT); + GTK_CMCLIST_SET_FLAG (ctree, CMCLIST_DRAW_DRAG_LINE); - /* rectangle of the cell spacing above the row */ - cell_rectangle.x = 0; - cell_rectangle.y = row_rectangle.y - CELL_SPACING; - cell_rectangle.width = row_rectangle.width; - cell_rectangle.height = CELL_SPACING; + clist = GTK_CMCLIST (ctree); - /* rectangle used to clip drawing operations, its y and height - * positions only need to be set once, so we set them once here. - * the x and width are set withing the drawing loop below once per - * column */ - clip_rectangle.y = row_rectangle.y; - clip_rectangle.height = row_rectangle.height; + ctree->tree_indent = 20; + ctree->tree_spacing = 5; + ctree->tree_column = 0; + ctree->line_style = GTK_CMCTREE_LINES_NONE; + ctree->expander_style = GTK_CMCTREE_EXPANDER_TRIANGLE; + ctree->drag_compare = NULL; + ctree->show_stub = TRUE; - if (clist_row->state == GTK_STATE_NORMAL) - { - if (clist_row->fg_set) - gdk_gc_set_foreground (clist->fg_gc, &clist_row->foreground); - if (clist_row->bg_set) - gdk_gc_set_foreground (clist->bg_gc, &clist_row->background); - } - - state = clist_row->state; + clist->button_actions[0] |= GTK_CMBUTTON_EXPANDS; +} - style = gtk_widget_get_style (widget); - gdk_gc_set_foreground (ctree->lines_gc, - &style->fg[clist_row->state]); +static void +ctree_attach_styles (GtkCMCTree *ctree, + GtkCMCTreeNode *node, + gpointer data) +{ + GtkCMCList *clist; + gint i; - /* draw the cell borders */ - if (area) - { - crect = &intersect_rectangle; + clist = GTK_CMCLIST (ctree); - if (gdk_rectangle_intersect (area, &cell_rectangle, crect)) - gdk_draw_rectangle (clist->clist_window, - style->base_gc[GTK_STATE_NORMAL], TRUE, - crect->x, crect->y, crect->width, crect->height); - } - else + if (GTK_CMCTREE_ROW (node)->row.style) + GTK_CMCTREE_ROW (node)->row.style = + gtk_style_attach (GTK_CMCTREE_ROW (node)->row.style, clist->clist_window); + + if (GTK_CMCTREE_ROW (node)->row.fg_set || GTK_CMCTREE_ROW (node)->row.bg_set) { - crect = &cell_rectangle; + GdkColormap *colormap; - gdk_draw_rectangle (clist->clist_window, - style->base_gc[GTK_STATE_NORMAL], TRUE, - crect->x, crect->y, crect->width, crect->height); + colormap = gtk_widget_get_colormap (GTK_WIDGET (ctree)); + if (GTK_CMCTREE_ROW (node)->row.fg_set) + gdk_colormap_alloc_color (colormap, &(GTK_CMCTREE_ROW (node)->row.foreground), TRUE, TRUE); + if (GTK_CMCTREE_ROW (node)->row.bg_set) + gdk_colormap_alloc_color (colormap, &(GTK_CMCTREE_ROW (node)->row.background), TRUE, TRUE); } - /* horizontal black lines */ - if (ctree->line_style == GTK_CMCTREE_LINES_TABBED) - { + for (i = 0; i < clist->columns; i++) + if (GTK_CMCTREE_ROW (node)->row.cell[i].style) + GTK_CMCTREE_ROW (node)->row.cell[i].style = + gtk_style_attach (GTK_CMCTREE_ROW (node)->row.cell[i].style, + clist->clist_window); +} - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - (ctree->tree_column != 0) * CELL_SPACING); +static void +ctree_detach_styles (GtkCMCTree *ctree, + GtkCMCTreeNode *node, + gpointer data) +{ + GtkCMCList *clist; + gint i; - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - offset = (column_left + ctree->tree_indent * - (((GtkCMCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (offset + TAB_SIZE, column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - offset = (column_right - 1 - ctree->tree_indent * - (((GtkCMCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (offset - TAB_SIZE, column_left), - cell_rectangle.y); - break; - } - } + clist = GTK_CMCLIST (ctree); - /* the last row has to clear its bottom cell spacing too */ - if (clist_row == clist->row_list_end->data) - { - cell_rectangle.y += clist->row_height + CELL_SPACING; + if (GTK_CMCTREE_ROW (node)->row.style) + gtk_style_detach (GTK_CMCTREE_ROW (node)->row.style); + for (i = 0; i < clist->columns; i++) + if (GTK_CMCTREE_ROW (node)->row.cell[i].style) + gtk_style_detach (GTK_CMCTREE_ROW (node)->row.cell[i].style); +} - if (!area || gdk_rectangle_intersect (area, &cell_rectangle, crect)) - { - gdk_draw_rectangle (clist->clist_window, - gtk_widget_get_style (widget)->base_gc[GTK_STATE_NORMAL], TRUE, - crect->x, crect->y, crect->width, crect->height); - - /* horizontal black lines */ - if (ctree->line_style == GTK_CMCTREE_LINES_TABBED) - { - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (column_left + TAB_SIZE + COLUMN_INSET + - (((GtkCMCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (column_right - TAB_SIZE - 1 - - COLUMN_INSET - - (((GtkCMCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_left - 1), cell_rectangle.y); - break; - } - } - } - } +static void +gtk_cmctree_realize (GtkWidget *widget) +{ + GtkCMCTree *ctree; + GtkCMCList *clist; + GtkCMCTreeNode *node; + GtkCMCTreeNode *child; + GtkStyle *style; + gint i; - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; + cm_return_if_fail (GTK_IS_CMCTREE (widget)); - /* iterate and draw all the columns (row cells) and draw their contents */ - for (i = 0; i < clist->columns; i++) + GTK_WIDGET_CLASS (parent_class)->realize (widget); + + ctree = GTK_CMCTREE (widget); + clist = GTK_CMCLIST (widget); + + node = GTK_CMCTREE_NODE (clist->row_list); + for (i = 0; i < clist->rows; i++) { - GtkStyle *style; - GdkGC *fg_gc; - GdkGC *bg_gc; - PangoLayout *layout = NULL; - PangoRectangle logical_rect; + if (GTK_CMCTREE_ROW (node)->children && !GTK_CMCTREE_ROW (node)->expanded) + for (child = GTK_CMCTREE_ROW (node)->children; child; + child = GTK_CMCTREE_ROW (child)->sibling) + gtk_cmctree_pre_recursive (ctree, child, ctree_attach_styles, NULL); + node = GTK_CMCTREE_NODE_NEXT (node); + } - gint width; - gint height; - gint pixbuf_width; - gint string_width; - gint old_offset; + style = gtk_widget_get_style(widget); +} - if (!clist->column[i].visible) - continue; +static void +gtk_cmctree_unrealize (GtkWidget *widget) +{ + GtkCMCTree *ctree; + GtkCMCList *clist; - get_cell_style (clist, clist_row, state, i, &style, &fg_gc, &bg_gc); + cm_return_if_fail (GTK_IS_CMCTREE (widget)); - /* calculate clipping region */ - clip_rectangle.x = clist->column[i].area.x + clist->hoffset; - clip_rectangle.width = clist->column[i].area.width; + GTK_WIDGET_CLASS (parent_class)->unrealize (widget); - cell_rectangle.x = clip_rectangle.x - COLUMN_INSET - CELL_SPACING; - cell_rectangle.width = (clip_rectangle.width + 2 * COLUMN_INSET + - (1 + (i == last_column)) * CELL_SPACING); - cell_rectangle.y = clip_rectangle.y; - cell_rectangle.height = clip_rectangle.height; + ctree = GTK_CMCTREE (widget); + clist = GTK_CMCLIST (widget); - string_width = 0; - pixbuf_width = 0; - height = 0; + if (gtk_widget_get_realized (widget)) + { + GtkCMCTreeNode *node; + GtkCMCTreeNode *child; + gint i; - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) + node = GTK_CMCTREE_NODE (clist->row_list); + for (i = 0; i < clist->rows; i++) { - if (i != ctree->tree_column) - continue; + if (GTK_CMCTREE_ROW (node)->children && + !GTK_CMCTREE_ROW (node)->expanded) + for (child = GTK_CMCTREE_ROW (node)->children; child; + child = GTK_CMCTREE_ROW (child)->sibling) + gtk_cmctree_pre_recursive(ctree, child, ctree_detach_styles, NULL); + node = GTK_CMCTREE_NODE_NEXT (node); } - else - { - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - crect->x, crect->y, crect->width, crect->height); + } +} +static gint +gtk_cmctree_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + GtkCMCTree *ctree; + GtkCMCList *clist; + gint button_actions; - layout = _gtk_cmclist_create_cell_layout (clist, clist_row, i); - if (layout) - { - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - width = logical_rect.width; - } - else - width = 0; + cm_return_val_if_fail (GTK_IS_CMCTREE (widget), FALSE); + cm_return_val_if_fail (event != NULL, FALSE); - switch (clist_row->cell[i].type) - { - case GTK_CMCELL_PIXBUF: - pixbuf_width = gdk_pixbuf_get_width(GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height(GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf); - width += pixbuf_width; - break; - case GTK_CMCELL_PIXTEXT: - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - { - pixbuf_width = gdk_pixbuf_get_width(GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height(GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf); - width += pixbuf_width; - } + ctree = GTK_CMCTREE (widget); + clist = GTK_CMCLIST (widget); - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->text && - GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - width += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; + button_actions = clist->button_actions[event->button - 1]; - if (i == ctree->tree_column) - width += (ctree->tree_indent * - ((GtkCMCTreeRow *)clist_row)->level); - break; - default: - break; - } + if (button_actions == GTK_CMBUTTON_IGNORED) + return FALSE; - switch (clist->column[i].justification) - { - case GTK_JUSTIFY_LEFT: - offset = clip_rectangle.x + clist_row->cell[i].horizontal; - break; - case GTK_JUSTIFY_RIGHT: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - clip_rectangle.width - width); - break; - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - (clip_rectangle.width / 2) - (width / 2)); - break; - }; + if (event->window == clist->clist_window) + { + GtkCMCTreeNode *work; + gint x; + gint y; + gint row; + gint column; - if (i != ctree->tree_column) - { - offset += clist_row->cell[i].horizontal; - switch (clist_row->cell[i].type) - { - case GTK_CMCELL_PIXBUF: - draw_cell_pixbuf - (clist->clist_window, &clip_rectangle, fg_gc, - GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2, - pixbuf_width, height); - break; - case GTK_CMCELL_PIXTEXT: - offset = draw_cell_pixbuf - (clist->clist_window, &clip_rectangle, fg_gc, - GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2, - pixbuf_width, height); - offset += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; + x = event->x; + y = event->y; - /* Fall through */ - case GTK_CMCELL_TEXT: - if (layout) - { - gint row_center_offset = (clist->row_height - logical_rect.height) / 2; + if (!gtk_cmclist_get_selection_info (clist, x, y, &row, &column)) + return FALSE; - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_layout (clist->clist_window, fg_gc, - offset, - row_rectangle.y + row_center_offset + clist_row->cell[i].vertical, - layout); - gdk_gc_set_clip_rectangle (fg_gc, NULL); - g_object_unref (G_OBJECT (layout)); - } - break; - default: - break; - } - continue; - } + work = GTK_CMCTREE_NODE (g_list_nth (clist->row_list, row)); + + if (button_actions & GTK_CMBUTTON_EXPANDS && + (GTK_CMCTREE_ROW (work)->children && !GTK_CMCTREE_ROW (work)->is_leaf && + (event->type == GDK_2BUTTON_PRESS || + ctree_is_hot_spot (ctree, work, row, x, y)))) + { + if (GTK_CMCTREE_ROW (work)->expanded) + gtk_cmctree_collapse (ctree, work); + else + gtk_cmctree_expand (ctree, work); + + return TRUE; } + } + + return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event); +} + +static void +draw_drag_highlight (GtkCMCList *clist, + GtkCMCListRow *dest_row, + gint dest_row_number, + GtkCMCListDragPos drag_pos) +{ + GtkAllocation allocation; + GtkCMCTree *ctree; + GdkPoint points[4]; + gint level; + gint i; + gint y = 0; - if (bg_gc == clist->bg_gc) - gdk_gc_set_background (ctree->lines_gc, &clist_row->background); + cm_return_if_fail (GTK_IS_CMCTREE (clist)); - /* draw ctree->tree_column */ - cell_rectangle.y -= CELL_SPACING; - cell_rectangle.height += CELL_SPACING; + ctree = GTK_CMCTREE (clist); + gtk_widget_get_allocation(GTK_WIDGET(ctree), &allocation); - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) - { - if (layout) - g_object_unref (G_OBJECT (layout)); - continue; - } + level = ((GtkCMCTreeRow *)(dest_row))->level; - /* draw lines */ - offset = gtk_cmctree_draw_lines (ctree, (GtkCMCTreeRow *)clist_row, row, i, - state, &clip_rectangle, &cell_rectangle, - crect, area, style); + y = ROW_TOP_YPIXEL (clist, dest_row_number) - 1; - /* draw expander */ - offset = gtk_cmctree_draw_expander (ctree, (GtkCMCTreeRow *)clist_row, - style, &clip_rectangle, offset); + switch (drag_pos) + { + case GTK_CMCLIST_DRAG_NONE: + break; + case GTK_CMCLIST_DRAG_AFTER: + y += clist->row_height + 1; + case GTK_CMCLIST_DRAG_BEFORE: + + if (clist->column[ctree->tree_column].visible) + switch (clist->column[ctree->tree_column].justification) + { + case GTK_JUSTIFY_CENTER: + case GTK_JUSTIFY_FILL: + case GTK_JUSTIFY_LEFT: + if (ctree->tree_column > 0) + gdk_draw_line (clist->clist_window, clist->xor_gc, + COLUMN_LEFT_XPIXEL(clist, 0), y, + COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1)+ + clist->column[ctree->tree_column - 1].area.width, + y); - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= ctree->tree_spacing; + gdk_draw_line (clist->clist_window, clist->xor_gc, + COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + + ctree->tree_indent * level - + (ctree->tree_indent - PM_SIZE) / 2, y, + allocation.width, y); + break; + case GTK_JUSTIFY_RIGHT: + if (ctree->tree_column < clist->columns - 1) + gdk_draw_line (clist->clist_window, clist->xor_gc, + COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1), + y, + COLUMN_LEFT_XPIXEL(clist, clist->columns - 1) + + clist->column[clist->columns - 1].area.width, y); + + gdk_draw_line (clist->clist_window, clist->xor_gc, + 0, y, COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + + clist->column[ctree->tree_column].area.width - + ctree->tree_indent * level + + (ctree->tree_indent - PM_SIZE) / 2, y); + break; + } else - offset += ctree->tree_spacing; + gdk_draw_line (clist->clist_window, clist->xor_gc, + 0, y, clist->clist_window_width, y); + break; + case GTK_CMCLIST_DRAG_INTO: + y = ROW_TOP_YPIXEL (clist, dest_row_number) + clist->row_height; - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= (pixbuf_width + clist_row->cell[i].horizontal); - else - offset += clist_row->cell[i].horizontal; + if (clist->column[ctree->tree_column].visible) + switch (clist->column[ctree->tree_column].justification) + { + case GTK_JUSTIFY_CENTER: + case GTK_JUSTIFY_FILL: + case GTK_JUSTIFY_LEFT: + points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + + ctree->tree_indent * level - (ctree->tree_indent - PM_SIZE) / 2; + points[0].y = y; + points[3].x = points[0].x; + points[3].y = y - clist->row_height - 1; + points[1].x = clist->clist_window_width - 1; + points[1].y = points[0].y; + points[2].x = points[1].x; + points[2].y = points[3].y; - old_offset = offset; - offset = draw_cell_pixbuf (clist->clist_window, &clip_rectangle, fg_gc, - GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical - + (clip_rectangle.height - height) / 2, - pixbuf_width, height); + for (i = 0; i < 3; i++) + gdk_draw_line (clist->clist_window, clist->xor_gc, + points[i].x, points[i].y, + points[i+1].x, points[i+1].y); - if (layout) - { - gint row_center_offset = (clist->row_height - logical_rect.height) / 2; - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - { - offset = (old_offset - string_width); - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset -= GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - } - else - { - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - } - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_layout (clist->clist_window, fg_gc, - offset, - row_rectangle.y + row_center_offset + clist_row->cell[i].vertical, - layout); + if (ctree->tree_column > 0) + { + points[0].x = COLUMN_LEFT_XPIXEL(clist, + ctree->tree_column - 1) + + clist->column[ctree->tree_column - 1].area.width ; + points[0].y = y; + points[3].x = points[0].x; + points[3].y = y - clist->row_height - 1; + points[1].x = 0; + points[1].y = points[0].y; + points[2].x = 0; + points[2].y = points[3].y; - g_object_unref (G_OBJECT (layout)); - } - gdk_gc_set_clip_rectangle (fg_gc, NULL); - } + for (i = 0; i < 3; i++) + gdk_draw_line (clist->clist_window, clist->xor_gc, + points[i].x, points[i].y, points[i+1].x, + points[i+1].y); + } + break; + case GTK_JUSTIFY_RIGHT: + points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - + ctree->tree_indent * level + (ctree->tree_indent - PM_SIZE) / 2 + + clist->column[ctree->tree_column].area.width; + points[0].y = y; + points[3].x = points[0].x; + points[3].y = y - clist->row_height - 1; + points[1].x = 0; + points[1].y = points[0].y; + points[2].x = 0; + points[2].y = points[3].y; - /* draw focus rectangle */ - if (clist->focus_row == row && - gtk_widget_get_can_focus (widget) && gtk_widget_has_focus (widget)) - { - if (!area) + for (i = 0; i < 3; i++) + gdk_draw_line (clist->clist_window, clist->xor_gc, + points[i].x, points[i].y, + points[i+1].x, points[i+1].y); + + if (ctree->tree_column < clist->columns - 1) + { + points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column +1); + points[0].y = y; + points[3].x = points[0].x; + points[3].y = y - clist->row_height - 1; + points[1].x = clist->clist_window_width - 1; + points[1].y = points[0].y; + points[2].x = points[1].x; + points[2].y = points[3].y; + + for (i = 0; i < 3; i++) + gdk_draw_line (clist->clist_window, clist->xor_gc, + points[i].x, points[i].y, + points[i+1].x, points[i+1].y); + } + break; + } + else gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, row_rectangle.height - 1); - else if (gdk_rectangle_intersect (area, &row_rectangle, - &intersect_rectangle)) - { - gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle); - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, - row_rectangle.height - 1); - gdk_gc_set_clip_rectangle (clist->xor_gc, NULL); - } + 0, y - clist->row_height, + clist->clist_window_width - 1, clist->row_height); + break; } } -static void -tree_draw_node (GtkCMCTree *ctree, - GtkCMCTreeNode *node) +static gint +gtk_cmctree_get_offset(GtkCMCTree *ctree, + GtkCMCTreeRow *ctree_row, + gint column, + GdkRectangle *clip_rectangle) { - GtkCMCList *clist; - - clist = GTK_CMCLIST (ctree); + gint justify_right = (GTK_CMCLIST (ctree)->column[column].justification == GTK_JUSTIFY_RIGHT); - if (CLIST_UNFROZEN (clist) && gtk_cmctree_is_viewable (ctree, node)) - { - GtkCMCTreeNode *work; - gint num = 0; - - work = GTK_CMCTREE_NODE (clist->row_list); - while (work && work != node) - { - work = GTK_CMCTREE_NODE_NEXT (work); - num++; - } - if (work && gtk_cmclist_row_is_visible (clist, num) != GTK_VISIBILITY_NONE) - GTK_CMCLIST_GET_CLASS (clist)->draw_row - (clist, NULL, num, GTK_CMCLIST_ROW ((GList *) node)); - } + if (justify_right) + return (clip_rectangle->x + clip_rectangle->width - 1 - + ctree->tree_indent * (ctree_row->level - 1)); + + return clip_rectangle->x + ctree->tree_indent * (ctree_row->level - 1); } static GtkCMCTreeNode * @@ -2938,7 +2420,7 @@ cell_size_request (GtkCMCList *clist, ctree = GTK_CMCTREE (clist); - layout = _gtk_cmclist_create_cell_layout (clist, clist_row, column); + layout = create_cell_layout (clist, clist_row, column); if (layout) { pango_layout_get_pixel_extents (layout, NULL, &logical_rect); @@ -2980,13 +2462,7 @@ cell_size_request (GtkCMCList *clist, case GTK_CMCTREE_EXPANDER_TRIANGLE: requisition->width += PM_SIZE + 3; break; - case GTK_CMCTREE_EXPANDER_SQUARE: - case GTK_CMCTREE_EXPANDER_CIRCULAR: - requisition->width += PM_SIZE + 1; - break; } - if (ctree->line_style == GTK_CMCTREE_LINES_TABBED) - requisition->width += 3; } break; case GTK_CMCELL_PIXBUF: @@ -3393,6 +2869,31 @@ real_unselect_row (GtkCMCList *clist, } static void +tree_draw_node (GtkCMCTree *ctree, + GtkCMCTreeNode *node) +{ + GtkCMCList *clist; + + clist = GTK_CMCLIST (ctree); + + if (CLIST_UNFROZEN (clist) && gtk_cmctree_is_viewable (ctree, node)) + { + GtkCMCTreeNode *work; + gint num = 0; + + work = GTK_CMCTREE_NODE (clist->row_list); + while (work && work != node) + { + work = GTK_CMCTREE_NODE_NEXT (work); + num++; + } + if (work && gtk_cmclist_row_is_visible (clist, num) != GTK_VISIBILITY_NONE) + GTK_CMCLIST_GET_CLASS(ctree)->draw_row + (clist, NULL, num, GTK_CMCLIST_ROW ((GList *) node)); + } +} + +static void real_tree_select (GtkCMCTree *ctree, GtkCMCTreeNode *node, gint column) @@ -3608,12 +3109,10 @@ ctree_is_hot_spot (GtkCMCTree *ctree, if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) xl = (clist->column[ctree->tree_column].area.x + clist->column[ctree->tree_column].area.width - 1 + clist->hoffset - - (tree_row->level - 1) * ctree->tree_indent - PM_SIZE - - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3); + (tree_row->level - 1) * ctree->tree_indent - PM_SIZE); else xl = (clist->column[ctree->tree_column].area.x + clist->hoffset + - (tree_row->level - 1) * ctree->tree_indent + - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3); + (tree_row->level - 1) * ctree->tree_indent); return (x >= xl && x <= xl + PM_SIZE && y >= yu && y <= yu + PM_SIZE); } @@ -5338,59 +4837,6 @@ void gtk_cmctree_set_line_style (GtkCMCTree *ctree, GtkCMCTreeLineStyle line_style) { - GtkCMCList *clist; - GtkCMCTreeLineStyle old_style; - - cm_return_if_fail (GTK_IS_CMCTREE (ctree)); - - if (line_style == ctree->line_style) - return; - - clist = GTK_CMCLIST (ctree); - - old_style = ctree->line_style; - ctree->line_style = line_style; - - if (clist->column[ctree->tree_column].auto_resize && - !GTK_CMCLIST_AUTO_RESIZE_BLOCKED (clist)) - { - if (old_style == GTK_CMCTREE_LINES_TABBED) - gtk_cmclist_set_column_width - (clist, ctree->tree_column, - clist->column[ctree->tree_column].width - 3); - else if (line_style == GTK_CMCTREE_LINES_TABBED) - gtk_cmclist_set_column_width - (clist, ctree->tree_column, - clist->column[ctree->tree_column].width + 3); - } - - if (gtk_widget_get_realized (GTK_WIDGET(ctree))) - { - switch (line_style) - { - case GTK_CMCTREE_LINES_SOLID: - if (gtk_widget_get_realized (GTK_WIDGET(ctree))) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, GDK_LINE_SOLID, - GDK_CAP_BUTT, GDK_JOIN_MITER); - break; - case GTK_CMCTREE_LINES_DOTTED: - if (gtk_widget_get_realized (GTK_WIDGET(ctree))) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, - GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER); - gdk_gc_set_dashes (ctree->lines_gc, 0, "\1\1", 2); - break; - case GTK_CMCTREE_LINES_TABBED: - if (gtk_widget_get_realized (GTK_WIDGET(ctree))) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, GDK_LINE_SOLID, - GDK_CAP_BUTT, GDK_JOIN_MITER); - break; - case GTK_CMCTREE_LINES_NONE: - break; - default: - return; - } - CLIST_REFRESH (ctree); - } } void @@ -5423,10 +4869,6 @@ gtk_cmctree_set_expander_style (GtkCMCTree *ctree, case GTK_CMCTREE_EXPANDER_TRIANGLE: new_width -= PM_SIZE + 3; break; - case GTK_CMCTREE_EXPANDER_SQUARE: - case GTK_CMCTREE_EXPANDER_CIRCULAR: - new_width -= PM_SIZE + 1; - break; } switch (expander_style) @@ -5436,10 +4878,6 @@ gtk_cmctree_set_expander_style (GtkCMCTree *ctree, case GTK_CMCTREE_EXPANDER_TRIANGLE: new_width += PM_SIZE + 3; break; - case GTK_CMCTREE_EXPANDER_SQUARE: - case GTK_CMCTREE_EXPANDER_CIRCULAR: - new_width += PM_SIZE + 1; - break; } gtk_cmclist_set_column_width (clist, ctree->tree_column, new_width); diff --git a/src/gtk/gtkcmctree.h b/src/gtk/gtkcmctree.h @@ -68,18 +68,13 @@ typedef enum typedef enum { - GTK_CMCTREE_LINES_NONE, - GTK_CMCTREE_LINES_SOLID, - GTK_CMCTREE_LINES_DOTTED, - GTK_CMCTREE_LINES_TABBED + GTK_CMCTREE_LINES_NONE } GtkCMCTreeLineStyle; typedef enum { GTK_CMCTREE_EXPANDER_NONE, - GTK_CMCTREE_EXPANDER_SQUARE, - GTK_CMCTREE_EXPANDER_TRIANGLE, - GTK_CMCTREE_EXPANDER_CIRCULAR + GTK_CMCTREE_EXPANDER_TRIANGLE } GtkCMCTreeExpanderStyle; typedef enum @@ -116,8 +111,6 @@ struct _GtkCMCTree { GtkCMCList clist; - GdkGC *lines_gc; - gint tree_indent; gint tree_spacing; gint tree_column; diff --git a/src/gtk/gtksctree.c b/src/gtk/gtksctree.c @@ -152,1129 +152,6 @@ gtk_sctree_get_type (void) return sctree_type; } -static gint -gtk_sctree_draw_cell_pixbuf (GdkWindow *window, - GdkRectangle *clip_rectangle, - GdkGC *fg_gc, - GdkPixbuf *pixbuf, - gint x, - gint y, - gint width, - gint height) -{ - gint xsrc = 0; - gint ysrc = 0; - - gdk_gc_set_clip_origin (fg_gc, x, y); - if (x < clip_rectangle->x) - { - xsrc = clip_rectangle->x - x; - width -= xsrc; - x = clip_rectangle->x; - } - if (x + width > clip_rectangle->x + clip_rectangle->width) - width = clip_rectangle->x + clip_rectangle->width - x; - - if (y < clip_rectangle->y) - { - ysrc = clip_rectangle->y - y; - height -= ysrc; - y = clip_rectangle->y; - } - if (y + height > clip_rectangle->y + clip_rectangle->height) - height = clip_rectangle->y + clip_rectangle->height - y; - - if (width > 0 && height > 0) - gdk_draw_pixbuf (window, fg_gc, pixbuf, xsrc, ysrc, x, y, width, height, GDK_RGB_DITHER_NONE, 0, 0); - - gdk_gc_set_clip_origin (fg_gc, 0, 0); - - return x + MAX (width, 0); -} - -static void -gtk_sctree_get_cell_style (GtkCMCList *clist, - GtkCMCListRow *clist_row, - gint state, - gint row, - gint column, - GtkStyle **style, - GdkGC **fg_gc, - GdkGC **bg_gc) -{ - GtkStyle *gtkstyle; - gint fg_state; - - if ((state == GTK_STATE_NORMAL) && - (gtk_widget_get_state (GTK_WIDGET (clist)) == GTK_STATE_INSENSITIVE)) - fg_state = GTK_STATE_INSENSITIVE; - else - fg_state = state; - - if (clist_row->cell[column].style) - { - if (style) - *style = clist_row->cell[column].style; - if (fg_gc) - *fg_gc = clist_row->cell[column].style->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = clist_row->cell[column].style->bg_gc[state]; - } - } - else if (clist_row->style) - { - if (style) - *style = clist_row->style; - if (fg_gc) - *fg_gc = clist_row->style->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = clist_row->style->bg_gc[state]; - else - *bg_gc = clist_row->bg_set ? - clist->bg_gc : clist_row->style->base_gc[state]; - } - } - else - { - gtkstyle = gtk_widget_get_style (GTK_WIDGET (clist)); - if (style) - *style = gtkstyle; - if (fg_gc) - *fg_gc = gtkstyle->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = gtkstyle->bg_gc[state]; - else - *bg_gc = gtkstyle->base_gc[state]; - } - - if (state != GTK_STATE_SELECTED) - { - if (fg_gc && clist_row->fg_set) - *fg_gc = clist->fg_gc; - if (bg_gc && clist_row->bg_set) - *bg_gc = clist->bg_gc; - } - } -} - -static gint -gtk_sctree_draw_expander (GtkCMCTree *ctree, - GtkCMCTreeRow *ctree_row, - GtkStyle *style, - GdkRectangle *clip_rectangle, - gint x) -{ - GtkCMCList *clist; - GdkPoint points[3]; - gint justification_factor; - gint y; - - if (ctree->expander_style == GTK_CMCTREE_EXPANDER_NONE) - return x; - - clist = GTK_CMCLIST (ctree); - if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) - justification_factor = -1; - else - justification_factor = 1; - if (!GTK_CMCLIST_ROW_HEIGHT_SET(GTK_CMCLIST(clist))) - y = (clip_rectangle->y + (clip_rectangle->height - PM_SIZE) / 2 - - (clip_rectangle->height + 1) % 2); - else - y = (clip_rectangle->y + (clip_rectangle->height/2 - PM_SIZE) / 2 - - (clip_rectangle->height/2 + 1) % 2); - - if (!ctree_row->children) - { - switch (ctree->expander_style) - { - case GTK_CMCTREE_EXPANDER_NONE: - return x; - case GTK_CMCTREE_EXPANDER_TRIANGLE: - return x + justification_factor * (PM_SIZE + 3); - case GTK_CMCTREE_EXPANDER_SQUARE: - case GTK_CMCTREE_EXPANDER_CIRCULAR: - return x + justification_factor * (PM_SIZE + 1); - } - } - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], clip_rectangle); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], clip_rectangle); - - switch (ctree->expander_style) - { - case GTK_CMCTREE_EXPANDER_NONE: - break; - case GTK_CMCTREE_EXPANDER_TRIANGLE: - if (ctree_row->expanded) - { - points[0].x = x; - points[0].y = y + (PM_SIZE + 2) / 6; - points[1].x = points[0].x + justification_factor * (PM_SIZE + 2); - points[1].y = points[0].y; - points[2].x = (points[0].x + - justification_factor * (PM_SIZE + 2) / 2); - points[2].y = y + 2 * (PM_SIZE + 2) / 3; - } - else - { - points[0].x = x + justification_factor * ((PM_SIZE + 2) / 6 + 2); - points[0].y = y - 1; - points[1].x = points[0].x; - points[1].y = points[0].y + (PM_SIZE + 2); - points[2].x = (points[0].x + - justification_factor * (2 * (PM_SIZE + 2) / 3 - 1)); - points[2].y = points[0].y + (PM_SIZE + 2) / 2; - } - - gdk_draw_polygon (clist->clist_window, style->base_gc[GTK_STATE_NORMAL], - TRUE, points, 3); - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - FALSE, points, 3); - - x += justification_factor * (PM_SIZE + 3); - break; - case GTK_CMCTREE_EXPANDER_SQUARE: - case GTK_CMCTREE_EXPANDER_CIRCULAR: - if (justification_factor == -1) - x += justification_factor * (PM_SIZE + 1); - - if (ctree->expander_style == GTK_CMCTREE_EXPANDER_CIRCULAR) - { - gdk_draw_arc (clist->clist_window, style->base_gc[GTK_STATE_NORMAL], - TRUE, x, y, PM_SIZE, PM_SIZE, 0, 360 * 64); - gdk_draw_arc (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - FALSE, x, y, PM_SIZE, PM_SIZE, 0, 360 * 64); - } - else - { - gdk_draw_rectangle (clist->clist_window, - style->base_gc[GTK_STATE_NORMAL], TRUE, - x, y, PM_SIZE, PM_SIZE); - gdk_draw_rectangle (clist->clist_window, - style->fg_gc[GTK_STATE_NORMAL], FALSE, - x, y, PM_SIZE, PM_SIZE); - } - - gdk_draw_line (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - x + 2, y + PM_SIZE / 2, x + PM_SIZE - 2, y + PM_SIZE / 2); - - if (!ctree_row->expanded) - gdk_draw_line (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], - x + PM_SIZE / 2, y + 2, - x + PM_SIZE / 2, y + PM_SIZE - 2); - - if (justification_factor == 1) - x += justification_factor * (PM_SIZE + 1); - break; - } - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL); - - return x; -} - -static gint -gtk_sctree_draw_lines (GtkCMCTree *ctree, - GtkCMCTreeRow *ctree_row, - gint row, - gint column, - gint state, - GdkRectangle *clip_rectangle, - GdkRectangle *cell_rectangle, - GdkRectangle *crect, - GdkRectangle *area, - GtkStyle *style) -{ - GtkCMCList *clist; - GtkCMCTreeNode *node; - GtkCMCTreeNode *parent; - GdkRectangle tree_rectangle; - GdkRectangle tc_rectangle; - GdkGC *bg_gc; - gint offset; - gint offset_x; - gint offset_y; - gint xcenter; - gint ycenter; - gint next_level; - gint column_right; - gint column_left; - gint justify_right; - gint justification_factor; - - clist = GTK_CMCLIST (ctree); - ycenter = clip_rectangle->y + (clip_rectangle->height / 2); - justify_right = (clist->column[column].justification == GTK_JUSTIFY_RIGHT); - - if (justify_right) - { - offset = (clip_rectangle->x + clip_rectangle->width - 1 - - ctree->tree_indent * (ctree_row->level - 1)); - justification_factor = -1; - } - else - { - offset = clip_rectangle->x + ctree->tree_indent * (ctree_row->level - 1); - justification_factor = 1; - } - - switch (ctree->line_style) - { - case GTK_CMCTREE_LINES_NONE: - break; - case GTK_CMCTREE_LINES_TABBED: - xcenter = offset + justification_factor * TAB_SIZE; - - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - CELL_SPACING); - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter; - tree_rectangle.width = column_right - xcenter; - } - else - { - tree_rectangle.x = column_left; - tree_rectangle.width = xcenter - column_left; - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - { - offset += justification_factor * 3; - break; - } - } - - gdk_gc_set_clip_rectangle (ctree->lines_gc, crect); - - next_level = ctree_row->level; - - if (!ctree_row->sibling || (ctree_row->children && ctree_row->expanded)) - { - node = gtk_cmctree_find_node_ptr (ctree, ctree_row); - if (GTK_CMCTREE_NODE_NEXT (node)) - next_level = GTK_CMCTREE_ROW (GTK_CMCTREE_NODE_NEXT (node))->level; - else - next_level = 0; - } - - if (ctree->tree_indent > 0) - { - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if ((justify_right && xcenter < column_left) || - (!justify_right && xcenter > column_right)) - { - node = GTK_CMCTREE_ROW (node)->parent; - continue; - } - - tree_rectangle.y = cell_rectangle->y; - tree_rectangle.height = cell_rectangle->height; - if (justify_right) - { - tree_rectangle.x = MAX (xcenter - ctree->tree_indent + 1, - column_left); - tree_rectangle.width = MIN (xcenter - column_left, - ctree->tree_indent); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - ctree->tree_indent); - } - - if (!area || gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - gtk_sctree_get_cell_style (clist, &GTK_CMCTREE_ROW (node)->row, - state, row, column, NULL, NULL, &bg_gc); - - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &GTK_CMCTREE_ROW (node)->row.background); - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - if (next_level > GTK_CMCTREE_ROW (node)->level) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, crect->y, - xcenter, crect->y + crect->height); - else - { - gint width; - - offset_x = MIN (ctree->tree_indent, 2 * TAB_SIZE); - width = offset_x / 2 + offset_x % 2; - - parent = GTK_CMCTREE_ROW (node)->parent; - - tree_rectangle.y = ycenter; - tree_rectangle.height = (cell_rectangle->y - ycenter + - cell_rectangle->height); - - if (justify_right) - { - tree_rectangle.x = MAX(xcenter + 1 - width, column_left); - tree_rectangle.width = MIN (xcenter + 1 - column_left, - width); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - width); - } - - if (!area || - gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - if (parent) - { - gtk_sctree_get_cell_style (clist, &GTK_CMCTREE_ROW (parent)->row, - state, row, column, NULL, NULL, &bg_gc); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, - &GTK_CMCTREE_ROW (parent)->row.background); - } - else if (state == GTK_STATE_SELECTED) - bg_gc = style->base_gc[state]; - else - bg_gc = gtk_widget_get_style (GTK_WIDGET (clist))->base_gc[state]; - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, - bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - gtk_sctree_get_cell_style (clist, &GTK_CMCTREE_ROW (node)->row, - state, row, column, NULL, NULL, &bg_gc); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &GTK_CMCTREE_ROW (node)->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - xcenter - (justify_right * offset_x), - cell_rectangle->y, - offset_x, clist->row_height, - (180 + (justify_right * 90)) * 64, 90 * 64); - gdk_gc_set_clip_rectangle (bg_gc, NULL); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y, xcenter, ycenter); - - if (justify_right) - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter - offset_x, cell_rectangle->y, - offset_x, clist->row_height, - 270 * 64, 90 * 64); - else - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter, cell_rectangle->y, - offset_x, clist->row_height, - 180 * 64, 90 * 64); - } - node = GTK_CMCTREE_ROW (node)->parent; - } - } - - if (state != GTK_STATE_SELECTED) - { - tree_rectangle.y = clip_rectangle->y; - tree_rectangle.height = clip_rectangle->height; - tree_rectangle.width = COLUMN_INSET + CELL_SPACING + - MIN (clist->column[ctree->tree_column].area.width + COLUMN_INSET, - TAB_SIZE); - - if (justify_right) - tree_rectangle.x = MAX (xcenter + 1, column_left); - else - tree_rectangle.x = column_left; - - if (!area) - gdk_draw_rectangle (clist->clist_window, - gtk_widget_get_style (GTK_WIDGET - (ctree))->base_gc[GTK_STATE_NORMAL], - TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else if (gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - gdk_draw_rectangle (clist->clist_window, - gtk_widget_get_style (GTK_WIDGET - (ctree))->base_gc[GTK_STATE_NORMAL], - TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - xcenter = offset + (justification_factor * ctree->tree_indent / 2); - - gtk_sctree_get_cell_style (clist, &ctree_row->row, state, row, column, NULL, NULL, - &bg_gc); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground (clist->bg_gc, &ctree_row->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - if (ctree_row->is_leaf) - { - GdkPoint points[6]; - - points[0].x = offset + justification_factor * TAB_SIZE; - points[0].y = cell_rectangle->y; - - points[1].x = points[0].x - justification_factor * 4; - points[1].y = points[0].y; - - points[2].x = points[1].x - justification_factor * 2; - points[2].y = points[1].y + 3; - - points[3].x = points[2].x; - points[3].y = points[2].y + clist->row_height - 5; - - points[4].x = points[3].x + justification_factor * 2; - points[4].y = points[3].y + 3; - - points[5].x = points[4].x + justification_factor * 4; - points[5].y = points[4].y; - - gdk_draw_polygon (clist->clist_window, bg_gc, TRUE, points, 6); - gdk_draw_lines (clist->clist_window, ctree->lines_gc, points, 6); - } - else - { - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - } - gdk_gc_set_clip_rectangle (bg_gc, NULL); - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - - offset += justification_factor * 3; - break; - default: - xcenter = offset + justification_factor * PM_SIZE / 2; - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter - PM_SIZE / 2 - 2; - tree_rectangle.width = (clip_rectangle->x + - clip_rectangle->width -tree_rectangle.x); - } - else - { - tree_rectangle.x = clip_rectangle->x + PM_SIZE / 2; - tree_rectangle.width = (xcenter + PM_SIZE / 2 + 2 - - clip_rectangle->x); - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - break; - } - - offset_x = 1; - offset_y = 0; - if (ctree->line_style == GTK_CMCTREE_LINES_DOTTED) - { - offset_x += abs((clip_rectangle->x + clist->hoffset) % 2); - offset_y = abs((cell_rectangle->y + clist->voffset) % 2); - } - - clip_rectangle->y--; - clip_rectangle->height++; - gdk_gc_set_clip_rectangle (ctree->lines_gc, clip_rectangle); - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, - (ctree->show_stub || clist->row_list->data != ctree_row) ? - cell_rectangle->y + offset_y : ycenter, - xcenter, - (ctree_row->sibling) ? crect->y +crect->height : ycenter); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter + (justification_factor * offset_x), ycenter, - xcenter + (justification_factor * (PM_SIZE / 2 + 2)), - ycenter); - - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if (GTK_CMCTREE_ROW (node)->sibling) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y + offset_y, - xcenter, crect->y + crect->height); - node = GTK_CMCTREE_ROW (node)->parent; - } - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - clip_rectangle->y++; - clip_rectangle->height--; - break; - } - return offset; -} - -static gboolean filter_fg (PangoAttribute *attribute, gpointer data) -{ - const PangoAttrClass *klass = attribute->klass; - if (klass->type == PANGO_ATTR_FOREGROUND) - return TRUE; - - return FALSE; -} - -static PangoLayout * -sc_gtk_cmclist_create_cell_layout (GtkCMCList *clist, - GtkCMCListRow *clist_row, - gint column) -{ - PangoLayout *layout; - GtkStyle *style; - GtkCMCell *cell; - gchar *text; - - gtk_sctree_get_cell_style (clist, clist_row, GTK_STATE_NORMAL, 0, column, &style, - NULL, NULL); - - - cell = &clist_row->cell[column]; - switch (cell->type) - { - case GTK_CMCELL_TEXT: - case GTK_CMCELL_PIXTEXT: - text = ((cell->type == GTK_CMCELL_PIXTEXT) ? - GTK_CMCELL_PIXTEXT (*cell)->text : - GTK_CMCELL_TEXT (*cell)->text); - - if (!text) - return NULL; - - if (!GTK_SCTREE(clist)->use_markup[column]) { - layout = gtk_widget_create_pango_layout (GTK_WIDGET (clist), - ((cell->type == GTK_CMCELL_PIXTEXT) ? - GTK_CMCELL_PIXTEXT (*cell)->text : - GTK_CMCELL_TEXT (*cell)->text)); - pango_layout_set_font_description (layout, style->font_desc); - } else { - PangoContext *context = gtk_widget_get_pango_context (GTK_WIDGET(clist)); - layout = pango_layout_new (context); - pango_layout_set_markup (layout, text, -1); - pango_layout_set_font_description (layout, style->font_desc); - if (clist_row->state == GTK_STATE_SELECTED) { - /* for selected row, we should remove any forced foreground color - * or it looks like shit */ - PangoAttrList *list = pango_layout_get_attributes(layout); - PangoAttrList *rem = pango_attr_list_filter(list, filter_fg, NULL); - if (rem) - pango_attr_list_unref(rem); - } - } - - return layout; - - default: - return NULL; - } -} - -static void -gtk_sctree_draw_row (GtkCMCList *clist, - GdkRectangle *area, - gint row, - GtkCMCListRow *clist_row) -{ - GtkWidget *widget; - GtkStyle *style; - GtkCMCTree *ctree; - GdkRectangle *rect; - GdkRectangle *crect; - GdkRectangle row_rectangle; - GdkRectangle cell_rectangle; - GdkRectangle clip_rectangle; - GdkRectangle intersect_rectangle; - gint last_column; - gint column_left = 0; - gint column_right = 0; - gint offset = 0; - gint state; - gint i; - static GdkColor greybg={0, 0, 0, 0}; - static gboolean color_change = TRUE; - - cm_return_if_fail (clist != NULL); - widget = GTK_WIDGET (clist); - style = gtk_widget_get_style (widget); - - if (greybg.pixel == 0 && - greybg.red == 0 && - greybg.green == 0 && - greybg.blue == 0) { - GdkColor normalbg = {0, 0xffff, 0xffff, 0xffff}; - if (style) { - normalbg = style->base[GTK_STATE_NORMAL]; - } - if (normalbg.red > 0x8888 && normalbg.green > 0x8888 && normalbg.blue > 0x8888) { - greybg.pixel = normalbg.pixel; - greybg.red = normalbg.red - prefs_common.stripes_color_offset; - greybg.green = normalbg.green - prefs_common.stripes_color_offset; - greybg.blue = normalbg.blue - prefs_common.stripes_color_offset; - } else if (normalbg.red < 0x8888 && normalbg.green < 0x8888 && normalbg.blue < 0x8888) { - greybg.pixel = normalbg.pixel; - greybg.red = normalbg.red + prefs_common.stripes_color_offset; - greybg.green = normalbg.green + prefs_common.stripes_color_offset; - greybg.blue = normalbg.blue + prefs_common.stripes_color_offset; - } else { - color_change = FALSE; - } - } - - /* bail now if we arn't drawable yet */ - if (!gtk_widget_is_drawable (GTK_WIDGET(clist)) || row < 0 || row >= clist->rows) - return; - - ctree = GTK_CMCTREE (clist); - - /* if the function is passed the pointer to the row instead of null, - * it avoids this expensive lookup */ - if (!clist_row) - clist_row = (g_list_nth (clist->row_list, row))->data; - - /* rectangle of the entire row */ - row_rectangle.x = 0; - row_rectangle.y = ROW_TOP_YPIXEL (clist, row); - row_rectangle.width = clist->clist_window_width; - row_rectangle.height = clist->row_height; - - /* rectangle of the cell spacing above the row */ - cell_rectangle.x = 0; - cell_rectangle.y = row_rectangle.y - CELL_SPACING; - cell_rectangle.width = row_rectangle.width; - cell_rectangle.height = CELL_SPACING; - - /* rectangle used to clip drawing operations, its y and height - * positions only need to be set once, so we set them once here. - * the x and width are set withing the drawing loop below once per - * column */ - clip_rectangle.y = row_rectangle.y; - clip_rectangle.height = row_rectangle.height; - - if (prefs_common.use_stripes_everywhere && GTK_SCTREE(ctree)->show_stripes - && color_change && row % 2) { - clist_row->background = greybg; - clist_row->bg_set = TRUE; - } else { - clist_row->bg_set = FALSE; - } - if (clist_row->state == GTK_STATE_NORMAL) - { - if (clist_row->fg_set) - gdk_gc_set_foreground (clist->fg_gc, &clist_row->foreground); - if (clist_row->bg_set) - gdk_gc_set_rgb_fg_color (clist->bg_gc, &clist_row->background); - } - - state = clist_row->state; - - gdk_gc_set_foreground (ctree->lines_gc, - &style->fg[clist_row->state]); - - /* draw the cell borders */ - if (area) - { - rect = &intersect_rectangle; - crect = &intersect_rectangle; - - if (gdk_rectangle_intersect (area, &cell_rectangle, crect)) - gdk_draw_rectangle (clist->clist_window, - style->base_gc[GTK_STATE_NORMAL], TRUE, - crect->x, crect->y, crect->width, crect->height); - } - else - { - rect = &clip_rectangle; - crect = &cell_rectangle; - - gdk_draw_rectangle (clist->clist_window, - style->base_gc[GTK_STATE_NORMAL], TRUE, - crect->x, crect->y, crect->width, crect->height); - } - - /* horizontal black lines */ - if (ctree->line_style == GTK_CMCTREE_LINES_TABBED) - { - - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - (ctree->tree_column != 0) * CELL_SPACING); - - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - offset = (column_left + ctree->tree_indent * - (((GtkCMCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (offset + TAB_SIZE, column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - offset = (column_right - 1 - ctree->tree_indent * - (((GtkCMCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (offset - TAB_SIZE, column_left), - cell_rectangle.y); - break; - } - } - - /* the last row has to clear its bottom cell spacing too */ - if (clist_row == clist->row_list_end->data) - { - cell_rectangle.y += clist->row_height + CELL_SPACING; - - if (!area || gdk_rectangle_intersect (area, &cell_rectangle, crect)) - { - gdk_draw_rectangle (clist->clist_window, - style->base_gc[GTK_STATE_NORMAL], TRUE, - crect->x, crect->y, crect->width, crect->height); - - /* horizontal black lines */ - if (ctree->line_style == GTK_CMCTREE_LINES_TABBED) - { - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (column_left + TAB_SIZE + COLUMN_INSET + - (((GtkCMCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (column_right - TAB_SIZE - 1 - - COLUMN_INSET - - (((GtkCMCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_left - 1), cell_rectangle.y); - break; - } - } - } - } - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; - - /* iterate and draw all the columns (row cells) and draw their contents */ - for (i = 0; i < clist->columns; i++) - { - GtkStyle *style; - GdkGC *fg_gc; - GdkGC *bg_gc; - PangoLayout *layout = NULL; - PangoRectangle logical_rect; - - gint width; - gint height; - gint pixbuf_width; - gint string_width; - gint old_offset; - - if (!clist->column[i].visible) - continue; - - gtk_sctree_get_cell_style (clist, clist_row, state, row, i, &style, &fg_gc, &bg_gc); - - /* calculate clipping region */ - clip_rectangle.x = clist->column[i].area.x + clist->hoffset; - clip_rectangle.width = clist->column[i].area.width; - - cell_rectangle.x = clip_rectangle.x - COLUMN_INSET - CELL_SPACING; - cell_rectangle.width = (clip_rectangle.width + 2 * COLUMN_INSET + - (1 + (i == last_column)) * CELL_SPACING); - cell_rectangle.y = clip_rectangle.y; - cell_rectangle.height = clip_rectangle.height; - - string_width = 0; - pixbuf_width = 0; - height = 0; - - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) - { - if (i != ctree->tree_column) - continue; - } - else - { - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - crect->x, crect->y, crect->width, crect->height); - - - layout = sc_gtk_cmclist_create_cell_layout (clist, clist_row, i); - if (layout) - { - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - width = logical_rect.width; - } - else - width = 0; - - switch (clist_row->cell[i].type) - { - case GTK_CMCELL_PIXBUF: - pixbuf_width = gdk_pixbuf_get_width(GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height(GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf); - width += pixbuf_width; - break; - case GTK_CMCELL_PIXTEXT: - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - { - pixbuf_width = gdk_pixbuf_get_width(GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height(GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf); - width += pixbuf_width; - } - - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->text && - GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - width += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - - if (i == ctree->tree_column) - width += (ctree->tree_indent * - ((GtkCMCTreeRow *)clist_row)->level); - break; - default: - break; - } - - switch (clist->column[i].justification) - { - case GTK_JUSTIFY_LEFT: - offset = clip_rectangle.x + clist_row->cell[i].horizontal; - break; - case GTK_JUSTIFY_RIGHT: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - clip_rectangle.width - width); - break; - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - (clip_rectangle.width / 2) - (width / 2)); - break; - }; - - if (i != ctree->tree_column) - { - int start_y = (clip_rectangle.height - height) / 2; - if (GTK_CMCLIST_ROW_HEIGHT_SET(GTK_CMCLIST(clist))) - start_y = (clip_rectangle.height/2 - height) / 2; - - offset += clist_row->cell[i].horizontal; - switch (clist_row->cell[i].type) - { - case GTK_CMCELL_PIXBUF: - gtk_sctree_draw_cell_pixbuf - (clist->clist_window, &clip_rectangle, fg_gc, - GTK_CMCELL_PIXBUF (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - start_y, - pixbuf_width, height); - break; - case GTK_CMCELL_PIXTEXT: - offset = gtk_sctree_draw_cell_pixbuf - (clist->clist_window, &clip_rectangle, fg_gc, - GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - start_y, - pixbuf_width, height); - offset += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - - /* Fall through */ - case GTK_CMCELL_TEXT: - if (layout) - { - gint row_center_offset = (clist->row_height - logical_rect.height) / 2; - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_layout (clist->clist_window, fg_gc, - offset, - row_rectangle.y + row_center_offset + clist_row->cell[i].vertical, - layout); - gdk_gc_set_clip_rectangle (fg_gc, NULL); - g_object_unref (G_OBJECT (layout)); - } - break; - default: - break; - } - continue; - } - } - - if (bg_gc == clist->bg_gc) - gdk_gc_set_background (ctree->lines_gc, &clist_row->background); - - /* draw ctree->tree_column */ - cell_rectangle.y -= CELL_SPACING; - cell_rectangle.height += CELL_SPACING; - - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) - { - if (layout) - g_object_unref (G_OBJECT (layout)); - continue; - } - - /* draw lines */ - offset = gtk_sctree_draw_lines (ctree, (GtkCMCTreeRow *)clist_row, row, i, - state, &clip_rectangle, &cell_rectangle, - crect, area, style); - - /* draw expander */ - offset = gtk_sctree_draw_expander (ctree, (GtkCMCTreeRow *)clist_row, - style, &clip_rectangle, offset); - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= ctree->tree_spacing; - else - offset += ctree->tree_spacing; - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= (pixbuf_width + clist_row->cell[i].horizontal); - else - offset += clist_row->cell[i].horizontal; - - old_offset = offset; - offset = gtk_sctree_draw_cell_pixbuf (clist->clist_window, &clip_rectangle, fg_gc, - GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical - + (clip_rectangle.height - height) / 2, - pixbuf_width, height); - - if (layout) - { - gint row_center_offset = (clist->row_height - logical_rect.height) / 2; - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - { - offset = (old_offset - string_width); - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset -= GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - } - else - { - if (GTK_CMCELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset += GTK_CMCELL_PIXTEXT (clist_row->cell[i])->spacing; - } - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_layout (clist->clist_window, fg_gc, - offset, - row_rectangle.y + row_center_offset + clist_row->cell[i].vertical, - layout); - - g_object_unref (G_OBJECT (layout)); - } - gdk_gc_set_clip_rectangle (fg_gc, NULL); - } - - /* draw focus rectangle */ - if (clist->focus_row == row && - gtk_widget_get_can_focus (widget) && gtk_widget_has_focus (widget)) - { - if (!area) - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, row_rectangle.height - 1); - else if (gdk_rectangle_intersect (area, &row_rectangle, - &intersect_rectangle)) - { - gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle); - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, - row_rectangle.height - 1); - gdk_gc_set_clip_rectangle (clist->xor_gc, NULL); - } - } -} - static void gtk_sctree_change_focus_row_expansion (GtkCMCTree *ctree, GtkCMCTreeExpansionType action) @@ -1338,12 +215,10 @@ static void gtk_sctree_class_init (GtkSCTreeClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkCMCListClass *clist_class; GtkCMCTreeClass *ctree_class; - object_class = (GtkObjectClass *) klass; widget_class = (GtkWidgetClass *) klass; clist_class = (GtkCMCListClass *) klass; ctree_class = (GtkCMCTreeClass *) klass; @@ -1390,7 +265,6 @@ gtk_sctree_class_init (GtkSCTreeClass *klass) /* gtk_object_class_add_signals (object_class, sctree_signals, LAST_SIGNAL); */ clist_class->clear = gtk_sctree_clear; - clist_class->draw_row = gtk_sctree_draw_row; clist_class->unselect_all = gtk_sctree_real_unselect_all; ctree_class->tree_collapse = gtk_sctree_real_tree_collapse; ctree_class->tree_expand = gtk_sctree_real_tree_expand; @@ -1542,7 +416,6 @@ sctree_is_hot_spot (GtkSCTree *sctree, GtkCMCTreeRow *tree_row; GtkCMCList *clist; GtkCMCTree *ctree; - GtkCMCellPixText *cell; gint xl, xmax; gint yu; @@ -1558,8 +431,6 @@ sctree_is_hot_spot (GtkSCTree *sctree, tree_row = GTK_CMCTREE_ROW (node); - cell = GTK_CMCELL_PIXTEXT (tree_row->row.cell[ctree->tree_column]); - if (!GTK_CMCLIST_ROW_HEIGHT_SET(GTK_CMCLIST(clist))) yu = (ROW_TOP_YPIXEL (clist, row) + (clist->row_height - PM_SIZE) / 2 - (clist->row_height - 1) % 2); @@ -1569,34 +440,28 @@ sctree_is_hot_spot (GtkSCTree *sctree, #ifndef GENERIC_UMPC if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) - xl = (clist->column[ctree->tree_column].area.x + + xl = clist->column[ctree->tree_column].area.x + clist->column[ctree->tree_column].area.width - 1 + clist->hoffset - - (tree_row->level - 1) * ctree->tree_indent - PM_SIZE - - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3); + (tree_row->level - 1) * ctree->tree_indent - PM_SIZE; else - xl = (clist->column[ctree->tree_column].area.x + clist->hoffset + - (tree_row->level - 1) * ctree->tree_indent + - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3); + xl = clist->column[ctree->tree_column].area.x + clist->hoffset + + (tree_row->level - 1) * ctree->tree_indent; xmax = xl + PM_SIZE; #else if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) { - xl = (clist->column[ctree->tree_column].area.x + + xl = clist->column[ctree->tree_column].area.x + clist->column[ctree->tree_column].area.width - 1 + clist->hoffset - - (tree_row->level - 1) * ctree->tree_indent - PM_SIZE - - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3); + (tree_row->level - 1) * ctree->tree_indent - PM_SIZE; xmax = xl + PM_SIZE; } else if (ctree->tree_column == 0) { - xl = (clist->column[ctree->tree_column].area.x + clist->hoffset + - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3); - xmax = (clist->column[ctree->tree_column].area.x + clist->hoffset + + xl = clist->column[ctree->tree_column].area.x + clist->hoffset; + xmax = clist->column[ctree->tree_column].area.x + clist->hoffset + (tree_row->level - 1) * ctree->tree_indent + - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3) + PM_SIZE; } else { - xl = (clist->column[ctree->tree_column].area.x + clist->hoffset + - (tree_row->level - 1) * ctree->tree_indent + - (ctree->line_style == GTK_CMCTREE_LINES_TABBED) * 3); + xl = clist->column[ctree->tree_column].area.x + clist->hoffset + + (tree_row->level - 1) * ctree->tree_indent; xmax = xl + PM_SIZE; } #endif @@ -2706,83 +1571,6 @@ sset_node_info (GtkCMCTree *ctree, text, spacing, pixbuf_closed); } -static void -stree_draw_node (GtkCMCTree *ctree, - GtkCMCTreeNode *node) -{ - GtkCMCList *clist; - - clist = GTK_CMCLIST (ctree); - - if (CLIST_UNFROZEN (clist) && gtk_cmctree_is_viewable (ctree, node)) - { - GtkCMCTreeNode *work; - gint num = 0; - - work = GTK_CMCTREE_NODE (clist->row_list); - while (work && work != node) - { - work = GTK_CMCTREE_NODE_NEXT (work); - num++; - } - if (work && gtk_cmclist_row_is_visible (clist, num) != GTK_VISIBILITY_NONE) - GTK_CMCLIST_GET_CLASS (clist)->draw_row - (clist, NULL, num, GTK_CMCLIST_ROW ((GList *) node)); - } -} - -/* this wrapper simply replaces NULL pixbufs - * with a transparent, 1x1 pixbuf. This works - * around a memory problem deep inside gtk, - * revealed by valgrind. - */ -void gtk_sctree_set_node_info (GtkCMCTree *ctree, - GtkCMCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded) -{ - gboolean old_leaf; - gboolean old_expanded; - GtkCMCTreeNode *work; - - if (!GTK_IS_CMCTREE (ctree) || !node) return; - - old_leaf = GTK_CMCTREE_ROW (node)->is_leaf; - old_expanded = GTK_CMCTREE_ROW (node)->expanded; - - if (is_leaf && (work = GTK_CMCTREE_ROW (node)->children) != NULL) - { - GtkCMCTreeNode *ptr; - - while (work) - { - ptr = work; - work = GTK_CMCTREE_ROW (work)->sibling; - gtk_cmctree_remove_node (ctree, ptr); - } - } - - sset_node_info (ctree, node, text, spacing, pixbuf_closed, - pixbuf_opened, is_leaf, expanded); - - if (!is_leaf && !old_leaf) - { - GTK_CMCTREE_ROW (node)->expanded = old_expanded; - if (expanded && !old_expanded) - gtk_cmctree_expand (ctree, node); - else if (!expanded && old_expanded) - gtk_cmctree_collapse (ctree, node); - } - - GTK_CMCTREE_ROW (node)->expanded = (is_leaf) ? FALSE : expanded; - - stree_draw_node (ctree, node); -} - static GtkCMCTreeRow * srow_new (GtkCMCTree *ctree) { @@ -2902,7 +1690,6 @@ gtk_sctree_real_tree_expand (GtkCMCTree *ctree, GtkCMCTreeNode *work; GtkRequisition requisition; gboolean visible; - gint level; cm_return_if_fail (GTK_IS_CMCTREE (ctree)); @@ -2914,7 +1701,6 @@ gtk_sctree_real_tree_expand (GtkCMCTree *ctree, GTK_CMCLIST_GET_CLASS (clist)->resync_selection (clist, NULL); GTK_CMCTREE_ROW (node)->expanded = TRUE; - level = GTK_CMCTREE_ROW (node)->level; visible = gtk_cmctree_is_viewable (ctree, node); /* get cell width if tree_column is auto resized */ diff --git a/src/prefs_common.c b/src/prefs_common.c @@ -1064,8 +1064,6 @@ static PrefParam param[] = { NULL, NULL, NULL}, {"stripes_color_offset", "4000", &prefs_common.stripes_color_offset, P_INT, NULL, NULL, NULL}, - {"enable_dotted_lines", "FALSE", &prefs_common.enable_dotted_lines, P_BOOL, - NULL, NULL, NULL}, {"enable_hscrollbar", "TRUE", &prefs_common.enable_hscrollbar, P_BOOL, NULL, NULL, NULL}, {"folderview_vscrollbar_policy", "0", diff --git a/src/prefs_common.h b/src/prefs_common.h @@ -227,7 +227,6 @@ struct _PrefsCommon gboolean use_stripes_everywhere; gboolean use_stripes_in_summaries; /* overrides if use_stripes_everywhere is set to TRUE */ gint stripes_color_offset; - gboolean enable_dotted_lines; gboolean enable_hscrollbar; gboolean bold_unread; gboolean enable_thread; diff --git a/src/summaryview.c b/src/summaryview.c @@ -2931,7 +2931,7 @@ static gboolean summary_insert_gnode_func(GtkCMCTree *ctree, guint depth, GNode summary_set_header(summaryview, text, msginfo); - gtk_sctree_set_node_info(ctree, cnode, text[col_pos[S_COL_SUBJECT]], 2, + gtk_cmctree_set_node_info(ctree, cnode, text[col_pos[S_COL_SUBJECT]], 2, NULL, NULL, FALSE, summaryview->threaded && !summaryview->thread_collapsed); #define SET_TEXT(col) { \ gtk_cmctree_node_set_text(ctree, cnode, col_pos[col], \ @@ -6318,15 +6318,9 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview) gtk_cmclist_set_column_width(GTK_CMCLIST(ctree), col_pos[S_COL_TAGS], prefs_common.summary_col_size[S_COL_TAGS]); - if (prefs_common.enable_dotted_lines) { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_DOTTED); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_SQUARE); - } else { - gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); - gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), - GTK_CMCTREE_EXPANDER_TRIANGLE); - } + gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE); + gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree), + GTK_CMCTREE_EXPANDER_TRIANGLE); gtk_sctree_set_stripes(GTK_SCTREE(ctree), prefs_common.use_stripes_in_summaries);