2011-11-07 13:46:58 -06:00
|
|
|
/*
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma-notebook.c
|
|
|
|
* This file is part of pluma
|
2011-11-07 13:46:58 -06:00
|
|
|
*
|
|
|
|
* Copyright (C) 2005 - Paolo Maggi
|
|
|
|
*
|
|
|
|
* 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
|
2012-11-18 19:54:49 -06:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
2011-11-07 13:46:58 -06:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2011-11-07 16:52:18 -06:00
|
|
|
* Modified by the pluma Team, 2005. See the AUTHORS file for a
|
|
|
|
* list of people on the pluma Team.
|
2011-11-07 13:46:58 -06:00
|
|
|
* See the ChangeLog files for a list of changes.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* This file is a modified version of the epiphany file ephy-notebook.c
|
|
|
|
* Here the relevant copyright:
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002 Christophe Fergeau
|
|
|
|
* Copyright (C) 2003 Marco Pesenti Gritti
|
|
|
|
* Copyright (C) 2003, 2004 Christian Persch
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <glib-object.h>
|
|
|
|
#include <glib/gi18n.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
#include "pluma-notebook.h"
|
|
|
|
#include "pluma-tab.h"
|
|
|
|
#include "pluma-tab-label.h"
|
|
|
|
#include "pluma-marshal.h"
|
|
|
|
#include "pluma-window.h"
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
#define AFTER_ALL_TABS -1
|
|
|
|
#define NOT_IN_APP_WINDOWS -2
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
#define PLUMA_NOTEBOOK_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), PLUMA_TYPE_NOTEBOOK, PlumaNotebookPrivate))
|
2011-11-07 13:46:58 -06:00
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
struct _PlumaNotebookPrivate
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
GList *focused_pages;
|
|
|
|
gulong motion_notify_handler_id;
|
|
|
|
gint x_start;
|
|
|
|
gint y_start;
|
|
|
|
gint drag_in_progress : 1;
|
|
|
|
gint always_show_tabs : 1;
|
|
|
|
gint close_buttons_sensitive : 1;
|
|
|
|
gint tab_drag_and_drop_enabled : 1;
|
|
|
|
guint destroy_has_run : 1;
|
|
|
|
};
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
G_DEFINE_TYPE(PlumaNotebook, pluma_notebook, GTK_TYPE_NOTEBOOK)
|
2011-11-07 13:46:58 -06:00
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
static void pluma_notebook_finalize (GObject *object);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
static gboolean pluma_notebook_change_current_page (GtkNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint offset);
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
static void move_current_tab_to_another_notebook (PlumaNotebook *src,
|
|
|
|
PlumaNotebook *dest,
|
2011-11-07 13:46:58 -06:00
|
|
|
GdkEventMotion *event,
|
|
|
|
gint dest_position);
|
|
|
|
|
|
|
|
/* Local variables */
|
|
|
|
static GdkCursor *cursor = NULL;
|
|
|
|
|
|
|
|
/* Signals */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
TAB_ADDED,
|
|
|
|
TAB_REMOVED,
|
|
|
|
TABS_REORDERED,
|
|
|
|
TAB_DETACHED,
|
|
|
|
TAB_CLOSE_REQUEST,
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
|
|
static void
|
2013-10-29 18:56:56 -05:00
|
|
|
pluma_notebook_dispose (GObject *object)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaNotebook *notebook = PLUMA_NOTEBOOK (object);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
if (!notebook->priv->destroy_has_run)
|
|
|
|
{
|
|
|
|
GList *children, *l;
|
|
|
|
|
|
|
|
children = gtk_container_get_children (GTK_CONTAINER (notebook));
|
|
|
|
|
|
|
|
for (l = children; l != NULL; l = g_list_next (l))
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_remove_tab (notebook,
|
|
|
|
PLUMA_TAB (l->data));
|
2011-11-07 13:46:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (children);
|
|
|
|
notebook->priv->destroy_has_run = TRUE;
|
|
|
|
}
|
|
|
|
|
2013-10-29 18:56:56 -05:00
|
|
|
G_OBJECT_CLASS (pluma_notebook_parent_class)->dispose (object);
|
2011-11-07 13:46:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_class_init (PlumaNotebookClass *klass)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
object_class->finalize = pluma_notebook_finalize;
|
2013-10-29 18:56:56 -05:00
|
|
|
object_class->dispose = pluma_notebook_dispose;
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
notebook_class->change_current_page = pluma_notebook_change_current_page;
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
signals[TAB_ADDED] =
|
|
|
|
g_signal_new ("tab_added",
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2011-11-07 16:52:18 -06:00
|
|
|
G_STRUCT_OFFSET (PlumaNotebookClass, tab_added),
|
2011-11-07 13:46:58 -06:00
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
G_TYPE_NONE,
|
|
|
|
1,
|
2011-11-07 16:52:18 -06:00
|
|
|
PLUMA_TYPE_TAB);
|
2011-11-07 13:46:58 -06:00
|
|
|
signals[TAB_REMOVED] =
|
|
|
|
g_signal_new ("tab_removed",
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2011-11-07 16:52:18 -06:00
|
|
|
G_STRUCT_OFFSET (PlumaNotebookClass, tab_removed),
|
2011-11-07 13:46:58 -06:00
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
G_TYPE_NONE,
|
|
|
|
1,
|
2011-11-07 16:52:18 -06:00
|
|
|
PLUMA_TYPE_TAB);
|
2011-11-07 13:46:58 -06:00
|
|
|
signals[TAB_DETACHED] =
|
|
|
|
g_signal_new ("tab_detached",
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2011-11-07 16:52:18 -06:00
|
|
|
G_STRUCT_OFFSET (PlumaNotebookClass, tab_detached),
|
2011-11-07 13:46:58 -06:00
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
G_TYPE_NONE,
|
|
|
|
1,
|
2011-11-07 16:52:18 -06:00
|
|
|
PLUMA_TYPE_TAB);
|
2011-11-07 13:46:58 -06:00
|
|
|
signals[TABS_REORDERED] =
|
|
|
|
g_signal_new ("tabs_reordered",
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2011-11-07 16:52:18 -06:00
|
|
|
G_STRUCT_OFFSET (PlumaNotebookClass, tabs_reordered),
|
2011-11-07 13:46:58 -06:00
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE,
|
|
|
|
0);
|
|
|
|
signals[TAB_CLOSE_REQUEST] =
|
|
|
|
g_signal_new ("tab-close-request",
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
2011-11-07 16:52:18 -06:00
|
|
|
G_STRUCT_OFFSET (PlumaNotebookClass, tab_close_request),
|
2011-11-07 13:46:58 -06:00
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
G_TYPE_NONE,
|
|
|
|
1,
|
2011-11-07 16:52:18 -06:00
|
|
|
PLUMA_TYPE_TAB);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
g_type_class_add_private (object_class, sizeof(PlumaNotebookPrivate));
|
2011-11-07 13:46:58 -06:00
|
|
|
}
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
static PlumaNotebook *
|
2011-11-07 13:46:58 -06:00
|
|
|
find_notebook_at_pointer (gint abs_x, gint abs_y)
|
|
|
|
{
|
|
|
|
GdkWindow *win_at_pointer;
|
|
|
|
GdkWindow *toplevel_win;
|
|
|
|
gpointer toplevel = NULL;
|
|
|
|
gint x, y;
|
|
|
|
|
|
|
|
/* FIXME multi-head */
|
|
|
|
win_at_pointer = gdk_window_at_pointer (&x, &y);
|
|
|
|
if (win_at_pointer == NULL)
|
|
|
|
{
|
|
|
|
/* We are outside all windows of the same application */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
toplevel_win = gdk_window_get_toplevel (win_at_pointer);
|
|
|
|
|
|
|
|
/* get the GtkWidget which owns the toplevel GdkWindow */
|
|
|
|
gdk_window_get_user_data (toplevel_win, &toplevel);
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
/* toplevel should be an PlumaWindow */
|
2011-11-07 13:46:58 -06:00
|
|
|
if ((toplevel != NULL) &&
|
2011-11-07 16:52:18 -06:00
|
|
|
PLUMA_IS_WINDOW (toplevel))
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
return PLUMA_NOTEBOOK (_pluma_window_get_notebook
|
|
|
|
(PLUMA_WINDOW (toplevel)));
|
2011-11-07 13:46:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We are outside all windows containing a notebook */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2011-11-07 16:52:18 -06:00
|
|
|
is_in_notebook_window (PlumaNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint abs_x,
|
|
|
|
gint abs_y)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaNotebook *nb_at_pointer;
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
g_return_val_if_fail (notebook != NULL, FALSE);
|
|
|
|
|
|
|
|
nb_at_pointer = find_notebook_at_pointer (abs_x, abs_y);
|
|
|
|
|
|
|
|
return (nb_at_pointer == notebook);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
2011-11-07 16:52:18 -06:00
|
|
|
find_tab_num_at_pos (PlumaNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint abs_x,
|
|
|
|
gint abs_y)
|
|
|
|
{
|
|
|
|
GtkPositionType tab_pos;
|
|
|
|
int page_num = 0;
|
|
|
|
GtkNotebook *nb = GTK_NOTEBOOK (notebook);
|
|
|
|
GtkWidget *page;
|
|
|
|
|
|
|
|
tab_pos = gtk_notebook_get_tab_pos (GTK_NOTEBOOK (notebook));
|
|
|
|
|
|
|
|
/* For some reason unfullscreen + quick click can
|
|
|
|
cause a wrong click event to be reported to the tab */
|
|
|
|
if (!is_in_notebook_window (notebook, abs_x, abs_y))
|
|
|
|
{
|
|
|
|
return NOT_IN_APP_WINDOWS;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((page = gtk_notebook_get_nth_page (nb, page_num)) != NULL)
|
|
|
|
{
|
2013-10-29 18:56:56 -05:00
|
|
|
GtkAllocation allocation;
|
2011-11-07 13:46:58 -06:00
|
|
|
GtkWidget *tab;
|
|
|
|
gint max_x, max_y;
|
|
|
|
gint x_root, y_root;
|
|
|
|
|
|
|
|
tab = gtk_notebook_get_tab_label (nb, page);
|
|
|
|
g_return_val_if_fail (tab != NULL, AFTER_ALL_TABS);
|
|
|
|
|
2013-10-29 18:56:56 -05:00
|
|
|
if (!gtk_widget_get_mapped (tab))
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
++page_num;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-10-29 18:56:56 -05:00
|
|
|
gdk_window_get_origin (GDK_WINDOW (gtk_widget_get_window (tab)),
|
2011-11-07 13:46:58 -06:00
|
|
|
&x_root, &y_root);
|
|
|
|
|
2013-10-29 18:56:56 -05:00
|
|
|
gtk_widget_get_allocation(tab, &allocation);
|
|
|
|
|
|
|
|
max_x = x_root + allocation.x + allocation.width;
|
|
|
|
max_y = y_root + allocation.y + allocation.height;
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
if (((tab_pos == GTK_POS_TOP) ||
|
|
|
|
(tab_pos == GTK_POS_BOTTOM)) &&
|
|
|
|
(abs_x <= max_x))
|
|
|
|
{
|
|
|
|
return page_num;
|
|
|
|
}
|
|
|
|
else if (((tab_pos == GTK_POS_LEFT) ||
|
|
|
|
(tab_pos == GTK_POS_RIGHT)) &&
|
|
|
|
(abs_y <= max_y))
|
|
|
|
{
|
|
|
|
return page_num;
|
|
|
|
}
|
|
|
|
|
|
|
|
++page_num;
|
|
|
|
}
|
|
|
|
|
|
|
|
return AFTER_ALL_TABS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
find_notebook_and_tab_at_pos (gint abs_x,
|
|
|
|
gint abs_y,
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaNotebook **notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint *page_num)
|
|
|
|
{
|
|
|
|
*notebook = find_notebook_at_pointer (abs_x, abs_y);
|
|
|
|
if (*notebook == NULL)
|
|
|
|
{
|
|
|
|
return NOT_IN_APP_WINDOWS;
|
|
|
|
}
|
|
|
|
|
|
|
|
*page_num = find_tab_num_at_pos (*notebook, abs_x, abs_y);
|
|
|
|
|
|
|
|
if (*page_num < 0)
|
|
|
|
{
|
|
|
|
return *page_num;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_move_tab:
|
|
|
|
* @src: a #PlumaNotebook
|
|
|
|
* @dest: a #PlumaNotebook
|
|
|
|
* @tab: a #PlumaTab
|
2011-11-07 13:46:58 -06:00
|
|
|
* @dest_position: the position for @tab
|
|
|
|
*
|
|
|
|
* Moves @tab from @src to @dest.
|
|
|
|
* If dest_position is greater than or equal to the number of tabs
|
|
|
|
* of the destination nootebook or negative, tab will be moved to the
|
|
|
|
* end of the tabs.
|
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_move_tab (PlumaNotebook *src,
|
|
|
|
PlumaNotebook *dest,
|
|
|
|
PlumaTab *tab,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint dest_position)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (src));
|
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (dest));
|
2011-11-07 13:46:58 -06:00
|
|
|
g_return_if_fail (src != dest);
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_TAB (tab));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
/* make sure the tab isn't destroyed while we move it */
|
|
|
|
g_object_ref (tab);
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_remove_tab (src, tab);
|
|
|
|
pluma_notebook_add_tab (dest, tab, dest_position, TRUE);
|
2011-11-07 13:46:58 -06:00
|
|
|
g_object_unref (tab);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_reorder_tab:
|
|
|
|
* @src: a #PlumaNotebook
|
|
|
|
* @tab: a #PlumaTab
|
2011-11-07 13:46:58 -06:00
|
|
|
* @dest_position: the position for @tab
|
|
|
|
*
|
|
|
|
* Reorders the page containing @tab, so that it appears in @dest_position position.
|
|
|
|
* If dest_position is greater than or equal to the number of tabs
|
|
|
|
* of the destination notebook or negative, tab will be moved to the
|
|
|
|
* end of the tabs.
|
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_reorder_tab (PlumaNotebook *src,
|
|
|
|
PlumaTab *tab,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint dest_position)
|
|
|
|
{
|
|
|
|
gint old_position;
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (src));
|
|
|
|
g_return_if_fail (PLUMA_IS_TAB (tab));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
old_position = gtk_notebook_page_num (GTK_NOTEBOOK (src),
|
|
|
|
GTK_WIDGET (tab));
|
|
|
|
|
|
|
|
if (old_position == dest_position)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gtk_notebook_reorder_child (GTK_NOTEBOOK (src),
|
|
|
|
GTK_WIDGET (tab),
|
|
|
|
dest_position);
|
|
|
|
|
|
|
|
if (!src->priv->drag_in_progress)
|
|
|
|
{
|
|
|
|
g_signal_emit (G_OBJECT (src),
|
|
|
|
signals[TABS_REORDERED],
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
drag_start (PlumaNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
guint32 time)
|
|
|
|
{
|
|
|
|
notebook->priv->drag_in_progress = TRUE;
|
|
|
|
|
|
|
|
/* get a new cursor, if necessary */
|
|
|
|
/* FIXME multi-head */
|
|
|
|
if (cursor == NULL)
|
|
|
|
cursor = gdk_cursor_new (GDK_FLEUR);
|
|
|
|
|
|
|
|
/* grab the pointer */
|
|
|
|
gtk_grab_add (GTK_WIDGET (notebook));
|
|
|
|
|
|
|
|
/* FIXME multi-head */
|
|
|
|
if (!gdk_pointer_is_grabbed ())
|
|
|
|
{
|
|
|
|
gdk_pointer_grab (gtk_widget_get_window (GTK_WIDGET (notebook)),
|
|
|
|
FALSE,
|
|
|
|
GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
|
|
|
NULL,
|
|
|
|
cursor,
|
|
|
|
time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
drag_stop (PlumaNotebook *notebook)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
if (notebook->priv->drag_in_progress)
|
|
|
|
{
|
|
|
|
g_signal_emit (G_OBJECT (notebook),
|
|
|
|
signals[TABS_REORDERED],
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
notebook->priv->drag_in_progress = FALSE;
|
|
|
|
if (notebook->priv->motion_notify_handler_id != 0)
|
|
|
|
{
|
|
|
|
g_signal_handler_disconnect (G_OBJECT (notebook),
|
|
|
|
notebook->priv->motion_notify_handler_id);
|
|
|
|
notebook->priv->motion_notify_handler_id = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This function is only called during dnd, we don't need to emit TABS_REORDERED
|
|
|
|
* here, instead we do it on drag_stop
|
|
|
|
*/
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
move_current_tab (PlumaNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint dest_position)
|
|
|
|
{
|
|
|
|
gint cur_page_num;
|
|
|
|
|
|
|
|
cur_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
|
|
|
|
|
|
|
|
if (dest_position != cur_page_num)
|
|
|
|
{
|
|
|
|
GtkWidget *cur_tab;
|
|
|
|
|
|
|
|
cur_tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook),
|
|
|
|
cur_page_num);
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_reorder_tab (PLUMA_NOTEBOOK (notebook),
|
|
|
|
PLUMA_TAB (cur_tab),
|
2011-11-07 13:46:58 -06:00
|
|
|
dest_position);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2011-11-07 16:52:18 -06:00
|
|
|
motion_notify_cb (PlumaNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
GdkEventMotion *event,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaNotebook *dest;
|
2011-11-07 13:46:58 -06:00
|
|
|
gint page_num;
|
|
|
|
gint result;
|
|
|
|
|
|
|
|
if (notebook->priv->drag_in_progress == FALSE)
|
|
|
|
{
|
|
|
|
if (notebook->priv->tab_drag_and_drop_enabled == FALSE)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (gtk_drag_check_threshold (GTK_WIDGET (notebook),
|
|
|
|
notebook->priv->x_start,
|
|
|
|
notebook->priv->y_start,
|
|
|
|
event->x_root,
|
|
|
|
event->y_root))
|
|
|
|
{
|
|
|
|
drag_start (notebook, event->time);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = find_notebook_and_tab_at_pos ((gint)event->x_root,
|
|
|
|
(gint)event->y_root,
|
|
|
|
&dest,
|
|
|
|
&page_num);
|
|
|
|
|
|
|
|
if (result != NOT_IN_APP_WINDOWS)
|
|
|
|
{
|
|
|
|
if (dest != notebook)
|
|
|
|
{
|
|
|
|
move_current_tab_to_another_notebook (notebook,
|
|
|
|
dest,
|
|
|
|
event,
|
|
|
|
page_num);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (page_num >= -1, FALSE);
|
|
|
|
move_current_tab (notebook, page_num);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
move_current_tab_to_another_notebook (PlumaNotebook *src,
|
|
|
|
PlumaNotebook *dest,
|
2011-11-07 13:46:58 -06:00
|
|
|
GdkEventMotion *event,
|
|
|
|
gint dest_position)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaTab *tab;
|
2011-11-07 13:46:58 -06:00
|
|
|
gint cur_page;
|
|
|
|
|
|
|
|
/* This is getting tricky, the tab was dragged in a notebook
|
|
|
|
* in another window of the same app, we move the tab
|
|
|
|
* to that new notebook, and let this notebook handle the
|
|
|
|
* drag
|
|
|
|
*/
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (dest));
|
2011-11-07 13:46:58 -06:00
|
|
|
g_return_if_fail (dest != src);
|
|
|
|
|
|
|
|
cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (src));
|
2011-11-07 16:52:18 -06:00
|
|
|
tab = PLUMA_TAB (gtk_notebook_get_nth_page (GTK_NOTEBOOK (src),
|
2011-11-07 13:46:58 -06:00
|
|
|
cur_page));
|
|
|
|
|
|
|
|
/* stop drag in origin window */
|
|
|
|
/* ungrab the pointer if it's grabbed */
|
|
|
|
drag_stop (src);
|
|
|
|
if (gdk_pointer_is_grabbed ())
|
|
|
|
{
|
|
|
|
gdk_pointer_ungrab (event->time);
|
|
|
|
}
|
|
|
|
gtk_grab_remove (GTK_WIDGET (src));
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_move_tab (src, dest, tab, dest_position);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
/* start drag handling in dest notebook */
|
|
|
|
dest->priv->motion_notify_handler_id =
|
|
|
|
g_signal_connect (G_OBJECT (dest),
|
|
|
|
"motion-notify-event",
|
|
|
|
G_CALLBACK (motion_notify_cb),
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
drag_start (dest, event->time);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2011-11-07 16:52:18 -06:00
|
|
|
button_release_cb (PlumaNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
GdkEventButton *event,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
if (notebook->priv->drag_in_progress)
|
|
|
|
{
|
|
|
|
gint cur_page_num;
|
|
|
|
GtkWidget *cur_page;
|
|
|
|
|
|
|
|
cur_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
|
|
|
|
cur_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook),
|
|
|
|
cur_page_num);
|
|
|
|
|
|
|
|
/* CHECK: I don't follow the code here -- Paolo */
|
|
|
|
if (!is_in_notebook_window (notebook, event->x_root, event->y_root) &&
|
|
|
|
(gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) > 1))
|
|
|
|
{
|
|
|
|
/* Tab was detached */
|
|
|
|
g_signal_emit (G_OBJECT (notebook),
|
|
|
|
signals[TAB_DETACHED],
|
|
|
|
0,
|
|
|
|
cur_page);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ungrab the pointer if it's grabbed */
|
|
|
|
if (gdk_pointer_is_grabbed ())
|
|
|
|
{
|
|
|
|
gdk_pointer_ungrab (event->time);
|
|
|
|
}
|
|
|
|
gtk_grab_remove (GTK_WIDGET (notebook));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This must be called even if a drag isn't happening */
|
|
|
|
drag_stop (notebook);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2011-11-07 16:52:18 -06:00
|
|
|
button_press_cb (PlumaNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
GdkEventButton *event,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
gint tab_clicked;
|
|
|
|
|
|
|
|
if (notebook->priv->drag_in_progress)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
tab_clicked = find_tab_num_at_pos (notebook,
|
|
|
|
event->x_root,
|
|
|
|
event->y_root);
|
|
|
|
|
|
|
|
if ((event->button == 1) &&
|
|
|
|
(event->type == GDK_BUTTON_PRESS) &&
|
|
|
|
(tab_clicked >= 0))
|
|
|
|
{
|
|
|
|
notebook->priv->x_start = event->x_root;
|
|
|
|
notebook->priv->y_start = event->y_root;
|
|
|
|
|
|
|
|
notebook->priv->motion_notify_handler_id =
|
|
|
|
g_signal_connect (G_OBJECT (notebook),
|
|
|
|
"motion-notify-event",
|
|
|
|
G_CALLBACK (motion_notify_cb),
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
else if ((event->type == GDK_BUTTON_PRESS) &&
|
2016-01-22 16:05:28 -06:00
|
|
|
(event->button == 3 || event->button == 2))
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
if (tab_clicked == -1)
|
|
|
|
{
|
|
|
|
// CHECK: do we really need it?
|
|
|
|
|
|
|
|
/* consume event, so that we don't pop up the context menu when
|
|
|
|
* the mouse if not over a tab label
|
|
|
|
*/
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Switch to the page the mouse is over, but don't consume the event */
|
|
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook),
|
|
|
|
tab_clicked);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_new:
|
2011-11-07 13:46:58 -06:00
|
|
|
*
|
2011-11-07 16:52:18 -06:00
|
|
|
* Creates a new #PlumaNotebook object.
|
2011-11-07 13:46:58 -06:00
|
|
|
*
|
2011-11-07 16:52:18 -06:00
|
|
|
* Returns: a new #PlumaNotebook
|
2011-11-07 13:46:58 -06:00
|
|
|
*/
|
|
|
|
GtkWidget *
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_new (void)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
return GTK_WIDGET (g_object_new (PLUMA_TYPE_NOTEBOOK, NULL));
|
2011-11-07 13:46:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_switch_page_cb (GtkNotebook *notebook,
|
2013-10-29 18:56:56 -05:00
|
|
|
GtkWidget *page,
|
2011-11-07 13:46:58 -06:00
|
|
|
guint page_num,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaNotebook *nb = PLUMA_NOTEBOOK (notebook);
|
2011-11-07 13:46:58 -06:00
|
|
|
GtkWidget *child;
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaView *view;
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
child = gtk_notebook_get_nth_page (notebook, page_num);
|
|
|
|
|
|
|
|
/* Remove the old page, we dont want to grow unnecessarily
|
|
|
|
* the list */
|
|
|
|
if (nb->priv->focused_pages)
|
|
|
|
{
|
|
|
|
nb->priv->focused_pages =
|
|
|
|
g_list_remove (nb->priv->focused_pages, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
nb->priv->focused_pages = g_list_append (nb->priv->focused_pages,
|
|
|
|
child);
|
|
|
|
|
|
|
|
/* give focus to the view */
|
2011-11-07 16:52:18 -06:00
|
|
|
view = pluma_tab_get_view (PLUMA_TAB (child));
|
2011-11-07 13:46:58 -06:00
|
|
|
gtk_widget_grab_focus (GTK_WIDGET (view));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* update_tabs_visibility: Hide tabs if there is only one tab
|
|
|
|
* and the pref is not set.
|
|
|
|
*/
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
update_tabs_visibility (PlumaNotebook *nb,
|
2011-11-07 13:46:58 -06:00
|
|
|
gboolean before_inserting)
|
|
|
|
{
|
|
|
|
gboolean show_tabs;
|
|
|
|
guint num;
|
|
|
|
|
|
|
|
num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb));
|
|
|
|
|
|
|
|
if (before_inserting) num++;
|
|
|
|
|
|
|
|
show_tabs = (nb->priv->always_show_tabs || num > 1);
|
|
|
|
|
|
|
|
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), show_tabs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_init (PlumaNotebook *notebook)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
notebook->priv = PLUMA_NOTEBOOK_GET_PRIVATE (notebook);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
notebook->priv->close_buttons_sensitive = TRUE;
|
|
|
|
notebook->priv->tab_drag_and_drop_enabled = TRUE;
|
|
|
|
|
|
|
|
gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
|
|
|
|
gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
|
|
|
|
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
|
|
|
|
|
|
|
|
notebook->priv->always_show_tabs = TRUE;
|
|
|
|
|
|
|
|
g_signal_connect (notebook,
|
|
|
|
"button-press-event",
|
|
|
|
(GCallback)button_press_cb,
|
|
|
|
NULL);
|
|
|
|
g_signal_connect (notebook,
|
|
|
|
"button-release-event",
|
|
|
|
(GCallback)button_release_cb,
|
|
|
|
NULL);
|
|
|
|
gtk_widget_add_events (GTK_WIDGET (notebook),
|
|
|
|
GDK_BUTTON1_MOTION_MASK);
|
|
|
|
|
|
|
|
g_signal_connect_after (G_OBJECT (notebook),
|
|
|
|
"switch_page",
|
2011-11-07 16:52:18 -06:00
|
|
|
G_CALLBACK (pluma_notebook_switch_page_cb),
|
2011-11-07 13:46:58 -06:00
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_finalize (GObject *object)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaNotebook *notebook = PLUMA_NOTEBOOK (object);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
g_list_free (notebook->priv->focused_pages);
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
G_OBJECT_CLASS (pluma_notebook_parent_class)->finalize (object);
|
2011-11-07 13:46:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to override this because when we don't show the tabs, like in
|
|
|
|
* fullscreen we need to have wrap around too
|
|
|
|
*/
|
|
|
|
static gboolean
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_change_current_page (GtkNotebook *notebook,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint offset)
|
|
|
|
{
|
|
|
|
gboolean wrap_around;
|
|
|
|
gint current;
|
|
|
|
|
|
|
|
current = gtk_notebook_get_current_page (notebook);
|
|
|
|
|
|
|
|
if (current != -1)
|
|
|
|
{
|
|
|
|
current = current + offset;
|
|
|
|
|
|
|
|
g_object_get (gtk_widget_get_settings (GTK_WIDGET (notebook)),
|
|
|
|
"gtk-keynav-wrap-around", &wrap_around,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (wrap_around)
|
|
|
|
{
|
|
|
|
if (current < 0)
|
|
|
|
{
|
|
|
|
current = gtk_notebook_get_n_pages (notebook) - 1;
|
|
|
|
}
|
|
|
|
else if (current >= gtk_notebook_get_n_pages (notebook))
|
|
|
|
{
|
|
|
|
current = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_notebook_set_current_page (notebook, current);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (notebook));
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
close_button_clicked_cb (PlumaTabLabel *tab_label, PlumaNotebook *notebook)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaTab *tab;
|
2011-11-07 13:46:58 -06:00
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
tab = pluma_tab_label_get_tab (tab_label);
|
2011-11-07 13:46:58 -06:00
|
|
|
g_signal_emit (notebook, signals[TAB_CLOSE_REQUEST], 0, tab);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GtkWidget *
|
2011-11-07 16:52:18 -06:00
|
|
|
create_tab_label (PlumaNotebook *nb,
|
|
|
|
PlumaTab *tab)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
GtkWidget *tab_label;
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
tab_label = pluma_tab_label_new (tab);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
g_signal_connect (tab_label,
|
|
|
|
"close-clicked",
|
|
|
|
G_CALLBACK (close_button_clicked_cb),
|
|
|
|
nb);
|
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (tab), "tab-label", tab_label);
|
|
|
|
|
|
|
|
return tab_label;
|
|
|
|
}
|
|
|
|
|
2010-10-03 06:59:46 -05:00
|
|
|
static GtkWidget *
|
|
|
|
get_tab_label (PlumaTab *tab)
|
|
|
|
{
|
|
|
|
GtkWidget *tab_label;
|
|
|
|
|
|
|
|
tab_label = GTK_WIDGET (g_object_get_data (G_OBJECT (tab), "tab-label"));
|
|
|
|
g_return_val_if_fail (tab_label != NULL, NULL);
|
|
|
|
|
|
|
|
return tab_label;
|
|
|
|
}
|
|
|
|
|
2011-11-07 13:46:58 -06:00
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
remove_tab_label (PlumaNotebook *nb,
|
|
|
|
PlumaTab *tab)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
GtkWidget *tab_label;
|
|
|
|
|
2010-10-03 06:59:46 -05:00
|
|
|
tab_label = get_tab_label (tab);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (tab_label,
|
|
|
|
G_CALLBACK (close_button_clicked_cb),
|
|
|
|
nb);
|
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (tab), "tab-label", NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_set_always_show_tabs:
|
|
|
|
* @nb: a #PlumaNotebook
|
2011-11-07 13:46:58 -06:00
|
|
|
* @show_tabs: %TRUE to always show the tabs
|
|
|
|
*
|
|
|
|
* Sets the visibility of the tabs in the @nb.
|
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_set_always_show_tabs (PlumaNotebook *nb,
|
2011-11-07 13:46:58 -06:00
|
|
|
gboolean show_tabs)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (nb));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
nb->priv->always_show_tabs = (show_tabs != FALSE);
|
|
|
|
|
|
|
|
update_tabs_visibility (nb, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_add_tab:
|
|
|
|
* @nb: a #PlumaNotebook
|
|
|
|
* @tab: a #PlumaTab
|
2011-11-07 13:46:58 -06:00
|
|
|
* @position: the position where the @tab should be added
|
|
|
|
* @jump_to: %TRUE to set the @tab as active
|
|
|
|
*
|
|
|
|
* Adds the specified @tab to the @nb.
|
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_add_tab (PlumaNotebook *nb,
|
|
|
|
PlumaTab *tab,
|
2011-11-07 13:46:58 -06:00
|
|
|
gint position,
|
|
|
|
gboolean jump_to)
|
|
|
|
{
|
|
|
|
GtkWidget *tab_label;
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (nb));
|
|
|
|
g_return_if_fail (PLUMA_IS_TAB (tab));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
tab_label = create_tab_label (nb, tab);
|
|
|
|
gtk_notebook_insert_page (GTK_NOTEBOOK (nb),
|
|
|
|
GTK_WIDGET (tab),
|
|
|
|
tab_label,
|
|
|
|
position);
|
|
|
|
update_tabs_visibility (nb, TRUE);
|
|
|
|
|
|
|
|
g_signal_emit (G_OBJECT (nb), signals[TAB_ADDED], 0, tab);
|
|
|
|
|
|
|
|
/* The signal handler may have reordered the tabs */
|
|
|
|
position = gtk_notebook_page_num (GTK_NOTEBOOK (nb),
|
|
|
|
GTK_WIDGET (tab));
|
|
|
|
|
|
|
|
if (jump_to)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
PlumaView *view;
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), position);
|
|
|
|
g_object_set_data (G_OBJECT (tab),
|
|
|
|
"jump_to",
|
|
|
|
GINT_TO_POINTER (jump_to));
|
2011-11-07 16:52:18 -06:00
|
|
|
view = pluma_tab_get_view (tab);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
gtk_widget_grab_focus (GTK_WIDGET (view));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
smart_tab_switching_on_closure (PlumaNotebook *nb,
|
|
|
|
PlumaTab *tab)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
gboolean jump_to;
|
|
|
|
|
|
|
|
jump_to = GPOINTER_TO_INT (g_object_get_data
|
|
|
|
(G_OBJECT (tab), "jump_to"));
|
|
|
|
|
|
|
|
if (!jump_to || !nb->priv->focused_pages)
|
|
|
|
{
|
|
|
|
gtk_notebook_next_page (GTK_NOTEBOOK (nb));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
GtkWidget *child;
|
|
|
|
int page_num;
|
|
|
|
|
|
|
|
/* activate the last focused tab */
|
|
|
|
l = g_list_last (nb->priv->focused_pages);
|
|
|
|
child = GTK_WIDGET (l->data);
|
|
|
|
page_num = gtk_notebook_page_num (GTK_NOTEBOOK (nb),
|
|
|
|
child);
|
|
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (nb),
|
|
|
|
page_num);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
remove_tab (PlumaTab *tab,
|
|
|
|
PlumaNotebook *nb)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
gint position;
|
|
|
|
|
|
|
|
position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab));
|
|
|
|
|
|
|
|
/* we ref the tab so that it's still alive while the tabs_removed
|
|
|
|
* signal is processed.
|
|
|
|
*/
|
|
|
|
g_object_ref (tab);
|
|
|
|
|
|
|
|
remove_tab_label (nb, tab);
|
|
|
|
gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position);
|
|
|
|
update_tabs_visibility (nb, FALSE);
|
|
|
|
|
|
|
|
g_signal_emit (G_OBJECT (nb), signals[TAB_REMOVED], 0, tab);
|
|
|
|
|
|
|
|
g_object_unref (tab);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_remove_tab:
|
|
|
|
* @nb: a #PlumaNotebook
|
|
|
|
* @tab: a #PlumaTab
|
2011-11-07 13:46:58 -06:00
|
|
|
*
|
|
|
|
* Removes @tab from @nb.
|
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_remove_tab (PlumaNotebook *nb,
|
|
|
|
PlumaTab *tab)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
gint position, curr;
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (nb));
|
|
|
|
g_return_if_fail (PLUMA_IS_TAB (tab));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
/* Remove the page from the focused pages list */
|
|
|
|
nb->priv->focused_pages = g_list_remove (nb->priv->focused_pages,
|
|
|
|
tab);
|
|
|
|
|
|
|
|
position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab));
|
|
|
|
curr = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb));
|
|
|
|
|
|
|
|
if (position == curr)
|
|
|
|
{
|
|
|
|
smart_tab_switching_on_closure (nb, tab);
|
|
|
|
}
|
|
|
|
|
|
|
|
remove_tab (tab, nb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_remove_all_tabs:
|
|
|
|
* @nb: a #PlumaNotebook
|
2011-11-07 13:46:58 -06:00
|
|
|
*
|
2011-11-07 16:52:18 -06:00
|
|
|
* Removes all #PlumaTab from @nb.
|
2011-11-07 13:46:58 -06:00
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_remove_all_tabs (PlumaNotebook *nb)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (nb));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
g_list_free (nb->priv->focused_pages);
|
|
|
|
nb->priv->focused_pages = NULL;
|
|
|
|
|
|
|
|
gtk_container_foreach (GTK_CONTAINER (nb),
|
|
|
|
(GtkCallback)remove_tab,
|
|
|
|
nb);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-07 16:52:18 -06:00
|
|
|
set_close_buttons_sensitivity (PlumaTab *tab,
|
|
|
|
PlumaNotebook *nb)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
|
|
|
GtkWidget *tab_label;
|
|
|
|
|
|
|
|
tab_label = get_tab_label (tab);
|
|
|
|
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_tab_label_set_close_button_sensitive (PLUMA_TAB_LABEL (tab_label),
|
2011-11-07 13:46:58 -06:00
|
|
|
nb->priv->close_buttons_sensitive);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_set_close_buttons_sensitive:
|
|
|
|
* @nb: a #PlumaNotebook
|
2011-11-07 13:46:58 -06:00
|
|
|
* @sensitive: %TRUE to make the buttons sensitive
|
|
|
|
*
|
|
|
|
* Sets whether the close buttons in the tabs of @nb are sensitive.
|
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_set_close_buttons_sensitive (PlumaNotebook *nb,
|
2011-11-07 13:46:58 -06:00
|
|
|
gboolean sensitive)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (nb));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
sensitive = (sensitive != FALSE);
|
|
|
|
|
|
|
|
if (sensitive == nb->priv->close_buttons_sensitive)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nb->priv->close_buttons_sensitive = sensitive;
|
|
|
|
|
|
|
|
gtk_container_foreach (GTK_CONTAINER (nb),
|
|
|
|
(GtkCallback)set_close_buttons_sensitivity,
|
|
|
|
nb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_get_close_buttons_sensitive:
|
|
|
|
* @nb: a #PlumaNotebook
|
2011-11-07 13:46:58 -06:00
|
|
|
*
|
|
|
|
* Whether the close buttons are sensitive.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the close buttons are sensitive
|
|
|
|
*/
|
|
|
|
gboolean
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_get_close_buttons_sensitive (PlumaNotebook *nb)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_val_if_fail (PLUMA_IS_NOTEBOOK (nb), TRUE);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
return nb->priv->close_buttons_sensitive;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_set_tab_drag_and_drop_enabled:
|
|
|
|
* @nb: a #PlumaNotebook
|
2011-11-07 13:46:58 -06:00
|
|
|
* @enable: %TRUE to enable the drag and drop
|
|
|
|
*
|
|
|
|
* Sets whether drag and drop of tabs in the @nb is enabled.
|
|
|
|
*/
|
|
|
|
void
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_set_tab_drag_and_drop_enabled (PlumaNotebook *nb,
|
2011-11-07 13:46:58 -06:00
|
|
|
gboolean enable)
|
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_if_fail (PLUMA_IS_NOTEBOOK (nb));
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
enable = (enable != FALSE);
|
|
|
|
|
|
|
|
if (enable == nb->priv->tab_drag_and_drop_enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nb->priv->tab_drag_and_drop_enabled = enable;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-11-07 16:52:18 -06:00
|
|
|
* pluma_notebook_get_tab_drag_and_drop_enabled:
|
|
|
|
* @nb: a #PlumaNotebook
|
2011-11-07 13:46:58 -06:00
|
|
|
*
|
|
|
|
* Whether the drag and drop is enabled in the @nb.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the drag and drop is enabled.
|
|
|
|
*/
|
|
|
|
gboolean
|
2011-11-07 16:52:18 -06:00
|
|
|
pluma_notebook_get_tab_drag_and_drop_enabled (PlumaNotebook *nb)
|
2011-11-07 13:46:58 -06:00
|
|
|
{
|
2011-11-07 16:52:18 -06:00
|
|
|
g_return_val_if_fail (PLUMA_IS_NOTEBOOK (nb), TRUE);
|
2011-11-07 13:46:58 -06:00
|
|
|
|
|
|
|
return nb->priv->tab_drag_and_drop_enabled;
|
|
|
|
}
|
|
|
|
|