diff --git a/src/apps/icon-o-matic/IconEditorApp.cpp b/src/apps/icon-o-matic/IconEditorApp.cpp index d5c0231bac..c58ef8714a 100644 --- a/src/apps/icon-o-matic/IconEditorApp.cpp +++ b/src/apps/icon-o-matic/IconEditorApp.cpp @@ -62,7 +62,9 @@ IconEditorApp::IconEditorApp() fLastOpenPath(""), fLastSavePath(""), - fLastExportPath("") + fLastExportPath(""), + + fMessageAfterSave(NULL) { } @@ -76,6 +78,8 @@ IconEditorApp::~IconEditorApp() delete fOpenPanel; delete fSavePanel; + + delete fMessageAfterSave; } // #pragma mark - @@ -84,7 +88,9 @@ IconEditorApp::~IconEditorApp() bool IconEditorApp::QuitRequested() { - // TODO: ask main window if quitting is ok + if (!_CheckSaveIcon(CurrentMessage())) + return false; + _StoreSettings(); fMainWindow->Lock(); @@ -103,14 +109,12 @@ IconEditorApp::MessageReceived(BMessage* message) _MakeIconEmpty(); break; case MSG_OPEN: { -// fOpenPanel->Refresh(); BMessage openMessage(B_REFS_RECEIVED); fOpenPanel->SetMessage(&openMessage); fOpenPanel->Show(); break; } case MSG_APPEND: { -// fOpenPanel->Refresh(); BMessage openMessage(B_REFS_RECEIVED); openMessage.AddBool("append", true); fOpenPanel->SetMessage(&openMessage); @@ -126,6 +130,7 @@ IconEditorApp::MessageReceived(BMessage* message) saver = fDocument->ExportSaver(); if (saver) { saver->Save(fDocument); + _PickUpActionBeforeSave(); break; } // else fall through } @@ -153,6 +158,7 @@ IconEditorApp::MessageReceived(BMessage* message) else fDocument->SetExportSaver(saver); saver->Save(fDocument); + _PickUpActionBeforeSave(); } } _SyncPanels(fSavePanel, fOpenPanel); @@ -267,9 +273,61 @@ IconEditorApp::ArgvReceived(int32 argc, char** argv) // #pragma mark - +// _CheckSaveIcon +bool +IconEditorApp::_CheckSaveIcon(const BMessage* currentMessage) +{ + if (fDocument->IsEmpty() || fDocument->CommandStack()->IsSaved()) + return true; + + BAlert* alert = new BAlert("save", "Save changes to current icon?", + "Discard", "Cancel", "Save"); + int32 choice = alert->Go(); + switch (choice) { + case 0: + // discard + return true; + case 1: + // cancel + return false; + case 2: + default: + // cancel (save first) but pick what we were doing before + PostMessage(MSG_SAVE); + if (currentMessage) { + delete fMessageAfterSave; + fMessageAfterSave = new BMessage(*currentMessage); + } + return false; + } +} + +// _PickUpActionBeforeSave +void +IconEditorApp::_PickUpActionBeforeSave() +{ + if (fDocument->WriteLock()) { + fDocument->CommandStack()->Save(); + fDocument->WriteUnlock(); + } + + if (!fMessageAfterSave) + return; + + PostMessage(fMessageAfterSave); + delete fMessageAfterSave; + fMessageAfterSave = NULL; +} + +// #pragma mark - + +// _MakeIconEmpty void IconEditorApp::_MakeIconEmpty() { + if (!_CheckSaveIcon(CurrentMessage())) + return; + bool mainWindowLocked = fMainWindow && fMainWindow->Lock(); AutoWriteLocker locker(fDocument); @@ -289,6 +347,9 @@ IconEditorApp::_MakeIconEmpty() void IconEditorApp::_Open(const entry_ref& ref, bool append) { + if (!_CheckSaveIcon(CurrentMessage())) + return; + BFile file(&ref, B_READ_ONLY); if (file.InitCheck() < B_OK) return; @@ -390,6 +451,9 @@ void IconEditorApp::_Open(const BMessenger& externalObserver, const uint8* data, size_t size) { + if (!_CheckSaveIcon(CurrentMessage())) + return; + if (!externalObserver.IsValid()) return; diff --git a/src/apps/icon-o-matic/IconEditorApp.h b/src/apps/icon-o-matic/IconEditorApp.h index 41c0b30910..d19ee5663d 100644 --- a/src/apps/icon-o-matic/IconEditorApp.h +++ b/src/apps/icon-o-matic/IconEditorApp.h @@ -63,6 +63,9 @@ class IconEditorApp : public BApplication { // IconEditorApp private: + bool _CheckSaveIcon(const BMessage* currentMessage); + void _PickUpActionBeforeSave(); + void _MakeIconEmpty(); void _Open(const entry_ref& ref, bool append = false); @@ -89,6 +92,8 @@ class IconEditorApp : public BApplication { BString fLastOpenPath; BString fLastSavePath; BString fLastExportPath; + + BMessage* fMessageAfterSave; }; #endif // ICON_EDITOR_APP_H diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index 1df0a59aed..eeaf935175 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -215,6 +215,10 @@ case MSG_PATH_SELECTED: { VectorPath* path; if (message->FindPointer("path", (void**)&path) < B_OK) path = NULL; + + fPathListView->SetCurrentShape(NULL); + fStyleListView->SetCurrentShape(NULL); + fTransformerListView->SetShape(NULL); fState->DeleteManipulators(); if (fDocument->Icon()->Paths()->HasPath(path)) { @@ -223,7 +227,8 @@ case MSG_PATH_SELECTED: { } break; } -case MSG_STYLE_SELECTED: { +case MSG_STYLE_SELECTED: +case MSG_STYLE_TYPE_CHANGED: { Style* style; if (message->FindPointer("style", (void**)&style) < B_OK) style = NULL; @@ -231,14 +236,13 @@ case MSG_STYLE_SELECTED: { style = NULL; fStyleView->SetStyle(style); - break; -} -case MSG_GRADIENT_SELECTED: { - // if there is a gradient, add a transform box around it - Gradient* gradient; - if (message->FindPointer("gradient", (void**)&gradient) < B_OK) - gradient = NULL; + fPathListView->SetCurrentShape(NULL); + fStyleListView->SetCurrentShape(NULL); + fTransformerListView->SetShape(NULL); + fState->DeleteManipulators(); + Gradient* gradient = style ? style->Gradient() : NULL; + if (gradient) { TransformGradientBox* transformBox = new (nothrow) TransformGradientBox(fCanvasView, diff --git a/src/apps/icon-o-matic/document/Document.cpp b/src/apps/icon-o-matic/document/Document.cpp index 02b63492e8..ade4d275cc 100644 --- a/src/apps/icon-o-matic/document/Document.cpp +++ b/src/apps/icon-o-matic/document/Document.cpp @@ -12,7 +12,10 @@ #include "CommandStack.h" #include "DocumentSaver.h" #include "Icon.h" +#include "PathContainer.h" #include "Selection.h" +#include "ShapeContainer.h" +#include "StyleContainer.h" #include @@ -112,4 +115,12 @@ Document::MakeEmpty(bool includingSavers) } } +// IsEmpty +bool +Document::IsEmpty() const +{ + return fIcon->Styles()->CountStyles() == 0 + && fIcon->Paths()->CountPaths() == 0 + && fIcon->Shapes()->CountShapes() == 0; +} diff --git a/src/apps/icon-o-matic/document/Document.h b/src/apps/icon-o-matic/document/Document.h index b26bdf642a..7863b0c92d 100644 --- a/src/apps/icon-o-matic/document/Document.h +++ b/src/apps/icon-o-matic/document/Document.h @@ -57,6 +57,8 @@ class Document : public RWLocker, void MakeEmpty(bool includingSavers = true); + bool IsEmpty() const; + private: BPrivate::Icon::Icon* fIcon; ::CommandStack* fCommandStack; diff --git a/src/apps/icon-o-matic/generic/gui/ListViews.cpp b/src/apps/icon-o-matic/generic/gui/ListViews.cpp index cd95f8c4db..f2f2dccd47 100644 --- a/src/apps/icon-o-matic/generic/gui/ListViews.cpp +++ b/src/apps/icon-o-matic/generic/gui/ListViews.cpp @@ -533,9 +533,10 @@ DragSortableListView::MouseWheelChanged(float x, float y) void DragSortableListView::ObjectChanged(const Observable* object) { - if (object != fSelection || fModifyingSelection) + if (object != fSelection || fModifyingSelection || fSyncingToSelection) return; +//printf("%s - syncing start\n", Name()); fSyncingToSelection = true; // try to sync to Selection @@ -567,6 +568,7 @@ DragSortableListView::ObjectChanged(const Observable* object) } fSyncingToSelection = false; +//printf("%s - done\n", Name()); } // #pragma mark - @@ -813,7 +815,7 @@ DragSortableListView::SelectionChanged() { //printf("%s::SelectionChanged()", typeid(*this).name()); // modify global Selection - if (!fSelection) + if (!fSelection || fSyncingToSelection) return; fModifyingSelection = true; diff --git a/src/apps/icon-o-matic/gui/PathListView.cpp b/src/apps/icon-o-matic/gui/PathListView.cpp index 7244c95216..eb3b7fcb55 100644 --- a/src/apps/icon-o-matic/gui/PathListView.cpp +++ b/src/apps/icon-o-matic/gui/PathListView.cpp @@ -623,7 +623,7 @@ PathListView::PathAdded(VectorPath* path, int32 index) return; if (_AddPath(path, index)) - Select(CountItems() - 1); + Select(index); UnlockLooper(); } diff --git a/src/apps/icon-o-matic/gui/ShapeListView.cpp b/src/apps/icon-o-matic/gui/ShapeListView.cpp index dc78ee1958..3bdb154a17 100644 --- a/src/apps/icon-o-matic/gui/ShapeListView.cpp +++ b/src/apps/icon-o-matic/gui/ShapeListView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku. + * Copyright 2006-2007, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -129,7 +129,6 @@ ShapeListView::~ShapeListView() void ShapeListView::SelectionChanged() { - SimpleListView::SelectionChanged(); if (!fSyncingToSelection) { @@ -387,7 +386,8 @@ ShapeListView::ShapeAdded(Shape* shape, int32 index) if (!LockLooper()) return; - _AddShape(shape, index); + if (_AddShape(shape, index)) + Select(index); UnlockLooper(); } diff --git a/src/apps/icon-o-matic/gui/StyleListView.cpp b/src/apps/icon-o-matic/gui/StyleListView.cpp index cc5ae4920b..9d3b2e01b5 100644 --- a/src/apps/icon-o-matic/gui/StyleListView.cpp +++ b/src/apps/icon-o-matic/gui/StyleListView.cpp @@ -555,10 +555,8 @@ StyleListView::StyleAdded(Style* style, int32 index) if (!LockLooper()) return; - // NOTE: shapes are always added at the end - // of the list, so the sorting is synced... if (_AddStyle(style, index)) - Select(CountItems() - 1); + Select(index); UnlockLooper(); } diff --git a/src/apps/icon-o-matic/gui/StyleView.cpp b/src/apps/icon-o-matic/gui/StyleView.cpp index 3aa3e0ec89..0925cdb760 100644 --- a/src/apps/icon-o-matic/gui/StyleView.cpp +++ b/src/apps/icon-o-matic/gui/StyleView.cpp @@ -267,7 +267,7 @@ StyleView::ObjectChanged(const Observable* object) // TODO: is this really necessary? controlGradient->SetTransform(*fGradient); - if (*fGradient != *controlGradient) { + if (!fGradient->ColorStepsAreEqual(*controlGradient)) { if (fCommandStack) { fCommandStack->Perform( new (nothrow) SetGradientCommand( @@ -279,7 +279,7 @@ StyleView::ObjectChanged(const Observable* object) _TransferGradientStopColor(); } } else if (object == fGradient) { - if (*fGradient != *controlGradient) { + if (!fGradient->ColorStepsAreEqual(*controlGradient)) { fGradientControl->SetGradient(fGradient); _MarkType(fGradientType->Menu(), fGradient->Type()); // transfer the current gradient color to the current color @@ -288,7 +288,7 @@ StyleView::ObjectChanged(const Observable* object) } else if (object == fStyle) { // maybe the gradient was added or removed // or the color changed - _SetGradient(fStyle->Gradient()); + _SetGradient(fStyle->Gradient(), false, true); if (fCurrentColor && !fStyle->Gradient()) fCurrentColor->SetColor(fStyle->Color()); } else if (object == fCurrentColor) { @@ -361,7 +361,7 @@ StyleView::SetCurrentColor(CurrentColor* color) // _SetGradient void -StyleView::_SetGradient(Gradient* gradient, bool forceControlUpdate) +StyleView::_SetGradient(Gradient* gradient, bool forceControlUpdate, bool sendMessage) { if (!forceControlUpdate && fGradient == gradient) return; @@ -387,9 +387,9 @@ StyleView::_SetGradient(Gradient* gradient, bool forceControlUpdate) _MarkType(fGradientType->Menu(), -1); } - if (Window()) { - BMessage message(MSG_GRADIENT_SELECTED); - message.AddPointer("gradient", (void*)fGradient); + if (sendMessage) { + BMessage message(MSG_STYLE_TYPE_CHANGED); + message.AddPointer("style", fStyle); Window()->PostMessage(&message); } } diff --git a/src/apps/icon-o-matic/gui/StyleView.h b/src/apps/icon-o-matic/gui/StyleView.h index 793e25f057..96f5b04b0b 100644 --- a/src/apps/icon-o-matic/gui/StyleView.h +++ b/src/apps/icon-o-matic/gui/StyleView.h @@ -31,7 +31,7 @@ using namespace BPrivate::Icon; // TODO: write lock the document when changing something... enum { - MSG_GRADIENT_SELECTED = 'grsl', + MSG_STYLE_TYPE_CHANGED = 'stch', }; class StyleView : public BView, @@ -59,7 +59,8 @@ class StyleView : public BView, private: void _SetGradient(Gradient* gradient, - bool forceControlUpdate = false); + bool forceControlUpdate = false, + bool sendMessage = false); void _MarkType(BMenu* menu, int32 type) const; void _SetStyleType(int32 type); diff --git a/src/apps/icon-o-matic/shape/commands/AddShapesCommand.cpp b/src/apps/icon-o-matic/shape/commands/AddShapesCommand.cpp index 20c31989bc..89090fda99 100644 --- a/src/apps/icon-o-matic/shape/commands/AddShapesCommand.cpp +++ b/src/apps/icon-o-matic/shape/commands/AddShapesCommand.cpp @@ -72,8 +72,6 @@ AddShapesCommand::Perform() fContainer->RemoveShape(fShapes[j]); break; } - if (fSelection) - fSelection->Select(fShapes[i], i > 0); index++; } fShapesAdded = true; diff --git a/src/libs/icon/style/Gradient.cpp b/src/libs/icon/style/Gradient.cpp index 609bfcfc4e..7b0e2e0d27 100644 --- a/src/libs/icon/style/Gradient.cpp +++ b/src/libs/icon/style/Gradient.cpp @@ -227,25 +227,8 @@ Gradient::operator=(const Gradient& other) bool Gradient::operator==(const Gradient& other) const { - if (Transformable::operator==(other)) { - int32 count = CountColors(); - if (count == other.CountColors() && - fType == other.fType && - fInterpolation == other.fInterpolation && - fInheritTransformation == other.fInheritTransformation) { - - bool equal = true; - for (int32 i = 0; i < count; i++) { - color_step* ourStep = ColorAtFast(i); - color_step* otherStep = other.ColorAtFast(i); - if (*ourStep != *otherStep) { - equal = false; - break; - } - } - return equal; - } - } + if (Transformable::operator==(other)) + return ColorStepsAreEqual(other); return false; } @@ -256,6 +239,30 @@ Gradient::operator!=(const Gradient& other) const return !(*this == other); } +// ColorStepsAreEqual +bool +Gradient::ColorStepsAreEqual(const Gradient& other) const +{ + int32 count = CountColors(); + if (count == other.CountColors() && + fType == other.fType && + fInterpolation == other.fInterpolation && + fInheritTransformation == other.fInheritTransformation) { + + bool equal = true; + for (int32 i = 0; i < count; i++) { + color_step* ourStep = ColorAtFast(i); + color_step* otherStep = other.ColorAtFast(i); + if (*ourStep != *otherStep) { + equal = false; + break; + } + } + return equal; + } + return false; +} + // SetColors void Gradient::SetColors(const Gradient& other) diff --git a/src/libs/icon/style/Gradient.h b/src/libs/icon/style/Gradient.h index aae25fcd20..ac1f82938a 100644 --- a/src/libs/icon/style/Gradient.h +++ b/src/libs/icon/style/Gradient.h @@ -78,6 +78,8 @@ class Gradient : public Transformable { bool operator==(const Gradient& other) const; bool operator!=(const Gradient& other) const; + bool ColorStepsAreEqual( + const Gradient& other) const; void SetColors(const Gradient& other);