2005-11-22 12:26:26 +00:00
|
|
|
/*
|
2007-08-23 11:34:06 +00:00
|
|
|
* treeviews.c - this file is part of Geany, a fast and lightweight IDE
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
2009-01-04 18:30:42 +00:00
|
|
|
* Copyright 2005-2009 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
|
|
|
|
* Copyright 2006-2009 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2006-05-10 23:00:22 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-12-11 02:16:02 +00:00
|
|
|
*
|
|
|
|
* $Id$
|
2005-11-22 12:26:26 +00:00
|
|
|
*/
|
|
|
|
|
2007-02-24 11:41:56 +00:00
|
|
|
/*
|
|
|
|
* Sidebar related code for the Symbol list and Open files GtkTreeViews.
|
|
|
|
*/
|
|
|
|
|
2005-12-11 02:16:02 +00:00
|
|
|
#include <string.h>
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
#include "geany.h"
|
|
|
|
#include "support.h"
|
|
|
|
#include "callbacks.h"
|
|
|
|
#include "treeviews.h"
|
2006-07-22 14:36:20 +00:00
|
|
|
#include "document.h"
|
2008-07-08 16:30:37 +00:00
|
|
|
#include "editor.h"
|
2008-06-02 15:31:59 +00:00
|
|
|
#include "documentprivate.h"
|
2007-08-15 15:37:21 +00:00
|
|
|
#include "filetypes.h"
|
2006-10-29 13:48:39 +00:00
|
|
|
#include "utils.h"
|
|
|
|
#include "ui_utils.h"
|
2007-02-05 16:17:44 +00:00
|
|
|
#include "symbols.h"
|
2007-07-17 16:11:38 +00:00
|
|
|
#include "navqueue.h"
|
2006-10-29 13:48:39 +00:00
|
|
|
|
2008-03-21 18:44:12 +00:00
|
|
|
#include <gdk/gdkkeysyms.h>
|
2006-10-29 13:48:39 +00:00
|
|
|
|
2007-08-23 11:34:06 +00:00
|
|
|
SidebarTreeviews tv;
|
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
static struct
|
|
|
|
{
|
|
|
|
GtkWidget *close;
|
|
|
|
GtkWidget *save;
|
|
|
|
GtkWidget *reload;
|
|
|
|
}
|
|
|
|
doc_items = {NULL, NULL, NULL};
|
|
|
|
|
2006-10-29 13:48:39 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
TREEVIEW_SYMBOL = 0,
|
|
|
|
TREEVIEW_OPENFILES
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
OPENFILES_ACTION_REMOVE = 0,
|
|
|
|
OPENFILES_ACTION_SAVE,
|
2008-11-18 13:29:53 +00:00
|
|
|
OPENFILES_ACTION_RELOAD
|
2006-10-29 13:48:39 +00:00
|
|
|
};
|
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
/* documents tree model columns */
|
|
|
|
enum
|
2007-10-28 21:14:35 +00:00
|
|
|
{
|
2009-03-30 18:46:37 +00:00
|
|
|
DOCUMENTS_ICON,
|
2009-01-19 13:12:45 +00:00
|
|
|
DOCUMENTS_SHORTNAME, /* dirname for parents, basename for children */
|
|
|
|
DOCUMENTS_DOCUMENT,
|
|
|
|
DOCUMENTS_COLOR,
|
|
|
|
DOCUMENTS_FILENAME /* full filename */
|
|
|
|
};
|
2006-10-29 13:48:39 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
static GtkTreeStore *store_openfiles;
|
2008-02-27 13:17:29 +00:00
|
|
|
static GtkWidget *tag_window; /* scrolled window that holds the symbol list GtkTreeView */
|
2007-08-23 11:34:06 +00:00
|
|
|
|
2006-10-29 13:48:39 +00:00
|
|
|
/* callback prototypes */
|
|
|
|
static void on_openfiles_tree_selection_changed(GtkTreeSelection *selection, gpointer data);
|
2007-10-24 16:10:56 +00:00
|
|
|
static void on_openfiles_document_action(GtkMenuItem *menuitem, gpointer user_data);
|
2007-06-10 11:28:54 +00:00
|
|
|
static gboolean on_taglist_tree_selection_changed(GtkTreeSelection *selection);
|
2009-01-20 16:34:11 +00:00
|
|
|
static gboolean on_symbols_button_press_event(GtkWidget *widget, GdkEventButton *event,
|
|
|
|
gpointer user_data);
|
|
|
|
static gboolean on_documents_button_release_event(GtkWidget *widget, GdkEventButton *event,
|
|
|
|
gpointer user_data);
|
2008-03-21 18:44:12 +00:00
|
|
|
static gboolean on_treeviews_key_press_event(GtkWidget *widget, GdkEventKey *event,
|
2009-01-20 16:34:11 +00:00
|
|
|
gpointer user_data);
|
2007-10-28 21:14:35 +00:00
|
|
|
static void on_list_document_activate(GtkCheckMenuItem *item, gpointer user_data);
|
|
|
|
static void on_list_symbol_activate(GtkCheckMenuItem *item, gpointer user_data);
|
2006-10-29 13:48:39 +00:00
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2007-02-05 16:17:44 +00:00
|
|
|
/* the prepare_* functions are document-related, but I think they fit better here than in document.c */
|
|
|
|
static void prepare_taglist(GtkWidget *tree, GtkTreeStore *store)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2007-07-20 16:33:16 +00:00
|
|
|
GtkCellRenderer *text_renderer, *icon_renderer;
|
2005-11-22 12:26:26 +00:00
|
|
|
GtkTreeViewColumn *column;
|
|
|
|
GtkTreeSelection *select;
|
|
|
|
|
2007-07-20 16:33:16 +00:00
|
|
|
text_renderer = gtk_cell_renderer_text_new();
|
|
|
|
icon_renderer = gtk_cell_renderer_pixbuf_new();
|
|
|
|
column = gtk_tree_view_column_new();
|
|
|
|
|
|
|
|
gtk_tree_view_column_pack_start(column, icon_renderer, FALSE);
|
|
|
|
gtk_tree_view_column_set_attributes(column, icon_renderer, "pixbuf", SYMBOLS_COLUMN_ICON, NULL);
|
|
|
|
g_object_set(icon_renderer, "xalign", 0.0, NULL);
|
|
|
|
|
|
|
|
gtk_tree_view_column_pack_start(column, text_renderer, TRUE);
|
2007-11-21 17:20:26 +00:00
|
|
|
gtk_tree_view_column_set_attributes(column, text_renderer, "text", SYMBOLS_COLUMN_NAME, NULL);
|
2007-07-20 16:33:16 +00:00
|
|
|
g_object_set(text_renderer, "yalign", 0.5, NULL);
|
|
|
|
gtk_tree_view_column_set_title(column, _("Symbols"));
|
|
|
|
|
2005-12-18 22:08:42 +00:00
|
|
|
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
|
|
|
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-12-06 18:04:46 +00:00
|
|
|
ui_widget_modify_font_from_string(tree, interface_prefs.tagbar_font);
|
2006-12-13 15:18:49 +00:00
|
|
|
|
2005-12-18 22:08:42 +00:00
|
|
|
gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
|
2008-10-07 18:51:50 +00:00
|
|
|
g_object_unref(store);
|
|
|
|
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(tree, "button-press-event",
|
2009-01-20 16:34:11 +00:00
|
|
|
G_CALLBACK(on_symbols_button_press_event), NULL);
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(tree, "key-press-event",
|
2009-01-20 16:34:11 +00:00
|
|
|
G_CALLBACK(on_treeviews_key_press_event), GINT_TO_POINTER(TREEVIEW_SYMBOL));
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-04-28 15:05:11 +00:00
|
|
|
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree), FALSE);
|
|
|
|
|
2008-11-29 12:50:27 +00:00
|
|
|
if (gtk_check_version(2, 12, 0) == NULL)
|
|
|
|
{
|
|
|
|
g_object_set(tree, "show-expanders", interface_prefs.show_symbol_list_expanders, NULL);
|
|
|
|
if (! interface_prefs.show_symbol_list_expanders)
|
|
|
|
g_object_set(tree, "level-indentation", 10, NULL);
|
2008-11-29 12:50:52 +00:00
|
|
|
/* Tooltips */
|
|
|
|
g_object_set(tree,
|
|
|
|
"has-tooltip", TRUE,
|
|
|
|
"tooltip-column", SYMBOLS_COLUMN_TOOLTIP, NULL);
|
2008-11-29 12:50:27 +00:00
|
|
|
}
|
2007-11-18 15:09:28 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* selection handling */
|
2005-12-18 22:08:42 +00:00
|
|
|
select = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
|
2005-11-22 12:26:26 +00:00
|
|
|
gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
|
2008-02-27 13:17:29 +00:00
|
|
|
/* callback for changed selection not necessary, will be handled by button-press-event */
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-13 12:02:16 +00:00
|
|
|
static gboolean
|
|
|
|
on_default_tag_tree_button_press_event(GtkWidget *widget, GdkEventButton *event,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
if (event->button == 3)
|
|
|
|
{
|
2009-01-20 16:34:11 +00:00
|
|
|
on_symbols_button_press_event(widget, event, NULL);
|
2007-02-13 12:02:16 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
/* update = rescan the tags for doc->filename */
|
|
|
|
void treeviews_update_tag_list(GeanyDocument *doc, gboolean update)
|
2007-02-05 16:17:44 +00:00
|
|
|
{
|
2007-08-23 11:34:06 +00:00
|
|
|
if (gtk_bin_get_child(GTK_BIN(tag_window)))
|
|
|
|
gtk_container_remove(GTK_CONTAINER(tag_window), gtk_bin_get_child(GTK_BIN(tag_window)));
|
2007-02-05 16:17:44 +00:00
|
|
|
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(tv.default_tag_tree == NULL))
|
2007-02-05 16:17:44 +00:00
|
|
|
{
|
2007-08-23 11:34:06 +00:00
|
|
|
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW(tag_window);
|
2007-02-15 23:20:41 +00:00
|
|
|
GtkWidget *label;
|
2007-02-13 12:02:16 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* default_tag_tree is a GtkViewPort with a GtkLabel inside it */
|
2007-08-23 11:34:06 +00:00
|
|
|
tv.default_tag_tree = gtk_viewport_new(
|
2007-02-13 12:02:16 +00:00
|
|
|
gtk_scrolled_window_get_hadjustment(scrolled_window),
|
|
|
|
gtk_scrolled_window_get_vadjustment(scrolled_window));
|
2007-02-15 23:20:41 +00:00
|
|
|
label = gtk_label_new(_("No tags found"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.1, 0.01);
|
2007-08-23 11:34:06 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(tv.default_tag_tree), label);
|
|
|
|
gtk_widget_show_all(tv.default_tag_tree);
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(tv.default_tag_tree, "button-press-event",
|
2007-02-13 12:02:16 +00:00
|
|
|
G_CALLBACK(on_default_tag_tree_button_press_event), NULL);
|
2008-02-27 13:17:29 +00:00
|
|
|
g_object_ref((gpointer)tv.default_tag_tree); /* to hold it after removing */
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* show default empty tag tree if there are no tags */
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(doc == NULL) || G_UNLIKELY(doc->file_type == NULL) ||
|
2008-06-15 13:35:48 +00:00
|
|
|
! filetype_has_tags(doc->file_type))
|
2007-02-05 16:17:44 +00:00
|
|
|
{
|
2007-08-23 11:34:06 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(tag_window), tv.default_tag_tree);
|
2007-02-05 16:17:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (update)
|
2008-02-27 13:17:29 +00:00
|
|
|
{ /* updating the tag list in the left tag window */
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(doc->priv->tag_tree == NULL))
|
2007-02-05 16:17:44 +00:00
|
|
|
{
|
2008-09-26 17:28:50 +00:00
|
|
|
doc->priv->tag_store = gtk_tree_store_new(
|
2008-11-29 12:50:52 +00:00
|
|
|
SYMBOLS_N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING);
|
2008-09-26 17:28:50 +00:00
|
|
|
doc->priv->tag_tree = gtk_tree_view_new();
|
|
|
|
prepare_taglist(doc->priv->tag_tree, doc->priv->tag_store);
|
|
|
|
gtk_widget_show(doc->priv->tag_tree);
|
|
|
|
g_object_ref((gpointer)doc->priv->tag_tree); /* to hold it after removing */
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
doc->has_tags = symbols_recreate_tag_list(doc, SYMBOLS_SORT_USE_PREVIOUS);
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
if (doc->has_tags)
|
2007-02-05 16:17:44 +00:00
|
|
|
{
|
2008-09-26 17:28:50 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(tag_window), doc->priv->tag_tree);
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 11:34:06 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(tag_window), tv.default_tag_tree);
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
/* does some preparing things to the open files list widget */
|
2008-02-20 11:24:23 +00:00
|
|
|
static void prepare_openfiles(void)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2009-03-30 18:46:37 +00:00
|
|
|
GtkCellRenderer *icon_renderer;
|
|
|
|
GtkCellRenderer *text_renderer;
|
2005-11-22 12:26:26 +00:00
|
|
|
GtkTreeViewColumn *column;
|
|
|
|
GtkTreeSelection *select;
|
2007-10-09 12:26:44 +00:00
|
|
|
GtkTreeSortable *sortable;
|
2006-12-13 15:18:49 +00:00
|
|
|
|
2008-12-18 21:21:53 +00:00
|
|
|
tv.tree_openfiles = ui_lookup_widget(main_widgets.window, "treeview6");
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2009-03-30 18:46:37 +00:00
|
|
|
/* store the icon and the short filename to show, and the index as reference,
|
2008-02-27 13:17:29 +00:00
|
|
|
* the colour (black/red/green) and the full name for the tooltip */
|
2009-03-30 18:46:37 +00:00
|
|
|
store_openfiles = gtk_tree_store_new(5, G_TYPE_STRING, G_TYPE_STRING,
|
|
|
|
G_TYPE_POINTER, GDK_TYPE_COLOR, G_TYPE_STRING);
|
2007-08-23 11:34:06 +00:00
|
|
|
gtk_tree_view_set_model(GTK_TREE_VIEW(tv.tree_openfiles), GTK_TREE_MODEL(store_openfiles));
|
2008-10-07 18:51:50 +00:00
|
|
|
g_object_unref(store_openfiles);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* set policy settings for the scolledwindow around the treeview again, because glade
|
|
|
|
* doesn't keep the settings */
|
2006-06-24 18:43:56 +00:00
|
|
|
gtk_scrolled_window_set_policy(
|
2008-12-18 21:21:53 +00:00
|
|
|
GTK_SCROLLED_WINDOW(ui_lookup_widget(main_widgets.window, "scrolledwindow7")),
|
2007-10-08 12:10:03 +00:00
|
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
2006-06-24 18:43:56 +00:00
|
|
|
|
2009-03-30 18:46:37 +00:00
|
|
|
icon_renderer = gtk_cell_renderer_pixbuf_new();
|
|
|
|
text_renderer = gtk_cell_renderer_text_new();
|
|
|
|
column = gtk_tree_view_column_new();
|
|
|
|
gtk_tree_view_column_pack_start(column, icon_renderer, FALSE);
|
|
|
|
gtk_tree_view_column_set_attributes(column, icon_renderer, "stock-id", DOCUMENTS_ICON, NULL);
|
|
|
|
gtk_tree_view_column_pack_start(column, text_renderer, TRUE);
|
|
|
|
gtk_tree_view_column_set_attributes(column, text_renderer, "text", DOCUMENTS_SHORTNAME,
|
|
|
|
"foreground-gdk", DOCUMENTS_COLOR, NULL);
|
2005-11-22 12:26:26 +00:00
|
|
|
gtk_tree_view_append_column(GTK_TREE_VIEW(tv.tree_openfiles), column);
|
|
|
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tv.tree_openfiles), FALSE);
|
|
|
|
|
2006-04-28 15:05:11 +00:00
|
|
|
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tv.tree_openfiles), FALSE);
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* sort opened filenames in the store_openfiles treeview */
|
2007-08-23 11:34:06 +00:00
|
|
|
sortable = GTK_TREE_SORTABLE(GTK_TREE_MODEL(store_openfiles));
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_sortable_set_sort_column_id(sortable, DOCUMENTS_SHORTNAME, GTK_SORT_ASCENDING);
|
2007-02-01 15:43:13 +00:00
|
|
|
|
2008-12-06 18:04:46 +00:00
|
|
|
ui_widget_modify_font_from_string(tv.tree_openfiles, interface_prefs.tagbar_font);
|
2006-12-13 15:18:49 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* GTK 2.12 tooltips */
|
2008-11-29 12:50:27 +00:00
|
|
|
if (gtk_check_version(2, 12, 0) == NULL)
|
2009-01-19 13:12:45 +00:00
|
|
|
g_object_set(tv.tree_openfiles, "has-tooltip", TRUE, "tooltip-column", DOCUMENTS_FILENAME, NULL);
|
2007-10-09 12:26:44 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
g_signal_connect(tv.tree_openfiles, "button-release-event",
|
|
|
|
G_CALLBACK(on_documents_button_release_event), NULL);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* selection handling */
|
2005-11-22 12:26:26 +00:00
|
|
|
select = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles));
|
|
|
|
gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(select, "changed", G_CALLBACK(on_openfiles_tree_selection_changed), NULL);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
/* iter should be toplevel */
|
|
|
|
static gboolean find_tree_iter_dir(GtkTreeIter *iter, const gchar *dir)
|
|
|
|
{
|
|
|
|
GeanyDocument *doc;
|
|
|
|
gchar *name;
|
|
|
|
|
|
|
|
if (utils_str_equal(dir, "."))
|
|
|
|
dir = GEANY_STRING_UNTITLED;
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_model_get(GTK_TREE_MODEL(store_openfiles), iter, DOCUMENTS_DOCUMENT, &doc, -1);
|
|
|
|
g_return_val_if_fail(!doc, FALSE);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_model_get(GTK_TREE_MODEL(store_openfiles), iter, DOCUMENTS_SHORTNAME, &name, -1);
|
|
|
|
return utils_str_equal(name, dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static GtkTreeIter *get_doc_parent(GeanyDocument *doc)
|
|
|
|
{
|
|
|
|
gchar *dirname;
|
|
|
|
static GtkTreeIter parent;
|
|
|
|
GtkTreeModel *model = GTK_TREE_MODEL(store_openfiles);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
dirname = g_path_get_dirname(DOC_FILENAME(doc));
|
|
|
|
|
|
|
|
if (gtk_tree_model_get_iter_first(model, &parent))
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (find_tree_iter_dir(&parent, dirname))
|
|
|
|
{
|
|
|
|
g_free(dirname);
|
|
|
|
return &parent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (gtk_tree_model_iter_next(model, &parent));
|
|
|
|
}
|
|
|
|
/* no match, add dir parent */
|
|
|
|
gtk_tree_store_append(store_openfiles, &parent, NULL);
|
2009-03-30 18:46:37 +00:00
|
|
|
gtk_tree_store_set(store_openfiles, &parent, DOCUMENTS_ICON, GTK_STOCK_DIRECTORY,
|
|
|
|
DOCUMENTS_SHORTNAME, doc->file_name ? dirname : GEANY_STRING_UNTITLED, -1);
|
2009-01-19 13:12:45 +00:00
|
|
|
|
|
|
|
g_free(dirname);
|
|
|
|
return &parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Also sets doc->priv->iter.
|
2007-01-12 13:04:39 +00:00
|
|
|
* This is called recursively in treeviews_openfiles_update_all(). */
|
2008-06-15 13:35:48 +00:00
|
|
|
void treeviews_openfiles_add(GeanyDocument *doc)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2008-09-26 17:28:50 +00:00
|
|
|
GtkTreeIter *iter = &doc->priv->iter;
|
2009-01-19 13:12:45 +00:00
|
|
|
GtkTreeIter *parent = get_doc_parent(doc);
|
|
|
|
gchar *basename;
|
2009-02-08 19:52:21 +00:00
|
|
|
const GdkColor *color = document_get_status_color(doc);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_store_append(store_openfiles, iter, parent);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
/* check if new parent */
|
|
|
|
if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_openfiles), parent) == 1)
|
|
|
|
{
|
|
|
|
GtkTreePath *path;
|
2006-11-07 13:33:50 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
/* expand parent */
|
|
|
|
path = gtk_tree_model_get_path(GTK_TREE_MODEL(store_openfiles), parent);
|
|
|
|
gtk_tree_view_expand_row(GTK_TREE_VIEW(tv.tree_openfiles), path, TRUE);
|
|
|
|
gtk_tree_path_free(path);
|
|
|
|
}
|
|
|
|
basename = g_path_get_basename(DOC_FILENAME(doc));
|
2009-03-30 18:46:37 +00:00
|
|
|
gtk_tree_store_set(store_openfiles, iter, DOCUMENTS_ICON, GTK_STOCK_FILE,
|
2009-01-19 13:21:57 +00:00
|
|
|
DOCUMENTS_SHORTNAME, basename, DOCUMENTS_DOCUMENT, doc, DOCUMENTS_COLOR, color,
|
|
|
|
DOCUMENTS_FILENAME, DOC_FILENAME(doc), -1);
|
2009-01-19 13:12:45 +00:00
|
|
|
g_free(basename);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
static void openfiles_remove(GeanyDocument *doc)
|
2006-01-14 22:41:35 +00:00
|
|
|
{
|
2009-01-19 13:12:45 +00:00
|
|
|
GtkTreeIter *iter = &doc->priv->iter;
|
|
|
|
GtkTreeIter parent;
|
2006-11-07 13:33:50 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(store_openfiles), &parent, iter) &&
|
|
|
|
gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_openfiles), &parent) == 1)
|
|
|
|
gtk_tree_store_remove(store_openfiles, &parent);
|
2007-10-13 09:28:26 +00:00
|
|
|
else
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_store_remove(store_openfiles, iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void treeviews_openfiles_update(GeanyDocument *doc)
|
|
|
|
{
|
|
|
|
GtkTreeIter *iter = &doc->priv->iter;
|
|
|
|
gchar *fname;
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_model_get(GTK_TREE_MODEL(store_openfiles), iter, DOCUMENTS_FILENAME, &fname, -1);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
if (utils_str_equal(fname, DOC_FILENAME(doc)))
|
|
|
|
{
|
|
|
|
/* just update color */
|
2009-02-08 19:52:21 +00:00
|
|
|
const GdkColor *color = document_get_status_color(doc);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_store_set(store_openfiles, iter, DOCUMENTS_COLOR, color, -1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* path has changed, so remove and re-add */
|
|
|
|
GtkTreeSelection *treesel;
|
|
|
|
gboolean sel;
|
|
|
|
|
|
|
|
treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles));
|
|
|
|
sel = gtk_tree_selection_iter_is_selected(treesel, &doc->priv->iter);
|
|
|
|
openfiles_remove(doc);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
treeviews_openfiles_add(doc);
|
|
|
|
if (sel)
|
|
|
|
gtk_tree_selection_select_iter(treesel, &doc->priv->iter);
|
|
|
|
}
|
|
|
|
g_free(fname);
|
2006-01-14 22:41:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-29 13:48:39 +00:00
|
|
|
void treeviews_openfiles_update_all()
|
2006-07-22 14:36:20 +00:00
|
|
|
{
|
2009-02-10 21:11:25 +00:00
|
|
|
guint i, page_count;
|
2008-06-15 13:35:48 +00:00
|
|
|
GeanyDocument *doc;
|
2006-07-22 14:36:20 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_store_clear(store_openfiles);
|
2009-02-10 21:11:25 +00:00
|
|
|
page_count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
|
|
|
|
for (i = 0; i < page_count; i++)
|
2006-07-22 14:36:20 +00:00
|
|
|
{
|
2008-06-15 13:35:48 +00:00
|
|
|
doc = document_get_from_page(i);
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(doc == NULL))
|
2008-06-15 13:35:48 +00:00
|
|
|
continue;
|
2006-07-22 14:36:20 +00:00
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
treeviews_openfiles_add(doc);
|
2006-12-05 10:37:36 +00:00
|
|
|
}
|
|
|
|
}
|
2006-07-22 19:27:12 +00:00
|
|
|
|
2006-12-05 10:37:36 +00:00
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
void treeviews_remove_document(GeanyDocument *doc)
|
2006-12-05 10:37:36 +00:00
|
|
|
{
|
2009-01-19 13:12:45 +00:00
|
|
|
openfiles_remove(doc);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2008-09-26 17:28:50 +00:00
|
|
|
if (GTK_IS_WIDGET(doc->priv->tag_tree))
|
2006-12-05 10:37:36 +00:00
|
|
|
{
|
2008-09-26 17:28:50 +00:00
|
|
|
gtk_widget_destroy(doc->priv->tag_tree);
|
|
|
|
if (GTK_IS_TREE_VIEW(doc->priv->tag_tree))
|
2006-12-20 10:47:01 +00:00
|
|
|
{
|
2008-02-27 13:17:29 +00:00
|
|
|
/* Because it was ref'd in treeviews_update_tag_list, it needs unref'ing */
|
2008-09-26 17:28:50 +00:00
|
|
|
g_object_unref((gpointer)doc->priv->tag_tree);
|
2006-12-20 10:47:01 +00:00
|
|
|
}
|
2008-09-26 17:28:50 +00:00
|
|
|
doc->priv->tag_tree = NULL;
|
2006-07-22 14:36:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-18 12:58:53 +00:00
|
|
|
static void on_hide_sidebar(void)
|
2006-01-14 22:41:35 +00:00
|
|
|
{
|
2008-11-18 12:58:53 +00:00
|
|
|
ui_prefs.sidebar_visible = FALSE;
|
|
|
|
ui_sidebar_show_hide();
|
|
|
|
}
|
2006-01-14 22:41:35 +00:00
|
|
|
|
|
|
|
|
2008-11-18 12:58:53 +00:00
|
|
|
static gboolean on_sidebar_display_symbol_list_show(GtkWidget *item)
|
|
|
|
{
|
|
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
|
|
|
|
interface_prefs.sidebar_symbol_visible);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-08-15 17:58:58 +00:00
|
|
|
|
2008-11-18 12:58:53 +00:00
|
|
|
|
|
|
|
static gboolean on_sidebar_display_open_files_show(GtkWidget *item)
|
|
|
|
{
|
|
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
|
|
|
|
interface_prefs.sidebar_openfiles_visible);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-18 13:29:53 +00:00
|
|
|
void sidebar_add_common_menu_items(GtkMenu *menu)
|
2008-11-18 12:58:53 +00:00
|
|
|
{
|
|
|
|
GtkWidget *item;
|
2007-08-15 17:58:58 +00:00
|
|
|
|
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
2008-11-18 12:58:53 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
2007-08-15 17:58:58 +00:00
|
|
|
|
2008-11-18 12:58:53 +00:00
|
|
|
item = gtk_check_menu_item_new_with_mnemonic(_("Show S_ymbol List"));
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
g_signal_connect(item, "expose-event",
|
|
|
|
G_CALLBACK(on_sidebar_display_symbol_list_show), NULL);
|
|
|
|
gtk_widget_show(item);
|
|
|
|
g_signal_connect(item, "activate",
|
2007-10-28 21:14:35 +00:00
|
|
|
G_CALLBACK(on_list_symbol_activate), NULL);
|
|
|
|
|
2008-11-18 12:58:53 +00:00
|
|
|
item = gtk_check_menu_item_new_with_mnemonic(_("Show _Document List"));
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
g_signal_connect(item, "expose-event",
|
|
|
|
G_CALLBACK(on_sidebar_display_open_files_show), NULL);
|
|
|
|
gtk_widget_show(item);
|
|
|
|
g_signal_connect(item, "activate",
|
2007-10-28 21:14:35 +00:00
|
|
|
G_CALLBACK(on_list_document_activate), NULL);
|
2006-01-14 22:41:35 +00:00
|
|
|
|
2007-11-08 16:21:46 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("H_ide Sidebar"));
|
2006-01-14 22:41:35 +00:00
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
|
|
|
|
gtk_image_new_from_stock("gtk-close", GTK_ICON_SIZE_MENU));
|
|
|
|
gtk_widget_show(item);
|
2008-11-18 12:58:53 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
g_signal_connect(item, "activate", G_CALLBACK(on_hide_sidebar), NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-28 21:14:35 +00:00
|
|
|
static void on_list_document_activate(GtkCheckMenuItem *item, gpointer user_data)
|
|
|
|
{
|
2008-05-16 12:08:39 +00:00
|
|
|
interface_prefs.sidebar_openfiles_visible = gtk_check_menu_item_get_active(item);
|
2008-01-23 14:12:08 +00:00
|
|
|
ui_sidebar_show_hide();
|
2007-10-28 21:14:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void on_list_symbol_activate(GtkCheckMenuItem *item, gpointer user_data)
|
|
|
|
{
|
2008-05-16 12:08:39 +00:00
|
|
|
interface_prefs.sidebar_symbol_visible = gtk_check_menu_item_get_active(item);
|
2008-01-23 14:12:08 +00:00
|
|
|
ui_sidebar_show_hide();
|
2007-10-28 21:14:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-20 11:24:23 +00:00
|
|
|
static void create_openfiles_popup_menu(void)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
GtkWidget *item;
|
|
|
|
|
|
|
|
tv.popup_openfiles = gtk_menu_new();
|
|
|
|
|
|
|
|
item = gtk_image_menu_item_new_from_stock("gtk-close", NULL);
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(tv.popup_openfiles), item);
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(item, "activate",
|
2007-10-24 16:10:56 +00:00
|
|
|
G_CALLBACK(on_openfiles_document_action), GINT_TO_POINTER(OPENFILES_ACTION_REMOVE));
|
2009-01-20 16:34:11 +00:00
|
|
|
doc_items.close = item;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(tv.popup_openfiles), item);
|
|
|
|
|
|
|
|
item = gtk_image_menu_item_new_from_stock("gtk-save", NULL);
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(tv.popup_openfiles), item);
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(item, "activate",
|
2007-10-24 16:10:56 +00:00
|
|
|
G_CALLBACK(on_openfiles_document_action), GINT_TO_POINTER(OPENFILES_ACTION_SAVE));
|
2009-01-20 16:34:11 +00:00
|
|
|
doc_items.save = item;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2007-10-13 09:28:26 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Reload"));
|
2005-11-22 12:26:26 +00:00
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
|
|
|
|
gtk_image_new_from_stock("gtk-revert-to-saved", GTK_ICON_SIZE_MENU));
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(tv.popup_openfiles), item);
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(item, "activate",
|
2007-10-24 16:10:56 +00:00
|
|
|
G_CALLBACK(on_openfiles_document_action), GINT_TO_POINTER(OPENFILES_ACTION_RELOAD));
|
2009-01-20 16:34:11 +00:00
|
|
|
doc_items.reload = item;
|
2006-01-14 22:41:35 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
sidebar_add_common_menu_items(GTK_MENU(tv.popup_openfiles));
|
|
|
|
}
|
2006-01-14 22:41:35 +00:00
|
|
|
|
2007-10-13 09:28:26 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
static void unfold_parent(GtkTreeIter *iter)
|
|
|
|
{
|
|
|
|
GtkTreeIter parent;
|
|
|
|
GtkTreePath *path;
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_model_iter_parent(GTK_TREE_MODEL(store_openfiles), &parent, iter);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
path = gtk_tree_model_get_path(GTK_TREE_MODEL(store_openfiles), &parent);
|
|
|
|
gtk_tree_view_expand_row(GTK_TREE_VIEW(tv.tree_openfiles), path, TRUE);
|
|
|
|
gtk_tree_path_free(path);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
/* compares the given data with the doc pointer from the selected row of openfiles
|
2005-11-22 12:26:26 +00:00
|
|
|
* treeview, in case of a match the row is selected and TRUE is returned
|
|
|
|
* (called indirectly from gtk_tree_model_foreach()) */
|
2007-08-23 11:34:06 +00:00
|
|
|
static gboolean tree_model_find_node(GtkTreeModel *model, GtkTreePath *path,
|
|
|
|
GtkTreeIter *iter, gpointer data)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2008-06-15 13:35:48 +00:00
|
|
|
GeanyDocument *doc;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_model_get(GTK_TREE_MODEL(store_openfiles), iter, DOCUMENTS_DOCUMENT, &doc, -1);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
if (doc == data)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2009-01-19 13:12:45 +00:00
|
|
|
/* unfolding also prevents a strange bug where the selection gets stuck on the parent
|
|
|
|
* when it is collapsed and then switching documents */
|
|
|
|
unfold_parent(iter);
|
2005-11-22 12:26:26 +00:00
|
|
|
gtk_tree_view_set_cursor(GTK_TREE_VIEW(tv.tree_openfiles), path, NULL, FALSE);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else return FALSE;
|
|
|
|
}
|
|
|
|
|
2006-10-29 13:48:39 +00:00
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
void treeviews_select_openfiles_item(GeanyDocument *doc)
|
2007-08-23 11:34:06 +00:00
|
|
|
{
|
2008-06-15 13:35:48 +00:00
|
|
|
gtk_tree_model_foreach(GTK_TREE_MODEL(store_openfiles), tree_model_find_node, doc);
|
2007-08-23 11:34:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-29 13:48:39 +00:00
|
|
|
/* callbacks */
|
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
static void document_action(GeanyDocument *doc, gint action)
|
|
|
|
{
|
2009-04-05 21:07:40 +00:00
|
|
|
if (! DOC_VALID(doc))
|
2009-01-20 16:34:11 +00:00
|
|
|
return;
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case OPENFILES_ACTION_REMOVE:
|
|
|
|
{
|
|
|
|
document_close(doc);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case OPENFILES_ACTION_SAVE:
|
|
|
|
{
|
|
|
|
document_save_file(doc, FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case OPENFILES_ACTION_RELOAD:
|
|
|
|
{
|
|
|
|
on_toolbutton_reload_clicked(NULL, NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-24 16:10:56 +00:00
|
|
|
static void on_openfiles_document_action(GtkMenuItem *menuitem, gpointer user_data)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles));
|
|
|
|
GtkTreeModel *model;
|
2008-06-15 13:35:48 +00:00
|
|
|
GeanyDocument *doc;
|
2009-01-20 16:34:11 +00:00
|
|
|
gint action = GPOINTER_TO_INT(user_data);
|
2006-10-29 13:48:39 +00:00
|
|
|
|
|
|
|
if (gtk_tree_selection_get_selected(selection, &model, &iter))
|
|
|
|
{
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc, -1);
|
2009-01-20 16:34:11 +00:00
|
|
|
if (doc)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
2009-01-20 16:34:11 +00:00
|
|
|
document_action(doc, action);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* parent item selected */
|
|
|
|
GtkTreeIter child;
|
|
|
|
gint i = gtk_tree_model_iter_n_children(model, &iter) - 1;
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
while (i >= 0 && gtk_tree_model_iter_nth_child(model, &child, &iter, i))
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
2009-01-20 16:34:11 +00:00
|
|
|
gtk_tree_model_get(model, &child, DOCUMENTS_DOCUMENT, &doc, -1);
|
|
|
|
|
|
|
|
document_action(doc, action);
|
|
|
|
i--;
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-13 10:46:11 +00:00
|
|
|
static gboolean change_focus(gpointer data)
|
2007-07-09 16:01:23 +00:00
|
|
|
{
|
2008-06-15 13:35:48 +00:00
|
|
|
GeanyDocument *doc = data;
|
2007-07-13 10:46:11 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* idx might not be valid e.g. if user closed a tab whilst Geany is opening files */
|
2008-06-15 13:35:48 +00:00
|
|
|
if (DOC_VALID(doc))
|
2007-07-13 10:46:11 +00:00
|
|
|
{
|
2008-05-22 14:41:28 +00:00
|
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
|
2008-07-14 11:13:54 +00:00
|
|
|
GtkWidget *sci = GTK_WIDGET(doc->editor->sci);
|
2007-07-13 10:46:11 +00:00
|
|
|
|
2007-08-30 14:24:26 +00:00
|
|
|
if (focusw == tv.tree_openfiles)
|
|
|
|
gtk_widget_grab_focus(sci);
|
2007-07-13 10:46:11 +00:00
|
|
|
}
|
2007-07-09 16:01:23 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-29 13:48:39 +00:00
|
|
|
static void on_openfiles_tree_selection_changed(GtkTreeSelection *selection, gpointer data)
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
GtkTreeModel *model;
|
2008-06-15 13:35:48 +00:00
|
|
|
GeanyDocument *doc = NULL;
|
2006-10-29 13:48:39 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* use switch_notebook_page to ignore changing the notebook page because it is already done */
|
2008-05-22 14:41:28 +00:00
|
|
|
if (gtk_tree_selection_get_selected(selection, &model, &iter) && ! ignore_callback)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc, -1);
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(! doc))
|
2009-01-19 13:12:45 +00:00
|
|
|
return; /* parent */
|
2008-05-22 14:41:28 +00:00
|
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
|
|
|
|
gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
|
2008-07-14 11:13:54 +00:00
|
|
|
(GtkWidget*) doc->editor->sci));
|
2008-06-15 13:35:48 +00:00
|
|
|
g_idle_add((GSourceFunc) change_focus, doc);
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-10 11:28:54 +00:00
|
|
|
static gboolean on_taglist_tree_selection_changed(GtkTreeSelection *selection)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
GtkTreeModel *model;
|
2007-07-22 14:38:47 +00:00
|
|
|
gint line = 0;
|
2006-10-29 13:48:39 +00:00
|
|
|
|
|
|
|
if (gtk_tree_selection_get_selected(selection, &model, &iter))
|
|
|
|
{
|
2008-11-03 17:25:35 +00:00
|
|
|
const TMTag *tag;
|
|
|
|
|
|
|
|
gtk_tree_model_get(model, &iter, SYMBOLS_COLUMN_TAG, &tag, -1);
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(! tag))
|
2008-11-03 17:25:35 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
line = tag->atts.entry.line;
|
2007-07-22 14:38:47 +00:00
|
|
|
if (line > 0)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
2008-06-12 20:45:18 +00:00
|
|
|
GeanyDocument *doc = document_get_current();
|
2007-07-17 16:11:38 +00:00
|
|
|
|
2008-06-12 20:45:18 +00:00
|
|
|
navqueue_goto_line(doc, doc, line);
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-10 11:28:54 +00:00
|
|
|
return FALSE;
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-21 18:44:12 +00:00
|
|
|
static gboolean on_treeviews_key_press_event(GtkWidget *widget, GdkEventKey *event,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
if (event->keyval == GDK_Return ||
|
|
|
|
event->keyval == GDK_ISO_Enter ||
|
|
|
|
event->keyval == GDK_KP_Enter ||
|
|
|
|
event->keyval == GDK_space)
|
|
|
|
{
|
|
|
|
GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
|
|
|
|
/* delay the query of selection state because this callback is executed before GTK
|
|
|
|
* changes the selection (g_signal_connect_after would be better but it doesn't work) */
|
|
|
|
g_idle_add((GSourceFunc) on_taglist_tree_selection_changed, select);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
static gboolean on_symbols_button_press_event(GtkWidget *widget, GdkEventButton *event,
|
|
|
|
G_GNUC_UNUSED gpointer user_data)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
2009-01-20 16:34:11 +00:00
|
|
|
GtkTreeSelection *selection;
|
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
|
|
|
|
|
|
|
|
if (event->type == GDK_2BUTTON_PRESS)
|
2008-02-27 13:17:29 +00:00
|
|
|
{ /* double click on parent node(section) expands/collapses it */
|
2007-11-18 15:09:28 +00:00
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
if (gtk_tree_selection_get_selected(selection, &model, &iter))
|
|
|
|
{
|
|
|
|
if (gtk_tree_model_iter_has_child(model, &iter))
|
|
|
|
{
|
|
|
|
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
|
|
|
|
|
|
|
|
if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
|
|
|
|
gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
|
|
|
|
else
|
|
|
|
gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path, FALSE);
|
|
|
|
|
|
|
|
gtk_tree_path_free(path);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-01-20 16:34:11 +00:00
|
|
|
else if (event->button == 1)
|
2008-02-27 13:17:29 +00:00
|
|
|
{ /* allow reclicking of taglist treeview item */
|
|
|
|
/* delay the query of selection state because this callback is executed before GTK
|
|
|
|
* changes the selection (g_signal_connect_after would be better but it doesn't work) */
|
2009-01-20 16:34:11 +00:00
|
|
|
g_idle_add((GSourceFunc) on_taglist_tree_selection_changed, selection);
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
2007-11-18 15:09:28 +00:00
|
|
|
else if (event->button == 3)
|
2009-01-20 16:34:11 +00:00
|
|
|
{
|
|
|
|
gtk_menu_popup(GTK_MENU(tv.popup_taglist), NULL, NULL, NULL, NULL,
|
|
|
|
event->button, event->time);
|
|
|
|
return TRUE; /* prevent selection changed signal for symbol tags */
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void documents_menu_update(GtkTreeSelection *selection)
|
|
|
|
{
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
gboolean sel, path;
|
|
|
|
gchar *shortname = NULL;
|
|
|
|
GeanyDocument *doc = NULL;
|
|
|
|
|
|
|
|
/* maybe no selection e.g. if ctrl-click deselected */
|
|
|
|
sel = gtk_tree_selection_get_selected(selection, &model, &iter);
|
|
|
|
if (sel)
|
|
|
|
{
|
|
|
|
gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc,
|
|
|
|
DOCUMENTS_SHORTNAME, &shortname, -1);
|
|
|
|
}
|
|
|
|
path = NZV(shortname) && g_path_is_absolute(shortname);
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
/* can close all, save all (except shortname), but only reload individually ATM */
|
|
|
|
gtk_widget_set_sensitive(doc_items.close, sel);
|
|
|
|
gtk_widget_set_sensitive(doc_items.save, (doc && doc->real_path) || path);
|
|
|
|
gtk_widget_set_sensitive(doc_items.reload, doc && doc->real_path);
|
|
|
|
g_free(shortname);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean on_documents_button_release_event(GtkWidget *widget, GdkEventButton *event,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
if (event->button == 3)
|
|
|
|
{
|
|
|
|
documents_menu_update(selection);
|
|
|
|
gtk_menu_popup(GTK_MENU(tv.popup_openfiles), NULL, NULL, NULL, NULL,
|
|
|
|
event->button, event->time);
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-08-23 11:34:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
void treeviews_init()
|
|
|
|
{
|
|
|
|
tv.default_tag_tree = NULL;
|
2008-12-18 21:21:53 +00:00
|
|
|
tag_window = ui_lookup_widget(main_widgets.window, "scrolledwindow2");
|
2007-08-23 11:34:06 +00:00
|
|
|
|
|
|
|
prepare_openfiles();
|
|
|
|
create_openfiles_popup_menu();
|
|
|
|
}
|
|
|
|
|
|
|
|
|