xed/xedit/xedit-tab.c

2784 lines
66 KiB
C
Raw Permalink Normal View History

2011-11-07 13:46:58 -06:00
/*
2016-01-25 08:13:49 -06:00
* xedit-tab.c
* This file is part of xedit
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
*/
/*
2016-01-25 08:13:49 -06:00
* Modified by the xedit Team, 2005. See the AUTHORS file for a
* list of people on the xedit Team.
2011-11-07 13:46:58 -06:00
* See the ChangeLog files for a list of changes.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib/gi18n.h>
#include <gio/gio.h>
2016-01-25 08:13:49 -06:00
#include "xedit-app.h"
#include "xedit-notebook.h"
#include "xedit-tab.h"
#include "xedit-utils.h"
#include "xedit-io-error-message-area.h"
#include "xedit-print-job.h"
#include "xedit-print-preview.h"
#include "xedit-progress-message-area.h"
#include "xedit-debug.h"
#include "xedit-prefs-manager-app.h"
#include "xedit-enum-types.h"
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
#define XEDIT_TAB_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XEDIT_TYPE_TAB, XeditTabPrivate))
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
#define XEDIT_TAB_KEY "XEDIT_TAB_KEY"
2011-11-07 13:46:58 -06:00
#if GTK_CHECK_VERSION (3, 0, 0)
#define gdk_cursor_unref(cursor) g_object_unref (cursor)
#endif
2016-01-25 08:13:49 -06:00
struct _XeditTabPrivate
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditTabState state;
2011-11-07 13:46:58 -06:00
GtkWidget *view;
GtkWidget *view_scrolled_window;
GtkWidget *message_area;
GtkWidget *print_preview;
2016-01-25 08:13:49 -06:00
XeditPrintJob *print_job;
2011-11-07 13:46:58 -06:00
/* tmp data for saving */
gchar *tmp_save_uri;
/* tmp data for loading */
gint tmp_line_pos;
2016-01-25 08:13:49 -06:00
const XeditEncoding *tmp_encoding;
2011-11-07 13:46:58 -06:00
GTimer *timer;
guint times_called;
2016-01-25 08:13:49 -06:00
XeditDocumentSaveFlags save_flags;
2011-11-07 13:46:58 -06:00
gint auto_save_interval;
guint auto_save_timeout;
gint not_editable : 1;
gint auto_save : 1;
gint ask_if_externally_modified : 1;
};
#if GTK_CHECK_VERSION (3, 0, 0)
2016-01-25 08:13:49 -06:00
G_DEFINE_TYPE(XeditTab, xedit_tab, GTK_TYPE_BOX)
#else
2016-01-25 08:13:49 -06:00
G_DEFINE_TYPE(XeditTab, xedit_tab, GTK_TYPE_VBOX)
#endif
2011-11-07 13:46:58 -06:00
enum
{
PROP_0,
PROP_NAME,
PROP_STATE,
PROP_AUTO_SAVE,
PROP_AUTO_SAVE_INTERVAL
};
2016-01-25 08:13:49 -06:00
static gboolean xedit_tab_auto_save (XeditTab *tab);
2011-11-07 13:46:58 -06:00
static void
2016-01-25 08:13:49 -06:00
install_auto_save_timeout (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
gint timeout;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->auto_save_timeout <= 0);
g_return_if_fail (tab->priv->auto_save);
g_return_if_fail (tab->priv->auto_save_interval > 0);
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state != XEDIT_TAB_STATE_LOADING);
g_return_if_fail (tab->priv->state != XEDIT_TAB_STATE_SAVING);
g_return_if_fail (tab->priv->state != XEDIT_TAB_STATE_REVERTING);
g_return_if_fail (tab->priv->state != XEDIT_TAB_STATE_LOADING_ERROR);
g_return_if_fail (tab->priv->state != XEDIT_TAB_STATE_SAVING_ERROR);
g_return_if_fail (tab->priv->state != XEDIT_TAB_STATE_SAVING_ERROR);
g_return_if_fail (tab->priv->state != XEDIT_TAB_STATE_REVERTING_ERROR);
2011-11-07 13:46:58 -06:00
/* Add a new timeout */
timeout = g_timeout_add_seconds (tab->priv->auto_save_interval * 60,
2016-01-25 08:13:49 -06:00
(GSourceFunc) xedit_tab_auto_save,
2011-11-07 13:46:58 -06:00
tab);
tab->priv->auto_save_timeout = timeout;
}
static gboolean
2016-01-25 08:13:49 -06:00
install_auto_save_timeout_if_needed (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
g_return_val_if_fail (tab->priv->auto_save_timeout <= 0, FALSE);
2016-01-25 08:13:49 -06:00
g_return_val_if_fail ((tab->priv->state == XEDIT_TAB_STATE_NORMAL) ||
(tab->priv->state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW) ||
(tab->priv->state == XEDIT_TAB_STATE_CLOSING), FALSE);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_CLOSING)
2011-11-07 13:46:58 -06:00
return FALSE;
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
if (tab->priv->auto_save &&
2016-01-25 08:13:49 -06:00
!xedit_document_is_untitled (doc) &&
!xedit_document_get_readonly (doc))
2011-11-07 13:46:58 -06:00
{
install_auto_save_timeout (tab);
return TRUE;
}
return FALSE;
}
static void
2016-01-25 08:13:49 -06:00
remove_auto_save_timeout (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
/* FIXME: check sugli stati */
g_return_if_fail (tab->priv->auto_save_timeout > 0);
g_source_remove (tab->priv->auto_save_timeout);
tab->priv->auto_save_timeout = 0;
}
static void
2016-01-25 08:13:49 -06:00
xedit_tab_get_property (GObject *object,
2011-11-07 13:46:58 -06:00
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
2016-01-25 08:13:49 -06:00
XeditTab *tab = XEDIT_TAB (object);
2011-11-07 13:46:58 -06:00
switch (prop_id)
{
case PROP_NAME:
g_value_take_string (value,
2016-01-25 08:13:49 -06:00
_xedit_tab_get_name (tab));
2011-11-07 13:46:58 -06:00
break;
case PROP_STATE:
g_value_set_enum (value,
2016-01-25 08:13:49 -06:00
xedit_tab_get_state (tab));
2011-11-07 13:46:58 -06:00
break;
case PROP_AUTO_SAVE:
g_value_set_boolean (value,
2016-01-25 08:13:49 -06:00
xedit_tab_get_auto_save_enabled (tab));
2011-11-07 13:46:58 -06:00
break;
case PROP_AUTO_SAVE_INTERVAL:
g_value_set_int (value,
2016-01-25 08:13:49 -06:00
xedit_tab_get_auto_save_interval (tab));
2011-11-07 13:46:58 -06:00
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
2016-01-25 08:13:49 -06:00
xedit_tab_set_property (GObject *object,
2011-11-07 13:46:58 -06:00
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
2016-01-25 08:13:49 -06:00
XeditTab *tab = XEDIT_TAB (object);
2011-11-07 13:46:58 -06:00
switch (prop_id)
{
case PROP_AUTO_SAVE:
2016-01-25 08:13:49 -06:00
xedit_tab_set_auto_save_enabled (tab,
2011-11-07 13:46:58 -06:00
g_value_get_boolean (value));
break;
case PROP_AUTO_SAVE_INTERVAL:
2016-01-25 08:13:49 -06:00
xedit_tab_set_auto_save_interval (tab,
2011-11-07 13:46:58 -06:00
g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
2016-01-25 08:13:49 -06:00
xedit_tab_finalize (GObject *object)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditTab *tab = XEDIT_TAB (object);
2011-11-07 13:46:58 -06:00
if (tab->priv->timer != NULL)
g_timer_destroy (tab->priv->timer);
g_free (tab->priv->tmp_save_uri);
if (tab->priv->auto_save_timeout > 0)
remove_auto_save_timeout (tab);
2016-01-25 08:13:49 -06:00
G_OBJECT_CLASS (xedit_tab_parent_class)->finalize (object);
2011-11-07 13:46:58 -06:00
}
static void
2016-01-25 08:13:49 -06:00
xedit_tab_class_init (XeditTabClass *klass)
2011-11-07 13:46:58 -06:00
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
2016-01-25 08:13:49 -06:00
object_class->finalize = xedit_tab_finalize;
object_class->get_property = xedit_tab_get_property;
object_class->set_property = xedit_tab_set_property;
2011-11-07 13:46:58 -06:00
g_object_class_install_property (object_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"The tab's name",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_STATE,
g_param_spec_enum ("state",
"State",
"The tab's state",
2016-01-25 08:13:49 -06:00
XEDIT_TYPE_TAB_STATE,
XEDIT_TAB_STATE_NORMAL,
2011-11-07 13:46:58 -06:00
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_AUTO_SAVE,
g_param_spec_boolean ("autosave",
"Autosave",
"Autosave feature",
TRUE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_AUTO_SAVE_INTERVAL,
g_param_spec_int ("autosave-interval",
"AutosaveInterval",
"Time between two autosaves",
0,
G_MAXINT,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
2016-01-25 08:13:49 -06:00
g_type_class_add_private (object_class, sizeof (XeditTabPrivate));
2011-11-07 13:46:58 -06:00
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_get_state:
* @tab: a #XeditTab
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Gets the #XeditTabState of @tab.
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Returns: the #XeditTabState of @tab
2011-11-07 13:46:58 -06:00
*/
2016-01-25 08:13:49 -06:00
XeditTabState
xedit_tab_get_state (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
return tab->priv->state;
}
static void
set_cursor_according_to_state (GtkTextView *view,
2016-01-25 08:13:49 -06:00
XeditTabState state)
2011-11-07 13:46:58 -06:00
{
GdkCursor *cursor;
GdkWindow *text_window;
GdkWindow *left_window;
text_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_TEXT);
left_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_LEFT);
2016-01-25 08:13:49 -06:00
if ((state == XEDIT_TAB_STATE_LOADING) ||
(state == XEDIT_TAB_STATE_REVERTING) ||
(state == XEDIT_TAB_STATE_SAVING) ||
(state == XEDIT_TAB_STATE_PRINTING) ||
(state == XEDIT_TAB_STATE_PRINT_PREVIEWING) ||
(state == XEDIT_TAB_STATE_CLOSING))
2011-11-07 13:46:58 -06:00
{
cursor = gdk_cursor_new_for_display (
gtk_widget_get_display (GTK_WIDGET (view)),
GDK_WATCH);
if (text_window != NULL)
gdk_window_set_cursor (text_window, cursor);
if (left_window != NULL)
gdk_window_set_cursor (left_window, cursor);
gdk_cursor_unref (cursor);
}
else
{
cursor = gdk_cursor_new_for_display (
gtk_widget_get_display (GTK_WIDGET (view)),
GDK_XTERM);
if (text_window != NULL)
gdk_window_set_cursor (text_window, cursor);
if (left_window != NULL)
gdk_window_set_cursor (left_window, NULL);
gdk_cursor_unref (cursor);
}
}
static void
view_realized (GtkTextView *view,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
set_cursor_according_to_state (view, tab->priv->state);
}
static void
2016-01-25 08:13:49 -06:00
set_view_properties_according_to_state (XeditTab *tab,
XeditTabState state)
2011-11-07 13:46:58 -06:00
{
gboolean val;
2016-01-25 08:13:49 -06:00
val = ((state == XEDIT_TAB_STATE_NORMAL) &&
2011-11-07 13:46:58 -06:00
(tab->priv->print_preview == NULL) &&
!tab->priv->not_editable);
gtk_text_view_set_editable (GTK_TEXT_VIEW (tab->priv->view), val);
2016-01-25 08:13:49 -06:00
val = ((state != XEDIT_TAB_STATE_LOADING) &&
(state != XEDIT_TAB_STATE_CLOSING));
2011-11-07 13:46:58 -06:00
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (tab->priv->view), val);
2016-01-25 08:13:49 -06:00
val = ((state != XEDIT_TAB_STATE_LOADING) &&
(state != XEDIT_TAB_STATE_CLOSING) &&
(xedit_prefs_manager_get_highlight_current_line ()));
2011-11-07 13:46:58 -06:00
gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (tab->priv->view), val);
}
static void
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (XeditTab *tab,
XeditTabState state)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
g_return_if_fail ((state >= 0) && (state < XEDIT_TAB_NUM_OF_STATES));
2011-11-07 13:46:58 -06:00
if (tab->priv->state == state)
return;
tab->priv->state = state;
set_view_properties_according_to_state (tab, state);
2016-01-25 08:13:49 -06:00
if ((state == XEDIT_TAB_STATE_LOADING_ERROR) || /* FIXME: add other states if needed */
(state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW))
2011-11-07 13:46:58 -06:00
{
gtk_widget_hide (tab->priv->view_scrolled_window);
}
else
{
if (tab->priv->print_preview == NULL)
gtk_widget_show (tab->priv->view_scrolled_window);
}
set_cursor_according_to_state (GTK_TEXT_VIEW (tab->priv->view),
state);
g_object_notify (G_OBJECT (tab), "state");
}
static void
2016-01-25 08:13:49 -06:00
document_uri_notify_handler (XeditDocument *document,
2011-11-07 13:46:58 -06:00
GParamSpec *pspec,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
/* Notify the change in the URI */
g_object_notify (G_OBJECT (tab), "name");
}
static void
2016-01-25 08:13:49 -06:00
document_shortname_notify_handler (XeditDocument *document,
2011-11-07 13:46:58 -06:00
GParamSpec *pspec,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
/* Notify the change in the shortname */
g_object_notify (G_OBJECT (tab), "name");
}
static void
document_modified_changed (GtkTextBuffer *document,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
g_object_notify (G_OBJECT (tab), "name");
}
static void
2016-01-25 08:13:49 -06:00
set_message_area (XeditTab *tab,
2011-11-07 13:46:58 -06:00
GtkWidget *message_area)
{
if (tab->priv->message_area == message_area)
return;
if (tab->priv->message_area != NULL)
gtk_widget_destroy (tab->priv->message_area);
tab->priv->message_area = message_area;
if (message_area == NULL)
return;
gtk_box_pack_start (GTK_BOX (tab),
tab->priv->message_area,
FALSE,
FALSE,
0);
g_object_add_weak_pointer (G_OBJECT (tab->priv->message_area),
(gpointer *)&tab->priv->message_area);
}
static void
2016-01-25 08:13:49 -06:00
remove_tab (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditNotebook *notebook;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
notebook = XEDIT_NOTEBOOK (gtk_widget_get_parent (GTK_WIDGET (tab)));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_notebook_remove_tab (notebook, tab);
2011-11-07 13:46:58 -06:00
}
static void
io_loading_error_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
XeditView *view;
2011-11-07 13:46:58 -06:00
gchar *uri;
2016-01-25 08:13:49 -06:00
const XeditEncoding *encoding;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
g_return_if_fail (XEDIT_IS_VIEW (view));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
uri = xedit_document_get_uri (doc);
2011-11-07 13:46:58 -06:00
g_return_if_fail (uri != NULL);
switch (response_id)
{
case GTK_RESPONSE_OK:
2016-01-25 08:13:49 -06:00
encoding = xedit_conversion_error_message_area_get_encoding (
2011-11-07 13:46:58 -06:00
GTK_WIDGET (message_area));
if (encoding != NULL)
{
tab->priv->tmp_encoding = encoding;
}
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_LOADING);
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->auto_save_timeout <= 0);
2016-01-25 08:13:49 -06:00
xedit_document_load (doc,
2011-11-07 13:46:58 -06:00
uri,
tab->priv->tmp_encoding,
tab->priv->tmp_line_pos,
FALSE);
break;
case GTK_RESPONSE_YES:
/* This means that we want to edit the document anyway */
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
_xedit_document_set_readonly (doc, FALSE);
2011-11-07 13:46:58 -06:00
break;
case GTK_RESPONSE_NO:
/* We don't want to edit the document just show it */
set_message_area (tab, NULL);
break;
default:
2016-01-25 08:13:49 -06:00
_xedit_recent_remove (XEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), uri);
2011-11-07 13:46:58 -06:00
remove_tab (tab);
break;
}
g_free (uri);
}
static void
file_already_open_warning_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
if (response_id == GTK_RESPONSE_YES)
{
tab->priv->not_editable = FALSE;
gtk_text_view_set_editable (GTK_TEXT_VIEW (view),
TRUE);
}
gtk_widget_destroy (message_area);
gtk_widget_grab_focus (GTK_WIDGET (view));
}
static void
load_cancelled (GtkWidget *area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area));
2011-11-07 13:46:58 -06:00
g_object_ref (tab);
2016-01-25 08:13:49 -06:00
xedit_document_load_cancel (xedit_tab_get_document (tab));
2011-11-07 13:46:58 -06:00
g_object_unref (tab);
}
static void
unrecoverable_reverting_error_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab,
XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
gtk_widget_grab_focus (GTK_WIDGET (view));
install_auto_save_timeout_if_needed (tab);
}
#define MAX_MSG_LENGTH 100
static void
2016-01-25 08:13:49 -06:00
show_loading_message_area (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
GtkWidget *area;
2016-01-25 08:13:49 -06:00
XeditDocument *doc = NULL;
2011-11-07 13:46:58 -06:00
gchar *name;
gchar *dirname = NULL;
gchar *msg = NULL;
gchar *name_markup;
gchar *dirname_markup;
gint len;
if (tab->priv->message_area != NULL)
return;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
g_return_if_fail (doc != NULL);
2016-01-25 08:13:49 -06:00
name = xedit_document_get_short_name_for_display (doc);
2011-11-07 13:46:58 -06:00
len = g_utf8_strlen (name, -1);
/* if the name is awfully long, truncate it and be done with it,
* otherwise also show the directory (ellipsized if needed)
*/
if (len > MAX_MSG_LENGTH)
{
gchar *str;
2016-01-25 08:13:49 -06:00
str = xedit_utils_str_middle_truncate (name, MAX_MSG_LENGTH);
2011-11-07 13:46:58 -06:00
g_free (name);
name = str;
}
else
{
GFile *file;
2016-01-25 08:13:49 -06:00
file = xedit_document_get_location (doc);
2011-11-07 13:46:58 -06:00
if (file != NULL)
{
gchar *str;
2016-01-25 08:13:49 -06:00
str = xedit_utils_location_get_dirname_for_display (file);
2011-11-07 13:46:58 -06:00
g_object_unref (file);
/* use the remaining space for the dir, but use a min of 20 chars
* so that we do not end up with a dirname like "(a...b)".
* This means that in the worst case when the filename is long 99
* we have a title long 99 + 20, but I think it's a rare enough
* case to be acceptable. It's justa darn title afterall :)
*/
2016-01-25 08:13:49 -06:00
dirname = xedit_utils_str_middle_truncate (str,
2011-11-07 13:46:58 -06:00
MAX (20, MAX_MSG_LENGTH - len));
g_free (str);
}
}
name_markup = g_markup_printf_escaped ("<b>%s</b>", name);
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_REVERTING)
2011-11-07 13:46:58 -06:00
{
if (dirname != NULL)
{
dirname_markup = g_markup_printf_escaped ("<b>%s</b>", dirname);
/* Translators: the first %s is a file name (e.g. test.txt) the second one
2011-11-07 16:52:18 -06:00
is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
2011-11-07 13:46:58 -06:00
msg = g_strdup_printf (_("Reverting %s from %s"),
name_markup,
dirname_markup);
g_free (dirname_markup);
}
else
{
msg = g_strdup_printf (_("Reverting %s"),
name_markup);
}
2016-01-25 08:13:49 -06:00
area = xedit_progress_message_area_new (GTK_STOCK_REVERT_TO_SAVED,
2011-11-07 13:46:58 -06:00
msg,
TRUE);
}
else
{
if (dirname != NULL)
{
dirname_markup = g_markup_printf_escaped ("<b>%s</b>", dirname);
/* Translators: the first %s is a file name (e.g. test.txt) the second one
2011-11-07 16:52:18 -06:00
is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
2011-11-07 13:46:58 -06:00
msg = g_strdup_printf (_("Loading %s from %s"),
name_markup,
dirname_markup);
g_free (dirname_markup);
}
else
{
msg = g_strdup_printf (_("Loading %s"),
name_markup);
}
2016-01-25 08:13:49 -06:00
area = xedit_progress_message_area_new (GTK_STOCK_OPEN,
2011-11-07 13:46:58 -06:00
msg,
TRUE);
}
g_signal_connect (area,
"response",
G_CALLBACK (load_cancelled),
tab);
gtk_widget_show (area);
set_message_area (tab, area);
g_free (msg);
g_free (name);
g_free (name_markup);
g_free (dirname);
}
static void
2016-01-25 08:13:49 -06:00
show_saving_message_area (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
GtkWidget *area;
2016-01-25 08:13:49 -06:00
XeditDocument *doc = NULL;
2011-11-07 13:46:58 -06:00
gchar *short_name;
gchar *from;
gchar *to = NULL;
gchar *from_markup;
gchar *to_markup;
gchar *msg = NULL;
gint len;
g_return_if_fail (tab->priv->tmp_save_uri != NULL);
if (tab->priv->message_area != NULL)
return;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
g_return_if_fail (doc != NULL);
2016-01-25 08:13:49 -06:00
short_name = xedit_document_get_short_name_for_display (doc);
2011-11-07 13:46:58 -06:00
len = g_utf8_strlen (short_name, -1);
/* if the name is awfully long, truncate it and be done with it,
* otherwise also show the directory (ellipsized if needed)
*/
if (len > MAX_MSG_LENGTH)
{
2016-01-25 08:13:49 -06:00
from = xedit_utils_str_middle_truncate (short_name,
2011-11-07 13:46:58 -06:00
MAX_MSG_LENGTH);
g_free (short_name);
}
else
{
gchar *str;
from = short_name;
2016-01-25 08:13:49 -06:00
to = xedit_utils_uri_for_display (tab->priv->tmp_save_uri);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
str = xedit_utils_str_middle_truncate (to,
2011-11-07 13:46:58 -06:00
MAX (20, MAX_MSG_LENGTH - len));
g_free (to);
to = str;
}
from_markup = g_markup_printf_escaped ("<b>%s</b>", from);
if (to != NULL)
{
to_markup = g_markup_printf_escaped ("<b>%s</b>", to);
/* Translators: the first %s is a file name (e.g. test.txt) the second one
2011-11-07 16:52:18 -06:00
is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
2011-11-07 13:46:58 -06:00
msg = g_strdup_printf (_("Saving %s to %s"),
from_markup,
to_markup);
g_free (to_markup);
}
else
{
msg = g_strdup_printf (_("Saving %s"), from_markup);
}
2016-01-25 08:13:49 -06:00
area = xedit_progress_message_area_new (GTK_STOCK_SAVE,
2011-11-07 13:46:58 -06:00
msg,
FALSE);
gtk_widget_show (area);
set_message_area (tab, area);
g_free (msg);
g_free (to);
g_free (from);
g_free (from_markup);
}
static void
2016-01-25 08:13:49 -06:00
message_area_set_progress (XeditTab *tab,
2011-11-07 13:46:58 -06:00
goffset size,
goffset total_size)
{
if (tab->priv->message_area == NULL)
return;
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_TAB, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area));
2011-11-07 13:46:58 -06:00
if (total_size == 0)
{
if (size != 0)
2016-01-25 08:13:49 -06:00
xedit_progress_message_area_pulse (
XEDIT_PROGRESS_MESSAGE_AREA (tab->priv->message_area));
2011-11-07 13:46:58 -06:00
else
2016-01-25 08:13:49 -06:00
xedit_progress_message_area_set_fraction (
XEDIT_PROGRESS_MESSAGE_AREA (tab->priv->message_area),
2011-11-07 13:46:58 -06:00
0);
}
else
{
gdouble frac;
frac = (gdouble)size / (gdouble)total_size;
2016-01-25 08:13:49 -06:00
xedit_progress_message_area_set_fraction (
XEDIT_PROGRESS_MESSAGE_AREA (tab->priv->message_area),
2011-11-07 13:46:58 -06:00
frac);
}
}
static void
2016-01-25 08:13:49 -06:00
document_loading (XeditDocument *document,
2011-11-07 13:46:58 -06:00
goffset size,
goffset total_size,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
gdouble et;
gdouble total_time;
2016-01-25 08:13:49 -06:00
g_return_if_fail ((tab->priv->state == XEDIT_TAB_STATE_LOADING) ||
(tab->priv->state == XEDIT_TAB_STATE_REVERTING));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_TAB, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size);
2011-11-07 13:46:58 -06:00
if (tab->priv->timer == NULL)
{
g_return_if_fail (tab->priv->times_called == 0);
tab->priv->timer = g_timer_new ();
}
et = g_timer_elapsed (tab->priv->timer, NULL);
/* et : total_time = size : total_size */
total_time = (et * total_size) / size;
if ((total_time - et) > 3.0)
{
show_loading_message_area (tab);
}
message_area_set_progress (tab, size, total_size);
}
static gboolean
2016-01-25 08:13:49 -06:00
remove_tab_idle (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
remove_tab (tab);
return FALSE;
}
static void
2016-01-25 08:13:49 -06:00
document_loaded (XeditDocument *document,
2011-11-07 13:46:58 -06:00
const GError *error,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
GtkWidget *emsg;
GFile *location;
gchar *uri;
2016-01-25 08:13:49 -06:00
const XeditEncoding *encoding;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail ((tab->priv->state == XEDIT_TAB_STATE_LOADING) ||
(tab->priv->state == XEDIT_TAB_STATE_REVERTING));
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->auto_save_timeout <= 0);
if (tab->priv->timer != NULL)
{
g_timer_destroy (tab->priv->timer);
tab->priv->timer = NULL;
}
tab->priv->times_called = 0;
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
location = xedit_document_get_location (document);
uri = xedit_document_get_uri (document);
2011-11-07 13:46:58 -06:00
/* if the error is CONVERSION FALLBACK don't treat it as a normal error */
if (error != NULL &&
2016-01-25 08:13:49 -06:00
(error->domain != XEDIT_DOCUMENT_ERROR || error->code != XEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK))
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_LOADING)
xedit_tab_set_state (tab, XEDIT_TAB_STATE_LOADING_ERROR);
2011-11-07 13:46:58 -06:00
else
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_REVERTING_ERROR);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
encoding = xedit_document_get_encoding (document);
2011-11-07 13:46:58 -06:00
if (error->domain == G_IO_ERROR &&
error->code == G_IO_ERROR_CANCELLED)
{
/* remove the tab, but in an idle handler, since
* we are in the handler of doc loaded and we
* don't want doc and tab to be finalized now.
*/
g_idle_add ((GSourceFunc) remove_tab_idle, tab);
goto end;
}
else
{
2016-01-25 08:13:49 -06:00
_xedit_recent_remove (XEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))), uri);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_LOADING_ERROR)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
emsg = xedit_io_loading_error_message_area_new (uri,
2011-11-07 13:46:58 -06:00
tab->priv->tmp_encoding,
error);
g_signal_connect (emsg,
"response",
G_CALLBACK (io_loading_error_message_area_response),
tab);
}
else
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_REVERTING_ERROR);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
emsg = xedit_unrecoverable_reverting_error_message_area_new (uri,
2011-11-07 13:46:58 -06:00
error);
g_signal_connect (emsg,
"response",
G_CALLBACK (unrecoverable_reverting_error_message_area_response),
tab);
}
set_message_area (tab, emsg);
}
gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg),
GTK_RESPONSE_CANCEL);
gtk_widget_show (emsg);
g_object_unref (location);
g_free (uri);
return;
}
else
{
gchar *mime;
GList *all_documents;
GList *l;
g_return_if_fail (uri != NULL);
2016-01-25 08:13:49 -06:00
mime = xedit_document_get_mime_type (document);
_xedit_recent_add (XEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))),
2011-11-07 13:46:58 -06:00
uri,
mime);
g_free (mime);
if (error &&
2016-01-25 08:13:49 -06:00
error->domain == XEDIT_DOCUMENT_ERROR &&
error->code == XEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK)
2011-11-07 13:46:58 -06:00
{
GtkWidget *emsg;
2016-01-25 08:13:49 -06:00
_xedit_document_set_readonly (document, TRUE);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
emsg = xedit_io_loading_error_message_area_new (uri,
2011-11-07 13:46:58 -06:00
tab->priv->tmp_encoding,
error);
set_message_area (tab, emsg);
g_signal_connect (emsg,
"response",
G_CALLBACK (io_loading_error_message_area_response),
tab);
gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg),
GTK_RESPONSE_CANCEL);
gtk_widget_show (emsg);
}
/* Scroll to the cursor when the document is loaded */
2016-01-25 08:13:49 -06:00
xedit_view_scroll_to_cursor (XEDIT_VIEW (tab->priv->view));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
all_documents = xedit_app_get_documents (xedit_app_get_default ());
2011-11-07 13:46:58 -06:00
for (l = all_documents; l != NULL; l = g_list_next (l))
{
2016-01-25 08:13:49 -06:00
XeditDocument *d = XEDIT_DOCUMENT (l->data);
2011-11-07 13:46:58 -06:00
if (d != document)
{
GFile *loc;
2016-01-25 08:13:49 -06:00
loc = xedit_document_get_location (d);
2011-11-07 13:46:58 -06:00
if ((loc != NULL) &&
g_file_equal (location, loc))
{
GtkWidget *w;
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
tab->priv->not_editable = TRUE;
2016-01-25 08:13:49 -06:00
w = xedit_file_already_open_warning_message_area_new (uri);
2011-11-07 13:46:58 -06:00
set_message_area (tab, w);
gtk_info_bar_set_default_response (GTK_INFO_BAR (w),
GTK_RESPONSE_CANCEL);
gtk_widget_show (w);
g_signal_connect (w,
"response",
G_CALLBACK (file_already_open_warning_message_area_response),
tab);
g_object_unref (loc);
break;
}
if (loc != NULL)
g_object_unref (loc);
}
}
g_list_free (all_documents);
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
install_auto_save_timeout_if_needed (tab);
tab->priv->ask_if_externally_modified = TRUE;
}
end:
g_object_unref (location);
g_free (uri);
tab->priv->tmp_line_pos = 0;
tab->priv->tmp_encoding = NULL;
}
static void
2016-01-25 08:13:49 -06:00
document_saving (XeditDocument *document,
2011-11-07 13:46:58 -06:00
goffset size,
goffset total_size,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
gdouble et;
gdouble total_time;
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_TAB, "%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, size, total_size);
2011-11-07 13:46:58 -06:00
if (tab->priv->timer == NULL)
{
g_return_if_fail (tab->priv->times_called == 0);
tab->priv->timer = g_timer_new ();
}
et = g_timer_elapsed (tab->priv->timer, NULL);
/* et : total_time = size : total_size */
total_time = (et * total_size)/size;
if ((total_time - et) > 3.0)
{
show_saving_message_area (tab);
}
message_area_set_progress (tab, size, total_size);
tab->priv->times_called++;
}
static void
2016-01-25 08:13:49 -06:00
end_saving (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
/* Reset tmp data for saving */
g_free (tab->priv->tmp_save_uri);
tab->priv->tmp_save_uri = NULL;
tab->priv->tmp_encoding = NULL;
install_auto_save_timeout_if_needed (tab);
}
static void
unrecoverable_saving_error_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
if (tab->priv->print_preview != NULL)
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
2011-11-07 13:46:58 -06:00
else
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
end_saving (tab);
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
gtk_widget_grab_focus (GTK_WIDGET (view));
}
static void
no_backup_error_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
if (response_id == GTK_RESPONSE_YES)
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
set_message_area (tab, NULL);
g_return_if_fail (tab->priv->tmp_save_uri != NULL);
g_return_if_fail (tab->priv->tmp_encoding != NULL);
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
/* don't bug the user again with this... */
2016-01-25 08:13:49 -06:00
tab->priv->save_flags |= XEDIT_DOCUMENT_SAVE_IGNORE_BACKUP;
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->auto_save_timeout <= 0);
/* Force saving */
2016-01-25 08:13:49 -06:00
xedit_document_save (doc, tab->priv->save_flags);
2011-11-07 13:46:58 -06:00
}
else
{
unrecoverable_saving_error_message_area_response (message_area,
response_id,
tab);
}
}
static void
externally_modified_error_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
if (response_id == GTK_RESPONSE_YES)
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
set_message_area (tab, NULL);
g_return_if_fail (tab->priv->tmp_save_uri != NULL);
g_return_if_fail (tab->priv->tmp_encoding != NULL);
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->auto_save_timeout <= 0);
/* ignore mtime should not be persisted in save flags across saves */
/* Force saving */
2016-01-25 08:13:49 -06:00
xedit_document_save (doc, tab->priv->save_flags | XEDIT_DOCUMENT_SAVE_IGNORE_MTIME);
2011-11-07 13:46:58 -06:00
}
else
{
unrecoverable_saving_error_message_area_response (message_area,
response_id,
tab);
}
}
static void
recoverable_saving_error_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
if (response_id == GTK_RESPONSE_OK)
{
2016-01-25 08:13:49 -06:00
const XeditEncoding *encoding;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
encoding = xedit_conversion_error_message_area_get_encoding (
2011-11-07 13:46:58 -06:00
GTK_WIDGET (message_area));
g_return_if_fail (encoding != NULL);
set_message_area (tab, NULL);
g_return_if_fail (tab->priv->tmp_save_uri != NULL);
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
tab->priv->tmp_encoding = encoding;
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_TAB, "Force saving with URI '%s'", tab->priv->tmp_save_uri);
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->auto_save_timeout <= 0);
2016-01-25 08:13:49 -06:00
xedit_document_save_as (doc,
2011-11-07 13:46:58 -06:00
tab->priv->tmp_save_uri,
tab->priv->tmp_encoding,
tab->priv->save_flags);
}
else
{
unrecoverable_saving_error_message_area_response (message_area,
response_id,
tab);
}
}
static void
2016-01-25 08:13:49 -06:00
document_saved (XeditDocument *document,
2011-11-07 13:46:58 -06:00
const GError *error,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
GtkWidget *emsg;
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->tmp_save_uri != NULL);
g_return_if_fail (tab->priv->tmp_encoding != NULL);
g_return_if_fail (tab->priv->auto_save_timeout <= 0);
g_timer_destroy (tab->priv->timer);
tab->priv->timer = NULL;
tab->priv->times_called = 0;
set_message_area (tab, NULL);
if (error != NULL)
{
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SAVING_ERROR);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (error->domain == XEDIT_DOCUMENT_ERROR &&
error->code == XEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED)
2011-11-07 13:46:58 -06:00
{
/* This error is recoverable */
2016-01-25 08:13:49 -06:00
emsg = xedit_externally_modified_saving_error_message_area_new (
2011-11-07 13:46:58 -06:00
tab->priv->tmp_save_uri,
error);
g_return_if_fail (emsg != NULL);
set_message_area (tab, emsg);
g_signal_connect (emsg,
"response",
G_CALLBACK (externally_modified_error_message_area_response),
tab);
}
2016-01-25 08:13:49 -06:00
else if ((error->domain == XEDIT_DOCUMENT_ERROR &&
error->code == XEDIT_DOCUMENT_ERROR_CANT_CREATE_BACKUP) ||
2011-11-07 13:46:58 -06:00
(error->domain == G_IO_ERROR &&
error->code == G_IO_ERROR_CANT_CREATE_BACKUP))
{
/* This error is recoverable */
2016-01-25 08:13:49 -06:00
emsg = xedit_no_backup_saving_error_message_area_new (
2011-11-07 13:46:58 -06:00
tab->priv->tmp_save_uri,
error);
g_return_if_fail (emsg != NULL);
set_message_area (tab, emsg);
g_signal_connect (emsg,
"response",
G_CALLBACK (no_backup_error_message_area_response),
tab);
}
2016-01-25 08:13:49 -06:00
else if (error->domain == XEDIT_DOCUMENT_ERROR ||
2011-11-07 13:46:58 -06:00
(error->domain == G_IO_ERROR &&
error->code != G_IO_ERROR_INVALID_DATA &&
error->code != G_IO_ERROR_PARTIAL_INPUT))
{
/* These errors are _NOT_ recoverable */
2016-01-25 08:13:49 -06:00
_xedit_recent_remove (XEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))),
2011-11-07 13:46:58 -06:00
tab->priv->tmp_save_uri);
2016-01-25 08:13:49 -06:00
emsg = xedit_unrecoverable_saving_error_message_area_new (tab->priv->tmp_save_uri,
2011-11-07 13:46:58 -06:00
error);
g_return_if_fail (emsg != NULL);
set_message_area (tab, emsg);
g_signal_connect (emsg,
"response",
G_CALLBACK (unrecoverable_saving_error_message_area_response),
tab);
}
else
{
/* This error is recoverable */
g_return_if_fail (error->domain == G_CONVERT_ERROR ||
error->domain == G_IO_ERROR);
2016-01-25 08:13:49 -06:00
emsg = xedit_conversion_error_while_saving_message_area_new (
2011-11-07 13:46:58 -06:00
tab->priv->tmp_save_uri,
tab->priv->tmp_encoding,
error);
set_message_area (tab, emsg);
g_signal_connect (emsg,
"response",
G_CALLBACK (recoverable_saving_error_message_area_response),
tab);
}
gtk_info_bar_set_default_response (GTK_INFO_BAR (emsg),
GTK_RESPONSE_CANCEL);
gtk_widget_show (emsg);
}
else
{
2016-01-25 08:13:49 -06:00
gchar *mime = xedit_document_get_mime_type (document);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
_xedit_recent_add (XEDIT_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))),
2011-11-07 13:46:58 -06:00
tab->priv->tmp_save_uri,
mime);
g_free (mime);
if (tab->priv->print_preview != NULL)
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
2011-11-07 13:46:58 -06:00
else
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
tab->priv->ask_if_externally_modified = TRUE;
end_saving (tab);
}
}
static void
externally_modified_notification_message_area_response (GtkWidget *message_area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
if (response_id == GTK_RESPONSE_OK)
{
2016-01-25 08:13:49 -06:00
_xedit_tab_revert (tab);
2011-11-07 13:46:58 -06:00
}
else
{
tab->priv->ask_if_externally_modified = FALSE;
/* go back to normal state */
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
}
gtk_widget_grab_focus (GTK_WIDGET (view));
}
static void
2016-01-25 08:13:49 -06:00
display_externally_modified_notification (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
GtkWidget *message_area;
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
gchar *uri;
gboolean document_modified;
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
/* uri cannot be NULL, we're here because
* the file we're editing changed on disk */
2016-01-25 08:13:49 -06:00
uri = xedit_document_get_uri (doc);
2011-11-07 13:46:58 -06:00
g_return_if_fail (uri != NULL);
document_modified = gtk_text_buffer_get_modified (GTK_TEXT_BUFFER(doc));
2016-01-25 08:13:49 -06:00
message_area = xedit_externally_modified_message_area_new (uri, document_modified);
2011-11-07 13:46:58 -06:00
g_free (uri);
tab->priv->message_area = NULL;
set_message_area (tab, message_area);
gtk_widget_show (message_area);
g_signal_connect (message_area,
"response",
G_CALLBACK (externally_modified_notification_message_area_response),
tab);
}
static gboolean
view_focused_in (GtkWidget *widget,
GdkEventFocus *event,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), FALSE);
2011-11-07 13:46:58 -06:00
/* we try to detect file changes only in the normal state */
2016-01-25 08:13:49 -06:00
if (tab->priv->state != XEDIT_TAB_STATE_NORMAL)
2011-11-07 13:46:58 -06:00
{
return FALSE;
}
/* we already asked, don't bug the user again */
if (!tab->priv->ask_if_externally_modified)
{
return FALSE;
}
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
/* If file was never saved or is remote we do not check */
2016-01-25 08:13:49 -06:00
if (!xedit_document_is_local (doc))
2011-11-07 13:46:58 -06:00
{
return FALSE;
}
2016-01-25 08:13:49 -06:00
if (_xedit_document_check_externally_modified (doc))
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
2011-11-07 13:46:58 -06:00
display_externally_modified_notification (tab);
return FALSE;
}
return FALSE;
}
static GMountOperation *
2016-01-25 08:13:49 -06:00
tab_mount_operation_factory (XeditDocument *doc,
2011-11-07 13:46:58 -06:00
gpointer userdata)
{
2016-01-25 08:13:49 -06:00
XeditTab *tab = XEDIT_TAB (userdata);
2011-11-07 13:46:58 -06:00
GtkWidget *window;
window = gtk_widget_get_toplevel (GTK_WIDGET (tab));
return gtk_mount_operation_new (GTK_WINDOW (window));
}
static void
2016-01-25 08:13:49 -06:00
xedit_tab_init (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
GtkWidget *sw;
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
tab->priv = XEDIT_TAB_GET_PRIVATE (tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
tab->priv->state = XEDIT_TAB_STATE_NORMAL;
2011-11-07 13:46:58 -06:00
tab->priv->not_editable = FALSE;
tab->priv->save_flags = 0;
tab->priv->ask_if_externally_modified = TRUE;
#if GTK_CHECK_VERSION (3, 0, 0)
gtk_orientable_set_orientation (GTK_ORIENTABLE (tab),
GTK_ORIENTATION_VERTICAL);
#endif
2011-11-07 13:46:58 -06:00
/* Create the scrolled window */
sw = gtk_scrolled_window_new (NULL, NULL);
tab->priv->view_scrolled_window = sw;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
/* Manage auto save data */
tab->priv->auto_save = xedit_prefs_manager_get_auto_save ();
2011-11-07 13:46:58 -06:00
tab->priv->auto_save = (tab->priv->auto_save != FALSE);
2016-01-25 08:13:49 -06:00
tab->priv->auto_save_interval = xedit_prefs_manager_get_auto_save_interval ();
2011-11-07 13:46:58 -06:00
if (tab->priv->auto_save_interval <= 0)
tab->priv->auto_save_interval = GPM_DEFAULT_AUTO_SAVE_INTERVAL;
/* Create the view */
2016-01-25 08:13:49 -06:00
doc = xedit_document_new ();
g_object_set_data (G_OBJECT (doc), XEDIT_TAB_KEY, tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
_xedit_document_set_mount_operation_factory (doc,
2011-11-07 13:46:58 -06:00
tab_mount_operation_factory,
tab);
2016-01-25 08:13:49 -06:00
tab->priv->view = xedit_view_new (doc);
2011-11-07 13:46:58 -06:00
g_object_unref (doc);
gtk_widget_show (tab->priv->view);
2016-01-25 08:13:49 -06:00
g_object_set_data (G_OBJECT (tab->priv->view), XEDIT_TAB_KEY, tab);
2011-11-07 13:46:58 -06:00
gtk_box_pack_end (GTK_BOX (tab), sw, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (sw), tab->priv->view);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
GTK_SHADOW_IN);
gtk_widget_show (sw);
g_signal_connect (doc,
"notify::uri",
G_CALLBACK (document_uri_notify_handler),
tab);
g_signal_connect (doc,
"notify::shortname",
G_CALLBACK (document_shortname_notify_handler),
tab);
g_signal_connect (doc,
"modified_changed",
G_CALLBACK (document_modified_changed),
tab);
g_signal_connect (doc,
"loading",
G_CALLBACK (document_loading),
tab);
g_signal_connect (doc,
"loaded",
G_CALLBACK (document_loaded),
tab);
g_signal_connect (doc,
"saving",
G_CALLBACK (document_saving),
tab);
g_signal_connect (doc,
"saved",
G_CALLBACK (document_saved),
tab);
g_signal_connect_after (tab->priv->view,
"focus-in-event",
G_CALLBACK (view_focused_in),
tab);
g_signal_connect_after (tab->priv->view,
"realize",
G_CALLBACK (view_realized),
tab);
}
GtkWidget *
2016-01-25 08:13:49 -06:00
_xedit_tab_new (void)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
return GTK_WIDGET (g_object_new (XEDIT_TYPE_TAB, NULL));
2011-11-07 13:46:58 -06:00
}
/* Whether create is TRUE, creates a new empty document if location does
not refer to an existing file */
GtkWidget *
2016-01-25 08:13:49 -06:00
_xedit_tab_new_from_uri (const gchar *uri,
const XeditEncoding *encoding,
2011-11-07 13:46:58 -06:00
gint line_pos,
gboolean create)
{
2016-01-25 08:13:49 -06:00
XeditTab *tab;
2011-11-07 13:46:58 -06:00
g_return_val_if_fail (uri != NULL, NULL);
2016-01-25 08:13:49 -06:00
tab = XEDIT_TAB (_xedit_tab_new ());
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
_xedit_tab_load (tab,
2011-11-07 13:46:58 -06:00
uri,
encoding,
line_pos,
create);
return GTK_WIDGET (tab);
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_get_view:
* @tab: a #XeditTab
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Gets the #XeditView inside @tab.
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Returns: the #XeditView inside @tab
2011-11-07 13:46:58 -06:00
*/
2016-01-25 08:13:49 -06:00
XeditView *
xedit_tab_get_view (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
return XEDIT_VIEW (tab->priv->view);
2011-11-07 13:46:58 -06:00
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_get_document:
* @tab: a #XeditTab
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Gets the #XeditDocument associated to @tab.
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Returns: the #XeditDocument associated to @tab
2011-11-07 13:46:58 -06:00
*/
2016-01-25 08:13:49 -06:00
XeditDocument *
xedit_tab_get_document (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
return XEDIT_DOCUMENT (gtk_text_view_get_buffer (
2011-11-07 13:46:58 -06:00
GTK_TEXT_VIEW (tab->priv->view)));
}
#define MAX_DOC_NAME_LENGTH 40
gchar *
2016-01-25 08:13:49 -06:00
_xedit_tab_get_name (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
gchar *name;
gchar *docname;
gchar *tab_name;
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), NULL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
name = xedit_document_get_short_name_for_display (doc);
2011-11-07 13:46:58 -06:00
/* Truncate the name so it doesn't get insanely wide. */
2016-01-25 08:13:49 -06:00
docname = xedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
2011-11-07 13:46:58 -06:00
if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
{
tab_name = g_strdup_printf ("*%s", docname);
}
else
{
#if 0
2016-01-25 08:13:49 -06:00
if (xedit_document_get_readonly (doc))
2011-11-07 13:46:58 -06:00
{
tab_name = g_strdup_printf ("%s [%s]", docname,
/*Read only*/ _("RO"));
}
else
{
tab_name = g_strdup_printf ("%s", docname);
}
#endif
tab_name = g_strdup (docname);
}
g_free (docname);
g_free (name);
return tab_name;
}
gchar *
2016-01-25 08:13:49 -06:00
_xedit_tab_get_tooltips (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
gchar *tip;
gchar *uri;
gchar *ruri;
gchar *ruri_markup;
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), NULL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
uri = xedit_document_get_uri_for_display (doc);
2011-11-07 13:46:58 -06:00
g_return_val_if_fail (uri != NULL, NULL);
2016-01-25 08:13:49 -06:00
ruri = xedit_utils_replace_home_dir_with_tilde (uri);
2011-11-07 13:46:58 -06:00
g_free (uri);
ruri_markup = g_markup_printf_escaped ("<i>%s</i>", ruri);
switch (tab->priv->state)
{
gchar *content_type;
gchar *mime_type;
gchar *content_description;
gchar *content_full_description;
gchar *encoding;
2016-01-25 08:13:49 -06:00
const XeditEncoding *enc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_LOADING_ERROR:
2011-11-07 13:46:58 -06:00
tip = g_strdup_printf (_("Error opening file %s"),
ruri_markup);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_REVERTING_ERROR:
2011-11-07 13:46:58 -06:00
tip = g_strdup_printf (_("Error reverting file %s"),
ruri_markup);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_SAVING_ERROR:
2011-11-07 13:46:58 -06:00
tip = g_strdup_printf (_("Error saving file %s"),
ruri_markup);
break;
default:
2016-01-25 08:13:49 -06:00
content_type = xedit_document_get_content_type (doc);
mime_type = xedit_document_get_mime_type (doc);
2011-11-07 13:46:58 -06:00
content_description = g_content_type_get_description (content_type);
if (content_description == NULL)
content_full_description = g_strdup (mime_type);
else
content_full_description = g_strdup_printf ("%s (%s)",
content_description, mime_type);
g_free (content_type);
g_free (mime_type);
g_free (content_description);
2016-01-25 08:13:49 -06:00
enc = xedit_document_get_encoding (doc);
2011-11-07 13:46:58 -06:00
if (enc == NULL)
encoding = g_strdup (_("Unicode (UTF-8)"));
else
2016-01-25 08:13:49 -06:00
encoding = xedit_encoding_to_string (enc);
2011-11-07 13:46:58 -06:00
tip = g_markup_printf_escaped ("<b>%s</b> %s\n\n"
"<b>%s</b> %s\n"
"<b>%s</b> %s",
_("Name:"), ruri,
_("MIME Type:"), content_full_description,
_("Encoding:"), encoding);
g_free (encoding);
g_free (content_full_description);
break;
}
g_free (ruri);
g_free (ruri_markup);
return tip;
}
static GdkPixbuf *
resize_icon (GdkPixbuf *pixbuf,
gint size)
{
gint width, height;
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
/* if the icon is larger than the nominal size, scale down */
if (MAX (width, height) > size)
{
GdkPixbuf *scaled_pixbuf;
if (width > height)
{
height = height * size / width;
width = size;
}
else
{
width = width * size / height;
height = size;
}
scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
width,
height,
GDK_INTERP_BILINEAR);
g_object_unref (pixbuf);
pixbuf = scaled_pixbuf;
}
return pixbuf;
}
static GdkPixbuf *
get_stock_icon (GtkIconTheme *theme,
const gchar *stock,
gint size)
{
GdkPixbuf *pixbuf;
pixbuf = gtk_icon_theme_load_icon (theme, stock, size, 0, NULL);
if (pixbuf == NULL)
return NULL;
return resize_icon (pixbuf, size);
}
static GdkPixbuf *
get_icon (GtkIconTheme *theme,
GFile *location,
gint size)
{
GdkPixbuf *pixbuf;
GtkIconInfo *icon_info;
GFileInfo *info;
GIcon *gicon;
if (location == NULL)
return get_stock_icon (theme, GTK_STOCK_FILE, size);
/* FIXME: Doing a sync stat is bad, this should be fixed */
info = g_file_query_info (location,
G_FILE_ATTRIBUTE_STANDARD_ICON,
G_FILE_QUERY_INFO_NONE,
NULL,
NULL);
if (info == NULL)
return get_stock_icon (theme, GTK_STOCK_FILE, size);
gicon = g_file_info_get_icon (info);
if (gicon == NULL)
{
g_object_unref (info);
return get_stock_icon (theme, GTK_STOCK_FILE, size);
}
icon_info = gtk_icon_theme_lookup_by_gicon (theme, gicon, size, 0);
g_object_unref (info);
if (icon_info == NULL)
return get_stock_icon (theme, GTK_STOCK_FILE, size);
pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
gtk_icon_info_free (icon_info);
if (pixbuf == NULL)
return get_stock_icon (theme, GTK_STOCK_FILE, size);
return resize_icon (pixbuf, size);
}
/* FIXME: add support for theme changed. I think it should be as easy as
call g_object_notify (tab, "name") when the icon theme changes */
GdkPixbuf *
2016-01-25 08:13:49 -06:00
_xedit_tab_get_icon (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
GdkPixbuf *pixbuf;
GtkIconTheme *theme;
GdkScreen *screen;
gint icon_size;
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), NULL);
2011-11-07 13:46:58 -06:00
screen = gtk_widget_get_screen (GTK_WIDGET (tab));
theme = gtk_icon_theme_get_for_screen (screen);
g_return_val_if_fail (theme != NULL, NULL);
#if GTK_CHECK_VERSION (3, 10, 0)
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size);
#else
2011-11-07 13:46:58 -06:00
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (tab)),
GTK_ICON_SIZE_MENU,
NULL,
&icon_size);
#endif
2011-11-07 13:46:58 -06:00
switch (tab->priv->state)
{
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_LOADING:
2011-11-07 13:46:58 -06:00
pixbuf = get_stock_icon (theme,
GTK_STOCK_OPEN,
icon_size);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_REVERTING:
2011-11-07 13:46:58 -06:00
pixbuf = get_stock_icon (theme,
GTK_STOCK_REVERT_TO_SAVED,
icon_size);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_SAVING:
2011-11-07 13:46:58 -06:00
pixbuf = get_stock_icon (theme,
GTK_STOCK_SAVE,
icon_size);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_PRINTING:
2011-11-07 13:46:58 -06:00
pixbuf = get_stock_icon (theme,
GTK_STOCK_PRINT,
icon_size);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_PRINT_PREVIEWING:
case XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW:
2011-11-07 13:46:58 -06:00
pixbuf = get_stock_icon (theme,
GTK_STOCK_PRINT_PREVIEW,
icon_size);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_LOADING_ERROR:
case XEDIT_TAB_STATE_REVERTING_ERROR:
case XEDIT_TAB_STATE_SAVING_ERROR:
case XEDIT_TAB_STATE_GENERIC_ERROR:
2011-11-07 13:46:58 -06:00
pixbuf = get_stock_icon (theme,
GTK_STOCK_DIALOG_ERROR,
icon_size);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION:
2011-11-07 13:46:58 -06:00
pixbuf = get_stock_icon (theme,
GTK_STOCK_DIALOG_WARNING,
icon_size);
break;
default:
{
GFile *location;
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
location = xedit_document_get_location (doc);
2011-11-07 13:46:58 -06:00
pixbuf = get_icon (theme, location, icon_size);
if (location)
g_object_unref (location);
}
}
return pixbuf;
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_get_from_document:
* @doc: a #XeditDocument
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Gets the #XeditTab associated with @doc.
2011-11-07 13:46:58 -06:00
*
2016-01-25 08:13:49 -06:00
* Returns: the #XeditTab associated with @doc
2011-11-07 13:46:58 -06:00
*/
2016-01-25 08:13:49 -06:00
XeditTab *
xedit_tab_get_from_document (XeditDocument *doc)
2011-11-07 13:46:58 -06:00
{
gpointer res;
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_DOCUMENT (doc), NULL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
res = g_object_get_data (G_OBJECT (doc), XEDIT_TAB_KEY);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
return (res != NULL) ? XEDIT_TAB (res) : NULL;
2011-11-07 13:46:58 -06:00
}
void
2016-01-25 08:13:49 -06:00
_xedit_tab_load (XeditTab *tab,
2011-11-07 13:46:58 -06:00
const gchar *uri,
2016-01-25 08:13:49 -06:00
const XeditEncoding *encoding,
2011-11-07 13:46:58 -06:00
gint line_pos,
gboolean create)
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_LOADING);
2011-11-07 13:46:58 -06:00
tab->priv->tmp_line_pos = line_pos;
tab->priv->tmp_encoding = encoding;
if (tab->priv->auto_save_timeout > 0)
remove_auto_save_timeout (tab);
2016-01-25 08:13:49 -06:00
xedit_document_load (doc,
2011-11-07 13:46:58 -06:00
uri,
encoding,
line_pos,
create);
}
void
2016-01-25 08:13:49 -06:00
_xedit_tab_revert (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
gchar *uri;
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
g_return_if_fail ((tab->priv->state == XEDIT_TAB_STATE_NORMAL) ||
(tab->priv->state == XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
2011-11-07 13:46:58 -06:00
{
set_message_area (tab, NULL);
}
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_REVERTING);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
uri = xedit_document_get_uri (doc);
2011-11-07 13:46:58 -06:00
g_return_if_fail (uri != NULL);
tab->priv->tmp_line_pos = 0;
2016-01-25 08:13:49 -06:00
tab->priv->tmp_encoding = xedit_document_get_encoding (doc);
2011-11-07 13:46:58 -06:00
if (tab->priv->auto_save_timeout > 0)
remove_auto_save_timeout (tab);
2016-01-25 08:13:49 -06:00
xedit_document_load (doc,
2011-11-07 13:46:58 -06:00
uri,
tab->priv->tmp_encoding,
0,
FALSE);
g_free (uri);
}
void
2016-01-25 08:13:49 -06:00
_xedit_tab_save (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
XeditDocumentSaveFlags save_flags;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
g_return_if_fail ((tab->priv->state == XEDIT_TAB_STATE_NORMAL) ||
(tab->priv->state == XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) ||
(tab->priv->state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW));
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->tmp_save_uri == NULL);
g_return_if_fail (tab->priv->tmp_encoding == NULL);
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
g_return_if_fail (!xedit_document_is_untitled (doc));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
2011-11-07 13:46:58 -06:00
{
/* We already told the user about the external
* modification: hide the message area and set
* the save flag.
*/
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
save_flags = tab->priv->save_flags | XEDIT_DOCUMENT_SAVE_IGNORE_MTIME;
2011-11-07 13:46:58 -06:00
}
else
{
save_flags = tab->priv->save_flags;
}
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
/* uri used in error messages, will be freed in document_saved */
2016-01-25 08:13:49 -06:00
tab->priv->tmp_save_uri = xedit_document_get_uri (doc);
tab->priv->tmp_encoding = xedit_document_get_encoding (doc);
2011-11-07 13:46:58 -06:00
if (tab->priv->auto_save_timeout > 0)
remove_auto_save_timeout (tab);
2016-01-25 08:13:49 -06:00
xedit_document_save (doc, save_flags);
2011-11-07 13:46:58 -06:00
}
static gboolean
2016-01-25 08:13:49 -06:00
xedit_tab_auto_save (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
g_return_val_if_fail (tab->priv->tmp_save_uri == NULL, FALSE);
g_return_val_if_fail (tab->priv->tmp_encoding == NULL, FALSE);
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (!xedit_document_is_untitled (doc), FALSE);
g_return_val_if_fail (!xedit_document_get_readonly (doc), FALSE);
2011-11-07 13:46:58 -06:00
g_return_val_if_fail (tab->priv->auto_save_timeout > 0, FALSE);
g_return_val_if_fail (tab->priv->auto_save, FALSE);
g_return_val_if_fail (tab->priv->auto_save_interval > 0, FALSE);
if (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER(doc)))
{
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_TAB, "Document not modified");
2011-11-07 13:46:58 -06:00
return TRUE;
}
2016-01-25 08:13:49 -06:00
if ((tab->priv->state != XEDIT_TAB_STATE_NORMAL) &&
(tab->priv->state != XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW))
2011-11-07 13:46:58 -06:00
{
/* Retry after 30 seconds */
guint timeout;
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_TAB, "Retry after 30 seconds");
2011-11-07 13:46:58 -06:00
/* Add a new timeout */
timeout = g_timeout_add_seconds (30,
2016-01-25 08:13:49 -06:00
(GSourceFunc) xedit_tab_auto_save,
2011-11-07 13:46:58 -06:00
tab);
tab->priv->auto_save_timeout = timeout;
/* Returns FALSE so the old timeout is "destroyed" */
return FALSE;
}
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
/* uri used in error messages, will be freed in document_saved */
2016-01-25 08:13:49 -06:00
tab->priv->tmp_save_uri = xedit_document_get_uri (doc);
tab->priv->tmp_encoding = xedit_document_get_encoding (doc);
2011-11-07 13:46:58 -06:00
/* Set auto_save_timeout to 0 since the timeout is going to be destroyed */
tab->priv->auto_save_timeout = 0;
/* Since we are autosaving, we need to preserve the backup that was produced
the last time the user "manually" saved the file. In the case a recoverable
error happens while saving, the last backup is not preserved since the user
expressed his willing of saving the file */
2016-01-25 08:13:49 -06:00
xedit_document_save (doc, tab->priv->save_flags | XEDIT_DOCUMENT_SAVE_PRESERVE_BACKUP);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug_message (DEBUG_TAB, "Done");
2011-11-07 13:46:58 -06:00
/* Returns FALSE so the old timeout is "destroyed" */
return FALSE;
}
void
2016-01-25 08:13:49 -06:00
_xedit_tab_save_as (XeditTab *tab,
2011-11-07 13:46:58 -06:00
const gchar *uri,
2016-01-25 08:13:49 -06:00
const XeditEncoding *encoding,
XeditDocumentNewlineType newline_type)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
XeditDocumentSaveFlags save_flags;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
g_return_if_fail ((tab->priv->state == XEDIT_TAB_STATE_NORMAL) ||
(tab->priv->state == XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) ||
(tab->priv->state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW));
2011-11-07 13:46:58 -06:00
g_return_if_fail (encoding != NULL);
g_return_if_fail (tab->priv->tmp_save_uri == NULL);
g_return_if_fail (tab->priv->tmp_encoding == NULL);
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
/* reset the save flags, when saving as */
tab->priv->save_flags = 0;
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
2011-11-07 13:46:58 -06:00
{
/* We already told the user about the external
* modification: hide the message area and set
* the save flag.
*/
set_message_area (tab, NULL);
2016-01-25 08:13:49 -06:00
save_flags = tab->priv->save_flags | XEDIT_DOCUMENT_SAVE_IGNORE_MTIME;
2011-11-07 13:46:58 -06:00
}
else
{
save_flags = tab->priv->save_flags;
}
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SAVING);
2011-11-07 13:46:58 -06:00
/* uri used in error messages... strdup because errors are async
* and the string can go away, will be freed in document_saved */
tab->priv->tmp_save_uri = g_strdup (uri);
tab->priv->tmp_encoding = encoding;
if (tab->priv->auto_save_timeout > 0)
remove_auto_save_timeout (tab);
/* FIXME: this should behave the same as encoding, setting it here
makes it persistent (if save fails, it's remembered). It's not
a very big deal, but would be nice to have them follow the
same pattern. This can be changed once we break API for 3.0 */
2016-01-25 08:13:49 -06:00
xedit_document_set_newline_type (doc, newline_type);
xedit_document_save_as (doc, uri, encoding, tab->priv->save_flags);
2011-11-07 13:46:58 -06:00
}
2016-01-25 08:13:49 -06:00
#define XEDIT_PAGE_SETUP_KEY "xedit-page-setup-key"
#define XEDIT_PRINT_SETTINGS_KEY "xedit-print-settings-key"
2011-11-07 13:46:58 -06:00
static GtkPageSetup *
2016-01-25 08:13:49 -06:00
get_page_setup (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
gpointer data;
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
data = g_object_get_data (G_OBJECT (doc),
2016-01-25 08:13:49 -06:00
XEDIT_PAGE_SETUP_KEY);
2011-11-07 13:46:58 -06:00
if (data == NULL)
{
2016-01-25 08:13:49 -06:00
return _xedit_app_get_default_page_setup (xedit_app_get_default());
2011-11-07 13:46:58 -06:00
}
else
{
return gtk_page_setup_copy (GTK_PAGE_SETUP (data));
}
}
static GtkPrintSettings *
2016-01-25 08:13:49 -06:00
get_print_settings (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
gpointer data;
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2013-07-04 10:51:49 -05:00
GtkPrintSettings *settings;
gchar *uri, *name;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
data = g_object_get_data (G_OBJECT (doc),
2016-01-25 08:13:49 -06:00
XEDIT_PRINT_SETTINGS_KEY);
2011-11-07 13:46:58 -06:00
if (data == NULL)
{
2016-01-25 08:13:49 -06:00
settings = _xedit_app_get_default_print_settings (xedit_app_get_default());
2011-11-07 13:46:58 -06:00
}
else
{
2013-07-04 10:51:49 -05:00
settings = gtk_print_settings_copy (GTK_PRINT_SETTINGS (data));
2011-11-07 13:46:58 -06:00
}
2013-07-04 10:51:49 -05:00
2016-01-25 08:13:49 -06:00
name = xedit_document_get_short_name_for_display (doc);
2013-07-04 10:51:49 -05:00
uri = g_strconcat ("file://",
g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS),
"/", name, ".pdf", NULL);
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, uri);
g_free (uri);
g_free (name);
return settings;
2011-11-07 13:46:58 -06:00
}
/* FIXME: show the message area only if the operation will be "long" */
static void
2016-01-25 08:13:49 -06:00
printing_cb (XeditPrintJob *job,
XeditPrintJobStatus status,
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area));
2011-11-07 13:46:58 -06:00
gtk_widget_show (tab->priv->message_area);
2016-01-25 08:13:49 -06:00
xedit_progress_message_area_set_text (XEDIT_PROGRESS_MESSAGE_AREA (tab->priv->message_area),
xedit_print_job_get_status_string (job));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_progress_message_area_set_fraction (XEDIT_PROGRESS_MESSAGE_AREA (tab->priv->message_area),
xedit_print_job_get_progress (job));
2011-11-07 13:46:58 -06:00
}
static void
2016-01-25 08:13:49 -06:00
store_print_settings (XeditTab *tab,
XeditPrintJob *job)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
GtkPrintSettings *settings;
GtkPageSetup *page_setup;
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
settings = xedit_print_job_get_print_settings (job);
2011-11-07 13:46:58 -06:00
/* clear n-copies settings since we do not want to
* persist that one */
gtk_print_settings_unset (settings,
GTK_PRINT_SETTINGS_N_COPIES);
/* remember settings for this document */
g_object_set_data_full (G_OBJECT (doc),
2016-01-25 08:13:49 -06:00
XEDIT_PRINT_SETTINGS_KEY,
2011-11-07 13:46:58 -06:00
g_object_ref (settings),
(GDestroyNotify)g_object_unref);
/* make them the default */
2016-01-25 08:13:49 -06:00
_xedit_app_set_default_print_settings (xedit_app_get_default (),
2011-11-07 13:46:58 -06:00
settings);
2016-01-25 08:13:49 -06:00
page_setup = xedit_print_job_get_page_setup (job);
2011-11-07 13:46:58 -06:00
/* remember page setup for this document */
g_object_set_data_full (G_OBJECT (doc),
2016-01-25 08:13:49 -06:00
XEDIT_PAGE_SETUP_KEY,
2011-11-07 13:46:58 -06:00
g_object_ref (page_setup),
(GDestroyNotify)g_object_unref);
/* make it the default */
2016-01-25 08:13:49 -06:00
_xedit_app_set_default_page_setup (xedit_app_get_default (),
2011-11-07 13:46:58 -06:00
page_setup);
}
static void
2016-01-25 08:13:49 -06:00
done_printing_cb (XeditPrintJob *job,
XeditPrintJobResult result,
2011-11-07 13:46:58 -06:00
const GError *error,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_PRINT_PREVIEWING ||
tab->priv->state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW ||
tab->priv->state == XEDIT_TAB_STATE_PRINTING);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)
2011-11-07 13:46:58 -06:00
{
/* print preview has been destroyed... */
tab->priv->print_preview = NULL;
}
else
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area));
2011-11-07 13:46:58 -06:00
set_message_area (tab, NULL); /* destroy the message area */
}
// TODO: check status and error
2016-01-25 08:13:49 -06:00
if (result == XEDIT_PRINT_JOB_RESULT_OK)
2011-11-07 13:46:58 -06:00
{
store_print_settings (tab, job);
}
#if 0
if (tab->priv->print_preview != NULL)
{
/* If we were printing while showing the print preview,
see bug #352658 */
gtk_widget_destroy (tab->priv->print_preview);
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_PRINTING);
2011-11-07 13:46:58 -06:00
}
#endif
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
gtk_widget_grab_focus (GTK_WIDGET (view));
g_object_unref (tab->priv->print_job);
tab->priv->print_job = NULL;
}
#if 0
static void
print_preview_destroyed (GtkWidget *preview,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
tab->priv->print_preview = NULL;
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
gtk_widget_grab_focus (GTK_WIDGET (view));
}
else
{
/* This should happen only when printing while showing the print
* preview. In this case let us continue whithout changing
* the state and show the document. See bug #352658 */
gtk_widget_show (tab->priv->view_scrolled_window);
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_PRINTING);
2011-11-07 13:46:58 -06:00
}
}
#endif
static void
2016-01-25 08:13:49 -06:00
show_preview_cb (XeditPrintJob *job,
XeditPrintPreview *preview,
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
// g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_PRINT_PREVIEWING);
2011-11-07 13:46:58 -06:00
g_return_if_fail (tab->priv->print_preview == NULL);
set_message_area (tab, NULL); /* destroy the message area */
tab->priv->print_preview = GTK_WIDGET (preview);
gtk_box_pack_end (GTK_BOX (tab),
tab->priv->print_preview,
TRUE,
TRUE,
0);
gtk_widget_show (tab->priv->print_preview);
gtk_widget_grab_focus (tab->priv->print_preview);
/* when the preview gets destroyed we get "done" signal
g_signal_connect (tab->priv->print_preview,
"destroy",
G_CALLBACK (print_preview_destroyed),
tab);
*/
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
2011-11-07 13:46:58 -06:00
}
#if 0
static void
2016-01-25 08:13:49 -06:00
set_print_preview (XeditTab *tab,
2011-11-07 13:46:58 -06:00
GtkWidget *print_preview)
{
if (tab->priv->print_preview == print_preview)
return;
if (tab->priv->print_preview != NULL)
gtk_widget_destroy (tab->priv->print_preview);
tab->priv->print_preview = print_preview;
gtk_box_pack_end (GTK_BOX (tab),
tab->priv->print_preview,
TRUE,
TRUE,
0);
gtk_widget_grab_focus (tab->priv->print_preview);
g_signal_connect (tab->priv->print_preview,
"destroy",
G_CALLBACK (print_preview_destroyed),
tab);
}
static void
2016-01-25 08:13:49 -06:00
preview_finished_cb (GtkSourcePrintJob *pjob, XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
MatePrintJob *gjob;
GtkWidget *preview = NULL;
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area));
2011-11-07 13:46:58 -06:00
set_message_area (tab, NULL); /* destroy the message area */
gjob = gtk_source_print_job_get_print_job (pjob);
2016-01-25 08:13:49 -06:00
preview = xedit_print_job_preview_new (gjob);
2011-11-07 13:46:58 -06:00
g_object_unref (gjob);
set_print_preview (tab, preview);
gtk_widget_show (preview);
g_object_unref (pjob);
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
2011-11-07 13:46:58 -06:00
}
#endif
static void
print_cancelled (GtkWidget *area,
gint response_id,
2016-01-25 08:13:49 -06:00
XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_PROGRESS_MESSAGE_AREA (tab->priv->message_area));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_print_job_cancel (tab->priv->print_job);
2011-11-07 13:46:58 -06:00
g_debug ("print_cancelled");
}
static void
2016-01-25 08:13:49 -06:00
show_printing_message_area (XeditTab *tab, gboolean preview)
2011-11-07 13:46:58 -06:00
{
GtkWidget *area;
if (preview)
2016-01-25 08:13:49 -06:00
area = xedit_progress_message_area_new (GTK_STOCK_PRINT_PREVIEW,
2011-11-07 13:46:58 -06:00
"",
TRUE);
else
2016-01-25 08:13:49 -06:00
area = xedit_progress_message_area_new (GTK_STOCK_PRINT,
2011-11-07 13:46:58 -06:00
"",
TRUE);
g_signal_connect (area,
"response",
G_CALLBACK (print_cancelled),
tab);
set_message_area (tab, area);
}
static void
2016-01-25 08:13:49 -06:00
xedit_tab_print_or_print_preview (XeditTab *tab,
2011-11-07 13:46:58 -06:00
GtkPrintOperationAction print_action)
{
2016-01-25 08:13:49 -06:00
XeditView *view;
2011-11-07 13:46:58 -06:00
gboolean is_preview;
GtkPageSetup *setup;
GtkPrintSettings *settings;
GtkPrintOperationResult res;
GError *error = NULL;
g_return_if_fail (tab->priv->print_job == NULL);
2016-01-25 08:13:49 -06:00
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
view = xedit_tab_get_view (tab);
2011-11-07 13:46:58 -06:00
is_preview = (print_action == GTK_PRINT_OPERATION_ACTION_PREVIEW);
2016-01-25 08:13:49 -06:00
tab->priv->print_job = xedit_print_job_new (view);
2011-11-07 13:46:58 -06:00
g_object_add_weak_pointer (G_OBJECT (tab->priv->print_job),
(gpointer *) &tab->priv->print_job);
show_printing_message_area (tab, is_preview);
g_signal_connect (tab->priv->print_job,
"printing",
G_CALLBACK (printing_cb),
tab);
g_signal_connect (tab->priv->print_job,
"show-preview",
G_CALLBACK (show_preview_cb),
tab);
g_signal_connect (tab->priv->print_job,
"done",
G_CALLBACK (done_printing_cb),
tab);
if (is_preview)
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_PRINT_PREVIEWING);
2011-11-07 13:46:58 -06:00
else
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_PRINTING);
2011-11-07 13:46:58 -06:00
setup = get_page_setup (tab);
settings = get_print_settings (tab);
2016-01-25 08:13:49 -06:00
res = xedit_print_job_print (tab->priv->print_job,
2011-11-07 13:46:58 -06:00
print_action,
setup,
settings,
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab))),
&error);
// TODO: manage res in the correct way
if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
{
/* FIXME: go in error state */
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
g_warning ("Async print preview failed (%s)", error->message);
g_object_unref (tab->priv->print_job);
g_error_free (error);
}
}
void
2016-01-25 08:13:49 -06:00
_xedit_tab_print (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
2011-11-07 13:46:58 -06:00
/* FIXME: currently we can have just one printoperation going on
* at a given time, so before starting the print we close the preview.
* Would be nice to handle it properly though */
2016-01-25 08:13:49 -06:00
if (tab->priv->state == XEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)
2011-11-07 13:46:58 -06:00
{
gtk_widget_destroy (tab->priv->print_preview);
}
2016-01-25 08:13:49 -06:00
xedit_tab_print_or_print_preview (tab,
2011-11-07 13:46:58 -06:00
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
}
void
2016-01-25 08:13:49 -06:00
_xedit_tab_print_preview (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_tab_print_or_print_preview (tab,
2011-11-07 13:46:58 -06:00
GTK_PRINT_OPERATION_ACTION_PREVIEW);
}
void
2016-01-25 08:13:49 -06:00
_xedit_tab_mark_for_closing (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
g_return_if_fail (tab->priv->state == XEDIT_TAB_STATE_NORMAL);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_tab_set_state (tab, XEDIT_TAB_STATE_CLOSING);
2011-11-07 13:46:58 -06:00
}
gboolean
2016-01-25 08:13:49 -06:00
_xedit_tab_can_close (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
XeditTabState ts;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), FALSE);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
ts = xedit_tab_get_state (tab);
2011-11-07 13:46:58 -06:00
/* if we are loading or reverting, the tab can be closed */
2016-01-25 08:13:49 -06:00
if ((ts == XEDIT_TAB_STATE_LOADING) ||
(ts == XEDIT_TAB_STATE_LOADING_ERROR) ||
(ts == XEDIT_TAB_STATE_REVERTING) ||
(ts == XEDIT_TAB_STATE_REVERTING_ERROR)) /* CHECK: I'm not sure this is the right behavior for REVERTING ERROR */
2011-11-07 13:46:58 -06:00
return TRUE;
/* Do not close tab with saving errors */
2016-01-25 08:13:49 -06:00
if (ts == XEDIT_TAB_STATE_SAVING_ERROR)
2011-11-07 13:46:58 -06:00
return FALSE;
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
/* TODO: we need to save the file also if it has been externally
modified - Paolo (Oct 10, 2005) */
return (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)) &&
2016-01-25 08:13:49 -06:00
!xedit_document_get_deleted (doc));
2011-11-07 13:46:58 -06:00
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_get_auto_save_enabled:
* @tab: a #XeditTab
2011-11-07 13:46:58 -06:00
*
* Gets the current state for the autosave feature
*
* Return value: %TRUE if the autosave is enabled, else %FALSE
**/
gboolean
2016-01-25 08:13:49 -06:00
xedit_tab_get_auto_save_enabled (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), FALSE);
2011-11-07 13:46:58 -06:00
return tab->priv->auto_save;
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_set_auto_save_enabled:
* @tab: a #XeditTab
2011-11-07 13:46:58 -06:00
* @enable: enable (%TRUE) or disable (%FALSE) auto save
*
* Enables or disables the autosave feature. It does not install an
* autosave timeout if the document is new or is read-only
**/
void
2016-01-25 08:13:49 -06:00
xedit_tab_set_auto_save_enabled (XeditTab *tab,
gboolean enable)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc = NULL;
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document (tab);
2011-11-07 13:46:58 -06:00
if (tab->priv->auto_save == enable)
return;
tab->priv->auto_save = enable;
if (enable &&
(tab->priv->auto_save_timeout <=0) &&
2016-01-25 08:13:49 -06:00
!xedit_document_is_untitled (doc) &&
!xedit_document_get_readonly (doc))
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
if ((tab->priv->state != XEDIT_TAB_STATE_LOADING) &&
(tab->priv->state != XEDIT_TAB_STATE_SAVING) &&
(tab->priv->state != XEDIT_TAB_STATE_REVERTING) &&
(tab->priv->state != XEDIT_TAB_STATE_LOADING_ERROR) &&
(tab->priv->state != XEDIT_TAB_STATE_SAVING_ERROR) &&
(tab->priv->state != XEDIT_TAB_STATE_REVERTING_ERROR))
2011-11-07 13:46:58 -06:00
{
install_auto_save_timeout (tab);
}
/* else: the timeout will be installed when loading/saving/reverting
will terminate */
return;
}
if (!enable && (tab->priv->auto_save_timeout > 0))
{
remove_auto_save_timeout (tab);
return;
}
g_return_if_fail ((!enable && (tab->priv->auto_save_timeout <= 0)) ||
2016-01-25 08:13:49 -06:00
xedit_document_is_untitled (doc) || xedit_document_get_readonly (doc));
2011-11-07 13:46:58 -06:00
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_get_auto_save_interval:
* @tab: a #XeditTab
2011-11-07 13:46:58 -06:00
*
* Gets the current interval for the autosaves
*
* Return value: the value of the autosave
**/
gint
2016-01-25 08:13:49 -06:00
xedit_tab_get_auto_save_interval (XeditTab *tab)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_val_if_fail (XEDIT_IS_TAB (tab), 0);
2011-11-07 13:46:58 -06:00
return tab->priv->auto_save_interval;
}
/**
2016-01-25 08:13:49 -06:00
* xedit_tab_set_auto_save_interval:
* @tab: a #XeditTab
2011-11-07 13:46:58 -06:00
* @interval: the new interval
*
* Sets the interval for the autosave feature. It does nothing if the
* interval is the same as the one already present. It removes the old
* interval timeout and adds a new one with the autosave passed as
* argument.
**/
void
2016-01-25 08:13:49 -06:00
xedit_tab_set_auto_save_interval (XeditTab *tab,
gint interval)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc = NULL;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_TAB);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_tab_get_document(tab);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_DOCUMENT (doc));
2011-11-07 13:46:58 -06:00
g_return_if_fail (interval > 0);
if (tab->priv->auto_save_interval == interval)
return;
tab->priv->auto_save_interval = interval;
if (!tab->priv->auto_save)
return;
if (tab->priv->auto_save_timeout > 0)
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (!xedit_document_is_untitled (doc));
g_return_if_fail (!xedit_document_get_readonly (doc));
2011-11-07 13:46:58 -06:00
remove_auto_save_timeout (tab);
install_auto_save_timeout (tab);
}
}
void
2016-01-25 08:13:49 -06:00
xedit_tab_set_info_bar (XeditTab *tab,
2011-11-07 13:46:58 -06:00
GtkWidget *info_bar)
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_TAB (tab));
2011-11-07 13:46:58 -06:00
g_return_if_fail (info_bar == NULL || GTK_IS_WIDGET (info_bar));
/* FIXME: this can cause problems with the tab state machine */
set_message_area (tab, info_bar);
}