diff --git a/src/apps/showimage/ShowImageApp.cpp b/src/apps/showimage/ShowImageApp.cpp index 4b84583194..659771719b 100644 --- a/src/apps/showimage/ShowImageApp.cpp +++ b/src/apps/showimage/ShowImageApp.cpp @@ -150,6 +150,13 @@ ShowImageApp::MessageReceived(BMessage *pmsg) void ShowImageApp::RefsReceived(BMessage *pmsg) { + // + // If a tracker window opened me, get a messenger from it. + // + if (pmsg->HasMessenger("TrackerViewToken")) { + pmsg->FindMessenger("TrackerViewToken", &fTrackerMessenger); + } + uint32 type; int32 count; status_t ret = pmsg->GetInfo("refs", &type, &count); @@ -166,7 +173,7 @@ ShowImageApp::RefsReceived(BMessage *pmsg) void ShowImageApp::Open(const entry_ref *pref) { - new ShowImageWindow(pref); + new ShowImageWindow(pref, fTrackerMessenger); } void diff --git a/src/apps/showimage/ShowImageApp.h b/src/apps/showimage/ShowImageApp.h index c2d2c6a19a..093a852b0a 100644 --- a/src/apps/showimage/ShowImageApp.h +++ b/src/apps/showimage/ShowImageApp.h @@ -54,6 +54,7 @@ private: void BroadcastToWindows(BMessage *pmsg); void CheckClipboard(); + BMessenger fTrackerMessenger; // of the window this was launched BFilePanel *fOpenPanel; bool fPulseStarted; ShowImageSettings fSettings; diff --git a/src/apps/showimage/ShowImageView.cpp b/src/apps/showimage/ShowImageView.cpp index 70b572c861..00a31dfe03 100644 --- a/src/apps/showimage/ShowImageView.cpp +++ b/src/apps/showimage/ShowImageView.cpp @@ -252,6 +252,12 @@ ShowImageView::IsImage(const entry_ref *pref) return true; } +void +ShowImageView::SetTrackerMessenger(const BMessenger& trackerMessenger) +{ + fTrackerMessenger = trackerMessenger; +} + // send message to parent about new image void ShowImageView::Notify(const char* status) @@ -1879,62 +1885,61 @@ ShowImageView::FreeEntries(BList* entries) entries->MakeEmpty(); } -bool -ShowImageView::FindNextImage(entry_ref *in_current, entry_ref *out_image, bool next, bool rewind) + +void +ShowImageView::SetTrackerSelectionToCurrent() { - ASSERT(next || !rewind); - BEntry curImage(in_current); - entry_ref entry, *ref; - BDirectory parent; - BList entries; - bool found = false; - int32 cur; - - if (curImage.GetParent(&parent) != B_OK) + BMessage setsel(B_SET_PROPERTY); + setsel.AddSpecifier("Selection"); + setsel.AddRef("data", &fCurrentRef); + fTrackerMessenger.SendMessage(&setsel); +} + +bool +ShowImageView::FindNextImage(entry_ref *in_current, entry_ref *ref, bool next, bool rewind) +{ + // shamelessly stolen, I mean copied from BeMail! + // XXX rewind is not implemented yet => slide show will stop with last image + + if (!fTrackerMessenger.IsValid()) return false; - while (parent.GetNextRef(&entry) == B_OK) { - if (entry != *in_current) { - entries.AddItem(new entry_ref(entry)); - } else { - // insert current ref, so we can find it easily after sorting - entries.AddItem(in_current); - } - } - - entries.SortItems(CompareEntries); - - cur = entries.IndexOf(in_current); - ASSERT(cur >= 0); + // + // Ask the Tracker what the next/prev file in the window is. + // Continue asking for the next reference until a valid + // image is found. + // + entry_ref nextRef = *in_current; + bool foundRef = false; + while (!foundRef) + { + BMessage request(B_GET_PROPERTY); + BMessage spc; + if (next) + spc.what = 'snxt'; + else + spc.what = 'sprv'; - // remove it so FreeEntries() does not delete it - entries.RemoveItem(in_current); - - if (next) { - // find the next image in the list - if (rewind) cur = 0; // start with first - for (; (ref = (entry_ref*)entries.ItemAt(cur)) != NULL; cur ++) { - if (IsImage(ref)) { - found = true; - *out_image = (const entry_ref)*ref; - break; - } + spc.AddString("property", "Entry"); + spc.AddRef("data", &nextRef); + + request.AddSpecifier(&spc); + BMessage reply; + if (fTrackerMessenger.SendMessage(&request, &reply) != B_OK) { + return false; } - } else { - // find the previous image in the list - cur --; - for (; cur >= 0; cur --) { - ref = (entry_ref*)entries.ItemAt(cur); - if (IsImage(ref)) { - found = true; - *out_image = (const entry_ref)*ref; - break; - } + + if (reply.FindRef("result", &nextRef) != B_OK) { + return false; + } + + if (IsImage(&nextRef)) { + foundRef = true; } } - FreeEntries(&entries); - return found; + *ref = nextRef; + return foundRef; } bool @@ -1957,6 +1962,7 @@ ShowImageView::ShowNextImage(bool next, bool rewind) if (!found) return false; } + SetTrackerSelectionToCurrent(); return true; } return false; @@ -1974,6 +1980,20 @@ ShowImageView::PrevFile() return ShowNextImage(false, false); } +bool +ShowImageView::HasNextFile() +{ + entry_ref ref; + return FindNextImage(&fCurrentRef, &ref, true, false); +} + +bool +ShowImageView::HasPrevFile() +{ + entry_ref ref; + return FindNextImage(&fCurrentRef, &ref, false, false); +} + bool ShowImageView::FirstFile() { @@ -2087,26 +2107,31 @@ ShowImageView::DoImageOperation(ImageProcessor::operation op, bool quiet) } } +// image operation initiated by user +void +ShowImageView::UserDoImageOperation(ImageProcessor::operation op, bool quiet) +{ + fUndo.Clear(); + DoImageOperation(op, quiet); +} + void ShowImageView::Rotate(int degree) { if (degree == 90) { - fUndo.Clear(); - DoImageOperation(ImageProcessor::kRotateClockwise); + UserDoImageOperation(ImageProcessor::kRotateClockwise); } else if (degree == 270) { - fUndo.Clear(); - DoImageOperation(ImageProcessor::kRotateAntiClockwise); + UserDoImageOperation(ImageProcessor::kRotateAntiClockwise); } } void ShowImageView::Mirror(bool vertical) { - fUndo.Clear(); if (vertical) { - DoImageOperation(ImageProcessor::kMirrorVertical); + UserDoImageOperation(ImageProcessor::kMirrorVertical); } else { - DoImageOperation(ImageProcessor::kMirrorHorizontal); + UserDoImageOperation(ImageProcessor::kMirrorHorizontal); } } @@ -2117,8 +2142,7 @@ ShowImageView::Invert() // Only allow an invert operation if the // bitmap color space is supported by the // invert algorithm - fUndo.Clear(); - DoImageOperation(ImageProcessor::kInvert); + UserDoImageOperation(ImageProcessor::kInvert); } } diff --git a/src/apps/showimage/ShowImageView.h b/src/apps/showimage/ShowImageView.h index a8a3f11f6a..474de89867 100644 --- a/src/apps/showimage/ShowImageView.h +++ b/src/apps/showimage/ShowImageView.h @@ -39,6 +39,7 @@ #include "Filter.h" #include "ShowImageUndo.h" +// delay scaling operation, so that a sequence of zoom in/out operations works smoother #define DELAYED_SCALING 1 class ShowImageView : public BView { @@ -49,6 +50,7 @@ public: void Pulse(); + void SetTrackerMessenger(const BMessenger& trackerMessenger); status_t SetImage(const entry_ref *pref); void SaveToFile(BDirectory* dir, const char* name, BBitmap* bitmap, const translation_format* format); void SetDither(bool dither); @@ -99,6 +101,8 @@ public: void GoToPage(int32 page); bool NextFile(); bool PrevFile(); + bool HasNextFile(); + bool HasPrevFile(); void SetSlideShowDelay(float seconds); float GetSlideShowDelay() const { return fSlideShowDelay / 10.0; } bool SlideShowStarted() const { return fSlideShow; } @@ -150,6 +154,7 @@ private: inline void CopyPixel(uchar* dest, int32 destX, int32 destY, int32 destBPR, uchar* src, int32 x, int32 y, int32 bpr, int32 bpp); inline void InvertPixel(int32 x, int32 y, uchar* dest, int32 destBPR, uchar* src, int32 bpr, int32 bpp); void DoImageOperation(enum ImageProcessor::operation op, bool quiet = false); + void UserDoImageOperation(enum ImageProcessor::operation op, bool quiet = false); BRect AlignBitmap(); void Setup(BRect r); BPoint ImageToView(BPoint p) const; @@ -158,6 +163,7 @@ private: bool IsImage(const entry_ref* pref); static int CompareEntries(const void* a, const void* b); void FreeEntries(BList* entries); + void SetTrackerSelectionToCurrent(); bool FindNextImage(entry_ref *in_current, entry_ref *out_image, bool next, bool rewind); bool ShowNextImage(bool next, bool rewind); bool FirstFile(); @@ -189,6 +195,7 @@ private: void SettingsSetBool(const char* name, bool value); void SetIcon(bool clear, icon_size which); + BMessenger fTrackerMessenger; // of the window that this was launched from entry_ref fCurrentRef; // of the image bool fDither; // dither the image int32 fDocumentIndex; // of the image in the file diff --git a/src/apps/showimage/ShowImageWindow.cpp b/src/apps/showimage/ShowImageWindow.cpp index fb64c0297f..0ec5f3315d 100644 --- a/src/apps/showimage/ShowImageWindow.cpp +++ b/src/apps/showimage/ShowImageWindow.cpp @@ -93,7 +93,7 @@ RecentDocumentsMenu::AddDynamicItem(add_state s) // Implementation of ShowImageWindow -ShowImageWindow::ShowImageWindow(const entry_ref *pref) +ShowImageWindow::ShowImageWindow(const entry_ref *pref, const BMessenger& trackerMessenger) : BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0) { fSavePanel = NULL; @@ -154,8 +154,9 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref) SetSizeLimits(250, 100000, 100, 100000); - // finish creating window + // finish creating the window fImageView->SetImage(pref); + fImageView->SetTrackerMessenger(trackerMessenger); if (InitCheck() == B_OK) { // add View menu here so it can access ShowImageView methods @@ -512,6 +513,9 @@ ShowImageWindow::MessageReceived(BMessage *pmsg) EnableMenuItem(fBar, MSG_PAGE_NEXT, benable); EnableMenuItem(fBar, MSG_PAGE_PREV, benable); + EnableMenuItem(fBar, MSG_FILE_NEXT, fImageView->HasNextFile()); + EnableMenuItem(fBar, MSG_FILE_PREV, fImageView->HasPrevFile()); + if (fGoToPageMenu->CountItems() != pages) { // Only rebuild the submenu if the number of // pages is different @@ -759,7 +763,7 @@ ShowImageWindow::MessageReceived(BMessage *pmsg) case MSG_SCALE_BILINEAR: fImageView->SetScaleBilinear(ToggleMenuItem(pmsg->what)); break; - + default: BWindow::MessageReceived(pmsg); break; diff --git a/src/apps/showimage/ShowImageWindow.h b/src/apps/showimage/ShowImageWindow.h index 94f41da0cd..b513e70afb 100644 --- a/src/apps/showimage/ShowImageWindow.h +++ b/src/apps/showimage/ShowImageWindow.h @@ -56,7 +56,7 @@ private: class ShowImageWindow : public BWindow { public: - ShowImageWindow(const entry_ref *pref); + ShowImageWindow(const entry_ref *pref, const BMessenger& trackerMessenger); virtual ~ShowImageWindow(); virtual void FrameResized(float width, float height);