[haiku-commits] r39364 - haiku/trunk/src/apps/showimage

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 9 Nov 2010 00:06:36 +0100 (CET)

Author: axeld
Date: 2010-11-09 00:06:36 +0100 (Tue, 09 Nov 2010)
New Revision: 39364
Changeset: http://dev.haiku-os.org/changeset/39364
Ticket: http://dev.haiku-os.org/ticket/6778
Ticket: http://dev.haiku-os.org/ticket/6797

Added:
   haiku/trunk/src/apps/showimage/ImageCache.cpp
   haiku/trunk/src/apps/showimage/ImageCache.h
Modified:
   haiku/trunk/src/apps/showimage/ImageFileNavigator.cpp
   haiku/trunk/src/apps/showimage/ImageFileNavigator.h
   haiku/trunk/src/apps/showimage/Jamfile
   haiku/trunk/src/apps/showimage/ShowImageStatusView.cpp
   haiku/trunk/src/apps/showimage/ShowImageStatusView.h
   haiku/trunk/src/apps/showimage/ShowImageView.cpp
   haiku/trunk/src/apps/showimage/ShowImageWindow.cpp
   haiku/trunk/src/apps/showimage/ShowImageWindow.h
Log:
* The ImageFileNavigator is now only for navigation, it doesn't load any images
  anymore.
* Moved the new ImageCache into its own source file.
* The cache is now used within ShowImage. There is no read-ahead caching being
  done yet, though, but you can quickly return to previous images, and you can
  also skip images faster than before.
* Improved separation between the ShowImageStatusView and the rest;
  ShowImageWindow no longer has a getter for the image view.
* The status view is now using the private BDirMenu which implements enhancement
  ticket #6778.
* Made a few more methods private/protected in ShowImageWindow.
* Fixed bug #6797.
* The bitmap is currently only owned by the ImageCache, but we need to have a
  separate referenceable object owning it. Added a TODO comment for this.
* The ProgressWindow is currently not being used anymore, added a TODO comment
  for this as well.


Added: haiku/trunk/src/apps/showimage/ImageCache.cpp
===================================================================
--- haiku/trunk/src/apps/showimage/ImageCache.cpp                               
(rev 0)
+++ haiku/trunk/src/apps/showimage/ImageCache.cpp       2010-11-08 23:06:36 UTC 
(rev 39364)
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "ImageCache.h"
+
+#include <new>
+
+#include <Autolock.h>
+#include <Bitmap.h>
+#include <BitmapStream.h>
+#include <Debug.h>
+#include <File.h>
+#include <Messenger.h>
+#include <TranslatorRoster.h>
+
+#include <AutoDeleter.h>
+
+#include "ShowImageConstants.h"
+
+
+struct QueueEntry {
+       entry_ref                               ref;
+       int32                                   page;
+       status_t                                status;
+       std::set<BMessenger>    listeners;
+};
+
+
+/*static*/ ImageCache ImageCache::sCache;
+
+
+// #pragma mark -
+
+
+ImageCache::ImageCache()
+       :
+       fLocker("image cache"),
+       fThreadCount(0),
+       fBytes(0)
+{
+       system_info info;
+       get_system_info(&info);
+
+       fMaxThreadCount = (info.cpu_count + 1) / 2;
+       fMaxBytes = info.max_pages * B_PAGE_SIZE / 8;
+       fMaxEntries = 10;
+}
+
+
+ImageCache::~ImageCache()
+{
+       // TODO: delete CacheEntries, and QueueEntries
+}
+
+
+status_t
+ImageCache::RetrieveImage(const entry_ref& ref, int32 page,
+       const BMessenger* target)
+{
+       BAutolock locker(fLocker);
+
+       CacheMap::iterator find = fCacheMap.find(std::make_pair(ref, page));
+       if (find != fCacheMap.end()) {
+               CacheEntry* entry = find->second;
+
+               // Requeue cache entry to the end of the by-age list
+               fCacheEntriesByAge.Remove(entry);
+               fCacheEntriesByAge.Add(entry);
+
+               // Notify target, if any
+               _NotifyTarget(entry, target);
+               return B_OK;
+       }
+
+       QueueMap::iterator findQueue = fQueueMap.find(std::make_pair(ref, 
page));
+       QueueEntry* entry;
+
+       if (findQueue == fQueueMap.end()) {
+               // Push new entry to the queue
+               entry = new(std::nothrow) QueueEntry();
+               if (entry == NULL)
+                       return B_NO_MEMORY;
+
+               entry->ref = ref;
+               entry->page = page;
+
+               if (fThreadCount < fMaxThreadCount) {
+                       // start a new worker thread to load the image
+                       thread_id thread = 
spawn_thread(&ImageCache::_QueueWorkerThread,
+                               "image loader", B_LOW_PRIORITY, this);
+                       if (thread >= B_OK) {
+                               atomic_add(&fThreadCount, 1);
+                               resume_thread(thread);
+                       } else if (fThreadCount == 0) {
+                               delete entry;
+                               return thread;
+                       }
+               }
+
+               fQueueMap.insert(std::make_pair(
+                       std::make_pair(entry->ref, entry->page), entry));
+               fQueue.push_front(entry);
+       } else
+               entry = findQueue->second;
+
+       if (target != NULL) {
+               // Attach target as listener
+               entry->listeners.insert(*target);
+       }
+
+       return B_OK;
+}
+
+
+/*static*/ status_t
+ImageCache::_QueueWorkerThread(void* _self)
+{
+       ImageCache* self = (ImageCache*)_self;
+
+       // get next queue entry
+       while (true) {
+               self->fLocker.Lock();
+               if (self->fQueue.empty()) {
+                       self->fLocker.Unlock();
+                       break;
+               }
+
+               QueueEntry* entry = *self->fQueue.begin();
+               self->fQueue.pop_front();
+               self->fLocker.Unlock();
+
+               if (entry == NULL)
+                       break;
+
+               CacheEntry* cacheEntry = NULL;
+               entry->status = self->_RetrieveImage(entry, &cacheEntry);
+
+               self->fLocker.Lock();
+               self->fQueueMap.erase(std::make_pair(entry->ref, entry->page));
+               self->fLocker.Unlock();
+
+               self->_NotifyListeners(cacheEntry, entry);
+               delete entry;
+       }
+
+       atomic_add(&self->fThreadCount, -1);
+       return B_OK;
+}
+
+
+status_t
+ImageCache::_RetrieveImage(QueueEntry* queueEntry, CacheEntry** _entry)
+{
+       CacheEntry* entry = new(std::nothrow) CacheEntry();
+       if (entry == NULL)
+               return B_NO_MEMORY;
+
+       ObjectDeleter<CacheEntry> deleter(entry);
+
+       BTranslatorRoster* roster = BTranslatorRoster::Default();
+       if (roster == NULL)
+               return B_ERROR;
+
+       BFile file;
+       status_t status = file.SetTo(&queueEntry->ref, B_READ_ONLY);
+       if (status != B_OK)
+               return status;
+
+       translator_info info;
+       memset(&info, 0, sizeof(translator_info));
+       BMessage ioExtension;
+
+       if (queueEntry->page != 0
+               && ioExtension.AddInt32("/documentIndex", queueEntry->page) != 
B_OK)
+               return B_NO_MEMORY;
+
+// TODO: rethink this!
+#if 0
+       if (fProgressWindow != NULL) {
+               BMessage progress(kMsgProgressStatusUpdate);
+               if (ioExtension.AddMessenger("/progressMonitor",
+                               fProgressWindow) == B_OK
+                       && ioExtension.AddMessage("/progressMessage", 
&progress) == B_OK)
+                       fProgressWindow->Start();
+       }
+#endif
+
+       // Translate image data and create a new ShowImage window
+
+       BBitmapStream outstream;
+
+       status = roster->Identify(&file, &ioExtension, &info, 0, NULL,
+               B_TRANSLATOR_BITMAP);
+       if (status == B_OK) {
+               status = roster->Translate(&file, &info, &ioExtension, 
&outstream,
+                       B_TRANSLATOR_BITMAP);
+       }
+
+#if 0
+       if (fProgressWindow != NULL)
+               fProgressWindow->Stop();
+#endif
+
+       if (status != B_OK)
+               return status;
+
+       BBitmap* bitmap;
+       if (outstream.DetachBitmap(&bitmap) != B_OK)
+               return B_ERROR;
+
+       entry->ref = queueEntry->ref;
+       entry->page = queueEntry->page;
+       entry->bitmap = bitmap;
+       entry->type = info.name;
+       entry->mimeType = info.MIME;
+
+       // get the number of documents (pages) if it has been supplied
+       int32 documentCount = 0;
+       if (ioExtension.FindInt32("/documentCount", &documentCount) == B_OK
+               && documentCount > 0)
+               entry->pageCount = documentCount;
+       else
+               entry->pageCount = 1;
+
+       deleter.Detach();
+       *_entry = entry;
+
+       BAutolock locker(fLocker);
+
+       fCacheMap.insert(std::make_pair(
+               std::make_pair(entry->ref, entry->page), entry));
+       fCacheEntriesByAge.Add(entry);
+
+       fBytes += bitmap->BitsLength();
+
+       while (fBytes > fMaxBytes || fCacheMap.size() > fMaxEntries) {
+               if (fCacheMap.size() <= 2)
+                       break;
+
+               // Remove the oldest entry
+               entry = fCacheEntriesByAge.RemoveHead();
+               fBytes -= entry->bitmap->BitsLength();
+               fCacheMap.erase(std::make_pair(entry->ref, entry->page));
+               delete entry;
+       }
+
+       return B_OK;
+}
+
+
+void
+ImageCache::_NotifyListeners(CacheEntry* entry, QueueEntry* queueEntry)
+{
+       ASSERT(fLocker.IsLocked());
+
+       if (queueEntry->listeners.empty())
+               return;
+
+       BMessage notification(kMsgImageLoaded);
+       _BuildNotification(entry, notification);
+
+       if (queueEntry->status != B_OK)
+               notification.AddInt32("error", queueEntry->status);
+
+       std::set<BMessenger>::iterator iterator = queueEntry->listeners.begin();
+       for (; iterator != queueEntry->listeners.end(); iterator++) {
+               iterator->SendMessage(&notification);
+       }
+}
+
+
+void
+ImageCache::_NotifyTarget(CacheEntry* entry, const BMessenger* target)
+{
+       if (target == NULL)
+               return;
+
+       BMessage notification(kMsgImageLoaded);
+       _BuildNotification(entry, notification);
+
+       target->SendMessage(&notification);
+}
+
+
+void
+ImageCache::_BuildNotification(CacheEntry* entry, BMessage& message)
+{
+       if (entry == NULL)
+               return;
+
+       message.AddString("type", entry->type);
+       message.AddString("mime", entry->mimeType);
+       message.AddRef("ref", &entry->ref);
+       message.AddInt32("page", entry->page);
+       message.AddInt32("pageCount", entry->pageCount);
+       message.AddPointer("bitmap", (void*)entry->bitmap);
+}

Added: haiku/trunk/src/apps/showimage/ImageCache.h
===================================================================
--- haiku/trunk/src/apps/showimage/ImageCache.h                         (rev 0)
+++ haiku/trunk/src/apps/showimage/ImageCache.h 2010-11-08 23:06:36 UTC (rev 
39364)
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef IMAGE_CACHE_H
+#define IMAGE_CACHE_H
+
+
+#include <deque>
+#include <map>
+#include <set>
+
+#include <Entry.h>
+#include <Locker.h>
+#include <String.h>
+
+#include <kernel/util/DoublyLinkedList.h>
+
+
+class BBitmap;
+class BMessage;
+class BMessenger;
+struct QueueEntry;
+
+
+enum {
+       kMsgImageLoaded = 'ifnL'
+};
+
+
+struct CacheEntry : DoublyLinkedListLinkImpl<CacheEntry> {
+       entry_ref                               ref;
+       int32                                   page;
+       int32                                   pageCount;
+       BBitmap*                                bitmap;
+       BString                                 type;
+       BString                                 mimeType;
+};
+
+
+class ImageCache {
+public:
+       static  ImageCache&                     Default() { return sCache; }
+
+                       status_t                        RetrieveImage(const 
entry_ref& ref, int32 page,
+                                                                       const 
BMessenger* target);
+
+private:
+                                                               ImageCache();
+       virtual                                         ~ImageCache();
+
+       static  status_t                        _QueueWorkerThread(void* self);
+
+                       status_t                        
_RetrieveImage(QueueEntry* entry,
+                                                                       
CacheEntry** _entry);
+                       void                            
_NotifyListeners(CacheEntry* entry,
+                                                                       
QueueEntry* queueEntry);
+                       void                            
_NotifyTarget(CacheEntry* entry,
+                                                                       const 
BMessenger* target);
+                       void                            
_BuildNotification(CacheEntry* entry,
+                                                                       
BMessage& message);
+
+private:
+                       typedef std::pair<entry_ref, int32> ImageSelector;
+                       typedef std::map<ImageSelector, CacheEntry*> CacheMap;
+                       typedef std::map<ImageSelector, QueueEntry*> QueueMap;
+                       typedef std::deque<QueueEntry*> QueueDeque;
+                       typedef DoublyLinkedList<CacheEntry> CacheList;
+
+                       BLocker                         fLocker;
+                       CacheMap                        fCacheMap;
+                       CacheList                       fCacheEntriesByAge;
+                       QueueMap                        fQueueMap;
+                       QueueDeque                      fQueue;
+                       vint32                          fThreadCount;
+                       int32                           fMaxThreadCount;
+                       uint64                          fBytes;
+                       uint64                          fMaxBytes;
+                       size_t                          fMaxEntries;
+
+       static  ImageCache                      sCache;
+};
+
+
+#endif // IMAGE_CACHE_H

Modified: haiku/trunk/src/apps/showimage/ImageFileNavigator.cpp
===================================================================
--- haiku/trunk/src/apps/showimage/ImageFileNavigator.cpp       2010-11-08 
21:53:24 UTC (rev 39363)
+++ haiku/trunk/src/apps/showimage/ImageFileNavigator.cpp       2010-11-08 
23:06:36 UTC (rev 39364)
@@ -18,26 +18,20 @@
 
 #include "ImageFileNavigator.h"
 
-#include <deque>
-#include <map>
 #include <new>
-#include <set>
 
 #include <stdio.h>
 
-#include <Bitmap.h>
 #include <BitmapStream.h>
 #include <Directory.h>
 #include <Entry.h>
 #include <File.h>
-#include <Locker.h>
+//#include <Locker.h>
 #include <ObjectList.h>
-#include <Path.h>
+//#include <Path.h>
 #include <TranslatorRoster.h>
 
-#include <AutoDeleter.h>
 #include <tracker_private.h>
-#include <kernel/util/DoublyLinkedList.h>
 
 #include "ProgressWindow.h"
 #include "ShowImageConstants.h"
@@ -320,254 +314,10 @@
 // #pragma mark -
 
 
-struct CacheEntry : DoublyLinkedListLinkImpl<CacheEntry> {
-       entry_ref                               ref;
-       int32                                   page;
-       int32                                   pageCount;
-       BBitmap*                                bitmap;
-       BString                                 type;
-       BString                                 mimeType;
-};
-
-
-struct QueueEntry {
-       entry_ref                               ref;
-       int32                                   page;
-       std::set<BMessenger>    listeners;
-};
-
-
-class ImageCache {
-public:
-                                                               ImageCache();
-       virtual                                         ~ImageCache();
-
-                       void                            RetrieveImage(const 
entry_ref& ref,
-                                                                       const 
BMessenger* target);
-
-private:
-       static  status_t                        _QueueWorkerThread(void* self);
-
-                       status_t                        
_RetrieveImage(QueueEntry* entry,
-                                                                       
BMessage& message);
-                       void                            
_NotifyListeners(QueueEntry* entry,
-                                                                       
BMessage& message);
-
-private:
-                       typedef std::pair<entry_ref, int32> ImageSelector;
-                       typedef std::map<ImageSelector, CacheEntry*> CacheMap;
-                       typedef std::map<ImageSelector, QueueEntry*> QueueMap;
-                       typedef std::deque<QueueEntry*> QueueDeque;
-                       typedef DoublyLinkedList<CacheEntry> CacheList;
-
-                       BLocker                         fCacheLocker;
-                       CacheMap                        fCacheMap;
-                       CacheList                       fCacheEntriesByAge;
-                       BLocker                         fQueueLocker;
-                       QueueMap                        fQueueMap;
-                       QueueDeque                      fQueue;
-                       vint32                          fThreadCount;
-                       int32                           fMaxThreadCount;
-                       uint64                          fBytes;
-                       uint64                          fMaxBytes;
-                       size_t                          fMaxEntries;
-};
-
-
-ImageCache::ImageCache()
+ImageFileNavigator::ImageFileNavigator(const entry_ref& ref,
+       const BMessenger& trackerMessenger)
        :
-       fCacheLocker("image cache"),
-       fQueueLocker("image queue"),
-       fThreadCount(0),
-       fBytes(0)
-{
-       system_info info;
-       get_system_info(&info);
-
-       fMaxThreadCount = (info.cpu_count + 1) / 2;
-       fMaxBytes = info.max_pages * B_PAGE_SIZE / 8;
-       fMaxEntries = 10;
-}
-
-
-ImageCache::~ImageCache()
-{
-       // TODO: delete CacheEntries, and QueueEntries
-}
-
-
-void
-ImageCache::RetrieveImage(const entry_ref& ref, const BMessenger* target)
-{
-       // TODO!
-}
-
-
-/*static*/ status_t
-ImageCache::_QueueWorkerThread(void* _self)
-{
-       ImageCache* self = (ImageCache*)_self;
-
-       // get next queue entry
-       while (true) {
-               self->fQueueLocker.Lock();
-               if (self->fQueue.empty()) {
-                       self->fQueueLocker.Unlock();
-                       break;
-               }
-
-               QueueEntry* entry = *self->fQueue.begin();
-               self->fQueue.pop_front();
-               self->fQueueLocker.Unlock();
-
-               if (entry == NULL)
-                       break;
-
-               BMessage notification(kMsgImageLoaded);
-               status_t status = self->_RetrieveImage(entry, notification);
-               if (status != B_OK)
-                       notification.AddInt32("error", status);
-
-               self->fQueueLocker.Lock();
-               self->fQueueMap.erase(std::make_pair(entry->ref, entry->page));
-               self->fQueueLocker.Unlock();
-
-               self->_NotifyListeners(entry, notification);
-               delete entry;
-       }
-
-       atomic_add(&self->fThreadCount, -1);
-       return B_OK;
-}
-
-
-status_t
-ImageCache::_RetrieveImage(QueueEntry* queueEntry, BMessage& message)
-{
-       CacheEntry* entry = new(std::nothrow) CacheEntry();
-       if (entry == NULL)
-               return B_NO_MEMORY;
-
-       ObjectDeleter<CacheEntry> deleter(entry);
-
-       BTranslatorRoster* roster = BTranslatorRoster::Default();
-       if (roster == NULL)
-               return B_ERROR;
-
-       if (!entry_ref_is_file(queueEntry->ref))
-               return B_IS_A_DIRECTORY;
-
-       BFile file;
-       status_t status = file.SetTo(&queueEntry->ref, B_READ_ONLY);
-       if (status != B_OK)
-               return status;
-
-       translator_info info;
-       memset(&info, 0, sizeof(translator_info));
-       BMessage ioExtension;
-
-       if (queueEntry->page != 0
-               && ioExtension.AddInt32("/documentIndex", queueEntry->page) != 
B_OK)
-               return B_NO_MEMORY;
-
-// TODO: rethink this!
-#if 0
-       if (fProgressWindow != NULL) {
-               BMessage progress(kMsgProgressStatusUpdate);
-               if (ioExtension.AddMessenger("/progressMonitor",
-                               fProgressWindow) == B_OK
-                       && ioExtension.AddMessage("/progressMessage", 
&progress) == B_OK)
-                       fProgressWindow->Start();
-       }
-#endif
-
-       // Translate image data and create a new ShowImage window
-
-       BBitmapStream outstream;
-
-       status = roster->Identify(&file, &ioExtension, &info, 0, NULL,
-               B_TRANSLATOR_BITMAP);
-       if (status == B_OK) {
-               status = roster->Translate(&file, &info, &ioExtension, 
&outstream,
-                       B_TRANSLATOR_BITMAP);
-       }
-
-#if 0
-       if (fProgressWindow != NULL)
-               fProgressWindow->Stop();
-#endif
-
-       if (status != B_OK)
-               return status;
-
-       BBitmap* bitmap;
-       if (outstream.DetachBitmap(&bitmap) != B_OK)
-               return B_ERROR;
-
-       entry->ref = queueEntry->ref;
-       entry->page = queueEntry->page;
-       entry->bitmap = bitmap;
-       entry->type = info.name;
-       entry->mimeType = info.MIME;
-
-       // get the number of documents (pages) if it has been supplied
-       int32 documentCount = 0;
-       if (ioExtension.FindInt32("/documentCount", &documentCount) == B_OK
-               && documentCount > 0)
-               entry->pageCount = documentCount;
-       else
-               entry->pageCount = 1;
-
-       message.AddString("type", info.name);
-       message.AddString("mime", info.MIME);
-       message.AddRef("ref", &entry->ref);
-       message.AddInt32("page", entry->page);
-       message.AddPointer("bitmap", (void*)bitmap);
-
-       deleter.Detach();
-
-       fCacheLocker.Lock();
-
-       fCacheMap.insert(std::make_pair(
-               std::make_pair(entry->ref, entry->page), entry));
-       fCacheEntriesByAge.Add(entry);
-
-       fBytes += bitmap->BitsLength();
-
-       while (fBytes > fMaxBytes || fCacheMap.size() > fMaxEntries) {
-               if (fCacheMap.size() <= 2)
-                       break;
-
-               // Remove the oldest entry
-               entry = fCacheEntriesByAge.RemoveHead();
-               fBytes -= entry->bitmap->BitsLength();
-               fCacheMap.erase(std::make_pair(entry->ref, entry->page));
-               delete entry;
-       }
-
-       fCacheLocker.Unlock();
-       return B_OK;
-}
-
-
-void
-ImageCache::_NotifyListeners(QueueEntry* entry, BMessage& message)
-{
-       std::set<BMessenger>::iterator iterator = entry->listeners.begin();
-       for (; iterator != entry->listeners.end(); iterator++) {
-               iterator->SendMessage(&message);
-       }
-}
-
-
-// #pragma mark -
-
-
-ImageFileNavigator::ImageFileNavigator(const BMessenger& target,
-       const entry_ref& ref, const BMessenger& trackerMessenger)
-       :
-       fTarget(target),
-       fProgressWindow(NULL),
+       fCurrentRef(ref),
        fDocumentIndex(1),
        fDocumentCount(1)
 {
@@ -585,98 +335,14 @@
 
 
 void
-ImageFileNavigator::SetProgressWindow(ProgressWindow* progressWindow)
+ImageFileNavigator::SetTo(const entry_ref& ref, int32 page, int32 pageCount)
 {
-       fProgressWindow = progressWindow;
-}
-
-
-status_t
-ImageFileNavigator::LoadImage(const entry_ref& ref, int32 page)
-{
-       BTranslatorRoster* roster = BTranslatorRoster::Default();
-       if (roster == NULL)
-               return B_ERROR;
-
-       if (!entry_ref_is_file(ref))
-               return B_ERROR;
-
-       BFile file(&ref, B_READ_ONLY);
-       translator_info info;
-       memset(&info, 0, sizeof(translator_info));
-       BMessage ioExtension;
-
-       if (page != 0 && ioExtension.AddInt32("/documentIndex", page) != B_OK)
-               return B_ERROR;
-
-       if (fProgressWindow != NULL) {
-               BMessage progress(kMsgProgressStatusUpdate);
-               if (ioExtension.AddMessenger("/progressMonitor",
-                               fProgressWindow) == B_OK
-                       && ioExtension.AddMessage("/progressMessage", 
&progress) == B_OK)
-                       fProgressWindow->Start();
-       }
-
-       // Translate image data and create a new ShowImage window
-
-       BBitmapStream outstream;
-
-       status_t status = roster->Identify(&file, &ioExtension, &info, 0, NULL,
-               B_TRANSLATOR_BITMAP);
-       if (status == B_OK) {
-               status = roster->Translate(&file, &info, &ioExtension, 
&outstream,
-                       B_TRANSLATOR_BITMAP);
-       }
-
-       if (fProgressWindow != NULL)
-               fProgressWindow->Stop();
-
-       if (status != B_OK)
-               return status;
-
-       BBitmap* bitmap;
-       if (outstream.DetachBitmap(&bitmap) != B_OK)
-               return B_ERROR;
-
        fCurrentRef = ref;
        fDocumentIndex = page;
-
-       // get the number of documents (pages) if it has been supplied
-       int32 documentCount = 0;
-       if (ioExtension.FindInt32("/documentCount", &documentCount) == B_OK
-               && documentCount > 0)
-               fDocumentCount = documentCount;
-       else
-               fDocumentCount = 1;
-
-       BMessage message(kMsgImageLoaded);
-       message.AddString("type", info.name);
-       message.AddString("mime", info.MIME);
-       message.AddRef("ref", &ref);
-       message.AddInt32("page", page);
-       message.AddPointer("bitmap", (void*)bitmap);
-       status = fTarget.SendMessage(&message);
-       if (status != B_OK) {
-               delete bitmap;
-               return status;
-       }
-
-       return B_OK;
+       fDocumentCount = pageCount;
 }
 
 
-void
-ImageFileNavigator::GetPath(BString* outPath)
-{
-       BEntry entry(&fCurrentRef);
-       BPath path;
-       if (entry.InitCheck() < B_OK || entry.GetPath(&path) < B_OK)
-               outPath->SetTo("");
-       else
-               outPath->SetTo(path.Path());
-}
-
-
 int32
 ImageFileNavigator::CurrentPage()
 {
@@ -695,7 +361,7 @@
 ImageFileNavigator::FirstPage()
 {
        if (fDocumentIndex != 1) {
-               LoadImage(fCurrentRef, 1);
+               fDocumentIndex = 1;
                return true;
        }
        return false;
@@ -706,7 +372,7 @@
 ImageFileNavigator::LastPage()
 {
        if (fDocumentIndex != fDocumentCount) {
-               LoadImage(fCurrentRef, fDocumentCount);
+               fDocumentIndex = fDocumentCount;
                return true;
        }
        return false;
@@ -717,7 +383,7 @@
 ImageFileNavigator::NextPage()
 {
        if (fDocumentIndex < fDocumentCount) {
-               LoadImage(fCurrentRef, ++fDocumentIndex);
+               fDocumentIndex++;
                return true;
        }
        return false;
@@ -728,7 +394,7 @@
 ImageFileNavigator::PreviousPage()
 {
        if (fDocumentIndex > 1) {
-               LoadImage(fCurrentRef, --fDocumentIndex);
+               fDocumentIndex--;
                return true;
        }
        return false;
@@ -740,31 +406,51 @@
 {
        if (page > 0 && page <= fDocumentCount && page != fDocumentIndex) {
                fDocumentIndex = page;
-               LoadImage(fCurrentRef, fDocumentIndex);
                return true;
        }
        return false;
 }
 
 
-void
+bool
 ImageFileNavigator::FirstFile()
 {
-       _LoadNextImage(true, true);
+       entry_ref ref;
+       if (fNavigator->FindNextImage(fCurrentRef, ref, false, true)) {
+               SetTo(ref, 1, 1);
+               fNavigator->UpdateSelection(fCurrentRef);
+               return true;
+       }
+
+       return false;
 }
 
 
-void
+bool
 ImageFileNavigator::NextFile()
 {
-       _LoadNextImage(true, false);
+       entry_ref ref;
+       if (fNavigator->FindNextImage(fCurrentRef, ref, true, false)) {
+               SetTo(ref, 1, 1);
+               fNavigator->UpdateSelection(fCurrentRef);
+               return true;
+       }
+
+       return false;
 }
 
 
-void
+bool
 ImageFileNavigator::PreviousFile()
 {
-       _LoadNextImage(false, false);
+       entry_ref ref;
+       if (fNavigator->FindNextImage(fCurrentRef, ref, false, false)) {
+               SetTo(ref, 1, 1);
+               fNavigator->UpdateSelection(fCurrentRef);
+               return true;
+       }
+
+       return false;
 }
 
 
@@ -785,7 +471,7 @@
 
 
 /*!    Moves the current file into the trash.
-       Returns true if a new file is being loaded, false if not.
+       Returns true if a new file should be loaded, false if not.
 */
 bool
 ImageFileNavigator::MoveFileToTrash()
@@ -803,41 +489,12 @@
        // could be invalid
        BMessenger tracker(kTrackerSignature);
        if (tracker.SendMessage(&trash) != B_OK)
-               return true;
+               return false;
 
-       if (nextRef.device != -1 && LoadImage(nextRef) == B_OK) {
-               fNavigator->UpdateSelection(nextRef);
+       if (nextRef.device != -1) {
+               SetTo(nextRef, 1, 1);
                return true;
        }
 
        return false;
 }
-
-
-// #pragma mark -
-
-
-status_t
-ImageFileNavigator::_LoadNextImage(bool next, bool rewind)
-{
-       entry_ref currentRef = fCurrentRef;
-       entry_ref ref;
-       if (fNavigator->FindNextImage(currentRef, ref, next, rewind)) {
-               // Keep trying to load images until:
-               // 1. The image loads successfully
-               // 2. The last file in the directory is found (for find next or 
find
-               //    first)
-               // 3. The first file in the directory is found (for find prev)
-               // 4. The call to _FindNextImage fails for any other reason
-               while (LoadImage(ref) != B_OK) {
-                       currentRef = ref;
-                       if (!fNavigator->FindNextImage(currentRef, ref, next, 
false))
-                               return B_ENTRY_NOT_FOUND;
-               }
-               fNavigator->UpdateSelection(fCurrentRef);
-               return B_OK;
-       }
-       return B_ENTRY_NOT_FOUND;
-}
-
-

Modified: haiku/trunk/src/apps/showimage/ImageFileNavigator.h
===================================================================
--- haiku/trunk/src/apps/showimage/ImageFileNavigator.h 2010-11-08 21:53:24 UTC 
(rev 39363)
+++ haiku/trunk/src/apps/showimage/ImageFileNavigator.h 2010-11-08 23:06:36 UTC 
(rev 39364)
@@ -22,28 +22,18 @@
 
 
 class Navigator;
-class ProgressWindow;
 
-enum {
-       kMsgImageLoaded = 'ifnL'
-};
 
-
 class ImageFileNavigator {
 public:
-                                                               
ImageFileNavigator(const BMessenger& target,
-                                                                       const 
entry_ref& ref,
+                                                               
ImageFileNavigator(const entry_ref& ref,
                                                                        const 
BMessenger& trackerMessenger);
        virtual                                         ~ImageFileNavigator();
 
-                       void                            SetProgressWindow(
-                                                                       
ProgressWindow* progressWindow);
+                       void                            SetTo(const entry_ref& 
ref, int32 page = 1,
+                                                                       int32 
pageCount = 1);
+                       const entry_ref&        CurrentRef() const { return 
fCurrentRef; }
 
-                       status_t                        LoadImage(const 
entry_ref& ref, int32 page = 1);
-                       const entry_ref&        ImageRef() const { return 
fCurrentRef; }
-
-                       void                            GetPath(BString* name);
-
                        // The same image file may have multiple pages, TIFF 
images for
                        // example. The page count is determined at image 
loading time.
                        int32                           CurrentPage();
@@ -55,20 +45,15 @@
                        bool                            PreviousPage();
                        bool                            GoToPage(int32 page);
 
-                       void                            FirstFile();
-                       void                            NextFile();
-                       void                            PreviousFile();
+                       bool                            FirstFile();
+                       bool                            NextFile();
+                       bool                            PreviousFile();
                        bool                            HasNextFile();
                        bool                            HasPreviousFile();
 
                        bool                            MoveFileToTrash();
 
 private:
-                       status_t                        _LoadNextImage(bool 
next, bool rewind);
-
-private:
-                       BMessenger                      fTarget;
-                       ProgressWindow*         fProgressWindow;
                        Navigator*                      fNavigator;
 
                        entry_ref                       fCurrentRef;

[... truncated: 477 lines follow ...]

Other related posts:

  • » [haiku-commits] r39364 - haiku/trunk/src/apps/showimage - axeld