medit/moo/mooedit/mooeditor.cpp

2851 lines
79 KiB
C++
Raw Normal View History

2006-05-21 18:11:05 -05:00
/*
2016-01-03 05:13:00 -08:00
* mooeditor.cpp
2005-06-22 18:20:32 +00:00
*
2016-01-03 05:13:00 -08:00
* Copyright (C) 2004-2016 by Yevgen Muntyan <emuntyan@users.sourceforge.net>
2014-11-30 15:44:42 -08:00
* Copyright (C) 2014 by Ulrich Eckhardt <ulrich.eckhardt@base-42.de>
2005-06-22 18:20:32 +00:00
*
* This file is part of medit. medit is free software; you can
* redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
2005-06-22 18:20:32 +00:00
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
2005-06-22 18:20:32 +00:00
*/
2010-12-10 01:06:58 -08:00
/**
2011-12-29 01:47:32 -08:00
* class:MooEditor: (parent GObject): editor object
2010-12-10 01:06:58 -08:00
**/
#include "mooedit/mooeditor-private.h"
2010-11-23 21:54:39 -08:00
#include "mooedit/mooeditwindow-impl.h"
#include "mooedit/mooeditdialogs.h"
2008-09-07 00:15:07 -05:00
#include "mooedit/mooedit-fileops.h"
#include "mooedit/mooplugin.h"
#include "mooedit/mooeditprefs.h"
2010-02-01 22:44:03 -08:00
#include "mooedit/mooedit-impl.h"
2010-12-18 23:58:18 -08:00
#include "mooedit/mooeditview-impl.h"
2008-05-05 10:14:25 -05:00
#include "mooedit/mooedit-accels.h"
#include "mooedit/mooeditfiltersettings.h"
#include "mooedit/mooeditfileinfo-impl.h"
2010-12-08 01:17:17 -08:00
#include "mooedit/mooedithistoryitem.h"
#include "mooedit/mooedit-ui.h"
#include "mooedit/medit-ui.h"
2016-01-31 00:03:05 -08:00
#include "moocpp/moocpp.h"
#include "moocpp/gutil.h"
#include "mooutils/moomenuaction.h"
#include "marshals.h"
2005-10-31 22:58:01 +00:00
#include "mooutils/mooutils-misc.h"
#include "mooutils/mooaction-private.h"
2005-09-15 22:13:44 +00:00
#include "mooutils/mooutils-gobject.h"
#include "mooutils/mooutils-enums.h"
2006-08-01 20:18:35 -05:00
#include "mooutils/mooutils-fs.h"
2006-12-22 03:44:06 -06:00
#include "mooutils/moostock.h"
2007-02-27 22:55:05 -06:00
#include "mooutils/mooi18n.h"
#include "mooutils/mooencodings.h"
2008-09-08 02:17:32 -05:00
#include "mooutils/moolist.h"
2016-01-02 07:09:54 -08:00
#include "mooutils/moofilewatch.h"
#include <mooglib/moo-glib.h>
2005-07-31 14:53:10 +00:00
#include <string.h>
#include <stdlib.h>
2005-06-22 18:20:32 +00:00
2016-01-03 05:13:00 -08:00
using namespace moo;
#define RECENT_ACTION_ID "OpenRecent"
2008-02-20 09:34:34 -06:00
#define RECENT_DIALOG_ACTION_ID "OpenRecentDialog"
2008-09-15 03:59:22 -05:00
#define CURRENT_SESSION_VERSION "2.0"
2010-12-09 00:51:40 -08:00
MOO_DEFINE_QUARK (moo-edit-reload-error, moo_edit_reload_error_quark)
2010-12-12 02:29:20 -08:00
MOO_DEFINE_QUARK (moo-edit-save-error, moo_edit_save_error_quark)
2010-12-09 00:51:40 -08:00
2015-07-15 02:22:11 -07:00
static MooEditor* editor_instance = NULL;
2005-09-16 17:51:20 +00:00
2008-09-08 02:17:32 -05:00
static void set_single_window (MooEditor *editor,
gboolean single);
static GtkAction *create_open_recent_action (MooWindow *window,
gpointer user_data);
static void action_recent_dialog (MooEditWindow *window);
static MooEditWindow *create_window (MooEditor *editor);
static MooSaveResponse moo_editor_before_save (MooEditor *editor,
MooEdit *doc,
GFile *file);
static void moo_editor_will_save (MooEditor *editor,
MooEdit *doc,
GFile *file);
static MooCloseResponse moo_editor_before_close_window
(MooEditor *editor,
MooEditWindow *window);
2008-09-08 02:17:32 -05:00
static void do_close_window (MooEditor *editor,
MooEditWindow *window);
static void do_close_doc (MooEditor *editor,
MooEdit *doc);
static gboolean close_docs_real (MooEditor *editor,
MooEditArray *docs);
2010-11-23 21:54:39 -08:00
static MooEditArray *find_modified (MooEditArray *docs);
2005-06-22 18:20:32 +00:00
2008-09-08 02:17:32 -05:00
static void add_new_window_action (void);
static void remove_new_window_action (void);
2008-09-15 00:01:48 -05:00
static GObject *moo_editor_constructor (GType type,
guint n_props,
GObjectConstructParam *props);
2008-09-08 02:17:32 -05:00
static void moo_editor_finalize (GObject *object);
static void moo_editor_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void moo_editor_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
2005-06-22 18:20:32 +00:00
2005-09-03 16:07:59 +00:00
enum {
PROP_0,
2005-09-08 17:08:31 +00:00
PROP_OPEN_SINGLE_FILE_INSTANCE,
PROP_ALLOW_EMPTY_WINDOW,
2005-11-10 07:15:16 +00:00
PROP_SINGLE_WINDOW,
2005-11-11 20:05:33 +00:00
PROP_SAVE_BACKUPS,
PROP_STRIP_WHITESPACE,
2005-09-03 16:07:59 +00:00
};
2005-06-22 18:20:32 +00:00
enum {
BEFORE_CLOSE_WINDOW,
WILL_CLOSE_WINDOW,
AFTER_CLOSE_WINDOW,
WILL_CLOSE_DOC,
2010-12-12 02:29:20 -08:00
BEFORE_SAVE,
WILL_SAVE,
2010-12-12 02:29:20 -08:00
AFTER_SAVE,
2005-06-22 18:20:32 +00:00
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
/* MOO_TYPE_EDITOR */
G_DEFINE_TYPE (MooEditor, moo_editor, G_TYPE_OBJECT)
2008-08-28 19:23:10 -05:00
inline static gboolean test_flag(MooEditor *editor, MooEditorOptions flag)
{
2016-01-01 22:25:53 -08:00
return (editor->priv->opts & flag) != MOO_EDITOR_OPTIONS_NONE;
2008-08-28 19:23:10 -05:00
}
inline static void set_flag(MooEditor *editor, MooEditorOptions flag, gboolean set_or_not)
{
if (set_or_not)
editor->priv->opts |= flag;
else
editor->priv->opts &= ~flag;
}
static void
moo_editor_class_init (MooEditorClass *klass)
2005-06-22 18:20:32 +00:00
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
MooWindowClass *edit_window_class;
2005-06-22 18:20:32 +00:00
2008-09-15 00:01:48 -05:00
gobject_class->constructor = moo_editor_constructor;
2005-06-22 18:20:32 +00:00
gobject_class->finalize = moo_editor_finalize;
2005-09-03 16:07:59 +00:00
gobject_class->set_property = moo_editor_set_property;
gobject_class->get_property = moo_editor_get_property;
klass->before_close_window = moo_editor_before_close_window;
klass->before_save = moo_editor_before_save;
klass->will_save = moo_editor_will_save;
2007-06-24 12:16:36 -05:00
_moo_edit_init_config ();
g_type_class_unref (g_type_class_ref (MOO_TYPE_EDIT));
g_type_class_unref (g_type_class_ref (MOO_TYPE_EDIT_WINDOW));
2010-12-18 23:58:18 -08:00
g_type_class_unref (g_type_class_ref (MOO_TYPE_INDENTER));
2006-08-19 01:15:42 -05:00
g_type_class_add_private (klass, sizeof (MooEditorPrivate));
2008-08-28 19:23:10 -05:00
g_object_class_install_property (gobject_class, PROP_OPEN_SINGLE_FILE_INSTANCE,
g_param_spec_boolean ("open-single-file-instance", "open-single-file-instance", "open-single-file-instance",
2010-08-12 18:17:00 -07:00
TRUE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
2008-08-28 19:23:10 -05:00
g_object_class_install_property (gobject_class, PROP_ALLOW_EMPTY_WINDOW,
g_param_spec_boolean ("allow-empty-window", "allow-empty-window", "allow-empty-window",
2010-08-12 18:17:00 -07:00
FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
2008-08-28 19:23:10 -05:00
g_object_class_install_property (gobject_class, PROP_SINGLE_WINDOW,
g_param_spec_boolean ("single-window", "single-window", "single-window",
2010-08-12 18:17:00 -07:00
FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
2008-08-28 19:23:10 -05:00
g_object_class_install_property (gobject_class, PROP_SAVE_BACKUPS,
g_param_spec_boolean ("save-backups", "save-backups", "save-backups",
2010-08-12 18:17:00 -07:00
FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
2008-08-28 19:23:10 -05:00
g_object_class_install_property (gobject_class, PROP_STRIP_WHITESPACE,
g_param_spec_boolean ("strip-whitespace", "strip-whitespace", "strip-whitespace",
2010-08-12 18:17:00 -07:00
FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
2008-08-28 19:23:10 -05:00
signals[BEFORE_CLOSE_WINDOW] =
g_signal_new ("before-close-window",
2007-06-24 12:16:36 -05:00
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, before_close_window),
moo_signal_accumulator_continue_cancel,
GINT_TO_POINTER (MOO_CLOSE_RESPONSE_CONTINUE),
_moo_marshal_ENUM__OBJECT,
MOO_TYPE_CLOSE_RESPONSE, 1,
MOO_TYPE_EDIT_WINDOW);
/**
* MooEditor::will-close-window:
*
* @editor: the object which received the signal
* @window: the window which is about to be closed
*
* This signal is emitted before the window is closed.
**/
signals[WILL_CLOSE_WINDOW] =
g_signal_new ("will-close-window",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, will_close_window),
NULL, NULL,
_moo_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
MOO_TYPE_EDIT_WINDOW);
signals[AFTER_CLOSE_WINDOW] =
g_signal_new ("after-close-window",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, after_close_window),
NULL, NULL,
_moo_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* MooEditor::will-close-doc:
*
* @editor: the object which received the signal
* @doc: the document which is about to be closed
*
* This signal is emitted before the document is closed.
**/
signals[WILL_CLOSE_DOC] =
g_signal_new ("will-close-doc",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, will_close_doc),
NULL, NULL,
_moo_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
MOO_TYPE_EDIT);
2005-07-30 22:15:13 +00:00
/**
* MooEditor::before-save:
*
* @editor: the object which received the signal
* @doc: the document which is about to be saved on disk
* @file: the #GFile object which represents saved file
*
* This signal is emitted when the document is going to be saved on disk.
2011-12-29 01:47:32 -08:00
* Callbacks must return #MOO_SAVE_RESPONSE_CANCEL if document
* should not be saved, and #MOO_SAVE_RESPONSE_CONTINUE otherwise.
*
* For example, if before saving the file must be checked out from a version
* control system, a callback can do that and return #MOO_SAVE_RESPONSE_CANCEL
* if checkout failed.
*
2011-12-29 01:47:32 -08:00
* Callbacks must not modify document content. If you need to modify
* it before saving, use MooEditor::will-save signal instead.
*
* Returns: #MOO_SAVE_RESPONSE_CANCEL to cancel saving,
* #MOO_SAVE_RESPONSE_CONTINUE otherwise.
**/
2010-12-12 02:29:20 -08:00
signals[BEFORE_SAVE] =
g_signal_new ("before-save",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, before_save),
moo_signal_accumulator_continue_cancel,
GINT_TO_POINTER (MOO_SAVE_RESPONSE_CONTINUE),
_moo_marshal_ENUM__OBJECT_OBJECT,
MOO_TYPE_SAVE_RESPONSE, 2,
MOO_TYPE_EDIT,
G_TYPE_FILE);
/**
* MooEditor::will-save:
*
* @editor: the object which received the signal
* @doc: the document which is about to be saved on disk
* @file: the #GFile object which represents saved file
*
* This signal is emitted when the document is going to be saved on disk,
* after MooEditor::before-save signal. Callbacks may modify document
* content at this point.
**/
signals[WILL_SAVE] =
g_signal_new ("will-save",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, will_save),
NULL, NULL,
_moo_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2,
2010-12-12 02:29:20 -08:00
MOO_TYPE_EDIT,
G_TYPE_FILE);
2010-12-12 02:29:20 -08:00
/**
* MooEditor::after-save:
*
* @editor: the object which received the signal
* @doc: the document which was saved on disk
*
* This signal is emitted after the document has been successfully saved on disk.
**/
2010-12-12 02:29:20 -08:00
signals[AFTER_SAVE] =
g_signal_new ("after-save",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, after_save),
NULL, NULL,
_moo_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
MOO_TYPE_EDIT);
2015-07-15 02:22:11 -07:00
edit_window_class = MOO_WINDOW_CLASS (g_type_class_ref (MOO_TYPE_EDIT_WINDOW));
moo_window_class_new_action_custom (edit_window_class, RECENT_ACTION_ID, NULL,
create_open_recent_action,
2005-11-06 07:33:24 +00:00
NULL, NULL);
2008-02-20 09:34:34 -06:00
moo_window_class_new_action (edit_window_class, RECENT_DIALOG_ACTION_ID, NULL,
"display-name", _("Open Recent Files Dialog"),
2013-12-06 09:22:39 -08:00
/* Translators: remove the part before and including | */
2008-02-20 09:34:34 -06:00
"label", Q_("Open Recent|_More..."),
"default-accel", MOO_EDIT_ACCEL_OPEN_RECENT_DIALOG,
2008-02-20 09:34:34 -06:00
"closure-callback", action_recent_dialog,
NULL);
2005-07-30 22:15:13 +00:00
g_type_class_unref (edit_window_class);
add_new_window_action ();
2016-01-01 10:39:11 -08:00
}
2005-06-22 18:20:32 +00:00
2015-12-30 00:12:49 -08:00
MooEditorPrivate::MooEditorPrivate()
{
2015-12-31 04:51:56 -08:00
// zero-initialized when allocated with the GObject
2015-12-30 00:12:49 -08:00
}
MooEditorPrivate::~MooEditorPrivate()
{
if (file_watch)
{
GError *error = NULL;
2016-01-02 07:09:54 -08:00
if (!file_watch->close (&error))
2015-12-30 00:12:49 -08:00
{
g_warning ("error in moo_file_watch_close: %s", moo_error_message (error));
g_error_free (error);
error = NULL;
}
2015-12-31 16:41:12 -08:00
file_watch.reset();
2015-12-30 00:12:49 -08:00
}
if (!windows.empty())
g_critical ("finalizing editor while some windows are open");
}
static void
moo_editor_init (MooEditor *editor)
2005-06-22 18:20:32 +00:00
{
2016-01-05 02:18:52 -08:00
init_cpp_private(editor, editor->priv, MOO_TYPE_EDITOR);
2008-09-15 00:01:48 -05:00
}
static GObject *
moo_editor_constructor (GType type,
guint n_props,
GObjectConstructParam *props)
{
MooEditor *editor;
GObject *object;
object = G_OBJECT_CLASS (moo_editor_parent_class)->constructor (type, n_props, props);
editor = MOO_EDITOR (object);
2005-07-30 22:15:13 +00:00
2006-12-22 03:44:06 -06:00
_moo_stock_init ();
2016-01-21 03:16:33 -08:00
editor->priv->doc_ui_xml.set_new(moo_ui_xml_new());
2016-01-04 10:24:03 -08:00
moo_ui_xml_add_ui_from_string (editor->priv->doc_ui_xml.gobj(),
2008-01-15 00:49:38 -06:00
mooedit_ui_xml, -1);
2015-12-31 16:41:12 -08:00
editor->priv->lang_mgr.ref(moo_lang_mgr_default());
2016-01-04 10:24:03 -08:00
g_signal_connect_swapped (editor->priv->lang_mgr.gobj(), "loaded",
2010-12-12 02:29:20 -08:00
G_CALLBACK (_moo_editor_apply_prefs),
editor);
2016-01-21 03:16:33 -08:00
editor->priv->history.set_new(MOO_HISTORY_MGR (
2016-01-01 22:25:53 -08:00
g_object_new (MOO_TYPE_HISTORY_MGR,
"name", "Editor",
(const char*) NULL)));
_moo_edit_filter_settings_load ();
2010-12-12 02:29:20 -08:00
_moo_editor_apply_prefs (editor);
2008-09-15 00:01:48 -05:00
return object;
2005-06-22 18:20:32 +00:00
}
static void
moo_editor_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
2005-09-03 16:07:59 +00:00
{
MooEditor *editor = MOO_EDITOR (object);
switch (prop_id) {
2005-09-08 17:08:31 +00:00
case PROP_OPEN_SINGLE_FILE_INSTANCE:
2008-08-28 19:23:10 -05:00
set_flag (editor, OPEN_SINGLE, g_value_get_boolean (value));
2005-09-03 16:07:59 +00:00
break;
case PROP_ALLOW_EMPTY_WINDOW:
2008-08-28 19:23:10 -05:00
set_flag (editor, ALLOW_EMPTY_WINDOW, g_value_get_boolean (value));
2005-09-08 17:08:31 +00:00
break;
case PROP_SINGLE_WINDOW:
set_single_window (editor, g_value_get_boolean (value));
2005-09-03 16:07:59 +00:00
break;
2005-11-10 07:15:16 +00:00
case PROP_SAVE_BACKUPS:
2008-08-28 19:23:10 -05:00
set_flag (editor, SAVE_BACKUPS, g_value_get_boolean (value));
2005-11-10 07:15:16 +00:00
break;
2005-11-11 20:05:33 +00:00
case PROP_STRIP_WHITESPACE:
2008-08-28 19:23:10 -05:00
set_flag (editor, STRIP_WHITESPACE, g_value_get_boolean (value));
2005-11-11 20:05:33 +00:00
break;
2005-09-03 16:07:59 +00:00
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
moo_editor_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
2005-09-03 16:07:59 +00:00
{
MooEditor *editor = MOO_EDITOR (object);
switch (prop_id) {
2005-09-08 17:08:31 +00:00
case PROP_OPEN_SINGLE_FILE_INSTANCE:
2008-08-28 19:23:10 -05:00
g_value_set_boolean (value, test_flag (editor, OPEN_SINGLE));
2005-09-03 16:07:59 +00:00
break;
case PROP_ALLOW_EMPTY_WINDOW:
2008-08-28 19:23:10 -05:00
g_value_set_boolean (value, test_flag (editor, ALLOW_EMPTY_WINDOW));
2005-09-03 16:07:59 +00:00
break;
2005-09-08 17:08:31 +00:00
case PROP_SINGLE_WINDOW:
2008-08-28 19:23:10 -05:00
g_value_set_boolean (value, test_flag (editor, SINGLE_WINDOW));
2005-09-08 17:08:31 +00:00
break;
2005-11-10 07:15:16 +00:00
case PROP_SAVE_BACKUPS:
2008-08-28 19:23:10 -05:00
g_value_set_boolean (value, test_flag (editor, SAVE_BACKUPS));
2005-11-10 07:15:16 +00:00
break;
2005-11-11 20:05:33 +00:00
case PROP_STRIP_WHITESPACE:
2008-08-28 19:23:10 -05:00
g_value_set_boolean (value, test_flag (editor, STRIP_WHITESPACE));
2005-11-11 20:05:33 +00:00
break;
2005-09-03 16:07:59 +00:00
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
moo_editor_finalize (GObject *object)
2005-06-22 18:20:32 +00:00
{
MooEditor *editor = MOO_EDITOR (object);
if (editor_instance == editor)
editor_instance = NULL;
2016-01-05 02:18:52 -08:00
finalize_cpp_private(editor, editor->priv);
2010-11-23 21:54:39 -08:00
2005-06-22 18:20:32 +00:00
G_OBJECT_CLASS (moo_editor_parent_class)->finalize (object);
}
2010-02-01 22:44:03 -08:00
MooFileWatch *
_moo_editor_get_file_watch (MooEditor *editor)
{
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
if (!editor->priv->file_watch)
2016-01-02 07:09:54 -08:00
editor->priv->file_watch = MooFileWatch::create(nullptr);
2016-01-04 10:24:03 -08:00
return editor->priv->file_watch.gobj();
}
/**
* moo_editor_create_instance: (static-method-of MooEditor) (moo.lua 0)
*
* Returns: (transfer full)
*/
2008-08-28 19:23:10 -05:00
MooEditor *
2016-01-01 22:25:53 -08:00
moo_editor_create_instance ()
2005-06-22 18:20:32 +00:00
{
2005-09-16 17:51:20 +00:00
if (!editor_instance)
{
2010-08-12 18:17:00 -07:00
editor_instance = MOO_EDITOR (g_object_new (MOO_TYPE_EDITOR,
(const char*) NULL));
2015-07-15 02:22:11 -07:00
g_object_add_weak_pointer (G_OBJECT (editor_instance), reinterpret_cast<gpointer*> (&editor_instance));
2005-09-16 17:51:20 +00:00
}
else
{
g_object_ref (editor_instance);
}
return editor_instance;
}
2005-09-16 17:51:20 +00:00
2010-12-10 03:10:22 -08:00
/**
2011-01-09 23:33:47 -08:00
* moo_editor_instance: (static-method-of MooEditor)
2010-12-10 03:10:22 -08:00
**/
MooEditor *
moo_editor_instance (void)
{
2005-09-16 17:51:20 +00:00
return editor_instance;
2005-06-22 18:20:32 +00:00
}
2005-11-02 02:32:07 +00:00
static GType
get_window_type (MooEditor *editor)
{
return editor->priv->window_type ?
editor->priv->window_type : MOO_TYPE_EDIT_WINDOW;
}
static GType
get_doc_type (MooEditor *editor)
{
return editor->priv->doc_type ?
editor->priv->doc_type : MOO_TYPE_EDIT;
}
static void
set_single_window (MooEditor *editor,
gboolean single)
2005-09-08 17:08:31 +00:00
{
/* XXX move documents to some window if several windows open? */
2008-08-28 19:23:10 -05:00
set_flag (editor, SINGLE_WINDOW, single);
if (single)
remove_new_window_action ();
else
add_new_window_action ();
2005-09-08 17:08:31 +00:00
g_object_notify (G_OBJECT (editor), "single-window");
}
static void
add_new_window_action (void)
{
MooWindowClass *klass;
2015-07-15 02:22:11 -07:00
klass = MOO_WINDOW_CLASS (g_type_class_peek (MOO_TYPE_EDIT_WINDOW));
if (!moo_window_class_find_action (klass, "NewWindow"))
moo_window_class_new_action (klass, "NewWindow", NULL,
"display-name", MOO_STOCK_NEW_WINDOW,
"label", MOO_STOCK_NEW_WINDOW,
"tooltip", _("Open new editor window"),
"stock-id", MOO_STOCK_NEW_WINDOW,
"default-accel", MOO_EDIT_ACCEL_NEW_WINDOW,
"closure-callback", moo_editor_new_window,
"closure-proxy-func", moo_edit_window_get_editor,
NULL);
}
static void
remove_new_window_action (void)
{
MooWindowClass *klass;
2015-07-15 02:22:11 -07:00
klass = MOO_WINDOW_CLASS (g_type_class_peek (MOO_TYPE_EDIT_WINDOW));
moo_window_class_remove_action (klass, "NewWindow");
}
2008-09-08 02:17:32 -05:00
static MooEditWindow *
2005-11-02 02:32:07 +00:00
get_top_window (MooEditor *editor)
2005-06-22 18:20:32 +00:00
{
2005-09-02 23:27:25 +00:00
GtkWindow *window;
2005-07-29 15:25:29 +00:00
2015-12-30 00:12:49 -08:00
if (editor->priv->windows.empty())
2005-06-22 18:20:32 +00:00
return NULL;
2015-12-30 00:12:49 -08:00
GSList *window_list = nullptr;
2016-01-02 14:34:23 -08:00
for (const auto& w: editor->priv->windows)
window_list = g_slist_prepend (window_list, w);
2010-11-23 21:54:39 -08:00
window_list = g_slist_reverse (window_list);
2005-07-31 14:53:10 +00:00
2010-11-23 21:54:39 -08:00
window = _moo_get_top_window (window_list);
2010-11-23 21:54:39 -08:00
if (!window)
window = GTK_WINDOW (editor->priv->windows[0]);
2005-06-22 18:20:32 +00:00
2010-11-23 21:54:39 -08:00
g_slist_free (window_list);
2005-06-22 18:20:32 +00:00
2010-11-23 21:54:39 -08:00
return MOO_EDIT_WINDOW (window);
2005-06-22 18:20:32 +00:00
}
2010-12-10 03:11:38 -08:00
/**
* moo_editor_get_ui_xml: (moo.private 1)
2010-12-10 03:11:38 -08:00
*/
2008-09-13 14:56:47 -05:00
MooUiXml *
moo_editor_get_ui_xml (MooEditor *editor)
2005-06-22 18:20:32 +00:00
{
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
2006-12-22 03:44:06 -06:00
if (!editor->priv->ui_xml)
{
2016-01-21 03:16:33 -08:00
editor->priv->ui_xml.set_new(moo_ui_xml_new ());
2016-01-04 10:24:03 -08:00
moo_ui_xml_add_ui_from_string (editor->priv->ui_xml.gobj(), medit_ui_xml, -1);
2006-12-22 03:44:06 -06:00
}
2016-01-04 10:24:03 -08:00
return editor->priv->ui_xml.gobj();
2005-06-22 18:20:32 +00:00
}
/**
* moo_editor_get_doc_ui_xml: (moo.private 1)
*/
2008-09-13 14:56:47 -05:00
MooUiXml *
moo_editor_get_doc_ui_xml (MooEditor *editor)
{
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
2016-01-04 10:24:03 -08:00
return editor->priv->doc_ui_xml.gobj();
}
/**
* moo_editor_set_ui_xml: (moo.private 1)
*/
void
moo_editor_set_ui_xml (MooEditor *editor,
2008-09-13 14:56:47 -05:00
MooUiXml *xml)
2005-06-22 18:20:32 +00:00
{
g_return_if_fail (MOO_IS_EDITOR (editor));
2006-12-22 03:44:06 -06:00
g_return_if_fail (MOO_IS_UI_XML (xml));
2005-06-22 18:20:32 +00:00
2015-12-31 16:41:12 -08:00
if (editor->priv->ui_xml == xml)
2005-06-22 18:20:32 +00:00
return;
2015-12-31 16:41:12 -08:00
editor->priv->ui_xml.ref(xml);
2005-09-02 23:27:25 +00:00
2015-12-30 00:12:49 -08:00
for (const auto& window: editor->priv->windows)
2016-01-04 10:24:03 -08:00
moo_window_set_ui_xml (MOO_WINDOW (window), editor->priv->ui_xml.gobj());
2005-07-31 14:53:10 +00:00
}
2010-12-08 01:17:17 -08:00
MooHistoryMgr *
_moo_editor_get_history_mgr (MooEditor *editor)
{
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
2016-01-04 10:24:03 -08:00
return editor->priv->history.gobj();
}
2010-12-12 02:29:20 -08:00
// static void
// add_recent_uri (MooEditor *editor,
// const char *uri)
// {
2016-01-01 22:25:53 -08:00
// moo_history_mgr_add_uri (editor->priv->history, uri);
2010-12-12 02:29:20 -08:00
// }
2008-09-15 03:59:22 -05:00
static void
2008-02-20 09:34:34 -06:00
recent_item_activated (GSList *items,
gpointer data)
{
2015-07-15 02:22:11 -07:00
MooEditWindow *window = MOO_EDIT_WINDOW (data);
MooEditor *editor = moo_editor_instance ();
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
g_return_if_fail (MOO_IS_EDITOR (editor));
2008-02-20 09:34:34 -06:00
while (items)
{
const char *encoding;
const char *uri;
char *filename;
2015-07-15 02:22:11 -07:00
MooHistoryItem *item = static_cast<MooHistoryItem*>(items->data);
2008-02-20 09:34:34 -06:00
2010-12-08 01:17:17 -08:00
uri = moo_history_item_get_uri (item);
2008-02-20 09:34:34 -06:00
filename = g_filename_from_uri (uri, NULL, NULL);
g_return_if_fail (filename != NULL);
2008-02-20 09:34:34 -06:00
encoding = _moo_edit_history_item_get_encoding (item);
2010-12-12 02:29:20 -08:00
if (!moo_editor_open_uri (editor, uri, encoding, -1, window))
2016-01-04 10:24:03 -08:00
moo_history_mgr_remove_uri (editor->priv->history.gobj(), uri);
2008-02-20 09:34:34 -06:00
g_free (filename);
items = items->next;
}
}
static GtkWidget *
create_recent_menu (GtkAction *action)
{
GtkWidget *menu, *item;
2008-02-20 09:34:34 -06:00
GtkAction *action_more;
MooWindow *window;
MooEditor *editor;
2015-07-15 02:22:11 -07:00
window = MOO_WINDOW (_moo_action_get_window (action));
g_return_val_if_fail (MOO_IS_EDIT_WINDOW (window), NULL);
editor = moo_editor_instance ();
2016-01-04 10:24:03 -08:00
menu = moo_history_mgr_create_menu (editor->priv->history.gobj(),
2015-12-31 16:41:12 -08:00
recent_item_activated,
window, NULL);
moo_bind_bool_property (action,
2016-01-04 10:24:03 -08:00
"sensitive", editor->priv->history.gobj(),
"empty", TRUE);
2008-02-20 09:34:34 -06:00
item = gtk_separator_menu_item_new ();
gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
action_more = moo_window_get_action (window, RECENT_DIALOG_ACTION_ID);
item = gtk_action_create_menu_item (action_more);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = gtk_menu_item_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
return item;
2005-07-30 22:15:13 +00:00
}
static GtkAction *
create_open_recent_action (G_GNUC_UNUSED MooWindow *window,
G_GNUC_UNUSED gpointer user_data)
2005-07-30 22:15:13 +00:00
{
GtkAction *action;
2005-07-30 22:15:13 +00:00
action = moo_menu_action_new ("OpenRecent", _("Open Recent"));
moo_menu_action_set_func (MOO_MENU_ACTION (action), create_recent_menu);
2005-07-30 22:15:13 +00:00
return action;
2005-09-02 23:27:25 +00:00
}
2008-02-20 09:34:34 -06:00
static void
action_recent_dialog (MooEditWindow *window)
{
GtkWidget *dialog;
MooEditor *editor;
editor = moo_editor_instance ();
g_return_if_fail (MOO_IS_EDITOR (editor));
2016-01-04 10:24:03 -08:00
dialog = moo_history_mgr_create_dialog (editor->priv->history.gobj(),
2015-12-31 16:41:12 -08:00
recent_item_activated,
window, NULL);
2008-02-20 09:34:34 -06:00
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
_moo_window_set_remember_size (GTK_WINDOW (dialog),
moo_edit_setting (MOO_EDIT_PREFS_DIALOGS "/recent-files"),
400, 350,
2008-02-20 09:34:34 -06:00
FALSE);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
2005-09-02 23:27:25 +00:00
/*****************************************************************************/
2008-09-15 00:44:03 -05:00
static MooEditWindow *
2005-11-02 02:32:07 +00:00
create_window (MooEditor *editor)
2005-09-02 23:27:25 +00:00
{
2010-08-12 18:17:00 -07:00
MooEditWindow *window = MOO_EDIT_WINDOW (
g_object_new (get_window_type (editor),
"editor", editor,
"ui-xml", moo_editor_get_ui_xml (editor),
(const char*) NULL));
2015-12-30 00:12:49 -08:00
editor->priv->windows.emplace_back(window);
2005-09-12 06:57:29 +00:00
_moo_window_attach_plugins (window);
2005-09-07 11:19:26 +00:00
gtk_widget_show (GTK_WIDGET (window));
return window;
2005-09-02 23:27:25 +00:00
}
/**
* moo_editor_new_window:
*/
2007-04-05 08:52:11 -05:00
MooEditWindow *
2005-11-11 20:05:33 +00:00
moo_editor_new_window (MooEditor *editor)
2005-09-02 23:27:25 +00:00
{
MooEditWindow *window;
2010-12-08 01:11:51 -08:00
MooEdit *doc;
2005-09-02 23:27:25 +00:00
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
2005-09-07 11:19:26 +00:00
window = create_window (editor);
2005-09-02 23:27:25 +00:00
2008-08-28 19:23:10 -05:00
if (!test_flag (editor, ALLOW_EMPTY_WINDOW))
2005-09-07 11:19:26 +00:00
{
2010-12-08 01:11:51 -08:00
doc = MOO_EDIT (g_object_new (get_doc_type (editor), "editor", editor, (const char*) NULL));
2011-01-09 03:31:34 -08:00
_moo_edit_window_insert_doc (window, doc, NULL);
2010-12-18 23:58:18 -08:00
g_object_unref (doc);
2005-09-07 11:19:26 +00:00
}
2005-09-02 23:27:25 +00:00
return window;
}
/**
* moo_editor_new_doc:
*
* @editor:
* @window: (allow-none) (default NULL)
*/
2007-04-05 08:52:11 -05:00
MooEdit *
2005-11-11 20:05:33 +00:00
moo_editor_new_doc (MooEditor *editor,
MooEditWindow *window)
{
MooEdit *doc;
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
2005-11-11 20:05:33 +00:00
g_return_val_if_fail (!window || MOO_IS_EDIT_WINDOW (window), NULL);
if (!window)
window = get_top_window (editor);
if (!window)
window = moo_editor_new_window (editor);
g_return_val_if_fail (window != NULL, NULL);
2010-08-12 18:17:00 -07:00
doc = MOO_EDIT (g_object_new (get_doc_type (editor), "editor", editor, (const char*) NULL));
2011-01-09 03:31:34 -08:00
_moo_edit_window_insert_doc (window, doc, NULL);
2010-12-18 23:58:18 -08:00
g_object_unref (doc);
if (moo_prefs_get_bool (moo_edit_setting (MOO_EDIT_PREFS_AUTO_SYNC)))
{
// After creating the new document, prompt the user for a path to save
// it to. If the user aborts, delete the document, too.
if (!moo_editor_save_as (editor, doc, NULL, NULL))
{
moo_editor_close_doc (editor, doc);
return NULL;
}
}
return doc;
}
2007-04-05 08:52:11 -05:00
void
_moo_editor_move_doc (MooEditor *editor,
MooEdit *doc,
MooEditWindow *dest,
2011-01-09 03:31:34 -08:00
MooEditView *dest_view,
2007-04-05 08:52:11 -05:00
gboolean focus)
{
2008-09-15 00:44:03 -05:00
MooEditWindow *old_window;
2011-01-09 03:31:34 -08:00
MooEdit *dest_doc = NULL;
2011-01-17 03:01:11 -08:00
MooEditTab *tab;
2007-04-05 08:52:11 -05:00
g_return_if_fail (MOO_IS_EDITOR (editor));
2010-02-01 22:44:03 -08:00
g_return_if_fail (MOO_IS_EDIT (doc) && moo_edit_get_editor (doc) == editor);
g_return_if_fail (!dest || (MOO_IS_EDIT_WINDOW (dest) && moo_edit_window_get_editor (dest) == editor));
2007-04-05 08:52:11 -05:00
if (!dest)
2011-01-09 03:31:34 -08:00
{
dest = moo_editor_new_window (editor);
2011-01-09 03:31:34 -08:00
dest_view = moo_edit_window_get_active_view (dest);
}
2011-01-17 03:01:11 -08:00
tab = moo_edit_view_get_tab (moo_edit_get_view (doc));
g_object_ref (tab);
2007-04-05 08:52:11 -05:00
g_object_ref (doc);
2008-09-15 00:44:03 -05:00
if ((old_window = moo_edit_get_window (doc)))
2007-04-05 08:52:11 -05:00
{
2011-01-17 03:01:11 -08:00
_moo_edit_window_remove_doc (old_window, doc);
2007-04-05 08:52:11 -05:00
2008-09-15 00:44:03 -05:00
if (!moo_edit_window_get_active_doc (old_window))
moo_editor_close_window (editor, old_window);
2007-04-05 08:52:11 -05:00
}
2011-01-17 03:01:11 -08:00
_moo_edit_window_insert_tab (dest, tab, dest_view);
2007-04-05 08:52:11 -05:00
2011-01-09 03:31:34 -08:00
dest_doc = dest_view ? moo_edit_view_get_doc (dest_view) : NULL;
if (dest_doc && moo_edit_is_empty (dest_doc))
moo_editor_close_doc (editor, dest_doc);
2007-04-05 08:52:11 -05:00
if (focus)
moo_editor_set_active_doc (editor, doc);
g_object_unref (doc);
2011-01-17 03:01:11 -08:00
g_object_unref (tab);
2007-04-05 08:52:11 -05:00
}
2010-11-07 23:49:51 -08:00
static void
update_history_item_for_doc (MooEditor *editor,
MooEdit *doc,
gboolean add)
2010-11-07 23:49:51 -08:00
{
char *uri;
2010-12-08 01:17:17 -08:00
MooHistoryItem *item;
2010-11-07 23:49:51 -08:00
int line;
const char *enc;
2010-12-18 23:58:18 -08:00
MooEditView *view;
2010-11-07 23:49:51 -08:00
if (!(uri = moo_edit_get_uri (doc)))
return;
2010-12-08 01:17:17 -08:00
item = moo_history_item_new (uri, NULL);
2010-11-07 23:49:51 -08:00
2010-12-18 23:58:18 -08:00
view = moo_edit_get_view (doc);
line = moo_text_view_get_cursor_line (GTK_TEXT_VIEW (view));
2010-11-07 23:49:51 -08:00
if (line != 0)
_moo_edit_history_item_set_line (item, line);
enc = moo_edit_get_encoding (doc);
if (enc && strcmp (enc, MOO_ENCODING_UTF8) != 0)
2010-11-07 23:49:51 -08:00
_moo_edit_history_item_set_encoding (item, enc);
if (add)
2016-01-04 10:24:03 -08:00
moo_history_mgr_add_file (editor->priv->history.gobj(), item);
else
2016-01-04 10:24:03 -08:00
moo_history_mgr_update_file (editor->priv->history.gobj(), item);
2010-12-08 01:17:17 -08:00
moo_history_item_free (item);
2010-11-07 23:49:51 -08:00
g_free (uri);
}
2016-01-04 09:56:33 -08:00
static EditPtr
2016-01-04 03:56:42 -08:00
moo_editor_load_file(MooEditor *editor,
MooOpenInfo *info,
MooEditWindow *window,
GtkWidget *parent,
gboolean silent,
gboolean add_history,
2016-01-19 03:54:06 -08:00
gerrp& error)
2007-06-24 12:16:36 -05:00
{
MooEditView *view = NULL;
2007-06-24 12:16:36 -05:00
gboolean new_doc = FALSE;
2010-12-12 02:29:20 -08:00
gboolean new_object = FALSE;
const char *recent_encoding = NULL;
2016-01-19 03:54:06 -08:00
gerrp error_here;
2010-12-12 02:29:20 -08:00
gboolean success = TRUE;
2007-06-24 12:16:36 -05:00
2016-01-04 03:56:42 -08:00
moo_return_error_if_fail_p(MOO_IS_EDITOR(editor));
moo_return_error_if_fail_p(info != NULL && info->file != nullptr);
2007-06-24 12:16:36 -05:00
2016-01-04 03:56:42 -08:00
gstr uri = info->file->get_uri();
gstr filename = info->file->get_path();
int line = info->line;
2016-01-04 10:24:03 -08:00
EditPtr doc = wrap(moo_editor_get_doc_for_file(editor, info->file.gobj()));
2007-06-24 12:16:36 -05:00
2016-01-04 03:56:42 -08:00
if (filename.empty())
{
g_set_error (&error_here, MOO_EDIT_FILE_ERROR,
MOO_EDIT_FILE_ERROR_NOT_IMPLEMENTED,
"Loading remote files is not implemented");
success = FALSE;
}
if (success && !doc)
2007-06-24 12:16:36 -05:00
{
2010-12-12 02:29:20 -08:00
new_doc = TRUE;
2007-06-24 12:16:36 -05:00
2010-12-12 02:29:20 -08:00
if (!window)
window = moo_editor_get_active_window (editor);
if (window)
{
2016-01-04 03:56:42 -08:00
doc = wrap (moo_edit_window_get_active_doc (window));
2010-12-12 02:29:20 -08:00
2016-01-04 10:24:03 -08:00
if (doc && !moo_edit_is_empty (doc.gobj()))
2010-12-12 02:29:20 -08:00
doc = NULL;
}
2007-06-24 12:16:36 -05:00
}
if (success && !doc)
2007-06-24 12:16:36 -05:00
{
2010-12-12 02:29:20 -08:00
new_object = TRUE;
2016-01-04 03:56:42 -08:00
doc = wrap_new(MOO_EDIT(g_object_new(get_doc_type(editor), "editor", editor, nullptr)));
2007-06-24 12:16:36 -05:00
}
if (success)
{
2016-01-04 10:24:03 -08:00
view = moo_edit_get_view (doc.gobj());
2016-01-01 22:25:53 -08:00
if (!new_doc && line < 0 && (info->flags & MOO_OPEN_FLAG_RELOAD) != MOO_OPEN_FLAGS_NONE)
line = moo_text_view_get_cursor_line (GTK_TEXT_VIEW (view));
2016-01-04 03:56:42 -08:00
if (info->encoding.empty())
{
2016-01-04 10:24:03 -08:00
MooHistoryItem *hist_item = moo_history_mgr_find_uri (editor->priv->history.gobj(), uri);
if (hist_item)
recent_encoding = _moo_edit_history_item_get_encoding (hist_item);
}
}
if (success && new_doc)
2010-12-12 02:29:20 -08:00
{
2016-01-04 03:56:42 -08:00
if ((info->flags & MOO_OPEN_FLAG_CREATE_NEW) && _moo_edit_file_is_new(*info->file))
2010-12-12 02:29:20 -08:00
{
2016-01-04 03:56:42 -08:00
doc->_set_status(MOO_EDIT_STATUS_NEW);
2016-01-04 10:24:03 -08:00
doc->_set_file(info->file.gobj(), info->encoding);
2010-12-12 02:29:20 -08:00
}
else
{
2016-01-02 07:09:54 -08:00
// XXX
2016-01-04 03:56:42 -08:00
success = _moo_edit_load_file(*doc, *info->file,
2016-01-21 03:16:33 -08:00
info->encoding,
gstr::wrap(recent_encoding),
2016-01-19 03:54:06 -08:00
error_here);
2010-12-12 02:29:20 -08:00
}
}
if (!success)
2007-06-24 12:16:36 -05:00
{
if (!silent && !_moo_is_file_error_cancelled (error_here))
{
if (!parent && !window)
window = moo_editor_get_active_window (editor);
if (!parent && window)
parent = GTK_WIDGET (window);
2016-01-19 03:54:06 -08:00
_moo_edit_open_error_dialog(parent, info->file, error_here.get());
}
2010-12-12 02:29:20 -08:00
2016-01-19 03:54:06 -08:00
error = std::move (error_here);
2007-06-24 12:16:36 -05:00
}
else if (!new_doc && (info->flags & MOO_OPEN_FLAG_RELOAD))
2010-12-12 02:29:20 -08:00
{
2016-01-19 03:54:06 -08:00
success = _moo_edit_reload_file(*doc, info->encoding, error_here);
2010-12-12 02:29:20 -08:00
if (!success)
{
if (!silent && !_moo_is_file_error_cancelled (error_here))
2016-01-19 03:54:06 -08:00
_moo_edit_reload_error_dialog (doc.gobj(), error_here.get());
error = std::move (error_here);
2010-12-12 02:29:20 -08:00
}
}
if (success && new_object)
{
if (!window || (info->flags & MOO_OPEN_FLAG_NEW_WINDOW))
2010-12-12 02:29:20 -08:00
window = create_window (editor);
2016-01-04 10:24:03 -08:00
_moo_edit_window_insert_doc (window, doc.gobj(), NULL);
2010-12-12 02:29:20 -08:00
}
if (success)
2007-06-24 12:16:36 -05:00
{
2010-12-08 01:17:17 -08:00
MooHistoryItem *hist_item;
if (line < 0 && new_doc)
{
2016-01-04 10:24:03 -08:00
hist_item = moo_history_mgr_find_uri (editor->priv->history.gobj(), uri);
2008-08-23 02:33:54 -05:00
if (hist_item)
line = _moo_edit_history_item_get_line (hist_item);
}
2008-08-23 02:33:54 -05:00
if (line >= 0)
2010-12-18 23:58:18 -08:00
moo_text_view_move_cursor (MOO_TEXT_VIEW (view), line, 0, FALSE, TRUE);
2010-12-12 02:29:20 -08:00
}
2010-12-12 02:29:20 -08:00
if (success && add_history)
2016-01-04 10:24:03 -08:00
update_history_item_for_doc (editor, doc.gobj(), TRUE);
2007-06-24 12:16:36 -05:00
2010-12-12 02:29:20 -08:00
if (success)
{
2016-01-04 10:24:03 -08:00
moo_editor_set_active_doc (editor, doc.gobj());
2010-12-18 23:58:18 -08:00
gtk_widget_grab_focus (GTK_WIDGET (view));
2007-06-24 12:16:36 -05:00
}
2016-01-04 03:56:42 -08:00
return success ? std::move(doc) : nullptr;
2010-12-12 02:29:20 -08:00
}
// static MooEdit *
// moo_editor_load_file (MooEditor *editor,
2011-01-10 02:31:07 -08:00
// MooOpenInfo *info,
2010-12-12 02:29:20 -08:00
// MooEditWindow *window,
// GtkWidget *parent,
// gboolean silent,
// gboolean add_history,
// GError **error)
// {
// GError *error = NULL;
// gboolean new_doc = FALSE;
// MooEdit *doc = NULL;
// char *uri;
// gboolean result = TRUE;
// const char *recent_encoding = NULL;
//
// *docp = NULL;
// uri = g_file_get_uri (info->file);
// g_return_val_if_fail (uri != NULL, FALSE);
//
// if ((doc = moo_editor_get_doc_for_uri (editor, uri)))
// {
// *docp = doc;
// if (add_history)
// add_recent_uri (editor, uri);
// g_free (uri);
// return FALSE;
// }
//
// if (window)
// {
// doc = moo_edit_window_get_active_doc (window);
//
// if (doc && moo_edit_is_empty (doc))
// g_object_ref (doc);
// else
// doc = NULL;
// }
//
// if (!doc)
// {
// doc = MOO_EDIT (g_object_new (get_doc_type (editor), "editor", editor, (const char*) NULL));
// g_object_ref_sink (doc);
// new_doc = TRUE;
// }
//
// if (!info->encoding)
// {
// MooHistoryItem *hist_item = moo_history_mgr_find_uri (editor->priv->history, uri);
// if (hist_item)
// recent_encoding = _moo_edit_history_item_get_encoding (hist_item);
// }
//
// /* XXX open_single */
// if (!_moo_edit_load_file (doc, info->file, info->encoding, recent_encoding, &error))
// {
// if (!silent)
// {
// if (!parent && !window)
// window = moo_editor_get_active_window (editor);
// if (!parent && window)
// parent = GTK_WIDGET (window);
// _moo_edit_open_error_dialog (parent, info->file, info->encoding, error);
// }
// g_error_free (error);
// result = FALSE;
// }
// else
// {
// MooHistoryItem *hist_item;
// int line = info->line;
//
// if (line < 0)
// {
// hist_item = moo_history_mgr_find_uri (editor->priv->history, uri);
// if (hist_item)
// line = _moo_edit_history_item_get_line (hist_item);
// }
//
// if (line >= 0)
// moo_text_view_move_cursor (MOO_TEXT_VIEW (doc), line, 0, FALSE, TRUE);
//
// if (!window)
// window = moo_editor_get_active_window (editor);
// if (!window)
// window = create_window (editor);
//
// if (new_doc)
// {
2011-01-09 03:31:34 -08:00
// _moo_edit_window_insert_doc (window, doc, NULL);
2010-12-12 02:29:20 -08:00
// moo_editor_add_doc (editor, window, doc);
// }
//
// if (add_history)
// update_history_item_for_doc (editor, doc, TRUE);
// }
//
// if (result)
// *docp = doc;
//
// g_free (uri);
// g_object_unref (doc);
// return result;
// }
2007-06-24 12:16:36 -05:00
2010-12-12 02:29:20 -08:00
static MooEditArray *
2016-01-19 03:54:06 -08:00
_moo_editor_open_files (MooEditor* editor,
MooOpenInfoArray* files,
GtkWidget* parent,
gerrp& error)
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
guint i;
2005-09-03 16:07:59 +00:00
MooEdit *bring_to_front = NULL;
2005-11-02 15:49:35 +00:00
gboolean result = TRUE;
2010-12-12 02:29:20 -08:00
MooEditWindow *window = NULL;
MooEditArray *docs;
2005-09-02 23:27:25 +00:00
2010-12-12 02:29:20 -08:00
moo_return_error_if_fail_p (MOO_IS_EDITOR (editor));
moo_return_error_if_fail_p (!parent || GTK_IS_WIDGET (parent));
2011-01-10 02:31:07 -08:00
moo_return_error_if_fail_p (!moo_open_info_array_is_empty (files));
2005-09-02 23:27:25 +00:00
2010-12-12 02:29:20 -08:00
if (parent)
2005-09-02 23:27:25 +00:00
{
2010-12-12 02:29:20 -08:00
GtkWidget *top = gtk_widget_get_toplevel (parent);
if (MOO_IS_EDIT_WINDOW (top))
window = MOO_EDIT_WINDOW (top);
2005-09-02 23:27:25 +00:00
}
2010-12-12 02:29:20 -08:00
docs = moo_edit_array_new ();
2007-06-24 12:16:36 -05:00
2010-11-23 21:54:39 -08:00
for (i = 0; i < files->n_elms; ++i)
2005-09-02 23:27:25 +00:00
{
2011-01-10 02:31:07 -08:00
MooOpenInfo *info = files->elms[i];
2005-09-02 23:27:25 +00:00
if (!window)
window = moo_editor_get_active_window (editor);
2016-01-04 09:56:33 -08:00
EditPtr doc = moo_editor_load_file(editor, info, window, parent,
FALSE, TRUE, error);
2005-09-03 16:07:59 +00:00
2007-06-24 12:16:36 -05:00
if (doc)
2010-12-12 02:29:20 -08:00
{
2016-01-04 10:24:03 -08:00
parent = GTK_WIDGET (moo_edit_get_view (doc.gobj()));
bring_to_front = doc.gobj();
moo_edit_array_append (docs, doc.gobj());
2010-12-12 02:29:20 -08:00
}
else
{
result = FALSE;
break;
}
2005-09-02 23:27:25 +00:00
}
2005-09-03 16:07:59 +00:00
if (bring_to_front)
{
2005-09-03 16:07:59 +00:00
moo_editor_set_active_doc (editor, bring_to_front);
2010-12-18 23:58:18 -08:00
gtk_widget_grab_focus (GTK_WIDGET (moo_edit_get_view (bring_to_front)));
}
2005-11-02 15:49:35 +00:00
2010-12-12 02:29:20 -08:00
if (!result)
{
moo_edit_array_free (docs);
docs = NULL;
}
return docs;
2005-09-02 23:27:25 +00:00
}
/**
* moo_editor_get_active_doc:
*/
MooEdit *
2005-11-02 02:32:07 +00:00
moo_editor_get_active_doc (MooEditor *editor)
2005-09-02 23:27:25 +00:00
{
MooEditWindow *window = moo_editor_get_active_window (editor);
return window ? moo_edit_window_get_active_doc (window) : NULL;
}
2010-12-18 23:58:18 -08:00
/**
* moo_editor_get_active_view:
*/
MooEditView *
moo_editor_get_active_view (MooEditor *editor)
{
MooEditWindow *window = moo_editor_get_active_window (editor);
return window ? moo_edit_window_get_active_view (window) : NULL;
}
2005-09-02 23:27:25 +00:00
/**
* moo_editor_get_active_window:
*/
MooEditWindow *
2005-11-02 02:32:07 +00:00
moo_editor_get_active_window (MooEditor *editor)
2005-09-02 23:27:25 +00:00
{
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
return get_top_window (editor);
}
2005-11-02 02:32:07 +00:00
void
moo_editor_present (MooEditor *editor,
guint32 stamp)
2005-11-02 02:32:07 +00:00
{
MooEditWindow *window;
g_return_if_fail (MOO_IS_EDITOR (editor));
window = moo_editor_get_active_window (editor);
if (!window)
window = moo_editor_new_window (editor);
g_return_if_fail (window != NULL);
moo_window_present (GTK_WINDOW (window), stamp);
2005-11-02 02:32:07 +00:00
}
/**
* moo_editor_set_active_window:
*/
2005-11-02 02:32:07 +00:00
void
2008-09-15 00:44:03 -05:00
moo_editor_set_active_window (MooEditor *editor,
2005-11-02 02:32:07 +00:00
MooEditWindow *window)
2005-09-02 23:27:25 +00:00
{
g_return_if_fail (MOO_IS_EDITOR (editor));
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
2008-09-15 00:44:03 -05:00
gtk_window_present (GTK_WINDOW (window));
2005-07-30 22:15:13 +00:00
}
/**
2010-12-18 23:58:18 -08:00
* moo_editor_set_active_view:
*/
2005-11-02 02:32:07 +00:00
void
2010-12-18 23:58:18 -08:00
moo_editor_set_active_view (MooEditor *editor,
MooEditView *view)
2005-07-30 22:15:13 +00:00
{
2008-09-15 00:44:03 -05:00
MooEditWindow *window;
2005-09-02 23:27:25 +00:00
2005-07-30 22:15:13 +00:00
g_return_if_fail (MOO_IS_EDITOR (editor));
2010-12-18 23:58:18 -08:00
g_return_if_fail (MOO_IS_EDIT_VIEW (view));
2005-09-02 23:27:25 +00:00
2010-12-18 23:58:18 -08:00
window = moo_edit_view_get_window (view);
2008-09-15 00:44:03 -05:00
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
2005-09-02 23:27:25 +00:00
2008-09-15 00:44:03 -05:00
moo_window_present (GTK_WINDOW (window), 0);
2010-12-18 23:58:18 -08:00
moo_edit_window_set_active_view (window, view);
}
/**
* moo_editor_set_active_doc:
*/
void
moo_editor_set_active_doc (MooEditor *editor,
MooEdit *doc)
{
moo_editor_set_active_view (editor, moo_edit_get_view (doc));
2005-09-02 23:27:25 +00:00
}
2006-06-30 00:58:35 -05:00
static MooEdit *
2010-11-23 21:54:39 -08:00
find_busy (MooEditArray *docs)
2006-06-30 00:58:35 -05:00
{
2010-11-23 21:54:39 -08:00
guint i;
for (i = 0; i < docs->n_elms; ++i)
2016-01-04 09:56:33 -08:00
if (Edit(*docs->elms[i])._is_busy())
2010-11-23 21:54:39 -08:00
return docs->elms[i];
2006-06-30 00:58:35 -05:00
return NULL;
}
static MooCloseResponse
moo_editor_before_close_window (MooEditor *editor,
MooEditWindow *window)
2005-09-02 23:27:25 +00:00
{
2011-01-01 17:41:01 -08:00
MooSaveChangesResponse response;
2010-11-23 21:54:39 -08:00
MooEditArray *modified;
MooEditArray *docs;
2005-09-02 23:27:25 +00:00
gboolean do_close = FALSE;
2006-06-30 00:58:35 -05:00
MooEdit *busy = NULL;
2005-09-02 23:27:25 +00:00
2015-07-15 02:22:11 -07:00
g_return_val_if_fail (MOO_IS_EDITOR (editor), MOO_CLOSE_RESPONSE_CANCEL);
g_return_val_if_fail (MOO_IS_EDIT_WINDOW (window), MOO_CLOSE_RESPONSE_CANCEL);
2005-09-02 23:27:25 +00:00
2010-11-23 21:54:39 -08:00
docs = moo_edit_window_get_docs (window);
2008-09-15 00:44:03 -05:00
busy = find_busy (docs);
2006-06-30 00:58:35 -05:00
if (busy)
{
moo_editor_set_active_doc (editor, busy);
2010-11-23 21:54:39 -08:00
moo_edit_array_free (docs);
return MOO_CLOSE_RESPONSE_CANCEL;
2006-06-30 00:58:35 -05:00
}
2008-09-15 00:44:03 -05:00
modified = find_modified (docs);
2005-09-02 23:27:25 +00:00
if (moo_edit_array_is_empty (modified))
2005-09-02 23:27:25 +00:00
{
do_close = TRUE;
}
2010-11-23 21:54:39 -08:00
else if (modified->n_elms == 1)
2005-09-02 23:27:25 +00:00
{
2008-09-15 00:44:03 -05:00
if (window)
2010-11-23 21:54:39 -08:00
moo_edit_window_set_active_doc (window, modified->elms[0]);
2010-11-23 21:54:39 -08:00
response = _moo_edit_save_changes_dialog (modified->elms[0]);
2005-09-02 23:27:25 +00:00
switch (response)
{
case MOO_SAVE_CHANGES_RESPONSE_SAVE:
2010-12-12 02:29:20 -08:00
if (moo_editor_save (editor, modified->elms[0], NULL))
2005-09-02 23:27:25 +00:00
do_close = TRUE;
break;
case MOO_SAVE_CHANGES_RESPONSE_CANCEL:
2005-09-02 23:27:25 +00:00
break;
default:
do_close = TRUE;
break;
}
}
else
{
2010-11-23 21:54:39 -08:00
guint i;
MooEditArray *to_save;
2005-09-02 23:27:25 +00:00
gboolean saved = TRUE;
2010-11-23 21:54:39 -08:00
to_save = moo_edit_array_new ();
response = _moo_edit_save_multiple_changes_dialog (modified, to_save);
2005-09-02 23:27:25 +00:00
switch (response)
{
case MOO_SAVE_CHANGES_RESPONSE_SAVE:
2010-11-23 21:54:39 -08:00
for (i = 0; i < to_save->n_elms; ++i)
2010-12-12 02:29:20 -08:00
if (!moo_editor_save (editor, to_save->elms[i], NULL))
2005-09-02 23:27:25 +00:00
{
saved = FALSE;
break;
}
if (saved)
do_close = TRUE;
break;
case MOO_SAVE_CHANGES_RESPONSE_CANCEL:
2005-09-02 23:27:25 +00:00
break;
default:
do_close = TRUE;
break;
}
2010-11-23 21:54:39 -08:00
moo_edit_array_free (to_save);
2005-09-02 23:27:25 +00:00
}
2010-11-23 21:54:39 -08:00
moo_edit_array_free (modified);
moo_edit_array_free (docs);
return do_close ? MOO_CLOSE_RESPONSE_CONTINUE : MOO_CLOSE_RESPONSE_CANCEL;
2007-06-24 12:16:36 -05:00
}
/**
* moo_editor_close_window:
*/
2007-06-24 12:16:36 -05:00
gboolean
moo_editor_close_window (MooEditor *editor,
MooEditWindow *window)
2007-06-24 12:16:36 -05:00
{
MooCloseResponse response = MOO_CLOSE_RESPONSE_CONTINUE;
2007-06-24 12:16:36 -05:00
g_return_val_if_fail (MOO_IS_EDITOR (editor), FALSE);
g_return_val_if_fail (MOO_IS_EDIT_WINDOW (window), FALSE);
2015-12-30 00:12:49 -08:00
if (!contains(editor->priv->windows, window))
2007-06-24 12:16:36 -05:00
return TRUE;
g_object_ref (window);
g_signal_emit_by_name (window, "before-close", &response);
2015-12-30 00:12:49 -08:00
if (response != MOO_CLOSE_RESPONSE_CANCEL && contains(editor->priv->windows, window))
g_signal_emit (editor, signals[BEFORE_CLOSE_WINDOW], 0, window, &response);
2007-06-24 12:16:36 -05:00
2015-12-30 00:12:49 -08:00
if (response != MOO_CLOSE_RESPONSE_CANCEL && contains(editor->priv->windows, window))
2005-09-02 23:27:25 +00:00
do_close_window (editor, window);
2007-06-24 12:16:36 -05:00
g_object_unref (window);
return response != MOO_CLOSE_RESPONSE_CANCEL;
2005-09-02 23:27:25 +00:00
}
2005-11-02 02:32:07 +00:00
static void
do_close_window (MooEditor *editor,
MooEditWindow *window)
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
MooEditArray *docs;
guint i;
2005-09-02 23:27:25 +00:00
g_signal_emit (editor, signals[WILL_CLOSE_WINDOW], 0, window);
g_signal_emit_by_name (window, "will-close");
2010-11-23 21:54:39 -08:00
docs = moo_edit_window_get_docs (window);
2005-09-02 23:27:25 +00:00
2010-11-23 21:54:39 -08:00
for (i = 0; i < docs->n_elms; ++i)
do_close_doc (editor, docs->elms[i]);
2005-09-02 23:27:25 +00:00
2015-12-30 00:12:49 -08:00
remove(editor->priv->windows, window);
2005-09-02 23:27:25 +00:00
_moo_window_detach_plugins (window);
2005-09-07 11:19:26 +00:00
gtk_widget_destroy (GTK_WIDGET (window));
2005-09-02 23:27:25 +00:00
g_signal_emit (editor, signals[AFTER_CLOSE_WINDOW], 0);
2010-11-23 21:54:39 -08:00
moo_edit_array_free (docs);
2005-09-02 23:27:25 +00:00
}
2005-09-08 17:08:31 +00:00
static void
do_close_doc (MooEditor *editor,
MooEdit *doc)
2005-09-02 23:27:25 +00:00
{
2008-09-15 00:44:03 -05:00
MooEditWindow *window;
2016-01-04 09:56:33 -08:00
EditPtr docp = wrap(doc); // get a reference so it doesn't get destroyed below
2010-12-18 23:58:18 -08:00
2016-01-04 03:56:42 -08:00
g_signal_emit(editor, signals[WILL_CLOSE_DOC], 0, doc);
g_signal_emit_by_name(doc, "will-close");
2016-01-04 03:56:42 -08:00
window = moo_edit_get_window(doc);
g_assert(window);
2016-01-04 03:56:42 -08:00
update_history_item_for_doc(editor, doc, TRUE);
2008-09-15 00:44:03 -05:00
if (window)
2016-01-04 03:56:42 -08:00
_moo_edit_window_remove_doc(window, doc);
else
2016-01-04 03:56:42 -08:00
_moo_doc_detach_plugins(NULL, doc);
2010-12-18 23:58:18 -08:00
2016-01-04 03:56:42 -08:00
docp->_closed();
2005-09-02 23:27:25 +00:00
}
/**
* moo_editor_close_doc:
*/
2005-09-08 17:08:31 +00:00
gboolean
2010-11-23 21:54:39 -08:00
moo_editor_close_doc (MooEditor *editor,
MooEdit *doc)
2005-09-02 23:27:25 +00:00
{
gboolean result;
2010-11-23 21:54:39 -08:00
MooEditArray *docs;
2005-09-02 23:27:25 +00:00
2010-11-23 21:54:39 -08:00
docs = moo_edit_array_new ();
moo_edit_array_append (docs, doc);
result = moo_editor_close_docs (editor, docs);
2010-11-23 21:54:39 -08:00
moo_edit_array_free (docs);
2005-09-02 23:27:25 +00:00
return result;
}
/**
* moo_editor_close_docs:
*/
2005-09-08 17:08:31 +00:00
gboolean
2010-11-23 21:54:39 -08:00
moo_editor_close_docs (MooEditor *editor,
MooEditArray *docs)
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
guint i;
2008-09-15 00:44:03 -05:00
MooEditWindow *window;
2005-09-02 23:27:25 +00:00
g_return_val_if_fail (MOO_IS_EDITOR (editor), FALSE);
2006-06-01 02:09:07 -05:00
2010-11-23 21:54:39 -08:00
if (moo_edit_array_is_empty (docs))
2006-06-01 02:09:07 -05:00
return TRUE;
2005-09-02 23:27:25 +00:00
2010-11-23 21:54:39 -08:00
for (i = 0; i < docs->n_elms; ++i)
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
MooEdit *doc = docs->elms[i];
g_return_val_if_fail (MOO_IS_EDIT (doc), FALSE);
2006-06-30 00:58:35 -05:00
2016-01-04 09:56:33 -08:00
if (Edit(*doc)._is_busy())
2006-06-30 00:58:35 -05:00
{
moo_editor_set_active_doc (editor, doc);
return FALSE;
}
2005-09-02 23:27:25 +00:00
}
2010-11-23 21:54:39 -08:00
window = moo_edit_get_window (docs->elms[0]);
2005-09-02 23:27:25 +00:00
if (close_docs_real (editor, docs))
2005-09-02 23:27:25 +00:00
{
2008-09-15 00:44:03 -05:00
if (window &&
2011-01-17 03:01:11 -08:00
!moo_edit_window_get_n_tabs (window) &&
2008-08-28 19:23:10 -05:00
!test_flag (editor, ALLOW_EMPTY_WINDOW))
2005-09-02 23:27:25 +00:00
{
2010-08-12 18:17:00 -07:00
MooEdit *doc = MOO_EDIT (g_object_new (get_doc_type (editor),
"editor", editor,
(const char*) NULL));
2011-01-09 03:31:34 -08:00
_moo_edit_window_insert_doc (window, doc, NULL);
2010-12-18 23:58:18 -08:00
g_object_unref (doc);
2005-09-02 23:27:25 +00:00
}
return TRUE;
}
else
{
return FALSE;
}
}
2005-09-08 17:08:31 +00:00
static gboolean
2010-11-23 21:54:39 -08:00
close_docs_real (MooEditor *editor,
MooEditArray *docs)
2005-09-02 23:27:25 +00:00
{
2011-01-01 17:41:01 -08:00
MooSaveChangesResponse response;
2010-11-23 21:54:39 -08:00
MooEditArray *modified;
2005-09-02 23:27:25 +00:00
gboolean do_close = FALSE;
modified = find_modified (docs);
if (moo_edit_array_is_empty (modified))
2005-09-02 23:27:25 +00:00
{
do_close = TRUE;
}
2010-11-23 21:54:39 -08:00
else if (modified->n_elms == 1)
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
MooEditWindow *window = moo_edit_get_window (modified->elms[0]);
2005-09-02 23:27:25 +00:00
2008-09-15 00:44:03 -05:00
if (window)
2010-11-23 21:54:39 -08:00
moo_edit_window_set_active_doc (window, modified->elms[0]);
2010-11-23 21:54:39 -08:00
response = _moo_edit_save_changes_dialog (modified->elms[0]);
2005-09-02 23:27:25 +00:00
switch (response)
{
case MOO_SAVE_CHANGES_RESPONSE_SAVE:
2010-12-12 02:29:20 -08:00
if (moo_editor_save (editor, modified->elms[0], NULL))
2005-09-02 23:27:25 +00:00
do_close = TRUE;
break;
case MOO_SAVE_CHANGES_RESPONSE_CANCEL:
2005-09-02 23:27:25 +00:00
break;
default:
do_close = TRUE;
break;
}
}
else
{
2010-11-23 21:54:39 -08:00
guint i;
MooEditArray *to_save;
2005-09-02 23:27:25 +00:00
gboolean saved = TRUE;
2010-11-23 21:54:39 -08:00
to_save = moo_edit_array_new ();
response = _moo_edit_save_multiple_changes_dialog (modified, to_save);
2005-09-02 23:27:25 +00:00
switch (response)
{
case MOO_SAVE_CHANGES_RESPONSE_SAVE:
2010-11-23 21:54:39 -08:00
for (i = 0; i < to_save->n_elms; ++i)
2010-12-12 02:29:20 -08:00
if (!moo_editor_save (editor, to_save->elms[i], NULL))
2005-09-02 23:27:25 +00:00
{
saved = FALSE;
break;
}
if (saved)
do_close = TRUE;
break;
case MOO_SAVE_CHANGES_RESPONSE_CANCEL:
2005-09-02 23:27:25 +00:00
break;
default:
do_close = TRUE;
break;
}
2010-11-23 21:54:39 -08:00
moo_edit_array_free (to_save);
2005-09-02 23:27:25 +00:00
}
if (do_close)
2008-09-08 02:17:32 -05:00
{
2010-11-23 21:54:39 -08:00
guint i;
for (i = 0; i < docs->n_elms; ++i)
do_close_doc (editor, docs->elms[i]);
2008-09-08 02:17:32 -05:00
}
2005-09-02 23:27:25 +00:00
2010-11-23 21:54:39 -08:00
moo_edit_array_free (modified);
2005-09-02 23:27:25 +00:00
return do_close;
}
2010-11-23 21:54:39 -08:00
static MooEditArray *
find_modified (MooEditArray *docs)
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
guint i;
MooEditArray *modified = moo_edit_array_new ();
for (i = 0; i < docs->n_elms; ++i)
if (moo_edit_is_modified (docs->elms[i]) && !moo_edit_get_clean (docs->elms[i]))
2010-11-23 21:54:39 -08:00
moo_edit_array_append (modified, docs->elms[i]);
return modified;
2005-09-02 23:27:25 +00:00
}
2005-09-08 17:08:31 +00:00
gboolean
_moo_editor_close_all (MooEditor *editor)
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
guint i;
MooEditWindowArray *windows;
2005-09-02 23:27:25 +00:00
g_return_val_if_fail (MOO_IS_EDITOR (editor), FALSE);
2010-11-23 21:54:39 -08:00
windows = moo_editor_get_windows (editor);
2005-09-02 23:27:25 +00:00
2010-11-23 21:54:39 -08:00
for (i = 0; i < windows->n_elms; ++i)
2005-09-02 23:27:25 +00:00
{
if (!moo_editor_close_window (editor, windows->elms[i]))
2005-09-02 23:27:25 +00:00
{
2010-11-23 21:54:39 -08:00
moo_edit_window_array_free (windows);
2005-09-02 23:27:25 +00:00
return FALSE;
}
}
2010-11-23 21:54:39 -08:00
moo_edit_window_array_free (windows);
2005-09-02 23:27:25 +00:00
return TRUE;
}
2016-01-04 09:56:33 -08:00
static EditPtr
2007-06-24 12:16:36 -05:00
load_doc_session (MooEditor *editor,
MooEditWindow *window,
2008-09-15 03:59:22 -05:00
MooMarkupNode *elm,
gboolean file_is_uri)
2007-06-24 12:16:36 -05:00
{
2016-01-04 03:56:42 -08:00
gstr uri;
2007-06-24 12:16:36 -05:00
2008-09-15 03:59:22 -05:00
if (file_is_uri)
{
2016-01-21 03:16:33 -08:00
uri = gstr::wrap(moo_markup_get_content(elm));
2008-09-15 03:59:22 -05:00
}
else
{
2016-01-04 03:56:42 -08:00
const char *filename = moo_markup_get_content (elm);
2008-09-15 03:59:22 -05:00
if (filename)
uri = g::filename_to_uri(filename);
2008-09-15 03:59:22 -05:00
}
2007-06-24 12:16:36 -05:00
2016-01-04 03:56:42 -08:00
if (uri.empty())
2016-01-04 09:56:33 -08:00
return EditPtr::wrap(moo_editor_new_doc(editor, window));
2007-06-24 12:16:36 -05:00
2016-01-04 03:56:42 -08:00
const char *encoding = moo_markup_get_prop (elm, "encoding");
std::unique_ptr<MooOpenInfo> info(moo_open_info_new_uri(uri, encoding, -1, MOO_OPEN_FLAGS_NONE));
2007-06-24 12:16:36 -05:00
2016-01-19 03:54:06 -08:00
gerrp ignored;
return moo_editor_load_file(editor, info.get(), window, GTK_WIDGET(window), TRUE, FALSE, ignored);
2007-06-24 12:16:36 -05:00
}
static MooMarkupNode *
save_doc_session (MooEdit *doc,
MooMarkupNode *elm)
{
2008-09-15 03:59:22 -05:00
char *uri;
2007-06-24 12:16:36 -05:00
const char *encoding;
MooMarkupNode *node;
2008-09-15 03:59:22 -05:00
uri = moo_edit_get_uri (doc);
2007-06-24 12:16:36 -05:00
encoding = moo_edit_get_encoding (doc);
2008-09-15 03:59:22 -05:00
if (uri)
2007-06-24 12:16:36 -05:00
{
2008-09-15 03:59:22 -05:00
node = moo_markup_create_text_element (elm, "document", uri);
2007-06-24 12:16:36 -05:00
if (encoding && encoding[0])
moo_markup_set_prop (node, "encoding", encoding);
}
else
{
node = moo_markup_create_element (elm, "document");
}
2008-09-15 03:59:22 -05:00
g_free (uri);
2007-06-24 12:16:36 -05:00
return node;
}
static MooEditWindow *
load_window_session (MooEditor *editor,
2008-09-15 03:59:22 -05:00
MooMarkupNode *elm,
gboolean file_is_uri)
2007-06-24 12:16:36 -05:00
{
MooEditWindow *window;
MooEdit *active_doc = NULL;
MooMarkupNode *node;
window = create_window (editor);
for (node = elm->children; node != NULL; node = node->next)
{
if (MOO_MARKUP_IS_ELEMENT (node))
{
2016-01-04 09:56:33 -08:00
EditPtr doc = load_doc_session (editor, window, node, file_is_uri);
2007-06-24 12:16:36 -05:00
2008-11-06 22:33:06 -06:00
if (doc && moo_markup_bool_prop (node, "active", FALSE))
2016-01-04 10:24:03 -08:00
active_doc = doc.gobj();
2007-06-24 12:16:36 -05:00
}
}
if (active_doc)
moo_edit_window_set_active_doc (window, active_doc);
return window;
}
static MooMarkupNode *
save_window_session (MooEditWindow *window,
MooMarkupNode *elm)
{
MooMarkupNode *node;
MooEdit *active_doc;
2010-11-23 21:54:39 -08:00
MooEditArray *docs;
guint i;
2007-06-24 12:16:36 -05:00
active_doc = moo_edit_window_get_active_doc (window);
2010-11-23 21:54:39 -08:00
docs = moo_edit_window_get_docs (window);
2007-06-24 12:16:36 -05:00
node = moo_markup_create_element (elm, "window");
2010-11-23 21:54:39 -08:00
for (i = 0; i < docs->n_elms; ++i)
2007-06-24 12:16:36 -05:00
{
MooMarkupNode *doc_node;
2010-11-23 21:54:39 -08:00
MooEdit *doc = docs->elms[i];
2007-06-24 12:16:36 -05:00
doc_node = save_doc_session (doc, node);
if (doc_node && doc == active_doc)
moo_markup_set_bool_prop (doc_node, "active", TRUE);
}
2010-11-23 21:54:39 -08:00
moo_edit_array_free (docs);
2007-06-24 12:16:36 -05:00
return node;
}
void
_moo_editor_load_session (MooEditor *editor,
MooMarkupNode *xml)
{
MooMarkupNode *editor_node;
2008-09-15 03:59:22 -05:00
gboolean old_format = FALSE;
2007-06-24 12:16:36 -05:00
g_return_if_fail (MOO_IS_EDITOR (editor));
g_return_if_fail (MOO_MARKUP_IS_ELEMENT (xml));
editor_node = moo_markup_get_element (xml, "editor");
2008-09-15 03:59:22 -05:00
if (editor_node)
{
const char *version = moo_markup_get_prop (editor_node, "version");
if (!version)
old_format = TRUE;
else if (strcmp (version, CURRENT_SESSION_VERSION) != 0)
editor_node = NULL;
}
2007-06-24 12:16:36 -05:00
if (editor_node)
{
MooEditWindow *active_window = NULL;
MooMarkupNode *node;
for (node = editor_node->children; node != NULL; node = node->next)
{
MooEditWindow *window;
if (!MOO_MARKUP_IS_ELEMENT (node))
continue;
2008-09-15 03:59:22 -05:00
window = load_window_session (editor, node, !old_format);
2007-06-24 12:16:36 -05:00
2008-11-06 22:33:06 -06:00
if (window && moo_markup_bool_prop (node, "active", FALSE))
2007-06-24 12:16:36 -05:00
active_window = window;
}
if (active_window)
moo_editor_set_active_window (editor, active_window);
}
}
void
_moo_editor_save_session (MooEditor *editor,
MooMarkupNode *xml)
{
MooMarkupNode *node;
MooEditWindow *active_window;
2010-11-23 21:54:39 -08:00
MooEditWindowArray *windows;
guint i;
2007-06-24 12:16:36 -05:00
g_return_if_fail (MOO_IS_EDITOR (editor));
g_return_if_fail (MOO_MARKUP_IS_ELEMENT (xml));
active_window = moo_editor_get_active_window (editor);
2010-11-23 21:54:39 -08:00
windows = moo_editor_get_windows (editor);
2007-06-24 12:16:36 -05:00
node = moo_markup_create_element (xml, "editor");
2008-09-15 03:59:22 -05:00
moo_markup_set_prop (node, "version", CURRENT_SESSION_VERSION);
2007-06-24 12:16:36 -05:00
2010-11-23 21:54:39 -08:00
for (i = 0; i < windows->n_elms; ++i)
2007-06-24 12:16:36 -05:00
{
2010-11-23 21:54:39 -08:00
MooEditWindow *window = windows->elms[i];
2007-06-24 12:16:36 -05:00
MooMarkupNode *window_node;
window_node = save_window_session (window, node);
if (window_node && window == active_window)
moo_markup_set_bool_prop (window_node, "active", TRUE);
}
2010-11-23 21:54:39 -08:00
moo_edit_window_array_free (windows);
2007-06-24 12:16:36 -05:00
}
/**
* moo_editor_get_windows:
*
* Returns: (transfer full)
*/
2010-11-23 21:54:39 -08:00
MooEditWindowArray *
moo_editor_get_windows (MooEditor *editor)
2005-09-02 23:27:25 +00:00
{
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
2015-12-30 00:12:49 -08:00
MooEditWindowArray* copy = moo_edit_window_array_new ();
MOO_IP_ARRAY_GROW (MooEditWindow*, copy, elms, editor->priv->windows.size());
gsize i = 0;
for (const auto& window: editor->priv->windows)
{
copy->elms[i++] = MOO_EDIT_WINDOW(g_object_ref(window));
2015-12-30 00:12:49 -08:00
}
return copy;
2005-09-02 23:27:25 +00:00
}
/**
* moo_editor_get_docs:
*
* Returns: (transfer full)
*/
2010-11-23 21:54:39 -08:00
MooEditArray *
moo_editor_get_docs (MooEditor *editor)
{
2010-11-23 21:54:39 -08:00
MooEditArray *docs;
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
2010-11-23 21:54:39 -08:00
docs = moo_edit_array_new ();
2015-12-30 00:12:49 -08:00
for (const auto& window: editor->priv->windows)
{
MooEditArray *docs_here = moo_edit_window_get_docs (window);
2010-11-23 21:54:39 -08:00
moo_edit_array_append_array (docs, docs_here);
moo_edit_array_free (docs_here);
}
2010-11-23 21:54:39 -08:00
return docs;
}
2010-12-12 02:29:20 -08:00
/**
* moo_editor_open_files:
*
* @editor:
* @files:
* @parent: (allow-none) (default NULL)
* @error:
*/
gboolean
2011-01-10 02:31:07 -08:00
moo_editor_open_files (MooEditor *editor,
MooOpenInfoArray *files,
GtkWidget *parent,
GError **error)
2005-09-02 23:27:25 +00:00
{
2010-12-12 02:29:20 -08:00
MooEditArray *docs;
gboolean ret;
2005-11-02 15:49:35 +00:00
2010-12-12 02:29:20 -08:00
moo_return_error_if_fail (MOO_IS_EDITOR (editor));
2011-01-10 02:31:07 -08:00
moo_return_error_if_fail (!moo_open_info_array_is_empty (files));
2006-06-01 02:09:07 -05:00
2016-01-19 03:54:06 -08:00
gerrp error_here(error);
docs = _moo_editor_open_files (editor, files, parent, error_here);
2010-12-12 02:29:20 -08:00
ret = !moo_edit_array_is_empty (docs);
2006-06-01 02:09:07 -05:00
2010-12-12 02:29:20 -08:00
moo_assert (moo_edit_array_is_empty (docs) ||
moo_edit_array_get_size (docs) ==
2011-01-10 02:31:07 -08:00
moo_open_info_array_get_size (files));
2006-06-01 02:09:07 -05:00
2010-12-12 02:29:20 -08:00
moo_edit_array_free (docs);
return ret;
2005-09-02 23:27:25 +00:00
}
2010-12-12 02:29:20 -08:00
/**
* moo_editor_new_file:
*
* @editor:
* @info:
* @parent: (allow-none) (default NULL)
* @error:
*/
2006-06-04 22:13:54 -05:00
MooEdit *
2011-01-10 02:31:07 -08:00
moo_editor_new_file (MooEditor *editor,
MooOpenInfo *info,
GtkWidget *parent,
GError **error)
2006-06-04 22:13:54 -05:00
{
2010-12-12 02:29:20 -08:00
MooEdit *doc;
2006-06-04 22:13:54 -05:00
2010-12-12 02:29:20 -08:00
moo_return_error_if_fail_p (MOO_IS_EDITOR (editor));
moo_return_error_if_fail_p (info != nullptr);
2006-08-01 20:18:35 -05:00
std::unique_ptr<MooOpenInfo> info_copy (moo_open_info_dup (info));
info_copy->flags |= MOO_OPEN_FLAG_CREATE_NEW;
2006-06-04 22:13:54 -05:00
doc = moo_editor_open_file (editor, info_copy.get (), parent, error);
2006-08-01 20:18:35 -05:00
2006-06-04 22:13:54 -05:00
return doc;
}
2010-12-12 02:29:20 -08:00
/**
* moo_editor_open_file:
*
* @editor:
* @info:
* @parent: (allow-none) (default NULL)
* @error:
*/
MooEdit *
2011-01-10 02:31:07 -08:00
moo_editor_open_file (MooEditor *editor,
MooOpenInfo *info,
GtkWidget *parent,
GError **error)
{
2010-12-12 02:29:20 -08:00
MooEditArray *docs;
2011-01-10 02:31:07 -08:00
MooOpenInfoArray *files;
2010-12-12 02:29:20 -08:00
MooEdit *ret = NULL;
2010-12-12 02:29:20 -08:00
moo_return_error_if_fail_p (info != NULL);
2011-01-10 02:31:07 -08:00
files = moo_open_info_array_new ();
moo_open_info_array_append (files, info);
2016-01-19 03:54:06 -08:00
gerrp error_here(error);
docs = _moo_editor_open_files (editor, files, parent, error_here);
2011-01-10 02:31:07 -08:00
moo_open_info_array_free (files);
2010-12-12 02:29:20 -08:00
if (docs)
{
2010-12-12 02:29:20 -08:00
moo_release_assert (docs->n_elms > 0);
ret = docs->elms[0];
}
2010-12-12 02:29:20 -08:00
moo_edit_array_free (docs);
return ret;
}
2010-12-12 02:29:20 -08:00
/**
2011-01-25 01:55:18 -08:00
* moo_editor_open_uri: (moo-kwargs)
2010-12-12 02:29:20 -08:00
*
* @editor:
* @uri: (type const-utf8)
* @encoding: (type const-utf8) (allow-none) (default NULL)
2010-12-12 02:29:20 -08:00
* @line: (default -1)
* @window: (allow-none) (default NULL)
*/
2006-06-01 02:09:07 -05:00
MooEdit *
2010-12-12 02:29:20 -08:00
moo_editor_open_uri (MooEditor *editor,
const char *uri,
const char *encoding,
int line,
MooEditWindow *window)
{
std::unique_ptr<MooOpenInfo> info (moo_open_info_new_uri (uri, encoding, line, MOO_OPEN_FLAGS_NONE));
return moo_editor_open_file (editor, info.get(), window ? GTK_WIDGET (window) : NULL, NULL);
}
2010-12-12 02:29:20 -08:00
/**
2011-01-25 01:55:18 -08:00
* moo_editor_open_path: (moo-kwargs)
2010-12-12 02:29:20 -08:00
*
* @editor:
* @path: (type const-filename)
* @encoding: (type const-utf8) (allow-none) (default NULL)
2010-12-12 02:29:20 -08:00
* @line: (default -1)
* @window: (allow-none) (default NULL)
*/
2006-06-01 02:09:07 -05:00
MooEdit *
2010-12-12 02:29:20 -08:00
moo_editor_open_path (MooEditor *editor,
const char *path,
const char *encoding,
int line,
MooEditWindow *window)
{
std::unique_ptr<MooOpenInfo> info (moo_open_info_new (path, encoding, line, MOO_OPEN_FLAGS_NONE));
return moo_editor_open_file (editor, info.get(), window ? GTK_WIDGET (window) : NULL, NULL);
2010-12-12 02:29:20 -08:00
}
2010-12-12 02:29:20 -08:00
// MooEdit *
// moo_editor_open_file (MooEditor *editor,
// MooEditWindow *window,
// GtkWidget *parent,
// const char *filename,
// const char *encoding)
// {
// gboolean result;
//
// g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
// g_return_val_if_fail (!window || MOO_IS_EDIT_WINDOW (window), NULL);
// g_return_val_if_fail (!parent || GTK_IS_WIDGET (parent), NULL);
//
// if (!filename)
// {
// result = moo_editor_open (editor, window, parent, NULL);
// }
// else
// {
// MooFileEncArray *list;
//
// list = moo_file_enc_array_new ();
// moo_file_enc_array_take (list, moo_file_enc_new_for_path (filename, encoding));
//
// result = moo_editor_open (editor, window, parent, list);
//
// moo_file_enc_array_free (list);
// }
//
// if (!result)
// return NULL;
//
// return moo_editor_get_doc (editor, filename);
2010-12-12 02:29:20 -08:00
// }
// MooEdit *
// moo_editor_open_file_line (MooEditor *editor,
// const char *filename,
// int line,
// MooEditWindow *window)
// {
// MooEdit *doc = NULL;
// char *freeme = NULL;
// MooFileEnc *fenc = NULL;
//
// g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
// g_return_val_if_fail (filename != NULL, NULL);
//
// doc = moo_editor_get_doc (editor, filename);
2010-12-12 02:29:20 -08:00
//
// if (doc)
// {
// if (line >= 0)
// moo_text_view_move_cursor (MOO_TEXT_VIEW (doc), line, 0, FALSE, FALSE);
// moo_editor_set_active_doc (editor, doc);
// gtk_widget_grab_focus (GTK_WIDGET (doc));
// return doc;
// }
//
// freeme = _moo_normalize_file_path (filename);
// filename = freeme;
//
// if (!g_file_test (filename, G_FILE_TEST_EXISTS))
// goto out;
//
// fenc = moo_file_enc_new_for_path (filename, NULL);
// moo_editor_load_file (editor, window, NULL, fenc,
2016-01-01 22:25:53 -08:00
// FALSE, TRUE, line, &doc);
2010-12-12 02:29:20 -08:00
//
// /* XXX */
// moo_editor_set_active_doc (editor, doc);
// if (line >= 0)
// moo_text_view_move_cursor (MOO_TEXT_VIEW (doc), line, 0, FALSE, TRUE);
// gtk_widget_grab_focus (GTK_WIDGET (doc));
//
// out:
// moo_file_enc_free (fenc);
// g_free (freeme);
// return doc;
// }
// static MooEdit *
// moo_editor_new_uri (MooEditor *editor,
// MooEditWindow *window,
// GtkWidget *parent,
// const char *uri,
// const char *encoding)
// {
// MooEdit *doc = NULL;
// char *path;
// GFile *file;
//
// g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
// g_return_val_if_fail (!window || MOO_IS_EDIT_WINDOW (window), NULL);
// g_return_val_if_fail (!parent || GTK_IS_WIDGET (parent), NULL);
//
// if (!uri)
// return moo_editor_open_uri (editor, window, parent, NULL, NULL);
//
// file = g_file_new_for_uri (uri);
// path = g_file_get_path (file);
//
// if (path && g_file_test (path, G_FILE_TEST_EXISTS))
// {
// g_free (path);
// g_object_unref (file);
// return moo_editor_open_uri (editor, window, parent,
// uri, encoding);
// }
//
// if (!window)
// window = moo_editor_get_active_window (editor);
//
// if (window)
// {
// doc = moo_edit_window_get_active_doc (window);
//
// if (!doc || !moo_edit_is_empty (doc))
// doc = NULL;
// }
//
// if (!doc)
// doc = moo_editor_new_doc (editor, window);
//
// _moo_edit_set_status (doc, MOO_EDIT_STATUS_NEW);
2010-12-12 02:29:20 -08:00
// _moo_edit_set_file (doc, file, encoding);
// moo_editor_set_active_doc (editor, doc);
// gtk_widget_grab_focus (GTK_WIDGET (doc));
//
// g_free (path);
// g_object_unref (file);
// return doc;
// }
// MooEdit *
// moo_editor_new_file (MooEditor *editor,
// MooEditWindow *window,
// GtkWidget *parent,
// const char *filename,
// const char *encoding)
// {
// MooEdit *doc = NULL;
// char *freeme = NULL;
// GFile *file;
//
// g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
// g_return_val_if_fail (!window || MOO_IS_EDIT_WINDOW (window), NULL);
// g_return_val_if_fail (!parent || GTK_IS_WIDGET (parent), NULL);
//
// if (!filename)
// return moo_editor_open_file (editor, window, parent, NULL, NULL);
//
// if (g_file_test (filename, G_FILE_TEST_EXISTS))
// return moo_editor_open_file (editor, window, parent,
// filename, encoding);
//
// freeme = _moo_normalize_file_path (filename);
// filename = freeme;
//
// if (!window)
// window = moo_editor_get_active_window (editor);
//
// if (window)
// {
// doc = moo_edit_window_get_active_doc (window);
//
// if (!doc || !moo_edit_is_empty (doc))
// doc = NULL;
// }
//
// if (!doc)
// doc = moo_editor_new_doc (editor, window);
//
// _moo_edit_set_status (doc, MOO_EDIT_STATUS_NEW);
2010-12-12 02:29:20 -08:00
// file = g_file_new_for_path (filename);
// _moo_edit_set_file (doc, file, encoding);
// moo_editor_set_active_doc (editor, doc);
// gtk_widget_grab_focus (GTK_WIDGET (doc));
//
// g_object_unref (file);
// g_free (freeme);
// return doc;
// }
//
//
// MooEdit *
// moo_editor_open_uri (MooEditor *editor,
// MooEditWindow *window,
// GtkWidget *parent,
// const char *uri,
// const char *encoding)
// {
// char *filename;
// MooEdit *doc;
//
// g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
// g_return_val_if_fail (!window || MOO_IS_EDIT_WINDOW (window), NULL);
// g_return_val_if_fail (!parent || GTK_IS_WIDGET (parent), NULL);
// g_return_val_if_fail (uri != NULL, NULL);
//
// filename = g_filename_from_uri (uri, NULL, NULL);
// g_return_val_if_fail (filename != NULL, NULL);
//
// doc = moo_editor_open_file (editor, window, parent, filename, encoding);
//
// g_free (filename);
// return doc;
// }
2010-12-12 02:29:20 -08:00
/**
* moo_editor_reload:
2011-01-23 12:28:12 -08:00
*
* @editor:
* @doc:
* @info: (allow-none) (default NULL)
* @error:
2010-12-12 02:29:20 -08:00
**/
2010-12-09 00:51:40 -08:00
gboolean
2011-01-10 02:31:07 -08:00
moo_editor_reload (MooEditor *editor,
MooEdit *doc,
MooReloadInfo *info,
2016-01-19 03:54:06 -08:00
GError **errorp)
2005-09-02 23:27:25 +00:00
{
2011-01-17 03:01:11 -08:00
guint i;
2016-01-19 03:54:06 -08:00
gerrp error(errorp);
2011-01-25 03:17:10 -08:00
MooEditViewArray *views = NULL;
gboolean ret = FALSE;
2005-09-02 23:27:25 +00:00
2010-12-09 00:51:40 -08:00
moo_return_error_if_fail (MOO_IS_EDITOR (editor));
2005-09-02 23:27:25 +00:00
2016-01-04 09:56:33 -08:00
if (Edit(*doc)._is_busy())
2010-12-09 00:51:40 -08:00
{
2016-01-19 03:54:06 -08:00
g_set_error (&error,
2010-12-09 00:51:40 -08:00
MOO_EDIT_RELOAD_ERROR,
MOO_EDIT_RELOAD_ERROR_BUSY,
"document is busy");
2011-01-25 03:17:10 -08:00
goto out;
2010-12-09 00:51:40 -08:00
}
2006-06-30 00:58:35 -05:00
2010-12-09 00:51:40 -08:00
if (moo_edit_is_untitled (doc))
{
2016-01-19 03:54:06 -08:00
g_set_error (&error,
2010-12-09 00:51:40 -08:00
MOO_EDIT_RELOAD_ERROR,
MOO_EDIT_RELOAD_ERROR_UNTITLED,
"document is untitled");
2011-01-25 03:17:10 -08:00
goto out;
2010-12-09 00:51:40 -08:00
}
2005-09-02 23:27:25 +00:00
2016-01-01 22:25:53 -08:00
if (!moo_edit_get_clean (doc) &&
moo_edit_is_modified (doc) &&
2008-08-28 19:23:10 -05:00
!_moo_edit_reload_modified_dialog (doc))
2010-12-09 00:51:40 -08:00
{
2016-01-19 03:54:06 -08:00
g_set_error (&error,
2010-12-09 00:51:40 -08:00
MOO_EDIT_RELOAD_ERROR,
MOO_EDIT_RELOAD_ERROR_CANCELLED,
"cancelled by user");
2011-01-25 03:17:10 -08:00
goto out;
2010-12-09 00:51:40 -08:00
}
2005-09-02 23:27:25 +00:00
2011-01-17 03:01:11 -08:00
views = moo_edit_get_views (doc);
2005-11-10 07:15:16 +00:00
2011-01-17 03:01:11 -08:00
for (i = 0; i < moo_edit_view_array_get_size (views); ++i)
2010-12-12 02:29:20 -08:00
{
2011-01-17 03:01:11 -08:00
int cursor_line, cursor_offset;
GtkTextIter iter;
MooEditView *view = views->elms[i];
moo_text_view_get_cursor (GTK_TEXT_VIEW (view), &iter);
cursor_line = gtk_text_iter_get_line (&iter);
cursor_offset = moo_text_iter_get_visual_line_offset (&iter, 8);
if (info != NULL && info->line >= 0 && info->line != cursor_line)
{
cursor_line = info->line;
cursor_offset = 0;
}
g_object_set_data (G_OBJECT (view), "moo-reload-cursor-line", GINT_TO_POINTER (cursor_line));
g_object_set_data (G_OBJECT (view), "moo-reload-cursor-offset", GINT_TO_POINTER (cursor_offset));
2010-12-12 02:29:20 -08:00
}
2016-01-19 03:54:06 -08:00
if (!_moo_edit_reload_file(*doc, info ? (const char*) info->encoding : nullptr, error))
2005-09-02 23:27:25 +00:00
{
2016-01-19 03:54:06 -08:00
if (!_moo_is_file_error_cancelled (error))
_moo_edit_reload_error_dialog (doc, error.get());
2005-11-10 07:15:16 +00:00
g_object_set_data (G_OBJECT (doc), "moo-scroll-to", NULL);
2011-01-25 03:17:10 -08:00
goto out;
2005-09-02 23:27:25 +00:00
}
2005-11-10 07:15:16 +00:00
2011-01-17 03:01:11 -08:00
for (i = 0; i < moo_edit_view_array_get_size (views); ++i)
{
int cursor_line, cursor_offset;
MooEditView *view = views->elms[i];
cursor_line = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view), "moo-reload-cursor-line"));
cursor_offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view), "moo-reload-cursor-offset"));
moo_text_view_move_cursor (MOO_TEXT_VIEW (view), cursor_line,
cursor_offset, TRUE, TRUE);
2011-01-17 03:01:11 -08:00
}
2011-01-25 03:17:10 -08:00
ret = TRUE;
out:
moo_edit_view_array_free (views);
return ret;
2005-11-10 07:15:16 +00:00
}
static MooSaveResponse
moo_editor_before_save (G_GNUC_UNUSED MooEditor *editor,
G_GNUC_UNUSED MooEdit *doc,
G_GNUC_UNUSED GFile *file)
{
return MOO_SAVE_RESPONSE_CONTINUE;
}
2005-11-10 07:15:16 +00:00
static MooEditSaveFlags
moo_editor_get_save_flags (MooEditor *editor)
{
2015-07-15 02:22:11 -07:00
MooEditSaveFlags flags = MOO_EDIT_SAVE_FLAGS_NONE;
2005-11-10 07:15:16 +00:00
2008-08-28 19:23:10 -05:00
if (test_flag (editor, SAVE_BACKUPS))
2005-11-10 07:15:16 +00:00
flags |= MOO_EDIT_SAVE_BACKUP;
return flags;
2005-09-02 23:27:25 +00:00
}
static void
moo_editor_will_save (G_GNUC_UNUSED MooEditor *editor,
MooEdit *doc,
G_GNUC_UNUSED GFile *file)
{
2016-01-04 03:56:42 -08:00
g_return_if_fail(doc != nullptr);
if (moo_edit_config_get_bool (doc->config, "strip"))
2016-01-04 09:56:33 -08:00
Edit(*doc)._strip_whitespace();
if (moo_edit_config_get_bool (doc->config, "add-newline"))
2016-01-04 09:56:33 -08:00
Edit(*doc)._ensure_newline();
}
2016-01-04 03:56:42 -08:00
static bool
2016-01-19 03:54:06 -08:00
do_save(MooEditor& editor,
Edit doc,
g::File file,
const char* encoding,
gerrp& error)
2005-11-11 20:05:33 +00:00
{
int response = MOO_SAVE_RESPONSE_CONTINUE;
2016-01-19 03:54:06 -08:00
gerrp error_here;
gboolean result;
2010-09-30 03:42:40 -07:00
2016-01-04 03:56:42 -08:00
g_signal_emit(&editor, signals[BEFORE_SAVE], 0, doc, file, &response);
2010-12-12 02:29:20 -08:00
if (response != MOO_SAVE_RESPONSE_CANCEL)
2016-01-04 03:56:42 -08:00
doc.signal_emit_by_name("before-save", file, &response);
if (response == MOO_SAVE_RESPONSE_CANCEL)
{
2016-01-19 03:54:06 -08:00
g_set_error(&error,
2016-01-04 03:56:42 -08:00
MOO_EDIT_SAVE_ERROR,
MOO_EDIT_SAVE_ERROR_CANCELLED,
"cancelled");
2010-09-30 03:42:40 -07:00
return FALSE;
}
2005-11-11 20:05:33 +00:00
2016-01-04 03:56:42 -08:00
g_signal_emit(&editor, signals[WILL_SAVE], 0, doc, file);
doc.signal_emit_by_name("will-save", file);
2005-11-11 20:05:33 +00:00
2016-01-04 03:56:42 -08:00
result = _moo_edit_save_file(doc, file, encoding,
moo_editor_get_save_flags(&editor),
2016-01-19 03:54:06 -08:00
error_here);
if (!result && error_here->domain == MOO_EDIT_FILE_ERROR &&
error_here->code == MOO_EDIT_FILE_ERROR_ENCODING)
2010-09-30 03:42:40 -07:00
{
2016-01-19 03:54:06 -08:00
error_here.clear();
2016-01-04 03:56:42 -08:00
if (_moo_edit_save_error_enc_dialog(doc, file, encoding))
2010-09-30 03:42:40 -07:00
{
2016-01-04 03:56:42 -08:00
result = _moo_edit_save_file(doc, file, "UTF-8",
moo_editor_get_save_flags(&editor),
2016-01-19 03:54:06 -08:00
error_here);
2010-09-30 03:42:40 -07:00
}
else
{
2016-01-19 03:54:06 -08:00
g_set_error(&error,
2016-01-04 03:56:42 -08:00
MOO_EDIT_SAVE_ERROR,
MOO_EDIT_SAVE_ERROR_CANCELLED,
"cancelled");
return FALSE;
2010-09-30 03:42:40 -07:00
}
}
if (!result)
{
2016-01-19 03:54:06 -08:00
_moo_edit_save_error_dialog(doc, file, error_here.get());
error = std::move(error_here);
2010-09-30 03:42:40 -07:00
return FALSE;
}
2016-01-04 03:56:42 -08:00
update_history_item_for_doc(&editor, &doc, TRUE);
2010-09-30 03:42:40 -07:00
2016-01-04 03:56:42 -08:00
doc.signal_emit_by_name("after-save");
g_signal_emit(&editor, signals[AFTER_SAVE], 0, doc);
2010-12-12 02:29:20 -08:00
2016-01-04 03:56:42 -08:00
return true;
2005-11-11 20:05:33 +00:00
}
2010-12-12 02:29:20 -08:00
/**
* moo_editor_save:
**/
2005-09-08 17:08:31 +00:00
gboolean
2010-12-12 02:29:20 -08:00
moo_editor_save (MooEditor *editor,
MooEdit *doc,
GError **error)
2005-09-02 23:27:25 +00:00
{
2010-12-12 02:29:20 -08:00
moo_return_error_if_fail (MOO_IS_EDITOR (editor));
moo_return_error_if_fail (MOO_IS_EDIT (doc));
2005-09-02 23:27:25 +00:00
2016-01-04 09:56:33 -08:00
if (Edit(*doc)._is_busy())
2010-12-12 02:29:20 -08:00
{
g_set_error (error,
MOO_EDIT_SAVE_ERROR,
MOO_EDIT_SAVE_ERROR_BUSY,
"document is busy");
2006-06-30 00:58:35 -05:00
return FALSE;
2010-12-12 02:29:20 -08:00
}
2006-06-30 00:58:35 -05:00
if (moo_edit_is_untitled (doc))
2010-12-12 02:29:20 -08:00
return moo_editor_save_as (editor, doc, NULL, error);
2005-09-02 23:27:25 +00:00
2016-01-04 09:56:33 -08:00
g::FilePtr file = wrap_new(moo_edit_get_file(doc));
2016-01-21 03:16:33 -08:00
gstr encoding = gstr::wrap(moo_edit_get_encoding(doc));
2016-01-01 22:25:53 -08:00
if ((moo_edit_get_status (doc) & MOO_EDIT_STATUS_MODIFIED_ON_DISK) &&
2008-08-28 19:23:10 -05:00
!_moo_edit_overwrite_modified_dialog (doc))
2010-12-12 02:29:20 -08:00
{
g_set_error (error,
MOO_EDIT_SAVE_ERROR,
MOO_EDIT_SAVE_ERROR_CANCELLED,
"cancelled by user");
2016-01-19 03:54:06 -08:00
return false;
2010-12-12 02:29:20 -08:00
}
2016-01-19 03:54:06 -08:00
gerrp error_here(error);
return do_save(*editor, *doc, *file, encoding, error_here);
2005-09-02 23:27:25 +00:00
}
2010-12-12 02:29:20 -08:00
/**
* moo_editor_save_as:
*
* @editor:
* @doc:
* @info: (allow-none) (default NULL)
* @error:
*
* Save document with new filename and/or encoding. If @info is
* missing or %NULL then user is asked for new filename first.
2010-12-12 02:29:20 -08:00
**/
2005-09-08 17:08:31 +00:00
gboolean
2011-01-10 02:31:07 -08:00
moo_editor_save_as (MooEditor *editor,
MooEdit *doc,
2016-01-04 03:56:42 -08:00
MooSaveInfo *info_init,
2011-01-10 02:31:07 -08:00
GError **error)
2005-09-02 23:27:25 +00:00
{
2010-12-12 02:29:20 -08:00
moo_return_error_if_fail (MOO_IS_EDITOR (editor));
moo_return_error_if_fail (MOO_IS_EDIT (doc));
2016-01-04 03:56:42 -08:00
moo_return_error_if_fail (!info_init || !info_init->file);
2005-09-02 23:27:25 +00:00
2016-01-04 09:56:33 -08:00
if (Edit(*doc)._is_busy())
2010-12-12 02:29:20 -08:00
{
g_set_error (error,
MOO_EDIT_SAVE_ERROR,
MOO_EDIT_SAVE_ERROR_BUSY,
"document is busy");
2016-01-04 03:56:42 -08:00
return false;
2010-12-12 02:29:20 -08:00
}
2006-06-30 00:58:35 -05:00
std::unique_ptr<MooSaveInfo> info (info_init ? moo_save_info_dup (info_init) : nullptr);
2016-01-04 03:56:42 -08:00
2010-12-12 02:29:20 -08:00
if (!info)
2005-09-02 23:27:25 +00:00
{
info.reset(_moo_edit_save_as_dialog(doc, moo_edit_get_display_basename(doc)));
2005-09-02 23:27:25 +00:00
2016-01-04 03:56:42 -08:00
if (!info)
2010-12-12 02:29:20 -08:00
{
g_set_error (error,
MOO_EDIT_SAVE_ERROR,
MOO_EDIT_SAVE_ERROR_CANCELLED,
"cancelled by user");
2016-01-04 03:56:42 -08:00
return false;
2010-12-12 02:29:20 -08:00
}
}
else if (info->encoding.empty())
{
info.reset(moo_save_info_new_file(info->file.gobj(), moo_edit_get_encoding(doc)));
2005-09-02 23:27:25 +00:00
}
2016-01-04 03:56:42 -08:00
update_history_item_for_doc(editor, doc, FALSE);
2016-01-19 03:54:06 -08:00
gerrp error_here(error);
return do_save(*editor, *doc, *info->file, info->encoding, error_here);
2005-09-02 23:27:25 +00:00
}
2010-12-12 02:29:20 -08:00
/**
* moo_editor_save_copy:
**/
2005-11-02 04:41:09 +00:00
gboolean
2011-01-10 02:31:07 -08:00
moo_editor_save_copy (MooEditor *editor,
MooEdit *doc,
MooSaveInfo *info,
GError **error)
2005-11-02 04:41:09 +00:00
{
2010-12-12 02:29:20 -08:00
moo_return_error_if_fail (MOO_IS_EDITOR (editor));
moo_return_error_if_fail (MOO_IS_EDIT (doc));
2016-01-04 03:56:42 -08:00
moo_return_error_if_fail (info != nullptr && info->file != nullptr);
2008-09-15 03:59:22 -05:00
2016-01-19 03:54:06 -08:00
gerrp error_here(error);
return _moo_edit_save_file_copy (*doc, *info->file,
!info->encoding.empty() ? info->encoding : moo_edit_get_encoding (doc),
moo_editor_get_save_flags (editor),
error_here);
2005-07-30 22:15:13 +00:00
}
2005-09-08 17:08:31 +00:00
2010-12-12 02:29:20 -08:00
2008-09-15 00:44:03 -05:00
static MooEdit *
2010-12-12 02:29:20 -08:00
doc_array_find_norm_name (MooEditArray *docs,
const char *norm_name)
2005-09-08 17:08:31 +00:00
{
2010-11-23 21:54:39 -08:00
guint i;
g_return_val_if_fail (docs != NULL, NULL);
g_return_val_if_fail (norm_name != NULL, NULL);
2010-12-12 02:29:20 -08:00
2010-11-23 21:54:39 -08:00
for (i = 0; i < docs->n_elms; ++i)
2008-09-15 00:44:03 -05:00
{
2016-01-04 09:56:33 -08:00
Edit doc = *docs->elms[i];
2016-01-04 03:56:42 -08:00
const gstr& doc_norm_name = doc._get_normalized_name();
2016-01-03 05:13:00 -08:00
if (doc_norm_name == norm_name)
2016-01-04 03:56:42 -08:00
return &doc;
2008-09-15 00:44:03 -05:00
}
2010-11-23 21:54:39 -08:00
2008-09-15 00:44:03 -05:00
return NULL;
}
2016-01-02 13:51:52 -08:00
// static MooEdit *
2016-01-04 09:56:33 -08:00
// doc_array_find_norm_name (const std::vector<gobj_ptr<MooEdit>>& docs,
2016-01-02 13:51:52 -08:00
// const char *norm_name)
// {
// g_return_val_if_fail (norm_name != NULL, NULL);
//
// for (const auto& doc: docs)
// {
2016-01-04 10:24:03 -08:00
// char *doc_norm_name = _moo_edit_get_normalized_name (doc.gobj());
2016-01-02 13:51:52 -08:00
// gboolean this_doc = doc_norm_name != NULL && strcmp (doc_norm_name, norm_name) == 0;
// g_free (doc_norm_name);
// if (this_doc)
2016-01-04 10:24:03 -08:00
// return doc.gobj();
2016-01-02 13:51:52 -08:00
// }
//
// return NULL;
// }
2015-12-30 00:12:49 -08:00
/**
* moo_editor_get_doc_for_file:
*
* Finds open document by #GFile.
*/
2008-09-15 00:44:03 -05:00
MooEdit *
moo_editor_get_doc_for_file (MooEditor *editor,
GFile *file)
2008-09-15 00:44:03 -05:00
{
2005-09-08 17:08:31 +00:00
MooEdit *doc = NULL;
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
2005-09-08 17:08:31 +00:00
2016-01-04 09:56:33 -08:00
gstr norm_name = Edit::_get_normalized_name (*file);
2016-01-04 03:56:42 -08:00
g_return_val_if_fail (!norm_name.empty(), NULL);
2006-06-01 02:09:07 -05:00
2015-12-30 00:12:49 -08:00
for (const auto& window: editor->priv->windows)
2008-09-15 00:44:03 -05:00
{
MooEditArray *docs = moo_edit_window_get_docs (window);
2010-12-12 02:29:20 -08:00
doc = doc_array_find_norm_name (docs, norm_name);
2010-11-23 21:54:39 -08:00
moo_edit_array_free (docs);
2016-01-01 22:25:53 -08:00
if (doc != nullptr)
break;
2008-09-15 00:44:03 -05:00
}
2005-09-08 17:08:31 +00:00
return doc;
}
2010-12-12 02:29:20 -08:00
/**
* moo_editor_get_doc:
*
* @editor:
* @filename: (type const-filename)
*
* Finds open document by filename.
2010-12-12 02:29:20 -08:00
*/
MooEdit *
moo_editor_get_doc (MooEditor *editor,
const char *filename)
2008-09-15 03:59:22 -05:00
{
2010-12-12 02:29:20 -08:00
GFile *file;
MooEdit *doc;
2010-11-23 21:54:39 -08:00
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
g_return_val_if_fail (filename != NULL, NULL);
2010-11-23 21:54:39 -08:00
file = g_file_new_for_path (filename);
doc = moo_editor_get_doc_for_file (editor, file);
2010-12-12 02:29:20 -08:00
g_object_unref (file);
return doc;
2008-09-15 03:59:22 -05:00
}
/**
* moo_editor_get_doc_for_uri:
*
* @editor:
* @uri: (type const-utf8)
*
* Finds open document by URI.
*/
2008-09-15 03:59:22 -05:00
MooEdit *
moo_editor_get_doc_for_uri (MooEditor *editor,
const char *uri)
{
2010-12-12 02:29:20 -08:00
GFile *file;
MooEdit *doc;
2008-09-15 03:59:22 -05:00
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
g_return_val_if_fail (uri != NULL, NULL);
2010-04-11 18:49:15 -07:00
2010-12-12 02:29:20 -08:00
file = g_file_new_for_uri (uri);
doc = moo_editor_get_doc_for_file (editor, file);
2008-09-15 03:59:22 -05:00
2010-12-12 02:29:20 -08:00
g_object_unref (file);
2010-04-11 18:49:15 -07:00
return doc;
2008-09-15 03:59:22 -05:00
}
/**
2010-12-21 03:03:17 -08:00
* moo_editor_set_window_type: (moo.lua 0)
*/
2005-11-02 02:32:07 +00:00
void
moo_editor_set_window_type (MooEditor *editor,
GType type)
{
g_return_if_fail (MOO_IS_EDITOR (editor));
g_return_if_fail (g_type_is_a (type, MOO_TYPE_EDIT_WINDOW));
editor->priv->window_type = type;
}
/**
2010-12-21 03:03:17 -08:00
* moo_editor_set_doc_type: (moo.lua 0)
*/
2005-11-02 02:32:07 +00:00
void
moo_editor_set_doc_type (MooEditor *editor,
GType type)
2005-11-02 02:32:07 +00:00
{
g_return_if_fail (MOO_IS_EDITOR (editor));
g_return_if_fail (g_type_is_a (type, MOO_TYPE_EDIT));
editor->priv->doc_type = type;
}
2005-11-02 15:49:35 +00:00
void
2010-12-12 02:29:20 -08:00
_moo_editor_apply_prefs (MooEditor *editor)
{
2008-09-08 02:17:32 -05:00
gboolean backups;
2010-12-19 00:16:30 -08:00
const char *color_scheme;
2007-09-05 18:20:01 -05:00
_moo_edit_window_update_title ();
_moo_edit_window_set_use_tabs ();
2007-09-05 18:20:01 -05:00
_moo_edit_update_global_config ();
2010-12-19 02:26:03 -08:00
_moo_edit_queue_recheck_config_all ();
color_scheme = moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_COLOR_SCHEME));
if (color_scheme)
2016-01-04 10:24:03 -08:00
_moo_lang_mgr_set_active_scheme (editor->priv->lang_mgr.gobj(), color_scheme);
backups = moo_prefs_get_bool (moo_edit_setting (MOO_EDIT_PREFS_MAKE_BACKUPS));
g_object_set (editor,
"save-backups", backups,
NULL);
}
2010-12-12 02:29:20 -08:00
// void
// _moo_editor_open_uri (MooEditor *editor,
// const char *uri,
// const char *encoding,
// guint line,
// guint options)
// {
// MooEdit *doc;
// MooEditWindow *window;
//
// g_return_if_fail (MOO_IS_EDITOR (editor));
// g_return_if_fail (uri != NULL);
//
// doc = moo_editor_get_doc_for_uri (editor, uri);
//
// if (doc)
// {
// if (line > 0)
// moo_text_view_move_cursor (MOO_TEXT_VIEW (doc), line - 1, 0, FALSE, FALSE);
// moo_editor_set_active_doc (editor, doc);
// gtk_widget_grab_focus (GTK_WIDGET (doc));
//
// if (options & MOO_OPEN_RELOAD)
2010-12-12 02:29:20 -08:00
// _moo_editor_reload (editor, doc, NULL, NULL);
//
// return;
// }
//
// window = moo_editor_get_active_window (editor);
// doc = window ? moo_edit_window_get_active_doc (window) : NULL;
//
// if (!doc || !moo_edit_is_empty (doc))
// {
// gboolean new_window = moo_prefs_get_bool (moo_edit_setting (MOO_EDIT_PREFS_OPEN_NEW_WINDOW));
//
// if (options & MOO_OPEN_NEW_TAB)
2010-12-12 02:29:20 -08:00
// new_window = FALSE;
// else if (options & MOO_OPEN_NEW_WINDOW)
2010-12-12 02:29:20 -08:00
// new_window = TRUE;
//
// if (new_window)
// window = moo_editor_new_window (editor);
// }
//
// doc = moo_editor_new_uri (editor, window, NULL, uri, encoding);
// g_return_if_fail (doc != NULL);
//
// moo_editor_set_active_doc (editor, doc);
// if (line > 0)
// moo_text_view_move_cursor (MOO_TEXT_VIEW (doc), line - 1, 0, FALSE, TRUE);
// gtk_widget_grab_focus (GTK_WIDGET (doc));
//
// if (options & MOO_OPEN_RELOAD)
2010-12-12 02:29:20 -08:00
// _moo_editor_reload (editor, doc, NULL, NULL);
// }