Esempio n. 1
0
Thtml_diag *html_diag_new(Tbfwin *bfwin, gchar *title) {
	Thtml_diag *dg;
	
	dg = g_malloc(sizeof(Thtml_diag));
	/* kyanh, removed, 20050225,
	dg->tobedestroyed = FALSE;
	*/
	DEBUG_MSG("html_diag_new, dg=%p\n",dg);
	dg->dialog = window_full2(title, GTK_WIN_POS_MOUSE, 12,G_CALLBACK(html_diag_destroy_cb), dg, TRUE/* escape key close the winow */,  bfwin ? bfwin->main_window : NULL);
	gtk_window_set_type_hint(GTK_WINDOW(dg->dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
	gtk_window_set_role(GTK_WINDOW(dg->dialog), "html_dialog");
	dg->vbox = gtk_vbox_new(FALSE, 1);
	gtk_container_add(GTK_CONTAINER(dg->dialog), dg->vbox);
	{
		if (!gtk_text_buffer_get_mark(bfwin->current_document->buffer,"diag_ins")) {
			GtkTextIter iter;
			GtkTextMark* mark = gtk_text_buffer_get_mark(bfwin->current_document->buffer,"insert");
			gtk_text_buffer_get_iter_at_mark(bfwin->current_document->buffer,&iter,mark);
			dg->mark_ins = gtk_text_buffer_create_mark(bfwin->current_document->buffer,"diag_ins",&iter,TRUE);
			mark = gtk_text_buffer_get_mark(bfwin->current_document->buffer,"selection_bound");
			gtk_text_buffer_get_iter_at_mark(bfwin->current_document->buffer,&iter,mark);
			dg->mark_sel = gtk_text_buffer_create_mark(bfwin->current_document->buffer,"diag_sel",&iter,TRUE);
		} else {
			dg->mark_ins = dg->mark_sel = NULL;
		}
	}
/*	
	dg->range.pos = -1;
	dg->range.end = -1;
*/

	if (main_v->props.view_bars & MODE_MAKE_LATEX_TRANSIENT) {
		/* must be set before realizing */
		DEBUG_MSG("html_diag_finish, setting dg->dialog=%p transient!\n", dg->dialog);
		gtk_window_set_transient_for(GTK_WINDOW(dg->dialog), GTK_WINDOW(bfwin->main_window));
	}
	gtk_widget_realize(dg->dialog);
	dg->bfwin = bfwin;
	dg->doc = bfwin->current_document;
	return dg;
}
Esempio n. 2
0
Thtml_diag *
html_diag_new(Tbfwin * bfwin, gchar * title)
{
	Thtml_diag *dg;

	if (!bfwin) {
		g_warning("plugin_htmlbar: bfwin may not be NULL in html_diag_new()\n");
		return NULL;
	}
	dg = g_new0(Thtml_diag, 1);
	dg->tobedestroyed = FALSE;
	DEBUG_MSG("html_diag_new, dg=%p\n", dg);
	dg->dialog =
		window_full2(title, GTK_WIN_POS_CENTER, 12, G_CALLBACK(html_diag_destroy_cb), dg, TRUE,
					 bfwin->main_window);
	gtk_window_set_type_hint(GTK_WINDOW(dg->dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
	gtk_window_set_role(GTK_WINDOW(dg->dialog), "html_dialog");
	dg->vbox = gtk_vbox_new(FALSE, 1);
	gtk_container_add(GTK_CONTAINER(dg->dialog), dg->vbox);
#ifdef DEBUG
	{
		Tdocument *doc = bfwin->current_document;
		GtkTextIter iter1, iter2;
		GtkTextMark *mark;
		mark = gtk_text_buffer_get_mark(doc->buffer, "insert");
		gtk_text_buffer_get_iter_at_mark(doc->buffer, &iter1, mark);
		mark = gtk_text_buffer_get_mark(doc->buffer, "selection_bound");
		gtk_text_buffer_get_iter_at_mark(doc->buffer, &iter2, mark);
		g_print("html_diag_new, current marks: insert=%d, selection=%d\n", gtk_text_iter_get_offset(&iter1),
				gtk_text_iter_get_offset(&iter2));
	}
#endif

	if (!gtk_text_buffer_get_mark(bfwin->current_document->buffer, "diag_ins")) {
		GtkTextIter iter;
		GtkTextMark *mark = gtk_text_buffer_get_mark(bfwin->current_document->buffer, "insert");
		gtk_text_buffer_get_iter_at_mark(bfwin->current_document->buffer, &iter, mark);
		dg->mark_ins = gtk_text_buffer_create_mark(bfwin->current_document->buffer, "diag_ins", &iter, TRUE);
		DEBUG_MSG("html_diag_new, setting diag_ins at %d", gtk_text_iter_get_offset(&iter));
		mark = gtk_text_buffer_get_mark(bfwin->current_document->buffer, "selection_bound");
		gtk_text_buffer_get_iter_at_mark(bfwin->current_document->buffer, &iter, mark);
		dg->mark_sel = gtk_text_buffer_create_mark(bfwin->current_document->buffer, "diag_sel", &iter, TRUE);
		DEBUG_MSG(" and diag_sel at %d\n", gtk_text_iter_get_offset(&iter));
	} else {
		DEBUG_MSG("html_diag_new, another dialog is open, marking mark_ins and mark_sel = NULL\n");
		dg->mark_ins = dg->mark_sel = NULL;
	}

	dg->range.pos = -1;
	dg->range.end = -1;
	if (htmlbar_v.transient_htdialogs) {
		/* must be set before realizing */
		DEBUG_MSG("html_diag_new, setting dg->dialog=%p transient!\n", dg->dialog);
		gtk_window_set_transient_for(GTK_WINDOW(dg->dialog), GTK_WINDOW(bfwin->main_window));
	}

	gtk_widget_realize(dg->dialog);
	dg->bfwin = bfwin;
	dg->doc = bfwin->current_document;
	return dg;
}
Esempio n. 3
0
void
filefilter_gui(Tfilter * filter)
{
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *column;
	GList *tmplist, *reglist;
	GtkWidget *table, *hbox, *but, *vbox, *scrolwin;
#ifdef WIN32
	GList *mimelist = NULL;
	gchar *last_mime = NULL;
#endif

	Tfilefiltergui *ffg = g_new0(Tfilefiltergui, 1);
	ffg->curfilter = filter;
	if (filter) {
		ffg->origname = g_strdup(filter->name);
	}
	if (!filter) {
		ffg->curfilter = g_new0(Tfilter, 1);
		ffg->curfilter->name = g_strdup(_("New filter"));
	}

	DEBUG_MSG("filefilter_gui, editing filter %p\n", ffg->curfilter);
	ffg->win =
		window_full2(_("Edit filter"), GTK_WIN_POS_MOUSE, 10, G_CALLBACK(filefiltergui_destroy_lcb), ffg,
					 TRUE, NULL);
	gtk_window_set_default_size(GTK_WINDOW(ffg->win), 400, 400);
	ffg->lstore = gtk_list_store_new(3, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN);

	/* fill the list model from the currently known filetypes */
	reglist = g_content_types_get_registered();

#ifdef WIN32
	tmplist = g_list_first(reglist);
	while (tmplist) {
		mimelist = g_list_prepend(mimelist, g_content_type_get_mime_type(tmplist->data));
		tmplist = g_list_next(tmplist);
	}
	mimelist = g_list_reverse(g_list_sort(mimelist, (GCompareFunc) g_strcmp0));
	tmplist = g_list_first(mimelist);
	while (tmplist) {
		if (!last_mime || g_strcmp0(last_mime, tmplist->data) != 0) {
			GtkTreeIter it;
			last_mime = tmplist->data;
			if (MIME_ISDIR(tmplist->data)) {
				gtk_list_store_prepend(ffg->lstore, &it);
				gtk_list_store_set(ffg->lstore, &it, 0, tmplist->data, 2, 0, -1);
			}
		}
		tmplist = g_list_next(tmplist);
	}
/*	GList *winlist = NULL;
	gchar *mimetype;
	gint llen, lpos;
	while(reglist) {
		mimetype = g_content_type_get_mime_type(reglist->data);
		if ((llen = g_list_length(winlist))) {
			tmplist = g_list_copy(winlist);
			for (lpos = 0; llen != -1 && lpos < llen; lpos++) {
				if (!g_strcmp0(mimetype, tmplist->data))
					llen = -1;
				else
					tmplist = g_list_next(tmplist);
			}
			g_list_free(tmplist);
		}
		if (llen != -1)
			winlist = g_list_append(winlist, mimetype);
		reglist = g_list_next(reglist);
	}
	tmplist = g_list_first(g_list_reverse(g_list_sort(winlist, (GCompareFunc) g_strcmp0)));*/
	free_stringlist(mimelist);
#else
	tmplist = g_list_first(g_list_sort(reglist, (GCompareFunc) g_strcmp0));
	while (tmplist) {
		GtkTreeIter it;
		if (!MIME_ISDIR(tmplist->data)) {
			gtk_list_store_prepend(ffg->lstore, &it);
			gtk_list_store_set(ffg->lstore, &it, 0, tmplist->data, 2, 0, -1);
		}
		tmplist = g_list_next(tmplist);
	}
#endif

	g_list_foreach(reglist, (GFunc) g_free, NULL);
	g_list_free(reglist);
	/* add the patterns from the current filter */
	tmplist = g_list_first(ffg->curfilter->patterns);
	while (tmplist) {
		GtkTreeIter it;
		Tfilterpattern *pat = (Tfilterpattern *) tmplist->data;
		gtk_list_store_prepend(ffg->lstore, &it);
		gtk_list_store_set(ffg->lstore, &it, 0, pat->pattern, 1, NULL, 2, 1, -1);
		tmplist = g_list_next(tmplist);
	}

	ffg->in_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(ffg->lstore), NULL);
	gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(ffg->in_model),
										   filefiltergui_infilter_visiblefunc, ffg, NULL);
	ffg->out_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(ffg->lstore), NULL);
	gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(ffg->out_model),
										   filefiltergui_outfilter_visiblefunc, ffg, NULL);

	table = gtk_table_new(5, 4, FALSE);
	gtk_table_set_row_spacings(GTK_TABLE(table), 5);

	ffg->nameentry = dialog_entry_in_table(ffg->curfilter->name, table, 0, 1, 0, 1);

	ffg->inversecheck =
		dialog_check_button_in_table(_("Hide files that match the filter"), !ffg->curfilter->mode, table, 0,
									 1, 1, 2);

	ffg->patentry = dialog_entry_in_table("*.*", table, 2, 3, 1, 2);
	but = gtk_button_new_with_label(_("Add pattern"));
	g_signal_connect(but, "clicked", G_CALLBACK(filefiltergui_addpattern_clicked_lcb), ffg);
	gtk_table_attach(GTK_TABLE(table), but, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);

	ffg->in_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ffg->in_model));
	renderer = gtk_cell_renderer_text_new();
	column = gtk_tree_view_column_new_with_attributes(_("Mime type"), renderer, "text", 0, NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(ffg->in_view), column);
	renderer = gtk_cell_renderer_pixbuf_new();
	column = gtk_tree_view_column_new_with_attributes(_("Icon"), renderer, "pixbuf", 1, NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(ffg->in_view), column);
	scrolwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_container_add(GTK_CONTAINER(scrolwin), ffg->in_view);
	gtk_table_attach_defaults(GTK_TABLE(table), scrolwin, 2, 4, 2, 3);

	ffg->out_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ffg->out_model));
	renderer = gtk_cell_renderer_text_new();
	column = gtk_tree_view_column_new_with_attributes(_("Mime type"), renderer, "text", 0, NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(ffg->out_view), column);
	renderer = gtk_cell_renderer_pixbuf_new();
	column = gtk_tree_view_column_new_with_attributes(_("Icon"), renderer, "pixbuf", 1, NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(ffg->out_view), column);
	scrolwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_container_add(GTK_CONTAINER(scrolwin), ffg->out_view);
	gtk_table_attach_defaults(GTK_TABLE(table), scrolwin, 0, 1, 2, 3);

	vbox = gtk_vbox_new(TRUE, 5);
	but = gtk_button_new_with_label("->");
	g_signal_connect(but, "clicked", G_CALLBACK(filefiltergui_2right_clicked), ffg);
	gtk_box_pack_start(GTK_BOX(vbox), but, TRUE, TRUE, 0);
	but = gtk_button_new_with_label("<-");
	g_signal_connect(but, "clicked", G_CALLBACK(filefiltergui_2left_clicked), ffg);
	gtk_box_pack_start(GTK_BOX(vbox), but, TRUE, TRUE, 0);
	gtk_table_attach(GTK_TABLE(table), vbox, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 5, 5);

#if GTK_CHECK_VERSION(3,0,0)
	hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
#else
	hbox = gtk_hbutton_box_new();
#endif
	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
	gtk_box_set_spacing(GTK_BOX(hbox), 12);
	but = bf_stock_cancel_button(G_CALLBACK(filefiltergui_cancel_clicked), ffg);
	gtk_box_pack_start(GTK_BOX(hbox), but, FALSE, FALSE, 0);
	but = bf_stock_ok_button(G_CALLBACK(filefiltergui_ok_clicked), ffg);
	gtk_box_pack_start(GTK_BOX(hbox), but, FALSE, FALSE, 0);

	gtk_table_attach(GTK_TABLE(table), hbox, 2, 4, 4, 5, GTK_SHRINK, GTK_SHRINK, 0, 0);

	gtk_container_add(GTK_CONTAINER(ffg->win), table);
	gtk_widget_show_all(ffg->win);
}
Esempio n. 4
0
static Tcs3_diag *css_diag(Tcs3_destination dest, Tcs3_style style, GtkWidget *transient_win, gboolean grab) {

	Tcs3_diag *diag;
	GtkWidget *scrolwin, *table, *but, *vbox, *hbox, *vbox2;
	GList *tmplist = NULL;
	Tcs3_arr tmp;
	gint count=0;
	GtkTreeSelection *selection;
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *column;
	
	diag = g_slice_new(Tcs3_diag);
	diag->win = window_full2(_("Cascading Style Sheet Builder"), GTK_WIN_POS_CENTER_ON_PARENT, 
			12, G_CALLBACK(cs3d_destroy_lcb), diag, TRUE, transient_win);
	gtk_window_set_role(GTK_WINDOW(diag->win), "css");
	diag->dest = dest;
	diag->styletype = style;
	diag->grab = grab;
	diag->selected_row = -1;

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(diag->win),vbox);
	
	table = gtk_table_new(3, 6, TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(table), 12);
	gtk_table_set_col_spacings(GTK_TABLE(table), 12);
	gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
	tmplist = NULL;
	
	if (diag->styletype == multistyle) {
		tmplist = glist_with_html_tags(0);
		diag->selector = combobox_with_popdown("", tmplist,1);
		dialog_mnemonic_label_in_table(_("_Selector(s):"), diag->selector, table, 0, 1, 0, 1);
		gtk_table_attach_defaults(GTK_TABLE(table), diag->selector, 1 ,5 , 0, 1);
		gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(diag->selector), 5);
		gtk_combo_box_set_add_tearoffs(GTK_COMBO_BOX(diag->selector), 1);

		diag->html5 = gtk_check_button_new_with_mnemonic("_html 5");
		gtk_table_attach_defaults(GTK_TABLE(table), diag->html5, 5,6, 0,1);
		g_signal_connect(diag->html5, "clicked", G_CALLBACK(cs3d_html5_clicked_lcb), diag);
		
		g_list_free(tmplist);
		tmplist = NULL;
	} 

	tmp = cs3_arr[count];
	while (tmp.property) {
		tmplist = g_list_append(tmplist, tmp.property);
		count++;
		tmp = cs3_arr[count];
	}
	diag->property = combobox_with_popdown("", tmplist,1);
	g_list_free(tmplist);
	tmplist = NULL;
	g_signal_connect(gtk_bin_get_child(GTK_BIN(diag->property)), "activate", G_CALLBACK(cs3d_prop_activate_lcb), diag);
	g_signal_connect(gtk_bin_get_child(GTK_BIN(diag->property)), "changed", G_CALLBACK(cs3d_prop_activate_lcb), diag);

	diag->value = combobox_with_popdown("", tmplist,1);
	dialog_mnemonic_label_in_table(_("_Property:"), diag->property, table, 0, 1, 1, 2);
	gtk_table_attach_defaults(GTK_TABLE(table), diag->property, 1, 5, 1, 2);
	gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(diag->property), 4);
	gtk_combo_box_set_add_tearoffs(GTK_COMBO_BOX(diag->property), 1);
	dialog_mnemonic_label_in_table(_("_Value:"), diag->value, table, 0, 1, 2, 3);
	gtk_table_attach_defaults(GTK_TABLE(table), diag->value, 1, 4, 2, 3);

	
	gtk_widget_realize(diag->win);


	diag->extra_but = color_but_new(GTK_WIDGET(gtk_bin_get_child(GTK_BIN(diag->value))), diag->win);
	gtk_table_attach(GTK_TABLE(table), diag->extra_but, 4, 5, 2, 3, GTK_EXPAND, GTK_EXPAND, 0, 0);

	/* the list widget and the buttons are in a horizontal box */
	hbox = gtk_hbox_new(FALSE, 12);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 18);
	
	diag->lstore = gtk_list_store_new(3, G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING);
	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(diag->lstore),0,GTK_SORT_ASCENDING);
	diag->lview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(diag->lstore));
	g_object_unref(G_OBJECT(diag->lstore));
	if (diag->styletype == multistyle) {
		renderer = gtk_cell_renderer_text_new();
		column = gtk_tree_view_column_new_with_attributes (_("Selector(s)"),renderer,"text", 0,NULL);
		gtk_tree_view_append_column(GTK_TREE_VIEW(diag->lview), column);
	}
	renderer = gtk_cell_renderer_text_new();
	column = gtk_tree_view_column_new_with_attributes (_("Property"),renderer,"text", 1,NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(diag->lview), column);
	renderer = gtk_cell_renderer_text_new();
	column = gtk_tree_view_column_new_with_attributes (_("Value"),renderer,"text", 2,NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(diag->lview), column);
	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(diag->lview));
	gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
	g_signal_connect(G_OBJECT(selection), "changed",G_CALLBACK(cs3d_selection_changed_cb),diag);
	scrolwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_widget_set_size_request(scrolwin, 400, 300);
	gtk_box_pack_start(GTK_BOX(hbox), scrolwin, TRUE, TRUE, 0);
	gtk_container_add(GTK_CONTAINER(scrolwin), diag->lview);
	/*if (diag->styletype == multistyle) {
		gchar *titles[] = {_("Selector"), _("Property"), _("Value"), NULL};
		diag->clist = gtk_clist_new_with_titles(3, titles);
	} else {
		gchar *titles[] = {_("Property"), _("Value"), NULL};
		diag->clist = gtk_clist_new_with_titles(2, titles);
	}
	gtk_clist_set_sort_column(GTK_CLIST(diag->clist), 0);
	gtk_clist_set_auto_sort(GTK_CLIST(diag->clist), TRUE);

	g_signal_connect(diag->clist, "select_row", G_CALLBACK(cs3d_select_row_lcb), diag);
	g_signal_connect(diag->clist, "unselect_row", G_CALLBACK(cs3d_unselect_row_lcb), diag);
	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolwin), diag->lview);
	*/
	
	vbox2 = gtk_vbox_new(FALSE, 6);
	gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0);
	
	but = gtk_button_new_with_mnemonic(_(" _Add "));
	g_signal_connect(but, "clicked", G_CALLBACK(cs3d_add_clicked_lcb), diag);
	gtk_box_pack_start(GTK_BOX(vbox2), but, FALSE, FALSE, 0);

	but = gtk_button_new_with_mnemonic(_(" _Update "));
	g_signal_connect(but, "clicked", G_CALLBACK(cs3d_update_clicked_lcb), diag);
	gtk_box_pack_start(GTK_BOX(vbox2), but, FALSE, FALSE, 0);
	
	but = gtk_button_new_with_mnemonic(_(" _Delete "));
	g_signal_connect(but, "clicked", G_CALLBACK(cs3d_del_clicked_lcb), diag);
	gtk_box_pack_start(GTK_BOX(vbox2), but, FALSE, FALSE, 0);

	/* the ok and cancel button are in a horizontal box below */
	hbox = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 12);	
#if GTK_CHECK_VERSION(3,0,0)
	hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
#else
	hbox = gtk_hbutton_box_new();
#endif
	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
	gtk_box_set_spacing(GTK_BOX(hbox), 12);
	
	but = bf_stock_cancel_button(G_CALLBACK(cs3d_cancel_clicked_lcb), diag);
	gtk_box_pack_start(GTK_BOX(hbox), but, FALSE, FALSE, 0);
	but = bf_stock_ok_button(G_CALLBACK(cs3d_ok_clicked_lcb), diag);
	gtk_box_pack_start(GTK_BOX(hbox), but, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);	
	
	gtk_widget_show_all(diag->win);
	
	cs3d_prop_activate_lcb(NULL, diag);
		
	if (diag->grab) {
		gtk_grab_add(diag->win);
	}
	return diag;
}
Esempio n. 5
0
static Tcolsel *colsel_dialog(Tbfwin *bfwin,const gchar *setcolor, gint modal, gint startpos, gint endpos) {
	Tcolsel *csd;
	GtkWidget *vbox, *hbox, *but;
	GdkColor gcolor;
	const gchar *this_color=setcolor;
	csd = g_new0(Tcolsel, 1);
	/* warning: bfwin might be NULL if this dialog is started by return_color() */
	csd->bfwin = bfwin;
	csd->is_modal = modal;
	csd->startpos = startpos;
	csd->endpos = endpos;
	csd->returnval = setcolor ? g_strdup(setcolor) : g_strdup("");
	
	DEBUG_MSG("colsel_dialog, malloced at %p, setcolor=%s\n", csd, setcolor);
	csd->win = window_full2(_("Bluefish: Select color"), GTK_WIN_POS_CENTER, 12, G_CALLBACK(colsel_destroy_lcb), csd, TRUE, bfwin?bfwin->main_window:NULL);
	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(csd->win), vbox);
	csd->csel = gtk_color_selection_new();
	gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(csd->csel), FALSE);
	if (this_color) {
		if (gdk_color_parse(this_color, &gcolor)) {
			gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(csd->csel), &gcolor);
		} else {
			this_color=NULL;
		}
	}
	gtk_color_selection_set_has_palette(GTK_COLOR_SELECTION(csd->csel), TRUE);
	gtk_box_pack_start(GTK_BOX(vbox), csd->csel, TRUE, TRUE, 0);

	hbox = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 12);
#if GTK_CHECK_VERSION(3,0,0)
	hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
#else
	hbox = gtk_hbutton_box_new();
#endif
	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
	gtk_box_set_spacing(GTK_BOX(hbox), 12);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);

	but = bf_stock_cancel_button(G_CALLBACK(colsel_cancel_clicked_lcb), csd);
	gtk_box_pack_start(GTK_BOX(hbox), but, TRUE, TRUE, 0);
	but = bf_stock_ok_button(G_CALLBACK(colsel_ok_clicked_lcb), csd);
	gtk_window_set_default(GTK_WINDOW(csd->win), but);
	gtk_box_pack_start(GTK_BOX(hbox), but, TRUE, TRUE, 0);

	if (bfwin && bfwin->session->colorlist) {
		GtkSettings* gtksettings;
		/* Note that this function can only be called when the GtkWidget is attached to a toplevel, since the settings object is specific to a particular GdkScreen.  */
		gtksettings = gtk_widget_get_settings(GTK_WIDGET(csd->csel));
		if (gtksettings) {
			gchar *strings;
			DEBUG_MSG("pallette list=%d\n",g_list_length(bfwin->session->colorlist));
			bfwin->session->colorlist = limit_stringlist(bfwin->session->colorlist, 20, TRUE);
			DEBUG_MSG("pallette list=%d\n",g_list_length(bfwin->session->colorlist));
			strings = stringlist_to_string(bfwin->session->colorlist, ":");
			strings[strlen(strings)-1] = '\0';
			/* this property may contain max 20 colors, otherwise gtk will crash */
			g_object_set(G_OBJECT(gtksettings), "gtk-color-palette", strings, NULL);
			g_free(strings);
		} 
/*		DEBUG_MSG("colsel_dialog, setting palette from %s\n", strings);
		if (gtk_color_selection_palette_from_string(strings, &gcolorarr, &num)) {
			DEBUG_MSG("num=%d, gcolorarr=%p\n",num,gcolorarr);
		} else {
			DEBUG_MSG("hmm, failed to parse our string :(\n");
		} */
	}

	gtk_widget_show_all(csd->win);

	DEBUG_MSG("colsel_dialog, finished\n");
	return csd;
}