This patch adds locking capabilities to gnumeric version 1.6.2,
preventing modification of the same workbook by multiple users or
program instances.
The mechanism used is creation of hidden (on UNIX at least) lock files
(lock filename syntax: DOT <workbookname> DOT lock). A lock file is
created for each named workbook that is opened. The lock file
contains the ascii string "[EMAIL PROTECTED] (uid xxx, pid xxx)" to identify
the holder of the lock.
If a locked workbook is opened by gnumeric, the user will be informed
of the lock and be told of the current lock holder (and some
explanation of why the file might be locked). The SAVE functionality
will also be disabled for workbooks where the lock is held by an
external party. To save data, the user must use SAVE-AS.
Attempts are made to discover failures when they occur (such as a
lockfile being deleted by a crafty user), and to tolerate them when
possible. I have done some testing to verify that locking works in
the obvious foreseeable cases.
As an aside, there was some discussion on this list of implementing
similar locking mechanisms a few years back. From what I have
gleaned, my patch should exceed the functionality of those earlier
contributions. Hopefully others find it useful. Constructive
comments (or bug reports) are appreciated.
Cheers,
Tammo
--- gnumeric-1.6.2/src/workbook-control-gui.h.dotlocking 2005-05-03
14:38:59.000000000 -0400
+++ gnumeric-1.6.2/src/workbook-control-gui.h 2006-03-08 15:56:05.000000000
-0500
@@ -41,9 +41,14 @@ void wbcg_copy_toolbar_visibility
void wbcg_toggle_end_mode (WorkbookControlGUI *wbcg);
void wbcg_set_end_mode (WorkbookControlGUI *wbcg, gboolean flag);
void wbcg_set_transient_for (WorkbookControlGUI *wbcg, GtkWindow *window);
+void wbcg_save_set_sensitivity (WorkbookControlGUI *wbcg, gboolean
state);
+
+void wbcg_locked_file_dialog (WorkbookControl *wbc, const char *data,
const char *msg);
+
+
PangoFontDescription *wbcg_get_font_desc (WorkbookControlGUI *wbcg);
#endif /* GNUMERIC_WORKBOOK_CONTROL_GUI_H */
--- /dev/null 2006-02-28 19:57:22.510895250 -0500
+++ gnumeric-1.6.2/src/flock.h 2006-03-08 15:56:05.000000000 -0500
@@ -0,0 +1,10 @@
+#ifndef FLOCK_H
+#define FLOCK_H
+
+char *flock_acquire (const char *);
+
+char *flock_verify (const char *);
+
+gboolean flock_release (const char *);
+
+#endif /* FLOCK_H */
--- gnumeric-1.6.2/src/workbook-view.c.dotlocking 2005-09-15
21:27:13.000000000 -0400
+++ gnumeric-1.6.2/src/workbook-view.c 2006-03-08 15:56:05.000000000 -0500
@@ -1,7 +1,8 @@
-/* vim: set sw=8: */
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t;
c-basic-offset: 8 -*- */
+
/*
* workbook-view.c: View functions for the workbook
*
* Copyright (C) 2000-2004 Jody Goldberg ([EMAIL PROTECTED])
*
* This program is free software; you can redistribute it and/or
@@ -21,12 +22,13 @@
*/
#include <gnumeric-config.h>
#include "gnumeric.h"
#include "workbook-view.h"
#include "workbook-control-priv.h"
+#include "workbook-control-gui.h"
#include "workbook.h"
#include "application.h"
#include "sheet.h"
#include "sheet-view.h"
#include "sheet-merge.h"
#include "sheet-style.h"
@@ -59,12 +61,14 @@
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include "mathfunc.h"
#include <goffice/utils/go-file.h>
+#include "flock.h"
+
/* WorkbookView signals */
enum {
LAST_SIGNAL
};
Workbook *
@@ -578,12 +582,14 @@ workbook_view_new (Workbook *wb)
wbv->show_horizontal_scrollbar = TRUE;
wbv->show_vertical_scrollbar = TRUE;
wbv->show_notebook_tabs = TRUE;
wbv->do_auto_completion = gnm_app_use_auto_complete ();
wbv->is_protected = FALSE;
+ workbook_set_externally_locked (wb, FALSE);
+
/* Set the default operation to be performed over selections */
wbv->auto_expr = NULL;
wbv->auto_expr_desc = NULL;
wbv->auto_expr_value_as_string = NULL;
wbv->auto_expr_use_max_precision = FALSE;
wb_view_auto_expr (wbv, _("Sum"), "sum");
@@ -644,12 +650,72 @@ wbv_save_to_uri (WorkbookView *wbv, GOFi
if (!gnumeric_io_error_occurred (io_context))
go_cmd_context_error_export (GO_CMD_CONTEXT (io_context), msg);
g_free (msg);
}
+void
+wb_view_adapt_to_locking (WorkbookView *wbv,
+ const char *lockdata,
+ WbvLockNotification ln)
+{
+ char *uri, *msg, *tmp_data;
+ const char *raw_msg;
+
+ if ((ln != WBV_EXT_LOCK_SAVE) && (ln != WBV_EXT_LOCK_SAVEAS)) {
+ WORKBOOK_VIEW_FOREACH_CONTROL (wbv, control,
wbcg_save_set_sensitivity (control, FALSE););
+ }
+
+ switch (ln) {
+ case WBV_EXT_LOCK_OPEN:
+ raw_msg = "The workbook '%s' is locked, which should mean that "
+ "someone else is currently using it. The workbook "
+ "will be opened, but saving changes will be disabled "
+ "to prevent the possibility of conflicting changes by "
+ "concurrent users. Use the SAVE AS menu action to "
+ "store any changes under a new name. Otherwise try "
+ "re-opening the workbook later.";
+ break;
+ case WBV_EXT_LOCK_SAVE:
+ raw_msg = "Saving of workbook '%s' has been disabled. Use the "
+ "SAVE AS menu action to store any changes under a new
name.";
+ break;
+ case WBV_EXT_LOCK_SAVEAS:
+ raw_msg = "The workbook '%s' is locked. This likely means that
"
+ "someone else is currently using it. To prevent the
possibility "
+ "of conflicting changes by concurrent users, saving to
this "
+ "workbook has been disabled.";
+ break;
+ case WBV_SELF_LOCK_FAULT:
+ raw_msg = "The lock for workbook '%s' has been removed or
damaged. "
+ "This is unexpected and is probably a sign that
something "
+ "has gone wrong. To prevent the possibility of
conflicting "
+ "changes by concurrent users, saving to this workbook
has "
+ "been disabled.";
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ uri = workbook_get_uri (wb_view_workbook (wbv));
+ if (lockdata == NULL) {
+ tmp_data = flock_verify (uri);
+ } else {
+ tmp_data = lockdata;
+ }
+ msg = g_strdup_printf (raw_msg, g_path_get_basename (uri));
+
+ WORKBOOK_VIEW_FOREACH_CONTROL (wbv, control,
+ wbcg_locked_file_dialog(control,
tmp_data, msg); break;);
+
+ if (lockdata == NULL) {
+ g_free (tmp_data);
+ }
+ g_free (msg);
+}
+
/**
* wb_view_save_as:
* @wbv : Workbook View
* @fs : GOFileSaver object
* @uri : URI to save as.
* @context :
@@ -664,21 +730,34 @@ gboolean
wb_view_save_as (WorkbookView *wbv, GOFileSaver *fs, char const *uri,
GOCmdContext *context)
{
IOContext *io_context;
Workbook *wb;
gboolean has_error, has_warning;
+ char *lockdata;
g_return_val_if_fail (IS_WORKBOOK_VIEW (wbv), FALSE);
g_return_val_if_fail (IS_GO_FILE_SAVER (fs), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
g_return_val_if_fail (IS_GO_CMD_CONTEXT (context), FALSE);
wb = wb_view_workbook (wbv);
io_context = gnumeric_io_context_new (context);
+ if ((lockdata = flock_acquire(uri)) != NULL) {
+ wb_view_adapt_to_locking (wbv, lockdata, WBV_EXT_LOCK_SAVEAS);
+ g_free (lockdata);
+ return FALSE;
+ }
+ if (! workbook_externally_locked (wb)) {
+ flock_release (workbook_get_uri(wb));
+ } else {
+ workbook_set_externally_locked (wbv->wb, FALSE);
+ WORKBOOK_VIEW_FOREACH_CONTROL (wbv, control,
wbcg_save_set_sensitivity (control, TRUE););
+ }
+
go_cmd_context_set_sensitive (context, FALSE);
wbv_save_to_uri (wbv, fs, uri, io_context);
go_cmd_context_set_sensitive (context, TRUE);
has_error = gnumeric_io_error_occurred (io_context);
has_warning = gnumeric_io_warning_occurred (io_context);
@@ -710,17 +789,30 @@ gboolean
wb_view_save (WorkbookView *wbv, GOCmdContext *context)
{
IOContext *io_context;
Workbook *wb;
GOFileSaver *fs;
gboolean has_error, has_warning;
+ char *lockdata;
g_return_val_if_fail (IS_WORKBOOK_VIEW (wbv), FALSE);
g_return_val_if_fail (IS_GO_CMD_CONTEXT (context), FALSE);
wb = wb_view_workbook (wbv);
+
+ if ((lockdata = flock_verify (workbook_get_uri(wb))) != NULL) {
+ if (workbook_externally_locked (wb)) {
+ wb_view_adapt_to_locking (wbv, lockdata,
WBV_EXT_LOCK_SAVE);
+ } else {
+ workbook_set_externally_locked (wbv->wb, TRUE);
+ wb_view_adapt_to_locking (wbv, lockdata,
WBV_SELF_LOCK_FAULT);
+ }
+ g_free (lockdata);
+ return FALSE;
+ }
+
fs = workbook_get_file_saver (wb);
if (fs == NULL)
fs = go_file_saver_get_default ();
io_context = gnumeric_io_context_new (context);
if (fs == NULL)
@@ -1019,18 +1111,29 @@ wb_view_new_from_uri (char const *uri,
g_return_val_if_fail (uri != NULL, NULL);
input = go_file_open (uri, &err);
if (input != NULL) {
WorkbookView *res;
+ char *lockdata;
g_printerr ("Reading %s\n", uri);
res = wb_view_new_from_input (input,
optional_fmt, io_context,
optional_enc);
g_object_unref (G_OBJECT (input));
+
+ if ((lockdata = flock_acquire(uri)) != NULL) {
+ /* There is apparently no GUI existing yet (at least in
most cases),
+ so we cannot disable (grey out) SAVE here... Only
make a note for later. */
+ workbook_set_externally_locked (res->wb, TRUE);
+ g_free (lockdata);
+ } else {
+ workbook_set_externally_locked (res->wb, FALSE);
+ }
+
return res;
}
if (err != NULL) {
if (err->message != NULL)
msg = g_strdup (err->message);
--- gnumeric-1.6.2/src/workbook.c.dotlocking 2005-09-21 00:46:42.000000000
-0400
+++ gnumeric-1.6.2/src/workbook.c 2006-03-08 15:56:05.000000000 -0500
@@ -37,12 +37,14 @@
#include "gutils.h"
#include "gnm-marshalers.h"
#include "style-color.h"
#include <goffice/utils/go-file.h>
#include <goffice/utils/go-glib-extras.h>
+#include "flock.h"
+
#ifdef WITH_GTK
#ifdef WITH_GNOME
#include <bonobo/bonobo-main.h>
#else
#include <gtk/gtkmain.h> /* for gtk_main_quit */
#endif
@@ -69,20 +71,36 @@ static void
cb_saver_finalize (Workbook *wb, GOFileSaver *saver)
{
g_return_if_fail (IS_GO_FILE_SAVER (saver));
g_return_if_fail (IS_WORKBOOK (wb));
g_return_if_fail (wb->file_saver == saver);
wb->file_saver = NULL;
+}
+
+gboolean
+workbook_externally_locked (Workbook *wb)
+{
+ return wb->externally_locked;
+}
+
+void
+workbook_set_externally_locked (Workbook *wb, gboolean state)
+{
+ wb->externally_locked = state;
}
static void
workbook_dispose (GObject *wb_object)
{
Workbook *wb = WORKBOOK (wb_object);
GList *sheets, *ptr;
+ if (! wb->externally_locked) {
+ flock_release(wb->uri);
+ }
+
wb->during_destruction = TRUE;
if (wb->file_saver)
workbook_set_saveinfo (wb, wb->file_format_level, NULL);
/* Remove all the sheet controls to avoid displaying while we exit */
--- gnumeric-1.6.2/src/workbook-priv.h.dotlocking 2005-03-16
17:28:00.000000000 -0500
+++ gnumeric-1.6.2/src/workbook-priv.h 2006-03-08 15:56:05.000000000 -0500
@@ -17,12 +17,14 @@ struct _Workbook {
GHashTable *sheet_order_dependents;
GHashTable *sheet_local_functions;
gboolean modified;
gboolean is_placeholder;
+ gboolean externally_locked;
+
gchar *uri;
FileFormatLevel file_format_level;
GOFileSaver *file_saver;
/* Undo support */
GSList *undo_commands;
--- /dev/null 2006-02-28 19:57:22.510895250 -0500
+++ gnumeric-1.6.2/src/flock.c 2006-03-08 15:56:05.000000000 -0500
@@ -0,0 +1,238 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t;
c-basic-offset: 8 -*- */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <goffice/utils/go-file.h>
+
+#include "gnumeric.h"
+#include "flock.h"
+
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW (0)
+#endif
+
+const unsigned max_lockdata_sz = 128;
+
+char * gen_lockname (const char *);
+char * gen_lockdata (void);
+
+char *
+gen_lockname (const char *uri)
+{
+ char *dir, *base, *lockname;
+ const char *s0 = "/.";
+ const char *s1 = ".lock";
+
+ if ((uri == NULL) || (strlen(uri) == 0) || (strncmp (uri, "file://", 7)
!= 0)) {
+ return NULL;
+ }
+
+ dir = go_dirname_from_uri (uri, TRUE);
+ base = go_basename_from_uri (uri);
+ lockname = (char *) g_malloc (strlen (dir) + strlen (base) + strlen
(s0) + strlen (s1) + 1);
+ sprintf (lockname, "%s%s%s%s", dir, s0, base, s1);
+ g_free (base);
+ g_free (dir);
+
+ /* XXX debugging */
+ /* g_printerr ("lockname is '%s'\n", lockname); */
+
+ return lockname;
+}
+
+char *
+gen_lockdata ()
+{
+ char hostname [HOST_NAME_MAX + 1];
+ struct passwd *pw;
+ uid_t uid;
+ pid_t pid;
+ char *uid_str, *pid_str;
+ char *data;
+ const char *s0 = "@";
+ const char *s1 = " (uid ";
+ const char *s2 = ", pid ";
+ const char *s3 = ")";
+
+ if (gethostname (hostname, HOST_NAME_MAX) == -1) {
+ return NULL;
+ }
+ uid = getuid ();
+ pid = getpid ();
+ if ((pw = getpwuid (uid)) == NULL) {
+ return NULL;
+ }
+ uid_str = g_strdup_printf ("%lu", (long unsigned) uid);
+ pid_str = g_strdup_printf ("%lu", (long unsigned) pid);
+ data = (char *) g_malloc (MIN(strlen (pw->pw_name) + strlen (hostname)
+ strlen (uid_str) +
+ strlen (pid_str) + strlen (s0) + strlen
(s1) + strlen (s2) +
+ strlen (s3) + 1, max_lockdata_sz));
+ snprintf (data, max_lockdata_sz - 1, "%s%s%s%s%s%s%s%s",
+ pw->pw_name, s0, hostname, s1, uid_str, s2, pid_str, s3);
+ g_free(uid_str);
+ g_free(pid_str);
+
+ return data;
+}
+
+char *
+flock_acquire (const char* uri)
+{
+ char *lockname = NULL;
+ char *lockdata = NULL;
+ const char *err_msg = NULL;
+ int fd;
+
+ lockname = gen_lockname (uri);
+ if (lockname == NULL) {
+ err_msg = "illegal lockname";
+ goto flock_lock_finish;
+ }
+
+ /* XXX debugging */
+ /* g_printerr ("locking '%s'\n", lockname); */
+
+ fd = g_open (lockname, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd != -1) {
+ int w_rc, c_rc;
+
+ lockdata = gen_lockdata ();
+ if (lockdata == NULL) {
+ err_msg = "lock data generation error";
+ goto flock_lock_finish;
+ }
+
+ w_rc = write (fd, lockdata, strlen (lockdata) + 1);
+ g_free(lockdata);
+ lockdata = NULL;
+ c_rc = close (fd);
+
+ if (w_rc == -1) {
+ err_msg = "lock write failure";
+ goto flock_lock_finish;
+ }
+ if (c_rc == -1) {
+ err_msg = "lock close failure";
+ goto flock_lock_finish;
+ }
+ } else if (g_file_error_from_errno(errno) == G_FILE_ERROR_EXIST) {
+ GError *error = NULL;
+
+ if (! g_file_get_contents (lockname, &lockdata, NULL, &error)) {
+ err_msg = "lock exists, but reading it failed";
+ goto flock_lock_finish;
+ }
+
+ /* XXX debugging */
+ /* g_printerr ("lock already held by '%s'\n", lockdata); */
+
+ } else {
+ err_msg = "lock open failed";
+ }
+
+ flock_lock_finish:
+ if (err_msg != NULL) {
+ /* XXX debugging */
+ /* g_printerr ("locking failed for '%s'\n", lockname); */
+
+ g_assert (lockdata == NULL);
+ lockdata = g_strdup_printf ("unknown (%s)", err_msg);
+ }
+
+ if (lockname != NULL) {
+ g_free(lockname);
+ }
+ return lockdata;
+}
+
+char *
+flock_verify (const char* uri)
+{
+ char *lockname = NULL;
+ char *expected_lockdata = NULL;
+ char *actual_lockdata = NULL;
+ const char *err_msg = NULL;
+ GError *error = NULL;
+
+ lockname = gen_lockname (uri);
+ if (lockname == NULL) {
+ err_msg = "illegal lockname";
+ goto flock_verify_finish;
+ }
+
+ expected_lockdata = gen_lockdata ();
+ if (expected_lockdata == NULL) {
+ err_msg = "lock data generation error";
+ goto flock_verify_finish;
+ }
+
+ /* XXX debugging */
+ /* g_printerr ("verifying '%s'\n", lockname); */
+
+ g_file_get_contents (lockname, &actual_lockdata, NULL, &error);
+ g_assert ((actual_lockdata == NULL && error != NULL) ||
+ (actual_lockdata != NULL && error == NULL));
+ if (error != NULL) {
+ /* XXX debugging */
+ /* g_printerr ("ERROR: reading lock file -- %s\n",
error->message); */
+ g_error_free (error);
+ err_msg = "reading lock failed";
+ goto flock_verify_finish;
+ }
+
+ if (strncmp (expected_lockdata, actual_lockdata, max_lockdata_sz) == 0)
{
+ g_free(actual_lockdata);
+ actual_lockdata = NULL;
+ } else {
+ /* XXX debugging */
+ /* g_printerr ("expected '%s', actually '%s'\n",
expected_lockdata, actual_lockdata); */
+ }
+
+ flock_verify_finish:
+ if (err_msg != NULL) {
+ /* XXX debugging */
+ /* g_printerr ("lock verify failed for '%s'\n", lockname); */
+
+ g_assert (actual_lockdata == NULL);
+ actual_lockdata = g_strdup_printf ("unknown (%s)", err_msg);
+ }
+
+ if (lockname != NULL) {
+ g_free(lockname);
+ }
+ if (expected_lockdata != NULL) {
+ g_free(expected_lockdata);
+ }
+ return actual_lockdata;
+}
+
+gboolean
+flock_release (const char* uri)
+{
+ char *lockname;
+ gboolean success;
+
+ if (flock_verify (uri) != NULL) {
+ return FALSE;
+ }
+
+ lockname = gen_lockname (uri);
+
+ /* XXX debugging */
+ /* g_printerr ("releasing '%s'\n", lockname); */
+
+ success = (g_remove (lockname) == 0);
+ g_free(lockname);
+
+ return success;
+}
--- gnumeric-1.6.2/src/workbook-control-gui.c.dotlocking 2005-11-14
01:34:05.000000000 -0500
+++ gnumeric-1.6.2/src/workbook-control-gui.c 2006-03-08 15:56:05.000000000
-0500
@@ -1174,12 +1174,38 @@ wbcg_menu_state_update (WorkbookControl
? _("Remove a filter")
: _("Add a filter");
wbcg_set_action_label (wbcg, "DataAutoFilter", NULL, label,
new_tip);
}
}
+void
+wbcg_save_set_sensitivity (WorkbookControlGUI *wbcg, gboolean state)
+{
+ g_return_if_fail (wbcg != NULL);
+ wbcg_set_action_sensitivity (wbcg, "FileSave", state);
+}
+
+void
+wbcg_locked_file_dialog (WorkbookControl *wbc, const char *data, const char
*msg)
+{
+ GtkWidget *d;
+ WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
+ char *header;
+
+ g_return_if_fail (wbcg != NULL);
+
+ header = g_strdup_printf ("FILE LOCKED by %s", data);
+ d = gnumeric_message_dialog_new (wbcg_toplevel (wbcg),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ header, msg);
+ g_free (header);
+ go_gtk_dialog_add_button (GTK_DIALOG(d), "OK", GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL);
+ go_gtk_dialog_run (GTK_DIALOG (d), wbcg_toplevel (wbcg));
+}
+
static void
wbcg_undo_redo_labels (WorkbookControl *wbc, char const *undo, char const
*redo)
{
WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
g_return_if_fail (wbcg != NULL);
--- gnumeric-1.6.2/src/Makefile.am.dotlocking 2006-01-30 00:24:47.000000000
-0500
+++ gnumeric-1.6.2/src/Makefile.am 2006-03-08 15:56:05.000000000 -0500
@@ -82,12 +82,14 @@ GNUMERIC_BASE = \
expr.h \
expr-impl.h \
expr-name.c \
expr-name.h \
file-autoft.c \
file-autoft.h \
+ flock.c \
+ flock.h \
format-template.c \
format-template.h \
func.c \
func.h \
func-builtin.c \
func-builtin.h \
--- gnumeric-1.6.2/src/main-application.c.dotlocking 2006-01-30
00:24:47.000000000 -0500
+++ gnumeric-1.6.2/src/main-application.c 2006-03-08 15:56:05.000000000
-0500
@@ -445,12 +445,16 @@ main (int argc, char const *argv [])
opened_workbook = TRUE;
icg_set_transient_for (IO_CONTEXT_GTK (ioc),
wbcg_toplevel (wbcg));
if (immediate_exit_flag)
wbcgs_to_kill = g_slist_prepend
(wbcgs_to_kill,
wbcg);
+
+ if (workbook_externally_locked (wbv->wb)) {
+ wb_view_adapt_to_locking (wbv, NULL,
WBV_EXT_LOCK_OPEN);
+ }
}
/* cheesy attempt to keep the ui from freezing during
load */
handle_paint_events ();
if (icg_get_interrupted (IO_CONTEXT_GTK (ioc)))
break; /* Don't load any more workbooks */
--- gnumeric-1.6.2/src/workbook-view.h.dotlocking 2005-06-08
15:03:16.000000000 -0400
+++ gnumeric-1.6.2/src/workbook-view.h 2006-03-08 15:56:05.000000000 -0500
@@ -1,6 +1,8 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t;
c-basic-offset: 8 -*- */
+
#ifndef GNUMERIC_WORKBOOK_VIEW_H
#define GNUMERIC_WORKBOOK_VIEW_H
#include "gnumeric.h"
#include <glib-object.h>
#include <gsf/gsf.h>
@@ -44,12 +46,19 @@ typedef struct {
#define WORKBOOK_VIEW_TYPE (workbook_view_get_type ())
#define WORKBOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
WORKBOOK_VIEW_TYPE, WorkbookView))
#define WORKBOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k),
WORKBOOK_VIEW_TYPE, WorkbookViewClass))
#define IS_WORKBOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o),
WORKBOOK_VIEW_TYPE))
+typedef enum {
+ WBV_EXT_LOCK_OPEN,
+ WBV_EXT_LOCK_SAVE,
+ WBV_EXT_LOCK_SAVEAS,
+ WBV_SELF_LOCK_FAULT
+} WbvLockNotification;
+
/* Lifecycle */
GType workbook_view_get_type (void);
WorkbookView *workbook_view_new (Workbook *optional_workbook);
void wb_view_attach_control (WorkbookView *wbv, WorkbookControl
*wbc);
void wb_view_detach_control (WorkbookControl *wbc);
--- gnumeric-1.6.2/src/gui-file.c.dotlocking 2005-11-14 01:34:04.000000000
-0500
+++ gnumeric-1.6.2/src/gui-file.c 2006-03-08 15:56:05.000000000 -0500
@@ -142,12 +142,16 @@ gui_wb_view_show (WorkbookControlGUI *wb
new_wbcg = WORKBOOK_CONTROL_GUI (new_wbc);
wbcg_copy_toolbar_visibility (new_wbcg, wbcg);
}
#endif
+ if (workbook_externally_locked (wbv->wb)) {
+ wb_view_adapt_to_locking (wbv, NULL, WBV_EXT_LOCK_OPEN);
+ }
+
sheet_update (wb_view_cur_sheet (wbv));
}
gboolean
gui_file_read (WorkbookControlGUI *wbcg, char const *uri,
GOFileOpener const *optional_format, gchar const
*optional_encoding)
--- gnumeric-1.6.2/src/workbook.h.dotlocking 2005-06-30 12:08:02.000000000
-0400
+++ gnumeric-1.6.2/src/workbook.h 2006-03-08 15:56:05.000000000 -0500
@@ -35,12 +35,14 @@ gboolean workbook_sheet_rename
GSList *new_names,
GOCmdContext *cc);
unsigned workbook_find_command (Workbook *wb,
gboolean is_undo, gpointer cmd);
+gboolean workbook_externally_locked (Workbook *wb);
+void workbook_set_externally_locked (Workbook *wb, gboolean state);
/* IO Routines */
gboolean workbook_set_uri (Workbook *wb, char const *uri);
char const *workbook_get_uri (Workbook const *wb);
gboolean workbook_set_saveinfo (Workbook *wb,
_______________________________________________
gnumeric-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnumeric-list