mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 04:19:12 +00:00
Fix bug #14, don't ask for saving changes when read-only commands are used.
+ Added a new attribute for each undo item (undo::Modification). + Each item now modifies or does not modify the document (e.g. selection actions do not modify the document). + Added an asterisk in tabs when the document is modified.
This commit is contained in:
parent
4fcbc7b6df
commit
f854c7acf5
15
src/app.cpp
15
src/app.cpp
@ -378,11 +378,22 @@ void app_rebuild_documents_tabs()
|
||||
// Insert all other sprites
|
||||
for (Documents::const_iterator
|
||||
it = docs.begin(), end = docs.end(); it != end; ++it) {
|
||||
Document* document = *it;
|
||||
tabsbar->setTabText(get_filename(document->getFilename()), document);
|
||||
const Document* document = *it;
|
||||
app_update_document_tab(document);
|
||||
}
|
||||
}
|
||||
|
||||
void app_update_document_tab(const Document* document)
|
||||
{
|
||||
std::string str = get_filename(document->getFilename());
|
||||
|
||||
// Add an asterisk if the document is modified.
|
||||
if (document->isModified())
|
||||
str += "*";
|
||||
|
||||
tabsbar->setTabText(str.c_str(), const_cast<Document*>(document));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the recent list menu.
|
||||
*
|
||||
|
@ -87,6 +87,7 @@ private:
|
||||
void app_refresh_screen(const Document* document);
|
||||
|
||||
void app_rebuild_documents_tabs();
|
||||
void app_update_document_tab(const Document* document);
|
||||
bool app_realloc_recent_list();
|
||||
|
||||
int app_get_current_image_type();
|
||||
|
@ -141,6 +141,7 @@ void CelPropertiesCommand::onExecute(Context* context)
|
||||
cel_writer->opacity != new_opacity) {
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Cel Opacity Change");
|
||||
undo->setModification(undo::ModifyDocument);
|
||||
undo->undo_int(cel_writer, &cel_writer->opacity);
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ void DeselectMaskCommand::onExecute(Context* context)
|
||||
{
|
||||
ActiveDocumentWriter document(context);
|
||||
{
|
||||
UndoTransaction undoTransaction(document, "Mask Deselection");
|
||||
UndoTransaction undoTransaction(document, "Mask Deselection", undo::DoesntModifyDocument);
|
||||
undoTransaction.deselectMask();
|
||||
undoTransaction.commit();
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ void InvertMaskCommand::onExecute(Context* context)
|
||||
/* undo */
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Mask Invert");
|
||||
undo->setModification(undo::DoesntModifyDocument);
|
||||
undo->undo_set_mask(document);
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ void LoadMaskCommand::onExecute(Context* context)
|
||||
// Add the mask change into the undo history.
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Mask Load");
|
||||
undo->setModification(undo::DoesntModifyDocument);
|
||||
undo->undo_set_mask(document);
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@ void MaskAllCommand::onExecute(Context* context)
|
||||
// Undo
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Mask All");
|
||||
undo->setModification(undo::DoesntModifyDocument);
|
||||
undo->undo_set_mask(document);
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,7 @@ void MergeDownLayerCommand::onExecute(Context* context)
|
||||
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Merge Down Layer");
|
||||
undo->setModification(undo::ModifyDocument);
|
||||
undo->undo_open();
|
||||
}
|
||||
|
||||
|
@ -667,6 +667,7 @@ void PaletteEntryEditor::updateCurrentSpritePalette(const char* operationName)
|
||||
// Add undo information to save the range of pal entries that will be modified.
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel(operationName);
|
||||
undo->setModification(undo::ModifyDocument);
|
||||
undo->undo_set_palette_colors(sprite, currentSpritePalette, from, to);
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ void ReselectMaskCommand::onExecute(Context* context)
|
||||
// Undo
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Mask Reselection");
|
||||
undo->setModification(undo::DoesntModifyDocument);
|
||||
undo->undo_set_mask(document);
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,10 @@ static void save_document_in_background(Document* document, bool mark_as_saved)
|
||||
delete data->progress;
|
||||
fop_free(fop);
|
||||
delete data;
|
||||
|
||||
// Update the tab for the document. In this moment, the document is
|
||||
// already marked as saved, so the * is not shown in the tab.
|
||||
app_update_document_tab(document);
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
@ -179,9 +183,10 @@ static void save_as_dialog(Document* document, const char* dlg_title, bool mark_
|
||||
/* "no": we must back to select other file-name */
|
||||
}
|
||||
|
||||
// Change the document file name
|
||||
document->setFilename(filename.c_str());
|
||||
app_rebuild_documents_tabs();
|
||||
|
||||
// Save the document
|
||||
save_document_in_background(document, mark_as_saved);
|
||||
}
|
||||
|
||||
@ -305,7 +310,6 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
|
||||
|
||||
// Restore the file name.
|
||||
document->setFilename(old_filename.c_str());
|
||||
app_rebuild_documents_tabs();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -208,6 +208,7 @@ void FilterManagerImpl::apply()
|
||||
// Undo stuff
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel(m_filter->getName());
|
||||
undo->setModification(undo::ModifyDocument);
|
||||
undo->undo_image(m_src, m_x, m_y, m_w, m_h);
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,7 @@ void dialogs_mask_color(Document* document)
|
||||
/* undo */
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Mask by Color");
|
||||
undo->setModification(undo::DoesntModifyDocument);
|
||||
undo->undo_set_mask(document);
|
||||
}
|
||||
|
||||
|
@ -456,6 +456,9 @@ void update_screen_for_document(const Document* document)
|
||||
// If it's the same palette update only the editors with the sprite.
|
||||
update_editors_with_document(document);
|
||||
}
|
||||
|
||||
// Update the tabs (maybe the modified status has been changed).
|
||||
app_update_document_tab(document);
|
||||
}
|
||||
}
|
||||
|
||||
|
23
src/undo/modification.h
Normal file
23
src/undo/modification.h
Normal file
@ -0,0 +1,23 @@
|
||||
// ASEPRITE Undo Library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#ifndef UNDO_MODIFICATION_H_INCLUDED
|
||||
#define UNDO_MODIFICATION_H_INCLUDED
|
||||
|
||||
namespace undo {
|
||||
|
||||
// The modification flag is used to know if an Undoer item
|
||||
// modifies the document's "saved state". It means that if the
|
||||
// item modifies the document the user should be asked for "save
|
||||
// changes" when he closes the document.
|
||||
enum Modification {
|
||||
ModifyDocument, // This item changes the "saved status" of the document.
|
||||
DoesntModifyDocument // This item doesn't modify the document.
|
||||
};
|
||||
|
||||
} // namespace undo
|
||||
|
||||
#endif // UNDO_MODIFICATION_H_INCLUDED
|
@ -23,6 +23,7 @@ UndoHistory::UndoHistory(ObjectsContainer* objects)
|
||||
m_diffSaved = 0;
|
||||
m_enabled = true;
|
||||
m_label = NULL;
|
||||
m_modification = ModifyDocument;
|
||||
|
||||
m_undoers = new UndoersStack(this);
|
||||
try {
|
||||
@ -86,6 +87,16 @@ void UndoHistory::setLabel(const char* label)
|
||||
m_label = label;
|
||||
}
|
||||
|
||||
Modification UndoHistory::getModification()
|
||||
{
|
||||
return m_modification;
|
||||
}
|
||||
|
||||
void UndoHistory::setModification(Modification mod)
|
||||
{
|
||||
m_modification = mod;
|
||||
}
|
||||
|
||||
const char* UndoHistory::getNextUndoLabel() const
|
||||
{
|
||||
ASSERT(canUndo());
|
||||
@ -120,8 +131,13 @@ void UndoHistory::runUndo(Direction direction)
|
||||
|
||||
do {
|
||||
const char* itemLabel = NULL;
|
||||
if (!undoers->empty())
|
||||
itemLabel = (*undoers->begin())->getLabel();
|
||||
Modification itemModification = DoesntModifyDocument;
|
||||
|
||||
if (!undoers->empty()) {
|
||||
UndoersStack::Item* item = *undoers->begin();
|
||||
itemLabel = item->getLabel();
|
||||
itemModification = item->getModification();
|
||||
}
|
||||
|
||||
Undoer* undoer = undoers->popUndoer(UndoersStack::PopFromHead);
|
||||
if (!undoer)
|
||||
@ -138,10 +154,12 @@ void UndoHistory::runUndo(Direction direction)
|
||||
// Delete the undoer
|
||||
undoer->dispose();
|
||||
|
||||
if (direction == UndoDirection)
|
||||
m_diffCount--;
|
||||
else if (direction == RedoDirection)
|
||||
m_diffCount++;
|
||||
if (itemModification == ModifyDocument) {
|
||||
if (direction == UndoDirection)
|
||||
m_diffCount--;
|
||||
else if (direction == RedoDirection)
|
||||
m_diffCount++;
|
||||
}
|
||||
} while (level);
|
||||
}
|
||||
|
||||
@ -176,7 +194,8 @@ void UndoHistory::pushUndoer(Undoer* undoer)
|
||||
int undo_size_limit = (int)get_config_int("Options", "UndoSizeLimit", 8)*1024*1024;
|
||||
|
||||
// More differences.
|
||||
m_diffCount++;
|
||||
if (m_modification == ModifyDocument)
|
||||
m_diffCount++;
|
||||
|
||||
// Reset the "redo" stack.
|
||||
clearRedo();
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef UNDO_UNDO_HISTORY_H_INCLUDED
|
||||
#define UNDO_UNDO_HISTORY_H_INCLUDED
|
||||
|
||||
#include "undo/modification.h"
|
||||
#include "undo/undoers_collector.h"
|
||||
|
||||
#include <vector>
|
||||
@ -45,9 +46,16 @@ public:
|
||||
|
||||
void clearRedo();
|
||||
|
||||
// Current label for next added Undoers.
|
||||
const char* getLabel();
|
||||
void setLabel(const char* label);
|
||||
|
||||
// Change the "modify saved status" flag to be assigned for next
|
||||
// added items. When it is activated means that each added Undoer
|
||||
// modifies the "saved status" of the document.
|
||||
Modification getModification();
|
||||
void setModification(Modification mod);
|
||||
|
||||
const char* getNextUndoLabel() const;
|
||||
const char* getNextRedoLabel() const;
|
||||
|
||||
@ -109,6 +117,7 @@ private:
|
||||
int m_diffSaved;
|
||||
bool m_enabled; // Is undo enabled?
|
||||
const char* m_label; // Current label to be applied to all next undo operations.
|
||||
Modification m_modification; // Current label to be applied to all next undo operations.
|
||||
};
|
||||
|
||||
} // namespace undo
|
||||
|
@ -50,7 +50,8 @@ void UndoersStack::pushUndoer(Undoer* undoer)
|
||||
ASSERT(undoer != NULL);
|
||||
|
||||
try {
|
||||
Item* item = new Item(m_undoHistory->getLabel(), undoer);
|
||||
Item* item = new Item(m_undoHistory->getLabel(),
|
||||
m_undoHistory->getModification(), undoer);
|
||||
try {
|
||||
m_items.insert(begin(), item);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef UNDO_UNDOERS_STACK_H_INCLUDED
|
||||
#define UNDO_UNDOERS_STACK_H_INCLUDED
|
||||
|
||||
#include "undo/modification.h"
|
||||
#include "undo/undoers_collector.h"
|
||||
|
||||
#include <vector>
|
||||
@ -32,14 +33,18 @@ public:
|
||||
class Item
|
||||
{
|
||||
public:
|
||||
Item(const char* label, Undoer* undoer)
|
||||
Item(const char* label, Modification mod, Undoer* undoer)
|
||||
: m_label(label)
|
||||
, m_mod(mod)
|
||||
, m_undoer(undoer) { }
|
||||
|
||||
const char* getLabel() const { return m_label; }
|
||||
Modification getModification() const { return m_mod; }
|
||||
Undoer* getUndoer() const { return m_undoer; }
|
||||
|
||||
private:
|
||||
const char* m_label;
|
||||
Modification m_mod;
|
||||
Undoer* m_undoer;
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "raster/stock.h"
|
||||
#include "undo/undo_history.h"
|
||||
|
||||
UndoTransaction::UndoTransaction(Document* document, const char* label)
|
||||
UndoTransaction::UndoTransaction(Document* document, const char* label, undo::Modification modification)
|
||||
{
|
||||
ASSERT(label != NULL);
|
||||
|
||||
@ -46,6 +46,7 @@ UndoTransaction::UndoTransaction(Document* document, const char* label)
|
||||
|
||||
if (isEnabled()) {
|
||||
m_undoHistory->setLabel(label);
|
||||
m_undoHistory->setModification(modification);
|
||||
m_undoHistory->undo_open();
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define UNDO_TRANSACTION_H_INCLUDED
|
||||
|
||||
#include "raster/dithering_method.h"
|
||||
#include "undo/modification.h"
|
||||
|
||||
class Cel;
|
||||
class Document;
|
||||
@ -55,7 +56,7 @@ public:
|
||||
// Starts a undoable sequence of operations in a transaction that
|
||||
// can be committed or rollbacked. All the operations will be
|
||||
// grouped in the sprite's undo as an atomic operation.
|
||||
UndoTransaction(Document* document, const char* label);
|
||||
UndoTransaction(Document* document, const char* label, undo::Modification mod = undo::ModifyDocument);
|
||||
virtual ~UndoTransaction();
|
||||
|
||||
inline Sprite* getSprite() const { return m_sprite; }
|
||||
|
@ -72,6 +72,7 @@ void move_cel(DocumentWriter& document)
|
||||
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Move Cel");
|
||||
undo->setModification(undo::ModifyDocument);
|
||||
undo->undo_open();
|
||||
|
||||
undo->undo_set_layer(sprite);
|
||||
@ -161,6 +162,7 @@ void copy_cel(DocumentWriter& document)
|
||||
|
||||
if (undo->isEnabled()) {
|
||||
undo->setLabel("Move Cel");
|
||||
undo->setModification(undo::ModifyDocument);
|
||||
undo->undo_open();
|
||||
|
||||
undo->undo_set_layer(sprite);
|
||||
|
@ -156,6 +156,7 @@ int interactive_move_layer(int mode, bool use_undo, int (*callback)())
|
||||
if (!editor->editor_click_cancel()) {
|
||||
if (use_undo && undo->isEnabled()) {
|
||||
undo->setLabel("Cel Movement");
|
||||
undo->setModification(undo::ModifyDocument);
|
||||
undo->undo_open();
|
||||
undo->undo_int(cel, &cel->x);
|
||||
undo->undo_int(cel, &cel->y);
|
||||
|
@ -1900,8 +1900,17 @@ public:
|
||||
m_offset.y = -y1;
|
||||
|
||||
// Set undo label for any kind of undo used in the whole loop
|
||||
if (m_document->getUndoHistory()->isEnabled())
|
||||
if (m_document->getUndoHistory()->isEnabled()) {
|
||||
m_document->getUndoHistory()->setLabel(m_tool->getText().c_str());
|
||||
|
||||
if (getInk()->isSelection() ||
|
||||
getInk()->isEyedropper() ||
|
||||
getInk()->isScrollMovement()) {
|
||||
m_document->getUndoHistory()->setModification(undo::DoesntModifyDocument);
|
||||
}
|
||||
else
|
||||
m_document->getUndoHistory()->setModification(undo::ModifyDocument);
|
||||
}
|
||||
}
|
||||
|
||||
~ToolLoopImpl()
|
||||
|
Loading…
x
Reference in New Issue
Block a user