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', 975b76e505SStephan Aßmus MSG_SET_RATING = 'mSRT', 98e2069723SAxel Dörfler kMsgFitToWindow = 'mFtW', 99e2069723SAxel Dörfler kMsgOriginalSize = 'mOSZ', 1004aa63633SAxel Dörfler kMsgStretchToWindow = 'mStW', 101cf0d8308SStephan Aßmus kMsgNextSlide = 'mNxS', 10294fd9498SStephan Aßmus kMsgToggleToolBar = 'mTTB', 10394fd9498SStephan Aßmus kMsgSlideToolBar = 'mSTB', 10494fd9498SStephan Aßmus kMsgFinishSlidingToolBar = 'mFST' 105e2069723SAxel Dörfler }; 106e2069723SAxel Dörfler 107e2069723SAxel Dörfler 108cd6b5cdeSAxel Dörfler // This is temporary solution for building BString with printf like format. 109cd6b5cdeSAxel Dörfler // will be removed in the future. 110cd6b5cdeSAxel Dörfler static void 111cd6b5cdeSAxel Dörfler bs_printf(BString* string, const char* format, ...) 112cd6b5cdeSAxel Dörfler { 113cd6b5cdeSAxel Dörfler va_list ap; 114cd6b5cdeSAxel Dörfler char* buf; 115cd6b5cdeSAxel Dörfler 116cd6b5cdeSAxel Dörfler va_start(ap, format); 117cd6b5cdeSAxel Dörfler vasprintf(&buf, format, ap); 118cd6b5cdeSAxel Dörfler string->SetTo(buf); 119cd6b5cdeSAxel Dörfler free(buf); 120cd6b5cdeSAxel Dörfler va_end(ap); 121cd6b5cdeSAxel Dörfler } 122cd6b5cdeSAxel Dörfler 123cd6b5cdeSAxel Dörfler 1246163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow 1256163f333SKarsten Heimrich 1266163f333SKarsten Heimrich 127546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 128546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Menus" 129cf0d8308SStephan Aßmus 130cf0d8308SStephan Aßmus 1315b76e505SStephan Aßmus ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref, 132efa8b4f3SAxel Dörfler const BMessenger& trackerMessenger) 133fd952aefSRyan Leavengood : 13494fd9498SStephan Aßmus BWindow(frame, "", B_DOCUMENT_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS), 135b9767a83SAxel Dörfler fNavigator(ref, trackerMessenger), 136fd952aefSRyan Leavengood fSavePanel(NULL), 137fd952aefSRyan Leavengood fBar(NULL), 138fd952aefSRyan Leavengood fBrowseMenu(NULL), 139fd952aefSRyan Leavengood fGoToPageMenu(NULL), 1404aa63633SAxel Dörfler fSlideShowDelayMenu(NULL), 14194a4c1c4SAugustin Cavalier fToolBar(NULL), 142fd952aefSRyan Leavengood fImageView(NULL), 143fd952aefSRyan Leavengood fStatusView(NULL), 144e2069723SAxel Dörfler fProgressWindow(new ProgressWindow()), 145fd952aefSRyan Leavengood fModified(false), 146fd952aefSRyan Leavengood fFullScreen(false), 147fd952aefSRyan Leavengood fShowCaption(true), 148cf0d8308SStephan Aßmus fShowToolBar(true), 1494aa63633SAxel Dörfler fPrintSettings(NULL), 1504aa63633SAxel Dörfler fSlideShowRunner(NULL), 1514aa63633SAxel Dörfler fSlideShowDelay(kDefaultSlideShowDelay) 15213afa642SPhil Greenway { 1532281340dSAxel Dörfler _ApplySettings(); 154fc0a275bSMatthew Wilber 15594fd9498SStephan Aßmus SetLayout(new BGroupLayout(B_VERTICAL, 0)); 15694fd9498SStephan Aßmus 15713afa642SPhil Greenway // create menu bar 15894fd9498SStephan Aßmus fBar = new BMenuBar("menu_bar"); 159b9767a83SAxel Dörfler _AddMenus(fBar); 16094fd9498SStephan Aßmus float menuBarMinWidth = fBar->MinSize().width; 161e9dcd874SAxel Dörfler AddChild(fBar); 16213afa642SPhil Greenway 16394fd9498SStephan Aßmus // Add a content view so the tool bar can be moved outside of the 16494fd9498SStephan Aßmus // visible portion without colliding with the menu bar. 165cf0d8308SStephan Aßmus 16694fd9498SStephan Aßmus BView* contentView = new BView(BRect(), "content", B_FOLLOW_NONE, 0); 16794fd9498SStephan Aßmus contentView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 16894fd9498SStephan Aßmus contentView->SetExplicitMinSize(BSize(250, 100)); 16994fd9498SStephan Aßmus AddChild(contentView); 17094fd9498SStephan Aßmus 17194fd9498SStephan Aßmus // Create the tool bar 17294fd9498SStephan Aßmus BRect viewFrame = contentView->Bounds(); 17394fd9498SStephan Aßmus viewFrame.right -= B_V_SCROLL_BAR_WIDTH; 17494a4c1c4SAugustin Cavalier fToolBar = new BToolBar(viewFrame); 175cf0d8308SStephan Aßmus 176cf0d8308SStephan Aßmus // Add the tool icons. 177cf0d8308SStephan Aßmus 17894a4c1c4SAugustin Cavalier // fToolBar->AddAction(MSG_FILE_OPEN, be_app, 179cf0d8308SStephan Aßmus // tool_bar_icon(kIconDocumentOpen), B_TRANSLATE("Open" B_UTF8_ELLIPSIS)); 18094a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FILE_PREV, this, 181*58ee42e9SAugustin Cavalier tool_bar_icon(kIconGoPrevious), B_TRANSLATE("Previous file")); 18294a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FILE_NEXT, this, tool_bar_icon(kIconGoNext), 183*58ee42e9SAugustin Cavalier B_TRANSLATE("Next file")); 184a877c0e7SStephan Aßmus BMessage* fullScreenSlideShow = new BMessage(MSG_SLIDE_SHOW); 185a877c0e7SStephan Aßmus fullScreenSlideShow->AddBool("full screen", true); 18694a4c1c4SAugustin Cavalier fToolBar->AddAction(fullScreenSlideShow, this, 187*58ee42e9SAugustin Cavalier tool_bar_icon(kIconMediaMovieLibrary), B_TRANSLATE("Slide show")); 18894a4c1c4SAugustin Cavalier fToolBar->AddSeparator(); 18994a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_SELECTION_MODE, this, 190cf0d8308SStephan Aßmus tool_bar_icon(kIconDrawRectangularSelection), 191*58ee42e9SAugustin Cavalier B_TRANSLATE("Selection mode")); 19294a4c1c4SAugustin Cavalier fToolBar->AddSeparator(); 19394a4c1c4SAugustin Cavalier fToolBar->AddAction(kMsgOriginalSize, this, 194*58ee42e9SAugustin Cavalier tool_bar_icon(kIconZoomOriginal), B_TRANSLATE("Original size"), NULL, 195*58ee42e9SAugustin Cavalier true); 19694a4c1c4SAugustin Cavalier fToolBar->AddAction(kMsgFitToWindow, this, 197*58ee42e9SAugustin Cavalier tool_bar_icon(kIconZoomFitBest), B_TRANSLATE("Fit to window")); 19894a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_ZOOM_IN, this, tool_bar_icon(kIconZoomIn), 199*58ee42e9SAugustin Cavalier B_TRANSLATE("Zoom in")); 20094a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_ZOOM_OUT, this, tool_bar_icon(kIconZoomOut), 201*58ee42e9SAugustin Cavalier B_TRANSLATE("Zoom out")); 202442e457dSGerasim Troeglazov fToolBar->AddSeparator(); 203442e457dSGerasim Troeglazov fToolBar->AddAction(MSG_PAGE_PREV, this, tool_bar_icon(kIconPagePrevious), 204*58ee42e9SAugustin Cavalier B_TRANSLATE("Previous page")); 205442e457dSGerasim Troeglazov fToolBar->AddAction(MSG_PAGE_NEXT, this, tool_bar_icon(kIconPageNext), 206*58ee42e9SAugustin Cavalier B_TRANSLATE("Next page")); 20794a4c1c4SAugustin Cavalier fToolBar->AddGlue(); 20894a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FULL_SCREEN, this, 209*58ee42e9SAugustin Cavalier tool_bar_icon(kIconViewWindowed), B_TRANSLATE("Leave full screen")); 21094a4c1c4SAugustin Cavalier fToolBar->SetActionVisible(MSG_FULL_SCREEN, false); 211cf0d8308SStephan Aßmus 21294a4c1c4SAugustin Cavalier fToolBar->ResizeTo(viewFrame.Width(), fToolBar->MinSize().height); 213cf0d8308SStephan Aßmus 21494a4c1c4SAugustin Cavalier contentView->AddChild(fToolBar); 215cf0d8308SStephan Aßmus 216cf0d8308SStephan Aßmus if (fShowToolBar) 21794a4c1c4SAugustin Cavalier viewFrame.top = fToolBar->Frame().bottom + 1; 218cf0d8308SStephan Aßmus else 21994a4c1c4SAugustin Cavalier fToolBar->Hide(); 220cf0d8308SStephan Aßmus 22195667008SJanus fToolBarVisible = fShowToolBar; 22295667008SJanus 22394fd9498SStephan Aßmus viewFrame.bottom = contentView->Bounds().bottom; 22413afa642SPhil Greenway viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; 22513afa642SPhil Greenway 22613afa642SPhil Greenway // create the image view 227d3046f7dSMichael Pfeiffer fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL, 228e2069723SAxel Dörfler B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED 229e2069723SAxel Dörfler | B_FRAME_EVENTS); 23013afa642SPhil Greenway // wrap a scroll view around the view 231cf0d8308SStephan Aßmus fScrollView = new BScrollView("image_scroller", fImageView, 232cae52eadSJanus B_FOLLOW_ALL, 0, true, true, B_PLAIN_BORDER); 23394fd9498SStephan Aßmus contentView->AddChild(fScrollView); 23413afa642SPhil Greenway 235cae52eadSJanus fStatusView = new ShowImageStatusView(fScrollView); 236cae52eadSJanus fScrollView->AddChild(fStatusView); 23713afa642SPhil Greenway 2389b13c418SStephan Aßmus // Update minimum window size 23994a4c1c4SAugustin Cavalier float toolBarMinWidth = fToolBar->MinSize().width; 2409b13c418SStephan Aßmus SetSizeLimits(std::max(menuBarMinWidth, toolBarMinWidth), 100000, 100, 2419b13c418SStephan Aßmus 100000); 24213afa642SPhil Greenway 243134d6076SMichael Pfeiffer // finish creating the window 244b9767a83SAxel Dörfler if (_LoadImage() != B_OK) { 245ba3217eeSAxel Dörfler _LoadError(ref); 2465e09d5dbSRyan Leavengood Quit(); 24701939af6SAxel Dörfler return; 248d10d5947SMichael Pfeiffer } 249402c09e5SMatthew Wilber 250d9f6762dSMichael Pfeiffer // add View menu here so it can access ShowImageView methods 251546208a5SOliver Tappe BMenu* menu = new BMenu(B_TRANSLATE_CONTEXT("View", "Menus")); 252fd952aefSRyan Leavengood _BuildViewMenu(menu, false); 253d9f6762dSMichael Pfeiffer fBar->AddItem(menu); 254d9f6762dSMichael Pfeiffer 2555b76e505SStephan Aßmus fBar->AddItem(_BuildRatingMenu()); 2565b76e505SStephan Aßmus 257d9f6762dSMichael Pfeiffer SetPulseRate(100000); 258d9f6762dSMichael Pfeiffer // every 1/10 second; ShowImageView needs it for marching ants 259d9f6762dSMichael Pfeiffer 2606db01936SAxel Dörfler _MarkMenuItem(menu, MSG_SELECTION_MODE, 2616db01936SAxel Dörfler fImageView->IsSelectionModeEnabled()); 2626db01936SAxel Dörfler 263402c09e5SMatthew Wilber // Tell application object to query the clipboard 264402c09e5SMatthew Wilber // and tell this window if it contains interesting data or not 265402c09e5SMatthew Wilber be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED); 266cd6b5cdeSAxel Dörfler 267cd6b5cdeSAxel Dörfler // The window will be shown on screen automatically 268cd6b5cdeSAxel Dörfler Run(); 26913afa642SPhil Greenway } 27013afa642SPhil Greenway 271efa8b4f3SAxel Dörfler 27213afa642SPhil Greenway ShowImageWindow::~ShowImageWindow() 27313afa642SPhil Greenway { 274e2069723SAxel Dörfler fProgressWindow->Lock(); 275e2069723SAxel Dörfler fProgressWindow->Quit(); 2764aa63633SAxel Dörfler 2774aa63633SAxel Dörfler _StopSlideShow(); 27813afa642SPhil Greenway } 27913afa642SPhil Greenway 280efa8b4f3SAxel Dörfler 281cdb89ebbSMatthew Wilber void 282d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu) 283d9f6762dSMichael Pfeiffer { 284fd952aefSRyan Leavengood _BuildViewMenu(menu, true); 285d9f6762dSMichael Pfeiffer } 286efa8b4f3SAxel Dörfler 28756b0c7b9SKarsten Heimrich 288cdb89ebbSMatthew Wilber void 289fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) 290da87390fSMichael Pfeiffer { 291905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this); 2924aa63633SAxel Dörfler _MarkMenuItem(menu, MSG_SLIDE_SHOW, fSlideShowRunner != NULL); 293905c8c8cSMatt Madia BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay")); 2944aa63633SAxel Dörfler if (fSlideShowDelayMenu == NULL) 2954aa63633SAxel Dörfler fSlideShowDelayMenu = delayMenu; 296efa8b4f3SAxel Dörfler 297efa8b4f3SAxel Dörfler delayMenu->SetRadioMode(true); 2984aa63633SAxel Dörfler 2994aa63633SAxel Dörfler int32 kDelays[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 20}; 3004aa63633SAxel Dörfler for (uint32 i = 0; i < sizeof(kDelays) / sizeof(kDelays[0]); i++) { 30103ad73fcSAdrien Destugues BString text; 30203ad73fcSAdrien Destugues BDurationFormat format; 30303ad73fcSAdrien Destugues text.Truncate(0); 30403ad73fcSAdrien Destugues format.Format(text, 0, kDelays[i] * 1000000LL); 3054aa63633SAxel Dörfler 3064aa63633SAxel Dörfler _AddDelayItem(delayMenu, text.String(), kDelays[i] * 1000000LL); 3074aa63633SAxel Dörfler } 308efa8b4f3SAxel Dörfler menu->AddItem(delayMenu); 30930060f17SMatthew Wilber 310efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 311efa8b4f3SAxel Dörfler 312905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Original size"), 313e2069723SAxel Dörfler kMsgOriginalSize, '1', 0, this); 314e2069723SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Fit to window"), 315e2069723SAxel Dörfler kMsgFitToWindow, '0', 0, this); 316905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this); 317905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this); 318efa8b4f3SAxel Dörfler 319efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 320efa8b4f3SAxel Dörfler 3214fd570d3SAxel Dörfler if (!popupMenu || fFullScreen) { 322905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), 323905c8c8cSMatt Madia MSG_SCALE_BILINEAR, 0, 0, this); 3244fd570d3SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Stretch to window"), 325e2069723SAxel Dörfler kMsgStretchToWindow, 0, 0, this); 326efa8b4f3SAxel Dörfler 327efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 32832c22143SAxel Dörfler } 329efa8b4f3SAxel Dörfler 330905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Full screen"), 331905c8c8cSMatt Madia MSG_FULL_SCREEN, B_ENTER, 0, this); 332fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen); 333efa8b4f3SAxel Dörfler 334905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"), 335905c8c8cSMatt Madia MSG_SHOW_CAPTION, 0, 0, this); 336fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption); 337efa8b4f3SAxel Dörfler 338e2069723SAxel Dörfler _MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->ScaleBilinear()); 339e2069723SAxel Dörfler _MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds()); 340a60adbf9SAxel Dörfler 341cf0d8308SStephan Aßmus if (!popupMenu) { 34294fd9498SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar, 343d5647665SHumdinger 'B', 0, this); 344cf0d8308SStephan Aßmus _MarkMenuItem(menu, kMsgToggleToolBar, 34594a4c1c4SAugustin Cavalier !fToolBar->IsHidden(fToolBar)); 346cf0d8308SStephan Aßmus } 347cf0d8308SStephan Aßmus 348d9f6762dSMichael Pfeiffer if (popupMenu) { 349a60adbf9SAxel Dörfler menu->AddSeparatorItem(); 350905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 3511ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 352d9f6762dSMichael Pfeiffer } 353da87390fSMichael Pfeiffer } 354da87390fSMichael Pfeiffer 355efa8b4f3SAxel Dörfler 3565b76e505SStephan Aßmus BMenu* 3575b76e505SStephan Aßmus ShowImageWindow::_BuildRatingMenu() 3585b76e505SStephan Aßmus { 3595b76e505SStephan Aßmus fRatingMenu = new BMenu(B_TRANSLATE("Rating")); 3605b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) { 3615b76e505SStephan Aßmus BString label; 3625b76e505SStephan Aßmus label << i; 3635b76e505SStephan Aßmus BMessage* message = new BMessage(MSG_SET_RATING); 3645b76e505SStephan Aßmus message->AddInt32("rating", i); 3655b76e505SStephan Aßmus fRatingMenu->AddItem(new BMenuItem(label.String(), message)); 3665b76e505SStephan Aßmus } 3675b76e505SStephan Aßmus // NOTE: We may want to encapsulate the Rating menu within a more 3685b76e505SStephan Aßmus // general "Attributes" menu. 3695b76e505SStephan Aßmus return fRatingMenu; 3705b76e505SStephan Aßmus } 3715b76e505SStephan Aßmus 3725b76e505SStephan Aßmus 373da87390fSMichael Pfeiffer void 374b9767a83SAxel Dörfler ShowImageWindow::_AddMenus(BMenuBar* bar) 37513afa642SPhil Greenway { 376905c8c8cSMatt Madia BMenu* menu = new BMenu(B_TRANSLATE("File")); 37736272f0dSAxel Dörfler 37836272f0dSAxel Dörfler // Add recent files to "Open File" entry as sub-menu. 37936272f0dSAxel Dörfler BMenuItem* item = new BMenuItem(BRecentFilesList::NewFileListMenu( 38036272f0dSAxel Dörfler B_TRANSLATE("Open" B_UTF8_ELLIPSIS), NULL, NULL, be_app, 10, true, 38136272f0dSAxel Dörfler NULL, kApplicationSignature), new BMessage(MSG_FILE_OPEN)); 38236272f0dSAxel Dörfler item->SetShortcut('O', 0); 38336272f0dSAxel Dörfler item->SetTarget(be_app); 38436272f0dSAxel Dörfler menu->AddItem(item); 385efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 38636272f0dSAxel Dörfler 3876db01936SAxel Dörfler BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS), 3881ed4535fSStephan Aßmus B_ITEMS_IN_COLUMN); 3896db01936SAxel Dörfler BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP); 390fc0a275bSMatthew Wilber // Fill Save As submenu with all types that can be converted 391fc0a275bSMatthew Wilber // to from the Be bitmap image format 3926db01936SAxel Dörfler menu->AddItem(menuSaveAs); 393905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this); 394d5647665SHumdinger _AddItemMenu(menu, B_TRANSLATE("Move to Trash"), kMsgDeleteCurrentFile, 'T', 0, this); 395efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 396905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS), 3971ed4535fSStephan Aßmus MSG_PAGE_SETUP, 0, 0, this); 398905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS), 3991ed4535fSStephan Aßmus MSG_PREPARE_PRINT, 'P', 0, this); 400efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 401905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app); 402efa8b4f3SAxel Dörfler bar->AddItem(menu); 40313afa642SPhil Greenway 404905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Edit")); 405905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false); 406efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 407cf0d8308SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Selection mode"), MSG_SELECTION_MODE, 0, 0, 4086db01936SAxel Dörfler this); 40932c22143SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Clear selection"), 41032c22143SAxel Dörfler MSG_CLEAR_SELECT, 0, 0, this, false); 411905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Select all"), 412905c8c8cSMatt Madia MSG_SELECT_ALL, 'A', 0, this); 413efa8b4f3SAxel Dörfler bar->AddItem(menu); 41413afa642SPhil Greenway 415905c8c8cSMatt Madia menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse")); 416905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("First page"), 4171ed4535fSStephan Aßmus MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this); 418905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Last page"), 4191ed4535fSStephan Aßmus MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this); 420905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous page"), 421905c8c8cSMatt Madia MSG_PAGE_PREV, B_LEFT_ARROW, 0, this); 422905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next page"), 423905c8c8cSMatt Madia MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this); 424905c8c8cSMatt Madia fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page")); 4255e427b6aSMichael Pfeiffer fGoToPageMenu->SetRadioMode(true); 426efa8b4f3SAxel Dörfler menu->AddItem(fGoToPageMenu); 427efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 428905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous file"), 429905c8c8cSMatt Madia MSG_FILE_PREV, B_UP_ARROW, 0, this); 430905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next file"), 431905c8c8cSMatt Madia MSG_FILE_NEXT, B_DOWN_ARROW, 0, this); 432efa8b4f3SAxel Dörfler bar->AddItem(menu); 43303839579SMatthew Wilber 434905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Image")); 435905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"), 436905c8c8cSMatt Madia MSG_ROTATE_90, 'R', 0, this); 437905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"), 4381ed4535fSStephan Aßmus MSG_ROTATE_270, 'R', B_SHIFT_KEY, this); 439efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 440905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip left to right"), 4411ed4535fSStephan Aßmus MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this); 442905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"), 4431ed4535fSStephan Aßmus MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this); 444efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 445905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 4461ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 44704f96544SAxel Dörfler 44804f96544SAxel Dörfler bar->AddItem(menu); 44913afa642SPhil Greenway } 45013afa642SPhil Greenway 451efa8b4f3SAxel Dörfler 452cdb89ebbSMatthew Wilber BMenuItem* 453fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what, 4544fd570d3SAxel Dörfler char shortcut, uint32 modifier, const BHandler* target, bool enabled) 455cdb89ebbSMatthew Wilber { 4564fd570d3SAxel Dörfler BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut, 4574fd570d3SAxel Dörfler modifier); 458efa8b4f3SAxel Dörfler menu->AddItem(item); 459efa8b4f3SAxel Dörfler 4606163f333SKarsten Heimrich item->SetTarget(target); 4616163f333SKarsten Heimrich item->SetEnabled(enabled); 4626163f333SKarsten Heimrich 463efa8b4f3SAxel Dörfler return item; 46413afa642SPhil Greenway } 46513afa642SPhil Greenway 466efa8b4f3SAxel Dörfler 467ad13f387SMichael Pfeiffer BMenuItem* 4684aa63633SAxel Dörfler ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, bigtime_t delay) 469ad13f387SMichael Pfeiffer { 470efa8b4f3SAxel Dörfler BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY); 4714aa63633SAxel Dörfler message->AddInt64("delay", delay); 472ad13f387SMichael Pfeiffer 4736163f333SKarsten Heimrich BMenuItem* item = new BMenuItem(label, message, 0); 474efa8b4f3SAxel Dörfler item->SetTarget(this); 475ad13f387SMichael Pfeiffer 4764aa63633SAxel Dörfler if (delay == fSlideShowDelay) 477efa8b4f3SAxel Dörfler item->SetMarked(true); 478ad13f387SMichael Pfeiffer 479efa8b4f3SAxel Dörfler menu->AddItem(item); 480efa8b4f3SAxel Dörfler return item; 481ad13f387SMichael Pfeiffer } 482ad13f387SMichael Pfeiffer 483efa8b4f3SAxel Dörfler 484cdb89ebbSMatthew Wilber void 485e2069723SAxel Dörfler ShowImageWindow::_ResizeWindowToImage() 48613afa642SPhil Greenway { 487e2069723SAxel Dörfler BBitmap* bitmap = fImageView->Bitmap(); 488d10d5947SMichael Pfeiffer BScreen screen; 489e2069723SAxel Dörfler if (bitmap == NULL || !screen.IsValid()) 490efa8b4f3SAxel Dörfler return; 491efa8b4f3SAxel Dörfler 4921076d97bSAxel Dörfler // TODO: use View::GetPreferredSize() instead? 4931076d97bSAxel Dörfler BRect r(bitmap->Bounds()); 4941076d97bSAxel Dörfler float width = r.Width() + B_V_SCROLL_BAR_WIDTH; 4951076d97bSAxel Dörfler float height = r.Height() + 1 + fBar->Frame().Height() 4961076d97bSAxel Dörfler + B_H_SCROLL_BAR_HEIGHT; 497cdb89ebbSMatthew Wilber 4986163f333SKarsten Heimrich BRect frame = screen.Frame(); 4996163f333SKarsten Heimrich const float windowBorder = 5; 500d10d5947SMichael Pfeiffer // dimensions so that window does not reach outside of screen 5016163f333SKarsten Heimrich float maxWidth = frame.Width() + 1 - windowBorder - Frame().left; 5026163f333SKarsten Heimrich float maxHeight = frame.Height() + 1 - windowBorder - Frame().top; 503cdb89ebbSMatthew Wilber 504a8fc7138SMichael Pfeiffer // We have to check size limits manually, otherwise 505a8fc7138SMichael Pfeiffer // menu bar will be too short for small images. 506efa8b4f3SAxel Dörfler 507fc5ca95dSStephan Aßmus float minW, maxW, minH, maxH; 508a8fc7138SMichael Pfeiffer GetSizeLimits(&minW, &maxW, &minH, &maxH); 509efa8b4f3SAxel Dörfler if (maxWidth > maxW) 510efa8b4f3SAxel Dörfler maxWidth = maxW; 511efa8b4f3SAxel Dörfler if (maxHeight > maxH) 512efa8b4f3SAxel Dörfler maxHeight = maxH; 513efa8b4f3SAxel Dörfler if (width < minW) 514efa8b4f3SAxel Dörfler width = minW; 515efa8b4f3SAxel Dörfler if (height < minH) 516efa8b4f3SAxel Dörfler height = minH; 517a8fc7138SMichael Pfeiffer 518efa8b4f3SAxel Dörfler if (width > maxWidth) 519efa8b4f3SAxel Dörfler width = maxWidth; 520efa8b4f3SAxel Dörfler if (height > maxHeight) 521efa8b4f3SAxel Dörfler height = maxHeight; 522d10d5947SMichael Pfeiffer 523d10d5947SMichael Pfeiffer ResizeTo(width, height); 52413afa642SPhil Greenway } 52513afa642SPhil Greenway 526efa8b4f3SAxel Dörfler 5277eca0987SMichael Pfeiffer bool 528fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what) 5297eca0987SMichael Pfeiffer { 5307eca0987SMichael Pfeiffer bool marked = false; 5316163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(what); 5327eca0987SMichael Pfeiffer if (item != NULL) { 5337eca0987SMichael Pfeiffer marked = !item->IsMarked(); 5347eca0987SMichael Pfeiffer item->SetMarked(marked); 5357eca0987SMichael Pfeiffer } 53694a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(what, marked); 5377eca0987SMichael Pfeiffer return marked; 5387eca0987SMichael Pfeiffer } 5397eca0987SMichael Pfeiffer 540efa8b4f3SAxel Dörfler 541cdb89ebbSMatthew Wilber void 542fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable) 543e6a50d9cSMichael Pfeiffer { 5446163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 5456163f333SKarsten Heimrich if (item && item->IsEnabled() != enable) 546e6a50d9cSMichael Pfeiffer item->SetEnabled(enable); 54794a4c1c4SAugustin Cavalier fToolBar->SetActionEnabled(what, enable); 548e6a50d9cSMichael Pfeiffer } 549e6a50d9cSMichael Pfeiffer 550efa8b4f3SAxel Dörfler 551e6a50d9cSMichael Pfeiffer void 552fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked) 553e6a50d9cSMichael Pfeiffer { 5546163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 5556163f333SKarsten Heimrich if (item && item->IsMarked() != marked) 556e6a50d9cSMichael Pfeiffer item->SetMarked(marked); 55794a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(what, marked); 558e6a50d9cSMichael Pfeiffer } 559e6a50d9cSMichael Pfeiffer 560efa8b4f3SAxel Dörfler 561da87390fSMichael Pfeiffer void 5624aa63633SAxel Dörfler ShowImageWindow::_MarkSlideShowDelay(bigtime_t delay) 563da87390fSMichael Pfeiffer { 5644aa63633SAxel Dörfler const int32 count = fSlideShowDelayMenu->CountItems(); 5654aa63633SAxel Dörfler for (int32 i = 0; i < count; i ++) { 5664aa63633SAxel Dörfler BMenuItem* item = fSlideShowDelayMenu->ItemAt(i); 5674aa63633SAxel Dörfler if (item != NULL) { 5684aa63633SAxel Dörfler bigtime_t itemDelay; 5694aa63633SAxel Dörfler if (item->Message()->FindInt64("delay", &itemDelay) == B_OK 5704aa63633SAxel Dörfler && itemDelay == delay) { 571da87390fSMichael Pfeiffer item->SetMarked(true); 572da87390fSMichael Pfeiffer return; 573da87390fSMichael Pfeiffer } 574da87390fSMichael Pfeiffer } 575da87390fSMichael Pfeiffer } 576da87390fSMichael Pfeiffer } 577e6a50d9cSMichael Pfeiffer 57819c76de4SMichael Pfeiffer 57919c76de4SMichael Pfeiffer void 580e2069723SAxel Dörfler ShowImageWindow::Zoom(BPoint origin, float width, float height) 58119c76de4SMichael Pfeiffer { 582e2069723SAxel Dörfler _ToggleFullScreen(); 58319c76de4SMichael Pfeiffer } 58419c76de4SMichael Pfeiffer 585efa8b4f3SAxel Dörfler 586e6a50d9cSMichael Pfeiffer void 587efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message) 58813afa642SPhil Greenway { 589e2069723SAxel Dörfler if (message->WasDropped()) { 590e2069723SAxel Dörfler uint32 type; 591e2069723SAxel Dörfler int32 count; 592e2069723SAxel Dörfler status_t status = message->GetInfo("refs", &type, &count); 593e2069723SAxel Dörfler if (status == B_OK && type == B_REF_TYPE) { 594e2069723SAxel Dörfler message->what = B_REFS_RECEIVED; 595e2069723SAxel Dörfler be_app->PostMessage(message); 596e2069723SAxel Dörfler } 597e2069723SAxel Dörfler } 598e2069723SAxel Dörfler 599efa8b4f3SAxel Dörfler switch (message->what) { 600e2069723SAxel Dörfler case kMsgImageCacheImageLoaded: 601cd6b5cdeSAxel Dörfler { 602e2069723SAxel Dörfler fProgressWindow->Stop(); 603e2069723SAxel Dörfler 604df942b3eSAxel Dörfler BitmapOwner* bitmapOwner = NULL; 605df942b3eSAxel Dörfler message->FindPointer("bitmapOwner", (void**)&bitmapOwner); 606df942b3eSAxel Dörfler 607cd6b5cdeSAxel Dörfler bool first = fImageView->Bitmap() == NULL; 608b9767a83SAxel Dörfler entry_ref ref; 609b9767a83SAxel Dörfler message->FindRef("ref", &ref); 610b9767a83SAxel Dörfler if (!first && ref != fNavigator.CurrentRef()) { 611b9767a83SAxel Dörfler // ignore older images 612df942b3eSAxel Dörfler if (bitmapOwner != NULL) 613df942b3eSAxel Dörfler bitmapOwner->ReleaseReference(); 614b9767a83SAxel Dörfler break; 615b9767a83SAxel Dörfler } 616cd6b5cdeSAxel Dörfler 617baa27ccbSJanus int32 page = message->FindInt32("page"); 618baa27ccbSJanus int32 pageCount = message->FindInt32("pageCount"); 619baa27ccbSJanus if (!first && page != fNavigator.CurrentPage()) { 620baa27ccbSJanus // ignore older pages 621baa27ccbSJanus if (bitmapOwner != NULL) 622baa27ccbSJanus bitmapOwner->ReleaseReference(); 623baa27ccbSJanus break; 624baa27ccbSJanus } 625baa27ccbSJanus 626cd6b5cdeSAxel Dörfler status_t status = fImageView->SetImage(message); 627cd6b5cdeSAxel Dörfler if (status != B_OK) { 628df942b3eSAxel Dörfler if (bitmapOwner != NULL) 629df942b3eSAxel Dörfler bitmapOwner->ReleaseReference(); 630df942b3eSAxel Dörfler 631cd6b5cdeSAxel Dörfler _LoadError(ref); 632cd6b5cdeSAxel Dörfler 633cd6b5cdeSAxel Dörfler // quit if file could not be opened 634cd6b5cdeSAxel Dörfler if (first) 635cd6b5cdeSAxel Dörfler Quit(); 636cd6b5cdeSAxel Dörfler break; 637cd6b5cdeSAxel Dörfler } 638cd6b5cdeSAxel Dörfler 639cd6b5cdeSAxel Dörfler fImageType = message->FindString("type"); 640baa27ccbSJanus fNavigator.SetTo(ref, page, pageCount); 641cd6b5cdeSAxel Dörfler 642e2069723SAxel Dörfler fImageView->FitToBounds(); 643cd6b5cdeSAxel Dörfler if (first) { 644cd6b5cdeSAxel Dörfler fImageView->MakeFocus(true); 645cd6b5cdeSAxel Dörfler // to receive key messages 646cd6b5cdeSAxel Dörfler Show(); 647e2069723SAxel Dörfler } 6485b76e505SStephan Aßmus _UpdateRatingMenu(); 649e62a6973SJanus // Set width and height attributes of the currently showed file. 650e62a6973SJanus // This should only be a temporary solution. 651e62a6973SJanus _SaveWidthAndHeight(); 652e2069723SAxel Dörfler break; 653e2069723SAxel Dörfler } 654e2069723SAxel Dörfler 655e2069723SAxel Dörfler case kMsgImageCacheProgressUpdate: 656e2069723SAxel Dörfler { 657e2069723SAxel Dörfler entry_ref ref; 658e2069723SAxel Dörfler if (message->FindRef("ref", &ref) == B_OK 659e2069723SAxel Dörfler && ref == fNavigator.CurrentRef()) { 660e2069723SAxel Dörfler message->what = kMsgProgressUpdate; 661e2069723SAxel Dörfler fProgressWindow->PostMessage(message); 662cd6b5cdeSAxel Dörfler } 663cd6b5cdeSAxel Dörfler break; 664cd6b5cdeSAxel Dörfler } 665cd6b5cdeSAxel Dörfler 666ee7b4f39SMatthew Wilber case MSG_MODIFIED: 667ee7b4f39SMatthew Wilber // If image has been modified due to a Cut or Paste 668ee7b4f39SMatthew Wilber fModified = true; 669ee7b4f39SMatthew Wilber break; 670ee7b4f39SMatthew Wilber 671fc0a275bSMatthew Wilber case MSG_OUTPUT_TYPE: 672fc0a275bSMatthew Wilber // User clicked Save As then choose an output format 673d3046f7dSMichael Pfeiffer if (!fSavePanel) 674cdb89ebbSMatthew Wilber // If user doesn't already have a save panel open 675fd952aefSRyan Leavengood _SaveAs(message); 67613afa642SPhil Greenway break; 677fc0a275bSMatthew Wilber 678fc0a275bSMatthew Wilber case MSG_SAVE_PANEL: 679fc0a275bSMatthew Wilber // User specified where to save the output image 680fd952aefSRyan Leavengood _SaveToFile(message); 68107caaa8eSMatthew Wilber break; 68207caaa8eSMatthew Wilber 683cdb89ebbSMatthew Wilber case B_CANCEL: 684d3046f7dSMichael Pfeiffer delete fSavePanel; 685d3046f7dSMichael Pfeiffer fSavePanel = NULL; 686cdb89ebbSMatthew Wilber break; 687cdb89ebbSMatthew Wilber 6886db01936SAxel Dörfler case MSG_UPDATE_STATUS: 6896db01936SAxel Dörfler { 690cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 691cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 6926c305411SMatthew Wilber 693baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_FIRST, 694baa27ccbSJanus fNavigator.HasPreviousPage()); 695baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_LAST, fNavigator.HasNextPage()); 696baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_NEXT, fNavigator.HasNextPage()); 697baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_PREV, fNavigator.HasPreviousPage()); 698baa27ccbSJanus fGoToPageMenu->SetEnabled(pages > 1); 6991d592070SMatthew Wilber 700cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile()); 701cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile()); 702134d6076SMichael Pfeiffer 703d3046f7dSMichael Pfeiffer if (fGoToPageMenu->CountItems() != pages) { 7046c305411SMatthew Wilber // Only rebuild the submenu if the number of 7056c305411SMatthew Wilber // pages is different 7066c305411SMatthew Wilber 707cd6b5cdeSAxel Dörfler while (fGoToPageMenu->CountItems() > 0) { 7086c305411SMatthew Wilber // Remove all page numbers 7097f4d1af4SSergei Reznikov delete fGoToPageMenu->RemoveItem((int32)0); 710cd6b5cdeSAxel Dörfler } 7116c305411SMatthew Wilber 712780d8a62SMichael Pfeiffer for (int32 i = 1; i <= pages; i++) { 7136c305411SMatthew Wilber // Fill Go To page submenu with an entry for each page 714cd6b5cdeSAxel Dörfler BMessage* goTo = new BMessage(MSG_GOTO_PAGE); 715cd6b5cdeSAxel Dörfler goTo->AddInt32("page", i); 7166163f333SKarsten Heimrich 7176163f333SKarsten Heimrich char shortcut = 0; 718cd6b5cdeSAxel Dörfler if (i < 10) 719780d8a62SMichael Pfeiffer shortcut = '0' + i; 7206163f333SKarsten Heimrich 7216163f333SKarsten Heimrich BString strCaption; 7226163f333SKarsten Heimrich strCaption << i; 7236163f333SKarsten Heimrich 724cd6b5cdeSAxel Dörfler BMenuItem* item = new BMenuItem(strCaption.String(), goTo, 725a8199d69Sthreedeyes shortcut, B_SHIFT_KEY); 726cd6b5cdeSAxel Dörfler if (currentPage == i) 727efa8b4f3SAxel Dörfler item->SetMarked(true); 728efa8b4f3SAxel Dörfler fGoToPageMenu->AddItem(item); 7296c305411SMatthew Wilber } 7306c305411SMatthew Wilber } else { 7316c305411SMatthew Wilber // Make sure the correct page is marked 732cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 733cd6b5cdeSAxel Dörfler if (currentItem != NULL && !currentItem->IsMarked()) 734cd6b5cdeSAxel Dörfler currentItem->SetMarked(true); 7356c305411SMatthew Wilber } 7366c305411SMatthew Wilber 737cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 738b9767a83SAxel Dörfler 739b9767a83SAxel Dörfler BPath path(fImageView->Image()); 740b9767a83SAxel Dörfler SetTitle(path.Path()); 7416db01936SAxel Dörfler break; 7426db01936SAxel Dörfler } 74303839579SMatthew Wilber 7446db01936SAxel Dörfler case MSG_UPDATE_STATUS_TEXT: 7456db01936SAxel Dörfler { 746cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 7476db01936SAxel Dörfler break; 7486db01936SAxel Dörfler } 7498f5fd23fSRyan Leavengood 7506db01936SAxel Dörfler case MSG_SELECTION: 7516db01936SAxel Dörfler { 7528ad30bcfSMatthew Wilber // The view sends this message when a selection is 7538ad30bcfSMatthew Wilber // made or the selection is cleared so that the window 7548ad30bcfSMatthew Wilber // can update the state of the appropriate menu items 7556db01936SAxel Dörfler bool enable; 7566db01936SAxel Dörfler if (message->FindBool("has_selection", &enable) == B_OK) { 7576db01936SAxel Dörfler _EnableMenuItem(fBar, B_COPY, enable); 7586db01936SAxel Dörfler _EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable); 7598ad30bcfSMatthew Wilber } 7606db01936SAxel Dörfler break; 7616db01936SAxel Dörfler } 7628ad30bcfSMatthew Wilber 76313afa642SPhil Greenway case B_COPY: 764d3046f7dSMichael Pfeiffer fImageView->CopySelectionToClipboard(); 76513afa642SPhil Greenway break; 7666163f333SKarsten Heimrich 7676db01936SAxel Dörfler case MSG_SELECTION_MODE: 768cf0d8308SStephan Aßmus { 769cf0d8308SStephan Aßmus bool selectionMode = _ToggleMenuItem(MSG_SELECTION_MODE); 770cf0d8308SStephan Aßmus fImageView->SetSelectionMode(selectionMode); 771cf0d8308SStephan Aßmus if (!selectionMode) 772cf0d8308SStephan Aßmus fImageView->ClearSelection(); 7736db01936SAxel Dörfler break; 774cf0d8308SStephan Aßmus } 7756db01936SAxel Dörfler 77613afa642SPhil Greenway case MSG_CLEAR_SELECT: 777d3046f7dSMichael Pfeiffer fImageView->ClearSelection(); 77813afa642SPhil Greenway break; 7796163f333SKarsten Heimrich 78013afa642SPhil Greenway case MSG_SELECT_ALL: 781d3046f7dSMichael Pfeiffer fImageView->SelectAll(); 78213afa642SPhil Greenway break; 78313afa642SPhil Greenway 78403839579SMatthew Wilber case MSG_PAGE_FIRST: 785b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.FirstPage()) 786b9767a83SAxel Dörfler _LoadImage(); 78703839579SMatthew Wilber break; 78803839579SMatthew Wilber 78903839579SMatthew Wilber case MSG_PAGE_LAST: 790b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.LastPage()) 791b9767a83SAxel Dörfler _LoadImage(); 79203839579SMatthew Wilber break; 79303839579SMatthew Wilber 79403839579SMatthew Wilber case MSG_PAGE_NEXT: 795b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextPage()) 796b9767a83SAxel Dörfler _LoadImage(); 79703839579SMatthew Wilber break; 79803839579SMatthew Wilber 79903839579SMatthew Wilber case MSG_PAGE_PREV: 800b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousPage()) 801b9767a83SAxel Dörfler _LoadImage(); 80203839579SMatthew Wilber break; 80303839579SMatthew Wilber 804cd6b5cdeSAxel Dörfler case MSG_GOTO_PAGE: 805cd6b5cdeSAxel Dörfler { 806fd952aefSRyan Leavengood if (!_ClosePrompt()) 807ee7b4f39SMatthew Wilber break; 808ee7b4f39SMatthew Wilber 8096163f333SKarsten Heimrich int32 newPage; 8106163f333SKarsten Heimrich if (message->FindInt32("page", &newPage) != B_OK) 8116163f333SKarsten Heimrich break; 8126163f333SKarsten Heimrich 813cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 814cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 8156c305411SMatthew Wilber 816b9767a83SAxel Dörfler // TODO: use radio mode instead! 8176c305411SMatthew Wilber if (newPage > 0 && newPage <= pages) { 818cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 819cd6b5cdeSAxel Dörfler BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1); 820cd6b5cdeSAxel Dörfler if (currentItem != NULL && newItem != NULL) { 821cd6b5cdeSAxel Dörfler currentItem->SetMarked(false); 822cd6b5cdeSAxel Dörfler newItem->SetMarked(true); 823b9767a83SAxel Dörfler if (fNavigator.GoToPage(newPage)) 824b9767a83SAxel Dörfler _LoadImage(); 8256c305411SMatthew Wilber } 8266c305411SMatthew Wilber } 827cd6b5cdeSAxel Dörfler break; 828cd6b5cdeSAxel Dörfler } 8296c305411SMatthew Wilber 830e2069723SAxel Dörfler case kMsgFitToWindow: 831e2069723SAxel Dörfler fImageView->FitToBounds(); 83219c76de4SMichael Pfeiffer break; 8336163f333SKarsten Heimrich 834e2069723SAxel Dörfler case kMsgStretchToWindow: 835e2069723SAxel Dörfler fImageView->SetStretchToBounds( 836e2069723SAxel Dörfler _ToggleMenuItem(kMsgStretchToWindow)); 8377eca0987SMichael Pfeiffer break; 8387eca0987SMichael Pfeiffer 8397eca0987SMichael Pfeiffer case MSG_FILE_PREV: 840b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousFile()) 841a569816bSAxel Dörfler _LoadImage(false); 8427eca0987SMichael Pfeiffer break; 8437eca0987SMichael Pfeiffer 8447eca0987SMichael Pfeiffer case MSG_FILE_NEXT: 8454aa63633SAxel Dörfler case kMsgNextSlide: 846b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextFile()) 847b9767a83SAxel Dörfler _LoadImage(); 84813afa642SPhil Greenway break; 84913afa642SPhil Greenway 850328932acSAxel Dörfler case kMsgDeleteCurrentFile: 851b9767a83SAxel Dörfler { 852b9767a83SAxel Dörfler if (fNavigator.MoveFileToTrash()) 853b9767a83SAxel Dörfler _LoadImage(); 854b9767a83SAxel Dörfler else 855328932acSAxel Dörfler PostMessage(B_QUIT_REQUESTED); 856328932acSAxel Dörfler break; 857b9767a83SAxel Dörfler } 858328932acSAxel Dörfler 859bf461dbeSMatthew Wilber case MSG_ROTATE_90: 860d3046f7dSMichael Pfeiffer fImageView->Rotate(90); 861ad13f387SMichael Pfeiffer break; 8626163f333SKarsten Heimrich 863bf461dbeSMatthew Wilber case MSG_ROTATE_270: 864d3046f7dSMichael Pfeiffer fImageView->Rotate(270); 865ad13f387SMichael Pfeiffer break; 8666163f333SKarsten Heimrich 86769eee339SRyan Leavengood case MSG_FLIP_LEFT_TO_RIGHT: 86861ddc257SRyan Leavengood fImageView->Flip(true); 869ad13f387SMichael Pfeiffer break; 8706163f333SKarsten Heimrich 87169eee339SRyan Leavengood case MSG_FLIP_TOP_TO_BOTTOM: 87261ddc257SRyan Leavengood fImageView->Flip(false); 873ad13f387SMichael Pfeiffer break; 8746163f333SKarsten Heimrich 8751076d97bSAxel Dörfler case MSG_SLIDE_SHOW: 8761076d97bSAxel Dörfler { 87794fd9498SStephan Aßmus bool fullScreen = false; 87894fd9498SStephan Aßmus message->FindBool("full screen", &fullScreen); 879a877c0e7SStephan Aßmus 8806163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(message->what); 8814aa63633SAxel Dörfler if (item == NULL) 882ee7b4f39SMatthew Wilber break; 8834aa63633SAxel Dörfler 884ee7b4f39SMatthew Wilber if (item->IsMarked()) { 885ee7b4f39SMatthew Wilber item->SetMarked(false); 8864aa63633SAxel Dörfler _StopSlideShow(); 88794a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false); 888fd952aefSRyan Leavengood } else if (_ClosePrompt()) { 889ee7b4f39SMatthew Wilber item->SetMarked(true); 89094fd9498SStephan Aßmus if (!fFullScreen && fullScreen) 89194fd9498SStephan Aßmus _ToggleFullScreen(); 8924aa63633SAxel Dörfler _StartSlideShow(); 89394a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, true); 894ad13f387SMichael Pfeiffer } 8951076d97bSAxel Dörfler break; 8961076d97bSAxel Dörfler } 897ee7b4f39SMatthew Wilber 8984aa63633SAxel Dörfler case kMsgStopSlideShow: 8994aa63633SAxel Dörfler { 9004aa63633SAxel Dörfler BMenuItem* item = fBar->FindItem(MSG_SLIDE_SHOW); 9014aa63633SAxel Dörfler if (item != NULL) 9024aa63633SAxel Dörfler item->SetMarked(false); 9034aa63633SAxel Dörfler 9044aa63633SAxel Dörfler _StopSlideShow(); 90594a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false); 9064aa63633SAxel Dörfler break; 9074aa63633SAxel Dörfler } 9084aa63633SAxel Dörfler 9091076d97bSAxel Dörfler case MSG_SLIDE_SHOW_DELAY: 9101076d97bSAxel Dörfler { 9114aa63633SAxel Dörfler bigtime_t delay; 9124aa63633SAxel Dörfler if (message->FindInt64("delay", &delay) == B_OK) { 9134aa63633SAxel Dörfler _SetSlideShowDelay(delay); 914da87390fSMichael Pfeiffer // in case message is sent from popup menu 9154aa63633SAxel Dörfler _MarkSlideShowDelay(delay); 916ad13f387SMichael Pfeiffer } 9171076d97bSAxel Dörfler break; 9181076d97bSAxel Dörfler } 919ad13f387SMichael Pfeiffer 920ad13f387SMichael Pfeiffer case MSG_FULL_SCREEN: 921fd952aefSRyan Leavengood _ToggleFullScreen(); 922ad13f387SMichael Pfeiffer break; 9236163f333SKarsten Heimrich 924fc5ca95dSStephan Aßmus case MSG_EXIT_FULL_SCREEN: 925fc5ca95dSStephan Aßmus if (fFullScreen) 926fd952aefSRyan Leavengood _ToggleFullScreen(); 927fc5ca95dSStephan Aßmus break; 9286163f333SKarsten Heimrich 929cf0d8308SStephan Aßmus case MSG_SHOW_CAPTION: 930cf0d8308SStephan Aßmus { 931fd952aefSRyan Leavengood fShowCaption = _ToggleMenuItem(message->what); 932efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 933efa8b4f3SAxel Dörfler 934d3046f7dSMichael Pfeiffer if (settings->Lock()) { 935d3046f7dSMichael Pfeiffer settings->SetBool("ShowCaption", fShowCaption); 936d3046f7dSMichael Pfeiffer settings->Unlock(); 937d3046f7dSMichael Pfeiffer } 938efa8b4f3SAxel Dörfler if (fFullScreen) 939d3046f7dSMichael Pfeiffer fImageView->SetShowCaption(fShowCaption); 9406163f333SKarsten Heimrich } break; 941ad13f387SMichael Pfeiffer 942780d8a62SMichael Pfeiffer case MSG_PAGE_SETUP: 943fd952aefSRyan Leavengood _PageSetup(); 944780d8a62SMichael Pfeiffer break; 9456163f333SKarsten Heimrich 946780d8a62SMichael Pfeiffer case MSG_PREPARE_PRINT: 947fd952aefSRyan Leavengood _PrepareForPrint(); 948780d8a62SMichael Pfeiffer break; 9496163f333SKarsten Heimrich 950780d8a62SMichael Pfeiffer case MSG_PRINT: 951fd952aefSRyan Leavengood _Print(message); 952780d8a62SMichael Pfeiffer break; 953780d8a62SMichael Pfeiffer 954780d8a62SMichael Pfeiffer case MSG_ZOOM_IN: 955d3046f7dSMichael Pfeiffer fImageView->ZoomIn(); 956780d8a62SMichael Pfeiffer break; 9576163f333SKarsten Heimrich 958780d8a62SMichael Pfeiffer case MSG_ZOOM_OUT: 959d3046f7dSMichael Pfeiffer fImageView->ZoomOut(); 960780d8a62SMichael Pfeiffer break; 9616163f333SKarsten Heimrich 962cae52eadSJanus case MSG_UPDATE_STATUS_ZOOM: 963cae52eadSJanus fStatusView->SetZoom(fImageView->Zoom()); 964cae52eadSJanus break; 965cae52eadSJanus 966e2069723SAxel Dörfler case kMsgOriginalSize: 9678073fcbbSAdrien Destugues if (message->FindInt32("behavior") == BButton::B_TOGGLE_BEHAVIOR) { 9688073fcbbSAdrien Destugues bool force = (message->FindInt32("be:value") == B_CONTROL_ON); 969554e2073SAdrien Destugues fImageView->ForceOriginalSize(force); 970554e2073SAdrien Destugues if (!force) 971554e2073SAdrien Destugues break; 972554e2073SAdrien Destugues } 9734fd570d3SAxel Dörfler fImageView->SetZoom(1.0); 974780d8a62SMichael Pfeiffer break; 9756163f333SKarsten Heimrich 97681b9c776SMichael Pfeiffer case MSG_SCALE_BILINEAR: 977fd952aefSRyan Leavengood fImageView->SetScaleBilinear(_ToggleMenuItem(message->what)); 97881b9c776SMichael Pfeiffer break; 979780d8a62SMichael Pfeiffer 980cd6b5cdeSAxel Dörfler case MSG_DESKTOP_BACKGROUND: 981cd6b5cdeSAxel Dörfler { 9829617074cSRyan Leavengood BMessage backgroundsMessage(B_REFS_RECEIVED); 9839617074cSRyan Leavengood backgroundsMessage.AddRef("refs", fImageView->Image()); 9840a74004cSRyan Leavengood // This is used in the Backgrounds code for scaled placement 9859617074cSRyan Leavengood backgroundsMessage.AddInt32("placement", 'scpl'); 986537a273cSHumdinger be_roster->Launch("application/x-vnd.haiku-backgrounds", 987537a273cSHumdinger &backgroundsMessage); 988cd6b5cdeSAxel Dörfler break; 989cd6b5cdeSAxel Dörfler } 990a60adbf9SAxel Dörfler 9915b76e505SStephan Aßmus case MSG_SET_RATING: 9925b76e505SStephan Aßmus { 9935b76e505SStephan Aßmus int32 rating; 9945b76e505SStephan Aßmus if (message->FindInt32("rating", &rating) != B_OK) 9955b76e505SStephan Aßmus break; 9965b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_WRITE_ONLY); 9975b76e505SStephan Aßmus if (file.InitCheck() != B_OK) 9985b76e505SStephan Aßmus break; 9995b76e505SStephan Aßmus file.WriteAttr("Media:Rating", B_INT32_TYPE, 0, &rating, 10005b76e505SStephan Aßmus sizeof(rating)); 10015b76e505SStephan Aßmus _UpdateRatingMenu(); 10025b76e505SStephan Aßmus break; 10035b76e505SStephan Aßmus } 10045b76e505SStephan Aßmus 1005cf0d8308SStephan Aßmus case kMsgToggleToolBar: 1006cf0d8308SStephan Aßmus { 1007cf0d8308SStephan Aßmus fShowToolBar = _ToggleMenuItem(message->what); 100894fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar, true); 1009cf0d8308SStephan Aßmus 1010cf0d8308SStephan Aßmus ShowImageSettings* settings = my_app->Settings(); 1011cf0d8308SStephan Aßmus 1012cf0d8308SStephan Aßmus if (settings->Lock()) { 1013cf0d8308SStephan Aßmus settings->SetBool("ShowToolBar", fShowToolBar); 1014cf0d8308SStephan Aßmus settings->Unlock(); 1015cf0d8308SStephan Aßmus } 1016cf0d8308SStephan Aßmus break; 1017cf0d8308SStephan Aßmus } 101894fd9498SStephan Aßmus case kShowToolBarIfEnabled: 101994fd9498SStephan Aßmus { 102094fd9498SStephan Aßmus bool show; 102194fd9498SStephan Aßmus if (message->FindBool("show", &show) != B_OK) 102294fd9498SStephan Aßmus break; 102394fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar && show, true); 102494fd9498SStephan Aßmus break; 102594fd9498SStephan Aßmus } 102694fd9498SStephan Aßmus case kMsgSlideToolBar: 102794fd9498SStephan Aßmus { 102894fd9498SStephan Aßmus float offset; 102994fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK) { 103094a4c1c4SAugustin Cavalier fToolBar->MoveBy(0, offset); 103194fd9498SStephan Aßmus fScrollView->ResizeBy(0, -offset); 103294fd9498SStephan Aßmus fScrollView->MoveBy(0, offset); 103394fd9498SStephan Aßmus UpdateIfNeeded(); 103494fd9498SStephan Aßmus snooze(15000); 103594fd9498SStephan Aßmus } 103694fd9498SStephan Aßmus break; 103794fd9498SStephan Aßmus } 103894fd9498SStephan Aßmus case kMsgFinishSlidingToolBar: 103994fd9498SStephan Aßmus { 104094fd9498SStephan Aßmus float offset; 104194fd9498SStephan Aßmus bool show; 104294fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK 104394fd9498SStephan Aßmus && message->FindBool("show", &show) == B_OK) { 104494fd9498SStephan Aßmus // Compensate rounding errors with the final placement 104594a4c1c4SAugustin Cavalier fToolBar->MoveTo(fToolBar->Frame().left, offset); 104695667008SJanus if (!show) 104794a4c1c4SAugustin Cavalier fToolBar->Hide(); 104894a4c1c4SAugustin Cavalier BRect frame = fToolBar->Parent()->Bounds(); 104994a4c1c4SAugustin Cavalier frame.top = fToolBar->Frame().bottom + 1; 10502804cb33SRyan Leavengood fScrollView->MoveTo(fScrollView->Frame().left, frame.top); 105194fd9498SStephan Aßmus fScrollView->ResizeTo(fScrollView->Bounds().Width(), 1052cae52eadSJanus frame.Height() + 1); 105394fd9498SStephan Aßmus } 105494fd9498SStephan Aßmus break; 105594fd9498SStephan Aßmus } 1056cf0d8308SStephan Aßmus 105713afa642SPhil Greenway default: 1058efa8b4f3SAxel Dörfler BWindow::MessageReceived(message); 105913afa642SPhil Greenway break; 106013afa642SPhil Greenway } 106113afa642SPhil Greenway } 1062fc0a275bSMatthew Wilber 1063efa8b4f3SAxel Dörfler 1064fc0a275bSMatthew Wilber void 1065cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message) 1066cd6b5cdeSAxel Dörfler { 1067baa27ccbSJanus BString frameText; 1068cd6b5cdeSAxel Dörfler if (fImageView->Bitmap() != NULL) { 1069cd6b5cdeSAxel Dörfler BRect bounds = fImageView->Bitmap()->Bounds(); 1070baa27ccbSJanus frameText << bounds.IntegerWidth() + 1 1071cae52eadSJanus << "x" << bounds.IntegerHeight() + 1; 1072cd6b5cdeSAxel Dörfler } 1073baa27ccbSJanus BString pages; 1074baa27ccbSJanus if (fNavigator.PageCount() > 1) 1075baa27ccbSJanus pages << fNavigator.CurrentPage() << "/" << fNavigator.PageCount(); 1076baa27ccbSJanus fStatusView->Update(fNavigator.CurrentRef(), frameText, pages, fImageType, 1077cae52eadSJanus fImageView->Zoom()); 1078cd6b5cdeSAxel Dörfler } 1079cd6b5cdeSAxel Dörfler 1080cd6b5cdeSAxel Dörfler 1081cd6b5cdeSAxel Dörfler void 1082cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref) 1083cd6b5cdeSAxel Dörfler { 1084cd6b5cdeSAxel Dörfler // TODO: give a better error message! 1085560ff447SJonas Sundström BAlert* alert = new BAlert(B_TRANSLATE_SYSTEM_NAME("ShowImage"), 1086546208a5SOliver Tappe B_TRANSLATE_CONTEXT("Could not load image! Either the " 1087ddcb5a2cSAxel Dörfler "file or an image translator for it does not exist.", 1088ddcb5a2cSAxel Dörfler "LoadAlerts"), 1089546208a5SOliver Tappe B_TRANSLATE_CONTEXT("OK", "Alerts"), NULL, NULL, 10905df9097aSJohn Scipione B_WIDTH_AS_USUAL, B_STOP_ALERT); 1091aed35104SHumdinger alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 1092cd6b5cdeSAxel Dörfler alert->Go(); 1093cd6b5cdeSAxel Dörfler } 1094cd6b5cdeSAxel Dörfler 1095cd6b5cdeSAxel Dörfler 1096cd6b5cdeSAxel Dörfler void 1097fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message) 1098fc0a275bSMatthew Wilber { 1099cdb89ebbSMatthew Wilber // Read the translator and output type the user chose 1100cdb89ebbSMatthew Wilber translator_id outTranslator; 1101cdb89ebbSMatthew Wilber uint32 outType; 11026163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 1103efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 11046163f333SKarsten Heimrich || message->FindInt32(kTypeField, 1105cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 1106fc0a275bSMatthew Wilber return; 1107fc0a275bSMatthew Wilber 1108cdb89ebbSMatthew Wilber // Add the chosen translator and output type to the 1109cdb89ebbSMatthew Wilber // message that the save panel will send back 1110c1a10c14SKarsten Heimrich BMessage panelMsg(MSG_SAVE_PANEL); 1111c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTranslatorField, outTranslator); 1112c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTypeField, outType); 1113cdb89ebbSMatthew Wilber 1114cdb89ebbSMatthew Wilber // Create save panel and show it 11156163f333SKarsten Heimrich BMessenger target(this); 1116efa8b4f3SAxel Dörfler fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL, 1117c1a10c14SKarsten Heimrich &target, NULL, 0, false, &panelMsg); 1118d3046f7dSMichael Pfeiffer if (!fSavePanel) 1119fc0a275bSMatthew Wilber return; 1120a60adbf9SAxel Dörfler 11213000afd7SJanus // Retrieve save directory from settings; 11223000afd7SJanus ShowImageSettings* settings = my_app->Settings(); 11233000afd7SJanus if (settings->Lock()) { 11243000afd7SJanus fSavePanel->SetPanelDirectory( 11253000afd7SJanus settings->GetString("SaveDirectory", NULL)); 11263000afd7SJanus settings->Unlock(); 11273000afd7SJanus } 11283000afd7SJanus 1129d3046f7dSMichael Pfeiffer fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE); 1130d3046f7dSMichael Pfeiffer fSavePanel->Show(); 1131fc0a275bSMatthew Wilber } 1132fc0a275bSMatthew Wilber 1133efa8b4f3SAxel Dörfler 1134fc0a275bSMatthew Wilber void 1135fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message) 1136fc0a275bSMatthew Wilber { 1137cdb89ebbSMatthew Wilber // Read in where the file should be saved 1138efa8b4f3SAxel Dörfler entry_ref dirRef; 1139efa8b4f3SAxel Dörfler if (message->FindRef("directory", &dirRef) != B_OK) 1140fc0a275bSMatthew Wilber return; 1141efa8b4f3SAxel Dörfler 1142fc0a275bSMatthew Wilber const char* filename; 1143efa8b4f3SAxel Dörfler if (message->FindString("name", &filename) != B_OK) 1144fc0a275bSMatthew Wilber return; 1145fc0a275bSMatthew Wilber 1146cdb89ebbSMatthew Wilber // Read in the translator and type to be used 1147cdb89ebbSMatthew Wilber // to save the output image 1148cdb89ebbSMatthew Wilber translator_id outTranslator; 1149cdb89ebbSMatthew Wilber uint32 outType; 11506163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 1151efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 11526163f333SKarsten Heimrich || message->FindInt32(kTypeField, 1153cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 1154cdb89ebbSMatthew Wilber return; 1155cdb89ebbSMatthew Wilber 1156a7e78e3bSMatthew Wilber // Find the translator_format information needed to 1157a7e78e3bSMatthew Wilber // write a MIME attribute for the image file 1158a7e78e3bSMatthew Wilber BTranslatorRoster* roster = BTranslatorRoster::Default(); 1159efa8b4f3SAxel Dörfler const translation_format* outFormat = NULL; 1160efa8b4f3SAxel Dörfler int32 outCount = 0; 1161efa8b4f3SAxel Dörfler if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK 1162efa8b4f3SAxel Dörfler || outCount < 1) 1163a7e78e3bSMatthew Wilber return; 1164efa8b4f3SAxel Dörfler 1165a7e78e3bSMatthew Wilber int32 i; 1166efa8b4f3SAxel Dörfler for (i = 0; i < outCount; i++) { 1167537a273cSHumdinger if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type 1168537a273cSHumdinger == outType) 1169a7e78e3bSMatthew Wilber break; 1170a7e78e3bSMatthew Wilber } 1171efa8b4f3SAxel Dörfler if (i == outCount) 1172fc0a275bSMatthew Wilber return; 1173fc0a275bSMatthew Wilber 1174a7e78e3bSMatthew Wilber // Write out the image file 1175efa8b4f3SAxel Dörfler BDirectory dir(&dirRef); 1176efa8b4f3SAxel Dörfler fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]); 11773000afd7SJanus 11783000afd7SJanus // Store Save directory in settings; 11793000afd7SJanus ShowImageSettings* settings = my_app->Settings(); 11803000afd7SJanus if (settings->Lock()) { 11813000afd7SJanus BPath path(&dirRef); 11823000afd7SJanus settings->SetString("SaveDirectory", path.Path()); 11833000afd7SJanus settings->Unlock(); 11843000afd7SJanus } 1185fc0a275bSMatthew Wilber } 1186fc0a275bSMatthew Wilber 1187efa8b4f3SAxel Dörfler 1188546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 1189546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "ClosePrompt" 11901ed4535fSStephan Aßmus 1191b9767a83SAxel Dörfler 1192cdb89ebbSMatthew Wilber bool 1193fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt() 1194ee7b4f39SMatthew Wilber { 1195ee7b4f39SMatthew Wilber if (!fModified) 1196ee7b4f39SMatthew Wilber return true; 1197efa8b4f3SAxel Dörfler 1198cd6b5cdeSAxel Dörfler int32 count = fNavigator.PageCount(); 1199cd6b5cdeSAxel Dörfler int32 page = fNavigator.CurrentPage(); 1200cd6b5cdeSAxel Dörfler BString prompt; 1201efa8b4f3SAxel Dörfler 12021ed4535fSStephan Aßmus if (count > 1) { 12031ed4535fSStephan Aßmus bs_printf(&prompt, 1204905c8c8cSMatt Madia B_TRANSLATE("The document '%s' (page %d) has been changed. Do you " 1205905c8c8cSMatt Madia "want to close the document?"), 1206cd6b5cdeSAxel Dörfler fImageView->Image()->name, page); 12071ed4535fSStephan Aßmus } else { 12081ed4535fSStephan Aßmus bs_printf(&prompt, 1209905c8c8cSMatt Madia B_TRANSLATE("The document '%s' has been changed. Do you want to " 1210905c8c8cSMatt Madia "close the document?"), 1211cd6b5cdeSAxel Dörfler fImageView->Image()->name); 12121ed4535fSStephan Aßmus } 12131ed4535fSStephan Aßmus 1214cd6b5cdeSAxel Dörfler BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(), 1215905c8c8cSMatt Madia B_TRANSLATE("Cancel"), B_TRANSLATE("Close")); 1216aed35104SHumdinger alert->SetShortcut(0, B_ESCAPE); 1217aed35104SHumdinger 1218cd6b5cdeSAxel Dörfler if (alert->Go() == 0) { 1219ee7b4f39SMatthew Wilber // Cancel 1220ee7b4f39SMatthew Wilber return false; 1221cd6b5cdeSAxel Dörfler } 1222cd6b5cdeSAxel Dörfler 1223ee7b4f39SMatthew Wilber // Close 1224187f0b8aSMatthew Wilber fModified = false; 1225ee7b4f39SMatthew Wilber return true; 1226ee7b4f39SMatthew Wilber } 1227ee7b4f39SMatthew Wilber 1228cdb89ebbSMatthew Wilber 1229b9767a83SAxel Dörfler status_t 1230a569816bSAxel Dörfler ShowImageWindow::_LoadImage(bool forward) 1231b9767a83SAxel Dörfler { 1232b9767a83SAxel Dörfler BMessenger us(this); 1233be63ec85SJanus status_t status = my_app->DefaultCache().RetrieveImage( 1234a569816bSAxel Dörfler fNavigator.CurrentRef(), fNavigator.CurrentPage(), &us); 1235a569816bSAxel Dörfler if (status != B_OK) 1236a569816bSAxel Dörfler return status; 1237a569816bSAxel Dörfler 1238e2069723SAxel Dörfler fProgressWindow->Start(this); 1239e2069723SAxel Dörfler 1240a569816bSAxel Dörfler // Preload previous/next images - two in the navigation direction, one 1241a569816bSAxel Dörfler // in the opposite direction. 1242a569816bSAxel Dörfler 1243a569816bSAxel Dörfler entry_ref nextRef = fNavigator.CurrentRef(); 1244a569816bSAxel Dörfler if (_PreloadImage(forward, nextRef)) 1245a569816bSAxel Dörfler _PreloadImage(forward, nextRef); 1246a569816bSAxel Dörfler 1247a569816bSAxel Dörfler entry_ref previousRef = fNavigator.CurrentRef(); 1248a569816bSAxel Dörfler _PreloadImage(!forward, previousRef); 1249a569816bSAxel Dörfler 1250a569816bSAxel Dörfler return B_OK; 1251a569816bSAxel Dörfler } 1252a569816bSAxel Dörfler 1253a569816bSAxel Dörfler 1254a569816bSAxel Dörfler bool 1255a569816bSAxel Dörfler ShowImageWindow::_PreloadImage(bool forward, entry_ref& ref) 1256a569816bSAxel Dörfler { 1257a569816bSAxel Dörfler entry_ref currentRef = ref; 1258a569816bSAxel Dörfler if ((forward && !fNavigator.GetNextFile(currentRef, ref)) 1259a569816bSAxel Dörfler || (!forward && !fNavigator.GetPreviousFile(currentRef, ref))) 1260a569816bSAxel Dörfler return false; 1261a569816bSAxel Dörfler 1262be63ec85SJanus return my_app->DefaultCache().RetrieveImage(ref) == B_OK; 1263b9767a83SAxel Dörfler } 1264b9767a83SAxel Dörfler 1265b9767a83SAxel Dörfler 1266ad13f387SMichael Pfeiffer void 1267fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen() 1268ad13f387SMichael Pfeiffer { 1269ad13f387SMichael Pfeiffer BRect frame; 1270ad13f387SMichael Pfeiffer fFullScreen = !fFullScreen; 1271ad13f387SMichael Pfeiffer if (fFullScreen) { 1272ad13f387SMichael Pfeiffer BScreen screen; 1273ad13f387SMichael Pfeiffer fWindowFrame = Frame(); 1274ad13f387SMichael Pfeiffer frame = screen.Frame(); 1275d3046f7dSMichael Pfeiffer frame.top -= fBar->Bounds().Height() + 1; 127667eb2a04SHumdinger frame.right += B_V_SCROLL_BAR_WIDTH; 1277ad13f387SMichael Pfeiffer frame.bottom += B_H_SCROLL_BAR_HEIGHT; 1278ad13f387SMichael Pfeiffer 1279ad13f387SMichael Pfeiffer SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE); 1280c0b16687SAxel Dörfler 1281c0b16687SAxel Dörfler Activate(); 1282c0b16687SAxel Dörfler // make the window frontmost 1283ad13f387SMichael Pfeiffer } else { 1284ad13f387SMichael Pfeiffer frame = fWindowFrame; 1285ad13f387SMichael Pfeiffer 1286ad13f387SMichael Pfeiffer SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); 1287ad13f387SMichael Pfeiffer } 1288efa8b4f3SAxel Dörfler 128994a4c1c4SAugustin Cavalier fToolBar->SetActionVisible(MSG_FULL_SCREEN, fFullScreen); 1290cf0d8308SStephan Aßmus _SetToolBarVisible(!fFullScreen && fShowToolBar); 129160c23976SJanus _SetToolBarBorder(!fFullScreen); 1292cf0d8308SStephan Aßmus 1293ad13f387SMichael Pfeiffer MoveTo(frame.left, frame.top); 1294ad13f387SMichael Pfeiffer ResizeTo(frame.Width(), frame.Height()); 1295e2069723SAxel Dörfler 1296e2069723SAxel Dörfler fImageView->SetHideIdlingCursor(fFullScreen); 1297e2069723SAxel Dörfler fImageView->SetShowCaption(fFullScreen && fShowCaption); 1298eaa910c5SAxel Dörfler 129948ae3e38SAxel Dörfler Layout(false); 130048ae3e38SAxel Dörfler // We need to manually relayout here, as the views are layouted 130148ae3e38SAxel Dörfler // asynchronously, and FitToBounds() would still have the wrong size 1302e2069723SAxel Dörfler fImageView->FitToBounds(); 1303ad13f387SMichael Pfeiffer } 1304ad13f387SMichael Pfeiffer 1305efa8b4f3SAxel Dörfler 1306d3046f7dSMichael Pfeiffer void 13072281340dSAxel Dörfler ShowImageWindow::_ApplySettings() 1308d3046f7dSMichael Pfeiffer { 1309efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1310efa8b4f3SAxel Dörfler 1311d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1312d3046f7dSMichael Pfeiffer fShowCaption = settings->GetBool("ShowCaption", fShowCaption); 1313d3046f7dSMichael Pfeiffer fPrintOptions.SetBounds(BRect(0, 0, 1023, 767)); 1314d3046f7dSMichael Pfeiffer 13154aa63633SAxel Dörfler fSlideShowDelay = settings->GetTime("SlideShowDelay", fSlideShowDelay); 1316d3046f7dSMichael Pfeiffer 13174aa63633SAxel Dörfler fPrintOptions.SetOption((enum PrintOptions::Option)settings->GetInt32( 13184aa63633SAxel Dörfler "PO:Option", fPrintOptions.Option())); 13194aa63633SAxel Dörfler fPrintOptions.SetZoomFactor( 13204aa63633SAxel Dörfler settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor())); 13214aa63633SAxel Dörfler fPrintOptions.SetDPI(settings->GetFloat("PO:DPI", fPrintOptions.DPI())); 13224aa63633SAxel Dörfler fPrintOptions.SetWidth( 13234aa63633SAxel Dörfler settings->GetFloat("PO:Width", fPrintOptions.Width())); 13244aa63633SAxel Dörfler fPrintOptions.SetHeight( 13254aa63633SAxel Dörfler settings->GetFloat("PO:Height", fPrintOptions.Height())); 1326d3046f7dSMichael Pfeiffer 1327cf0d8308SStephan Aßmus fShowToolBar = settings->GetBool("ShowToolBar", fShowToolBar); 1328cf0d8308SStephan Aßmus 1329d3046f7dSMichael Pfeiffer settings->Unlock(); 1330d3046f7dSMichael Pfeiffer } 1331d3046f7dSMichael Pfeiffer } 1332d3046f7dSMichael Pfeiffer 1333efa8b4f3SAxel Dörfler 1334d3046f7dSMichael Pfeiffer void 1335fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions() 1336d3046f7dSMichael Pfeiffer { 1337efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1338efa8b4f3SAxel Dörfler 1339d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1340d3046f7dSMichael Pfeiffer settings->SetInt32("PO:Option", fPrintOptions.Option()); 1341d3046f7dSMichael Pfeiffer settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor()); 1342d3046f7dSMichael Pfeiffer settings->SetFloat("PO:DPI", fPrintOptions.DPI()); 1343d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Width", fPrintOptions.Width()); 1344d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Height", fPrintOptions.Height()); 1345d3046f7dSMichael Pfeiffer settings->Unlock(); 1346d3046f7dSMichael Pfeiffer } 1347d3046f7dSMichael Pfeiffer } 1348d3046f7dSMichael Pfeiffer 1349efa8b4f3SAxel Dörfler 1350cdb89ebbSMatthew Wilber bool 1351fd952aefSRyan Leavengood ShowImageWindow::_PageSetup() 1352780d8a62SMichael Pfeiffer { 1353cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 1354efa8b4f3SAxel Dörfler if (fPrintSettings != NULL) 1355780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 1356efa8b4f3SAxel Dörfler 13576163f333SKarsten Heimrich status_t status = printJob.ConfigPage(); 13586163f333SKarsten Heimrich if (status == B_OK) { 1359780d8a62SMichael Pfeiffer delete fPrintSettings; 1360780d8a62SMichael Pfeiffer fPrintSettings = printJob.Settings(); 1361780d8a62SMichael Pfeiffer } 1362efa8b4f3SAxel Dörfler 13636163f333SKarsten Heimrich return status == B_OK; 1364780d8a62SMichael Pfeiffer } 1365780d8a62SMichael Pfeiffer 1366efa8b4f3SAxel Dörfler 1367780d8a62SMichael Pfeiffer void 1368fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint() 1369780d8a62SMichael Pfeiffer { 13706163f333SKarsten Heimrich if (fPrintSettings == NULL) { 1371cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 13726163f333SKarsten Heimrich if (printJob.ConfigJob() == B_OK) 13736163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 13746163f333SKarsten Heimrich } 1375780d8a62SMichael Pfeiffer 1376cd6b5cdeSAxel Dörfler fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds()); 1377cd6b5cdeSAxel Dörfler fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1); 1378780d8a62SMichael Pfeiffer 1379efa8b4f3SAxel Dörfler new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50), 1380efa8b4f3SAxel Dörfler &fPrintOptions, this); 1381780d8a62SMichael Pfeiffer } 1382780d8a62SMichael Pfeiffer 1383efa8b4f3SAxel Dörfler 1384780d8a62SMichael Pfeiffer void 1385fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg) 1386780d8a62SMichael Pfeiffer { 1387780d8a62SMichael Pfeiffer status_t st; 1388efa8b4f3SAxel Dörfler if (msg->FindInt32("status", &st) != B_OK || st != B_OK) 1389780d8a62SMichael Pfeiffer return; 1390780d8a62SMichael Pfeiffer 1391fd952aefSRyan Leavengood _SavePrintOptions(); 1392d3046f7dSMichael Pfeiffer 1393cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 13946163f333SKarsten Heimrich if (fPrintSettings) 1395780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 13966163f333SKarsten Heimrich 1397780d8a62SMichael Pfeiffer if (printJob.ConfigJob() == B_OK) { 13986163f333SKarsten Heimrich delete fPrintSettings; 13996163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 1400780d8a62SMichael Pfeiffer 1401780d8a62SMichael Pfeiffer // first/lastPage is unused for now 14023177ae77SStefano Ceccherini int32 firstPage = printJob.FirstPage(); 14033177ae77SStefano Ceccherini int32 lastPage = printJob.LastPage(); 14046163f333SKarsten Heimrich BRect printableRect = printJob.PrintableRect(); 14056163f333SKarsten Heimrich 1406efa8b4f3SAxel Dörfler if (firstPage < 1) 1407780d8a62SMichael Pfeiffer firstPage = 1; 1408efa8b4f3SAxel Dörfler if (lastPage < firstPage) 1409780d8a62SMichael Pfeiffer lastPage = firstPage; 1410780d8a62SMichael Pfeiffer 1411cd6b5cdeSAxel Dörfler BBitmap* bitmap = fImageView->Bitmap(); 14123177ae77SStefano Ceccherini float imageWidth = bitmap->Bounds().Width() + 1.0; 14133177ae77SStefano Ceccherini float imageHeight = bitmap->Bounds().Height() + 1.0; 1414780d8a62SMichael Pfeiffer 14156163f333SKarsten Heimrich float width; 1416780d8a62SMichael Pfeiffer switch (fPrintOptions.Option()) { 14176163f333SKarsten Heimrich case PrintOptions::kFitToPage: { 14186163f333SKarsten Heimrich float w1 = printableRect.Width() + 1; 1419cd6b5cdeSAxel Dörfler float w2 = imageWidth * (printableRect.Height() + 1) 1420cd6b5cdeSAxel Dörfler / imageHeight; 1421efa8b4f3SAxel Dörfler if (w2 < w1) 1422780d8a62SMichael Pfeiffer width = w2; 1423efa8b4f3SAxel Dörfler else 1424780d8a62SMichael Pfeiffer width = w1; 14256163f333SKarsten Heimrich } break; 1426780d8a62SMichael Pfeiffer case PrintOptions::kZoomFactor: 1427780d8a62SMichael Pfeiffer width = imageWidth * fPrintOptions.ZoomFactor(); 1428780d8a62SMichael Pfeiffer break; 1429780d8a62SMichael Pfeiffer case PrintOptions::kDPI: 1430780d8a62SMichael Pfeiffer width = imageWidth * 72.0 / fPrintOptions.DPI(); 1431780d8a62SMichael Pfeiffer break; 1432780d8a62SMichael Pfeiffer case PrintOptions::kWidth: 1433780d8a62SMichael Pfeiffer case PrintOptions::kHeight: 1434780d8a62SMichael Pfeiffer width = fPrintOptions.Width(); 1435780d8a62SMichael Pfeiffer break; 1436efa8b4f3SAxel Dörfler 1437780d8a62SMichael Pfeiffer default: 1438780d8a62SMichael Pfeiffer // keep compiler silent; should not reach here 1439780d8a62SMichael Pfeiffer width = imageWidth; 1440780d8a62SMichael Pfeiffer } 1441780d8a62SMichael Pfeiffer 1442efa8b4f3SAxel Dörfler // TODO: eventually print large images on several pages 1443780d8a62SMichael Pfeiffer printJob.BeginJob(); 1444d3046f7dSMichael Pfeiffer fImageView->SetScale(width / imageWidth); 14455eb50e46SMichael Pfeiffer // coordinates are relative to printable rectangle 14465eb50e46SMichael Pfeiffer BRect bounds(bitmap->Bounds()); 14475eb50e46SMichael Pfeiffer printJob.DrawView(fImageView, bounds, BPoint(0, 0)); 1448d3046f7dSMichael Pfeiffer fImageView->SetScale(1.0); 1449780d8a62SMichael Pfeiffer printJob.SpoolPage(); 1450780d8a62SMichael Pfeiffer printJob.CommitJob(); 1451780d8a62SMichael Pfeiffer } 1452780d8a62SMichael Pfeiffer } 1453780d8a62SMichael Pfeiffer 145456b0c7b9SKarsten Heimrich 14554aa63633SAxel Dörfler void 14564aa63633SAxel Dörfler ShowImageWindow::_SetSlideShowDelay(bigtime_t delay) 14574aa63633SAxel Dörfler { 14584aa63633SAxel Dörfler if (fSlideShowDelay == delay) 14594aa63633SAxel Dörfler return; 14604aa63633SAxel Dörfler 14614aa63633SAxel Dörfler fSlideShowDelay = delay; 14624aa63633SAxel Dörfler 14634aa63633SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 14644aa63633SAxel Dörfler if (settings->Lock()) { 14654aa63633SAxel Dörfler settings->SetTime("SlideShowDelay", fSlideShowDelay); 14664aa63633SAxel Dörfler settings->Unlock(); 14674aa63633SAxel Dörfler } 14684aa63633SAxel Dörfler 14694aa63633SAxel Dörfler if (fSlideShowRunner != NULL) 14704aa63633SAxel Dörfler _StartSlideShow(); 14714aa63633SAxel Dörfler } 14724aa63633SAxel Dörfler 14734aa63633SAxel Dörfler 14744aa63633SAxel Dörfler void 14754aa63633SAxel Dörfler ShowImageWindow::_StartSlideShow() 14764aa63633SAxel Dörfler { 14774aa63633SAxel Dörfler _StopSlideShow(); 14784aa63633SAxel Dörfler 14794aa63633SAxel Dörfler BMessage nextSlide(kMsgNextSlide); 14804aa63633SAxel Dörfler fSlideShowRunner = new BMessageRunner(this, &nextSlide, fSlideShowDelay); 14814aa63633SAxel Dörfler } 14824aa63633SAxel Dörfler 14834aa63633SAxel Dörfler 14844aa63633SAxel Dörfler void 14854aa63633SAxel Dörfler ShowImageWindow::_StopSlideShow() 14864aa63633SAxel Dörfler { 14874aa63633SAxel Dörfler if (fSlideShowRunner != NULL) { 14884aa63633SAxel Dörfler delete fSlideShowRunner; 14894aa63633SAxel Dörfler fSlideShowRunner = NULL; 14904aa63633SAxel Dörfler } 14914aa63633SAxel Dörfler } 14924aa63633SAxel Dörfler 14934aa63633SAxel Dörfler 14945b76e505SStephan Aßmus void 14955b76e505SStephan Aßmus ShowImageWindow::_UpdateRatingMenu() 14965b76e505SStephan Aßmus { 14975b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_READ_ONLY); 14985b76e505SStephan Aßmus if (file.InitCheck() != B_OK) 14995b76e505SStephan Aßmus return; 15005b76e505SStephan Aßmus int32 rating; 15015b76e505SStephan Aßmus ssize_t size = sizeof(rating); 15025b76e505SStephan Aßmus if (file.ReadAttr("Media:Rating", B_INT32_TYPE, 0, &rating, size) != size) 15035b76e505SStephan Aßmus rating = 0; 15045b76e505SStephan Aßmus // TODO: Finding the correct item could be more robust, like by looking 15055b76e505SStephan Aßmus // at the message of each item. 15065b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) { 15075b76e505SStephan Aßmus BMenuItem* item = fRatingMenu->ItemAt(i - 1); 15085b76e505SStephan Aßmus if (item == NULL) 15095b76e505SStephan Aßmus break; 15105b76e505SStephan Aßmus item->SetMarked(i == rating); 15115b76e505SStephan Aßmus } 15125b76e505SStephan Aßmus } 15135b76e505SStephan Aßmus 15145b76e505SStephan Aßmus 1515cf0d8308SStephan Aßmus void 1516e62a6973SJanus ShowImageWindow::_SaveWidthAndHeight() 1517e62a6973SJanus { 1518e62a6973SJanus if (fNavigator.CurrentPage() != 1) 1519e62a6973SJanus return; 1520e62a6973SJanus 1521e62a6973SJanus if (fImageView->Bitmap() == NULL) 1522e62a6973SJanus return; 1523e62a6973SJanus 1524e62a6973SJanus BRect bounds = fImageView->Bitmap()->Bounds(); 1525c1994be8SJanus int32 width = bounds.IntegerWidth() + 1; 1526c1994be8SJanus int32 height = bounds.IntegerHeight() + 1; 1527e62a6973SJanus 15289c1f5f4dSJanus BNode node(&fNavigator.CurrentRef()); 15299c1f5f4dSJanus if (node.InitCheck() != B_OK) 1530e62a6973SJanus return; 1531e62a6973SJanus 15329c1f5f4dSJanus const char* kWidthAttrName = "Media:Width"; 15339c1f5f4dSJanus const char* kHeightAttrName = "Media:Height"; 15349c1f5f4dSJanus 15359c1f5f4dSJanus int32 widthAttr; 1536b41cdcb3SJanus ssize_t attrSize = node.ReadAttr(kWidthAttrName, B_INT32_TYPE, 0, 1537b41cdcb3SJanus &widthAttr, sizeof(widthAttr)); 15389c1f5f4dSJanus if (attrSize <= 0 || widthAttr != width) 15399c1f5f4dSJanus node.WriteAttr(kWidthAttrName, B_INT32_TYPE, 0, &width, sizeof(width)); 15409c1f5f4dSJanus 15419c1f5f4dSJanus int32 heightAttr; 1542b41cdcb3SJanus attrSize = node.ReadAttr(kHeightAttrName, B_INT32_TYPE, 0, 1543b41cdcb3SJanus &heightAttr, sizeof(heightAttr)); 15449c1f5f4dSJanus if (attrSize <= 0 || heightAttr != height) 15459c1f5f4dSJanus node.WriteAttr(kHeightAttrName, B_INT32_TYPE, 0, &height, sizeof(height)); 1546e62a6973SJanus } 1547e62a6973SJanus 1548e62a6973SJanus 1549e62a6973SJanus void 155094fd9498SStephan Aßmus ShowImageWindow::_SetToolBarVisible(bool visible, bool animate) 1551cf0d8308SStephan Aßmus { 155295667008SJanus if (visible == fToolBarVisible) 1553cf0d8308SStephan Aßmus return; 1554cf0d8308SStephan Aßmus 155595667008SJanus fToolBarVisible = visible; 155694a4c1c4SAugustin Cavalier float diff = fToolBar->Bounds().Height() + 2; 155794fd9498SStephan Aßmus if (!visible) 1558cf0d8308SStephan Aßmus diff = -diff; 155994fd9498SStephan Aßmus else 156094a4c1c4SAugustin Cavalier fToolBar->Show(); 1561cf0d8308SStephan Aßmus 156294fd9498SStephan Aßmus if (animate) { 156394fd9498SStephan Aßmus // Slide the controls into view. We do this with messages in order 156494fd9498SStephan Aßmus // not to block the window thread. 156594fd9498SStephan Aßmus const float kAnimationOffsets[] = { 0.05, 0.2, 0.5, 0.2, 0.05 }; 156694fd9498SStephan Aßmus const int32 steps = sizeof(kAnimationOffsets) / sizeof(float); 156794fd9498SStephan Aßmus for (int32 i = 0; i < steps; i++) { 156894fd9498SStephan Aßmus BMessage message(kMsgSlideToolBar); 156994fd9498SStephan Aßmus message.AddFloat("offset", floorf(diff * kAnimationOffsets[i])); 157094fd9498SStephan Aßmus PostMessage(&message, this); 157194fd9498SStephan Aßmus } 157294fd9498SStephan Aßmus BMessage finalMessage(kMsgFinishSlidingToolBar); 157395667008SJanus finalMessage.AddFloat("offset", visible ? 0 : diff); 157494fd9498SStephan Aßmus finalMessage.AddBool("show", visible); 157594fd9498SStephan Aßmus PostMessage(&finalMessage, this); 157694fd9498SStephan Aßmus } else { 1577cf0d8308SStephan Aßmus fScrollView->ResizeBy(0, -diff); 1578cf0d8308SStephan Aßmus fScrollView->MoveBy(0, diff); 157994a4c1c4SAugustin Cavalier fToolBar->MoveBy(0, diff); 158094fd9498SStephan Aßmus if (!visible) 158194a4c1c4SAugustin Cavalier fToolBar->Hide(); 158294fd9498SStephan Aßmus } 1583cf0d8308SStephan Aßmus } 1584cf0d8308SStephan Aßmus 1585cf0d8308SStephan Aßmus 158660c23976SJanus void 158760c23976SJanus ShowImageWindow::_SetToolBarBorder(bool visible) 158860c23976SJanus { 158960c23976SJanus float inset = visible 159060c23976SJanus ? ceilf(be_control_look->DefaultItemSpacing() / 2) : 0; 159160c23976SJanus 159260c23976SJanus fToolBar->GroupLayout()->SetInsets(inset, 0, inset, 0); 159360c23976SJanus } 159460c23976SJanus 159560c23976SJanus 1596780d8a62SMichael Pfeiffer bool 1597cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested() 1598cdb89ebbSMatthew Wilber { 1599efa8b4f3SAxel Dörfler if (fSavePanel) { 1600efa8b4f3SAxel Dörfler // Don't allow this window to be closed if a save panel is open 1601efa8b4f3SAxel Dörfler return false; 1602cdb89ebbSMatthew Wilber } 1603cdb89ebbSMatthew Wilber 16045b76e505SStephan Aßmus if (!_ClosePrompt()) 16055b76e505SStephan Aßmus return false; 16065b76e505SStephan Aßmus 16075b76e505SStephan Aßmus ShowImageSettings* settings = my_app->Settings(); 16085b76e505SStephan Aßmus if (settings->Lock()) { 1609c418e2beSStephan Aßmus if (fFullScreen) 1610c418e2beSStephan Aßmus settings->SetRect("WindowFrame", fWindowFrame); 1611c418e2beSStephan Aßmus else 16125b76e505SStephan Aßmus settings->SetRect("WindowFrame", Frame()); 16135b76e505SStephan Aßmus settings->Unlock(); 16145b76e505SStephan Aßmus } 16155b76e505SStephan Aßmus 16165b76e505SStephan Aßmus be_app->PostMessage(MSG_WINDOW_HAS_QUIT); 16175b76e505SStephan Aßmus 16185b76e505SStephan Aßmus return true; 1619efa8b4f3SAxel Dörfler } 1620