Session support

master
Yevgen Muntyan 2007-06-24 12:16:36 -05:00
parent 4574ecaf38
commit 7c890cb0ea
9 changed files with 686 additions and 148 deletions

View File

@ -73,6 +73,9 @@ int _medit_parse_options (const char *const program_name,
#define STR_HELP_NEW_APP "\
-n, --new-app Run new instance of application\n"
#define STR_HELP_USE_SESSION "\
-s, --use-session Load and save session\n"
#define STR_HELP_PID "\
--pid=PID Use existing instance with process id PID\n"
@ -105,6 +108,7 @@ int _medit_parse_options (const char *const program_name,
#define STR_HELP "\
-n, --new-app Run new instance of application\n\
-s, --use-session Load and save session\n\
--pid=PID Use existing instance with process id PID\n\
-m, --mode=[simple|project] Use specified mode\n\
-p, --project=PROJECT Open project file PROJECT\n\
@ -119,6 +123,9 @@ int _medit_parse_options (const char *const program_name,
/* Set to 1 if option --new-app (-n) has been specified. */
char _medit_opt_new_app;
/* Set to 1 if option --use-session (-s) has been specified. */
char _medit_opt_use_session;
/* Set to 1 if option --pid has been specified. */
char _medit_opt_pid;
@ -175,6 +182,7 @@ const char *_medit_arg_exec_file;
int _medit_parse_options (const char *const program_name, const int argc, char **const argv)
{
static const char *const optstr__new_app = "new-app";
static const char *const optstr__use_session = "use-session";
static const char *const optstr__pid = "pid";
static const char *const optstr__mode = "mode";
static const char *const optstr__project = "project";
@ -186,6 +194,7 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
static const char *const optstr__help = "help";
int i = 0;
_medit_opt_new_app = 0;
_medit_opt_use_session = 0;
_medit_opt_pid = 0;
_medit_opt_mode = 0;
_medit_opt_project = 0;
@ -371,6 +380,18 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
break;
}
goto error_unknown_long_opt;
case 'u':
if (strncmp (option + 1, optstr__use_session + 1, option_len - 1) == 0)
{
if (argument != 0)
{
option = optstr__use_session;
goto error_unexpec_arg_long;
}
_medit_opt_use_session = 1;
break;
}
goto error_unknown_long_opt;
case 'v':
if (strncmp (option + 1, optstr__version + 1, option_len - 1) == 0)
{
@ -438,6 +459,9 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
option = "\0";
_medit_opt_project = 1;
break;
case 's':
_medit_opt_use_session = 1;
break;
default:
fprintf (stderr, STR_ERR_UNKNOWN_SHORT_OPT, program_name, *option);
return -1;
@ -449,7 +473,7 @@ int _medit_parse_options (const char *const program_name, const int argc, char *
}
return i;
}
#line 135 "../../../medit/medit-app.opag"
#line 63 "../../../medit/medit-app.opag"
#undef STR_HELP
#define STR_HELP \
@ -542,6 +566,28 @@ push_appdir_to_path (void)
#endif
}
static void
project_mode (void)
{
MooPlugin *plugin;
plugin = moo_plugin_lookup ("ProjectManager");
if (!plugin)
{
g_printerr ("Could not initialize project manager plugin\n");
exit (1);
}
if (_medit_arg_project && *_medit_arg_project)
{
char *project = moo_filename_from_locale (_medit_arg_project);
g_object_set (plugin, "project", _medit_arg_project, NULL);
g_free (project);
}
moo_plugin_set_enabled (plugin, TRUE);
}
int
main (int argc, char *argv[])
@ -550,7 +596,6 @@ main (int argc, char *argv[])
int opt_remain;
MooEditor *editor;
char **files;
gpointer window;
int retval;
gboolean new_instance = FALSE;
gboolean run_input = TRUE;
@ -558,6 +603,7 @@ main (int argc, char *argv[])
guint32 stamp;
guint32 line = 0;
const char *pid_string = NULL;
gboolean use_session = FALSE;
init_mem_stuff ();
@ -603,7 +649,8 @@ main (int argc, char *argv[])
if (_medit_opt_new_app || mode == MODE_PROJECT)
new_instance = TRUE;
files = moo_filenames_from_locale (argv + opt_remain);
run_input = !_medit_opt_new_app || _medit_opt_use_session || _medit_opt_project;
use_session = !_medit_opt_new_app || _medit_opt_use_session;
app = g_object_new (MOO_TYPE_APP,
"argv", argv,
@ -613,6 +660,7 @@ main (int argc, char *argv[])
"description", _("medit is a text editor"),
"website", "http://mooedit.sourceforge.net/",
"website-label", "http://mooedit.sourceforge.net/",
"quit-on-editor-close", TRUE,
"logo", "medit",
"credits", THANKS,
NULL);
@ -634,6 +682,8 @@ main (int argc, char *argv[])
exit (0);
}
files = moo_filenames_from_locale (argv + opt_remain);
if (pid_string)
{
if (moo_app_send_files (app, files, line, stamp, pid_string))
@ -653,38 +703,19 @@ main (int argc, char *argv[])
}
if (mode == MODE_PROJECT)
{
MooPlugin *plugin;
plugin = moo_plugin_lookup ("ProjectManager");
if (!plugin)
{
g_printerr ("Could not initialize project manager plugin\n");
exit (1);
}
if (_medit_arg_project && *_medit_arg_project)
{
char *project = moo_filename_from_locale (_medit_arg_project);
g_object_set (plugin, "project", _medit_arg_project, NULL);
g_free (project);
}
moo_plugin_set_enabled (plugin, TRUE);
}
project_mode ();
else if (use_session)
moo_app_load_session (app);
editor = moo_app_get_editor (app);
window = moo_editor_new_window (editor);
if (!moo_editor_get_active_window (editor))
moo_editor_new_window (editor);
if (files && *files)
moo_app_open_files (app, files, line, stamp);
g_strfreev (files);
g_signal_connect_swapped (editor, "all-windows-closed",
G_CALLBACK (moo_app_quit), app);
retval = moo_app_run (app);
g_object_unref (app);

View File

@ -47,6 +47,7 @@ int _medit_parse_options (const char *const program_name,
#line 122 "medit-app.c"
%%
n new-app "Run new instance of application"
s use-session "Load and save session"
pid "=PID Use existing instance with process id PID" reqarg
m mode "=[simple|project] Use specified mode" reqarg
p project "=PROJECT Open project file PROJECT" reqarg
@ -58,7 +59,7 @@ l line "=LINE Open file and position cursor on line LINE" reqarg
version "Display version information and exit" return
h help "Display this help text and exit" return
%%
#line 135 "../../../medit/medit-app.opag"
#line 63 "../../../medit/medit-app.opag"
#undef STR_HELP
#define STR_HELP \
@ -151,6 +152,28 @@ push_appdir_to_path (void)
#endif
}
static void
project_mode (void)
{
MooPlugin *plugin;
plugin = moo_plugin_lookup ("ProjectManager");
if (!plugin)
{
g_printerr ("Could not initialize project manager plugin\n");
exit (1);
}
if (_medit_arg_project && *_medit_arg_project)
{
char *project = moo_filename_from_locale (_medit_arg_project);
g_object_set (plugin, "project", _medit_arg_project, NULL);
g_free (project);
}
moo_plugin_set_enabled (plugin, TRUE);
}
int
main (int argc, char *argv[])
@ -159,7 +182,6 @@ main (int argc, char *argv[])
int opt_remain;
MooEditor *editor;
char **files;
gpointer window;
int retval;
gboolean new_instance = FALSE;
gboolean run_input = TRUE;
@ -167,6 +189,7 @@ main (int argc, char *argv[])
guint32 stamp;
guint32 line = 0;
const char *pid_string = NULL;
gboolean use_session = FALSE;
init_mem_stuff ();
@ -212,7 +235,8 @@ main (int argc, char *argv[])
if (_medit_opt_new_app || mode == MODE_PROJECT)
new_instance = TRUE;
files = moo_filenames_from_locale (argv + opt_remain);
run_input = !_medit_opt_new_app || _medit_opt_use_session || _medit_opt_project;
use_session = !_medit_opt_new_app || _medit_opt_use_session;
app = g_object_new (MOO_TYPE_APP,
"argv", argv,
@ -222,6 +246,7 @@ main (int argc, char *argv[])
"description", _("medit is a text editor"),
"website", "http://mooedit.sourceforge.net/",
"website-label", "http://mooedit.sourceforge.net/",
"quit-on-editor-close", TRUE,
"logo", "medit",
"credits", THANKS,
NULL);
@ -243,6 +268,8 @@ main (int argc, char *argv[])
exit (0);
}
files = moo_filenames_from_locale (argv + opt_remain);
if (pid_string)
{
if (moo_app_send_files (app, files, line, stamp, pid_string))
@ -262,38 +289,19 @@ main (int argc, char *argv[])
}
if (mode == MODE_PROJECT)
{
MooPlugin *plugin;
plugin = moo_plugin_lookup ("ProjectManager");
if (!plugin)
{
g_printerr ("Could not initialize project manager plugin\n");
exit (1);
}
if (_medit_arg_project && *_medit_arg_project)
{
char *project = moo_filename_from_locale (_medit_arg_project);
g_object_set (plugin, "project", _medit_arg_project, NULL);
g_free (project);
}
moo_plugin_set_enabled (plugin, TRUE);
}
project_mode ();
else if (use_session)
moo_app_load_session (app);
editor = moo_app_get_editor (app);
window = moo_editor_new_window (editor);
if (!moo_editor_get_active_window (editor))
moo_editor_new_window (editor);
if (files && *files)
moo_app_open_files (app, files, line, stamp);
g_strfreev (files);
g_signal_connect_swapped (editor, "all-windows-closed",
G_CALLBACK (moo_app_quit), app);
retval = moo_app_run (app);
g_object_unref (app);

View File

@ -35,6 +35,9 @@ Show version of the program.
Run new instance of \fBmedit\fP. By default \fBmedit\fP opens \fBfiles\fP
in an existing instance of application.
.TP
.B \-s, \-\-use\-session
Load and save session. By default \fBmedit\fP does it when \-n is not used.
.TP
.B \-\-pid PID
Use existing instance with process id \fBPID\fP.
.TP

View File

@ -34,9 +34,9 @@
</configure>
</optimized>
</configurations>
<file_selector_dir>/home/muntyan/projects/moo/</file_selector_dir>
<file_selector_dir>/home/muntyan/projects/moo/moo/moopython/pygtk/</file_selector_dir>
<run>
<args>--new-app /tmp/file.rst</args>
<args>-ns</args>
<exe>medit/medit</exe>
<vars>
<var name="LANGUAGE">de</var>

View File

@ -58,6 +58,8 @@
#define MOO_ACTIONS_FILE "actions"
#endif
#define SESSION_VERSION "1.0"
static MooApp *moo_app_instance = NULL;
static MooAppInput *moo_app_input = NULL;
@ -76,11 +78,14 @@ struct _MooAppPrivate {
gboolean in_try_quit;
EggSMClient *sm_client;
char *session_file;
MooMarkupDoc *session;
MooUIXML *ui_xml;
char *default_ui;
guint quit_handler_id;
gboolean use_editor;
gboolean quit_on_editor_close;
char *tmpdir;
};
@ -120,6 +125,10 @@ static void moo_app_exec_cmd_real (MooApp *app,
char cmd,
const char *data,
guint len);
static void moo_app_load_session_real (MooApp *app,
MooMarkupNode *xml);
static void moo_app_save_session_real (MooApp *app,
MooMarkupNode *xml);
static GtkWidget *moo_app_create_prefs_dialog (MooApp *app);
static void moo_app_load_prefs (MooApp *app);
@ -133,6 +142,9 @@ static void moo_app_set_description (MooApp *app,
static void moo_app_set_version (MooApp *app,
const char *version);
static void moo_app_save_session (MooApp *app);
static void moo_app_write_session (MooApp *app);
static void start_input (MooApp *app);
@ -175,6 +187,7 @@ enum {
PROP_DESCRIPTION,
PROP_RUN_INPUT,
PROP_USE_EDITOR,
PROP_QUIT_ON_EDITOR_CLOSE,
PROP_DEFAULT_UI,
PROP_LOGO,
PROP_WEBSITE,
@ -189,6 +202,8 @@ enum {
TRY_QUIT,
PREFS_DIALOG,
EXEC_CMD,
LOAD_SESSION,
SAVE_SESSION,
LAST_SIGNAL
};
@ -214,6 +229,8 @@ moo_app_class_init (MooAppClass *klass)
klass->try_quit = moo_app_try_quit_real;
klass->prefs_dialog = moo_app_create_prefs_dialog;
klass->exec_cmd = moo_app_exec_cmd_real;
klass->load_session = moo_app_load_session_real;
klass->save_session = moo_app_save_session_real;
g_object_class_install_property (gobject_class,
PROP_ARGV,
@ -295,6 +312,14 @@ moo_app_class_init (MooAppClass *klass)
TRUE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_QUIT_ON_EDITOR_CLOSE,
g_param_spec_boolean ("quit-on-editor-close",
"quit-on-editor-close",
"quit-on-editor-close",
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_DEFAULT_UI,
g_param_spec_string ("default-ui",
@ -367,6 +392,26 @@ moo_app_class_init (MooAppClass *klass)
G_TYPE_CHAR,
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
G_TYPE_UINT);
signals[LOAD_SESSION] =
g_signal_new ("load-session",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooAppClass, load_session),
NULL, NULL,
_moo_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
signals[SAVE_SESSION] =
g_signal_new ("save-session",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooAppClass, save_session),
NULL, NULL,
_moo_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
}
@ -455,6 +500,10 @@ moo_app_finalize (GObject *object)
moo_app_info_free (app->priv->info);
g_free (app->priv->default_ui);
g_free (app->priv->session_file);
if (app->priv->session)
moo_markup_doc_unref (app->priv->session);
if (app->priv->argv)
g_strfreev (app->priv->argv);
if (app->priv->editor)
@ -517,6 +566,10 @@ moo_app_set_property (GObject *object,
app->priv->use_editor = g_value_get_boolean (value);
break;
case PROP_QUIT_ON_EDITOR_CLOSE:
app->priv->quit_on_editor_close = g_value_get_boolean (value);
break;
case PROP_DEFAULT_UI:
g_free (app->priv->default_ui);
app->priv->default_ui = g_strdup (g_value_get_string (value));
@ -578,6 +631,10 @@ moo_app_get_property (GObject *object,
g_value_set_boolean (value, app->priv->use_editor);
break;
case PROP_QUIT_ON_EDITOR_CLOSE:
g_value_set_boolean (value, app->priv->quit_on_editor_close);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -714,10 +771,36 @@ moo_app_get_info (MooApp *app)
#ifdef MOO_BUILD_EDIT
static gboolean
close_editor_window (MooApp *app)
{
GSList *windows;
gboolean ret = FALSE;
if (!app->priv->running || app->priv->in_try_quit ||
!app->priv->quit_on_editor_close)
return FALSE;
windows = moo_editor_list_windows (app->priv->editor);
if (windows && !windows->next)
{
moo_app_quit (app);
ret = TRUE;
}
g_slist_free (windows);
return ret;
}
static void
moo_app_init_editor (MooApp *app)
{
app->priv->editor = moo_editor_create_instance ();
g_signal_connect_swapped (app->priv->editor, "close-window",
G_CALLBACK (close_editor_window), app);
/* if ui_xml wasn't set yet, then moo_app_get_ui_xml()
will get editor's xml */
moo_editor_set_ui_xml (app->priv->editor,
@ -989,6 +1072,8 @@ moo_app_try_quit_real (MooApp *app)
if (!app->priv->running)
return FALSE;
moo_app_save_session (app);
#ifdef MOO_BUILD_EDIT
if (!moo_editor_close_all (app->priv->editor, TRUE, TRUE))
return TRUE;
@ -1027,6 +1112,7 @@ moo_app_quit_real (MooApp *app)
app->priv->editor = NULL;
#endif /* MOO_BUILD_EDIT */
moo_app_write_session (app);
moo_app_save_prefs (app);
if (app->priv->quit_handler_id)
@ -1373,6 +1459,121 @@ moo_app_new_file (MooApp *app,
}
static void
moo_app_load_session_real (MooApp *app,
MooMarkupNode *xml)
{
#ifdef MOO_BUILD_EDIT
MooEditor *editor;
editor = moo_app_get_editor (app);
g_return_if_fail (editor != NULL);
_moo_editor_load_session (editor, xml);
#endif /* MOO_BUILD_EDIT */
}
static void
moo_app_save_session_real (MooApp *app,
MooMarkupNode *xml)
{
#ifdef MOO_BUILD_EDIT
MooEditor *editor;
editor = moo_app_get_editor (app);
g_return_if_fail (editor != NULL);
_moo_editor_save_session (editor, xml);
#endif /* MOO_BUILD_EDIT */
}
static void
moo_app_save_session (MooApp *app)
{
MooMarkupNode *root;
if (!app->priv->session_file)
return;
if (app->priv->session)
moo_markup_doc_unref (app->priv->session);
app->priv->session = moo_markup_doc_new ("session");
root = moo_markup_create_root_element (app->priv->session, "session");
moo_markup_set_prop (root, "version", SESSION_VERSION);
g_signal_emit (app, signals[SAVE_SESSION], 0, root);
}
static void
moo_app_write_session (MooApp *app)
{
char *string;
GError *error = NULL;
if (!app->priv->session_file)
return;
if (!app->priv->session)
{
char *file = moo_get_user_cache_file (app->priv->session_file);
_moo_unlink (file);
g_free (file);
return;
}
string = moo_markup_format_pretty (app->priv->session, 1);
moo_save_user_cache_file (app->priv->session_file, string, -1, &error);
if (error)
{
char *file = moo_get_user_cache_file (app->priv->session_file);
g_critical ("could not save session file %s: %s", file, error->message);
g_free (file);
g_error_free (error);
}
}
void
moo_app_load_session (MooApp *app)
{
MooMarkupDoc *doc;
MooMarkupNode *root;
GError *error = NULL;
const char *version;
char *session_file;
g_return_if_fail (MOO_IS_APP (app));
if (!app->priv->session_file)
app->priv->session_file = g_strdup_printf ("%s.session", g_get_prgname ());
session_file = moo_get_user_cache_file (app->priv->session_file);
if (!g_file_test (session_file, G_FILE_TEST_EXISTS) ||
!(doc = moo_markup_parse_file (session_file, &error)))
{
if (error)
{
g_warning ("could not open session file %s: %s",
session_file, error->message);
g_error_free (error);
}
g_free (session_file);
return;
}
if (!(root = moo_markup_get_root_element (doc, "session")) ||
!(version = moo_markup_get_prop (root, "version")))
g_warning ("malformed session file %s, ignoring", session_file);
else if (strcmp (version, SESSION_VERSION) != 0)
g_warning ("invalid session file version %s in %s, ignoring",
version, session_file);
else
g_signal_emit (app, signals[LOAD_SESSION], 0, root);
moo_markup_doc_unref (doc);
g_free (session_file);
}
static void
moo_app_present (MooApp *app)
{

View File

@ -55,18 +55,23 @@ struct _MooAppClass
{
GObjectClass parent_class;
gboolean (*init) (MooApp *app);
int (*run) (MooApp *app);
void (*quit) (MooApp *app);
gboolean (*init) (MooApp *app);
int (*run) (MooApp *app);
void (*quit) (MooApp *app);
gboolean (*try_quit) (MooApp *app);
gboolean (*try_quit) (MooApp *app);
GtkWidget* (*prefs_dialog) (MooApp *app);
GtkWidget* (*prefs_dialog) (MooApp *app);
void (*exec_cmd) (MooApp *app,
char cmd,
const char *data,
guint len);
void (*exec_cmd) (MooApp *app,
char cmd,
const char *data,
guint len);
void (*load_session) (MooApp *app,
MooMarkupNode *xml);
void (*save_session) (MooApp *app,
MooMarkupNode *xml);
};
@ -79,6 +84,8 @@ gboolean moo_app_init (MooApp *app);
int moo_app_run (MooApp *app);
gboolean moo_app_quit (MooApp *app);
void moo_app_load_session (MooApp *app);
void moo_app_set_exit_code (MooApp *app,
int code);

View File

@ -75,6 +75,9 @@ static MooEditWindow *create_window (MooEditor *editor);
static void moo_editor_add_doc (MooEditor *editor,
MooEditWindow *window,
MooEdit *doc);
static gboolean close_window_handler (MooEditor *editor,
MooEditWindow *window,
gboolean ask_confirm);
static void do_close_window (MooEditor *editor,
MooEditWindow *window);
static void do_close_doc (MooEditor *editor,
@ -156,7 +159,7 @@ enum {
};
enum {
ALL_WINDOWS_CLOSED,
CLOSE_WINDOW,
LAST_SIGNAL
};
@ -177,6 +180,8 @@ moo_editor_class_init (MooEditorClass *klass)
gobject_class->set_property = moo_editor_set_property;
gobject_class->get_property = moo_editor_get_property;
klass->close_window = close_window_handler;
_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));
@ -255,13 +260,16 @@ moo_editor_class_init (MooEditorClass *klass)
MOO_TYPE_EDIT,
G_PARAM_READABLE));
signals[ALL_WINDOWS_CLOSED] =
_moo_signal_new_cb ("all-windows-closed",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
NULL, NULL, NULL,
_moo_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[CLOSE_WINDOW] =
g_signal_new ("close-window",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooEditorClass, close_window),
g_signal_accumulator_true_handled, NULL,
_moo_marshal_BOOLEAN__OBJECT_BOOLEAN,
G_TYPE_BOOLEAN, 2,
MOO_TYPE_EDIT_WINDOW,
G_TYPE_BOOLEAN);
edit_window_class = g_type_class_ref (MOO_TYPE_EDIT_WINDOW);
moo_window_class_new_action_custom (edit_window_class, RECENT_ACTION_ID, NULL,
@ -1154,6 +1162,82 @@ _moo_editor_move_doc (MooEditor *editor,
}
static gboolean
moo_editor_load_file (MooEditor *editor,
MooEditWindow *window,
GtkWidget *parent,
MooEditFileInfo *info,
gboolean silent,
gboolean add_history,
MooEdit **docp)
{
GError *error = NULL;
gboolean new_doc = FALSE;
MooEdit *doc = NULL;
char *filename;
gboolean result = TRUE;
*docp = NULL;
filename = _moo_normalize_file_path (info->filename);
if (window_list_find_file (editor, filename, docp))
{
if (add_history)
moo_history_list_add_filename (editor->priv->history, filename);
g_free (filename);
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 = g_object_new (get_doc_type (editor), "editor", editor, NULL);
MOO_OBJECT_REF_SINK (doc);
new_doc = TRUE;
}
/* XXX open_single */
if (!_moo_edit_load_file (doc, filename, info->encoding, &error))
{
if (!silent)
_moo_edit_open_error_dialog (parent, filename, info->encoding, error);
g_error_free (error);
result = FALSE;
}
else
{
if (!window)
window = moo_editor_get_active_window (editor);
if (!window)
window = create_window (editor);
if (new_doc)
{
_moo_edit_window_insert_doc (window, doc, -1);
moo_editor_add_doc (editor, window, doc);
}
if (add_history)
moo_history_list_add_filename (editor->priv->history, filename);
}
if (result)
*docp = doc;
g_free (filename);
g_object_unref (doc);
return result;
}
gboolean
moo_editor_open (MooEditor *editor,
MooEditWindow *window,
@ -1185,78 +1269,21 @@ moo_editor_open (MooEditor *editor,
return result;
}
bring_to_front = NULL;
for (l = files; l != NULL; l = l->next)
{
MooEditFileInfo *info = l->data;
GError *error = NULL;
gboolean new_doc = FALSE;
MooEdit *doc = NULL;
char *filename;
filename = _moo_normalize_file_path (info->filename);
if (window_list_find_file (editor, filename, &bring_to_front))
{
moo_history_list_add_filename (editor->priv->history, filename);
g_free (filename);
continue;
}
else
{
bring_to_front = NULL;
}
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))
g_object_ref (doc);
else
doc = NULL;
}
if (moo_editor_load_file (editor, window, parent, info, editor->priv->silent, TRUE, &doc))
parent = GTK_WIDGET (doc);
if (!doc)
{
doc = g_object_new (get_doc_type (editor), "editor", editor, NULL);
MOO_OBJECT_REF_SINK (doc);
new_doc = TRUE;
}
/* XXX open_single */
if (!_moo_edit_load_file (doc, filename, info->encoding, &error))
{
if (!editor->priv->silent)
_moo_edit_open_error_dialog (parent, filename, info->encoding, error);
g_error_free (error);
result = FALSE;
}
else
{
if (!window)
window = moo_editor_get_active_window (editor);
if (!window)
window = create_window (editor);
if (new_doc)
{
_moo_edit_window_insert_doc (window, doc, -1);
moo_editor_add_doc (editor, window, doc);
}
else
{
bring_to_front = doc;
}
moo_history_list_add_filename (editor->priv->history, filename);
parent = GTK_WIDGET (window);
}
g_free (filename);
g_object_unref (doc);
if (doc)
bring_to_front = doc;
}
if (bring_to_front)
@ -1351,10 +1378,10 @@ find_busy (GSList *docs)
}
gboolean
moo_editor_close_window (MooEditor *editor,
MooEditWindow *window,
gboolean ask_confirm)
static gboolean
close_window_handler (MooEditor *editor,
MooEditWindow *window,
gboolean ask_confirm)
{
WindowInfo *info;
MooEditDialogResponse response;
@ -1373,7 +1400,7 @@ moo_editor_close_window (MooEditor *editor,
if (busy)
{
moo_editor_set_active_doc (editor, busy);
return FALSE;
return TRUE;
}
modified = find_modified (info->docs);
@ -1436,11 +1463,34 @@ moo_editor_close_window (MooEditor *editor,
}
}
if (do_close)
g_slist_free (modified);
return !do_close;
}
gboolean
moo_editor_close_window (MooEditor *editor,
MooEditWindow *window,
gboolean ask_confirm)
{
gboolean stopped = FALSE;
g_return_val_if_fail (MOO_IS_EDITOR (editor), FALSE);
g_return_val_if_fail (MOO_IS_EDIT_WINDOW (window), FALSE);
if (!window_list_find (editor, window))
return TRUE;
g_object_ref (window);
g_signal_emit (editor, signals[CLOSE_WINDOW], 0, window, ask_confirm, &stopped);
if (!stopped && window_list_find (editor, window))
do_close_window (editor, window);
g_slist_free (modified);
return do_close;
g_object_unref (window);
return !stopped;
}
@ -1464,9 +1514,6 @@ do_close_window (MooEditor *editor,
_moo_window_detach_plugins (window);
gtk_widget_destroy (GTK_WIDGET (window));
if (!editor->priv->windows)
g_signal_emit (editor, signals[ALL_WINDOWS_CLOSED], 0);
g_slist_free (list);
}
@ -1686,6 +1733,237 @@ moo_editor_close_all (MooEditor *editor,
}
static char *
filename_from_utf8 (const char *encoded)
{
if (g_str_has_prefix (encoded, "base64"))
{
guchar *filename;
gsize len;
filename = g_base64_decode (encoded + strlen ("base64"), &len);
if (!filename || !len || filename[len-1] != 0)
{
g_critical ("%s: oops", G_STRLOC);
return NULL;
}
return (char*) filename;
}
else
{
return g_strdup (encoded);
}
}
static char *
filename_to_utf8 (const char *filename)
{
char *encoded, *ret;
if (g_utf8_validate (filename, -1, NULL))
return g_strdup (filename);
encoded = g_base64_encode ((const guchar *) filename, strlen (filename) + 1);
ret = g_strdup_printf ("base64%s", encoded);
g_free (encoded);
return ret;
}
static MooEdit *
load_doc_session (MooEditor *editor,
MooEditWindow *window,
MooMarkupNode *elm)
{
char *filename;
const char *utf8_filename;
const char *encoding;
MooEdit *doc = NULL;
MooEditFileInfo *info;
utf8_filename = moo_markup_get_content (elm);
if (!utf8_filename || !utf8_filename[0])
return moo_editor_new_doc (editor, window);
filename = filename_from_utf8 (utf8_filename);
g_return_val_if_fail (filename != NULL, NULL);
encoding = moo_markup_get_prop (elm, "encoding");
info = moo_edit_file_info_new (filename, encoding);
moo_editor_load_file (editor, window, GTK_WIDGET (window), info, TRUE, FALSE, &doc);
if (doc)
{
int line = moo_markup_get_int_prop (elm, "line", 0);
moo_text_view_move_cursor (MOO_TEXT_VIEW (doc), line, 0, FALSE, TRUE);
}
moo_edit_file_info_free (info);
g_free (filename);
return doc;
}
static MooMarkupNode *
save_doc_session (MooEdit *doc,
MooMarkupNode *elm)
{
const char *filename;
const char *encoding;
MooMarkupNode *node;
filename = moo_edit_get_filename (doc);
encoding = moo_edit_get_encoding (doc);
if (filename)
{
char *utf8_filename;
utf8_filename = filename_to_utf8 (filename);
g_return_val_if_fail (utf8_filename != NULL, NULL);
node = moo_markup_create_text_element (elm, "document", utf8_filename);
moo_markup_set_int_prop (node, "line", moo_text_view_get_cursor_line (MOO_TEXT_VIEW (doc)));
if (encoding && encoding[0])
moo_markup_set_prop (node, "encoding", encoding);
g_free (utf8_filename);
}
else
{
node = moo_markup_create_element (elm, "document");
}
return node;
}
static MooEditWindow *
load_window_session (MooEditor *editor,
MooMarkupNode *elm)
{
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))
{
MooEdit *doc;
doc = load_doc_session (editor, window, node);
if (doc && moo_markup_get_bool_prop (node, "active", FALSE))
active_doc = doc;
}
}
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;
GSList *docs;
active_doc = moo_edit_window_get_active_doc (window);
docs = moo_edit_window_list_docs (window);
node = moo_markup_create_element (elm, "window");
while (docs)
{
MooMarkupNode *doc_node;
MooEdit *doc = docs->data;
doc_node = save_doc_session (doc, node);
if (doc_node && doc == active_doc)
moo_markup_set_bool_prop (doc_node, "active", TRUE);
docs = g_slist_delete_link (docs, docs);
}
return node;
}
void
_moo_editor_load_session (MooEditor *editor,
MooMarkupNode *xml)
{
MooMarkupNode *editor_node;
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");
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;
window = load_window_session (editor, node);
if (window && moo_markup_get_bool_prop (node, "active", FALSE))
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;
GSList *windows;
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);
windows = moo_editor_list_windows (editor);
node = moo_markup_create_element (xml, "editor");
while (windows)
{
MooEditWindow *window = windows->data;
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);
windows = g_slist_delete_link (windows, windows);
}
}
GSList*
moo_editor_list_windows (MooEditor *editor)
{

View File

@ -42,7 +42,11 @@ struct _MooEditor
struct _MooEditorClass
{
GObjectClass parent_class;
GObjectClass parent_class;
gboolean (*close_window) (MooEditor *editor,
MooEditWindow *window,
gboolean ask_confirm);
};
@ -145,6 +149,11 @@ gboolean moo_editor_save_copy (MooEditor *editor,
void moo_editor_apply_prefs (MooEditor *editor);
void _moo_editor_load_session (MooEditor *editor,
MooMarkupNode *xml);
void _moo_editor_save_session (MooEditor *editor,
MooMarkupNode *xml);
G_END_DECLS

View File

@ -3,6 +3,7 @@ BOOL:BOXED,UINT
BOOL:ENUM,INT,BOOL
BOOL:INT
BOOL:OBJECT
BOOL:OBJECT,BOOL
BOOL:OBJECT,BOXED
BOOL:OBJECT,BOXED,BOXED
BOOL:OBJECT,OBJECT