1efa8b4f3SAxel Dörfler /* 2d5647665SHumdinger * Copyright 2003-2014, Haiku, Inc. All Rights Reserved. 3d9f6762dSMichael Pfeiffer * Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd. 4d9f6762dSMichael Pfeiffer * Copyright 2006 Bernd Korz. All Rights Reserved 5efa8b4f3SAxel Dörfler * Distributed under the terms of the MIT License. 6efa8b4f3SAxel Dörfler * 7efa8b4f3SAxel Dörfler * Authors: 8efa8b4f3SAxel Dörfler * Fernando Francisco de Oliveira 9efa8b4f3SAxel Dörfler * Michael Wilber 10efa8b4f3SAxel Dörfler * Michael Pfeiffer 11d9f6762dSMichael Pfeiffer * yellowTAB GmbH 12d9f6762dSMichael Pfeiffer * Bernd Korz 13e2069723SAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 149b13c418SStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 15efa8b4f3SAxel Dörfler */ 1613afa642SPhil Greenway 174fd570d3SAxel Dörfler 18efa8b4f3SAxel Dörfler #include "ShowImageWindow.h" 19efa8b4f3SAxel Dörfler 20fd952aefSRyan Leavengood #include <new> 21fd952aefSRyan Leavengood #include <stdio.h> 2204f96544SAxel Dörfler #include <stdlib.h> 236163f333SKarsten Heimrich 24efa8b4f3SAxel Dörfler #include <Alert.h> 2513afa642SPhil Greenway #include <Application.h> 2613afa642SPhil Greenway #include <Bitmap.h> 27fc0a275bSMatthew Wilber #include <BitmapStream.h> 28554e2073SAdrien Destugues #include <Button.h> 291ed4535fSStephan Aßmus #include <Catalog.h> 30efa8b4f3SAxel Dörfler #include <Clipboard.h> 3160c23976SJanus #include <ControlLook.h> 3203ad73fcSAdrien Destugues #include <DurationFormat.h> 3313afa642SPhil Greenway #include <Entry.h> 34fc0a275bSMatthew Wilber #include <File.h> 356163f333SKarsten Heimrich #include <FilePanel.h> 361ed4535fSStephan Aßmus #include <Locale.h> 3713afa642SPhil Greenway #include <Menu.h> 3813afa642SPhil Greenway #include <MenuBar.h> 3913afa642SPhil Greenway #include <MenuItem.h> 404aa63633SAxel Dörfler #include <MessageRunner.h> 4113afa642SPhil Greenway #include <Path.h> 42efa8b4f3SAxel Dörfler #include <PrintJob.h> 4336272f0dSAxel Dörfler #include <RecentItems.h> 44efa8b4f3SAxel Dörfler #include <Roster.h> 45efa8b4f3SAxel Dörfler #include <Screen.h> 4613afa642SPhil Greenway #include <ScrollView.h> 476163f333SKarsten Heimrich #include <String.h> 48efa8b4f3SAxel Dörfler #include <SupportDefs.h> 496163f333SKarsten Heimrich #include <TranslationDefs.h> 5013afa642SPhil Greenway #include <TranslationUtils.h> 5113afa642SPhil Greenway #include <TranslatorRoster.h> 5213afa642SPhil Greenway 53b9767a83SAxel Dörfler #include "ImageCache.h" 54e2069723SAxel Dörfler #include "ProgressWindow.h" 55fd952aefSRyan Leavengood #include "ShowImageApp.h" 56fd952aefSRyan Leavengood #include "ShowImageConstants.h" 57fd952aefSRyan Leavengood #include "ShowImageStatusView.h" 58fd952aefSRyan Leavengood #include "ShowImageView.h" 59cf0d8308SStephan Aßmus #include "ToolBarIcons.h" 6013afa642SPhil Greenway 61a8fc7138SMichael Pfeiffer 62cd6b5cdeSAxel Dörfler // BMessage field names used in Save messages 63cd6b5cdeSAxel Dörfler const char* kTypeField = "be:type"; 64cd6b5cdeSAxel Dörfler const char* kTranslatorField = "be:translator"; 65cd6b5cdeSAxel Dörfler 664aa63633SAxel Dörfler const bigtime_t kDefaultSlideShowDelay = 3000000; 674aa63633SAxel Dörfler // 3 seconds 684aa63633SAxel Dörfler 69cd6b5cdeSAxel Dörfler 70e2069723SAxel Dörfler // message constants 71e2069723SAxel Dörfler enum { 72e2069723SAxel Dörfler MSG_CAPTURE_MOUSE = 'mCPM', 73e2069723SAxel Dörfler MSG_CHANGE_FOCUS = 'mCFS', 74e2069723SAxel Dörfler MSG_WINDOW_QUIT = 'mWQT', 75e2069723SAxel Dörfler MSG_OUTPUT_TYPE = 'BTMN', 76e2069723SAxel Dörfler MSG_SAVE_PANEL = 'mFSP', 77e2069723SAxel Dörfler MSG_CLEAR_SELECT = 'mCSL', 78e2069723SAxel Dörfler MSG_SELECT_ALL = 'mSAL', 79e2069723SAxel Dörfler MSG_SELECTION_MODE = 'mSLM', 80e2069723SAxel Dörfler MSG_PAGE_FIRST = 'mPGF', 81e2069723SAxel Dörfler MSG_PAGE_LAST = 'mPGL', 82e2069723SAxel Dörfler MSG_PAGE_NEXT = 'mPGN', 83e2069723SAxel Dörfler MSG_PAGE_PREV = 'mPGP', 84e2069723SAxel Dörfler MSG_GOTO_PAGE = 'mGTP', 85e2069723SAxel Dörfler MSG_ZOOM_IN = 'mZIN', 86e2069723SAxel Dörfler MSG_ZOOM_OUT = 'mZOU', 87e2069723SAxel Dörfler MSG_SCALE_BILINEAR = 'mSBL', 88e2069723SAxel Dörfler MSG_DESKTOP_BACKGROUND = 'mDBG', 89e2069723SAxel Dörfler MSG_ROTATE_90 = 'mR90', 90e2069723SAxel Dörfler MSG_ROTATE_270 = 'mR27', 91e2069723SAxel Dörfler MSG_FLIP_LEFT_TO_RIGHT = 'mFLR', 92e2069723SAxel Dörfler MSG_FLIP_TOP_TO_BOTTOM = 'mFTB', 93e2069723SAxel Dörfler MSG_SLIDE_SHOW_DELAY = 'mSSD', 94e2069723SAxel Dörfler MSG_SHOW_CAPTION = 'mSCP', 95e2069723SAxel Dörfler MSG_PAGE_SETUP = 'mPSU', 96e2069723SAxel Dörfler MSG_PREPARE_PRINT = 'mPPT', 97fb94ed11SAvi Brenner MSG_GET_INFO = 'mGFI', 985b76e505SStephan Aßmus MSG_SET_RATING = 'mSRT', 99e2069723SAxel Dörfler kMsgFitToWindow = 'mFtW', 100e2069723SAxel Dörfler kMsgOriginalSize = 'mOSZ', 1014aa63633SAxel Dörfler kMsgStretchToWindow = 'mStW', 102cf0d8308SStephan Aßmus kMsgNextSlide = 'mNxS', 10394fd9498SStephan Aßmus kMsgToggleToolBar = 'mTTB', 10494fd9498SStephan Aßmus kMsgSlideToolBar = 'mSTB', 10594fd9498SStephan Aßmus kMsgFinishSlidingToolBar = 'mFST' 106e2069723SAxel Dörfler }; 107e2069723SAxel Dörfler 108e2069723SAxel Dörfler 109cd6b5cdeSAxel Dörfler // This is temporary solution for building BString with printf like format. 110cd6b5cdeSAxel Dörfler // will be removed in the future. 111cd6b5cdeSAxel Dörfler static void 112cd6b5cdeSAxel Dörfler bs_printf(BString* string, const char* format, ...) 113cd6b5cdeSAxel Dörfler { 114cd6b5cdeSAxel Dörfler va_list ap; 115cd6b5cdeSAxel Dörfler char* buf; 116cd6b5cdeSAxel Dörfler 117cd6b5cdeSAxel Dörfler va_start(ap, format); 118cd6b5cdeSAxel Dörfler vasprintf(&buf, format, ap); 119cd6b5cdeSAxel Dörfler string->SetTo(buf); 120cd6b5cdeSAxel Dörfler free(buf); 121cd6b5cdeSAxel Dörfler va_end(ap); 122cd6b5cdeSAxel Dörfler } 123cd6b5cdeSAxel Dörfler 124cd6b5cdeSAxel Dörfler 1256163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow 1266163f333SKarsten Heimrich 1276163f333SKarsten Heimrich 128546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 129546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Menus" 130cf0d8308SStephan Aßmus 131cf0d8308SStephan Aßmus 1325b76e505SStephan Aßmus ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref, 133efa8b4f3SAxel Dörfler const BMessenger& trackerMessenger) 134fd952aefSRyan Leavengood : 13594fd9498SStephan Aßmus BWindow(frame, "", B_DOCUMENT_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS), 136b9767a83SAxel Dörfler fNavigator(ref, trackerMessenger), 137fd952aefSRyan Leavengood fSavePanel(NULL), 138fd952aefSRyan Leavengood fBar(NULL), 139fd952aefSRyan Leavengood fBrowseMenu(NULL), 140fd952aefSRyan Leavengood fGoToPageMenu(NULL), 1414aa63633SAxel Dörfler fSlideShowDelayMenu(NULL), 14294a4c1c4SAugustin Cavalier fToolBar(NULL), 143fd952aefSRyan Leavengood fImageView(NULL), 144fd952aefSRyan Leavengood fStatusView(NULL), 145e2069723SAxel Dörfler fProgressWindow(new ProgressWindow()), 146fd952aefSRyan Leavengood fModified(false), 147fd952aefSRyan Leavengood fFullScreen(false), 148fd952aefSRyan Leavengood fShowCaption(true), 149cf0d8308SStephan Aßmus fShowToolBar(true), 1504aa63633SAxel Dörfler fPrintSettings(NULL), 1514aa63633SAxel Dörfler fSlideShowRunner(NULL), 1524aa63633SAxel Dörfler fSlideShowDelay(kDefaultSlideShowDelay) 15313afa642SPhil Greenway { 1542281340dSAxel Dörfler _ApplySettings(); 155fc0a275bSMatthew Wilber 15694fd9498SStephan Aßmus SetLayout(new BGroupLayout(B_VERTICAL, 0)); 15794fd9498SStephan Aßmus 15813afa642SPhil Greenway // create menu bar 15994fd9498SStephan Aßmus fBar = new BMenuBar("menu_bar"); 160b9767a83SAxel Dörfler _AddMenus(fBar); 16194fd9498SStephan Aßmus float menuBarMinWidth = fBar->MinSize().width; 162e9dcd874SAxel Dörfler AddChild(fBar); 16313afa642SPhil Greenway 16494fd9498SStephan Aßmus // Add a content view so the tool bar can be moved outside of the 16594fd9498SStephan Aßmus // visible portion without colliding with the menu bar. 166cf0d8308SStephan Aßmus 16794fd9498SStephan Aßmus BView* contentView = new BView(BRect(), "content", B_FOLLOW_NONE, 0); 168fa19dd44Slooncraz contentView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 16994fd9498SStephan Aßmus contentView->SetExplicitMinSize(BSize(250, 100)); 17094fd9498SStephan Aßmus AddChild(contentView); 17194fd9498SStephan Aßmus 17294fd9498SStephan Aßmus // Create the tool bar 17394fd9498SStephan Aßmus BRect viewFrame = contentView->Bounds(); 17494fd9498SStephan Aßmus viewFrame.right -= B_V_SCROLL_BAR_WIDTH; 17594a4c1c4SAugustin Cavalier fToolBar = new BToolBar(viewFrame); 176cf0d8308SStephan Aßmus 177cf0d8308SStephan Aßmus // Add the tool icons. 178cf0d8308SStephan Aßmus 17994a4c1c4SAugustin Cavalier // fToolBar->AddAction(MSG_FILE_OPEN, be_app, 180cf0d8308SStephan Aßmus // tool_bar_icon(kIconDocumentOpen), B_TRANSLATE("Open" B_UTF8_ELLIPSIS)); 18194a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FILE_PREV, this, 18258ee42e9SAugustin Cavalier tool_bar_icon(kIconGoPrevious), B_TRANSLATE("Previous file")); 18394a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FILE_NEXT, this, tool_bar_icon(kIconGoNext), 18458ee42e9SAugustin Cavalier B_TRANSLATE("Next file")); 185a877c0e7SStephan Aßmus BMessage* fullScreenSlideShow = new BMessage(MSG_SLIDE_SHOW); 186a877c0e7SStephan Aßmus fullScreenSlideShow->AddBool("full screen", true); 18794a4c1c4SAugustin Cavalier fToolBar->AddAction(fullScreenSlideShow, this, 18858ee42e9SAugustin Cavalier tool_bar_icon(kIconMediaMovieLibrary), B_TRANSLATE("Slide show")); 18994a4c1c4SAugustin Cavalier fToolBar->AddSeparator(); 19094a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_SELECTION_MODE, this, 191cf0d8308SStephan Aßmus tool_bar_icon(kIconDrawRectangularSelection), 19258ee42e9SAugustin Cavalier B_TRANSLATE("Selection mode")); 19394a4c1c4SAugustin Cavalier fToolBar->AddSeparator(); 19494a4c1c4SAugustin Cavalier fToolBar->AddAction(kMsgOriginalSize, this, 19558ee42e9SAugustin Cavalier tool_bar_icon(kIconZoomOriginal), B_TRANSLATE("Original size"), NULL, 19658ee42e9SAugustin Cavalier true); 19794a4c1c4SAugustin Cavalier fToolBar->AddAction(kMsgFitToWindow, this, 19858ee42e9SAugustin Cavalier tool_bar_icon(kIconZoomFitBest), B_TRANSLATE("Fit to window")); 19994a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_ZOOM_IN, this, tool_bar_icon(kIconZoomIn), 20058ee42e9SAugustin Cavalier B_TRANSLATE("Zoom in")); 20194a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_ZOOM_OUT, this, tool_bar_icon(kIconZoomOut), 20258ee42e9SAugustin Cavalier B_TRANSLATE("Zoom out")); 203442e457dSGerasim Troeglazov fToolBar->AddSeparator(); 204442e457dSGerasim Troeglazov fToolBar->AddAction(MSG_PAGE_PREV, this, tool_bar_icon(kIconPagePrevious), 20558ee42e9SAugustin Cavalier B_TRANSLATE("Previous page")); 206442e457dSGerasim Troeglazov fToolBar->AddAction(MSG_PAGE_NEXT, this, tool_bar_icon(kIconPageNext), 20758ee42e9SAugustin Cavalier B_TRANSLATE("Next page")); 20894a4c1c4SAugustin Cavalier fToolBar->AddGlue(); 20994a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FULL_SCREEN, this, 21058ee42e9SAugustin Cavalier tool_bar_icon(kIconViewWindowed), B_TRANSLATE("Leave full screen")); 21194a4c1c4SAugustin Cavalier fToolBar->SetActionVisible(MSG_FULL_SCREEN, false); 212cf0d8308SStephan Aßmus 21394a4c1c4SAugustin Cavalier fToolBar->ResizeTo(viewFrame.Width(), fToolBar->MinSize().height); 214cf0d8308SStephan Aßmus 21594a4c1c4SAugustin Cavalier contentView->AddChild(fToolBar); 216cf0d8308SStephan Aßmus 217cf0d8308SStephan Aßmus if (fShowToolBar) 21894a4c1c4SAugustin Cavalier viewFrame.top = fToolBar->Frame().bottom + 1; 219cf0d8308SStephan Aßmus else 22094a4c1c4SAugustin Cavalier fToolBar->Hide(); 221cf0d8308SStephan Aßmus 22295667008SJanus fToolBarVisible = fShowToolBar; 22395667008SJanus 22494fd9498SStephan Aßmus viewFrame.bottom = contentView->Bounds().bottom; 22513afa642SPhil Greenway viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; 22613afa642SPhil Greenway 22713afa642SPhil Greenway // create the image view 228d3046f7dSMichael Pfeiffer fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL, 229e2069723SAxel Dörfler B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED 230e2069723SAxel Dörfler | B_FRAME_EVENTS); 23113afa642SPhil Greenway // wrap a scroll view around the view 232cf0d8308SStephan Aßmus fScrollView = new BScrollView("image_scroller", fImageView, 233cae52eadSJanus B_FOLLOW_ALL, 0, true, true, B_PLAIN_BORDER); 23494fd9498SStephan Aßmus contentView->AddChild(fScrollView); 23513afa642SPhil Greenway 236cae52eadSJanus fStatusView = new ShowImageStatusView(fScrollView); 237cae52eadSJanus fScrollView->AddChild(fStatusView); 23813afa642SPhil Greenway 2399b13c418SStephan Aßmus // Update minimum window size 24094a4c1c4SAugustin Cavalier float toolBarMinWidth = fToolBar->MinSize().width; 2419b13c418SStephan Aßmus SetSizeLimits(std::max(menuBarMinWidth, toolBarMinWidth), 100000, 100, 2429b13c418SStephan Aßmus 100000); 24313afa642SPhil Greenway 244134d6076SMichael Pfeiffer // finish creating the window 245b9767a83SAxel Dörfler if (_LoadImage() != B_OK) { 246ba3217eeSAxel Dörfler _LoadError(ref); 2475e09d5dbSRyan Leavengood Quit(); 24801939af6SAxel Dörfler return; 249d10d5947SMichael Pfeiffer } 250402c09e5SMatthew Wilber 251d9f6762dSMichael Pfeiffer // add View menu here so it can access ShowImageView methods 252546208a5SOliver Tappe BMenu* menu = new BMenu(B_TRANSLATE_CONTEXT("View", "Menus")); 253fd952aefSRyan Leavengood _BuildViewMenu(menu, false); 254d9f6762dSMichael Pfeiffer fBar->AddItem(menu); 255d9f6762dSMichael Pfeiffer 2565b76e505SStephan Aßmus fBar->AddItem(_BuildRatingMenu()); 2575b76e505SStephan Aßmus 258d9f6762dSMichael Pfeiffer SetPulseRate(100000); 259d9f6762dSMichael Pfeiffer // every 1/10 second; ShowImageView needs it for marching ants 260d9f6762dSMichael Pfeiffer 2616db01936SAxel Dörfler _MarkMenuItem(menu, MSG_SELECTION_MODE, 2626db01936SAxel Dörfler fImageView->IsSelectionModeEnabled()); 2636db01936SAxel Dörfler 264402c09e5SMatthew Wilber // Tell application object to query the clipboard 265402c09e5SMatthew Wilber // and tell this window if it contains interesting data or not 266402c09e5SMatthew Wilber be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED); 267cd6b5cdeSAxel Dörfler 268cd6b5cdeSAxel Dörfler // The window will be shown on screen automatically 269cd6b5cdeSAxel Dörfler Run(); 27013afa642SPhil Greenway } 27113afa642SPhil Greenway 272efa8b4f3SAxel Dörfler 27313afa642SPhil Greenway ShowImageWindow::~ShowImageWindow() 27413afa642SPhil Greenway { 275e2069723SAxel Dörfler fProgressWindow->Lock(); 276e2069723SAxel Dörfler fProgressWindow->Quit(); 2774aa63633SAxel Dörfler 2784aa63633SAxel Dörfler _StopSlideShow(); 27913afa642SPhil Greenway } 28013afa642SPhil Greenway 281efa8b4f3SAxel Dörfler 282cdb89ebbSMatthew Wilber void 283d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu) 284d9f6762dSMichael Pfeiffer { 285fd952aefSRyan Leavengood _BuildViewMenu(menu, true); 286d9f6762dSMichael Pfeiffer } 287efa8b4f3SAxel Dörfler 28856b0c7b9SKarsten Heimrich 289cdb89ebbSMatthew Wilber void 290fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) 291da87390fSMichael Pfeiffer { 292905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this); 2934aa63633SAxel Dörfler _MarkMenuItem(menu, MSG_SLIDE_SHOW, fSlideShowRunner != NULL); 294905c8c8cSMatt Madia BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay")); 2954aa63633SAxel Dörfler if (fSlideShowDelayMenu == NULL) 2964aa63633SAxel Dörfler fSlideShowDelayMenu = delayMenu; 297efa8b4f3SAxel Dörfler 298efa8b4f3SAxel Dörfler delayMenu->SetRadioMode(true); 2994aa63633SAxel Dörfler 3004aa63633SAxel Dörfler int32 kDelays[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 20}; 3014aa63633SAxel Dörfler for (uint32 i = 0; i < sizeof(kDelays) / sizeof(kDelays[0]); i++) { 30203ad73fcSAdrien Destugues BString text; 30303ad73fcSAdrien Destugues BDurationFormat format; 30403ad73fcSAdrien Destugues text.Truncate(0); 30503ad73fcSAdrien Destugues format.Format(text, 0, kDelays[i] * 1000000LL); 3064aa63633SAxel Dörfler 3074aa63633SAxel Dörfler _AddDelayItem(delayMenu, text.String(), kDelays[i] * 1000000LL); 3084aa63633SAxel Dörfler } 309efa8b4f3SAxel Dörfler menu->AddItem(delayMenu); 31030060f17SMatthew Wilber 311efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 312efa8b4f3SAxel Dörfler 313905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Original size"), 314e2069723SAxel Dörfler kMsgOriginalSize, '1', 0, this); 315e2069723SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Fit to window"), 316e2069723SAxel Dörfler kMsgFitToWindow, '0', 0, this); 317905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this); 318905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this); 319efa8b4f3SAxel Dörfler 320efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 321efa8b4f3SAxel Dörfler 3224fd570d3SAxel Dörfler if (!popupMenu || fFullScreen) { 323905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), 324905c8c8cSMatt Madia MSG_SCALE_BILINEAR, 0, 0, this); 3254fd570d3SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Stretch to window"), 326e2069723SAxel Dörfler kMsgStretchToWindow, 0, 0, this); 327efa8b4f3SAxel Dörfler 328efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 32932c22143SAxel Dörfler } 330efa8b4f3SAxel Dörfler 331905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Full screen"), 332905c8c8cSMatt Madia MSG_FULL_SCREEN, B_ENTER, 0, this); 333fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen); 334efa8b4f3SAxel Dörfler 335905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"), 336905c8c8cSMatt Madia MSG_SHOW_CAPTION, 0, 0, this); 337fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption); 338efa8b4f3SAxel Dörfler 339e2069723SAxel Dörfler _MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->ScaleBilinear()); 340e2069723SAxel Dörfler _MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds()); 341a60adbf9SAxel Dörfler 342cf0d8308SStephan Aßmus if (!popupMenu) { 34394fd9498SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar, 344d5647665SHumdinger 'B', 0, this); 345cf0d8308SStephan Aßmus _MarkMenuItem(menu, kMsgToggleToolBar, 34694a4c1c4SAugustin Cavalier !fToolBar->IsHidden(fToolBar)); 347cf0d8308SStephan Aßmus } 348cf0d8308SStephan Aßmus 349d9f6762dSMichael Pfeiffer if (popupMenu) { 350a60adbf9SAxel Dörfler menu->AddSeparatorItem(); 351905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 3521ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 353d9f6762dSMichael Pfeiffer } 354da87390fSMichael Pfeiffer } 355da87390fSMichael Pfeiffer 356efa8b4f3SAxel Dörfler 3575b76e505SStephan Aßmus BMenu* 3585b76e505SStephan Aßmus ShowImageWindow::_BuildRatingMenu() 3595b76e505SStephan Aßmus { 3605b76e505SStephan Aßmus fRatingMenu = new BMenu(B_TRANSLATE("Rating")); 3615b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) { 3625b76e505SStephan Aßmus BString label; 3635b76e505SStephan Aßmus label << i; 3645b76e505SStephan Aßmus BMessage* message = new BMessage(MSG_SET_RATING); 3655b76e505SStephan Aßmus message->AddInt32("rating", i); 3665b76e505SStephan Aßmus fRatingMenu->AddItem(new BMenuItem(label.String(), message)); 3675b76e505SStephan Aßmus } 3685b76e505SStephan Aßmus // NOTE: We may want to encapsulate the Rating menu within a more 3695b76e505SStephan Aßmus // general "Attributes" menu. 3705b76e505SStephan Aßmus return fRatingMenu; 3715b76e505SStephan Aßmus } 3725b76e505SStephan Aßmus 3735b76e505SStephan Aßmus 374da87390fSMichael Pfeiffer void 375b9767a83SAxel Dörfler ShowImageWindow::_AddMenus(BMenuBar* bar) 37613afa642SPhil Greenway { 377905c8c8cSMatt Madia BMenu* menu = new BMenu(B_TRANSLATE("File")); 37836272f0dSAxel Dörfler 37936272f0dSAxel Dörfler // Add recent files to "Open File" entry as sub-menu. 38036272f0dSAxel Dörfler BMenuItem* item = new BMenuItem(BRecentFilesList::NewFileListMenu( 38136272f0dSAxel Dörfler B_TRANSLATE("Open" B_UTF8_ELLIPSIS), NULL, NULL, be_app, 10, true, 38236272f0dSAxel Dörfler NULL, kApplicationSignature), new BMessage(MSG_FILE_OPEN)); 38336272f0dSAxel Dörfler item->SetShortcut('O', 0); 38436272f0dSAxel Dörfler item->SetTarget(be_app); 38536272f0dSAxel Dörfler menu->AddItem(item); 386efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 38736272f0dSAxel Dörfler 3886db01936SAxel Dörfler BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS), 3891ed4535fSStephan Aßmus B_ITEMS_IN_COLUMN); 3906db01936SAxel Dörfler BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP); 391fc0a275bSMatthew Wilber // Fill Save As submenu with all types that can be converted 392fc0a275bSMatthew Wilber // to from the Be bitmap image format 3936db01936SAxel Dörfler menu->AddItem(menuSaveAs); 394905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this); 395d5647665SHumdinger _AddItemMenu(menu, B_TRANSLATE("Move to Trash"), kMsgDeleteCurrentFile, 'T', 0, this); 396fb94ed11SAvi Brenner _AddItemMenu(menu, B_TRANSLATE("Get info" B_UTF8_ELLIPSIS), 397fb94ed11SAvi Brenner MSG_GET_INFO, 'I', 0, this); 398efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 399905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS), 4001ed4535fSStephan Aßmus MSG_PAGE_SETUP, 0, 0, this); 401905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS), 4021ed4535fSStephan Aßmus MSG_PREPARE_PRINT, 'P', 0, this); 403efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 404905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app); 405efa8b4f3SAxel Dörfler bar->AddItem(menu); 40613afa642SPhil Greenway 407905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Edit")); 408905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false); 409efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 410cf0d8308SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Selection mode"), MSG_SELECTION_MODE, 0, 0, 4116db01936SAxel Dörfler this); 41232c22143SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Clear selection"), 41332c22143SAxel Dörfler MSG_CLEAR_SELECT, 0, 0, this, false); 414905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Select all"), 415905c8c8cSMatt Madia MSG_SELECT_ALL, 'A', 0, this); 416efa8b4f3SAxel Dörfler bar->AddItem(menu); 41713afa642SPhil Greenway 418905c8c8cSMatt Madia menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse")); 419905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("First page"), 4201ed4535fSStephan Aßmus MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this); 421905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Last page"), 4221ed4535fSStephan Aßmus MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this); 423905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous page"), 424905c8c8cSMatt Madia MSG_PAGE_PREV, B_LEFT_ARROW, 0, this); 425905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next page"), 426905c8c8cSMatt Madia MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this); 427905c8c8cSMatt Madia fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page")); 4285e427b6aSMichael Pfeiffer fGoToPageMenu->SetRadioMode(true); 429efa8b4f3SAxel Dörfler menu->AddItem(fGoToPageMenu); 430efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 431905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous file"), 432905c8c8cSMatt Madia MSG_FILE_PREV, B_UP_ARROW, 0, this); 433905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next file"), 434905c8c8cSMatt Madia MSG_FILE_NEXT, B_DOWN_ARROW, 0, this); 435efa8b4f3SAxel Dörfler bar->AddItem(menu); 43603839579SMatthew Wilber 437905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Image")); 438905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"), 439905c8c8cSMatt Madia MSG_ROTATE_90, 'R', 0, this); 440905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"), 4411ed4535fSStephan Aßmus MSG_ROTATE_270, 'R', B_SHIFT_KEY, this); 442efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 443905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip left to right"), 4441ed4535fSStephan Aßmus MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this); 445905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"), 4461ed4535fSStephan Aßmus MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this); 447efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 448905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 4491ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 45004f96544SAxel Dörfler 45104f96544SAxel Dörfler bar->AddItem(menu); 45213afa642SPhil Greenway } 45313afa642SPhil Greenway 454efa8b4f3SAxel Dörfler 455cdb89ebbSMatthew Wilber BMenuItem* 456fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what, 4574fd570d3SAxel Dörfler char shortcut, uint32 modifier, const BHandler* target, bool enabled) 458cdb89ebbSMatthew Wilber { 4594fd570d3SAxel Dörfler BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut, 4604fd570d3SAxel Dörfler modifier); 461efa8b4f3SAxel Dörfler menu->AddItem(item); 462efa8b4f3SAxel Dörfler 4636163f333SKarsten Heimrich item->SetTarget(target); 4646163f333SKarsten Heimrich item->SetEnabled(enabled); 4656163f333SKarsten Heimrich 466efa8b4f3SAxel Dörfler return item; 46713afa642SPhil Greenway } 46813afa642SPhil Greenway 469efa8b4f3SAxel Dörfler 470ad13f387SMichael Pfeiffer BMenuItem* 4714aa63633SAxel Dörfler ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, bigtime_t delay) 472ad13f387SMichael Pfeiffer { 473efa8b4f3SAxel Dörfler BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY); 4744aa63633SAxel Dörfler message->AddInt64("delay", delay); 475ad13f387SMichael Pfeiffer 4766163f333SKarsten Heimrich BMenuItem* item = new BMenuItem(label, message, 0); 477efa8b4f3SAxel Dörfler item->SetTarget(this); 478ad13f387SMichael Pfeiffer 4794aa63633SAxel Dörfler if (delay == fSlideShowDelay) 480efa8b4f3SAxel Dörfler item->SetMarked(true); 481ad13f387SMichael Pfeiffer 482efa8b4f3SAxel Dörfler menu->AddItem(item); 483efa8b4f3SAxel Dörfler return item; 484ad13f387SMichael Pfeiffer } 485ad13f387SMichael Pfeiffer 486efa8b4f3SAxel Dörfler 487cdb89ebbSMatthew Wilber void 488e2069723SAxel Dörfler ShowImageWindow::_ResizeWindowToImage() 48913afa642SPhil Greenway { 490e2069723SAxel Dörfler BBitmap* bitmap = fImageView->Bitmap(); 491d10d5947SMichael Pfeiffer BScreen screen; 492e2069723SAxel Dörfler if (bitmap == NULL || !screen.IsValid()) 493efa8b4f3SAxel Dörfler return; 494efa8b4f3SAxel Dörfler 4951076d97bSAxel Dörfler // TODO: use View::GetPreferredSize() instead? 4961076d97bSAxel Dörfler BRect r(bitmap->Bounds()); 4971076d97bSAxel Dörfler float width = r.Width() + B_V_SCROLL_BAR_WIDTH; 4981076d97bSAxel Dörfler float height = r.Height() + 1 + fBar->Frame().Height() 4991076d97bSAxel Dörfler + B_H_SCROLL_BAR_HEIGHT; 500cdb89ebbSMatthew Wilber 5016163f333SKarsten Heimrich BRect frame = screen.Frame(); 5026163f333SKarsten Heimrich const float windowBorder = 5; 503d10d5947SMichael Pfeiffer // dimensions so that window does not reach outside of screen 5046163f333SKarsten Heimrich float maxWidth = frame.Width() + 1 - windowBorder - Frame().left; 5056163f333SKarsten Heimrich float maxHeight = frame.Height() + 1 - windowBorder - Frame().top; 506cdb89ebbSMatthew Wilber 507a8fc7138SMichael Pfeiffer // We have to check size limits manually, otherwise 508a8fc7138SMichael Pfeiffer // menu bar will be too short for small images. 509efa8b4f3SAxel Dörfler 510fc5ca95dSStephan Aßmus float minW, maxW, minH, maxH; 511a8fc7138SMichael Pfeiffer GetSizeLimits(&minW, &maxW, &minH, &maxH); 512efa8b4f3SAxel Dörfler if (maxWidth > maxW) 513efa8b4f3SAxel Dörfler maxWidth = maxW; 514efa8b4f3SAxel Dörfler if (maxHeight > maxH) 515efa8b4f3SAxel Dörfler maxHeight = maxH; 516efa8b4f3SAxel Dörfler if (width < minW) 517efa8b4f3SAxel Dörfler width = minW; 518efa8b4f3SAxel Dörfler if (height < minH) 519efa8b4f3SAxel Dörfler height = minH; 520a8fc7138SMichael Pfeiffer 521efa8b4f3SAxel Dörfler if (width > maxWidth) 522efa8b4f3SAxel Dörfler width = maxWidth; 523efa8b4f3SAxel Dörfler if (height > maxHeight) 524efa8b4f3SAxel Dörfler height = maxHeight; 525d10d5947SMichael Pfeiffer 526d10d5947SMichael Pfeiffer ResizeTo(width, height); 52713afa642SPhil Greenway } 52813afa642SPhil Greenway 529efa8b4f3SAxel Dörfler 5307eca0987SMichael Pfeiffer bool 531fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what) 5327eca0987SMichael Pfeiffer { 5337eca0987SMichael Pfeiffer bool marked = false; 5346163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(what); 5357eca0987SMichael Pfeiffer if (item != NULL) { 5367eca0987SMichael Pfeiffer marked = !item->IsMarked(); 5377eca0987SMichael Pfeiffer item->SetMarked(marked); 5387eca0987SMichael Pfeiffer } 53994a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(what, marked); 5407eca0987SMichael Pfeiffer return marked; 5417eca0987SMichael Pfeiffer } 5427eca0987SMichael Pfeiffer 543efa8b4f3SAxel Dörfler 544cdb89ebbSMatthew Wilber void 545fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable) 546e6a50d9cSMichael Pfeiffer { 5476163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 5486163f333SKarsten Heimrich if (item && item->IsEnabled() != enable) 549e6a50d9cSMichael Pfeiffer item->SetEnabled(enable); 55094a4c1c4SAugustin Cavalier fToolBar->SetActionEnabled(what, enable); 551e6a50d9cSMichael Pfeiffer } 552e6a50d9cSMichael Pfeiffer 553efa8b4f3SAxel Dörfler 554e6a50d9cSMichael Pfeiffer void 555fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked) 556e6a50d9cSMichael Pfeiffer { 5576163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 5586163f333SKarsten Heimrich if (item && item->IsMarked() != marked) 559e6a50d9cSMichael Pfeiffer item->SetMarked(marked); 56094a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(what, marked); 561e6a50d9cSMichael Pfeiffer } 562e6a50d9cSMichael Pfeiffer 563efa8b4f3SAxel Dörfler 564da87390fSMichael Pfeiffer void 5654aa63633SAxel Dörfler ShowImageWindow::_MarkSlideShowDelay(bigtime_t delay) 566da87390fSMichael Pfeiffer { 5674aa63633SAxel Dörfler const int32 count = fSlideShowDelayMenu->CountItems(); 5684aa63633SAxel Dörfler for (int32 i = 0; i < count; i ++) { 5694aa63633SAxel Dörfler BMenuItem* item = fSlideShowDelayMenu->ItemAt(i); 5704aa63633SAxel Dörfler if (item != NULL) { 5714aa63633SAxel Dörfler bigtime_t itemDelay; 5724aa63633SAxel Dörfler if (item->Message()->FindInt64("delay", &itemDelay) == B_OK 5734aa63633SAxel Dörfler && itemDelay == delay) { 574da87390fSMichael Pfeiffer item->SetMarked(true); 575da87390fSMichael Pfeiffer return; 576da87390fSMichael Pfeiffer } 577da87390fSMichael Pfeiffer } 578da87390fSMichael Pfeiffer } 579da87390fSMichael Pfeiffer } 580e6a50d9cSMichael Pfeiffer 58119c76de4SMichael Pfeiffer 58219c76de4SMichael Pfeiffer void 583e2069723SAxel Dörfler ShowImageWindow::Zoom(BPoint origin, float width, float height) 58419c76de4SMichael Pfeiffer { 585e2069723SAxel Dörfler _ToggleFullScreen(); 58619c76de4SMichael Pfeiffer } 58719c76de4SMichael Pfeiffer 588efa8b4f3SAxel Dörfler 589e6a50d9cSMichael Pfeiffer void 590efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message) 59113afa642SPhil Greenway { 592e2069723SAxel Dörfler if (message->WasDropped()) { 593e2069723SAxel Dörfler uint32 type; 594e2069723SAxel Dörfler int32 count; 595e2069723SAxel Dörfler status_t status = message->GetInfo("refs", &type, &count); 596e2069723SAxel Dörfler if (status == B_OK && type == B_REF_TYPE) { 597e2069723SAxel Dörfler message->what = B_REFS_RECEIVED; 598e2069723SAxel Dörfler be_app->PostMessage(message); 599e2069723SAxel Dörfler } 600e2069723SAxel Dörfler } 601e2069723SAxel Dörfler 602efa8b4f3SAxel Dörfler switch (message->what) { 603e2069723SAxel Dörfler case kMsgImageCacheImageLoaded: 604cd6b5cdeSAxel Dörfler { 605e2069723SAxel Dörfler fProgressWindow->Stop(); 606e2069723SAxel Dörfler 607df942b3eSAxel Dörfler BitmapOwner* bitmapOwner = NULL; 608df942b3eSAxel Dörfler message->FindPointer("bitmapOwner", (void**)&bitmapOwner); 609df942b3eSAxel Dörfler 610cd6b5cdeSAxel Dörfler bool first = fImageView->Bitmap() == NULL; 611b9767a83SAxel Dörfler entry_ref ref; 612b9767a83SAxel Dörfler message->FindRef("ref", &ref); 613b9767a83SAxel Dörfler if (!first && ref != fNavigator.CurrentRef()) { 614b9767a83SAxel Dörfler // ignore older images 615df942b3eSAxel Dörfler if (bitmapOwner != NULL) 616df942b3eSAxel Dörfler bitmapOwner->ReleaseReference(); 617b9767a83SAxel Dörfler break; 618b9767a83SAxel Dörfler } 619cd6b5cdeSAxel Dörfler 620baa27ccbSJanus int32 page = message->FindInt32("page"); 621baa27ccbSJanus int32 pageCount = message->FindInt32("pageCount"); 622baa27ccbSJanus if (!first && page != fNavigator.CurrentPage()) { 623baa27ccbSJanus // ignore older pages 624baa27ccbSJanus if (bitmapOwner != NULL) 625baa27ccbSJanus bitmapOwner->ReleaseReference(); 626baa27ccbSJanus break; 627baa27ccbSJanus } 628baa27ccbSJanus 629cd6b5cdeSAxel Dörfler status_t status = fImageView->SetImage(message); 630cd6b5cdeSAxel Dörfler if (status != B_OK) { 631df942b3eSAxel Dörfler if (bitmapOwner != NULL) 632df942b3eSAxel Dörfler bitmapOwner->ReleaseReference(); 633df942b3eSAxel Dörfler 634cd6b5cdeSAxel Dörfler _LoadError(ref); 635cd6b5cdeSAxel Dörfler 636cd6b5cdeSAxel Dörfler // quit if file could not be opened 637cd6b5cdeSAxel Dörfler if (first) 638cd6b5cdeSAxel Dörfler Quit(); 639cd6b5cdeSAxel Dörfler break; 640cd6b5cdeSAxel Dörfler } 641cd6b5cdeSAxel Dörfler 642cd6b5cdeSAxel Dörfler fImageType = message->FindString("type"); 643baa27ccbSJanus fNavigator.SetTo(ref, page, pageCount); 644cd6b5cdeSAxel Dörfler 645e2069723SAxel Dörfler fImageView->FitToBounds(); 646cd6b5cdeSAxel Dörfler if (first) { 647cd6b5cdeSAxel Dörfler fImageView->MakeFocus(true); 648cd6b5cdeSAxel Dörfler // to receive key messages 649cd6b5cdeSAxel Dörfler Show(); 650e2069723SAxel Dörfler } 6515b76e505SStephan Aßmus _UpdateRatingMenu(); 652e62a6973SJanus // Set width and height attributes of the currently showed file. 653e62a6973SJanus // This should only be a temporary solution. 654e62a6973SJanus _SaveWidthAndHeight(); 655e2069723SAxel Dörfler break; 656e2069723SAxel Dörfler } 657e2069723SAxel Dörfler 658e2069723SAxel Dörfler case kMsgImageCacheProgressUpdate: 659e2069723SAxel Dörfler { 660e2069723SAxel Dörfler entry_ref ref; 661e2069723SAxel Dörfler if (message->FindRef("ref", &ref) == B_OK 662e2069723SAxel Dörfler && ref == fNavigator.CurrentRef()) { 663e2069723SAxel Dörfler message->what = kMsgProgressUpdate; 664e2069723SAxel Dörfler fProgressWindow->PostMessage(message); 665cd6b5cdeSAxel Dörfler } 666cd6b5cdeSAxel Dörfler break; 667cd6b5cdeSAxel Dörfler } 668cd6b5cdeSAxel Dörfler 669ee7b4f39SMatthew Wilber case MSG_MODIFIED: 670ee7b4f39SMatthew Wilber // If image has been modified due to a Cut or Paste 671ee7b4f39SMatthew Wilber fModified = true; 672ee7b4f39SMatthew Wilber break; 673ee7b4f39SMatthew Wilber 674fc0a275bSMatthew Wilber case MSG_OUTPUT_TYPE: 675fc0a275bSMatthew Wilber // User clicked Save As then choose an output format 676d3046f7dSMichael Pfeiffer if (!fSavePanel) 677cdb89ebbSMatthew Wilber // If user doesn't already have a save panel open 678fd952aefSRyan Leavengood _SaveAs(message); 67913afa642SPhil Greenway break; 680fc0a275bSMatthew Wilber 681fc0a275bSMatthew Wilber case MSG_SAVE_PANEL: 682fc0a275bSMatthew Wilber // User specified where to save the output image 683fd952aefSRyan Leavengood _SaveToFile(message); 68407caaa8eSMatthew Wilber break; 68507caaa8eSMatthew Wilber 686cdb89ebbSMatthew Wilber case B_CANCEL: 687d3046f7dSMichael Pfeiffer delete fSavePanel; 688d3046f7dSMichael Pfeiffer fSavePanel = NULL; 689cdb89ebbSMatthew Wilber break; 690cdb89ebbSMatthew Wilber 6916db01936SAxel Dörfler case MSG_UPDATE_STATUS: 6926db01936SAxel Dörfler { 693cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 694cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 6956c305411SMatthew Wilber 696baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_FIRST, 697baa27ccbSJanus fNavigator.HasPreviousPage()); 698baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_LAST, fNavigator.HasNextPage()); 699baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_NEXT, fNavigator.HasNextPage()); 700baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_PREV, fNavigator.HasPreviousPage()); 701baa27ccbSJanus fGoToPageMenu->SetEnabled(pages > 1); 7021d592070SMatthew Wilber 703cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile()); 704cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile()); 705134d6076SMichael Pfeiffer 706d3046f7dSMichael Pfeiffer if (fGoToPageMenu->CountItems() != pages) { 7076c305411SMatthew Wilber // Only rebuild the submenu if the number of 7086c305411SMatthew Wilber // pages is different 7096c305411SMatthew Wilber 710cd6b5cdeSAxel Dörfler while (fGoToPageMenu->CountItems() > 0) { 7116c305411SMatthew Wilber // Remove all page numbers 7127f4d1af4SSergei Reznikov delete fGoToPageMenu->RemoveItem((int32)0); 713cd6b5cdeSAxel Dörfler } 7146c305411SMatthew Wilber 715780d8a62SMichael Pfeiffer for (int32 i = 1; i <= pages; i++) { 7166c305411SMatthew Wilber // Fill Go To page submenu with an entry for each page 717cd6b5cdeSAxel Dörfler BMessage* goTo = new BMessage(MSG_GOTO_PAGE); 718cd6b5cdeSAxel Dörfler goTo->AddInt32("page", i); 7196163f333SKarsten Heimrich 7206163f333SKarsten Heimrich char shortcut = 0; 721cd6b5cdeSAxel Dörfler if (i < 10) 722780d8a62SMichael Pfeiffer shortcut = '0' + i; 7236163f333SKarsten Heimrich 7246163f333SKarsten Heimrich BString strCaption; 7256163f333SKarsten Heimrich strCaption << i; 7266163f333SKarsten Heimrich 727cd6b5cdeSAxel Dörfler BMenuItem* item = new BMenuItem(strCaption.String(), goTo, 728a8199d69Sthreedeyes shortcut, B_SHIFT_KEY); 729cd6b5cdeSAxel Dörfler if (currentPage == i) 730efa8b4f3SAxel Dörfler item->SetMarked(true); 731efa8b4f3SAxel Dörfler fGoToPageMenu->AddItem(item); 7326c305411SMatthew Wilber } 7336c305411SMatthew Wilber } else { 7346c305411SMatthew Wilber // Make sure the correct page is marked 735cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 736cd6b5cdeSAxel Dörfler if (currentItem != NULL && !currentItem->IsMarked()) 737cd6b5cdeSAxel Dörfler currentItem->SetMarked(true); 7386c305411SMatthew Wilber } 7396c305411SMatthew Wilber 740cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 741b9767a83SAxel Dörfler 742b9767a83SAxel Dörfler BPath path(fImageView->Image()); 743b9767a83SAxel Dörfler SetTitle(path.Path()); 7446db01936SAxel Dörfler break; 7456db01936SAxel Dörfler } 74603839579SMatthew Wilber 7476db01936SAxel Dörfler case MSG_UPDATE_STATUS_TEXT: 7486db01936SAxel Dörfler { 749cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 7506db01936SAxel Dörfler break; 7516db01936SAxel Dörfler } 7528f5fd23fSRyan Leavengood 7536db01936SAxel Dörfler case MSG_SELECTION: 7546db01936SAxel Dörfler { 7558ad30bcfSMatthew Wilber // The view sends this message when a selection is 7568ad30bcfSMatthew Wilber // made or the selection is cleared so that the window 7578ad30bcfSMatthew Wilber // can update the state of the appropriate menu items 7586db01936SAxel Dörfler bool enable; 7596db01936SAxel Dörfler if (message->FindBool("has_selection", &enable) == B_OK) { 7606db01936SAxel Dörfler _EnableMenuItem(fBar, B_COPY, enable); 7616db01936SAxel Dörfler _EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable); 7628ad30bcfSMatthew Wilber } 7636db01936SAxel Dörfler break; 7646db01936SAxel Dörfler } 7658ad30bcfSMatthew Wilber 76613afa642SPhil Greenway case B_COPY: 767d3046f7dSMichael Pfeiffer fImageView->CopySelectionToClipboard(); 76813afa642SPhil Greenway break; 7696163f333SKarsten Heimrich 7706db01936SAxel Dörfler case MSG_SELECTION_MODE: 771cf0d8308SStephan Aßmus { 772cf0d8308SStephan Aßmus bool selectionMode = _ToggleMenuItem(MSG_SELECTION_MODE); 773cf0d8308SStephan Aßmus fImageView->SetSelectionMode(selectionMode); 774cf0d8308SStephan Aßmus if (!selectionMode) 775cf0d8308SStephan Aßmus fImageView->ClearSelection(); 7766db01936SAxel Dörfler break; 777cf0d8308SStephan Aßmus } 7786db01936SAxel Dörfler 77913afa642SPhil Greenway case MSG_CLEAR_SELECT: 780d3046f7dSMichael Pfeiffer fImageView->ClearSelection(); 78113afa642SPhil Greenway break; 7826163f333SKarsten Heimrich 78313afa642SPhil Greenway case MSG_SELECT_ALL: 784d3046f7dSMichael Pfeiffer fImageView->SelectAll(); 78513afa642SPhil Greenway break; 78613afa642SPhil Greenway 78703839579SMatthew Wilber case MSG_PAGE_FIRST: 788b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.FirstPage()) 789b9767a83SAxel Dörfler _LoadImage(); 79003839579SMatthew Wilber break; 79103839579SMatthew Wilber 79203839579SMatthew Wilber case MSG_PAGE_LAST: 793b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.LastPage()) 794b9767a83SAxel Dörfler _LoadImage(); 79503839579SMatthew Wilber break; 79603839579SMatthew Wilber 79703839579SMatthew Wilber case MSG_PAGE_NEXT: 798b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextPage()) 799b9767a83SAxel Dörfler _LoadImage(); 80003839579SMatthew Wilber break; 80103839579SMatthew Wilber 80203839579SMatthew Wilber case MSG_PAGE_PREV: 803b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousPage()) 804b9767a83SAxel Dörfler _LoadImage(); 80503839579SMatthew Wilber break; 80603839579SMatthew Wilber 807cd6b5cdeSAxel Dörfler case MSG_GOTO_PAGE: 808cd6b5cdeSAxel Dörfler { 809fd952aefSRyan Leavengood if (!_ClosePrompt()) 810ee7b4f39SMatthew Wilber break; 811ee7b4f39SMatthew Wilber 8126163f333SKarsten Heimrich int32 newPage; 8136163f333SKarsten Heimrich if (message->FindInt32("page", &newPage) != B_OK) 8146163f333SKarsten Heimrich break; 8156163f333SKarsten Heimrich 816cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 817cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 8186c305411SMatthew Wilber 819b9767a83SAxel Dörfler // TODO: use radio mode instead! 8206c305411SMatthew Wilber if (newPage > 0 && newPage <= pages) { 821cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 822cd6b5cdeSAxel Dörfler BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1); 823cd6b5cdeSAxel Dörfler if (currentItem != NULL && newItem != NULL) { 824cd6b5cdeSAxel Dörfler currentItem->SetMarked(false); 825cd6b5cdeSAxel Dörfler newItem->SetMarked(true); 826b9767a83SAxel Dörfler if (fNavigator.GoToPage(newPage)) 827b9767a83SAxel Dörfler _LoadImage(); 8286c305411SMatthew Wilber } 8296c305411SMatthew Wilber } 830cd6b5cdeSAxel Dörfler break; 831cd6b5cdeSAxel Dörfler } 8326c305411SMatthew Wilber 833e2069723SAxel Dörfler case kMsgFitToWindow: 834e2069723SAxel Dörfler fImageView->FitToBounds(); 83519c76de4SMichael Pfeiffer break; 8366163f333SKarsten Heimrich 837e2069723SAxel Dörfler case kMsgStretchToWindow: 838e2069723SAxel Dörfler fImageView->SetStretchToBounds( 839e2069723SAxel Dörfler _ToggleMenuItem(kMsgStretchToWindow)); 8407eca0987SMichael Pfeiffer break; 8417eca0987SMichael Pfeiffer 8427eca0987SMichael Pfeiffer case MSG_FILE_PREV: 843b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousFile()) 844a569816bSAxel Dörfler _LoadImage(false); 8457eca0987SMichael Pfeiffer break; 8467eca0987SMichael Pfeiffer 8477eca0987SMichael Pfeiffer case MSG_FILE_NEXT: 8484aa63633SAxel Dörfler case kMsgNextSlide: 84947df2afbSRyan Leavengood if (_ClosePrompt()) { 85047df2afbSRyan Leavengood if (!fNavigator.NextFile()) { 85147df2afbSRyan Leavengood // Wrap back around 85247df2afbSRyan Leavengood fNavigator.FirstFile(); 85347df2afbSRyan Leavengood } 854b9767a83SAxel Dörfler _LoadImage(); 85547df2afbSRyan Leavengood } 85613afa642SPhil Greenway break; 85713afa642SPhil Greenway 858328932acSAxel Dörfler case kMsgDeleteCurrentFile: 859b9767a83SAxel Dörfler { 860b9767a83SAxel Dörfler if (fNavigator.MoveFileToTrash()) 861b9767a83SAxel Dörfler _LoadImage(); 862b9767a83SAxel Dörfler else 863328932acSAxel Dörfler PostMessage(B_QUIT_REQUESTED); 864328932acSAxel Dörfler break; 865b9767a83SAxel Dörfler } 866328932acSAxel Dörfler 867bf461dbeSMatthew Wilber case MSG_ROTATE_90: 868d3046f7dSMichael Pfeiffer fImageView->Rotate(90); 869ad13f387SMichael Pfeiffer break; 8706163f333SKarsten Heimrich 871bf461dbeSMatthew Wilber case MSG_ROTATE_270: 872d3046f7dSMichael Pfeiffer fImageView->Rotate(270); 873ad13f387SMichael Pfeiffer break; 8746163f333SKarsten Heimrich 87569eee339SRyan Leavengood case MSG_FLIP_LEFT_TO_RIGHT: 87661ddc257SRyan Leavengood fImageView->Flip(true); 877ad13f387SMichael Pfeiffer break; 8786163f333SKarsten Heimrich 87969eee339SRyan Leavengood case MSG_FLIP_TOP_TO_BOTTOM: 88061ddc257SRyan Leavengood fImageView->Flip(false); 881ad13f387SMichael Pfeiffer break; 8826163f333SKarsten Heimrich 883fb94ed11SAvi Brenner case MSG_GET_INFO: 884fb94ed11SAvi Brenner _GetFileInfo(fNavigator.CurrentRef()); 885fb94ed11SAvi Brenner break; 886fb94ed11SAvi Brenner 8871076d97bSAxel Dörfler case MSG_SLIDE_SHOW: 8881076d97bSAxel Dörfler { 88994fd9498SStephan Aßmus bool fullScreen = false; 89094fd9498SStephan Aßmus message->FindBool("full screen", &fullScreen); 891a877c0e7SStephan Aßmus 8926163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(message->what); 8934aa63633SAxel Dörfler if (item == NULL) 894ee7b4f39SMatthew Wilber break; 8954aa63633SAxel Dörfler 896ee7b4f39SMatthew Wilber if (item->IsMarked()) { 897ee7b4f39SMatthew Wilber item->SetMarked(false); 8984aa63633SAxel Dörfler _StopSlideShow(); 89994a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false); 900fd952aefSRyan Leavengood } else if (_ClosePrompt()) { 901ee7b4f39SMatthew Wilber item->SetMarked(true); 90294fd9498SStephan Aßmus if (!fFullScreen && fullScreen) 90394fd9498SStephan Aßmus _ToggleFullScreen(); 9044aa63633SAxel Dörfler _StartSlideShow(); 90594a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, true); 906ad13f387SMichael Pfeiffer } 9071076d97bSAxel Dörfler break; 9081076d97bSAxel Dörfler } 909ee7b4f39SMatthew Wilber 9104aa63633SAxel Dörfler case kMsgStopSlideShow: 9114aa63633SAxel Dörfler { 9124aa63633SAxel Dörfler BMenuItem* item = fBar->FindItem(MSG_SLIDE_SHOW); 9134aa63633SAxel Dörfler if (item != NULL) 9144aa63633SAxel Dörfler item->SetMarked(false); 9154aa63633SAxel Dörfler 9164aa63633SAxel Dörfler _StopSlideShow(); 91794a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false); 9184aa63633SAxel Dörfler break; 9194aa63633SAxel Dörfler } 9204aa63633SAxel Dörfler 9211076d97bSAxel Dörfler case MSG_SLIDE_SHOW_DELAY: 9221076d97bSAxel Dörfler { 9234aa63633SAxel Dörfler bigtime_t delay; 9244aa63633SAxel Dörfler if (message->FindInt64("delay", &delay) == B_OK) { 9254aa63633SAxel Dörfler _SetSlideShowDelay(delay); 926da87390fSMichael Pfeiffer // in case message is sent from popup menu 9274aa63633SAxel Dörfler _MarkSlideShowDelay(delay); 928ad13f387SMichael Pfeiffer } 9291076d97bSAxel Dörfler break; 9301076d97bSAxel Dörfler } 931ad13f387SMichael Pfeiffer 932ad13f387SMichael Pfeiffer case MSG_FULL_SCREEN: 933fd952aefSRyan Leavengood _ToggleFullScreen(); 934ad13f387SMichael Pfeiffer break; 9356163f333SKarsten Heimrich 936fc5ca95dSStephan Aßmus case MSG_EXIT_FULL_SCREEN: 937fc5ca95dSStephan Aßmus if (fFullScreen) 938fd952aefSRyan Leavengood _ToggleFullScreen(); 939fc5ca95dSStephan Aßmus break; 9406163f333SKarsten Heimrich 941cf0d8308SStephan Aßmus case MSG_SHOW_CAPTION: 942cf0d8308SStephan Aßmus { 943fd952aefSRyan Leavengood fShowCaption = _ToggleMenuItem(message->what); 944efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 945efa8b4f3SAxel Dörfler 946d3046f7dSMichael Pfeiffer if (settings->Lock()) { 947d3046f7dSMichael Pfeiffer settings->SetBool("ShowCaption", fShowCaption); 948d3046f7dSMichael Pfeiffer settings->Unlock(); 949d3046f7dSMichael Pfeiffer } 950efa8b4f3SAxel Dörfler if (fFullScreen) 951d3046f7dSMichael Pfeiffer fImageView->SetShowCaption(fShowCaption); 9526163f333SKarsten Heimrich } break; 953ad13f387SMichael Pfeiffer 954780d8a62SMichael Pfeiffer case MSG_PAGE_SETUP: 955fd952aefSRyan Leavengood _PageSetup(); 956780d8a62SMichael Pfeiffer break; 9576163f333SKarsten Heimrich 958780d8a62SMichael Pfeiffer case MSG_PREPARE_PRINT: 959fd952aefSRyan Leavengood _PrepareForPrint(); 960780d8a62SMichael Pfeiffer break; 9616163f333SKarsten Heimrich 962780d8a62SMichael Pfeiffer case MSG_PRINT: 963fd952aefSRyan Leavengood _Print(message); 964780d8a62SMichael Pfeiffer break; 965780d8a62SMichael Pfeiffer 966780d8a62SMichael Pfeiffer case MSG_ZOOM_IN: 967d3046f7dSMichael Pfeiffer fImageView->ZoomIn(); 968780d8a62SMichael Pfeiffer break; 9696163f333SKarsten Heimrich 970780d8a62SMichael Pfeiffer case MSG_ZOOM_OUT: 971d3046f7dSMichael Pfeiffer fImageView->ZoomOut(); 972780d8a62SMichael Pfeiffer break; 9736163f333SKarsten Heimrich 974cae52eadSJanus case MSG_UPDATE_STATUS_ZOOM: 975cae52eadSJanus fStatusView->SetZoom(fImageView->Zoom()); 976cae52eadSJanus break; 977cae52eadSJanus 978e2069723SAxel Dörfler case kMsgOriginalSize: 9798073fcbbSAdrien Destugues if (message->FindInt32("behavior") == BButton::B_TOGGLE_BEHAVIOR) { 9808073fcbbSAdrien Destugues bool force = (message->FindInt32("be:value") == B_CONTROL_ON); 981554e2073SAdrien Destugues fImageView->ForceOriginalSize(force); 982554e2073SAdrien Destugues if (!force) 983554e2073SAdrien Destugues break; 984554e2073SAdrien Destugues } 9854fd570d3SAxel Dörfler fImageView->SetZoom(1.0); 986780d8a62SMichael Pfeiffer break; 9876163f333SKarsten Heimrich 98881b9c776SMichael Pfeiffer case MSG_SCALE_BILINEAR: 989fd952aefSRyan Leavengood fImageView->SetScaleBilinear(_ToggleMenuItem(message->what)); 99081b9c776SMichael Pfeiffer break; 991780d8a62SMichael Pfeiffer 992cd6b5cdeSAxel Dörfler case MSG_DESKTOP_BACKGROUND: 993cd6b5cdeSAxel Dörfler { 9949617074cSRyan Leavengood BMessage backgroundsMessage(B_REFS_RECEIVED); 9959617074cSRyan Leavengood backgroundsMessage.AddRef("refs", fImageView->Image()); 9960a74004cSRyan Leavengood // This is used in the Backgrounds code for scaled placement 9979617074cSRyan Leavengood backgroundsMessage.AddInt32("placement", 'scpl'); 998537a273cSHumdinger be_roster->Launch("application/x-vnd.haiku-backgrounds", 999537a273cSHumdinger &backgroundsMessage); 1000cd6b5cdeSAxel Dörfler break; 1001cd6b5cdeSAxel Dörfler } 1002a60adbf9SAxel Dörfler 10035b76e505SStephan Aßmus case MSG_SET_RATING: 10045b76e505SStephan Aßmus { 10055b76e505SStephan Aßmus int32 rating; 10065b76e505SStephan Aßmus if (message->FindInt32("rating", &rating) != B_OK) 10075b76e505SStephan Aßmus break; 10085b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_WRITE_ONLY); 10095b76e505SStephan Aßmus if (file.InitCheck() != B_OK) 10105b76e505SStephan Aßmus break; 10115b76e505SStephan Aßmus file.WriteAttr("Media:Rating", B_INT32_TYPE, 0, &rating, 10125b76e505SStephan Aßmus sizeof(rating)); 10135b76e505SStephan Aßmus _UpdateRatingMenu(); 10145b76e505SStephan Aßmus break; 10155b76e505SStephan Aßmus } 10165b76e505SStephan Aßmus 1017cf0d8308SStephan Aßmus case kMsgToggleToolBar: 1018cf0d8308SStephan Aßmus { 1019cf0d8308SStephan Aßmus fShowToolBar = _ToggleMenuItem(message->what); 102094fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar, true); 1021cf0d8308SStephan Aßmus 1022cf0d8308SStephan Aßmus ShowImageSettings* settings = my_app->Settings(); 1023cf0d8308SStephan Aßmus 1024cf0d8308SStephan Aßmus if (settings->Lock()) { 1025cf0d8308SStephan Aßmus settings->SetBool("ShowToolBar", fShowToolBar); 1026cf0d8308SStephan Aßmus settings->Unlock(); 1027cf0d8308SStephan Aßmus } 1028cf0d8308SStephan Aßmus break; 1029cf0d8308SStephan Aßmus } 103094fd9498SStephan Aßmus case kShowToolBarIfEnabled: 103194fd9498SStephan Aßmus { 103294fd9498SStephan Aßmus bool show; 103394fd9498SStephan Aßmus if (message->FindBool("show", &show) != B_OK) 103494fd9498SStephan Aßmus break; 103594fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar && show, true); 103694fd9498SStephan Aßmus break; 103794fd9498SStephan Aßmus } 103894fd9498SStephan Aßmus case kMsgSlideToolBar: 103994fd9498SStephan Aßmus { 104094fd9498SStephan Aßmus float offset; 104194fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK) { 104294a4c1c4SAugustin Cavalier fToolBar->MoveBy(0, offset); 104394fd9498SStephan Aßmus fScrollView->ResizeBy(0, -offset); 104494fd9498SStephan Aßmus fScrollView->MoveBy(0, offset); 104594fd9498SStephan Aßmus UpdateIfNeeded(); 104694fd9498SStephan Aßmus snooze(15000); 104794fd9498SStephan Aßmus } 104894fd9498SStephan Aßmus break; 104994fd9498SStephan Aßmus } 105094fd9498SStephan Aßmus case kMsgFinishSlidingToolBar: 105194fd9498SStephan Aßmus { 105294fd9498SStephan Aßmus float offset; 105394fd9498SStephan Aßmus bool show; 105494fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK 105594fd9498SStephan Aßmus && message->FindBool("show", &show) == B_OK) { 105694fd9498SStephan Aßmus // Compensate rounding errors with the final placement 105794a4c1c4SAugustin Cavalier fToolBar->MoveTo(fToolBar->Frame().left, offset); 105895667008SJanus if (!show) 105994a4c1c4SAugustin Cavalier fToolBar->Hide(); 106094a4c1c4SAugustin Cavalier BRect frame = fToolBar->Parent()->Bounds(); 106194a4c1c4SAugustin Cavalier frame.top = fToolBar->Frame().bottom + 1; 10622804cb33SRyan Leavengood fScrollView->MoveTo(fScrollView->Frame().left, frame.top); 106394fd9498SStephan Aßmus fScrollView->ResizeTo(fScrollView->Bounds().Width(), 1064cae52eadSJanus frame.Height() + 1); 106594fd9498SStephan Aßmus } 106694fd9498SStephan Aßmus break; 106794fd9498SStephan Aßmus } 1068cf0d8308SStephan Aßmus 106913afa642SPhil Greenway default: 1070efa8b4f3SAxel Dörfler BWindow::MessageReceived(message); 107113afa642SPhil Greenway break; 107213afa642SPhil Greenway } 107313afa642SPhil Greenway } 1074fc0a275bSMatthew Wilber 1075efa8b4f3SAxel Dörfler 1076fc0a275bSMatthew Wilber void 1077fb94ed11SAvi Brenner ShowImageWindow::_GetFileInfo(const entry_ref& ref) 1078fb94ed11SAvi Brenner { 1079fb94ed11SAvi Brenner BMessage message('Tinf'); 1080fb94ed11SAvi Brenner BMessenger tracker("application/x-vnd.Be-TRAK"); 1081fb94ed11SAvi Brenner message.AddRef("refs", &ref); 1082fb94ed11SAvi Brenner tracker.SendMessage(&message); 1083fb94ed11SAvi Brenner } 1084fb94ed11SAvi Brenner 1085fb94ed11SAvi Brenner 1086fb94ed11SAvi Brenner void 1087cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message) 1088cd6b5cdeSAxel Dörfler { 1089baa27ccbSJanus BString frameText; 1090cd6b5cdeSAxel Dörfler if (fImageView->Bitmap() != NULL) { 1091cd6b5cdeSAxel Dörfler BRect bounds = fImageView->Bitmap()->Bounds(); 1092baa27ccbSJanus frameText << bounds.IntegerWidth() + 1 1093cae52eadSJanus << "x" << bounds.IntegerHeight() + 1; 1094cd6b5cdeSAxel Dörfler } 1095baa27ccbSJanus BString pages; 1096baa27ccbSJanus if (fNavigator.PageCount() > 1) 1097baa27ccbSJanus pages << fNavigator.CurrentPage() << "/" << fNavigator.PageCount(); 1098baa27ccbSJanus fStatusView->Update(fNavigator.CurrentRef(), frameText, pages, fImageType, 1099cae52eadSJanus fImageView->Zoom()); 1100cd6b5cdeSAxel Dörfler } 1101cd6b5cdeSAxel Dörfler 1102cd6b5cdeSAxel Dörfler 1103cd6b5cdeSAxel Dörfler void 1104cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref) 1105cd6b5cdeSAxel Dörfler { 1106cd6b5cdeSAxel Dörfler // TODO: give a better error message! 1107560ff447SJonas Sundström BAlert* alert = new BAlert(B_TRANSLATE_SYSTEM_NAME("ShowImage"), 1108546208a5SOliver Tappe B_TRANSLATE_CONTEXT("Could not load image! Either the " 1109ddcb5a2cSAxel Dörfler "file or an image translator for it does not exist.", 1110ddcb5a2cSAxel Dörfler "LoadAlerts"), 1111546208a5SOliver Tappe B_TRANSLATE_CONTEXT("OK", "Alerts"), NULL, NULL, 11125df9097aSJohn Scipione B_WIDTH_AS_USUAL, B_STOP_ALERT); 1113aed35104SHumdinger alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 1114cd6b5cdeSAxel Dörfler alert->Go(); 1115cd6b5cdeSAxel Dörfler } 1116cd6b5cdeSAxel Dörfler 1117cd6b5cdeSAxel Dörfler 1118cd6b5cdeSAxel Dörfler void 1119fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message) 1120fc0a275bSMatthew Wilber { 1121cdb89ebbSMatthew Wilber // Read the translator and output type the user chose 1122cdb89ebbSMatthew Wilber translator_id outTranslator; 1123cdb89ebbSMatthew Wilber uint32 outType; 11246163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 1125efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 11266163f333SKarsten Heimrich || message->FindInt32(kTypeField, 1127cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 1128fc0a275bSMatthew Wilber return; 1129fc0a275bSMatthew Wilber 1130cdb89ebbSMatthew Wilber // Add the chosen translator and output type to the 1131cdb89ebbSMatthew Wilber // message that the save panel will send back 1132c1a10c14SKarsten Heimrich BMessage panelMsg(MSG_SAVE_PANEL); 1133c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTranslatorField, outTranslator); 1134c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTypeField, outType); 1135cdb89ebbSMatthew Wilber 1136cdb89ebbSMatthew Wilber // Create save panel and show it 11376163f333SKarsten Heimrich BMessenger target(this); 1138efa8b4f3SAxel Dörfler fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL, 1139c1a10c14SKarsten Heimrich &target, NULL, 0, false, &panelMsg); 1140d3046f7dSMichael Pfeiffer if (!fSavePanel) 1141fc0a275bSMatthew Wilber return; 1142a60adbf9SAxel Dörfler 11433000afd7SJanus // Retrieve save directory from settings; 11443000afd7SJanus ShowImageSettings* settings = my_app->Settings(); 11453000afd7SJanus if (settings->Lock()) { 11463000afd7SJanus fSavePanel->SetPanelDirectory( 11473000afd7SJanus settings->GetString("SaveDirectory", NULL)); 11483000afd7SJanus settings->Unlock(); 11493000afd7SJanus } 11503000afd7SJanus 1151d3046f7dSMichael Pfeiffer fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE); 1152d3046f7dSMichael Pfeiffer fSavePanel->Show(); 1153fc0a275bSMatthew Wilber } 1154fc0a275bSMatthew Wilber 1155efa8b4f3SAxel Dörfler 1156fc0a275bSMatthew Wilber void 1157fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message) 1158fc0a275bSMatthew Wilber { 1159cdb89ebbSMatthew Wilber // Read in where the file should be saved 1160efa8b4f3SAxel Dörfler entry_ref dirRef; 1161efa8b4f3SAxel Dörfler if (message->FindRef("directory", &dirRef) != B_OK) 1162fc0a275bSMatthew Wilber return; 1163efa8b4f3SAxel Dörfler 1164fc0a275bSMatthew Wilber const char* filename; 1165efa8b4f3SAxel Dörfler if (message->FindString("name", &filename) != B_OK) 1166fc0a275bSMatthew Wilber return; 1167fc0a275bSMatthew Wilber 1168cdb89ebbSMatthew Wilber // Read in the translator and type to be used 1169cdb89ebbSMatthew Wilber // to save the output image 1170cdb89ebbSMatthew Wilber translator_id outTranslator; 1171cdb89ebbSMatthew Wilber uint32 outType; 11726163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 1173efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 11746163f333SKarsten Heimrich || message->FindInt32(kTypeField, 1175cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 1176cdb89ebbSMatthew Wilber return; 1177cdb89ebbSMatthew Wilber 1178a7e78e3bSMatthew Wilber // Find the translator_format information needed to 1179a7e78e3bSMatthew Wilber // write a MIME attribute for the image file 1180a7e78e3bSMatthew Wilber BTranslatorRoster* roster = BTranslatorRoster::Default(); 1181efa8b4f3SAxel Dörfler const translation_format* outFormat = NULL; 1182efa8b4f3SAxel Dörfler int32 outCount = 0; 1183efa8b4f3SAxel Dörfler if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK 1184efa8b4f3SAxel Dörfler || outCount < 1) 1185a7e78e3bSMatthew Wilber return; 1186efa8b4f3SAxel Dörfler 1187a7e78e3bSMatthew Wilber int32 i; 1188efa8b4f3SAxel Dörfler for (i = 0; i < outCount; i++) { 1189537a273cSHumdinger if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type 1190537a273cSHumdinger == outType) 1191a7e78e3bSMatthew Wilber break; 1192a7e78e3bSMatthew Wilber } 1193efa8b4f3SAxel Dörfler if (i == outCount) 1194fc0a275bSMatthew Wilber return; 1195fc0a275bSMatthew Wilber 1196a7e78e3bSMatthew Wilber // Write out the image file 1197efa8b4f3SAxel Dörfler BDirectory dir(&dirRef); 1198efa8b4f3SAxel Dörfler fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]); 11993000afd7SJanus 12003000afd7SJanus // Store Save directory in settings; 12013000afd7SJanus ShowImageSettings* settings = my_app->Settings(); 12023000afd7SJanus if (settings->Lock()) { 12033000afd7SJanus BPath path(&dirRef); 12043000afd7SJanus settings->SetString("SaveDirectory", path.Path()); 12053000afd7SJanus settings->Unlock(); 12063000afd7SJanus } 1207fc0a275bSMatthew Wilber } 1208fc0a275bSMatthew Wilber 1209efa8b4f3SAxel Dörfler 1210546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 1211546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "ClosePrompt" 12121ed4535fSStephan Aßmus 1213b9767a83SAxel Dörfler 1214cdb89ebbSMatthew Wilber bool 1215fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt() 1216ee7b4f39SMatthew Wilber { 1217ee7b4f39SMatthew Wilber if (!fModified) 1218ee7b4f39SMatthew Wilber return true; 1219efa8b4f3SAxel Dörfler 1220cd6b5cdeSAxel Dörfler int32 count = fNavigator.PageCount(); 1221cd6b5cdeSAxel Dörfler int32 page = fNavigator.CurrentPage(); 1222cd6b5cdeSAxel Dörfler BString prompt; 1223efa8b4f3SAxel Dörfler 12241ed4535fSStephan Aßmus if (count > 1) { 12251ed4535fSStephan Aßmus bs_printf(&prompt, 1226905c8c8cSMatt Madia B_TRANSLATE("The document '%s' (page %d) has been changed. Do you " 1227905c8c8cSMatt Madia "want to close the document?"), 1228cd6b5cdeSAxel Dörfler fImageView->Image()->name, page); 12291ed4535fSStephan Aßmus } else { 12301ed4535fSStephan Aßmus bs_printf(&prompt, 1231905c8c8cSMatt Madia B_TRANSLATE("The document '%s' has been changed. Do you want to " 1232905c8c8cSMatt Madia "close the document?"), 1233cd6b5cdeSAxel Dörfler fImageView->Image()->name); 12341ed4535fSStephan Aßmus } 12351ed4535fSStephan Aßmus 1236cd6b5cdeSAxel Dörfler BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(), 1237905c8c8cSMatt Madia B_TRANSLATE("Cancel"), B_TRANSLATE("Close")); 1238aed35104SHumdinger alert->SetShortcut(0, B_ESCAPE); 1239aed35104SHumdinger 1240cd6b5cdeSAxel Dörfler if (alert->Go() == 0) { 1241ee7b4f39SMatthew Wilber // Cancel 1242ee7b4f39SMatthew Wilber return false; 1243cd6b5cdeSAxel Dörfler } 1244cd6b5cdeSAxel Dörfler 1245ee7b4f39SMatthew Wilber // Close 1246187f0b8aSMatthew Wilber fModified = false; 1247ee7b4f39SMatthew Wilber return true; 1248ee7b4f39SMatthew Wilber } 1249ee7b4f39SMatthew Wilber 1250cdb89ebbSMatthew Wilber 1251b9767a83SAxel Dörfler status_t 1252a569816bSAxel Dörfler ShowImageWindow::_LoadImage(bool forward) 1253b9767a83SAxel Dörfler { 1254*a4462d20SHumdinger // If the user triggered a _LoadImage while in a slide show, 1255*a4462d20SHumdinger // make sure the new image is shown for the set delay: 1256*a4462d20SHumdinger _ResetSlideShowDelay(); 1257*a4462d20SHumdinger 1258b9767a83SAxel Dörfler BMessenger us(this); 1259be63ec85SJanus status_t status = my_app->DefaultCache().RetrieveImage( 1260a569816bSAxel Dörfler fNavigator.CurrentRef(), fNavigator.CurrentPage(), &us); 1261a569816bSAxel Dörfler if (status != B_OK) 1262a569816bSAxel Dörfler return status; 1263a569816bSAxel Dörfler 1264e2069723SAxel Dörfler fProgressWindow->Start(this); 1265e2069723SAxel Dörfler 1266a569816bSAxel Dörfler // Preload previous/next images - two in the navigation direction, one 1267a569816bSAxel Dörfler // in the opposite direction. 1268a569816bSAxel Dörfler 1269a569816bSAxel Dörfler entry_ref nextRef = fNavigator.CurrentRef(); 1270a569816bSAxel Dörfler if (_PreloadImage(forward, nextRef)) 1271a569816bSAxel Dörfler _PreloadImage(forward, nextRef); 1272a569816bSAxel Dörfler 1273a569816bSAxel Dörfler entry_ref previousRef = fNavigator.CurrentRef(); 1274a569816bSAxel Dörfler _PreloadImage(!forward, previousRef); 1275a569816bSAxel Dörfler 1276a569816bSAxel Dörfler return B_OK; 1277a569816bSAxel Dörfler } 1278a569816bSAxel Dörfler 1279a569816bSAxel Dörfler 1280a569816bSAxel Dörfler bool 1281a569816bSAxel Dörfler ShowImageWindow::_PreloadImage(bool forward, entry_ref& ref) 1282a569816bSAxel Dörfler { 1283a569816bSAxel Dörfler entry_ref currentRef = ref; 1284a569816bSAxel Dörfler if ((forward && !fNavigator.GetNextFile(currentRef, ref)) 1285a569816bSAxel Dörfler || (!forward && !fNavigator.GetPreviousFile(currentRef, ref))) 1286a569816bSAxel Dörfler return false; 1287a569816bSAxel Dörfler 1288be63ec85SJanus return my_app->DefaultCache().RetrieveImage(ref) == B_OK; 1289b9767a83SAxel Dörfler } 1290b9767a83SAxel Dörfler 1291b9767a83SAxel Dörfler 1292ad13f387SMichael Pfeiffer void 1293fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen() 1294ad13f387SMichael Pfeiffer { 1295ad13f387SMichael Pfeiffer BRect frame; 1296ad13f387SMichael Pfeiffer fFullScreen = !fFullScreen; 1297ad13f387SMichael Pfeiffer if (fFullScreen) { 1298ad13f387SMichael Pfeiffer BScreen screen; 1299ad13f387SMichael Pfeiffer fWindowFrame = Frame(); 1300ad13f387SMichael Pfeiffer frame = screen.Frame(); 1301d3046f7dSMichael Pfeiffer frame.top -= fBar->Bounds().Height() + 1; 130267eb2a04SHumdinger frame.right += B_V_SCROLL_BAR_WIDTH; 1303ad13f387SMichael Pfeiffer frame.bottom += B_H_SCROLL_BAR_HEIGHT; 1304ad13f387SMichael Pfeiffer 1305ad13f387SMichael Pfeiffer SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE); 1306c0b16687SAxel Dörfler 1307c0b16687SAxel Dörfler Activate(); 1308c0b16687SAxel Dörfler // make the window frontmost 1309ad13f387SMichael Pfeiffer } else { 1310ad13f387SMichael Pfeiffer frame = fWindowFrame; 1311ad13f387SMichael Pfeiffer 1312ad13f387SMichael Pfeiffer SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); 1313ad13f387SMichael Pfeiffer } 1314efa8b4f3SAxel Dörfler 131594a4c1c4SAugustin Cavalier fToolBar->SetActionVisible(MSG_FULL_SCREEN, fFullScreen); 1316cf0d8308SStephan Aßmus _SetToolBarVisible(!fFullScreen && fShowToolBar); 131760c23976SJanus _SetToolBarBorder(!fFullScreen); 1318cf0d8308SStephan Aßmus 1319ad13f387SMichael Pfeiffer MoveTo(frame.left, frame.top); 1320ad13f387SMichael Pfeiffer ResizeTo(frame.Width(), frame.Height()); 1321e2069723SAxel Dörfler 1322e2069723SAxel Dörfler fImageView->SetHideIdlingCursor(fFullScreen); 1323e2069723SAxel Dörfler fImageView->SetShowCaption(fFullScreen && fShowCaption); 1324eaa910c5SAxel Dörfler 132548ae3e38SAxel Dörfler Layout(false); 132648ae3e38SAxel Dörfler // We need to manually relayout here, as the views are layouted 132748ae3e38SAxel Dörfler // asynchronously, and FitToBounds() would still have the wrong size 1328e2069723SAxel Dörfler fImageView->FitToBounds(); 1329ad13f387SMichael Pfeiffer } 1330ad13f387SMichael Pfeiffer 1331efa8b4f3SAxel Dörfler 1332d3046f7dSMichael Pfeiffer void 13332281340dSAxel Dörfler ShowImageWindow::_ApplySettings() 1334d3046f7dSMichael Pfeiffer { 1335efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1336efa8b4f3SAxel Dörfler 1337d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1338d3046f7dSMichael Pfeiffer fShowCaption = settings->GetBool("ShowCaption", fShowCaption); 1339d3046f7dSMichael Pfeiffer fPrintOptions.SetBounds(BRect(0, 0, 1023, 767)); 1340d3046f7dSMichael Pfeiffer 13414aa63633SAxel Dörfler fSlideShowDelay = settings->GetTime("SlideShowDelay", fSlideShowDelay); 1342d3046f7dSMichael Pfeiffer 13434aa63633SAxel Dörfler fPrintOptions.SetOption((enum PrintOptions::Option)settings->GetInt32( 13444aa63633SAxel Dörfler "PO:Option", fPrintOptions.Option())); 13454aa63633SAxel Dörfler fPrintOptions.SetZoomFactor( 13464aa63633SAxel Dörfler settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor())); 13474aa63633SAxel Dörfler fPrintOptions.SetDPI(settings->GetFloat("PO:DPI", fPrintOptions.DPI())); 13484aa63633SAxel Dörfler fPrintOptions.SetWidth( 13494aa63633SAxel Dörfler settings->GetFloat("PO:Width", fPrintOptions.Width())); 13504aa63633SAxel Dörfler fPrintOptions.SetHeight( 13514aa63633SAxel Dörfler settings->GetFloat("PO:Height", fPrintOptions.Height())); 1352d3046f7dSMichael Pfeiffer 1353cf0d8308SStephan Aßmus fShowToolBar = settings->GetBool("ShowToolBar", fShowToolBar); 1354cf0d8308SStephan Aßmus 1355d3046f7dSMichael Pfeiffer settings->Unlock(); 1356d3046f7dSMichael Pfeiffer } 1357d3046f7dSMichael Pfeiffer } 1358d3046f7dSMichael Pfeiffer 1359efa8b4f3SAxel Dörfler 1360d3046f7dSMichael Pfeiffer void 1361fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions() 1362d3046f7dSMichael Pfeiffer { 1363efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1364efa8b4f3SAxel Dörfler 1365d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1366d3046f7dSMichael Pfeiffer settings->SetInt32("PO:Option", fPrintOptions.Option()); 1367d3046f7dSMichael Pfeiffer settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor()); 1368d3046f7dSMichael Pfeiffer settings->SetFloat("PO:DPI", fPrintOptions.DPI()); 1369d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Width", fPrintOptions.Width()); 1370d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Height", fPrintOptions.Height()); 1371d3046f7dSMichael Pfeiffer settings->Unlock(); 1372d3046f7dSMichael Pfeiffer } 1373d3046f7dSMichael Pfeiffer } 1374d3046f7dSMichael Pfeiffer 1375efa8b4f3SAxel Dörfler 1376cdb89ebbSMatthew Wilber bool 1377fd952aefSRyan Leavengood ShowImageWindow::_PageSetup() 1378780d8a62SMichael Pfeiffer { 1379cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 1380efa8b4f3SAxel Dörfler if (fPrintSettings != NULL) 1381780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 1382efa8b4f3SAxel Dörfler 13836163f333SKarsten Heimrich status_t status = printJob.ConfigPage(); 13846163f333SKarsten Heimrich if (status == B_OK) { 1385780d8a62SMichael Pfeiffer delete fPrintSettings; 1386780d8a62SMichael Pfeiffer fPrintSettings = printJob.Settings(); 1387780d8a62SMichael Pfeiffer } 1388efa8b4f3SAxel Dörfler 13896163f333SKarsten Heimrich return status == B_OK; 1390780d8a62SMichael Pfeiffer } 1391780d8a62SMichael Pfeiffer 1392efa8b4f3SAxel Dörfler 1393780d8a62SMichael Pfeiffer void 1394fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint() 1395780d8a62SMichael Pfeiffer { 13966163f333SKarsten Heimrich if (fPrintSettings == NULL) { 1397cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 13986163f333SKarsten Heimrich if (printJob.ConfigJob() == B_OK) 13996163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 14006163f333SKarsten Heimrich } 1401780d8a62SMichael Pfeiffer 1402cd6b5cdeSAxel Dörfler fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds()); 1403cd6b5cdeSAxel Dörfler fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1); 1404780d8a62SMichael Pfeiffer 1405efa8b4f3SAxel Dörfler new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50), 1406efa8b4f3SAxel Dörfler &fPrintOptions, this); 1407780d8a62SMichael Pfeiffer } 1408780d8a62SMichael Pfeiffer 1409efa8b4f3SAxel Dörfler 1410780d8a62SMichael Pfeiffer void 1411fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg) 1412780d8a62SMichael Pfeiffer { 1413780d8a62SMichael Pfeiffer status_t st; 1414efa8b4f3SAxel Dörfler if (msg->FindInt32("status", &st) != B_OK || st != B_OK) 1415780d8a62SMichael Pfeiffer return; 1416780d8a62SMichael Pfeiffer 1417fd952aefSRyan Leavengood _SavePrintOptions(); 1418d3046f7dSMichael Pfeiffer 1419cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 14206163f333SKarsten Heimrich if (fPrintSettings) 1421780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 14226163f333SKarsten Heimrich 1423780d8a62SMichael Pfeiffer if (printJob.ConfigJob() == B_OK) { 14246163f333SKarsten Heimrich delete fPrintSettings; 14256163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 1426780d8a62SMichael Pfeiffer 1427780d8a62SMichael Pfeiffer // first/lastPage is unused for now 14283177ae77SStefano Ceccherini int32 firstPage = printJob.FirstPage(); 14293177ae77SStefano Ceccherini int32 lastPage = printJob.LastPage(); 14306163f333SKarsten Heimrich BRect printableRect = printJob.PrintableRect(); 14316163f333SKarsten Heimrich 1432efa8b4f3SAxel Dörfler if (firstPage < 1) 1433780d8a62SMichael Pfeiffer firstPage = 1; 1434efa8b4f3SAxel Dörfler if (lastPage < firstPage) 1435780d8a62SMichael Pfeiffer lastPage = firstPage; 1436780d8a62SMichael Pfeiffer 1437cd6b5cdeSAxel Dörfler BBitmap* bitmap = fImageView->Bitmap(); 14383177ae77SStefano Ceccherini float imageWidth = bitmap->Bounds().Width() + 1.0; 14393177ae77SStefano Ceccherini float imageHeight = bitmap->Bounds().Height() + 1.0; 1440780d8a62SMichael Pfeiffer 14416163f333SKarsten Heimrich float width; 1442780d8a62SMichael Pfeiffer switch (fPrintOptions.Option()) { 14436163f333SKarsten Heimrich case PrintOptions::kFitToPage: { 14446163f333SKarsten Heimrich float w1 = printableRect.Width() + 1; 1445cd6b5cdeSAxel Dörfler float w2 = imageWidth * (printableRect.Height() + 1) 1446cd6b5cdeSAxel Dörfler / imageHeight; 1447efa8b4f3SAxel Dörfler if (w2 < w1) 1448780d8a62SMichael Pfeiffer width = w2; 1449efa8b4f3SAxel Dörfler else 1450780d8a62SMichael Pfeiffer width = w1; 14516163f333SKarsten Heimrich } break; 1452780d8a62SMichael Pfeiffer case PrintOptions::kZoomFactor: 1453780d8a62SMichael Pfeiffer width = imageWidth * fPrintOptions.ZoomFactor(); 1454780d8a62SMichael Pfeiffer break; 1455780d8a62SMichael Pfeiffer case PrintOptions::kDPI: 1456780d8a62SMichael Pfeiffer width = imageWidth * 72.0 / fPrintOptions.DPI(); 1457780d8a62SMichael Pfeiffer break; 1458780d8a62SMichael Pfeiffer case PrintOptions::kWidth: 1459780d8a62SMichael Pfeiffer case PrintOptions::kHeight: 1460780d8a62SMichael Pfeiffer width = fPrintOptions.Width(); 1461780d8a62SMichael Pfeiffer break; 1462efa8b4f3SAxel Dörfler 1463780d8a62SMichael Pfeiffer default: 1464780d8a62SMichael Pfeiffer // keep compiler silent; should not reach here 1465780d8a62SMichael Pfeiffer width = imageWidth; 1466780d8a62SMichael Pfeiffer } 1467780d8a62SMichael Pfeiffer 1468efa8b4f3SAxel Dörfler // TODO: eventually print large images on several pages 1469780d8a62SMichael Pfeiffer printJob.BeginJob(); 1470d3046f7dSMichael Pfeiffer fImageView->SetScale(width / imageWidth); 14715eb50e46SMichael Pfeiffer // coordinates are relative to printable rectangle 14725eb50e46SMichael Pfeiffer BRect bounds(bitmap->Bounds()); 14735eb50e46SMichael Pfeiffer printJob.DrawView(fImageView, bounds, BPoint(0, 0)); 1474d3046f7dSMichael Pfeiffer fImageView->SetScale(1.0); 1475780d8a62SMichael Pfeiffer printJob.SpoolPage(); 1476780d8a62SMichael Pfeiffer printJob.CommitJob(); 1477780d8a62SMichael Pfeiffer } 1478780d8a62SMichael Pfeiffer } 1479780d8a62SMichael Pfeiffer 148056b0c7b9SKarsten Heimrich 14814aa63633SAxel Dörfler void 14824aa63633SAxel Dörfler ShowImageWindow::_SetSlideShowDelay(bigtime_t delay) 14834aa63633SAxel Dörfler { 14844aa63633SAxel Dörfler if (fSlideShowDelay == delay) 14854aa63633SAxel Dörfler return; 14864aa63633SAxel Dörfler 14874aa63633SAxel Dörfler fSlideShowDelay = delay; 14884aa63633SAxel Dörfler 14894aa63633SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 14904aa63633SAxel Dörfler if (settings->Lock()) { 14914aa63633SAxel Dörfler settings->SetTime("SlideShowDelay", fSlideShowDelay); 14924aa63633SAxel Dörfler settings->Unlock(); 14934aa63633SAxel Dörfler } 14944aa63633SAxel Dörfler 14954aa63633SAxel Dörfler if (fSlideShowRunner != NULL) 14964aa63633SAxel Dörfler _StartSlideShow(); 14974aa63633SAxel Dörfler } 14984aa63633SAxel Dörfler 14994aa63633SAxel Dörfler 15004aa63633SAxel Dörfler void 15014aa63633SAxel Dörfler ShowImageWindow::_StartSlideShow() 15024aa63633SAxel Dörfler { 15034aa63633SAxel Dörfler _StopSlideShow(); 15044aa63633SAxel Dörfler 15054aa63633SAxel Dörfler BMessage nextSlide(kMsgNextSlide); 15064aa63633SAxel Dörfler fSlideShowRunner = new BMessageRunner(this, &nextSlide, fSlideShowDelay); 15074aa63633SAxel Dörfler } 15084aa63633SAxel Dörfler 15094aa63633SAxel Dörfler 15104aa63633SAxel Dörfler void 15114aa63633SAxel Dörfler ShowImageWindow::_StopSlideShow() 15124aa63633SAxel Dörfler { 15134aa63633SAxel Dörfler if (fSlideShowRunner != NULL) { 15144aa63633SAxel Dörfler delete fSlideShowRunner; 15154aa63633SAxel Dörfler fSlideShowRunner = NULL; 15164aa63633SAxel Dörfler } 15174aa63633SAxel Dörfler } 15184aa63633SAxel Dörfler 15194aa63633SAxel Dörfler 15205b76e505SStephan Aßmus void 1521*a4462d20SHumdinger ShowImageWindow::_ResetSlideShowDelay() 1522*a4462d20SHumdinger { 1523*a4462d20SHumdinger if (fSlideShowRunner != NULL) 1524*a4462d20SHumdinger fSlideShowRunner->SetInterval(fSlideShowDelay); 1525*a4462d20SHumdinger } 1526*a4462d20SHumdinger 1527*a4462d20SHumdinger 1528*a4462d20SHumdinger void 15295b76e505SStephan Aßmus ShowImageWindow::_UpdateRatingMenu() 15305b76e505SStephan Aßmus { 15315b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_READ_ONLY); 15325b76e505SStephan Aßmus if (file.InitCheck() != B_OK) 15335b76e505SStephan Aßmus return; 15345b76e505SStephan Aßmus int32 rating; 15355b76e505SStephan Aßmus ssize_t size = sizeof(rating); 15365b76e505SStephan Aßmus if (file.ReadAttr("Media:Rating", B_INT32_TYPE, 0, &rating, size) != size) 15375b76e505SStephan Aßmus rating = 0; 15385b76e505SStephan Aßmus // TODO: Finding the correct item could be more robust, like by looking 15395b76e505SStephan Aßmus // at the message of each item. 15405b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) { 15415b76e505SStephan Aßmus BMenuItem* item = fRatingMenu->ItemAt(i - 1); 15425b76e505SStephan Aßmus if (item == NULL) 15435b76e505SStephan Aßmus break; 15445b76e505SStephan Aßmus item->SetMarked(i == rating); 15455b76e505SStephan Aßmus } 15465b76e505SStephan Aßmus } 15475b76e505SStephan Aßmus 15485b76e505SStephan Aßmus 1549cf0d8308SStephan Aßmus void 1550e62a6973SJanus ShowImageWindow::_SaveWidthAndHeight() 1551e62a6973SJanus { 1552e62a6973SJanus if (fNavigator.CurrentPage() != 1) 1553e62a6973SJanus return; 1554e62a6973SJanus 1555e62a6973SJanus if (fImageView->Bitmap() == NULL) 1556e62a6973SJanus return; 1557e62a6973SJanus 1558e62a6973SJanus BRect bounds = fImageView->Bitmap()->Bounds(); 1559c1994be8SJanus int32 width = bounds.IntegerWidth() + 1; 1560c1994be8SJanus int32 height = bounds.IntegerHeight() + 1; 1561e62a6973SJanus 15629c1f5f4dSJanus BNode node(&fNavigator.CurrentRef()); 15639c1f5f4dSJanus if (node.InitCheck() != B_OK) 1564e62a6973SJanus return; 1565e62a6973SJanus 15669c1f5f4dSJanus const char* kWidthAttrName = "Media:Width"; 15679c1f5f4dSJanus const char* kHeightAttrName = "Media:Height"; 15689c1f5f4dSJanus 15699c1f5f4dSJanus int32 widthAttr; 1570b41cdcb3SJanus ssize_t attrSize = node.ReadAttr(kWidthAttrName, B_INT32_TYPE, 0, 1571b41cdcb3SJanus &widthAttr, sizeof(widthAttr)); 15729c1f5f4dSJanus if (attrSize <= 0 || widthAttr != width) 15739c1f5f4dSJanus node.WriteAttr(kWidthAttrName, B_INT32_TYPE, 0, &width, sizeof(width)); 15749c1f5f4dSJanus 15759c1f5f4dSJanus int32 heightAttr; 1576b41cdcb3SJanus attrSize = node.ReadAttr(kHeightAttrName, B_INT32_TYPE, 0, 1577b41cdcb3SJanus &heightAttr, sizeof(heightAttr)); 15789c1f5f4dSJanus if (attrSize <= 0 || heightAttr != height) 15799c1f5f4dSJanus node.WriteAttr(kHeightAttrName, B_INT32_TYPE, 0, &height, sizeof(height)); 1580e62a6973SJanus } 1581e62a6973SJanus 1582e62a6973SJanus 1583e62a6973SJanus void 158494fd9498SStephan Aßmus ShowImageWindow::_SetToolBarVisible(bool visible, bool animate) 1585cf0d8308SStephan Aßmus { 158695667008SJanus if (visible == fToolBarVisible) 1587cf0d8308SStephan Aßmus return; 1588cf0d8308SStephan Aßmus 158995667008SJanus fToolBarVisible = visible; 159094a4c1c4SAugustin Cavalier float diff = fToolBar->Bounds().Height() + 2; 159194fd9498SStephan Aßmus if (!visible) 1592cf0d8308SStephan Aßmus diff = -diff; 159394fd9498SStephan Aßmus else 159494a4c1c4SAugustin Cavalier fToolBar->Show(); 1595cf0d8308SStephan Aßmus 159694fd9498SStephan Aßmus if (animate) { 159794fd9498SStephan Aßmus // Slide the controls into view. We do this with messages in order 159894fd9498SStephan Aßmus // not to block the window thread. 159994fd9498SStephan Aßmus const float kAnimationOffsets[] = { 0.05, 0.2, 0.5, 0.2, 0.05 }; 160094fd9498SStephan Aßmus const int32 steps = sizeof(kAnimationOffsets) / sizeof(float); 160194fd9498SStephan Aßmus for (int32 i = 0; i < steps; i++) { 160294fd9498SStephan Aßmus BMessage message(kMsgSlideToolBar); 160394fd9498SStephan Aßmus message.AddFloat("offset", floorf(diff * kAnimationOffsets[i])); 160494fd9498SStephan Aßmus PostMessage(&message, this); 160594fd9498SStephan Aßmus } 160694fd9498SStephan Aßmus BMessage finalMessage(kMsgFinishSlidingToolBar); 160795667008SJanus finalMessage.AddFloat("offset", visible ? 0 : diff); 160894fd9498SStephan Aßmus finalMessage.AddBool("show", visible); 160994fd9498SStephan Aßmus PostMessage(&finalMessage, this); 161094fd9498SStephan Aßmus } else { 1611cf0d8308SStephan Aßmus fScrollView->ResizeBy(0, -diff); 1612cf0d8308SStephan Aßmus fScrollView->MoveBy(0, diff); 161394a4c1c4SAugustin Cavalier fToolBar->MoveBy(0, diff); 161494fd9498SStephan Aßmus if (!visible) 161594a4c1c4SAugustin Cavalier fToolBar->Hide(); 161694fd9498SStephan Aßmus } 1617cf0d8308SStephan Aßmus } 1618cf0d8308SStephan Aßmus 1619cf0d8308SStephan Aßmus 162060c23976SJanus void 162160c23976SJanus ShowImageWindow::_SetToolBarBorder(bool visible) 162260c23976SJanus { 162360c23976SJanus float inset = visible 162460c23976SJanus ? ceilf(be_control_look->DefaultItemSpacing() / 2) : 0; 162560c23976SJanus 162660c23976SJanus fToolBar->GroupLayout()->SetInsets(inset, 0, inset, 0); 162760c23976SJanus } 162860c23976SJanus 162960c23976SJanus 1630780d8a62SMichael Pfeiffer bool 1631cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested() 1632cdb89ebbSMatthew Wilber { 1633efa8b4f3SAxel Dörfler if (fSavePanel) { 1634efa8b4f3SAxel Dörfler // Don't allow this window to be closed if a save panel is open 1635efa8b4f3SAxel Dörfler return false; 1636cdb89ebbSMatthew Wilber } 1637cdb89ebbSMatthew Wilber 16385b76e505SStephan Aßmus if (!_ClosePrompt()) 16395b76e505SStephan Aßmus return false; 16405b76e505SStephan Aßmus 16415b76e505SStephan Aßmus ShowImageSettings* settings = my_app->Settings(); 16425b76e505SStephan Aßmus if (settings->Lock()) { 1643c418e2beSStephan Aßmus if (fFullScreen) 1644c418e2beSStephan Aßmus settings->SetRect("WindowFrame", fWindowFrame); 1645c418e2beSStephan Aßmus else 16465b76e505SStephan Aßmus settings->SetRect("WindowFrame", Frame()); 16475b76e505SStephan Aßmus settings->Unlock(); 16485b76e505SStephan Aßmus } 16495b76e505SStephan Aßmus 16505b76e505SStephan Aßmus be_app->PostMessage(MSG_WINDOW_HAS_QUIT); 16515b76e505SStephan Aßmus 16525b76e505SStephan Aßmus return true; 1653efa8b4f3SAxel Dörfler } 1654