Skip to content

Commit

Permalink
infobars: Make document read-only while infobar is shown.
Browse files Browse the repository at this point in the history
This avoids accidental changes the file until the infobar is ackowledged. The
document can still be viewed and scrolled through but modifications and saving
are disabled. Of course ignoring the document by changing to another one is
also possible.
  • Loading branch information
kugel- committed May 24, 2014
1 parent 43bff93 commit 5117940
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
42 changes: 39 additions & 3 deletions src/document.c
Expand Up @@ -1238,6 +1238,7 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename

doc->readonly = readonly || filedata.readonly;
sci_set_readonly(doc->editor->sci, doc->readonly);
doc->priv->protected = 0;

/* update line number margin width */
doc->priv->line_count = sci_get_line_count(doc->editor->sci);
Expand Down Expand Up @@ -1491,6 +1492,22 @@ void document_rename_file(GeanyDocument *doc, const gchar *new_filename)
}


static void protect_document(GeanyDocument *doc)
{
/* do not call queue_colourise because to we want to keep the text-changed indication! */
if (!doc->priv->protected++)
sci_set_readonly(doc->editor->sci, TRUE);
}

static void unprotect_document(GeanyDocument *doc)
{
g_return_if_fail(doc->priv->protected > 0);

if (!--doc->priv->protected && doc->readonly == FALSE)
sci_set_readonly(doc->editor->sci, FALSE);
}


/* Return TRUE if the document doesn't have a full filename set.
* This makes filenames without a path show the save as dialog, e.g. for file templates.
* Otherwise just use the set filename instead of asking the user - e.g. for command-line
Expand All @@ -1517,9 +1534,11 @@ gboolean document_need_save_as(GeanyDocument *doc)
gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname)
{
gboolean ret;
gboolean new_file;

g_return_val_if_fail(doc != NULL, FALSE);

new_file = document_need_save_as(doc) || (utf8_fname != NULL && !strcmp(doc->file_name, utf8_fname));
if (utf8_fname != NULL)
SETPTR(doc->file_name, g_strdup(utf8_fname));

Expand All @@ -1539,6 +1558,15 @@ gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname)
ignore_callback = FALSE;
}
}

if (new_file)
{
sci_set_readonly(doc->editor->sci, FALSE);
doc->readonly = FALSE;
if (doc->priv->protected > 0)
unprotect_document(doc);
}

This comment has been minimized.

Copy link
@ntrel

ntrel Sep 23, 2014

Member

@kugel- This code needs at least a comment. Why is document_need_save_as part of the check? That doesn't seem relevant. Why is read-only cancelled, even when the document is not protected?

This comment has been minimized.

Copy link
@kugel-

kugel- Sep 24, 2014

Author Member

The need_save_as flag is set in some situations where the other condition doesn't evaluate to true (e.g. files generated by GeanyVC). The result of this flag is that a new file is created (logically).

I agree that cancelling doc->readonly looks unrelated here. I can't remember if I had a specific reason to do this here. But wasn't it always Geany's intended behavior to make readonly files writable when saving them under a different name?

This comment has been minimized.

Copy link
@ntrel

ntrel Sep 24, 2014

Member

The need_save_as flag is set in some situations ... The result of this flag is that a new file is created

BTW it's a function, not a flag: return (doc->file_name == NULL || !g_path_is_absolute(doc->file_name));

When that is TRUE, the document doesn't have a file on disk, so why would it have been protected?

wasn't it always Geany's intended behavior to make readonly files writable when saving them under a different name?

I suppose that's a good behaviour. But please try to list any non-obvious changes in the commit message next time ;-)


replace_header_filename(doc);

ret = document_save_file(doc, TRUE);
Expand Down Expand Up @@ -1729,7 +1757,6 @@ static gchar *save_doc(GeanyDocument *doc, const gchar *locale_filename,
return NULL;
}


/**
* Saves the document.
* Also shows the Save As dialog if necessary.
Expand Down Expand Up @@ -1773,7 +1800,9 @@ gboolean document_save_file(GeanyDocument *doc, gboolean force)
}

/* the "changed" flag should exclude the "readonly" flag, but check it anyway for safety */
if (! force && (! doc->changed || doc->readonly))
if (doc->readonly || doc->priv->protected)
return FALSE;
if (!force && !doc->changed)
return FALSE;

This comment has been minimized.

Copy link
@ntrel

ntrel Sep 23, 2014

Member

@kugel- Here read-only documents are now not saved when force is set. Do we want this change?

This comment has been minimized.

Copy link
@kugel-

kugel- Sep 24, 2014

Author Member

read-only documents should never be written to disk/saved (except via save as, under a different name). Normally a read-only file cannot have changes anyway (there is no way to change a writable or even changed file to read-only). But there's a setting to allow saving even if the file has no changes, therefore checking here is important.

This comment has been minimized.

Copy link
@ntrel

ntrel Sep 24, 2014

Member

BTW doc->readonly just means that a document was set (by the user) to not receive further changes at some point in its history, it's not related to the file permissions.

read-only documents should never be written to disk/saved

Normally. But what if the file has been accidentally overwritten or deleted? I think it's better to respect the force argument.

This comment has been minimized.

Copy link
@kugel-

kugel- Sep 25, 2014

Author Member

Normally. But what if the file has been accidentally overwritten or deleted? I think it's better to respect the force argument.

Exactly because it's set by the user and not based on permission we should assume the user doesn't want to touch the file at all, not even changing the timestamp. Your case can be accomplished by saving under a different name and then rename back to the old name (via Geany's 'rename as' or OS tools).

Anyway this is an edge case so I don't feel strong about it.

This comment has been minimized.

Copy link
@ntrel

ntrel Sep 25, 2014

Member

OK, I changed #335 to warn the user when attempting to save a read-only document. I think an easier workaround is to temporarily disable Document->Read-only.


fp = project_get_file_prefs();
Expand Down Expand Up @@ -2928,6 +2957,7 @@ GeanyDocument *document_clone(GeanyDocument *old_doc)
old_doc->editor->indent_width);
doc->readonly = old_doc->readonly;
doc->has_bom = old_doc->has_bom;
doc->priv->protected = 0;
document_set_encoding(doc, old_doc->encoding);
sci_set_lines_wrapped(doc->editor->sci, doc->editor->line_wrapping);
sci_set_readonly(doc->editor->sci, doc->readonly);
Expand Down Expand Up @@ -3114,6 +3144,8 @@ static GtkWidget* document_show_message(GeanyDocument *doc, GtkMessageType msgty

static void on_monitor_reload_file_response(GtkWidget *bar, gint response_id, GeanyDocument *doc)
{
unprotect_document(doc);

if (response_id == GTK_RESPONSE_ACCEPT)
document_reload_file(doc, doc->encoding);
}
Expand All @@ -3131,7 +3163,7 @@ static void monitor_reload_file(GeanyDocument *doc)
_("The file '%s' on the disk is more recent than the current buffer."),
base_name);

document_set_text_changed(doc, TRUE);
protect_document(doc);

g_free(base_name);
}
Expand All @@ -3143,6 +3175,8 @@ static void on_monitor_resave_missing_file_response(GtkWidget *bar,
{
gboolean file_saved = FALSE;

unprotect_document(doc);

if (response_id == GTK_RESPONSE_ACCEPT)
file_saved = dialogs_show_save_as();

Expand All @@ -3164,6 +3198,8 @@ static void monitor_resave_missing_file(GeanyDocument *doc)
_("Try to resave the file?"),
_("File \"%s\" was not found on disk!"),
doc->file_name);

protect_document(doc);
}


Expand Down
3 changes: 3 additions & 0 deletions src/documentprivate.h
Expand Up @@ -86,6 +86,9 @@ typedef struct GeanyDocumentPrivate
time_t mtime;
/* ID of the idle callback updating the tag list */
guint tag_list_update_source;
/* Whether it's temoporarily protected (read-only and saving is prevented). Does
* not imply doc->readonly as writable files can be protected */
gint protected;
}
GeanyDocumentPrivate;

Expand Down

1 comment on commit 5117940

@ntrel
Copy link
Member

@ntrel ntrel commented on 5117940 Sep 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I've made #335, but I'll correct it if necessary.

Please sign in to comment.