[haiku-commits] r41066 - haiku/trunk/src/apps/people

  • From: philippe.houdoin@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 21 Mar 2011 12:39:54 +0100 (CET)

Author: phoudoin
Date: 2011-03-21 12:39:54 +0100 (Mon, 21 Mar 2011)
New Revision: 41066
Changeset: https://dev.haiku-os.org/changeset/41066
Ticket: https://dev.haiku-os.org/ticket/7300

Modified:
   haiku/trunk/src/apps/people/PersonView.cpp
   haiku/trunk/src/apps/people/PersonView.h
   haiku/trunk/src/apps/people/PictureView.cpp
   haiku/trunk/src/apps/people/PictureView.h
Log:
Fix #7300:
* When saving, the internal bitmap wasn't detached from stream, which then
deleted it, paving the road to a crash at next bitmap access.
* When saved, notify PictureView that current and original pictures are
the same.

Also, add support for bitmap paste (needs more improvement) and
to avoid reloading picture on B_STAT_CHANGED after our own save operation.


Modified: haiku/trunk/src/apps/people/PersonView.cpp
===================================================================
--- haiku/trunk/src/apps/people/PersonView.cpp  2011-03-21 10:59:10 UTC (rev 
41065)
+++ haiku/trunk/src/apps/people/PersonView.cpp  2011-03-21 11:39:54 UTC (rev 
41066)
@@ -45,10 +45,12 @@
                const entry_ref *ref)
        :
        BGridView(),
+       fLastModificationTime(0),
        fGroups(NULL),
        fControls(20, false),
        fCategoryAttribute(categoryAttribute),
-       fPictureView(NULL)
+       fPictureView(NULL),
+       fSaving(false)
 {
        SetName(name);
        SetFlags(Flags() | B_WILL_DRAW);
@@ -68,6 +70,9 @@
        layout->AddView(fPictureView, 0, 0, 1, 5);
        layout->ItemAt(0, 0)->SetExplicitAlignment(
                BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP));
+
+       if (fFile)
+               fFile->GetModificationTime(&fLastModificationTime);
 }
 
 
@@ -288,6 +293,8 @@
 void
 PersonView::Save()
 {
+       fSaving = true;
+
        int32 count = fControls.CountItems();
        for (int32 i = 0; i < count; i++) {
                AttributeTextControl* control = fControls.ItemAt(i);
@@ -299,17 +306,30 @@
 
        // Write the picture, if any, in the person file content
        if (fPictureView) {
-               // trim previous content
+               // Trim any previous content
                fFile->Seek(0, SEEK_SET);
                fFile->SetSize(0);
-               if (fPictureView->Bitmap()) {
-                       BBitmapStream stream(fPictureView->Bitmap());
+
+               BBitmap* picture = fPictureView->Bitmap();
+               if (picture) {
+                       BBitmapStream stream(picture);
+                       // Detach *our* bitmap from stream to avoid its deletion
+                       // at stream object destruction
+                       stream.DetachBitmap(&picture);
+
                        BTranslatorRoster* roster = 
BTranslatorRoster::Default();
                        roster->Translate(&stream, NULL, NULL, fFile,
                                fPictureView->SuggestedType(), 
B_TRANSLATOR_BITMAP,
                                fPictureView->SuggestedMIMEType());
+
                }
+
+               fPictureView->Update();
        }
+
+       fFile->GetModificationTime(&fLastModificationTime);
+
+       fSaving = false;
 }
 
 
@@ -386,8 +406,22 @@
 void
 PersonView::UpdatePicture(const entry_ref* ref)
 {
-       if (fPictureView)
-               fPictureView->Update(ref);
+       if (fPictureView == NULL)
+               return;
+
+       if (fSaving)
+               return;
+
+       time_t modificationTime = 0;
+       BEntry entry(ref);
+       entry.GetModificationTime(&modificationTime);
+
+       if (entry.InitCheck() == B_OK
+               && modificationTime <= fLastModificationTime) {
+               return;
+       }
+
+       fPictureView->Update(ref);
 }
 
 

Modified: haiku/trunk/src/apps/people/PersonView.h
===================================================================
--- haiku/trunk/src/apps/people/PersonView.h    2011-03-21 10:59:10 UTC (rev 
41065)
+++ haiku/trunk/src/apps/people/PersonView.h    2011-03-21 11:39:54 UTC (rev 
41066)
@@ -63,12 +63,14 @@
 
 private:
                        BFile*                          fFile;
+                       time_t                          fLastModificationTime;
                        BPopUpMenu*                     fGroups;
                        typedef BObjectList<AttributeTextControl> AttributeList;
                        AttributeList           fControls;
 
                        BString                         fCategoryAttribute;
                        PictureView*            fPictureView;
+                       bool                            fSaving;
 };
 
 #endif // PERSON_VIEW_H

Modified: haiku/trunk/src/apps/people/PictureView.cpp
===================================================================
--- haiku/trunk/src/apps/people/PictureView.cpp 2011-03-21 10:59:10 UTC (rev 
41065)
+++ haiku/trunk/src/apps/people/PictureView.cpp 2011-03-21 11:39:54 UTC (rev 
41066)
@@ -17,6 +17,7 @@
 #include <Bitmap.h>
 #include <BitmapStream.h>
 #include <Catalog.h>
+#include <Clipboard.h>
 #include <Directory.h>
 #include <File.h>
 #include <FilePanel.h>
@@ -142,6 +143,16 @@
 
 
 void
+PictureView::Update()
+{
+       if (fOriginalPicture != fPicture) {
+               delete fOriginalPicture;
+               fOriginalPicture = fPicture;
+       }
+}
+
+
+void
 PictureView::Update(const entry_ref* ref)
 {
        // Don't update when user has modified the picture
@@ -187,23 +198,38 @@
                case B_SIMPLE_DATA:
                {
                        entry_ref ref;
-                       if (message->FindRef("refs", &ref) != B_OK)
-                               break;
-
-                       if (_LoadPicture(&ref) == B_OK)
+                       if (message->FindRef("refs", &ref) == B_OK
+                               && _LoadPicture(&ref) == B_OK)
                                MakeFocus(true);
+                       else
+                               _HandleDrop(message);
                        break;
                }
 
                case B_MIME_DATA:
-                       printf("B_MIME_DATA:\n");
-                       message->PrintToStream();
+                       // TODO
                        break;
 
                case B_COPY_TARGET:
                        _HandleDrop(message);
                        break;
 
+               case B_PASTE:
+               {
+                       if (be_clipboard->Lock() != B_OK)
+                               break;
+
+                       BMessage* data = be_clipboard->Data();
+                       BMessage archivedBitmap;
+                       if (data->FindMessage("image/bitmap", &archivedBitmap) 
== B_OK) {
+                               BBitmap* picture = new(std::nothrow) 
BBitmap(&archivedBitmap);
+                               _SetPicture(picture);
+                       }
+
+                       be_clipboard->Unlock();
+                       break;
+               }
+
                case B_DELETE:
                case B_TRASH_TARGET:
                        _SetPicture(NULL);
@@ -239,7 +265,7 @@
        StrokeRect(rect);
 
        if (fFocusChanging) {
-               printf("Draw(): focus changed...\n");
+               // focus frame is already redraw, stop here
                return;
        }
 
@@ -583,12 +609,10 @@
                return status;
 
        BBitmap* picture = NULL;
-       if (stream.DetachBitmap(&picture) != B_OK)
+       if (stream.DetachBitmap(&picture) != B_OK
+               || picture == NULL)
                return B_ERROR;
 
-       if (picture == NULL)
-               return B_ERROR;
-
        // Remember image format so we could store using the same
        fPictureMIMEType = info.MIME;
        fPictureType = info.type;
@@ -605,12 +629,13 @@
                delete fPicture;
 
        fPicture = picture;
-       Invalidate();
 
        if (picture == NULL) {
                fPictureType = 0;
                fPictureMIMEType = "";
        }
+
+       Invalidate();
 }
 
 

Modified: haiku/trunk/src/apps/people/PictureView.h
===================================================================
--- haiku/trunk/src/apps/people/PictureView.h   2011-03-21 10:59:10 UTC (rev 
41065)
+++ haiku/trunk/src/apps/people/PictureView.h   2011-03-21 11:39:54 UTC (rev 
41066)
@@ -28,6 +28,7 @@
 
                        bool                            HasChanged();
                        void                            Revert();
+                       void                            Update();
                        void                            Update(const entry_ref* 
ref);
 
                        BBitmap*                        Bitmap();


Other related posts: