1efa8b4f3SAxel Dörfler /* 24aa63633SAxel Dörfler * Copyright 2003-2011, 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> 281ed4535fSStephan Aßmus #include <Catalog.h> 29efa8b4f3SAxel Dörfler #include <Clipboard.h> 3013afa642SPhil Greenway #include <Entry.h> 31fc0a275bSMatthew Wilber #include <File.h> 326163f333SKarsten Heimrich #include <FilePanel.h> 331ed4535fSStephan Aßmus #include <Locale.h> 3413afa642SPhil Greenway #include <Menu.h> 3513afa642SPhil Greenway #include <MenuBar.h> 3613afa642SPhil Greenway #include <MenuItem.h> 374aa63633SAxel Dörfler #include <MessageRunner.h> 3813afa642SPhil Greenway #include <Path.h> 39efa8b4f3SAxel Dörfler #include <PrintJob.h> 4036272f0dSAxel Dörfler #include <RecentItems.h> 41efa8b4f3SAxel Dörfler #include <Roster.h> 42efa8b4f3SAxel Dörfler #include <Screen.h> 4313afa642SPhil Greenway #include <ScrollView.h> 446163f333SKarsten Heimrich #include <String.h> 45efa8b4f3SAxel Dörfler #include <SupportDefs.h> 466163f333SKarsten Heimrich #include <TranslationDefs.h> 4713afa642SPhil Greenway #include <TranslationUtils.h> 4813afa642SPhil Greenway #include <TranslatorRoster.h> 4913afa642SPhil Greenway 50b9767a83SAxel Dörfler #include "ImageCache.h" 51e2069723SAxel Dörfler #include "ProgressWindow.h" 52fd952aefSRyan Leavengood #include "ShowImageApp.h" 53fd952aefSRyan Leavengood #include "ShowImageConstants.h" 54fd952aefSRyan Leavengood #include "ShowImageStatusView.h" 55fd952aefSRyan Leavengood #include "ShowImageView.h" 56cf0d8308SStephan Aßmus #include "ToolBarIcons.h" 57cf0d8308SStephan Aßmus #include "ToolBarView.h" 5813afa642SPhil Greenway 59a8fc7138SMichael Pfeiffer 60cd6b5cdeSAxel Dörfler // BMessage field names used in Save messages 61cd6b5cdeSAxel Dörfler const char* kTypeField = "be:type"; 62cd6b5cdeSAxel Dörfler const char* kTranslatorField = "be:translator"; 63cd6b5cdeSAxel Dörfler 644aa63633SAxel Dörfler const bigtime_t kDefaultSlideShowDelay = 3000000; 654aa63633SAxel Dörfler // 3 seconds 664aa63633SAxel Dörfler 67cd6b5cdeSAxel Dörfler 68e2069723SAxel Dörfler // message constants 69e2069723SAxel Dörfler enum { 70e2069723SAxel Dörfler MSG_CAPTURE_MOUSE = 'mCPM', 71e2069723SAxel Dörfler MSG_CHANGE_FOCUS = 'mCFS', 72e2069723SAxel Dörfler MSG_WINDOW_QUIT = 'mWQT', 73e2069723SAxel Dörfler MSG_OUTPUT_TYPE = 'BTMN', 74e2069723SAxel Dörfler MSG_SAVE_PANEL = 'mFSP', 75e2069723SAxel Dörfler MSG_CLEAR_SELECT = 'mCSL', 76e2069723SAxel Dörfler MSG_SELECT_ALL = 'mSAL', 77e2069723SAxel Dörfler MSG_SELECTION_MODE = 'mSLM', 78e2069723SAxel Dörfler MSG_PAGE_FIRST = 'mPGF', 79e2069723SAxel Dörfler MSG_PAGE_LAST = 'mPGL', 80e2069723SAxel Dörfler MSG_PAGE_NEXT = 'mPGN', 81e2069723SAxel Dörfler MSG_PAGE_PREV = 'mPGP', 82e2069723SAxel Dörfler MSG_GOTO_PAGE = 'mGTP', 83e2069723SAxel Dörfler MSG_ZOOM_IN = 'mZIN', 84e2069723SAxel Dörfler MSG_ZOOM_OUT = 'mZOU', 85e2069723SAxel Dörfler MSG_SCALE_BILINEAR = 'mSBL', 86e2069723SAxel Dörfler MSG_DESKTOP_BACKGROUND = 'mDBG', 87e2069723SAxel Dörfler MSG_ROTATE_90 = 'mR90', 88e2069723SAxel Dörfler MSG_ROTATE_270 = 'mR27', 89e2069723SAxel Dörfler MSG_FLIP_LEFT_TO_RIGHT = 'mFLR', 90e2069723SAxel Dörfler MSG_FLIP_TOP_TO_BOTTOM = 'mFTB', 91e2069723SAxel Dörfler MSG_SLIDE_SHOW_DELAY = 'mSSD', 92e2069723SAxel Dörfler MSG_SHOW_CAPTION = 'mSCP', 93e2069723SAxel Dörfler MSG_PAGE_SETUP = 'mPSU', 94e2069723SAxel Dörfler MSG_PREPARE_PRINT = 'mPPT', 955b76e505SStephan Aßmus MSG_SET_RATING = 'mSRT', 96e2069723SAxel Dörfler kMsgFitToWindow = 'mFtW', 97e2069723SAxel Dörfler kMsgOriginalSize = 'mOSZ', 984aa63633SAxel Dörfler kMsgStretchToWindow = 'mStW', 99cf0d8308SStephan Aßmus kMsgNextSlide = 'mNxS', 10094fd9498SStephan Aßmus kMsgToggleToolBar = 'mTTB', 10194fd9498SStephan Aßmus kMsgSlideToolBar = 'mSTB', 10294fd9498SStephan Aßmus kMsgFinishSlidingToolBar = 'mFST' 103e2069723SAxel Dörfler }; 104e2069723SAxel Dörfler 105e2069723SAxel Dörfler 106cd6b5cdeSAxel Dörfler // This is temporary solution for building BString with printf like format. 107cd6b5cdeSAxel Dörfler // will be removed in the future. 108cd6b5cdeSAxel Dörfler static void 109cd6b5cdeSAxel Dörfler bs_printf(BString* string, const char* format, ...) 110cd6b5cdeSAxel Dörfler { 111cd6b5cdeSAxel Dörfler va_list ap; 112cd6b5cdeSAxel Dörfler char* buf; 113cd6b5cdeSAxel Dörfler 114cd6b5cdeSAxel Dörfler va_start(ap, format); 115cd6b5cdeSAxel Dörfler vasprintf(&buf, format, ap); 116cd6b5cdeSAxel Dörfler string->SetTo(buf); 117cd6b5cdeSAxel Dörfler free(buf); 118cd6b5cdeSAxel Dörfler va_end(ap); 119cd6b5cdeSAxel Dörfler } 120cd6b5cdeSAxel Dörfler 121cd6b5cdeSAxel Dörfler 1226163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow 1236163f333SKarsten Heimrich 1246163f333SKarsten Heimrich 125546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 126546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Menus" 127cf0d8308SStephan Aßmus 128cf0d8308SStephan Aßmus 1295b76e505SStephan Aßmus ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref, 130efa8b4f3SAxel Dörfler const BMessenger& trackerMessenger) 131fd952aefSRyan Leavengood : 13294fd9498SStephan Aßmus BWindow(frame, "", B_DOCUMENT_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS), 133b9767a83SAxel Dörfler fNavigator(ref, trackerMessenger), 134fd952aefSRyan Leavengood fSavePanel(NULL), 135fd952aefSRyan Leavengood fBar(NULL), 136fd952aefSRyan Leavengood fBrowseMenu(NULL), 137fd952aefSRyan Leavengood fGoToPageMenu(NULL), 1384aa63633SAxel Dörfler fSlideShowDelayMenu(NULL), 139cf0d8308SStephan Aßmus fToolBarView(NULL), 140fd952aefSRyan Leavengood fImageView(NULL), 141fd952aefSRyan Leavengood fStatusView(NULL), 142e2069723SAxel Dörfler fProgressWindow(new ProgressWindow()), 143fd952aefSRyan Leavengood fModified(false), 144fd952aefSRyan Leavengood fFullScreen(false), 145fd952aefSRyan Leavengood fShowCaption(true), 146cf0d8308SStephan Aßmus fShowToolBar(true), 1474aa63633SAxel Dörfler fPrintSettings(NULL), 1484aa63633SAxel Dörfler fSlideShowRunner(NULL), 1494aa63633SAxel Dörfler fSlideShowDelay(kDefaultSlideShowDelay) 15013afa642SPhil Greenway { 1512281340dSAxel Dörfler _ApplySettings(); 152fc0a275bSMatthew Wilber 15394fd9498SStephan Aßmus SetLayout(new BGroupLayout(B_VERTICAL, 0)); 15494fd9498SStephan Aßmus 15513afa642SPhil Greenway // create menu bar 15694fd9498SStephan Aßmus fBar = new BMenuBar("menu_bar"); 157b9767a83SAxel Dörfler _AddMenus(fBar); 15894fd9498SStephan Aßmus float menuBarMinWidth = fBar->MinSize().width; 159e9dcd874SAxel Dörfler AddChild(fBar); 16013afa642SPhil Greenway 16194fd9498SStephan Aßmus // Add a content view so the tool bar can be moved outside of the 16294fd9498SStephan Aßmus // visible portion without colliding with the menu bar. 163cf0d8308SStephan Aßmus 16494fd9498SStephan Aßmus BView* contentView = new BView(BRect(), "content", B_FOLLOW_NONE, 0); 16594fd9498SStephan Aßmus contentView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 16694fd9498SStephan Aßmus contentView->SetExplicitMinSize(BSize(250, 100)); 16794fd9498SStephan Aßmus AddChild(contentView); 16894fd9498SStephan Aßmus 16994fd9498SStephan Aßmus // Create the tool bar 17094fd9498SStephan Aßmus BRect viewFrame = contentView->Bounds(); 17194fd9498SStephan Aßmus viewFrame.right -= B_V_SCROLL_BAR_WIDTH; 172cf0d8308SStephan Aßmus fToolBarView = new ToolBarView(viewFrame); 173cf0d8308SStephan Aßmus 174cf0d8308SStephan Aßmus // Add the tool icons. 175cf0d8308SStephan Aßmus 176cf0d8308SStephan Aßmus // fToolBarView->AddAction(MSG_FILE_OPEN, be_app, 177cf0d8308SStephan Aßmus // tool_bar_icon(kIconDocumentOpen), B_TRANSLATE("Open"B_UTF8_ELLIPSIS)); 178a877c0e7SStephan Aßmus fToolBarView->AddAction(MSG_FILE_PREV, this, 179a877c0e7SStephan Aßmus tool_bar_icon(kIconGoPrevious), B_TRANSLATE("Previous file")); 180a877c0e7SStephan Aßmus fToolBarView->AddAction(MSG_FILE_NEXT, this, tool_bar_icon(kIconGoNext), 181cf0d8308SStephan Aßmus B_TRANSLATE("Next file")); 182a877c0e7SStephan Aßmus BMessage* fullScreenSlideShow = new BMessage(MSG_SLIDE_SHOW); 183a877c0e7SStephan Aßmus fullScreenSlideShow->AddBool("full screen", true); 184a877c0e7SStephan Aßmus fToolBarView->AddAction(fullScreenSlideShow, this, 185a877c0e7SStephan Aßmus tool_bar_icon(kIconMediaMovieLibrary), B_TRANSLATE("Slide show")); 186cf0d8308SStephan Aßmus fToolBarView->AddSeparator(); 187cf0d8308SStephan Aßmus fToolBarView->AddAction(MSG_SELECTION_MODE, this, 188cf0d8308SStephan Aßmus tool_bar_icon(kIconDrawRectangularSelection), 189cf0d8308SStephan Aßmus B_TRANSLATE("Selection mode")); 190cf0d8308SStephan Aßmus fToolBarView->AddSeparator(); 191cf0d8308SStephan Aßmus fToolBarView->AddAction(kMsgOriginalSize, this, 192cf0d8308SStephan Aßmus tool_bar_icon(kIconZoomOriginal), B_TRANSLATE("Original size")); 193cf0d8308SStephan Aßmus fToolBarView->AddAction(kMsgFitToWindow, this, 194cf0d8308SStephan Aßmus tool_bar_icon(kIconZoomFitBest), B_TRANSLATE("Fit to window")); 195cf0d8308SStephan Aßmus fToolBarView->AddAction(MSG_ZOOM_IN, this, tool_bar_icon(kIconZoomIn), 196cf0d8308SStephan Aßmus B_TRANSLATE("Zoom in")); 197cf0d8308SStephan Aßmus fToolBarView->AddAction(MSG_ZOOM_OUT, this, tool_bar_icon(kIconZoomOut), 198cf0d8308SStephan Aßmus B_TRANSLATE("Zoom out")); 19994fd9498SStephan Aßmus fToolBarView->AddGlue(); 20094fd9498SStephan Aßmus fToolBarView->AddAction(MSG_FULL_SCREEN, this, 20194fd9498SStephan Aßmus tool_bar_icon(kIconViewWindowed), B_TRANSLATE("Leave full screen")); 20294fd9498SStephan Aßmus fToolBarView->SetActionVisible(MSG_FULL_SCREEN, false); 203cf0d8308SStephan Aßmus 204cf0d8308SStephan Aßmus fToolBarView->ResizeTo(viewFrame.Width(), fToolBarView->MinSize().height); 205cf0d8308SStephan Aßmus 20694fd9498SStephan Aßmus contentView->AddChild(fToolBarView); 207cf0d8308SStephan Aßmus 208cf0d8308SStephan Aßmus if (fShowToolBar) 209cf0d8308SStephan Aßmus viewFrame.top = fToolBarView->Frame().bottom + 1; 210cf0d8308SStephan Aßmus else 211cf0d8308SStephan Aßmus fToolBarView->Hide(); 212cf0d8308SStephan Aßmus 21394fd9498SStephan Aßmus viewFrame.bottom = contentView->Bounds().bottom; 21413afa642SPhil Greenway viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; 21513afa642SPhil Greenway 21613afa642SPhil Greenway // create the image view 217d3046f7dSMichael Pfeiffer fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL, 218e2069723SAxel Dörfler B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED 219e2069723SAxel Dörfler | B_FRAME_EVENTS); 22013afa642SPhil Greenway // wrap a scroll view around the view 221cf0d8308SStephan Aßmus fScrollView = new BScrollView("image_scroller", fImageView, 222cdb89ebbSMatthew Wilber B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER); 22394fd9498SStephan Aßmus contentView->AddChild(fScrollView); 22413afa642SPhil Greenway 22507caaa8eSMatthew Wilber const int32 kstatusWidth = 190; 226cdb89ebbSMatthew Wilber BRect rect; 22794fd9498SStephan Aßmus rect = contentView->Bounds(); 22813afa642SPhil Greenway rect.top = viewFrame.bottom + 1; 22907caaa8eSMatthew Wilber rect.left = viewFrame.left + kstatusWidth; 2300916ab53SMatthew Wilber rect.right = viewFrame.right + 1; 2310916ab53SMatthew Wilber rect.bottom += 1; 232efa8b4f3SAxel Dörfler BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll", 233efa8b4f3SAxel Dörfler fImageView, 0, 150, B_HORIZONTAL); 23494fd9498SStephan Aßmus contentView->AddChild(horizontalScrollBar); 23513afa642SPhil Greenway 23613afa642SPhil Greenway rect.left = 0; 23707caaa8eSMatthew Wilber rect.right = kstatusWidth - 1; 2380cd4ecd8SStephan Aßmus rect.bottom -= 1; 239d3046f7dSMichael Pfeiffer fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM, 240cdb89ebbSMatthew Wilber B_WILL_DRAW); 24194fd9498SStephan Aßmus contentView->AddChild(fStatusView); 24213afa642SPhil Greenway 24394fd9498SStephan Aßmus rect = contentView->Bounds(); 2440916ab53SMatthew Wilber rect.top = viewFrame.top - 1; 24513afa642SPhil Greenway rect.left = viewFrame.right + 1; 2460916ab53SMatthew Wilber rect.bottom = viewFrame.bottom + 1; 2470916ab53SMatthew Wilber rect.right += 1; 248cf0d8308SStephan Aßmus fVerticalScrollBar = new BScrollBar(rect, "vscroll", fImageView, 249efa8b4f3SAxel Dörfler 0, 150, B_VERTICAL); 25094fd9498SStephan Aßmus contentView->AddChild(fVerticalScrollBar); 25113afa642SPhil Greenway 2529b13c418SStephan Aßmus // Update minimum window size 25394fd9498SStephan Aßmus float toolBarMinWidth = fToolBarView->MinSize().width; 2549b13c418SStephan Aßmus SetSizeLimits(std::max(menuBarMinWidth, toolBarMinWidth), 100000, 100, 2559b13c418SStephan Aßmus 100000); 25613afa642SPhil Greenway 257134d6076SMichael Pfeiffer // finish creating the window 258b9767a83SAxel Dörfler if (_LoadImage() != B_OK) { 259ba3217eeSAxel Dörfler _LoadError(ref); 2605e09d5dbSRyan Leavengood Quit(); 26101939af6SAxel Dörfler return; 262d10d5947SMichael Pfeiffer } 263402c09e5SMatthew Wilber 264d9f6762dSMichael Pfeiffer // add View menu here so it can access ShowImageView methods 265546208a5SOliver Tappe BMenu* menu = new BMenu(B_TRANSLATE_CONTEXT("View", "Menus")); 266fd952aefSRyan Leavengood _BuildViewMenu(menu, false); 267d9f6762dSMichael Pfeiffer fBar->AddItem(menu); 268d9f6762dSMichael Pfeiffer 2695b76e505SStephan Aßmus fBar->AddItem(_BuildRatingMenu()); 2705b76e505SStephan Aßmus 271d9f6762dSMichael Pfeiffer SetPulseRate(100000); 272d9f6762dSMichael Pfeiffer // every 1/10 second; ShowImageView needs it for marching ants 273d9f6762dSMichael Pfeiffer 2746db01936SAxel Dörfler _MarkMenuItem(menu, MSG_SELECTION_MODE, 2756db01936SAxel Dörfler fImageView->IsSelectionModeEnabled()); 2766db01936SAxel Dörfler 277402c09e5SMatthew Wilber // Tell application object to query the clipboard 278402c09e5SMatthew Wilber // and tell this window if it contains interesting data or not 279402c09e5SMatthew Wilber be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED); 280cd6b5cdeSAxel Dörfler 281cd6b5cdeSAxel Dörfler // The window will be shown on screen automatically 282cd6b5cdeSAxel Dörfler Run(); 28313afa642SPhil Greenway } 28413afa642SPhil Greenway 285efa8b4f3SAxel Dörfler 28613afa642SPhil Greenway ShowImageWindow::~ShowImageWindow() 28713afa642SPhil Greenway { 288e2069723SAxel Dörfler fProgressWindow->Lock(); 289e2069723SAxel Dörfler fProgressWindow->Quit(); 2904aa63633SAxel Dörfler 2914aa63633SAxel Dörfler _StopSlideShow(); 29213afa642SPhil Greenway } 29313afa642SPhil Greenway 294efa8b4f3SAxel Dörfler 295cdb89ebbSMatthew Wilber void 296d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu) 297d9f6762dSMichael Pfeiffer { 298fd952aefSRyan Leavengood _BuildViewMenu(menu, true); 299d9f6762dSMichael Pfeiffer } 300efa8b4f3SAxel Dörfler 30156b0c7b9SKarsten Heimrich 302cdb89ebbSMatthew Wilber void 303fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) 304da87390fSMichael Pfeiffer { 305905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this); 3064aa63633SAxel Dörfler _MarkMenuItem(menu, MSG_SLIDE_SHOW, fSlideShowRunner != NULL); 307905c8c8cSMatt Madia BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay")); 3084aa63633SAxel Dörfler if (fSlideShowDelayMenu == NULL) 3094aa63633SAxel Dörfler fSlideShowDelayMenu = delayMenu; 310efa8b4f3SAxel Dörfler 311efa8b4f3SAxel Dörfler delayMenu->SetRadioMode(true); 3124aa63633SAxel Dörfler 3134aa63633SAxel Dörfler int32 kDelays[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 20}; 3144aa63633SAxel Dörfler for (uint32 i = 0; i < sizeof(kDelays) / sizeof(kDelays[0]); i++) { 3154aa63633SAxel Dörfler BString text(B_TRANSLATE_COMMENT("%SECONDS seconds", 3164aa63633SAxel Dörfler "Don't translate %SECONDS")); 3174aa63633SAxel Dörfler char seconds[32]; 3184aa63633SAxel Dörfler snprintf(seconds, sizeof(seconds), "%" B_PRIi32, kDelays[i]); 3194aa63633SAxel Dörfler text.ReplaceFirst("%SECONDS", seconds); 3204aa63633SAxel Dörfler 3214aa63633SAxel Dörfler _AddDelayItem(delayMenu, text.String(), kDelays[i] * 1000000LL); 3224aa63633SAxel Dörfler } 323efa8b4f3SAxel Dörfler menu->AddItem(delayMenu); 32430060f17SMatthew Wilber 325efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 326efa8b4f3SAxel Dörfler 327905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Original size"), 328e2069723SAxel Dörfler kMsgOriginalSize, '1', 0, this); 329e2069723SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Fit to window"), 330e2069723SAxel Dörfler kMsgFitToWindow, '0', 0, this); 331905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this); 332905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this); 333efa8b4f3SAxel Dörfler 334efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 335efa8b4f3SAxel Dörfler 3364fd570d3SAxel Dörfler if (!popupMenu || fFullScreen) { 337905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), 338905c8c8cSMatt Madia MSG_SCALE_BILINEAR, 0, 0, this); 3394fd570d3SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Stretch to window"), 340e2069723SAxel Dörfler kMsgStretchToWindow, 0, 0, this); 341efa8b4f3SAxel Dörfler 342efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 34332c22143SAxel Dörfler } 344efa8b4f3SAxel Dörfler 345905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Full screen"), 346905c8c8cSMatt Madia MSG_FULL_SCREEN, B_ENTER, 0, this); 347fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen); 348efa8b4f3SAxel Dörfler 349905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"), 350905c8c8cSMatt Madia MSG_SHOW_CAPTION, 0, 0, this); 351fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption); 352efa8b4f3SAxel Dörfler 353e2069723SAxel Dörfler _MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->ScaleBilinear()); 354e2069723SAxel Dörfler _MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds()); 355a60adbf9SAxel Dörfler 356cf0d8308SStephan Aßmus if (!popupMenu) { 35794fd9498SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar, 35894fd9498SStephan Aßmus 'T', 0, this); 359cf0d8308SStephan Aßmus _MarkMenuItem(menu, kMsgToggleToolBar, 360cf0d8308SStephan Aßmus !fToolBarView->IsHidden(fToolBarView)); 361cf0d8308SStephan Aßmus } 362cf0d8308SStephan Aßmus 363d9f6762dSMichael Pfeiffer if (popupMenu) { 364a60adbf9SAxel Dörfler menu->AddSeparatorItem(); 365905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 3661ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 367d9f6762dSMichael Pfeiffer } 368da87390fSMichael Pfeiffer } 369da87390fSMichael Pfeiffer 370efa8b4f3SAxel Dörfler 3715b76e505SStephan Aßmus BMenu* 3725b76e505SStephan Aßmus ShowImageWindow::_BuildRatingMenu() 3735b76e505SStephan Aßmus { 3745b76e505SStephan Aßmus fRatingMenu = new BMenu(B_TRANSLATE("Rating")); 3755b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) { 3765b76e505SStephan Aßmus BString label; 3775b76e505SStephan Aßmus label << i; 3785b76e505SStephan Aßmus BMessage* message = new BMessage(MSG_SET_RATING); 3795b76e505SStephan Aßmus message->AddInt32("rating", i); 3805b76e505SStephan Aßmus fRatingMenu->AddItem(new BMenuItem(label.String(), message)); 3815b76e505SStephan Aßmus } 3825b76e505SStephan Aßmus // NOTE: We may want to encapsulate the Rating menu within a more 3835b76e505SStephan Aßmus // general "Attributes" menu. 3845b76e505SStephan Aßmus return fRatingMenu; 3855b76e505SStephan Aßmus } 3865b76e505SStephan Aßmus 3875b76e505SStephan Aßmus 388da87390fSMichael Pfeiffer void 389b9767a83SAxel Dörfler ShowImageWindow::_AddMenus(BMenuBar* bar) 39013afa642SPhil Greenway { 391905c8c8cSMatt Madia BMenu* menu = new BMenu(B_TRANSLATE("File")); 39236272f0dSAxel Dörfler 39336272f0dSAxel Dörfler // Add recent files to "Open File" entry as sub-menu. 39436272f0dSAxel Dörfler BMenuItem* item = new BMenuItem(BRecentFilesList::NewFileListMenu( 39536272f0dSAxel Dörfler B_TRANSLATE("Open"B_UTF8_ELLIPSIS), NULL, NULL, be_app, 10, true, 39636272f0dSAxel Dörfler NULL, kApplicationSignature), new BMessage(MSG_FILE_OPEN)); 39736272f0dSAxel Dörfler item->SetShortcut('O', 0); 39836272f0dSAxel Dörfler item->SetTarget(be_app); 39936272f0dSAxel Dörfler menu->AddItem(item); 400efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 40136272f0dSAxel Dörfler 4026db01936SAxel Dörfler BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS), 4031ed4535fSStephan Aßmus B_ITEMS_IN_COLUMN); 4046db01936SAxel Dörfler BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP); 405fc0a275bSMatthew Wilber // Fill Save As submenu with all types that can be converted 406fc0a275bSMatthew Wilber // to from the Be bitmap image format 4076db01936SAxel Dörfler menu->AddItem(menuSaveAs); 408905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this); 409efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 410905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS), 4111ed4535fSStephan Aßmus MSG_PAGE_SETUP, 0, 0, this); 412905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS), 4131ed4535fSStephan Aßmus MSG_PREPARE_PRINT, 'P', 0, this); 414efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 415905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app); 416efa8b4f3SAxel Dörfler bar->AddItem(menu); 41713afa642SPhil Greenway 418905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Edit")); 419905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Undo"), B_UNDO, 'Z', 0, this, false); 420efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 421905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false); 422efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 423cf0d8308SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Selection mode"), MSG_SELECTION_MODE, 0, 0, 4246db01936SAxel Dörfler this); 42532c22143SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Clear selection"), 42632c22143SAxel Dörfler MSG_CLEAR_SELECT, 0, 0, this, false); 427905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Select all"), 428905c8c8cSMatt Madia MSG_SELECT_ALL, 'A', 0, this); 429efa8b4f3SAxel Dörfler bar->AddItem(menu); 43013afa642SPhil Greenway 431905c8c8cSMatt Madia menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse")); 432905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("First page"), 4331ed4535fSStephan Aßmus MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this); 434905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Last page"), 4351ed4535fSStephan Aßmus MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this); 436905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous page"), 437905c8c8cSMatt Madia MSG_PAGE_PREV, B_LEFT_ARROW, 0, this); 438905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next page"), 439905c8c8cSMatt Madia MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this); 440905c8c8cSMatt Madia fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page")); 4415e427b6aSMichael Pfeiffer fGoToPageMenu->SetRadioMode(true); 442efa8b4f3SAxel Dörfler menu->AddItem(fGoToPageMenu); 443efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 444905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous file"), 445905c8c8cSMatt Madia MSG_FILE_PREV, B_UP_ARROW, 0, this); 446905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next file"), 447905c8c8cSMatt Madia MSG_FILE_NEXT, B_DOWN_ARROW, 0, this); 448efa8b4f3SAxel Dörfler bar->AddItem(menu); 44903839579SMatthew Wilber 450905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Image")); 451905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"), 452905c8c8cSMatt Madia MSG_ROTATE_90, 'R', 0, this); 453905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"), 4541ed4535fSStephan Aßmus MSG_ROTATE_270, 'R', B_SHIFT_KEY, this); 455efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 456905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip left to right"), 4571ed4535fSStephan Aßmus MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this); 458905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"), 4591ed4535fSStephan Aßmus MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this); 460efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 461905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 4621ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 46304f96544SAxel Dörfler 46404f96544SAxel Dörfler bar->AddItem(menu); 46513afa642SPhil Greenway } 46613afa642SPhil Greenway 467efa8b4f3SAxel Dörfler 468cdb89ebbSMatthew Wilber BMenuItem* 469fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what, 4704fd570d3SAxel Dörfler char shortcut, uint32 modifier, const BHandler* target, bool enabled) 471cdb89ebbSMatthew Wilber { 4724fd570d3SAxel Dörfler BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut, 4734fd570d3SAxel Dörfler modifier); 474efa8b4f3SAxel Dörfler menu->AddItem(item); 475efa8b4f3SAxel Dörfler 4766163f333SKarsten Heimrich item->SetTarget(target); 4776163f333SKarsten Heimrich item->SetEnabled(enabled); 4786163f333SKarsten Heimrich 479efa8b4f3SAxel Dörfler return item; 48013afa642SPhil Greenway } 48113afa642SPhil Greenway 482efa8b4f3SAxel Dörfler 483ad13f387SMichael Pfeiffer BMenuItem* 4844aa63633SAxel Dörfler ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, bigtime_t delay) 485ad13f387SMichael Pfeiffer { 486efa8b4f3SAxel Dörfler BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY); 4874aa63633SAxel Dörfler message->AddInt64("delay", delay); 488ad13f387SMichael Pfeiffer 4896163f333SKarsten Heimrich BMenuItem* item = new BMenuItem(label, message, 0); 490efa8b4f3SAxel Dörfler item->SetTarget(this); 491ad13f387SMichael Pfeiffer 4924aa63633SAxel Dörfler if (delay == fSlideShowDelay) 493efa8b4f3SAxel Dörfler item->SetMarked(true); 494ad13f387SMichael Pfeiffer 495efa8b4f3SAxel Dörfler menu->AddItem(item); 496efa8b4f3SAxel Dörfler return item; 497ad13f387SMichael Pfeiffer } 498ad13f387SMichael Pfeiffer 499efa8b4f3SAxel Dörfler 500cdb89ebbSMatthew Wilber void 501e2069723SAxel Dörfler ShowImageWindow::_ResizeWindowToImage() 50213afa642SPhil Greenway { 503e2069723SAxel Dörfler BBitmap* bitmap = fImageView->Bitmap(); 504d10d5947SMichael Pfeiffer BScreen screen; 505e2069723SAxel Dörfler if (bitmap == NULL || !screen.IsValid()) 506efa8b4f3SAxel Dörfler return; 507efa8b4f3SAxel Dörfler 5081076d97bSAxel Dörfler // TODO: use View::GetPreferredSize() instead? 5091076d97bSAxel Dörfler BRect r(bitmap->Bounds()); 5101076d97bSAxel Dörfler float width = r.Width() + B_V_SCROLL_BAR_WIDTH; 5111076d97bSAxel Dörfler float height = r.Height() + 1 + fBar->Frame().Height() 5121076d97bSAxel Dörfler + B_H_SCROLL_BAR_HEIGHT; 513cdb89ebbSMatthew Wilber 5146163f333SKarsten Heimrich BRect frame = screen.Frame(); 5156163f333SKarsten Heimrich const float windowBorder = 5; 516d10d5947SMichael Pfeiffer // dimensions so that window does not reach outside of screen 5176163f333SKarsten Heimrich float maxWidth = frame.Width() + 1 - windowBorder - Frame().left; 5186163f333SKarsten Heimrich float maxHeight = frame.Height() + 1 - windowBorder - Frame().top; 519cdb89ebbSMatthew Wilber 520a8fc7138SMichael Pfeiffer // We have to check size limits manually, otherwise 521a8fc7138SMichael Pfeiffer // menu bar will be too short for small images. 522efa8b4f3SAxel Dörfler 523fc5ca95dSStephan Aßmus float minW, maxW, minH, maxH; 524a8fc7138SMichael Pfeiffer GetSizeLimits(&minW, &maxW, &minH, &maxH); 525efa8b4f3SAxel Dörfler if (maxWidth > maxW) 526efa8b4f3SAxel Dörfler maxWidth = maxW; 527efa8b4f3SAxel Dörfler if (maxHeight > maxH) 528efa8b4f3SAxel Dörfler maxHeight = maxH; 529efa8b4f3SAxel Dörfler if (width < minW) 530efa8b4f3SAxel Dörfler width = minW; 531efa8b4f3SAxel Dörfler if (height < minH) 532efa8b4f3SAxel Dörfler height = minH; 533a8fc7138SMichael Pfeiffer 534efa8b4f3SAxel Dörfler if (width > maxWidth) 535efa8b4f3SAxel Dörfler width = maxWidth; 536efa8b4f3SAxel Dörfler if (height > maxHeight) 537efa8b4f3SAxel Dörfler height = maxHeight; 538d10d5947SMichael Pfeiffer 539d10d5947SMichael Pfeiffer ResizeTo(width, height); 54013afa642SPhil Greenway } 54113afa642SPhil Greenway 542efa8b4f3SAxel Dörfler 5437eca0987SMichael Pfeiffer bool 544fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what) 5457eca0987SMichael Pfeiffer { 5467eca0987SMichael Pfeiffer bool marked = false; 5476163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(what); 5487eca0987SMichael Pfeiffer if (item != NULL) { 5497eca0987SMichael Pfeiffer marked = !item->IsMarked(); 5507eca0987SMichael Pfeiffer item->SetMarked(marked); 5517eca0987SMichael Pfeiffer } 552cf0d8308SStephan Aßmus fToolBarView->SetActionPressed(what, marked); 5537eca0987SMichael Pfeiffer return marked; 5547eca0987SMichael Pfeiffer } 5557eca0987SMichael Pfeiffer 556efa8b4f3SAxel Dörfler 557cdb89ebbSMatthew Wilber void 558fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable) 559e6a50d9cSMichael Pfeiffer { 5606163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 5616163f333SKarsten Heimrich if (item && item->IsEnabled() != enable) 562e6a50d9cSMichael Pfeiffer item->SetEnabled(enable); 563cf0d8308SStephan Aßmus fToolBarView->SetActionEnabled(what, enable); 564e6a50d9cSMichael Pfeiffer } 565e6a50d9cSMichael Pfeiffer 566efa8b4f3SAxel Dörfler 567e6a50d9cSMichael Pfeiffer void 568fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked) 569e6a50d9cSMichael Pfeiffer { 5706163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 5716163f333SKarsten Heimrich if (item && item->IsMarked() != marked) 572e6a50d9cSMichael Pfeiffer item->SetMarked(marked); 573cf0d8308SStephan Aßmus fToolBarView->SetActionPressed(what, marked); 574e6a50d9cSMichael Pfeiffer } 575e6a50d9cSMichael Pfeiffer 576efa8b4f3SAxel Dörfler 577da87390fSMichael Pfeiffer void 5784aa63633SAxel Dörfler ShowImageWindow::_MarkSlideShowDelay(bigtime_t delay) 579da87390fSMichael Pfeiffer { 5804aa63633SAxel Dörfler const int32 count = fSlideShowDelayMenu->CountItems(); 5814aa63633SAxel Dörfler for (int32 i = 0; i < count; i ++) { 5824aa63633SAxel Dörfler BMenuItem* item = fSlideShowDelayMenu->ItemAt(i); 5834aa63633SAxel Dörfler if (item != NULL) { 5844aa63633SAxel Dörfler bigtime_t itemDelay; 5854aa63633SAxel Dörfler if (item->Message()->FindInt64("delay", &itemDelay) == B_OK 5864aa63633SAxel Dörfler && itemDelay == delay) { 587da87390fSMichael Pfeiffer item->SetMarked(true); 588da87390fSMichael Pfeiffer return; 589da87390fSMichael Pfeiffer } 590da87390fSMichael Pfeiffer } 591da87390fSMichael Pfeiffer } 592da87390fSMichael Pfeiffer } 593e6a50d9cSMichael Pfeiffer 59419c76de4SMichael Pfeiffer 59519c76de4SMichael Pfeiffer void 596e2069723SAxel Dörfler ShowImageWindow::Zoom(BPoint origin, float width, float height) 59719c76de4SMichael Pfeiffer { 598e2069723SAxel Dörfler _ToggleFullScreen(); 59919c76de4SMichael Pfeiffer } 60019c76de4SMichael Pfeiffer 601efa8b4f3SAxel Dörfler 602e6a50d9cSMichael Pfeiffer void 603efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message) 60413afa642SPhil Greenway { 605e2069723SAxel Dörfler if (message->WasDropped()) { 606e2069723SAxel Dörfler uint32 type; 607e2069723SAxel Dörfler int32 count; 608e2069723SAxel Dörfler status_t status = message->GetInfo("refs", &type, &count); 609e2069723SAxel Dörfler if (status == B_OK && type == B_REF_TYPE) { 610e2069723SAxel Dörfler message->what = B_REFS_RECEIVED; 611e2069723SAxel Dörfler be_app->PostMessage(message); 612e2069723SAxel Dörfler } 613e2069723SAxel Dörfler } 614e2069723SAxel Dörfler 615efa8b4f3SAxel Dörfler switch (message->what) { 616e2069723SAxel Dörfler case kMsgImageCacheImageLoaded: 617cd6b5cdeSAxel Dörfler { 618e2069723SAxel Dörfler fProgressWindow->Stop(); 619e2069723SAxel Dörfler 620df942b3eSAxel Dörfler BitmapOwner* bitmapOwner = NULL; 621df942b3eSAxel Dörfler message->FindPointer("bitmapOwner", (void**)&bitmapOwner); 622df942b3eSAxel Dörfler 623cd6b5cdeSAxel Dörfler bool first = fImageView->Bitmap() == NULL; 624b9767a83SAxel Dörfler entry_ref ref; 625b9767a83SAxel Dörfler message->FindRef("ref", &ref); 626b9767a83SAxel Dörfler if (!first && ref != fNavigator.CurrentRef()) { 627b9767a83SAxel Dörfler // ignore older images 628df942b3eSAxel Dörfler if (bitmapOwner != NULL) 629df942b3eSAxel Dörfler bitmapOwner->ReleaseReference(); 630b9767a83SAxel Dörfler break; 631b9767a83SAxel Dörfler } 632cd6b5cdeSAxel Dörfler 633cd6b5cdeSAxel Dörfler status_t status = fImageView->SetImage(message); 634cd6b5cdeSAxel Dörfler if (status != B_OK) { 635df942b3eSAxel Dörfler if (bitmapOwner != NULL) 636df942b3eSAxel Dörfler bitmapOwner->ReleaseReference(); 637df942b3eSAxel Dörfler 638cd6b5cdeSAxel Dörfler _LoadError(ref); 639cd6b5cdeSAxel Dörfler 640cd6b5cdeSAxel Dörfler // quit if file could not be opened 641cd6b5cdeSAxel Dörfler if (first) 642cd6b5cdeSAxel Dörfler Quit(); 643cd6b5cdeSAxel Dörfler break; 644cd6b5cdeSAxel Dörfler } 645cd6b5cdeSAxel Dörfler 646cd6b5cdeSAxel Dörfler fImageType = message->FindString("type"); 647b9767a83SAxel Dörfler fNavigator.SetTo(ref, message->FindInt32("page"), 648b9767a83SAxel Dörfler message->FindInt32("pageCount")); 649cd6b5cdeSAxel Dörfler 650e2069723SAxel Dörfler fImageView->FitToBounds(); 651cd6b5cdeSAxel Dörfler if (first) { 652cd6b5cdeSAxel Dörfler fImageView->MakeFocus(true); 653cd6b5cdeSAxel Dörfler // to receive key messages 654cd6b5cdeSAxel Dörfler Show(); 655e2069723SAxel Dörfler } 6565b76e505SStephan Aßmus _UpdateRatingMenu(); 657e2069723SAxel Dörfler break; 658e2069723SAxel Dörfler } 659e2069723SAxel Dörfler 660e2069723SAxel Dörfler case kMsgImageCacheProgressUpdate: 661e2069723SAxel Dörfler { 662e2069723SAxel Dörfler entry_ref ref; 663e2069723SAxel Dörfler if (message->FindRef("ref", &ref) == B_OK 664e2069723SAxel Dörfler && ref == fNavigator.CurrentRef()) { 665e2069723SAxel Dörfler message->what = kMsgProgressUpdate; 666e2069723SAxel Dörfler fProgressWindow->PostMessage(message); 667cd6b5cdeSAxel Dörfler } 668cd6b5cdeSAxel Dörfler break; 669cd6b5cdeSAxel Dörfler } 670cd6b5cdeSAxel Dörfler 671ee7b4f39SMatthew Wilber case MSG_MODIFIED: 672ee7b4f39SMatthew Wilber // If image has been modified due to a Cut or Paste 673ee7b4f39SMatthew Wilber fModified = true; 674ee7b4f39SMatthew Wilber break; 675ee7b4f39SMatthew Wilber 676fc0a275bSMatthew Wilber case MSG_OUTPUT_TYPE: 677fc0a275bSMatthew Wilber // User clicked Save As then choose an output format 678d3046f7dSMichael Pfeiffer if (!fSavePanel) 679cdb89ebbSMatthew Wilber // If user doesn't already have a save panel open 680fd952aefSRyan Leavengood _SaveAs(message); 68113afa642SPhil Greenway break; 682fc0a275bSMatthew Wilber 683fc0a275bSMatthew Wilber case MSG_SAVE_PANEL: 684fc0a275bSMatthew Wilber // User specified where to save the output image 685fd952aefSRyan Leavengood _SaveToFile(message); 68607caaa8eSMatthew Wilber break; 68707caaa8eSMatthew Wilber 688cdb89ebbSMatthew Wilber case B_CANCEL: 689d3046f7dSMichael Pfeiffer delete fSavePanel; 690d3046f7dSMichael Pfeiffer fSavePanel = NULL; 691cdb89ebbSMatthew Wilber break; 692cdb89ebbSMatthew Wilber 6936db01936SAxel Dörfler case MSG_UPDATE_STATUS: 6946db01936SAxel Dörfler { 695cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 696cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 6976c305411SMatthew Wilber 698cd6b5cdeSAxel Dörfler bool enable = pages > 1 ? true : false; 69936c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_FIRST, enable); 70036c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_LAST, enable); 70136c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_NEXT, enable); 70236c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_PREV, enable); 70336c17651SRyan Leavengood fGoToPageMenu->SetEnabled(enable); 7041d592070SMatthew Wilber 705cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile()); 706cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile()); 707134d6076SMichael Pfeiffer 708d3046f7dSMichael Pfeiffer if (fGoToPageMenu->CountItems() != pages) { 7096c305411SMatthew Wilber // Only rebuild the submenu if the number of 7106c305411SMatthew Wilber // pages is different 7116c305411SMatthew Wilber 712cd6b5cdeSAxel Dörfler while (fGoToPageMenu->CountItems() > 0) { 7136c305411SMatthew Wilber // Remove all page numbers 714d3046f7dSMichael Pfeiffer delete fGoToPageMenu->RemoveItem(0L); 715cd6b5cdeSAxel Dörfler } 7166c305411SMatthew Wilber 717780d8a62SMichael Pfeiffer for (int32 i = 1; i <= pages; i++) { 7186c305411SMatthew Wilber // Fill Go To page submenu with an entry for each page 719cd6b5cdeSAxel Dörfler BMessage* goTo = new BMessage(MSG_GOTO_PAGE); 720cd6b5cdeSAxel Dörfler goTo->AddInt32("page", i); 7216163f333SKarsten Heimrich 7226163f333SKarsten Heimrich char shortcut = 0; 723cd6b5cdeSAxel Dörfler if (i < 10) 724780d8a62SMichael Pfeiffer shortcut = '0' + i; 7256163f333SKarsten Heimrich 7266163f333SKarsten Heimrich BString strCaption; 7276163f333SKarsten Heimrich strCaption << i; 7286163f333SKarsten Heimrich 729cd6b5cdeSAxel Dörfler BMenuItem* item = new BMenuItem(strCaption.String(), goTo, 730*a8199d69Sthreedeyes shortcut, B_SHIFT_KEY); 731cd6b5cdeSAxel Dörfler if (currentPage == i) 732efa8b4f3SAxel Dörfler item->SetMarked(true); 733efa8b4f3SAxel Dörfler fGoToPageMenu->AddItem(item); 7346c305411SMatthew Wilber } 7356c305411SMatthew Wilber } else { 7366c305411SMatthew Wilber // Make sure the correct page is marked 737cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 738cd6b5cdeSAxel Dörfler if (currentItem != NULL && !currentItem->IsMarked()) 739cd6b5cdeSAxel Dörfler currentItem->SetMarked(true); 7406c305411SMatthew Wilber } 7416c305411SMatthew Wilber 742cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 743b9767a83SAxel Dörfler 744b9767a83SAxel Dörfler BPath path(fImageView->Image()); 745b9767a83SAxel Dörfler SetTitle(path.Path()); 7466db01936SAxel Dörfler break; 7476db01936SAxel Dörfler } 74803839579SMatthew Wilber 7496db01936SAxel Dörfler case MSG_UPDATE_STATUS_TEXT: 7506db01936SAxel Dörfler { 751cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 7526db01936SAxel Dörfler break; 7536db01936SAxel Dörfler } 7548f5fd23fSRyan Leavengood 7556db01936SAxel Dörfler case MSG_SELECTION: 7566db01936SAxel Dörfler { 7578ad30bcfSMatthew Wilber // The view sends this message when a selection is 7588ad30bcfSMatthew Wilber // made or the selection is cleared so that the window 7598ad30bcfSMatthew Wilber // can update the state of the appropriate menu items 7606db01936SAxel Dörfler bool enable; 7616db01936SAxel Dörfler if (message->FindBool("has_selection", &enable) == B_OK) { 7626db01936SAxel Dörfler _EnableMenuItem(fBar, B_COPY, enable); 7636db01936SAxel Dörfler _EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable); 7648ad30bcfSMatthew Wilber } 7656db01936SAxel Dörfler break; 7666db01936SAxel Dörfler } 7678ad30bcfSMatthew Wilber 7686db01936SAxel Dörfler case MSG_UNDO_STATE: 7696db01936SAxel Dörfler { 7706db01936SAxel Dörfler bool enable; 7716db01936SAxel Dörfler if (message->FindBool("can_undo", &enable) == B_OK) 7726db01936SAxel Dörfler _EnableMenuItem(fBar, B_UNDO, enable); 7736db01936SAxel Dörfler break; 7746db01936SAxel Dörfler } 775402c09e5SMatthew Wilber 77613afa642SPhil Greenway case B_UNDO: 7777598450eSMatthew Wilber fImageView->Undo(); 77813afa642SPhil Greenway break; 7796163f333SKarsten Heimrich 78013afa642SPhil Greenway case B_COPY: 781d3046f7dSMichael Pfeiffer fImageView->CopySelectionToClipboard(); 78213afa642SPhil Greenway break; 7836163f333SKarsten Heimrich 7846db01936SAxel Dörfler case MSG_SELECTION_MODE: 785cf0d8308SStephan Aßmus { 786cf0d8308SStephan Aßmus bool selectionMode = _ToggleMenuItem(MSG_SELECTION_MODE); 787cf0d8308SStephan Aßmus fImageView->SetSelectionMode(selectionMode); 788cf0d8308SStephan Aßmus if (!selectionMode) 789cf0d8308SStephan Aßmus fImageView->ClearSelection(); 7906db01936SAxel Dörfler break; 791cf0d8308SStephan Aßmus } 7926db01936SAxel Dörfler 79313afa642SPhil Greenway case MSG_CLEAR_SELECT: 794d3046f7dSMichael Pfeiffer fImageView->ClearSelection(); 79513afa642SPhil Greenway break; 7966163f333SKarsten Heimrich 79713afa642SPhil Greenway case MSG_SELECT_ALL: 798d3046f7dSMichael Pfeiffer fImageView->SelectAll(); 79913afa642SPhil Greenway break; 80013afa642SPhil Greenway 80103839579SMatthew Wilber case MSG_PAGE_FIRST: 802b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.FirstPage()) 803b9767a83SAxel Dörfler _LoadImage(); 80403839579SMatthew Wilber break; 80503839579SMatthew Wilber 80603839579SMatthew Wilber case MSG_PAGE_LAST: 807b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.LastPage()) 808b9767a83SAxel Dörfler _LoadImage(); 80903839579SMatthew Wilber break; 81003839579SMatthew Wilber 81103839579SMatthew Wilber case MSG_PAGE_NEXT: 812b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextPage()) 813b9767a83SAxel Dörfler _LoadImage(); 81403839579SMatthew Wilber break; 81503839579SMatthew Wilber 81603839579SMatthew Wilber case MSG_PAGE_PREV: 817b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousPage()) 818b9767a83SAxel Dörfler _LoadImage(); 81903839579SMatthew Wilber break; 82003839579SMatthew Wilber 821cd6b5cdeSAxel Dörfler case MSG_GOTO_PAGE: 822cd6b5cdeSAxel Dörfler { 823fd952aefSRyan Leavengood if (!_ClosePrompt()) 824ee7b4f39SMatthew Wilber break; 825ee7b4f39SMatthew Wilber 8266163f333SKarsten Heimrich int32 newPage; 8276163f333SKarsten Heimrich if (message->FindInt32("page", &newPage) != B_OK) 8286163f333SKarsten Heimrich break; 8296163f333SKarsten Heimrich 830cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 831cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 8326c305411SMatthew Wilber 833b9767a83SAxel Dörfler // TODO: use radio mode instead! 8346c305411SMatthew Wilber if (newPage > 0 && newPage <= pages) { 835cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 836cd6b5cdeSAxel Dörfler BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1); 837cd6b5cdeSAxel Dörfler if (currentItem != NULL && newItem != NULL) { 838cd6b5cdeSAxel Dörfler currentItem->SetMarked(false); 839cd6b5cdeSAxel Dörfler newItem->SetMarked(true); 840b9767a83SAxel Dörfler if (fNavigator.GoToPage(newPage)) 841b9767a83SAxel Dörfler _LoadImage(); 8426c305411SMatthew Wilber } 8436c305411SMatthew Wilber } 844cd6b5cdeSAxel Dörfler break; 845cd6b5cdeSAxel Dörfler } 8466c305411SMatthew Wilber 847e2069723SAxel Dörfler case kMsgFitToWindow: 848e2069723SAxel Dörfler fImageView->FitToBounds(); 84919c76de4SMichael Pfeiffer break; 8506163f333SKarsten Heimrich 851e2069723SAxel Dörfler case kMsgStretchToWindow: 852e2069723SAxel Dörfler fImageView->SetStretchToBounds( 853e2069723SAxel Dörfler _ToggleMenuItem(kMsgStretchToWindow)); 8547eca0987SMichael Pfeiffer break; 8557eca0987SMichael Pfeiffer 8567eca0987SMichael Pfeiffer case MSG_FILE_PREV: 857b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousFile()) 858a569816bSAxel Dörfler _LoadImage(false); 8597eca0987SMichael Pfeiffer break; 8607eca0987SMichael Pfeiffer 8617eca0987SMichael Pfeiffer case MSG_FILE_NEXT: 8624aa63633SAxel Dörfler case kMsgNextSlide: 863b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextFile()) 864b9767a83SAxel Dörfler _LoadImage(); 86513afa642SPhil Greenway break; 86613afa642SPhil Greenway 867328932acSAxel Dörfler case kMsgDeleteCurrentFile: 868b9767a83SAxel Dörfler { 869b9767a83SAxel Dörfler if (fNavigator.MoveFileToTrash()) 870b9767a83SAxel Dörfler _LoadImage(); 871b9767a83SAxel Dörfler else 872328932acSAxel Dörfler PostMessage(B_QUIT_REQUESTED); 873328932acSAxel Dörfler break; 874b9767a83SAxel Dörfler } 875328932acSAxel Dörfler 876bf461dbeSMatthew Wilber case MSG_ROTATE_90: 877d3046f7dSMichael Pfeiffer fImageView->Rotate(90); 878ad13f387SMichael Pfeiffer break; 8796163f333SKarsten Heimrich 880bf461dbeSMatthew Wilber case MSG_ROTATE_270: 881d3046f7dSMichael Pfeiffer fImageView->Rotate(270); 882ad13f387SMichael Pfeiffer break; 8836163f333SKarsten Heimrich 88469eee339SRyan Leavengood case MSG_FLIP_LEFT_TO_RIGHT: 88561ddc257SRyan Leavengood fImageView->Flip(true); 886ad13f387SMichael Pfeiffer break; 8876163f333SKarsten Heimrich 88869eee339SRyan Leavengood case MSG_FLIP_TOP_TO_BOTTOM: 88961ddc257SRyan Leavengood fImageView->Flip(false); 890ad13f387SMichael Pfeiffer break; 8916163f333SKarsten Heimrich 8921076d97bSAxel Dörfler case MSG_SLIDE_SHOW: 8931076d97bSAxel Dörfler { 89494fd9498SStephan Aßmus bool fullScreen = false; 89594fd9498SStephan Aßmus message->FindBool("full screen", &fullScreen); 896a877c0e7SStephan Aßmus 8976163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(message->what); 8984aa63633SAxel Dörfler if (item == NULL) 899ee7b4f39SMatthew Wilber break; 9004aa63633SAxel Dörfler 901ee7b4f39SMatthew Wilber if (item->IsMarked()) { 902ee7b4f39SMatthew Wilber item->SetMarked(false); 9034aa63633SAxel Dörfler _StopSlideShow(); 90494fd9498SStephan Aßmus fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, false); 905fd952aefSRyan Leavengood } else if (_ClosePrompt()) { 906ee7b4f39SMatthew Wilber item->SetMarked(true); 90794fd9498SStephan Aßmus if (!fFullScreen && fullScreen) 90894fd9498SStephan Aßmus _ToggleFullScreen(); 9094aa63633SAxel Dörfler _StartSlideShow(); 91094fd9498SStephan Aßmus fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, true); 911ad13f387SMichael Pfeiffer } 9121076d97bSAxel Dörfler break; 9131076d97bSAxel Dörfler } 914ee7b4f39SMatthew Wilber 9154aa63633SAxel Dörfler case kMsgStopSlideShow: 9164aa63633SAxel Dörfler { 9174aa63633SAxel Dörfler BMenuItem* item = fBar->FindItem(MSG_SLIDE_SHOW); 9184aa63633SAxel Dörfler if (item != NULL) 9194aa63633SAxel Dörfler item->SetMarked(false); 9204aa63633SAxel Dörfler 9214aa63633SAxel Dörfler _StopSlideShow(); 92294fd9498SStephan Aßmus fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, false); 9234aa63633SAxel Dörfler break; 9244aa63633SAxel Dörfler } 9254aa63633SAxel Dörfler 9261076d97bSAxel Dörfler case MSG_SLIDE_SHOW_DELAY: 9271076d97bSAxel Dörfler { 9284aa63633SAxel Dörfler bigtime_t delay; 9294aa63633SAxel Dörfler if (message->FindInt64("delay", &delay) == B_OK) { 9304aa63633SAxel Dörfler _SetSlideShowDelay(delay); 931da87390fSMichael Pfeiffer // in case message is sent from popup menu 9324aa63633SAxel Dörfler _MarkSlideShowDelay(delay); 933ad13f387SMichael Pfeiffer } 9341076d97bSAxel Dörfler break; 9351076d97bSAxel Dörfler } 936ad13f387SMichael Pfeiffer 937ad13f387SMichael Pfeiffer case MSG_FULL_SCREEN: 938fd952aefSRyan Leavengood _ToggleFullScreen(); 939ad13f387SMichael Pfeiffer break; 9406163f333SKarsten Heimrich 941fc5ca95dSStephan Aßmus case MSG_EXIT_FULL_SCREEN: 942fc5ca95dSStephan Aßmus if (fFullScreen) 943fd952aefSRyan Leavengood _ToggleFullScreen(); 944fc5ca95dSStephan Aßmus break; 9456163f333SKarsten Heimrich 946cf0d8308SStephan Aßmus case MSG_SHOW_CAPTION: 947cf0d8308SStephan Aßmus { 948fd952aefSRyan Leavengood fShowCaption = _ToggleMenuItem(message->what); 949efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 950efa8b4f3SAxel Dörfler 951d3046f7dSMichael Pfeiffer if (settings->Lock()) { 952d3046f7dSMichael Pfeiffer settings->SetBool("ShowCaption", fShowCaption); 953d3046f7dSMichael Pfeiffer settings->Unlock(); 954d3046f7dSMichael Pfeiffer } 955efa8b4f3SAxel Dörfler if (fFullScreen) 956d3046f7dSMichael Pfeiffer fImageView->SetShowCaption(fShowCaption); 9576163f333SKarsten Heimrich } break; 958ad13f387SMichael Pfeiffer 959780d8a62SMichael Pfeiffer case MSG_PAGE_SETUP: 960fd952aefSRyan Leavengood _PageSetup(); 961780d8a62SMichael Pfeiffer break; 9626163f333SKarsten Heimrich 963780d8a62SMichael Pfeiffer case MSG_PREPARE_PRINT: 964fd952aefSRyan Leavengood _PrepareForPrint(); 965780d8a62SMichael Pfeiffer break; 9666163f333SKarsten Heimrich 967780d8a62SMichael Pfeiffer case MSG_PRINT: 968fd952aefSRyan Leavengood _Print(message); 969780d8a62SMichael Pfeiffer break; 970780d8a62SMichael Pfeiffer 971780d8a62SMichael Pfeiffer case MSG_ZOOM_IN: 972d3046f7dSMichael Pfeiffer fImageView->ZoomIn(); 973780d8a62SMichael Pfeiffer break; 9746163f333SKarsten Heimrich 975780d8a62SMichael Pfeiffer case MSG_ZOOM_OUT: 976d3046f7dSMichael Pfeiffer fImageView->ZoomOut(); 977780d8a62SMichael Pfeiffer break; 9786163f333SKarsten Heimrich 979e2069723SAxel Dörfler case kMsgOriginalSize: 9804fd570d3SAxel Dörfler fImageView->SetZoom(1.0); 981780d8a62SMichael Pfeiffer break; 9826163f333SKarsten Heimrich 98381b9c776SMichael Pfeiffer case MSG_SCALE_BILINEAR: 984fd952aefSRyan Leavengood fImageView->SetScaleBilinear(_ToggleMenuItem(message->what)); 98581b9c776SMichael Pfeiffer break; 986780d8a62SMichael Pfeiffer 987cd6b5cdeSAxel Dörfler case MSG_DESKTOP_BACKGROUND: 988cd6b5cdeSAxel Dörfler { 9899617074cSRyan Leavengood BMessage backgroundsMessage(B_REFS_RECEIVED); 9909617074cSRyan Leavengood backgroundsMessage.AddRef("refs", fImageView->Image()); 9910a74004cSRyan Leavengood // This is used in the Backgrounds code for scaled placement 9929617074cSRyan Leavengood backgroundsMessage.AddInt32("placement", 'scpl'); 993537a273cSHumdinger be_roster->Launch("application/x-vnd.haiku-backgrounds", 994537a273cSHumdinger &backgroundsMessage); 995cd6b5cdeSAxel Dörfler break; 996cd6b5cdeSAxel Dörfler } 997a60adbf9SAxel Dörfler 9985b76e505SStephan Aßmus case MSG_SET_RATING: 9995b76e505SStephan Aßmus { 10005b76e505SStephan Aßmus int32 rating; 10015b76e505SStephan Aßmus if (message->FindInt32("rating", &rating) != B_OK) 10025b76e505SStephan Aßmus break; 10035b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_WRITE_ONLY); 10045b76e505SStephan Aßmus if (file.InitCheck() != B_OK) 10055b76e505SStephan Aßmus break; 10065b76e505SStephan Aßmus file.WriteAttr("Media:Rating", B_INT32_TYPE, 0, &rating, 10075b76e505SStephan Aßmus sizeof(rating)); 10085b76e505SStephan Aßmus _UpdateRatingMenu(); 10095b76e505SStephan Aßmus break; 10105b76e505SStephan Aßmus } 10115b76e505SStephan Aßmus 1012cf0d8308SStephan Aßmus case kMsgToggleToolBar: 1013cf0d8308SStephan Aßmus { 1014cf0d8308SStephan Aßmus fShowToolBar = _ToggleMenuItem(message->what); 101594fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar, true); 1016cf0d8308SStephan Aßmus 1017cf0d8308SStephan Aßmus ShowImageSettings* settings = my_app->Settings(); 1018cf0d8308SStephan Aßmus 1019cf0d8308SStephan Aßmus if (settings->Lock()) { 1020cf0d8308SStephan Aßmus settings->SetBool("ShowToolBar", fShowToolBar); 1021cf0d8308SStephan Aßmus settings->Unlock(); 1022cf0d8308SStephan Aßmus } 1023cf0d8308SStephan Aßmus break; 1024cf0d8308SStephan Aßmus } 102594fd9498SStephan Aßmus case kShowToolBarIfEnabled: 102694fd9498SStephan Aßmus { 102794fd9498SStephan Aßmus bool show; 102894fd9498SStephan Aßmus if (message->FindBool("show", &show) != B_OK) 102994fd9498SStephan Aßmus break; 103094fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar && show, true); 103194fd9498SStephan Aßmus break; 103294fd9498SStephan Aßmus } 103394fd9498SStephan Aßmus case kMsgSlideToolBar: 103494fd9498SStephan Aßmus { 103594fd9498SStephan Aßmus float offset; 103694fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK) { 103794fd9498SStephan Aßmus fToolBarView->MoveBy(0, offset); 103894fd9498SStephan Aßmus fScrollView->ResizeBy(0, -offset); 103994fd9498SStephan Aßmus fScrollView->MoveBy(0, offset); 104094fd9498SStephan Aßmus fVerticalScrollBar->ResizeBy(0, -offset); 104194fd9498SStephan Aßmus fVerticalScrollBar->MoveBy(0, offset); 104294fd9498SStephan Aßmus UpdateIfNeeded(); 104394fd9498SStephan Aßmus snooze(15000); 104494fd9498SStephan Aßmus } 104594fd9498SStephan Aßmus break; 104694fd9498SStephan Aßmus } 104794fd9498SStephan Aßmus case kMsgFinishSlidingToolBar: 104894fd9498SStephan Aßmus { 104994fd9498SStephan Aßmus float offset; 105094fd9498SStephan Aßmus bool show; 105194fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK 105294fd9498SStephan Aßmus && message->FindBool("show", &show) == B_OK) { 105394fd9498SStephan Aßmus // Compensate rounding errors with the final placement 1054537a273cSHumdinger if (show) 105594fd9498SStephan Aßmus fToolBarView->MoveTo(fToolBarView->Frame().left, 0); 1056537a273cSHumdinger else { 105794fd9498SStephan Aßmus fToolBarView->MoveTo(fToolBarView->Frame().left, offset); 105894fd9498SStephan Aßmus fToolBarView->Hide(); 105994fd9498SStephan Aßmus } 106094fd9498SStephan Aßmus BRect frame = fToolBarView->Parent()->Bounds(); 106194fd9498SStephan Aßmus frame.top = fToolBarView->Frame().bottom + 1; 10622804cb33SRyan Leavengood fScrollView->MoveTo(fScrollView->Frame().left, frame.top); 106394fd9498SStephan Aßmus fScrollView->ResizeTo(fScrollView->Bounds().Width(), 106494fd9498SStephan Aßmus frame.Height() - B_H_SCROLL_BAR_HEIGHT + 1); 106594fd9498SStephan Aßmus fVerticalScrollBar->MoveTo( 106694fd9498SStephan Aßmus frame.right - B_V_SCROLL_BAR_WIDTH + 1, frame.top); 106794fd9498SStephan Aßmus fVerticalScrollBar->ResizeTo( 106894fd9498SStephan Aßmus fVerticalScrollBar->Bounds().Width(), 106994fd9498SStephan Aßmus frame.Height() - B_H_SCROLL_BAR_HEIGHT + 1); 107094fd9498SStephan Aßmus } 107194fd9498SStephan Aßmus break; 107294fd9498SStephan Aßmus } 1073cf0d8308SStephan Aßmus 107413afa642SPhil Greenway default: 1075efa8b4f3SAxel Dörfler BWindow::MessageReceived(message); 107613afa642SPhil Greenway break; 107713afa642SPhil Greenway } 107813afa642SPhil Greenway } 1079fc0a275bSMatthew Wilber 1080efa8b4f3SAxel Dörfler 1081fc0a275bSMatthew Wilber void 1082cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message) 1083cd6b5cdeSAxel Dörfler { 1084cd6b5cdeSAxel Dörfler BString status; 1085cd6b5cdeSAxel Dörfler if (fImageView->Bitmap() != NULL) { 1086cd6b5cdeSAxel Dörfler BRect bounds = fImageView->Bitmap()->Bounds(); 1087cd6b5cdeSAxel Dörfler status << bounds.IntegerWidth() + 1 1088cd6b5cdeSAxel Dörfler << "x" << bounds.IntegerHeight() + 1 << ", " << fImageType; 1089cd6b5cdeSAxel Dörfler } 1090cd6b5cdeSAxel Dörfler 1091cd6b5cdeSAxel Dörfler BString text; 1092cd6b5cdeSAxel Dörfler if (message != NULL && message->FindString("status", &text) == B_OK 1093cd6b5cdeSAxel Dörfler && text.Length() > 0) { 1094cd6b5cdeSAxel Dörfler status << ", " << text; 1095cd6b5cdeSAxel Dörfler } 1096cd6b5cdeSAxel Dörfler 1097b9767a83SAxel Dörfler fStatusView->Update(fNavigator.CurrentRef(), status); 1098cd6b5cdeSAxel Dörfler } 1099cd6b5cdeSAxel Dörfler 1100cd6b5cdeSAxel Dörfler 1101cd6b5cdeSAxel Dörfler void 1102cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref) 1103cd6b5cdeSAxel Dörfler { 1104cd6b5cdeSAxel Dörfler // TODO: give a better error message! 1105560ff447SJonas Sundström BAlert* alert = new BAlert(B_TRANSLATE_SYSTEM_NAME("ShowImage"), 1106546208a5SOliver Tappe B_TRANSLATE_CONTEXT("Could not load image! Either the " 1107ddcb5a2cSAxel Dörfler "file or an image translator for it does not exist.", 1108ddcb5a2cSAxel Dörfler "LoadAlerts"), 1109546208a5SOliver Tappe B_TRANSLATE_CONTEXT("OK", "Alerts"), NULL, NULL, 1110cd6b5cdeSAxel Dörfler B_WIDTH_AS_USUAL, B_INFO_ALERT); 1111aed35104SHumdinger alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 1112cd6b5cdeSAxel Dörfler alert->Go(); 1113cd6b5cdeSAxel Dörfler } 1114cd6b5cdeSAxel Dörfler 1115cd6b5cdeSAxel Dörfler 1116cd6b5cdeSAxel Dörfler void 1117fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message) 1118fc0a275bSMatthew Wilber { 1119cdb89ebbSMatthew Wilber // Read the translator and output type the user chose 1120cdb89ebbSMatthew Wilber translator_id outTranslator; 1121cdb89ebbSMatthew Wilber uint32 outType; 11226163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 1123efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 11246163f333SKarsten Heimrich || message->FindInt32(kTypeField, 1125cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 1126fc0a275bSMatthew Wilber return; 1127fc0a275bSMatthew Wilber 1128cdb89ebbSMatthew Wilber // Add the chosen translator and output type to the 1129cdb89ebbSMatthew Wilber // message that the save panel will send back 1130c1a10c14SKarsten Heimrich BMessage panelMsg(MSG_SAVE_PANEL); 1131c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTranslatorField, outTranslator); 1132c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTypeField, outType); 1133cdb89ebbSMatthew Wilber 1134cdb89ebbSMatthew Wilber // Create save panel and show it 11356163f333SKarsten Heimrich BMessenger target(this); 1136efa8b4f3SAxel Dörfler fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL, 1137c1a10c14SKarsten Heimrich &target, NULL, 0, false, &panelMsg); 1138d3046f7dSMichael Pfeiffer if (!fSavePanel) 1139fc0a275bSMatthew Wilber return; 1140a60adbf9SAxel Dörfler 1141d3046f7dSMichael Pfeiffer fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE); 1142d3046f7dSMichael Pfeiffer fSavePanel->Show(); 1143fc0a275bSMatthew Wilber } 1144fc0a275bSMatthew Wilber 1145efa8b4f3SAxel Dörfler 1146fc0a275bSMatthew Wilber void 1147fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message) 1148fc0a275bSMatthew Wilber { 1149cdb89ebbSMatthew Wilber // Read in where the file should be saved 1150efa8b4f3SAxel Dörfler entry_ref dirRef; 1151efa8b4f3SAxel Dörfler if (message->FindRef("directory", &dirRef) != B_OK) 1152fc0a275bSMatthew Wilber return; 1153efa8b4f3SAxel Dörfler 1154fc0a275bSMatthew Wilber const char* filename; 1155efa8b4f3SAxel Dörfler if (message->FindString("name", &filename) != B_OK) 1156fc0a275bSMatthew Wilber return; 1157fc0a275bSMatthew Wilber 1158cdb89ebbSMatthew Wilber // Read in the translator and type to be used 1159cdb89ebbSMatthew Wilber // to save the output image 1160cdb89ebbSMatthew Wilber translator_id outTranslator; 1161cdb89ebbSMatthew Wilber uint32 outType; 11626163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 1163efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 11646163f333SKarsten Heimrich || message->FindInt32(kTypeField, 1165cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 1166cdb89ebbSMatthew Wilber return; 1167cdb89ebbSMatthew Wilber 1168a7e78e3bSMatthew Wilber // Find the translator_format information needed to 1169a7e78e3bSMatthew Wilber // write a MIME attribute for the image file 1170a7e78e3bSMatthew Wilber BTranslatorRoster* roster = BTranslatorRoster::Default(); 1171efa8b4f3SAxel Dörfler const translation_format* outFormat = NULL; 1172efa8b4f3SAxel Dörfler int32 outCount = 0; 1173efa8b4f3SAxel Dörfler if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK 1174efa8b4f3SAxel Dörfler || outCount < 1) 1175a7e78e3bSMatthew Wilber return; 1176efa8b4f3SAxel Dörfler 1177a7e78e3bSMatthew Wilber int32 i; 1178efa8b4f3SAxel Dörfler for (i = 0; i < outCount; i++) { 1179537a273cSHumdinger if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type 1180537a273cSHumdinger == outType) 1181a7e78e3bSMatthew Wilber break; 1182a7e78e3bSMatthew Wilber } 1183efa8b4f3SAxel Dörfler if (i == outCount) 1184fc0a275bSMatthew Wilber return; 1185fc0a275bSMatthew Wilber 1186a7e78e3bSMatthew Wilber // Write out the image file 1187efa8b4f3SAxel Dörfler BDirectory dir(&dirRef); 1188efa8b4f3SAxel Dörfler fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]); 1189fc0a275bSMatthew Wilber } 1190fc0a275bSMatthew Wilber 1191efa8b4f3SAxel Dörfler 1192546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 1193546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "ClosePrompt" 11941ed4535fSStephan Aßmus 1195b9767a83SAxel Dörfler 1196cdb89ebbSMatthew Wilber bool 1197fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt() 1198ee7b4f39SMatthew Wilber { 1199ee7b4f39SMatthew Wilber if (!fModified) 1200ee7b4f39SMatthew Wilber return true; 1201efa8b4f3SAxel Dörfler 1202cd6b5cdeSAxel Dörfler int32 count = fNavigator.PageCount(); 1203cd6b5cdeSAxel Dörfler int32 page = fNavigator.CurrentPage(); 1204cd6b5cdeSAxel Dörfler BString prompt; 1205efa8b4f3SAxel Dörfler 12061ed4535fSStephan Aßmus if (count > 1) { 12071ed4535fSStephan Aßmus bs_printf(&prompt, 1208905c8c8cSMatt Madia B_TRANSLATE("The document '%s' (page %d) has been changed. Do you " 1209905c8c8cSMatt Madia "want to close the document?"), 1210cd6b5cdeSAxel Dörfler fImageView->Image()->name, page); 12111ed4535fSStephan Aßmus } else { 12121ed4535fSStephan Aßmus bs_printf(&prompt, 1213905c8c8cSMatt Madia B_TRANSLATE("The document '%s' has been changed. Do you want to " 1214905c8c8cSMatt Madia "close the document?"), 1215cd6b5cdeSAxel Dörfler fImageView->Image()->name); 12161ed4535fSStephan Aßmus } 12171ed4535fSStephan Aßmus 1218cd6b5cdeSAxel Dörfler BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(), 1219905c8c8cSMatt Madia B_TRANSLATE("Cancel"), B_TRANSLATE("Close")); 1220aed35104SHumdinger alert->SetShortcut(0, B_ESCAPE); 1221aed35104SHumdinger 1222cd6b5cdeSAxel Dörfler if (alert->Go() == 0) { 1223ee7b4f39SMatthew Wilber // Cancel 1224ee7b4f39SMatthew Wilber return false; 1225cd6b5cdeSAxel Dörfler } 1226cd6b5cdeSAxel Dörfler 1227ee7b4f39SMatthew Wilber // Close 1228187f0b8aSMatthew Wilber fModified = false; 1229ee7b4f39SMatthew Wilber return true; 1230ee7b4f39SMatthew Wilber } 1231ee7b4f39SMatthew Wilber 1232cdb89ebbSMatthew Wilber 1233b9767a83SAxel Dörfler status_t 1234a569816bSAxel Dörfler ShowImageWindow::_LoadImage(bool forward) 1235b9767a83SAxel Dörfler { 1236b9767a83SAxel Dörfler BMessenger us(this); 1237a569816bSAxel Dörfler status_t status = ImageCache::Default().RetrieveImage( 1238a569816bSAxel Dörfler fNavigator.CurrentRef(), fNavigator.CurrentPage(), &us); 1239a569816bSAxel Dörfler if (status != B_OK) 1240a569816bSAxel Dörfler return status; 1241a569816bSAxel Dörfler 1242e2069723SAxel Dörfler fProgressWindow->Start(this); 1243e2069723SAxel Dörfler 1244a569816bSAxel Dörfler // Preload previous/next images - two in the navigation direction, one 1245a569816bSAxel Dörfler // in the opposite direction. 1246a569816bSAxel Dörfler 1247a569816bSAxel Dörfler entry_ref nextRef = fNavigator.CurrentRef(); 1248a569816bSAxel Dörfler if (_PreloadImage(forward, nextRef)) 1249a569816bSAxel Dörfler _PreloadImage(forward, nextRef); 1250a569816bSAxel Dörfler 1251a569816bSAxel Dörfler entry_ref previousRef = fNavigator.CurrentRef(); 1252a569816bSAxel Dörfler _PreloadImage(!forward, previousRef); 1253a569816bSAxel Dörfler 1254a569816bSAxel Dörfler return B_OK; 1255a569816bSAxel Dörfler } 1256a569816bSAxel Dörfler 1257a569816bSAxel Dörfler 1258a569816bSAxel Dörfler bool 1259a569816bSAxel Dörfler ShowImageWindow::_PreloadImage(bool forward, entry_ref& ref) 1260a569816bSAxel Dörfler { 1261a569816bSAxel Dörfler entry_ref currentRef = ref; 1262a569816bSAxel Dörfler if ((forward && !fNavigator.GetNextFile(currentRef, ref)) 1263a569816bSAxel Dörfler || (!forward && !fNavigator.GetPreviousFile(currentRef, ref))) 1264a569816bSAxel Dörfler return false; 1265a569816bSAxel Dörfler 1266a569816bSAxel Dörfler return ImageCache::Default().RetrieveImage(ref) == B_OK; 1267b9767a83SAxel Dörfler } 1268b9767a83SAxel Dörfler 1269b9767a83SAxel Dörfler 1270ad13f387SMichael Pfeiffer void 1271fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen() 1272ad13f387SMichael Pfeiffer { 1273ad13f387SMichael Pfeiffer BRect frame; 1274ad13f387SMichael Pfeiffer fFullScreen = !fFullScreen; 1275ad13f387SMichael Pfeiffer if (fFullScreen) { 1276ad13f387SMichael Pfeiffer BScreen screen; 1277ad13f387SMichael Pfeiffer fWindowFrame = Frame(); 1278ad13f387SMichael Pfeiffer frame = screen.Frame(); 1279d3046f7dSMichael Pfeiffer frame.top -= fBar->Bounds().Height() + 1; 128067eb2a04SHumdinger frame.right += B_V_SCROLL_BAR_WIDTH; 1281ad13f387SMichael Pfeiffer frame.bottom += B_H_SCROLL_BAR_HEIGHT; 1282ad13f387SMichael Pfeiffer frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView 1283ad13f387SMichael Pfeiffer 1284ad13f387SMichael Pfeiffer SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE); 1285c0b16687SAxel Dörfler 1286c0b16687SAxel Dörfler Activate(); 1287c0b16687SAxel Dörfler // make the window frontmost 1288ad13f387SMichael Pfeiffer } else { 1289ad13f387SMichael Pfeiffer frame = fWindowFrame; 1290ad13f387SMichael Pfeiffer 1291ad13f387SMichael Pfeiffer SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); 1292ad13f387SMichael Pfeiffer } 1293efa8b4f3SAxel Dörfler 129494fd9498SStephan Aßmus fToolBarView->SetActionVisible(MSG_FULL_SCREEN, fFullScreen); 1295cf0d8308SStephan Aßmus _SetToolBarVisible(!fFullScreen && fShowToolBar); 1296cf0d8308SStephan Aßmus 1297ad13f387SMichael Pfeiffer MoveTo(frame.left, frame.top); 1298ad13f387SMichael Pfeiffer ResizeTo(frame.Width(), frame.Height()); 1299e2069723SAxel Dörfler 1300e2069723SAxel Dörfler fImageView->SetHideIdlingCursor(fFullScreen); 1301e2069723SAxel Dörfler fImageView->SetShowCaption(fFullScreen && fShowCaption); 1302eaa910c5SAxel Dörfler 130348ae3e38SAxel Dörfler Layout(false); 130448ae3e38SAxel Dörfler // We need to manually relayout here, as the views are layouted 130548ae3e38SAxel Dörfler // asynchronously, and FitToBounds() would still have the wrong size 1306e2069723SAxel Dörfler fImageView->FitToBounds(); 1307ad13f387SMichael Pfeiffer } 1308ad13f387SMichael Pfeiffer 1309efa8b4f3SAxel Dörfler 1310d3046f7dSMichael Pfeiffer void 13112281340dSAxel Dörfler ShowImageWindow::_ApplySettings() 1312d3046f7dSMichael Pfeiffer { 1313efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1314efa8b4f3SAxel Dörfler 1315d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1316d3046f7dSMichael Pfeiffer fShowCaption = settings->GetBool("ShowCaption", fShowCaption); 1317d3046f7dSMichael Pfeiffer fPrintOptions.SetBounds(BRect(0, 0, 1023, 767)); 1318d3046f7dSMichael Pfeiffer 13194aa63633SAxel Dörfler fSlideShowDelay = settings->GetTime("SlideShowDelay", fSlideShowDelay); 1320d3046f7dSMichael Pfeiffer 13214aa63633SAxel Dörfler fPrintOptions.SetOption((enum PrintOptions::Option)settings->GetInt32( 13224aa63633SAxel Dörfler "PO:Option", fPrintOptions.Option())); 13234aa63633SAxel Dörfler fPrintOptions.SetZoomFactor( 13244aa63633SAxel Dörfler settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor())); 13254aa63633SAxel Dörfler fPrintOptions.SetDPI(settings->GetFloat("PO:DPI", fPrintOptions.DPI())); 13264aa63633SAxel Dörfler fPrintOptions.SetWidth( 13274aa63633SAxel Dörfler settings->GetFloat("PO:Width", fPrintOptions.Width())); 13284aa63633SAxel Dörfler fPrintOptions.SetHeight( 13294aa63633SAxel Dörfler settings->GetFloat("PO:Height", fPrintOptions.Height())); 1330d3046f7dSMichael Pfeiffer 1331cf0d8308SStephan Aßmus fShowToolBar = settings->GetBool("ShowToolBar", fShowToolBar); 1332cf0d8308SStephan Aßmus 1333d3046f7dSMichael Pfeiffer settings->Unlock(); 1334d3046f7dSMichael Pfeiffer } 1335d3046f7dSMichael Pfeiffer } 1336d3046f7dSMichael Pfeiffer 1337efa8b4f3SAxel Dörfler 1338d3046f7dSMichael Pfeiffer void 1339fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions() 1340d3046f7dSMichael Pfeiffer { 1341efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1342efa8b4f3SAxel Dörfler 1343d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1344d3046f7dSMichael Pfeiffer settings->SetInt32("PO:Option", fPrintOptions.Option()); 1345d3046f7dSMichael Pfeiffer settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor()); 1346d3046f7dSMichael Pfeiffer settings->SetFloat("PO:DPI", fPrintOptions.DPI()); 1347d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Width", fPrintOptions.Width()); 1348d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Height", fPrintOptions.Height()); 1349d3046f7dSMichael Pfeiffer settings->Unlock(); 1350d3046f7dSMichael Pfeiffer } 1351d3046f7dSMichael Pfeiffer } 1352d3046f7dSMichael Pfeiffer 1353efa8b4f3SAxel Dörfler 1354cdb89ebbSMatthew Wilber bool 1355fd952aefSRyan Leavengood ShowImageWindow::_PageSetup() 1356780d8a62SMichael Pfeiffer { 1357cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 1358efa8b4f3SAxel Dörfler if (fPrintSettings != NULL) 1359780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 1360efa8b4f3SAxel Dörfler 13616163f333SKarsten Heimrich status_t status = printJob.ConfigPage(); 13626163f333SKarsten Heimrich if (status == B_OK) { 1363780d8a62SMichael Pfeiffer delete fPrintSettings; 1364780d8a62SMichael Pfeiffer fPrintSettings = printJob.Settings(); 1365780d8a62SMichael Pfeiffer } 1366efa8b4f3SAxel Dörfler 13676163f333SKarsten Heimrich return status == B_OK; 1368780d8a62SMichael Pfeiffer } 1369780d8a62SMichael Pfeiffer 1370efa8b4f3SAxel Dörfler 1371780d8a62SMichael Pfeiffer void 1372fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint() 1373780d8a62SMichael Pfeiffer { 13746163f333SKarsten Heimrich if (fPrintSettings == NULL) { 1375cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 13766163f333SKarsten Heimrich if (printJob.ConfigJob() == B_OK) 13776163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 13786163f333SKarsten Heimrich } 1379780d8a62SMichael Pfeiffer 1380cd6b5cdeSAxel Dörfler fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds()); 1381cd6b5cdeSAxel Dörfler fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1); 1382780d8a62SMichael Pfeiffer 1383efa8b4f3SAxel Dörfler new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50), 1384efa8b4f3SAxel Dörfler &fPrintOptions, this); 1385780d8a62SMichael Pfeiffer } 1386780d8a62SMichael Pfeiffer 1387efa8b4f3SAxel Dörfler 1388780d8a62SMichael Pfeiffer void 1389fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg) 1390780d8a62SMichael Pfeiffer { 1391780d8a62SMichael Pfeiffer status_t st; 1392efa8b4f3SAxel Dörfler if (msg->FindInt32("status", &st) != B_OK || st != B_OK) 1393780d8a62SMichael Pfeiffer return; 1394780d8a62SMichael Pfeiffer 1395fd952aefSRyan Leavengood _SavePrintOptions(); 1396d3046f7dSMichael Pfeiffer 1397cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 13986163f333SKarsten Heimrich if (fPrintSettings) 1399780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 14006163f333SKarsten Heimrich 1401780d8a62SMichael Pfeiffer if (printJob.ConfigJob() == B_OK) { 14026163f333SKarsten Heimrich delete fPrintSettings; 14036163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 1404780d8a62SMichael Pfeiffer 1405780d8a62SMichael Pfeiffer // first/lastPage is unused for now 14063177ae77SStefano Ceccherini int32 firstPage = printJob.FirstPage(); 14073177ae77SStefano Ceccherini int32 lastPage = printJob.LastPage(); 14086163f333SKarsten Heimrich BRect printableRect = printJob.PrintableRect(); 14096163f333SKarsten Heimrich 1410efa8b4f3SAxel Dörfler if (firstPage < 1) 1411780d8a62SMichael Pfeiffer firstPage = 1; 1412efa8b4f3SAxel Dörfler if (lastPage < firstPage) 1413780d8a62SMichael Pfeiffer lastPage = firstPage; 1414780d8a62SMichael Pfeiffer 1415cd6b5cdeSAxel Dörfler BBitmap* bitmap = fImageView->Bitmap(); 14163177ae77SStefano Ceccherini float imageWidth = bitmap->Bounds().Width() + 1.0; 14173177ae77SStefano Ceccherini float imageHeight = bitmap->Bounds().Height() + 1.0; 1418780d8a62SMichael Pfeiffer 14196163f333SKarsten Heimrich float width; 1420780d8a62SMichael Pfeiffer switch (fPrintOptions.Option()) { 14216163f333SKarsten Heimrich case PrintOptions::kFitToPage: { 14226163f333SKarsten Heimrich float w1 = printableRect.Width() + 1; 1423cd6b5cdeSAxel Dörfler float w2 = imageWidth * (printableRect.Height() + 1) 1424cd6b5cdeSAxel Dörfler / imageHeight; 1425efa8b4f3SAxel Dörfler if (w2 < w1) 1426780d8a62SMichael Pfeiffer width = w2; 1427efa8b4f3SAxel Dörfler else 1428780d8a62SMichael Pfeiffer width = w1; 14296163f333SKarsten Heimrich } break; 1430780d8a62SMichael Pfeiffer case PrintOptions::kZoomFactor: 1431780d8a62SMichael Pfeiffer width = imageWidth * fPrintOptions.ZoomFactor(); 1432780d8a62SMichael Pfeiffer break; 1433780d8a62SMichael Pfeiffer case PrintOptions::kDPI: 1434780d8a62SMichael Pfeiffer width = imageWidth * 72.0 / fPrintOptions.DPI(); 1435780d8a62SMichael Pfeiffer break; 1436780d8a62SMichael Pfeiffer case PrintOptions::kWidth: 1437780d8a62SMichael Pfeiffer case PrintOptions::kHeight: 1438780d8a62SMichael Pfeiffer width = fPrintOptions.Width(); 1439780d8a62SMichael Pfeiffer break; 1440efa8b4f3SAxel Dörfler 1441780d8a62SMichael Pfeiffer default: 1442780d8a62SMichael Pfeiffer // keep compiler silent; should not reach here 1443780d8a62SMichael Pfeiffer width = imageWidth; 1444780d8a62SMichael Pfeiffer } 1445780d8a62SMichael Pfeiffer 1446efa8b4f3SAxel Dörfler // TODO: eventually print large images on several pages 1447780d8a62SMichael Pfeiffer printJob.BeginJob(); 1448d3046f7dSMichael Pfeiffer fImageView->SetScale(width / imageWidth); 14495eb50e46SMichael Pfeiffer // coordinates are relative to printable rectangle 14505eb50e46SMichael Pfeiffer BRect bounds(bitmap->Bounds()); 14515eb50e46SMichael Pfeiffer printJob.DrawView(fImageView, bounds, BPoint(0, 0)); 1452d3046f7dSMichael Pfeiffer fImageView->SetScale(1.0); 1453780d8a62SMichael Pfeiffer printJob.SpoolPage(); 1454780d8a62SMichael Pfeiffer printJob.CommitJob(); 1455780d8a62SMichael Pfeiffer } 1456780d8a62SMichael Pfeiffer } 1457780d8a62SMichael Pfeiffer 145856b0c7b9SKarsten Heimrich 14594aa63633SAxel Dörfler void 14604aa63633SAxel Dörfler ShowImageWindow::_SetSlideShowDelay(bigtime_t delay) 14614aa63633SAxel Dörfler { 14624aa63633SAxel Dörfler if (fSlideShowDelay == delay) 14634aa63633SAxel Dörfler return; 14644aa63633SAxel Dörfler 14654aa63633SAxel Dörfler fSlideShowDelay = delay; 14664aa63633SAxel Dörfler 14674aa63633SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 14684aa63633SAxel Dörfler if (settings->Lock()) { 14694aa63633SAxel Dörfler settings->SetTime("SlideShowDelay", fSlideShowDelay); 14704aa63633SAxel Dörfler settings->Unlock(); 14714aa63633SAxel Dörfler } 14724aa63633SAxel Dörfler 14734aa63633SAxel Dörfler if (fSlideShowRunner != NULL) 14744aa63633SAxel Dörfler _StartSlideShow(); 14754aa63633SAxel Dörfler } 14764aa63633SAxel Dörfler 14774aa63633SAxel Dörfler 14784aa63633SAxel Dörfler void 14794aa63633SAxel Dörfler ShowImageWindow::_StartSlideShow() 14804aa63633SAxel Dörfler { 14814aa63633SAxel Dörfler _StopSlideShow(); 14824aa63633SAxel Dörfler 14834aa63633SAxel Dörfler BMessage nextSlide(kMsgNextSlide); 14844aa63633SAxel Dörfler fSlideShowRunner = new BMessageRunner(this, &nextSlide, fSlideShowDelay); 14854aa63633SAxel Dörfler } 14864aa63633SAxel Dörfler 14874aa63633SAxel Dörfler 14884aa63633SAxel Dörfler void 14894aa63633SAxel Dörfler ShowImageWindow::_StopSlideShow() 14904aa63633SAxel Dörfler { 14914aa63633SAxel Dörfler if (fSlideShowRunner != NULL) { 14924aa63633SAxel Dörfler delete fSlideShowRunner; 14934aa63633SAxel Dörfler fSlideShowRunner = NULL; 14944aa63633SAxel Dörfler } 14954aa63633SAxel Dörfler } 14964aa63633SAxel Dörfler 14974aa63633SAxel Dörfler 14985b76e505SStephan Aßmus void 14995b76e505SStephan Aßmus ShowImageWindow::_UpdateRatingMenu() 15005b76e505SStephan Aßmus { 15015b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_READ_ONLY); 15025b76e505SStephan Aßmus if (file.InitCheck() != B_OK) 15035b76e505SStephan Aßmus return; 15045b76e505SStephan Aßmus int32 rating; 15055b76e505SStephan Aßmus ssize_t size = sizeof(rating); 15065b76e505SStephan Aßmus if (file.ReadAttr("Media:Rating", B_INT32_TYPE, 0, &rating, size) != size) 15075b76e505SStephan Aßmus rating = 0; 15085b76e505SStephan Aßmus // TODO: Finding the correct item could be more robust, like by looking 15095b76e505SStephan Aßmus // at the message of each item. 15105b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) { 15115b76e505SStephan Aßmus BMenuItem* item = fRatingMenu->ItemAt(i - 1); 15125b76e505SStephan Aßmus if (item == NULL) 15135b76e505SStephan Aßmus break; 15145b76e505SStephan Aßmus item->SetMarked(i == rating); 15155b76e505SStephan Aßmus } 15165b76e505SStephan Aßmus } 15175b76e505SStephan Aßmus 15185b76e505SStephan Aßmus 1519cf0d8308SStephan Aßmus void 152094fd9498SStephan Aßmus ShowImageWindow::_SetToolBarVisible(bool visible, bool animate) 1521cf0d8308SStephan Aßmus { 1522cf0d8308SStephan Aßmus if (visible == !fToolBarView->IsHidden()) 1523cf0d8308SStephan Aßmus return; 1524cf0d8308SStephan Aßmus 152594fd9498SStephan Aßmus float diff = fToolBarView->Bounds().Height() + 2; 152694fd9498SStephan Aßmus if (!visible) 1527cf0d8308SStephan Aßmus diff = -diff; 152894fd9498SStephan Aßmus else 152994fd9498SStephan Aßmus fToolBarView->Show(); 1530cf0d8308SStephan Aßmus 153194fd9498SStephan Aßmus if (animate) { 153294fd9498SStephan Aßmus // Slide the controls into view. We do this with messages in order 153394fd9498SStephan Aßmus // not to block the window thread. 153494fd9498SStephan Aßmus const float kAnimationOffsets[] = { 0.05, 0.2, 0.5, 0.2, 0.05 }; 153594fd9498SStephan Aßmus const int32 steps = sizeof(kAnimationOffsets) / sizeof(float); 153694fd9498SStephan Aßmus float originalY = fToolBarView->Frame().top; 153794fd9498SStephan Aßmus for (int32 i = 0; i < steps; i++) { 153894fd9498SStephan Aßmus BMessage message(kMsgSlideToolBar); 153994fd9498SStephan Aßmus message.AddFloat("offset", floorf(diff * kAnimationOffsets[i])); 154094fd9498SStephan Aßmus PostMessage(&message, this); 154194fd9498SStephan Aßmus } 154294fd9498SStephan Aßmus BMessage finalMessage(kMsgFinishSlidingToolBar); 154394fd9498SStephan Aßmus finalMessage.AddFloat("offset", originalY + diff); 154494fd9498SStephan Aßmus finalMessage.AddBool("show", visible); 154594fd9498SStephan Aßmus PostMessage(&finalMessage, this); 154694fd9498SStephan Aßmus } else { 1547cf0d8308SStephan Aßmus fScrollView->ResizeBy(0, -diff); 1548cf0d8308SStephan Aßmus fScrollView->MoveBy(0, diff); 1549cf0d8308SStephan Aßmus fVerticalScrollBar->ResizeBy(0, -diff); 1550cf0d8308SStephan Aßmus fVerticalScrollBar->MoveBy(0, diff); 1551162e5c80SRyan Leavengood fToolBarView->MoveBy(0, diff); 155294fd9498SStephan Aßmus if (!visible) 155394fd9498SStephan Aßmus fToolBarView->Hide(); 155494fd9498SStephan Aßmus } 1555cf0d8308SStephan Aßmus } 1556cf0d8308SStephan Aßmus 1557cf0d8308SStephan Aßmus 1558780d8a62SMichael Pfeiffer bool 1559cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested() 1560cdb89ebbSMatthew Wilber { 1561efa8b4f3SAxel Dörfler if (fSavePanel) { 1562efa8b4f3SAxel Dörfler // Don't allow this window to be closed if a save panel is open 1563efa8b4f3SAxel Dörfler return false; 1564cdb89ebbSMatthew Wilber } 1565cdb89ebbSMatthew Wilber 15665b76e505SStephan Aßmus if (!_ClosePrompt()) 15675b76e505SStephan Aßmus return false; 15685b76e505SStephan Aßmus 15695b76e505SStephan Aßmus ShowImageSettings* settings = my_app->Settings(); 15705b76e505SStephan Aßmus if (settings->Lock()) { 1571c418e2beSStephan Aßmus if (fFullScreen) 1572c418e2beSStephan Aßmus settings->SetRect("WindowFrame", fWindowFrame); 1573c418e2beSStephan Aßmus else 15745b76e505SStephan Aßmus settings->SetRect("WindowFrame", Frame()); 15755b76e505SStephan Aßmus settings->Unlock(); 15765b76e505SStephan Aßmus } 15775b76e505SStephan Aßmus 15785b76e505SStephan Aßmus be_app->PostMessage(MSG_WINDOW_HAS_QUIT); 15795b76e505SStephan Aßmus 15805b76e505SStephan Aßmus return true; 1581efa8b4f3SAxel Dörfler } 1582