[haiku-commits] haiku: hrev44117 - in src: apps/icon-o-matic/gui libs/icon/shape

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 6 May 2012 16:54:37 +0200 (CEST)

hrev44117 adds 3 changesets to branch 'master'
old head: 85fb3e7df81f8d5b6e47a9a64a53873ea906ea6e
new head: e4ef668253317fde1251f6c3130a71c4ace68600

----------------------------------------------------------------------------

7a20125: Style cleanup, no functional change intended

2d35ee0: Added operator== implementation

e4ef668: Implemented drag&drop of shape items between I-O-M windows.
  
   * The ShapeListView also knows the PathContainer and StyleContainer
   * When constructing the drag message, also include a complete archive
     of the dragged shapes, bundled with archives for each included path
     and the style.
   * When handling the drop, and it came from another I-O-M window,
     exract the Shape archive bundle from the drag message. For the
     Style and the included Paths, try to find an existing Style and
     existing Paths and reference those in the added Shape(s) instead
     of adding duplicates.

                                      [ Stephan Aßmus <superstippi@xxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 378 insertions(+), 149 deletions(-)
src/apps/icon-o-matic/MainWindow.cpp        |    2 +
src/apps/icon-o-matic/gui/ShapeListView.cpp |  481 ++++++++++++++++-------
src/apps/icon-o-matic/gui/ShapeListView.h   |   10 +-
src/libs/icon/shape/VectorPath.cpp          |   30 +-
src/libs/icon/shape/VectorPath.h            |    4 +-

############################################################################

Commit:      7a20125661e8c32c53f1b2401a3c0bd60134d626
URL:         http://cgit.haiku-os.org/haiku/commit/?id=7a20125
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Sun May  6 13:26:52 2012 UTC

Style cleanup, no functional change intended

----------------------------------------------------------------------------

diff --git a/src/apps/icon-o-matic/gui/ShapeListView.cpp 
b/src/apps/icon-o-matic/gui/ShapeListView.cpp
index 6dd90cc..04fa6ea 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-2009, Haiku, Inc. All rights reserved.
+ * Copyright 2006-2012, Haiku, Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -41,64 +41,68 @@
 
 using std::nothrow;
 
-class ShapeListItem : public SimpleItem,
-                                         public Observer {
- public:
-                                       ShapeListItem(Shape* s,
-                                                                 
ShapeListView* listView)
-                                               : SimpleItem(""),
-                                                 shape(NULL),
-                                                 fListView(listView)
-                                       {
-                                               SetClip(s);
-                                       }
-
-       virtual                 ~ShapeListItem()
-                                       {
-                                               SetClip(NULL);
-                                       }
-
-       virtual void    ObjectChanged(const Observable* object)
-                                       {
-                                               UpdateText();
-                                       }
-
-                       void    SetClip(Shape* s)
-                                       {
-                                               if (s == shape)
-                                                       return;
-
-                                               if (shape) {
-                                                       
shape->RemoveObserver(this);
-                                                       shape->Release();
-                                               }
-
-                                               shape = s;
-
-                                               if (shape) {
-                                                       shape->Acquire();
-                                                       
shape->AddObserver(this);
-                                                       UpdateText();
-                                               }
-                                       }
-                       void    UpdateText()
-                                       {
-                                               SetText(shape->Name());
-                                               // :-/
-                                               if (fListView->LockLooper()) {
-                                                       
fListView->InvalidateItem(
-                                                               
fListView->IndexOf(this));
-                                                       
fListView->UnlockLooper();
-                                               }
-                                       }
+class ShapeListItem : public SimpleItem, public Observer {
+public:
+       ShapeListItem(Shape* s, ShapeListView* listView)
+               :
+               SimpleItem(""),
+               shape(NULL),
+               fListView(listView)
+       {
+               SetShape(s);
+       }
+
+
+       virtual ~ShapeListItem()
+       {
+               SetShape(NULL);
+       }
+
+
+       virtual void ObjectChanged(const Observable* object)
+       {
+               UpdateText();
+       }
+
+       void SetShape(Shape* s)
+       {
+               if (s == shape)
+                       return;
+
+               if (shape) {
+                       shape->RemoveObserver(this);
+                       shape->Release();
+               }
+
+               shape = s;
+
+               if (shape) {
+                       shape->Acquire();
+                       shape->AddObserver(this);
+                       UpdateText();
+               }
+       }
 
+       void UpdateText()
+       {
+               SetText(shape->Name());
+               if (fListView->LockLooper()) {
+                       fListView->InvalidateItem(fListView->IndexOf(this));
+                       fListView->UnlockLooper();
+               }
+       }
+
+public:
        Shape*                  shape;
- private:
+
+private:
        ShapeListView*  fListView;
 };
 
+
 // #pragma mark -
 
+
 enum {
        MSG_REMOVE                                              = 'rmsh',
        MSG_DUPLICATE                                   = 'dpsh',
@@ -108,31 +112,30 @@ enum {
        MSG_DRAG_SHAPE                                  = 'drgs',
 };
 
-// constructor
-ShapeListView::ShapeListView(BRect frame,
-                                                        const char* name,
-                                                        BMessage* message, 
BHandler* target)
-       : SimpleListView(frame, name,
-                                        NULL, B_MULTIPLE_SELECTION_LIST),
-         fMessage(message),
-         fShapeContainer(NULL),
-         fCommandStack(NULL)
+
+ShapeListView::ShapeListView(BRect frame, const char* name, BMessage* message,
+       BHandler* target)
+       :
+       SimpleListView(frame, name, NULL, B_MULTIPLE_SELECTION_LIST),
+       fMessage(message),
+       fShapeContainer(NULL),
+       fCommandStack(NULL)
 {
        SetDragCommand(MSG_DRAG_SHAPE);
        SetTarget(target);
 }
 
-// destructor
+
 ShapeListView::~ShapeListView()
 {
        _MakeEmpty();
        delete fMessage;
 
-       if (fShapeContainer)
+       if (fShapeContainer != NULL)
                fShapeContainer->RemoveListener(this);
 }
 
-// SelectionChanged
+
 void
 ShapeListView::SelectionChanged()
 {
@@ -151,7 +154,7 @@ ShapeListView::SelectionChanged()
        _UpdateMenu();
 }
 
-// MessageReceived
+
 void
 ShapeListView::MessageReceived(BMessage* message)
 {
@@ -159,7 +162,9 @@ ShapeListView::MessageReceived(BMessage* message)
                case MSG_REMOVE:
                        RemoveSelected();
                        break;
-               case MSG_DUPLICATE: {
+
+               case MSG_DUPLICATE:
+               {
                        int32 count = CountSelectedItems();
                        int32 index = 0;
                        BList items;
@@ -172,7 +177,9 @@ ShapeListView::MessageReceived(BMessage* message)
                        CopyItems(items, index + 1);
                        break;
                }
-               case MSG_RESET_TRANSFORMATION: {
+               
+               case MSG_RESET_TRANSFORMATION:
+               {
                        BList shapes;
                        _GetSelectedShapes(shapes);
                        int32 count = shapes.CountItems();
@@ -191,27 +198,30 @@ ShapeListView::MessageReceived(BMessage* message)
                        fCommandStack->Perform(command);
                        break;
                }
-               case MSG_FREEZE_TRANSFORMATION: {
+               
+               case MSG_FREEZE_TRANSFORMATION:
+               {
                        BList shapes;
                        _GetSelectedShapes(shapes);
                        int32 count = shapes.CountItems();
                        if (count < 0)
                                break;
 
-                       FreezeTransformationCommand* command = 
-                               new 
FreezeTransformationCommand((Shape**)shapes.Items(),
+                       FreezeTransformationCommand* command
+                               = new 
FreezeTransformationCommand((Shape**)shapes.Items(),
                                        count);
 
                        fCommandStack->Perform(command);
                        break;
                }
+
                default:
                        SimpleListView::MessageReceived(message);
                        break;
        }
 }
 
-// MakeDragMessage
+
 void
 ShapeListView::MakeDragMessage(BMessage* message) const
 {
@@ -221,51 +231,40 @@ ShapeListView::MakeDragMessage(BMessage* message) const
        for (int32 i = 0; i < count; i++) {
                ShapeListItem* item = dynamic_cast<ShapeListItem*>(
                        ItemAt(CurrentSelection(i)));
-               if (item)
+               if (item != NULL)
                        message->AddPointer("shape", (void*)item->shape);
                else
                        break;
        }
-
-//             message->AddInt32("be:actions", B_COPY_TARGET);
-//             message->AddInt32("be:actions", B_TRASH_TARGET);
-//
-//             message->AddString("be:types", B_FILE_MIME_TYPE);
-////           message->AddString("be:filetypes", "");
-////           message->AddString("be:type_descriptions", "");
-//
-//             message->AddString("be:clip_name", item->shape->Name());
-//
-//             message->AddString("be:originator", "Icon-O-Matic");
-//             message->AddPointer("be:originator_data", (void*)item->shape);
 }
 
-// AcceptDragMessage
+
 bool
 ShapeListView::AcceptDragMessage(const BMessage* message) const
 {
        return SimpleListView::AcceptDragMessage(message);
 }
 
-// SetDropTargetRect
+
 void
 ShapeListView::SetDropTargetRect(const BMessage* message, BPoint where)
 {
        SimpleListView::SetDropTargetRect(message, where);
 }
 
+
 // #pragma mark -
 
-// MoveItems
+
 void
 ShapeListView::MoveItems(BList& items, int32 toIndex)
 {
-       if (!fCommandStack || !fShapeContainer)
+       if (fCommandStack == NULL || fShapeContainer == NULL)
                return;
 
        int32 count = items.CountItems();
-       Shape** shapes = new (nothrow) Shape*[count];
-       if (!shapes)
+       Shape** shapes = new(nothrow) Shape*[count];
+       if (shapes == NULL)
                return;
 
        for (int32 i = 0; i < count; i++) {
@@ -274,10 +273,9 @@ ShapeListView::MoveItems(BList& items, int32 toIndex)
                shapes[i] = item ? item->shape : NULL;
        }
 
-       MoveShapesCommand* command
-               = new (nothrow) MoveShapesCommand(fShapeContainer,
-                                                                               
  shapes, count, toIndex);
-       if (!command) {
+       MoveShapesCommand* command = new (nothrow) MoveShapesCommand(
+               fShapeContainer, shapes, count, toIndex);
+       if (command == NULL) {
                delete[] shapes;
                return;
        }
@@ -289,7 +287,7 @@ ShapeListView::MoveItems(BList& items, int32 toIndex)
 void
 ShapeListView::CopyItems(BList& items, int32 toIndex)
 {
-       if (!fCommandStack || !fShapeContainer)
+       if (fCommandStack == NULL || fShapeContainer == NULL)
                return;
 
        int32 count = items.CountItems();
@@ -298,14 +296,12 @@ ShapeListView::CopyItems(BList& items, int32 toIndex)
        for (int32 i = 0; i < count; i++) {
                ShapeListItem* item
                        = 
dynamic_cast<ShapeListItem*>((BListItem*)items.ItemAtFast(i));
-               shapes[i] = item ? new (nothrow) Shape(*item->shape) : NULL;
+               shapes[i] = item ? new(nothrow) Shape(*item->shape) : NULL;
        }
 
-       AddShapesCommand* command
-               = new (nothrow) AddShapesCommand(fShapeContainer,
-                                                                               
 shapes, count, toIndex,
-                                                                               
 fSelection);
-       if (!command) {
+       AddShapesCommand* command = new(nothrow) 
AddShapesCommand(fShapeContainer,
+               shapes, count, toIndex, fSelection);
+       if (command == NULL) {
                for (int32 i = 0; i < count; i++)
                        delete shapes[i];
                return;
@@ -314,11 +310,11 @@ ShapeListView::CopyItems(BList& items, int32 toIndex)
        fCommandStack->Perform(command);
 }
 
-// RemoveItemList
+
 void
 ShapeListView::RemoveItemList(BList& items)
 {
-       if (!fCommandStack || !fShapeContainer)
+       if (fCommandStack == NULL || fShapeContainer == NULL)
                return;
 
        int32 count = items.CountItems();
@@ -326,43 +322,44 @@ ShapeListView::RemoveItemList(BList& items)
        for (int32 i = 0; i < count; i++)
                indices[i] = IndexOf((BListItem*)items.ItemAtFast(i));
 
-       RemoveShapesCommand* command
-               = new (nothrow) RemoveShapesCommand(fShapeContainer,
-                                                                               
        indices, count);
+       RemoveShapesCommand* command = new(nothrow) RemoveShapesCommand(
+               fShapeContainer, indices, count);
+
        fCommandStack->Perform(command);
 }
 
-// CloneItem
+
 BListItem*
 ShapeListView::CloneItem(int32 index) const
 {
-       if (ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(index))) {
+       ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(index));
+       if (item != NULL) {
                return new ShapeListItem(item->shape,
-                                                                
const_cast<ShapeListView*>(this));
+                       const_cast<ShapeListView*>(this));
        }
        return NULL;
 }
 
-// IndexOfSelectable
+
 int32
 ShapeListView::IndexOfSelectable(Selectable* selectable) const
 {
        Shape* shape = dynamic_cast<Shape*>(selectable);
-       if (!shape) {
+       if (shape == NULL) {
                Transformer* transformer = 
dynamic_cast<Transformer*>(selectable);
-               if (!transformer)
+               if (transformer == NULL)
                        return -1;
-               for (int32 i = 0;
-                        ShapeListItem* item = 
dynamic_cast<ShapeListItem*>(ItemAt(i));
-                        i++) {
-                       if (item->shape->HasTransformer(transformer))
+               int32 count = CountItems();
+               for (int32 i = 0; i < count; i++) {
+                       ShapeListItem* item = 
dynamic_cast<ShapeListItem*>(ItemAt(i));
+                       if (item != NULL && 
item->shape->HasTransformer(transformer))
                                return i;
                }
        } else {
-               for (int32 i = 0;
-                        ShapeListItem* item = 
dynamic_cast<ShapeListItem*>(ItemAt(i));
-                        i++) {
-                       if (item->shape == shape)
+               int32 count = CountItems();
+               for (int32 i = 0; i < count; i++) {
+                       ShapeListItem* item = 
dynamic_cast<ShapeListItem*>(ItemAt(i));
+                       if (item != NULL && item->shape == shape)
                                return i;
                }
        }
@@ -370,19 +367,20 @@ ShapeListView::IndexOfSelectable(Selectable* selectable) 
const
        return -1;
 }
 
-// SelectableFor
+
 Selectable*
 ShapeListView::SelectableFor(BListItem* item) const
 {
        ShapeListItem* shapeItem = dynamic_cast<ShapeListItem*>(item);
-       if (shapeItem)
+       if (shapeItem != NULL)
                return shapeItem->shape;
        return NULL;
 }
 
+
 // #pragma mark -
 
-// ShapeAdded
+
 void
 ShapeListView::ShapeAdded(Shape* shape, int32 index)
 {
@@ -399,7 +397,7 @@ ShapeListView::ShapeAdded(Shape* shape, int32 index)
        UnlockLooper();
 }
 
-// ShapeRemoved
+
 void
 ShapeListView::ShapeRemoved(Shape* shape)
 {
@@ -416,9 +414,10 @@ ShapeListView::ShapeRemoved(Shape* shape)
        UnlockLooper();
 }
 
+
 // #pragma mark -
 
-// SetMenu
+
 void
 ShapeListView::SetMenu(BMenu* menu)
 {
@@ -426,6 +425,7 @@ ShapeListView::SetMenu(BMenu* menu)
                return;
 
        fMenu = menu;
+
        if (fMenu == NULL)
                return;
 
@@ -480,7 +480,7 @@ ShapeListView::SetMenu(BMenu* menu)
        _UpdateMenu();
 }
 
-// SetShapeContainer
+
 void
 ShapeListView::SetShapeContainer(ShapeContainer* container)
 {
@@ -488,14 +488,14 @@ ShapeListView::SetShapeContainer(ShapeContainer* 
container)
                return;
 
        // detach from old container
-       if (fShapeContainer)
+       if (fShapeContainer != NULL)
                fShapeContainer->RemoveListener(this);
 
        _MakeEmpty();
 
        fShapeContainer = container;
 
-       if (!fShapeContainer)
+       if (fShapeContainer == NULL)
                return;
 
        fShapeContainer->AddListener(this);
@@ -506,54 +506,65 @@ ShapeListView::SetShapeContainer(ShapeContainer* 
container)
                _AddShape(fShapeContainer->ShapeAtFast(i), i);
 }
 
-// SetCommandStack
+
 void
 ShapeListView::SetCommandStack(CommandStack* stack)
 {
        fCommandStack = stack;
 }
 
+
 // #pragma mark -
 
-// _AddShape
+
 bool
 ShapeListView::_AddShape(Shape* shape, int32 index)
 {
-       if (shape)
-                return AddItem(new ShapeListItem(shape, this), index);
-       return false;
+       if (shape == NULL)
+               return false;
+       
+       ShapeListItem* item = new(std::nothrow) ShapeListItem(shape, this);
+       if (item == NULL)
+               return false;
+       
+       if (!AddItem(item, index)) {
+               delete item;
+               return false;
+       }
+       
+       return true;
 }
 
-// _RemoveShape
+
 bool
 ShapeListView::_RemoveShape(Shape* shape)
 {
        ShapeListItem* item = _ItemForShape(shape);
-       if (item && RemoveItem(item)) {
+       if (item != NULL && RemoveItem(item)) {
                delete item;
                return true;
        }
        return false;
 }
 
-// _ItemForShape
+
 ShapeListItem*
 ShapeListView::_ItemForShape(Shape* shape) const
 {
-       for (int32 i = 0;
-                ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(i));
-                i++) {
-               if (item->shape == shape)
+       int32 count = CountItems();
+       for (int32 i = 0; i < count; i++) {
+               ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(i));
+               if (item != NULL && item->shape == shape)
                        return item;
        }
        return NULL;
 }
 
-// _UpdateMenu
+
 void
 ShapeListView::_UpdateMenu()
 {
-       if (!fMenu)
+       if (fMenu == NULL)
                return;
 
        bool gotSelection = CurrentSelection(0) >= 0;
@@ -564,7 +575,7 @@ ShapeListView::_UpdateMenu()
        fRemoveMI->SetEnabled(gotSelection);
 }
 
-// _GetSelectedShapes
+
 void
 ShapeListView::_GetSelectedShapes(BList& shapes) const
 {
@@ -572,7 +583,7 @@ ShapeListView::_GetSelectedShapes(BList& shapes) const
        for (int32 i = 0; i < count; i++) {
                ShapeListItem* item = dynamic_cast<ShapeListItem*>(
                        ItemAt(CurrentSelection(i)));
-               if (item && item->shape) {
+               if (item != NULL && item->shape != NULL) {
                        if (!shapes.AddItem((void*)item->shape))
                                break;
                }

############################################################################

Commit:      2d35ee03c024bfc42b64d47244db3e9224ad0912
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2d35ee0
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Sun May  6 14:50:02 2012 UTC

Added operator== implementation

----------------------------------------------------------------------------

diff --git a/src/libs/icon/shape/VectorPath.cpp 
b/src/libs/icon/shape/VectorPath.cpp
index 87c317d..a2f88a8 100644
--- a/src/libs/icon/shape/VectorPath.cpp
+++ b/src/libs/icon/shape/VectorPath.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2009, Haiku.
+ * Copyright 2006-2012, Haiku.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -317,6 +317,34 @@ VectorPath::operator=(const VectorPath& from)
 }
 
 
+bool
+VectorPath::operator==(const VectorPath& other) const
+{
+       if (fClosed != other.fClosed)
+               return false;
+       
+       if (fPointCount != other.fPointCount)
+               return false;
+
+       if (fPath == NULL && other.fPath == NULL)
+               return true;
+
+       if (fPath == NULL || other.fPath == NULL)
+               return false;
+
+       for (int32 i = 0; i < fPointCount; i++) {
+               if (fPath[i].point != other.fPath[i].point
+                       || fPath[i].point_in != other.fPath[i].point_in
+                       || fPath[i].point_out != other.fPath[i].point_out
+                       || fPath[i].connected != other.fPath[i].connected) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+
 void
 VectorPath::MakeEmpty()
 {
diff --git a/src/libs/icon/shape/VectorPath.h b/src/libs/icon/shape/VectorPath.h
index 7deb160..b0cd632 100644
--- a/src/libs/icon/shape/VectorPath.h
+++ b/src/libs/icon/shape/VectorPath.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2007, Haiku.
+ * Copyright 2006-2012, Haiku.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -89,7 +89,7 @@ class VectorPath {
 
        // VectorPath
                        VectorPath&                     operator=(const 
VectorPath& from);
-//                     bool                            operator==(const 
VectorPath& from) const;
+                       bool                            operator==(const 
VectorPath& from) const;
 
                        void                            MakeEmpty();
 

############################################################################

Revision:    hrev44117
Commit:      e4ef668253317fde1251f6c3130a71c4ace68600
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e4ef668
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Sun May  6 14:50:25 2012 UTC

Implemented drag&drop of shape items between I-O-M windows.

 * The ShapeListView also knows the PathContainer and StyleContainer
 * When constructing the drag message, also include a complete archive
   of the dragged shapes, bundled with archives for each included path
   and the style.
 * When handling the drop, and it came from another I-O-M window,
   exract the Shape archive bundle from the drag message. For the
   Style and the included Paths, try to find an existing Style and
   existing Paths and reference those in the added Shape(s) instead
   of adding duplicates.

----------------------------------------------------------------------------

diff --git a/src/apps/icon-o-matic/MainWindow.cpp 
b/src/apps/icon-o-matic/MainWindow.cpp
index f7a0b07..51692f5 100644
--- a/src/apps/icon-o-matic/MainWindow.cpp
+++ b/src/apps/icon-o-matic/MainWindow.cpp
@@ -844,6 +844,8 @@ MainWindow::SetIcon(Icon* icon)
        fStyleListView->SetShapeContainer(fIcon != NULL ? fIcon->Shapes() : 
NULL);
 
        fShapeListView->SetShapeContainer(fIcon != NULL ? fIcon->Shapes() : 
NULL);
+       fShapeListView->SetStyleContainer(fIcon != NULL ? fIcon->Styles() : 
NULL);
+       fShapeListView->SetPathContainer(fIcon != NULL ? fIcon->Paths() : NULL);
 
        // icon previews
        fIconPreview16Folder->SetIcon(fIcon);
diff --git a/src/apps/icon-o-matic/gui/ShapeListView.cpp 
b/src/apps/icon-o-matic/gui/ShapeListView.cpp
index 04fa6ea..91e9b3b 100644
--- a/src/apps/icon-o-matic/gui/ShapeListView.cpp
+++ b/src/apps/icon-o-matic/gui/ShapeListView.cpp
@@ -25,14 +25,19 @@
 #include "AddShapesCommand.h"
 #include "AddStylesCommand.h"
 #include "CommandStack.h"
+#include "CompoundCommand.h"
 #include "FreezeTransformationCommand.h"
 #include "MoveShapesCommand.h"
 #include "Observer.h"
+#include "PathContainer.h"
 #include "RemoveShapesCommand.h"
 #include "ResetTransformationCommand.h"
 #include "Selection.h"
 #include "Shape.h"
+#include "Style.h"
+#include "StyleContainer.h"
 #include "Util.h"
+#include "VectorPath.h"
 
 
 #undef B_TRANSLATION_CONTEXT
@@ -119,6 +124,8 @@ ShapeListView::ShapeListView(BRect frame, const char* name, 
BMessage* message,
        SimpleListView(frame, name, NULL, B_MULTIPLE_SELECTION_LIST),
        fMessage(message),
        fShapeContainer(NULL),
+       fStyleContainer(NULL),
+       fPathContainer(NULL),
        fCommandStack(NULL)
 {
        SetDragCommand(MSG_DRAG_SHAPE);
@@ -231,9 +238,29 @@ ShapeListView::MakeDragMessage(BMessage* message) const
        for (int32 i = 0; i < count; i++) {
                ShapeListItem* item = dynamic_cast<ShapeListItem*>(
                        ItemAt(CurrentSelection(i)));
-               if (item != NULL)
+               if (item != NULL && item->shape != NULL) {
                        message->AddPointer("shape", (void*)item->shape);
-               else
+                       
+                       // Add archives of everything this Shape uses
+                       BMessage archive;
+                       
+                       BMessage styleArchive;
+                       item->shape->Style()->Archive(&styleArchive, true);
+                       archive.AddMessage("style", &styleArchive);
+
+                       PathContainer* paths = item->shape->Paths();
+                       for (int32 j = 0; j < paths->CountPaths(); j++) {
+                               BMessage pathArchive;
+                               paths->PathAt(j)->Archive(&pathArchive, true);
+                               archive.AddMessage("path", &pathArchive);
+                       }
+
+                       BMessage shapeArchive;
+                       item->shape->Archive(&shapeArchive, true);
+                       archive.AddMessage("shape", &shapeArchive);
+
+                       message->AddMessage("shape archive", &archive);
+               } else
                        break;
        }
 }
@@ -253,6 +280,145 @@ ShapeListView::SetDropTargetRect(const BMessage* message, 
BPoint where)
 }
 
 
+bool
+ShapeListView::HandleDropMessage(const BMessage* message, int32 dropIndex)
+{
+       // Let SimpleListView handle drag-sorting (when drag came from ourself)
+       if (SimpleListView::HandleDropMessage(message, dropIndex))
+               return true;
+
+       if (fCommandStack == NULL || fShapeContainer == NULL
+               || fStyleContainer == NULL || fPathContainer == NULL) {
+               return false;
+       }
+
+       // Drag may have come from another instance, like in another window.
+       // Reconstruct the Shapes from the archive and add them at the drop
+       // index.
+       int index = 0;
+       BList styles;
+       BList paths;
+       BList shapes;
+       while (true) {
+               BMessage archive;
+               if (message->FindMessage("shape archive", index, &archive) != 
B_OK)
+                       break;
+
+               // Extract the shape archive            
+               BMessage shapeArchive;
+               if (archive.FindMessage("shape", &shapeArchive) != B_OK)
+                       break;
+
+               // Extract the style
+               BMessage styleArchive;
+               if (archive.FindMessage("style", &styleArchive) != B_OK)
+                       break;
+
+               Style* style = new Style(&styleArchive);
+               if (style == NULL)
+                       break;
+               
+               Style* styleToAssign = style;
+               // Try to find an existing style that is the same as the 
extracted
+               // style and use that one instead.
+               for (int32 i = 0; i < fStyleContainer->CountStyles(); i++) {
+                       Style* other = fStyleContainer->StyleAtFast(i);
+                       if (*other == *style) {
+                               styleToAssign = other;
+                               delete style;
+                               style = NULL;
+                               break;
+                       }
+               }
+               
+               if (style != NULL && !styles.AddItem(style)) {
+                       delete style;
+                       break;
+               }
+
+               // Create the shape using the given style
+               Shape* shape = new(std::nothrow) Shape(styleToAssign);
+               if (shape == NULL)
+                       break;
+
+               if (shape->Unarchive(&shapeArchive) != B_OK
+                       || !shapes.AddItem(shape)) {
+                       delete shape;
+                       if (style != NULL) {
+                               styles.RemoveItem(style);
+                               delete style;
+                       }
+                       break;
+               }
+               
+               // Extract the paths
+               int pathIndex = 0;
+               while (true) {
+                       BMessage pathArchive;
+                       if (archive.FindMessage("path", pathIndex, 
&pathArchive) != B_OK)
+                               break;
+                       
+                       VectorPath* path = new(nothrow) 
VectorPath(&pathArchive);
+                       if (path == NULL)
+                               break;
+                       
+                       VectorPath* pathToInclude = path;
+                       for (int32 i = 0; i < fPathContainer->CountPaths(); 
i++) {
+                               VectorPath* other = 
fPathContainer->PathAtFast(i);
+                               if (*other == *path) {
+                                       pathToInclude = other;
+                                       delete path;
+                                       path = NULL;
+                                       break;
+                               }
+                       }
+                       
+                       if (path != NULL && !paths.AddItem(path)) {
+                               delete path;
+                               break;
+                       }
+                       
+                       shape->Paths()->AddPath(pathToInclude);
+                       
+                       pathIndex++;
+               }
+
+               index++;
+       }
+
+       int32 shapeCount = shapes.CountItems();
+       if (shapeCount == 0)
+               return false;
+
+       // TODO: Add allocation checks beyond this point.
+
+       AddStylesCommand* stylesCommand = new(std::nothrow) AddStylesCommand(
+               fStyleContainer, (Style**)styles.Items(), styles.CountItems(),
+               fStyleContainer->CountStyles());
+
+       AddPathsCommand* pathsCommand = new(std::nothrow) AddPathsCommand(
+               fPathContainer, (VectorPath**)paths.Items(), paths.CountItems(),
+               true, fPathContainer->CountPaths());
+
+       AddShapesCommand* shapesCommand = new(std::nothrow) AddShapesCommand(
+               fShapeContainer, (Shape**)shapes.Items(), shapeCount, dropIndex,
+               fSelection);
+
+       ::Command** commands = new(std::nothrow) ::Command*[3];
+
+       commands[0] = stylesCommand;
+       commands[1] = pathsCommand;
+       commands[2] = shapesCommand;
+
+       CompoundCommand* command = new CompoundCommand(commands, 3,
+               B_TRANSLATE("Drop shapes"), -1);
+
+       fCommandStack->Perform(command);
+
+       return true;
+}
+
+
 // #pragma mark -
 
 
@@ -508,6 +674,20 @@ ShapeListView::SetShapeContainer(ShapeContainer* container)
 
 
 void
+ShapeListView::SetStyleContainer(StyleContainer* container)
+{
+       fStyleContainer = container;
+}
+
+
+void
+ShapeListView::SetPathContainer(PathContainer* container)
+{
+       fPathContainer = container;
+}
+
+
+void
 ShapeListView::SetCommandStack(CommandStack* stack)
 {
        fCommandStack = stack;
diff --git a/src/apps/icon-o-matic/gui/ShapeListView.h 
b/src/apps/icon-o-matic/gui/ShapeListView.h
index b8464ae..9e92069 100644
--- a/src/apps/icon-o-matic/gui/ShapeListView.h
+++ b/src/apps/icon-o-matic/gui/ShapeListView.h
@@ -17,6 +17,8 @@ class BMenu;
 class BMenuItem;
 class CommandStack;
 class ShapeListItem;
+class StyleContainer;
+class PathContainer;
 class Selection;
 
 _BEGIN_ICON_NAMESPACE
@@ -48,7 +50,9 @@ class ShapeListView : public SimpleListView,
 
        virtual bool                            AcceptDragMessage(const 
BMessage* message) const;
        virtual void                            SetDropTargetRect(const 
BMessage* message,
-                                                                               
                  BPoint where);
+                                                                       BPoint 
where);
+       virtual bool                            HandleDropMessage(const 
BMessage* message,
+                                                                       int32 
dropIndex);
 
        virtual void                            MoveItems(BList& items, int32 
toIndex);
        virtual void                            CopyItems(BList& items, int32 
toIndex);
@@ -66,6 +70,8 @@ class ShapeListView : public SimpleListView,
        // ShapeListView
                        void                            SetMenu(BMenu* menu);
                        void                            
SetShapeContainer(ShapeContainer* container);
+                       void                            
SetStyleContainer(StyleContainer* container);
+                       void                            
SetPathContainer(PathContainer* container);
                        void                            
SetCommandStack(CommandStack* stack);
 
  private:
@@ -80,6 +86,8 @@ class ShapeListView : public SimpleListView,
                        BMessage*                       fMessage;
 
                        ShapeContainer*         fShapeContainer;
+                       StyleContainer*         fStyleContainer;
+                       PathContainer*          fPathContainer;
                        CommandStack*           fCommandStack;
 
                        BMenu*                          fMenu;


Other related posts:

  • » [haiku-commits] haiku: hrev44117 - in src: apps/icon-o-matic/gui libs/icon/shape - superstippi