2005-11-22 12:26:26 +00:00
|
|
|
/*
|
2009-09-28 11:16:59 +00:00
|
|
|
* sidebar.c - this file is part of Geany, a fast and lightweight IDE
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
2011-01-19 19:39:09 +00:00
|
|
|
* Copyright 2005-2011 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
|
|
|
|
* Copyright 2006-2011 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"
|
2009-09-28 11:16:59 +00:00
|
|
|
#include "sidebar.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"
|
2009-04-16 17:55:42 +00:00
|
|
|
#include "project.h"
|
2009-07-16 15:04:21 +00:00
|
|
|
#include "stash.h"
|
|
|
|
#include "keyfile.h"
|
2009-09-03 12:04:27 +00:00
|
|
|
#include "sciwrappers.h"
|
2010-07-05 11:55:44 +00:00
|
|
|
#include "search.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
|
|
|
|
2010-02-28 14:30:27 +00:00
|
|
|
|
2009-07-16 15:50:13 +00:00
|
|
|
SidebarTreeviews tv = {NULL, NULL, NULL};
|
2009-09-03 12:04:27 +00:00
|
|
|
/* while typeahead searching, editor should not get focus */
|
|
|
|
static gboolean may_steal_focus = FALSE;
|
2007-08-23 11:34:06 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
static struct
|
|
|
|
{
|
|
|
|
GtkWidget *close;
|
|
|
|
GtkWidget *save;
|
|
|
|
GtkWidget *reload;
|
2009-07-16 15:04:21 +00:00
|
|
|
GtkWidget *show_paths;
|
2010-07-05 11:55:44 +00:00
|
|
|
GtkWidget *find_in_files;
|
2009-01-20 16:34:11 +00:00
|
|
|
}
|
2010-07-05 11:55:44 +00:00
|
|
|
doc_items = {NULL, NULL, NULL, NULL, NULL};
|
2009-01-20 16:34:11 +00:00
|
|
|
|
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;
|
2009-07-16 15:50:13 +00:00
|
|
|
static GtkWidget *openfiles_popup_menu;
|
2009-07-16 15:04:21 +00:00
|
|
|
static gboolean documents_show_paths;
|
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 */
|
2007-10-24 16:10:56 +00:00
|
|
|
static void on_openfiles_document_action(GtkMenuItem *menuitem, gpointer user_data);
|
2009-09-28 11:16:59 +00:00
|
|
|
static gboolean sidebar_button_press_cb(GtkWidget *widget, GdkEventButton *event,
|
2009-01-20 16:34:11 +00:00
|
|
|
gpointer user_data);
|
2009-09-28 11:16:59 +00:00
|
|
|
static gboolean sidebar_key_press_cb(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);
|
2009-09-03 12:04:27 +00:00
|
|
|
static void documents_menu_update(GtkTreeSelection *selection);
|
2010-04-19 20:42:34 +00:00
|
|
|
static void sidebar_tabs_show_hide(GtkNotebook *notebook, GtkWidget *child,
|
|
|
|
guint page_num, gpointer 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;
|
2009-10-25 12:21:05 +00:00
|
|
|
GtkTreeSelection *selection;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2007-07-20 16:33:16 +00:00
|
|
|
text_renderer = gtk_cell_renderer_text_new();
|
|
|
|
icon_renderer = gtk_cell_renderer_pixbuf_new();
|
2009-09-03 12:04:27 +00:00
|
|
|
column = gtk_tree_view_column_new();
|
2007-07-20 16:33:16 +00:00
|
|
|
|
2009-09-03 12:04:27 +00:00
|
|
|
gtk_tree_view_column_pack_start(column, icon_renderer, FALSE);
|
2007-07-20 16:33:16 +00:00
|
|
|
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-09-28 11:16:59 +00:00
|
|
|
G_CALLBACK(sidebar_button_press_cb), NULL);
|
2008-07-18 13:40:48 +00:00
|
|
|
g_signal_connect(tree, "key-press-event",
|
2009-09-28 11:16:59 +00:00
|
|
|
G_CALLBACK(sidebar_key_press_cb), NULL);
|
2006-04-28 15:05:11 +00:00
|
|
|
|
2011-06-17 22:52:43 +00:00
|
|
|
gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(tree), interface_prefs.show_symbol_list_expanders);
|
2011-06-13 20:43:17 +00:00
|
|
|
if (! interface_prefs.show_symbol_list_expanders)
|
2011-06-17 22:52:43 +00:00
|
|
|
gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(tree), 10);
|
2011-06-13 20:43:17 +00:00
|
|
|
/* Tooltips */
|
2011-06-17 22:52:43 +00:00
|
|
|
gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(tree), SYMBOLS_COLUMN_TOOLTIP);
|
2007-11-18 15:09:28 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* selection handling */
|
2009-10-25 12:21:05 +00:00
|
|
|
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
|
|
|
|
gtk_tree_selection_set_mode(selection, 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-07-16 15:19:57 +00:00
|
|
|
gtk_menu_popup(GTK_MENU(tv.popup_taglist), NULL, NULL, NULL, NULL,
|
|
|
|
event->button, event->time);
|
|
|
|
return TRUE;
|
2007-02-13 12:02:16 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-16 15:19:57 +00:00
|
|
|
static void create_default_tag_tree(void)
|
|
|
|
{
|
|
|
|
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW(tag_window);
|
|
|
|
GtkWidget *label;
|
|
|
|
|
|
|
|
/* default_tag_tree is a GtkViewPort with a GtkLabel inside it */
|
|
|
|
tv.default_tag_tree = gtk_viewport_new(
|
|
|
|
gtk_scrolled_window_get_hadjustment(scrolled_window),
|
|
|
|
gtk_scrolled_window_get_vadjustment(scrolled_window));
|
|
|
|
label = gtk_label_new(_("No tags found"));
|
2010-04-25 17:43:39 +00:00
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.1f, 0.01f);
|
2009-07-16 15:19:57 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(tv.default_tag_tree), label);
|
|
|
|
gtk_widget_show_all(tv.default_tag_tree);
|
|
|
|
g_signal_connect(tv.default_tag_tree, "button-press-event",
|
|
|
|
G_CALLBACK(on_default_tag_tree_button_press_event), NULL);
|
|
|
|
g_object_ref((gpointer)tv.default_tag_tree); /* to hold it after removing */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-15 13:35:48 +00:00
|
|
|
/* update = rescan the tags for doc->filename */
|
2009-09-28 11:16:59 +00:00
|
|
|
void sidebar_update_tag_list(GeanyDocument *doc, gboolean update)
|
2007-02-05 16:17:44 +00:00
|
|
|
{
|
2011-03-05 22:51:32 +00:00
|
|
|
GtkWidget *child = gtk_bin_get_child(GTK_BIN(tag_window));
|
|
|
|
|
|
|
|
/* changes the tree view to the given one, trying not to do useless changes */
|
|
|
|
#define CHANGE_TREE(new_child) \
|
|
|
|
G_STMT_START { \
|
2011-04-26 16:21:47 +00:00
|
|
|
/* only change the tag tree if it's actually not the same (to avoid flickering) and if
|
|
|
|
* it's the one of the current document (to avoid problems when e.g. reloading
|
|
|
|
* configuration files */ \
|
|
|
|
if (child != new_child && doc == document_get_current()) \
|
2011-03-05 22:51:32 +00:00
|
|
|
{ \
|
|
|
|
if (child) \
|
|
|
|
gtk_container_remove(GTK_CONTAINER(tag_window), child); \
|
|
|
|
gtk_container_add(GTK_CONTAINER(tag_window), new_child); \
|
|
|
|
} \
|
|
|
|
} G_STMT_END
|
2007-02-05 16:17:44 +00:00
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
if (tv.default_tag_tree == NULL)
|
2009-07-16 15:19:57 +00:00
|
|
|
create_default_tag_tree();
|
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-15 22:47:33 +00:00
|
|
|
if (doc == NULL || doc->file_type == NULL || ! filetype_has_tags(doc->file_type))
|
2007-02-05 16:17:44 +00:00
|
|
|
{
|
2011-03-05 22:51:32 +00:00
|
|
|
CHANGE_TREE(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-15 22:47:33 +00:00
|
|
|
if (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(
|
Update the symbol list rather than clearing and re-building it
The main advantages of not clearing and rebuilding the whole list is
that it doesn't loose the folding and selection (as far as the selected
row(s) still exist after the update, of course), and it reduces
flickering upon update.
The current implementation works in 3-steps:
1) mark all rows as invalid;
2) insert/update the rows, according to the new tag list, marking them
as valid;
3) remove all rows that are still invalid.
This walks (rows) the first time, (tags*rows) the second and (rows) the
third. This also uses an extra column to store the row's validity.
A (probably) better implementation would be to:
1) walk the current rows, updating them if necessary, or removing them;
2) add the remaining tags that weren't there before.
This is probably faster in theory (and probably also in practice), but
it needs to refactor a lot the code to easily update *or* create a row,
what the current code does not provide.
Basically this is would be a two-pass update, walking (rows*tags) in
the first pass, and only the remaining non-added tags in the second.
git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@5562 ea778897-0a13-0410-b9d1-a72fbfd435f5
2011-03-05 22:53:13 +00:00
|
|
|
SYMBOLS_N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, TM_TYPE_TAG, G_TYPE_STRING, G_TYPE_BOOLEAN);
|
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
|
|
|
{
|
2011-03-05 22:51:32 +00:00
|
|
|
CHANGE_TREE(doc->priv->tag_tree);
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-03-05 22:51:32 +00:00
|
|
|
CHANGE_TREE(tv.default_tag_tree);
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
2011-03-05 22:51:32 +00:00
|
|
|
|
|
|
|
#undef CHANGE_TREE
|
2007-02-05 16:17:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-14 14:46:20 +00:00
|
|
|
/* cleverly sorts documents by their short name */
|
|
|
|
static gint documents_sort_func(GtkTreeModel *model, GtkTreeIter *iter_a,
|
|
|
|
GtkTreeIter *iter_b, gpointer data)
|
|
|
|
{
|
|
|
|
gchar *key_a, *key_b;
|
|
|
|
gchar *name_a, *name_b;
|
|
|
|
gint cmp;
|
|
|
|
|
|
|
|
gtk_tree_model_get(model, iter_a, DOCUMENTS_SHORTNAME, &name_a, -1);
|
|
|
|
key_a = g_utf8_collate_key_for_filename(name_a, -1);
|
|
|
|
g_free(name_a);
|
|
|
|
gtk_tree_model_get(model, iter_b, DOCUMENTS_SHORTNAME, &name_b, -1);
|
|
|
|
key_b = g_utf8_collate_key_for_filename(name_b, -1);
|
|
|
|
g_free(name_b);
|
|
|
|
cmp = strcmp(key_a, key_b);
|
|
|
|
g_free(key_b);
|
|
|
|
g_free(key_a);
|
|
|
|
|
|
|
|
return cmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
2009-10-25 12:21:05 +00:00
|
|
|
GtkTreeSelection *selection;
|
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 */
|
2010-10-26 17:20:48 +00:00
|
|
|
store_openfiles = gtk_tree_store_new(5, GDK_TYPE_PIXBUF, G_TYPE_STRING,
|
2009-03-30 18:46:37 +00:00
|
|
|
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));
|
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(
|
2009-09-03 12:04:27 +00:00
|
|
|
GTK_SCROLLED_WINDOW(ui_lookup_widget(main_widgets.window, "scrolledwindow7")),
|
|
|
|
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();
|
2009-04-24 19:30:07 +00:00
|
|
|
g_object_set(text_renderer, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
|
2009-03-30 18:46:37 +00:00
|
|
|
column = gtk_tree_view_column_new();
|
|
|
|
gtk_tree_view_column_pack_start(column, icon_renderer, FALSE);
|
2010-10-26 17:20:48 +00:00
|
|
|
gtk_tree_view_column_set_attributes(column, icon_renderer, "pixbuf", DOCUMENTS_ICON, NULL);
|
2009-03-30 18:46:37 +00:00
|
|
|
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);
|
|
|
|
|
2009-09-03 12:04:27 +00:00
|
|
|
gtk_tree_view_set_search_column(GTK_TREE_VIEW(tv.tree_openfiles),
|
|
|
|
DOCUMENTS_SHORTNAME);
|
2006-04-28 15:05:11 +00:00
|
|
|
|
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));
|
2010-05-14 14:46:20 +00:00
|
|
|
gtk_tree_sortable_set_sort_func(sortable, DOCUMENTS_SHORTNAME, documents_sort_func, NULL, NULL);
|
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
|
|
|
|
2011-06-13 23:03:19 +00:00
|
|
|
/* tooltips */
|
2011-06-17 22:52:43 +00:00
|
|
|
gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(tv.tree_openfiles), DOCUMENTS_FILENAME);
|
2007-10-09 12:26:44 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* selection handling */
|
2009-10-25 12:21:05 +00:00
|
|
|
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles));
|
|
|
|
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
|
2009-09-03 12:04:27 +00:00
|
|
|
g_object_unref(store_openfiles);
|
|
|
|
|
|
|
|
g_signal_connect(GTK_TREE_VIEW(tv.tree_openfiles), "button-press-event",
|
2009-09-28 11:16:59 +00:00
|
|
|
G_CALLBACK(sidebar_button_press_cb), NULL);
|
2009-09-03 12:04:27 +00:00
|
|
|
g_signal_connect(GTK_TREE_VIEW(tv.tree_openfiles), "key-press-event",
|
2009-09-28 11:16:59 +00:00
|
|
|
G_CALLBACK(sidebar_key_press_cb), 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;
|
2009-04-16 17:57:29 +00:00
|
|
|
gboolean result;
|
2009-01-19 13:12:45 +00:00
|
|
|
|
|
|
|
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);
|
2009-04-16 17:57:29 +00:00
|
|
|
|
|
|
|
result = utils_str_equal(name, dir);
|
|
|
|
g_free(name);
|
|
|
|
|
|
|
|
return result;
|
2009-01-19 13:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-05 11:55:44 +00:00
|
|
|
static gchar *get_doc_folder(const gchar *path)
|
2009-01-19 13:12:45 +00:00
|
|
|
{
|
2010-07-05 11:55:44 +00:00
|
|
|
gchar *tmp_dirname = g_strdup(path);
|
2009-04-16 17:55:42 +00:00
|
|
|
gchar *project_base_path;
|
|
|
|
gchar *dirname = NULL;
|
2010-06-17 12:03:00 +00:00
|
|
|
const gchar *home_dir = g_get_home_dir();
|
|
|
|
const gchar *rest;
|
2009-02-05 19:18:46 +00:00
|
|
|
|
2009-04-16 17:55:42 +00:00
|
|
|
/* replace the project base path with the project name */
|
|
|
|
project_base_path = project_get_base_path();
|
2010-06-17 12:14:48 +00:00
|
|
|
|
2009-04-16 17:55:42 +00:00
|
|
|
if (project_base_path != NULL)
|
|
|
|
{
|
|
|
|
gsize len = strlen(project_base_path);
|
2009-07-07 12:46:45 +00:00
|
|
|
|
2010-06-06 17:21:52 +00:00
|
|
|
if (project_base_path[len-1] == G_DIR_SEPARATOR)
|
|
|
|
project_base_path[len-1] = '\0';
|
|
|
|
|
2009-07-20 15:46:35 +00:00
|
|
|
/* check whether the dir name matches or uses the project base path */
|
2009-07-07 12:46:45 +00:00
|
|
|
if (g_str_has_prefix(tmp_dirname, project_base_path))
|
2009-04-16 17:55:42 +00:00
|
|
|
{
|
|
|
|
rest = tmp_dirname + len;
|
2010-06-06 17:21:52 +00:00
|
|
|
if (*rest == G_DIR_SEPARATOR || *rest == '\0')
|
2010-06-17 12:03:00 +00:00
|
|
|
{
|
2010-06-06 17:21:52 +00:00
|
|
|
dirname = g_strdup_printf("%s%s", app->project->name, rest);
|
2010-06-17 12:03:00 +00:00
|
|
|
}
|
2009-04-16 17:55:42 +00:00
|
|
|
}
|
|
|
|
g_free(project_base_path);
|
|
|
|
}
|
|
|
|
if (dirname == NULL)
|
2010-06-17 12:03:00 +00:00
|
|
|
{
|
2009-04-16 17:55:42 +00:00
|
|
|
dirname = tmp_dirname;
|
2010-06-17 12:03:00 +00:00
|
|
|
|
|
|
|
/* If matches home dir, replace with tilde */
|
|
|
|
if (home_dir && *home_dir != 0 && g_str_has_prefix(dirname, home_dir))
|
|
|
|
{
|
|
|
|
rest = dirname + strlen(home_dir);
|
|
|
|
if (*rest == G_DIR_SEPARATOR || *rest == '\0')
|
|
|
|
{
|
|
|
|
dirname = g_strdup_printf("~%s", rest);
|
|
|
|
g_free(tmp_dirname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-04-16 17:55:42 +00:00
|
|
|
else
|
|
|
|
g_free(tmp_dirname);
|
2009-01-19 13:12:45 +00:00
|
|
|
|
2010-06-17 12:14:48 +00:00
|
|
|
return dirname;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static GtkTreeIter *get_doc_parent(GeanyDocument *doc)
|
|
|
|
{
|
2010-07-05 11:55:44 +00:00
|
|
|
gchar *path;
|
2010-06-17 12:14:48 +00:00
|
|
|
gchar *dirname = NULL;
|
|
|
|
static GtkTreeIter parent;
|
|
|
|
GtkTreeModel *model = GTK_TREE_MODEL(store_openfiles);
|
2010-10-26 17:20:48 +00:00
|
|
|
static GdkPixbuf *dir_icon = NULL;
|
2010-06-17 12:14:48 +00:00
|
|
|
|
|
|
|
if (!documents_show_paths)
|
|
|
|
return NULL;
|
|
|
|
|
2010-07-05 11:55:44 +00:00
|
|
|
path = g_path_get_dirname(DOC_FILENAME(doc));
|
|
|
|
dirname = get_doc_folder(path);
|
2010-06-17 12:14:48 +00:00
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
if (gtk_tree_model_get_iter_first(model, &parent))
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (find_tree_iter_dir(&parent, dirname))
|
|
|
|
{
|
|
|
|
g_free(dirname);
|
2010-07-05 11:55:44 +00:00
|
|
|
g_free(path);
|
2009-01-19 13:12:45 +00:00
|
|
|
return &parent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (gtk_tree_model_iter_next(model, &parent));
|
|
|
|
}
|
|
|
|
/* no match, add dir parent */
|
2010-10-26 17:20:48 +00:00
|
|
|
if (!dir_icon)
|
|
|
|
dir_icon = ui_get_mime_icon("inode/directory", GTK_ICON_SIZE_MENU);
|
|
|
|
|
2009-01-19 13:12:45 +00:00
|
|
|
gtk_tree_store_append(store_openfiles, &parent, NULL);
|
2010-10-26 17:20:48 +00:00
|
|
|
gtk_tree_store_set(store_openfiles, &parent, DOCUMENTS_ICON, dir_icon,
|
2010-07-05 11:55:44 +00:00
|
|
|
DOCUMENTS_FILENAME, path,
|
2009-03-30 18:46:37 +00:00
|
|
|
DOCUMENTS_SHORTNAME, doc->file_name ? dirname : GEANY_STRING_UNTITLED, -1);
|
2009-01-19 13:12:45 +00:00
|
|
|
|
|
|
|
g_free(dirname);
|
2010-07-05 11:55:44 +00:00
|
|
|
g_free(path);
|
2009-01-19 13:12:45 +00:00
|
|
|
return &parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Also sets doc->priv->iter.
|
2009-09-28 11:16:59 +00:00
|
|
|
* This is called recursively in sidebar_openfiles_update_all(). */
|
|
|
|
void sidebar_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);
|
2010-10-26 17:20:48 +00:00
|
|
|
static GdkPixbuf *file_icon = NULL;
|
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 */
|
2009-07-16 15:04:21 +00:00
|
|
|
if (parent && gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_openfiles), parent) == 1)
|
2009-01-19 13:12:45 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2010-10-26 17:20:48 +00:00
|
|
|
if (!file_icon)
|
|
|
|
file_icon = ui_get_mime_icon("text/plain", GTK_ICON_SIZE_MENU);
|
|
|
|
|
2009-04-24 19:30:07 +00:00
|
|
|
basename = g_path_get_basename(DOC_FILENAME(doc));
|
2010-10-26 17:20:48 +00:00
|
|
|
gtk_tree_store_set(store_openfiles, iter,
|
|
|
|
DOCUMENTS_ICON, (doc->file_type && doc->file_type->icon) ? doc->file_type->icon : file_icon,
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
void sidebar_openfiles_update(GeanyDocument *doc)
|
2009-01-19 13:12:45 +00:00
|
|
|
{
|
|
|
|
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)))
|
|
|
|
{
|
2010-10-26 17:20:48 +00:00
|
|
|
/* just update color and the icon */
|
2009-02-08 19:52:21 +00:00
|
|
|
const GdkColor *color = document_get_status_color(doc);
|
2010-10-26 17:20:48 +00:00
|
|
|
GdkPixbuf *icon = doc->file_type->icon;
|
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);
|
2010-10-26 17:20:48 +00:00
|
|
|
if (icon)
|
|
|
|
gtk_tree_store_set(store_openfiles, iter, DOCUMENTS_ICON, icon, -1);
|
2009-01-19 13:12:45 +00:00
|
|
|
}
|
|
|
|
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-09-28 11:16:59 +00:00
|
|
|
sidebar_openfiles_add(doc);
|
2009-01-19 13:12:45 +00:00
|
|
|
if (sel)
|
|
|
|
gtk_tree_selection_select_iter(treesel, &doc->priv->iter);
|
|
|
|
}
|
|
|
|
g_free(fname);
|
2006-01-14 22:41:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
void sidebar_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
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
sidebar_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
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
void sidebar_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
|
|
|
{
|
2009-09-28 11:16:59 +00:00
|
|
|
/* Because it was ref'd in sidebar_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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-16 15:04:21 +00:00
|
|
|
static void on_openfiles_show_paths_activate(GtkCheckMenuItem *item, gpointer user_data)
|
|
|
|
{
|
|
|
|
documents_show_paths = gtk_check_menu_item_get_active(item);
|
2009-09-28 11:16:59 +00:00
|
|
|
sidebar_openfiles_update_all();
|
2009-07-16 15:04:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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();
|
2010-04-19 20:42:34 +00:00
|
|
|
sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL);
|
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();
|
2010-04-19 20:42:34 +00:00
|
|
|
sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL);
|
2007-10-28 21:14:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-05 11:55:44 +00:00
|
|
|
static void on_find_in_files(GtkMenuItem *menuitem, gpointer user_data)
|
|
|
|
{
|
|
|
|
GtkTreeSelection *treesel;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GeanyDocument *doc;
|
|
|
|
gchar *dir;
|
|
|
|
|
|
|
|
treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles));
|
|
|
|
if (!gtk_tree_selection_get_selected(treesel, &model, &iter))
|
|
|
|
return;
|
|
|
|
gtk_tree_model_get(model, &iter, DOCUMENTS_DOCUMENT, &doc, -1);
|
|
|
|
|
|
|
|
if (!doc)
|
|
|
|
{
|
|
|
|
gtk_tree_model_get(model, &iter, DOCUMENTS_FILENAME, &dir, -1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
dir = g_path_get_dirname(DOC_FILENAME(doc));
|
|
|
|
|
|
|
|
search_show_find_in_files_dialog(dir);
|
|
|
|
g_free(dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2009-07-16 15:50:13 +00:00
|
|
|
openfiles_popup_menu = gtk_menu_new();
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
item = gtk_image_menu_item_new_from_stock("gtk-close", NULL);
|
|
|
|
gtk_widget_show(item);
|
2009-07-16 15:50:13 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), 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);
|
2009-07-16 15:50:13 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
item = gtk_image_menu_item_new_from_stock("gtk-save", NULL);
|
|
|
|
gtk_widget_show(item);
|
2009-07-16 15:50:13 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), 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);
|
2009-07-16 15:50:13 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), 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-07-16 15:04:21 +00:00
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
2009-07-16 15:50:13 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item);
|
2009-07-16 15:04:21 +00:00
|
|
|
|
2010-07-05 11:55:44 +00:00
|
|
|
item = ui_image_menu_item_new(GTK_STOCK_FIND, _("_Find in Files"));
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item);
|
|
|
|
g_signal_connect(item, "activate", G_CALLBACK(on_find_in_files), NULL);
|
|
|
|
doc_items.find_in_files = item;
|
|
|
|
|
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), item);
|
|
|
|
|
2009-07-16 15:04:21 +00:00
|
|
|
doc_items.show_paths = gtk_check_menu_item_new_with_mnemonic(_("Show _Paths"));
|
2011-03-26 03:12:50 +00:00
|
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(doc_items.show_paths), documents_show_paths);
|
2009-07-16 15:04:21 +00:00
|
|
|
gtk_widget_show(doc_items.show_paths);
|
2009-07-16 15:50:13 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(openfiles_popup_menu), doc_items.show_paths);
|
2009-07-16 15:04:21 +00:00
|
|
|
g_signal_connect(doc_items.show_paths, "activate",
|
|
|
|
G_CALLBACK(on_openfiles_show_paths_activate), NULL);
|
|
|
|
|
2009-07-16 15:50:13 +00:00
|
|
|
sidebar_add_common_menu_items(GTK_MENU(openfiles_popup_menu));
|
2009-01-19 13:12:45 +00:00
|
|
|
}
|
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-07-16 15:04:21 +00:00
|
|
|
if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(store_openfiles), &parent, iter))
|
|
|
|
{
|
|
|
|
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
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
void sidebar_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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-28 14:32:38 +00:00
|
|
|
static void change_focus_to_editor(GeanyDocument *doc, GtkWidget *source_widget)
|
2007-07-09 16:01:23 +00:00
|
|
|
{
|
2009-09-03 12:04:27 +00:00
|
|
|
if (may_steal_focus)
|
2010-02-28 14:32:38 +00:00
|
|
|
document_try_focus(doc, source_widget);
|
2009-09-03 12:04:27 +00:00
|
|
|
may_steal_focus = FALSE;
|
2007-07-09 16:01:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-26 03:12:50 +00:00
|
|
|
static gboolean openfiles_go_to_selection(GtkTreeSelection *selection, guint keyval)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
|
|
|
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 */
|
2011-03-26 03:12:50 +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-15 22:47:33 +00:00
|
|
|
if (! doc)
|
2009-09-03 12:04:27 +00:00
|
|
|
return FALSE; /* parent */
|
|
|
|
|
2009-09-04 11:34:12 +00:00
|
|
|
/* switch to the doc and grab the focus */
|
|
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
|
|
|
|
gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
|
|
|
|
(GtkWidget*) doc->editor->sci));
|
2011-03-26 03:12:50 +00:00
|
|
|
if (keyval != GDK_space)
|
2010-02-28 14:32:38 +00:00
|
|
|
change_focus_to_editor(doc, tv.tree_openfiles);
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
2009-09-03 12:04:27 +00:00
|
|
|
return FALSE;
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-26 03:12:50 +00:00
|
|
|
static gboolean taglist_go_to_selection(GtkTreeSelection *selection, guint keyval)
|
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
|
|
|
|
2011-03-26 03:12:50 +00:00
|
|
|
if (gtk_tree_selection_get_selected(selection, &model, &iter))
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
2011-03-06 17:08:54 +00:00
|
|
|
TMTag *tag;
|
2008-11-03 17:25:35 +00:00
|
|
|
|
|
|
|
gtk_tree_model_get(model, &iter, SYMBOLS_COLUMN_TAG, &tag, -1);
|
2009-04-15 22:47:33 +00:00
|
|
|
if (! 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
|
|
|
|
2009-04-27 20:22:47 +00:00
|
|
|
if (doc != NULL)
|
|
|
|
{
|
|
|
|
navqueue_goto_line(doc, doc, line);
|
2011-03-26 03:12:50 +00:00
|
|
|
if (keyval != GDK_space)
|
2010-02-28 14:32:38 +00:00
|
|
|
change_focus_to_editor(doc, NULL);
|
2009-04-27 20:22:47 +00:00
|
|
|
}
|
2006-10-29 13:48:39 +00:00
|
|
|
}
|
2011-03-05 22:50:04 +00:00
|
|
|
tm_tag_unref(tag);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
static gboolean sidebar_key_press_cb(GtkWidget *widget, GdkEventKey *event,
|
2008-03-21 18:44:12 +00:00
|
|
|
gpointer user_data)
|
|
|
|
{
|
2009-09-03 12:04:27 +00:00
|
|
|
may_steal_focus = FALSE;
|
2010-03-07 19:33:15 +00:00
|
|
|
if (ui_is_keyval_enter_or_return(event->keyval) || event->keyval == GDK_space)
|
2008-03-21 18:44:12 +00:00
|
|
|
{
|
2011-03-26 03:12:50 +00:00
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS(widget);
|
2009-10-25 12:21:05 +00:00
|
|
|
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
|
2009-09-06 16:49:51 +00:00
|
|
|
may_steal_focus = TRUE;
|
2010-02-28 14:30:27 +00:00
|
|
|
|
2011-03-26 03:12:50 +00:00
|
|
|
/* force the TreeView handler to run before us for it to do its job (selection & stuff).
|
|
|
|
* doing so will prevent further handlers to be run in most cases, but the only one is our
|
|
|
|
* own, so guess it's fine. */
|
|
|
|
if (widget_class->key_press_event)
|
|
|
|
widget_class->key_press_event(widget, event);
|
|
|
|
|
|
|
|
if (widget == tv.tree_openfiles) /* tag and doc list have separate handlers */
|
|
|
|
openfiles_go_to_selection(selection, event->keyval);
|
2009-09-03 12:04:27 +00:00
|
|
|
else
|
2011-03-26 03:12:50 +00:00
|
|
|
taglist_go_to_selection(selection, event->keyval);
|
|
|
|
|
|
|
|
return TRUE;
|
2008-03-21 18:44:12 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
static gboolean sidebar_button_press_cb(GtkWidget *widget, GdkEventButton *event,
|
2009-01-20 16:34:11 +00:00
|
|
|
G_GNUC_UNUSED gpointer user_data)
|
2006-10-29 13:48:39 +00:00
|
|
|
{
|
2009-01-20 16:34:11 +00:00
|
|
|
GtkTreeSelection *selection;
|
2011-03-26 03:12:50 +00:00
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS(widget);
|
|
|
|
gboolean handled = FALSE;
|
|
|
|
|
|
|
|
/* force the TreeView handler to run before us for it to do its job (selection & stuff).
|
|
|
|
* doing so will prevent further handlers to be run in most cases, but the only one is our own,
|
|
|
|
* so guess it's fine. */
|
|
|
|
if (widget_class->button_press_event)
|
|
|
|
handled = widget_class->button_press_event(widget, event);
|
2009-01-20 16:34:11 +00:00
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
|
2009-09-03 12:04:27 +00:00
|
|
|
may_steal_focus = TRUE;
|
2009-01-20 16:34:11 +00:00
|
|
|
|
|
|
|
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 */
|
2009-09-03 12:04:27 +00:00
|
|
|
if (widget == tv.tree_openfiles)
|
2011-03-26 03:12:50 +00:00
|
|
|
openfiles_go_to_selection(selection, 0);
|
2009-09-03 12:04:27 +00:00
|
|
|
else
|
2011-03-26 03:12:50 +00:00
|
|
|
taglist_go_to_selection(selection, 0);
|
|
|
|
handled = TRUE;
|
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
|
|
|
{
|
2009-09-03 12:04:27 +00:00
|
|
|
if (widget == tv.tree_openfiles)
|
|
|
|
{
|
|
|
|
if (!openfiles_popup_menu)
|
|
|
|
create_openfiles_popup_menu();
|
|
|
|
|
2009-09-07 15:42:21 +00:00
|
|
|
/* update menu item sensitivity */
|
|
|
|
documents_menu_update(selection);
|
2009-09-03 12:04:27 +00:00
|
|
|
gtk_menu_popup(GTK_MENU(openfiles_popup_menu), NULL, NULL, NULL, NULL,
|
|
|
|
event->button, event->time);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_menu_popup(GTK_MENU(tv.popup_taglist), NULL, NULL, NULL, NULL,
|
|
|
|
event->button, event->time);
|
|
|
|
}
|
2011-03-26 03:12:50 +00:00
|
|
|
handled = TRUE;
|
2009-01-20 16:34:11 +00:00
|
|
|
}
|
2011-03-26 03:12:50 +00:00
|
|
|
return handled;
|
2009-01-20 16:34:11 +00:00
|
|
|
}
|
|
|
|
|
2009-09-16 14:13:38 +00:00
|
|
|
|
2009-01-20 16:34:11 +00:00
|
|
|
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);
|
|
|
|
}
|
2009-04-16 17:55:42 +00:00
|
|
|
path = NZV(shortname) &&
|
|
|
|
(g_path_is_absolute(shortname) ||
|
|
|
|
(app->project && g_str_has_prefix(shortname, app->project->name)));
|
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);
|
2010-07-05 11:55:44 +00:00
|
|
|
gtk_widget_set_sensitive(doc_items.find_in_files, sel);
|
2009-01-20 16:34:11 +00:00
|
|
|
g_free(shortname);
|
2009-07-16 15:04:21 +00:00
|
|
|
|
|
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(doc_items.show_paths),
|
|
|
|
documents_show_paths);
|
2009-01-20 16:34:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-07 11:50:16 +00:00
|
|
|
static StashGroup *stash_group = NULL;
|
2009-07-20 12:00:06 +00:00
|
|
|
|
2009-07-16 15:04:21 +00:00
|
|
|
static void on_load_settings(void)
|
2007-08-23 11:34:06 +00:00
|
|
|
{
|
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();
|
2009-07-20 12:00:06 +00:00
|
|
|
/* note: ui_prefs.sidebar_page is reapplied after plugins are loaded */
|
|
|
|
stash_group_display(stash_group, NULL);
|
2010-04-19 20:42:34 +00:00
|
|
|
sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL);
|
2009-07-20 12:00:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void on_save_settings(void)
|
|
|
|
{
|
|
|
|
stash_group_update(stash_group, NULL);
|
2010-04-19 20:42:34 +00:00
|
|
|
sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL);
|
2009-07-16 15:04:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
void sidebar_init(void)
|
2009-07-16 15:04:21 +00:00
|
|
|
{
|
2010-03-18 17:04:17 +00:00
|
|
|
StashGroup *group;
|
2009-07-16 15:04:21 +00:00
|
|
|
|
|
|
|
group = stash_group_new(PACKAGE);
|
|
|
|
stash_group_add_boolean(group, &documents_show_paths, "documents_show_paths", TRUE);
|
2009-07-20 12:00:06 +00:00
|
|
|
stash_group_add_widget_property(group, &ui_prefs.sidebar_page, "sidebar_page", GINT_TO_POINTER(0),
|
|
|
|
main_widgets.sidebar_notebook, "page", 0);
|
2009-07-16 15:04:21 +00:00
|
|
|
configuration_add_pref_group(group, FALSE);
|
2009-07-20 12:00:06 +00:00
|
|
|
stash_group = group;
|
2009-07-16 15:04:21 +00:00
|
|
|
|
|
|
|
/* delay building documents treeview until sidebar font has been read */
|
|
|
|
g_signal_connect(geany_object, "load-settings", on_load_settings, NULL);
|
2009-07-20 12:00:06 +00:00
|
|
|
g_signal_connect(geany_object, "save-settings", on_save_settings, NULL);
|
2007-08-23 11:34:06 +00:00
|
|
|
|
2011-06-13 23:03:19 +00:00
|
|
|
g_signal_connect(main_widgets.sidebar_notebook, "page-added",
|
|
|
|
G_CALLBACK(sidebar_tabs_show_hide), NULL);
|
|
|
|
g_signal_connect(main_widgets.sidebar_notebook, "page-removed",
|
|
|
|
G_CALLBACK(sidebar_tabs_show_hide), NULL);
|
|
|
|
/* tabs may have changed when sidebar is reshown */
|
|
|
|
g_signal_connect(main_widgets.sidebar_notebook, "show",
|
|
|
|
G_CALLBACK(sidebar_tabs_show_hide), NULL);
|
2007-08-23 11:34:06 +00:00
|
|
|
|
2010-04-19 20:42:34 +00:00
|
|
|
sidebar_tabs_show_hide(GTK_NOTEBOOK(main_widgets.sidebar_notebook), NULL, 0, NULL);
|
|
|
|
}
|
|
|
|
|
2009-07-16 15:50:13 +00:00
|
|
|
#define WIDGET(w) w && GTK_IS_WIDGET(w)
|
|
|
|
|
2009-09-28 11:16:59 +00:00
|
|
|
void sidebar_finalize(void)
|
2009-07-16 15:50:13 +00:00
|
|
|
{
|
|
|
|
if (WIDGET(tv.default_tag_tree))
|
|
|
|
{
|
|
|
|
g_object_unref(tv.default_tag_tree);
|
2010-06-03 15:37:27 +00:00
|
|
|
/* This is not exactly clean, default_tag_tree's ref_count is 2 when it is shown,
|
|
|
|
* 1 oherwise. We should probably handle the ref_count more accurate. */
|
|
|
|
if (WIDGET(tv.default_tag_tree))
|
|
|
|
gtk_widget_destroy(tv.default_tag_tree);
|
2009-07-16 15:50:13 +00:00
|
|
|
}
|
|
|
|
if (WIDGET(tv.popup_taglist))
|
|
|
|
gtk_widget_destroy(tv.popup_taglist);
|
|
|
|
if (WIDGET(openfiles_popup_menu))
|
|
|
|
gtk_widget_destroy(openfiles_popup_menu);
|
|
|
|
}
|
2010-02-21 18:06:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
void sidebar_focus_openfiles_tab(void)
|
|
|
|
{
|
|
|
|
if (ui_prefs.sidebar_visible && interface_prefs.sidebar_openfiles_visible)
|
|
|
|
{
|
|
|
|
GtkNotebook *notebook = GTK_NOTEBOOK(main_widgets.sidebar_notebook);
|
|
|
|
|
|
|
|
gtk_notebook_set_current_page(notebook, TREEVIEW_OPENFILES);
|
|
|
|
gtk_widget_grab_focus(tv.tree_openfiles);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void sidebar_focus_symbols_tab(void)
|
|
|
|
{
|
|
|
|
if (ui_prefs.sidebar_visible && interface_prefs.sidebar_symbol_visible)
|
|
|
|
{
|
|
|
|
GtkNotebook *notebook = GTK_NOTEBOOK(main_widgets.sidebar_notebook);
|
|
|
|
GtkWidget *symbol_list_scrollwin = gtk_notebook_get_nth_page(notebook, TREEVIEW_SYMBOL);
|
|
|
|
|
|
|
|
gtk_notebook_set_current_page(notebook, TREEVIEW_SYMBOL);
|
|
|
|
gtk_widget_grab_focus(gtk_bin_get_child(GTK_BIN(symbol_list_scrollwin)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-19 20:42:34 +00:00
|
|
|
|
|
|
|
static void sidebar_tabs_show_hide(GtkNotebook *notebook, GtkWidget *child,
|
|
|
|
guint page_num, gpointer data)
|
|
|
|
{
|
2011-06-13 23:03:19 +00:00
|
|
|
gint tabs = gtk_notebook_get_n_pages(notebook);
|
2010-04-19 20:42:34 +00:00
|
|
|
|
2011-06-13 23:03:19 +00:00
|
|
|
if (interface_prefs.sidebar_symbol_visible == FALSE)
|
|
|
|
tabs--;
|
|
|
|
if (interface_prefs.sidebar_openfiles_visible == FALSE)
|
|
|
|
tabs--;
|
2010-04-19 20:42:34 +00:00
|
|
|
|
2011-06-13 23:03:19 +00:00
|
|
|
gtk_notebook_set_show_tabs(notebook, (tabs > 1));
|
2010-04-19 20:42:34 +00:00
|
|
|
}
|