void ShowImageWindow::MessageReceived(BMessage *message) { switch (message->what) { case MSG_MODIFIED: // If image has been modified due to a Cut or Paste fModified = true; break; case MSG_OUTPUT_TYPE: // User clicked Save As then choose an output format if (!fSavePanel) // If user doesn't already have a save panel open _SaveAs(message); break; case MSG_SAVE_PANEL: // User specified where to save the output image _SaveToFile(message); break; case B_CANCEL: delete fSavePanel; fSavePanel = NULL; break; case MSG_UPDATE_STATUS: { int32 pages = fImageView->PageCount(); int32 curPage = fImageView->CurrentPage(); bool benable = (pages > 1) ? true : false; _EnableMenuItem(fBar, MSG_PAGE_FIRST, benable); _EnableMenuItem(fBar, MSG_PAGE_LAST, benable); _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 while (fGoToPageMenu->CountItems() > 0) // Remove all page numbers delete fGoToPageMenu->RemoveItem(0L); for (int32 i = 1; i <= pages; i++) { // Fill Go To page submenu with an entry for each page BMessage *pgomsg = new BMessage(MSG_GOTO_PAGE); pgomsg->AddInt32("page", i); char shortcut = 0; if (i < 10) { shortcut = '0' + i; } else if (i == 10) { shortcut = '0'; } BString strCaption; strCaption << i; BMenuItem *item = new BMenuItem(strCaption.String(), pgomsg, shortcut); if (curPage == i) item->SetMarked(true); fGoToPageMenu->AddItem(item); } } else { // Make sure the correct page is marked BMenuItem *pcurItem; pcurItem = fGoToPageMenu->ItemAt(curPage - 1); if (!pcurItem->IsMarked()) { pcurItem->SetMarked(true); } } // Disable the Invert menu item if the bitmap color space // is B_CMAP8. (B_CMAP8 is currently unsupported by the // invert algorithm) color_space colors = B_NO_COLOR_SPACE; message->FindInt32("colors", reinterpret_cast<int32 *>(&colors)); _EnableMenuItem(fBar, MSG_INVERT, (colors != B_CMAP8)); BString status; bool messageProvidesSize = false; if (message->FindInt32("width", &fWidth) >= B_OK && message->FindInt32("height", &fHeight) >= B_OK) { status << fWidth << "x" << fHeight; messageProvidesSize = true; } BString str; if (message->FindString("status", &str) == B_OK && str.Length() > 0) { if (status.Length() > 0) status << ", "; status << str; } if (messageProvidesSize) { _UpdateResizerWindow(fWidth, fHeight); if (!fImageView->GetZoomToBounds() && !fImageView->GetShrinkToBounds() && !fFullScreen) WindowRedimension(fImageView->GetBitmap()); } fStatusView->SetText(status); UpdateTitle(); } break; case MSG_UPDATE_STATUS_TEXT: { BString status; status << fWidth << "x" << fHeight; BString str; if (message->FindString("status", &str) == B_OK && str.Length() > 0) { status << ", " << str; fStatusView->SetText(status); } } break; case MSG_SELECTION: { // The view sends this message when a selection is // made or the selection is cleared so that the window // can update the state of the appropriate menu items bool benable; if (message->FindBool("has_selection", &benable) == B_OK) { _EnableMenuItem(fBar, B_CUT, benable); _EnableMenuItem(fBar, B_COPY, benable); _EnableMenuItem(fBar, MSG_CLEAR_SELECT, benable); } } break; case MSG_UNDO_STATE: { bool benable; if (message->FindBool("can_undo", &benable) == B_OK) _EnableMenuItem(fBar, B_UNDO, benable); } break; case MSG_CLIPBOARD_CHANGED: { // The app sends this message after it examines the clipboard in // response to a B_CLIPBOARD_CHANGED message bool bdata; if (message->FindBool("data_available", &bdata) == B_OK) _EnableMenuItem(fBar, B_PASTE, bdata); } break; case B_UNDO: fImageView->Undo(); break; case B_CUT: fImageView->Cut(); break; case B_COPY: fImageView->CopySelectionToClipboard(); break; case B_PASTE: fImageView->Paste(); break; case MSG_CLEAR_SELECT: fImageView->ClearSelection(); break; case MSG_SELECT_ALL: fImageView->SelectAll(); break; case MSG_PAGE_FIRST: if (_ClosePrompt()) fImageView->FirstPage(); break; case MSG_PAGE_LAST: if (_ClosePrompt()) fImageView->LastPage(); break; case MSG_PAGE_NEXT: if (_ClosePrompt()) fImageView->NextPage(); break; case MSG_PAGE_PREV: if (_ClosePrompt()) fImageView->PrevPage(); break; case MSG_GOTO_PAGE: { if (!_ClosePrompt()) break; int32 newPage; if (message->FindInt32("page", &newPage) != B_OK) break; int32 curPage = fImageView->CurrentPage(); int32 pages = fImageView->PageCount(); if (newPage > 0 && newPage <= pages) { BMenuItem* pcurItem = fGoToPageMenu->ItemAt(curPage - 1); BMenuItem* pnewItem = fGoToPageMenu->ItemAt(newPage - 1); if (pcurItem && pnewItem) { pcurItem->SetMarked(false); pnewItem->SetMarked(true); fImageView->GoToPage(newPage); } } } break; case MSG_DITHER_IMAGE: fImageView->SetDither(_ToggleMenuItem(message->what)); break; case MSG_SHRINK_TO_WINDOW: _ResizeToWindow(true, message->what); break; case MSG_ZOOM_TO_WINDOW: _ResizeToWindow(false, message->what); break; case MSG_FILE_PREV: if (_ClosePrompt()) fImageView->PrevFile(); break; case MSG_FILE_NEXT: if (_ClosePrompt()) fImageView->NextFile(); break; case MSG_ROTATE_90: fImageView->Rotate(90); break; case MSG_ROTATE_270: fImageView->Rotate(270); break; case MSG_FLIP_LEFT_TO_RIGHT: fImageView->Flip(true); break; case MSG_FLIP_TOP_TO_BOTTOM: fImageView->Flip(false); break; case MSG_INVERT: fImageView->Invert(); break; case MSG_SLIDE_SHOW: { BMenuItem *item = fBar->FindItem(message->what); if (!item) break; if (item->IsMarked()) { item->SetMarked(false); fResizeItem->SetEnabled(true); fImageView->StopSlideShow(); } else if (_ClosePrompt()) { item->SetMarked(true); fResizeItem->SetEnabled(false); fImageView->StartSlideShow(); } } break; case MSG_SLIDE_SHOW_DELAY: { float value; if (message->FindFloat("value", &value) == B_OK) { fImageView->SetSlideShowDelay(value); // in case message is sent from popup menu _MarkSlideShowDelay(value); } } break; case MSG_FULL_SCREEN: _ToggleFullScreen(); break; case MSG_EXIT_FULL_SCREEN: if (fFullScreen) _ToggleFullScreen(); break; case MSG_SHOW_CAPTION: { fShowCaption = _ToggleMenuItem(message->what); ShowImageSettings* settings = my_app->Settings(); if (settings->Lock()) { settings->SetBool("ShowCaption", fShowCaption); settings->Unlock(); } if (fFullScreen) fImageView->SetShowCaption(fShowCaption); } break; case MSG_PAGE_SETUP: _PageSetup(); break; case MSG_PREPARE_PRINT: _PrepareForPrint(); break; case MSG_PRINT: _Print(message); break; case MSG_ZOOM_IN: fImageView->ZoomIn(); break; case MSG_ZOOM_OUT: fImageView->ZoomOut(); break; case MSG_ORIGINAL_SIZE: fImageView->SetZoom(1.0); break; case MSG_SCALE_BILINEAR: fImageView->SetScaleBilinear(_ToggleMenuItem(message->what)); break; case MSG_OPEN_RESIZER_WINDOW: { if (fImageView->GetBitmap() != NULL) { BRect rect = fImageView->GetBitmap()->Bounds(); _OpenResizerWindow(rect.IntegerWidth()+1, rect.IntegerHeight()+1); } } break; case MSG_RESIZE: { int w = message->FindInt32("w"); int h = message->FindInt32("h"); fImageView->ResizeImage(w, h); } break; case MSG_RESIZER_WINDOW_QUIT: delete fResizerWindowMessenger; fResizerWindowMessenger = NULL; break; case MSG_DESKTOP_BACKGROUND: { BMessage message(B_REFS_RECEIVED); message.AddRef("refs", fImageView->Image()); // This is used in the Backgrounds code for scaled placement message.AddInt32("placement", 'scpl'); be_roster->Launch("application/x-vnd.antares-backgrounds", &message); } break; default: BWindow::MessageReceived(message); break; } }
void ShowImageWindow::MessageReceived(BMessage* message) { if (message->WasDropped()) { uint32 type; int32 count; status_t status = message->GetInfo("refs", &type, &count); if (status == B_OK && type == B_REF_TYPE) { message->what = B_REFS_RECEIVED; be_app->PostMessage(message); } } switch (message->what) { case kMsgImageCacheImageLoaded: { fProgressWindow->Stop(); BitmapOwner* bitmapOwner = NULL; message->FindPointer("bitmapOwner", (void**)&bitmapOwner); bool first = fImageView->Bitmap() == NULL; entry_ref ref; message->FindRef("ref", &ref); if (!first && ref != fNavigator.CurrentRef()) { // ignore older images if (bitmapOwner != NULL) bitmapOwner->ReleaseReference(); break; } int32 page = message->FindInt32("page"); int32 pageCount = message->FindInt32("pageCount"); if (!first && page != fNavigator.CurrentPage()) { // ignore older pages if (bitmapOwner != NULL) bitmapOwner->ReleaseReference(); break; } status_t status = fImageView->SetImage(message); if (status != B_OK) { if (bitmapOwner != NULL) bitmapOwner->ReleaseReference(); _LoadError(ref); // quit if file could not be opened if (first) Quit(); break; } fImageType = message->FindString("type"); fNavigator.SetTo(ref, page, pageCount); fImageView->FitToBounds(); if (first) { fImageView->MakeFocus(true); // to receive key messages Show(); } _UpdateRatingMenu(); // Set width and height attributes of the currently showed file. // This should only be a temporary solution. _SaveWidthAndHeight(); break; } case kMsgImageCacheProgressUpdate: { entry_ref ref; if (message->FindRef("ref", &ref) == B_OK && ref == fNavigator.CurrentRef()) { message->what = kMsgProgressUpdate; fProgressWindow->PostMessage(message); } break; } case MSG_MODIFIED: // If image has been modified due to a Cut or Paste fModified = true; break; case MSG_OUTPUT_TYPE: // User clicked Save As then choose an output format if (!fSavePanel) // If user doesn't already have a save panel open _SaveAs(message); break; case MSG_SAVE_PANEL: // User specified where to save the output image _SaveToFile(message); break; case B_CANCEL: delete fSavePanel; fSavePanel = NULL; break; case MSG_UPDATE_STATUS: { int32 pages = fNavigator.PageCount(); int32 currentPage = fNavigator.CurrentPage(); _EnableMenuItem(fBar, MSG_PAGE_FIRST, fNavigator.HasPreviousPage()); _EnableMenuItem(fBar, MSG_PAGE_LAST, fNavigator.HasNextPage()); _EnableMenuItem(fBar, MSG_PAGE_NEXT, fNavigator.HasNextPage()); _EnableMenuItem(fBar, MSG_PAGE_PREV, fNavigator.HasPreviousPage()); fGoToPageMenu->SetEnabled(pages > 1); _EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile()); _EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile()); if (fGoToPageMenu->CountItems() != pages) { // Only rebuild the submenu if the number of // pages is different while (fGoToPageMenu->CountItems() > 0) { // Remove all page numbers delete fGoToPageMenu->RemoveItem((int32)0); } for (int32 i = 1; i <= pages; i++) { // Fill Go To page submenu with an entry for each page BMessage* goTo = new BMessage(MSG_GOTO_PAGE); goTo->AddInt32("page", i); char shortcut = 0; if (i < 10) shortcut = '0' + i; BString strCaption; strCaption << i; BMenuItem* item = new BMenuItem(strCaption.String(), goTo, shortcut, B_SHIFT_KEY); if (currentPage == i) item->SetMarked(true); fGoToPageMenu->AddItem(item); } } else { // Make sure the correct page is marked BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); if (currentItem != NULL && !currentItem->IsMarked()) currentItem->SetMarked(true); } _UpdateStatusText(message); BPath path(fImageView->Image()); SetTitle(path.Path()); break; } case MSG_UPDATE_STATUS_TEXT: { _UpdateStatusText(message); break; } case MSG_SELECTION: { // The view sends this message when a selection is // made or the selection is cleared so that the window // can update the state of the appropriate menu items bool enable; if (message->FindBool("has_selection", &enable) == B_OK) { _EnableMenuItem(fBar, B_COPY, enable); _EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable); } break; } case B_COPY: fImageView->CopySelectionToClipboard(); break; case MSG_SELECTION_MODE: { bool selectionMode = _ToggleMenuItem(MSG_SELECTION_MODE); fImageView->SetSelectionMode(selectionMode); if (!selectionMode) fImageView->ClearSelection(); break; } case MSG_CLEAR_SELECT: fImageView->ClearSelection(); break; case MSG_SELECT_ALL: fImageView->SelectAll(); break; case MSG_PAGE_FIRST: if (_ClosePrompt() && fNavigator.FirstPage()) _LoadImage(); break; case MSG_PAGE_LAST: if (_ClosePrompt() && fNavigator.LastPage()) _LoadImage(); break; case MSG_PAGE_NEXT: if (_ClosePrompt() && fNavigator.NextPage()) _LoadImage(); break; case MSG_PAGE_PREV: if (_ClosePrompt() && fNavigator.PreviousPage()) _LoadImage(); break; case MSG_GOTO_PAGE: { if (!_ClosePrompt()) break; int32 newPage; if (message->FindInt32("page", &newPage) != B_OK) break; int32 currentPage = fNavigator.CurrentPage(); int32 pages = fNavigator.PageCount(); // TODO: use radio mode instead! if (newPage > 0 && newPage <= pages) { BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1); if (currentItem != NULL && newItem != NULL) { currentItem->SetMarked(false); newItem->SetMarked(true); if (fNavigator.GoToPage(newPage)) _LoadImage(); } } break; } case kMsgFitToWindow: fImageView->FitToBounds(); break; case kMsgStretchToWindow: fImageView->SetStretchToBounds( _ToggleMenuItem(kMsgStretchToWindow)); break; case MSG_FILE_PREV: if (_ClosePrompt() && fNavigator.PreviousFile()) _LoadImage(false); break; case MSG_FILE_NEXT: case kMsgNextSlide: if (_ClosePrompt() && fNavigator.NextFile()) _LoadImage(); break; case kMsgDeleteCurrentFile: { if (fNavigator.MoveFileToTrash()) _LoadImage(); else PostMessage(B_QUIT_REQUESTED); break; } case MSG_ROTATE_90: fImageView->Rotate(90); break; case MSG_ROTATE_270: fImageView->Rotate(270); break; case MSG_FLIP_LEFT_TO_RIGHT: fImageView->Flip(true); break; case MSG_FLIP_TOP_TO_BOTTOM: fImageView->Flip(false); break; case MSG_SLIDE_SHOW: { bool fullScreen = false; message->FindBool("full screen", &fullScreen); BMenuItem* item = fBar->FindItem(message->what); if (item == NULL) break; if (item->IsMarked()) { item->SetMarked(false); _StopSlideShow(); fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false); } else if (_ClosePrompt()) { item->SetMarked(true); if (!fFullScreen && fullScreen) _ToggleFullScreen(); _StartSlideShow(); fToolBar->SetActionPressed(MSG_SLIDE_SHOW, true); } break; } case kMsgStopSlideShow: { BMenuItem* item = fBar->FindItem(MSG_SLIDE_SHOW); if (item != NULL) item->SetMarked(false); _StopSlideShow(); fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false); break; } case MSG_SLIDE_SHOW_DELAY: { bigtime_t delay; if (message->FindInt64("delay", &delay) == B_OK) { _SetSlideShowDelay(delay); // in case message is sent from popup menu _MarkSlideShowDelay(delay); } break; } case MSG_FULL_SCREEN: _ToggleFullScreen(); break; case MSG_EXIT_FULL_SCREEN: if (fFullScreen) _ToggleFullScreen(); break; case MSG_SHOW_CAPTION: { fShowCaption = _ToggleMenuItem(message->what); ShowImageSettings* settings = my_app->Settings(); if (settings->Lock()) { settings->SetBool("ShowCaption", fShowCaption); settings->Unlock(); } if (fFullScreen) fImageView->SetShowCaption(fShowCaption); } break; case MSG_PAGE_SETUP: _PageSetup(); break; case MSG_PREPARE_PRINT: _PrepareForPrint(); break; case MSG_PRINT: _Print(message); break; case MSG_ZOOM_IN: fImageView->ZoomIn(); break; case MSG_ZOOM_OUT: fImageView->ZoomOut(); break; case MSG_UPDATE_STATUS_ZOOM: fStatusView->SetZoom(fImageView->Zoom()); break; case kMsgOriginalSize: if (message->FindInt32("behavior") == BButton::B_TOGGLE_BEHAVIOR) { bool force = (message->FindInt32("be:value") == B_CONTROL_ON); fImageView->ForceOriginalSize(force); if (!force) break; } fImageView->SetZoom(1.0); break; case MSG_SCALE_BILINEAR: fImageView->SetScaleBilinear(_ToggleMenuItem(message->what)); break; case MSG_DESKTOP_BACKGROUND: { BMessage backgroundsMessage(B_REFS_RECEIVED); backgroundsMessage.AddRef("refs", fImageView->Image()); // This is used in the Backgrounds code for scaled placement backgroundsMessage.AddInt32("placement", 'scpl'); be_roster->Launch("application/x-vnd.haiku-backgrounds", &backgroundsMessage); break; } case MSG_SET_RATING: { int32 rating; if (message->FindInt32("rating", &rating) != B_OK) break; BFile file(&fNavigator.CurrentRef(), B_WRITE_ONLY); if (file.InitCheck() != B_OK) break; file.WriteAttr("Media:Rating", B_INT32_TYPE, 0, &rating, sizeof(rating)); _UpdateRatingMenu(); break; } case kMsgToggleToolBar: { fShowToolBar = _ToggleMenuItem(message->what); _SetToolBarVisible(fShowToolBar, true); ShowImageSettings* settings = my_app->Settings(); if (settings->Lock()) { settings->SetBool("ShowToolBar", fShowToolBar); settings->Unlock(); } break; } case kShowToolBarIfEnabled: { bool show; if (message->FindBool("show", &show) != B_OK) break; _SetToolBarVisible(fShowToolBar && show, true); break; } case kMsgSlideToolBar: { float offset; if (message->FindFloat("offset", &offset) == B_OK) { fToolBar->MoveBy(0, offset); fScrollView->ResizeBy(0, -offset); fScrollView->MoveBy(0, offset); UpdateIfNeeded(); snooze(15000); } break; } case kMsgFinishSlidingToolBar: { float offset; bool show; if (message->FindFloat("offset", &offset) == B_OK && message->FindBool("show", &show) == B_OK) { // Compensate rounding errors with the final placement fToolBar->MoveTo(fToolBar->Frame().left, offset); if (!show) fToolBar->Hide(); BRect frame = fToolBar->Parent()->Bounds(); frame.top = fToolBar->Frame().bottom + 1; fScrollView->MoveTo(fScrollView->Frame().left, frame.top); fScrollView->ResizeTo(fScrollView->Bounds().Width(), frame.Height() + 1); } break; } default: BWindow::MessageReceived(message); break; } }