1efa8b4f3SAxel Dörfler /* 24fd570d3SAxel Dörfler * Copyright 2003-2010, 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 13efa8b4f3SAxel Dörfler */ 1413afa642SPhil Greenway 154fd570d3SAxel Dörfler 16efa8b4f3SAxel Dörfler #include "ShowImageWindow.h" 17efa8b4f3SAxel Dörfler 18fd952aefSRyan Leavengood #include <new> 19fd952aefSRyan Leavengood #include <stdio.h> 2004f96544SAxel Dörfler #include <stdlib.h> 216163f333SKarsten Heimrich 22efa8b4f3SAxel Dörfler #include <Alert.h> 2313afa642SPhil Greenway #include <Application.h> 2413afa642SPhil Greenway #include <Bitmap.h> 25fc0a275bSMatthew Wilber #include <BitmapStream.h> 261ed4535fSStephan Aßmus #include <Catalog.h> 27efa8b4f3SAxel Dörfler #include <Clipboard.h> 2813afa642SPhil Greenway #include <Entry.h> 29fc0a275bSMatthew Wilber #include <File.h> 306163f333SKarsten Heimrich #include <FilePanel.h> 311ed4535fSStephan Aßmus #include <Locale.h> 3213afa642SPhil Greenway #include <Menu.h> 3313afa642SPhil Greenway #include <MenuBar.h> 3413afa642SPhil Greenway #include <MenuItem.h> 3513afa642SPhil Greenway #include <Path.h> 36efa8b4f3SAxel Dörfler #include <PrintJob.h> 3736272f0dSAxel Dörfler #include <RecentItems.h> 38efa8b4f3SAxel Dörfler #include <Roster.h> 39efa8b4f3SAxel Dörfler #include <Screen.h> 4013afa642SPhil Greenway #include <ScrollView.h> 416163f333SKarsten Heimrich #include <String.h> 42efa8b4f3SAxel Dörfler #include <SupportDefs.h> 436163f333SKarsten Heimrich #include <TranslationDefs.h> 4413afa642SPhil Greenway #include <TranslationUtils.h> 4513afa642SPhil Greenway #include <TranslatorRoster.h> 4613afa642SPhil Greenway 47b9767a83SAxel Dörfler #include "ImageCache.h" 48fd952aefSRyan Leavengood #include "ShowImageApp.h" 49fd952aefSRyan Leavengood #include "ShowImageConstants.h" 50fd952aefSRyan Leavengood #include "ShowImageStatusView.h" 51fd952aefSRyan Leavengood #include "ShowImageView.h" 5213afa642SPhil Greenway 53a8fc7138SMichael Pfeiffer 54cd6b5cdeSAxel Dörfler // BMessage field names used in Save messages 55cd6b5cdeSAxel Dörfler const char* kTypeField = "be:type"; 56cd6b5cdeSAxel Dörfler const char* kTranslatorField = "be:translator"; 57cd6b5cdeSAxel Dörfler 58cd6b5cdeSAxel Dörfler 59cd6b5cdeSAxel Dörfler // This is temporary solution for building BString with printf like format. 60cd6b5cdeSAxel Dörfler // will be removed in the future. 61cd6b5cdeSAxel Dörfler static void 62cd6b5cdeSAxel Dörfler bs_printf(BString* string, const char* format, ...) 63cd6b5cdeSAxel Dörfler { 64cd6b5cdeSAxel Dörfler va_list ap; 65cd6b5cdeSAxel Dörfler char* buf; 66cd6b5cdeSAxel Dörfler 67cd6b5cdeSAxel Dörfler va_start(ap, format); 68cd6b5cdeSAxel Dörfler vasprintf(&buf, format, ap); 69cd6b5cdeSAxel Dörfler string->SetTo(buf); 70cd6b5cdeSAxel Dörfler free(buf); 71cd6b5cdeSAxel Dörfler va_end(ap); 72cd6b5cdeSAxel Dörfler } 73cd6b5cdeSAxel Dörfler 74cd6b5cdeSAxel Dörfler 756163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow 766163f333SKarsten Heimrich 776163f333SKarsten Heimrich 78ba3217eeSAxel Dörfler ShowImageWindow::ShowImageWindow(const entry_ref& ref, 79efa8b4f3SAxel Dörfler const BMessenger& trackerMessenger) 80fd952aefSRyan Leavengood : 81fd952aefSRyan Leavengood BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0), 82b9767a83SAxel Dörfler fNavigator(ref, trackerMessenger), 83fd952aefSRyan Leavengood fSavePanel(NULL), 84fd952aefSRyan Leavengood fBar(NULL), 85fd952aefSRyan Leavengood fBrowseMenu(NULL), 86fd952aefSRyan Leavengood fGoToPageMenu(NULL), 87fd952aefSRyan Leavengood fSlideShowDelay(NULL), 88fd952aefSRyan Leavengood fImageView(NULL), 89fd952aefSRyan Leavengood fStatusView(NULL), 90fd952aefSRyan Leavengood fModified(false), 91fd952aefSRyan Leavengood fFullScreen(false), 92fd952aefSRyan Leavengood fShowCaption(true), 9304f96544SAxel Dörfler fPrintSettings(NULL) 9413afa642SPhil Greenway { 952281340dSAxel Dörfler _ApplySettings(); 96fc0a275bSMatthew Wilber 9713afa642SPhil Greenway // create menu bar 98e9dcd874SAxel Dörfler fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar"); 99b9767a83SAxel Dörfler _AddMenus(fBar); 100e9dcd874SAxel Dörfler AddChild(fBar); 10113afa642SPhil Greenway 10213afa642SPhil Greenway BRect viewFrame = Bounds(); 103e9dcd874SAxel Dörfler viewFrame.top = fBar->Bounds().Height() + 1; 10413afa642SPhil Greenway viewFrame.right -= B_V_SCROLL_BAR_WIDTH; 10513afa642SPhil Greenway viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; 10613afa642SPhil Greenway 10713afa642SPhil Greenway // create the image view 108d3046f7dSMichael Pfeiffer fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL, 1097eca0987SMichael Pfeiffer B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED); 11013afa642SPhil Greenway // wrap a scroll view around the view 111efa8b4f3SAxel Dörfler BScrollView* scrollView = new BScrollView("image_scroller", fImageView, 112cdb89ebbSMatthew Wilber B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER); 113efa8b4f3SAxel Dörfler AddChild(scrollView); 11413afa642SPhil Greenway 11507caaa8eSMatthew Wilber const int32 kstatusWidth = 190; 116cdb89ebbSMatthew Wilber BRect rect; 11713afa642SPhil Greenway rect = Bounds(); 11813afa642SPhil Greenway rect.top = viewFrame.bottom + 1; 11907caaa8eSMatthew Wilber rect.left = viewFrame.left + kstatusWidth; 1200916ab53SMatthew Wilber rect.right = viewFrame.right + 1; 1210916ab53SMatthew Wilber rect.bottom += 1; 122efa8b4f3SAxel Dörfler BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll", 123efa8b4f3SAxel Dörfler fImageView, 0, 150, B_HORIZONTAL); 124efa8b4f3SAxel Dörfler AddChild(horizontalScrollBar); 12513afa642SPhil Greenway 12613afa642SPhil Greenway rect.left = 0; 12707caaa8eSMatthew Wilber rect.right = kstatusWidth - 1; 1280cd4ecd8SStephan Aßmus rect.bottom -= 1; 129d3046f7dSMichael Pfeiffer fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM, 130cdb89ebbSMatthew Wilber B_WILL_DRAW); 131d3046f7dSMichael Pfeiffer AddChild(fStatusView); 13213afa642SPhil Greenway 13313afa642SPhil Greenway rect = Bounds(); 1340916ab53SMatthew Wilber rect.top = viewFrame.top - 1; 13513afa642SPhil Greenway rect.left = viewFrame.right + 1; 1360916ab53SMatthew Wilber rect.bottom = viewFrame.bottom + 1; 1370916ab53SMatthew Wilber rect.right += 1; 138efa8b4f3SAxel Dörfler BScrollBar* verticalScrollBar = new BScrollBar(rect, "vscroll", fImageView, 139efa8b4f3SAxel Dörfler 0, 150, B_VERTICAL); 140efa8b4f3SAxel Dörfler AddChild(verticalScrollBar); 14113afa642SPhil Greenway 14203839579SMatthew Wilber SetSizeLimits(250, 100000, 100, 100000); 14313afa642SPhil Greenway 144134d6076SMichael Pfeiffer // finish creating the window 145b9767a83SAxel Dörfler if (_LoadImage() != B_OK) { 146ba3217eeSAxel Dörfler _LoadError(ref); 1475e09d5dbSRyan Leavengood Quit(); 14801939af6SAxel Dörfler return; 149d10d5947SMichael Pfeiffer } 150402c09e5SMatthew Wilber 151d9f6762dSMichael Pfeiffer // add View menu here so it can access ShowImageView methods 152ddcb5a2cSAxel Dörfler BMenu* menu = new BMenu(B_TRANSLATE_WITH_CONTEXT("View", "Menus")); 153fd952aefSRyan Leavengood _BuildViewMenu(menu, false); 154d9f6762dSMichael Pfeiffer fBar->AddItem(menu); 155d9f6762dSMichael Pfeiffer 156d9f6762dSMichael Pfeiffer SetPulseRate(100000); 157d9f6762dSMichael Pfeiffer // every 1/10 second; ShowImageView needs it for marching ants 158d9f6762dSMichael Pfeiffer 1596db01936SAxel Dörfler _MarkMenuItem(menu, MSG_SELECTION_MODE, 1606db01936SAxel Dörfler fImageView->IsSelectionModeEnabled()); 1616db01936SAxel Dörfler 162402c09e5SMatthew Wilber // Tell application object to query the clipboard 163402c09e5SMatthew Wilber // and tell this window if it contains interesting data or not 164402c09e5SMatthew Wilber be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED); 165cd6b5cdeSAxel Dörfler 166cd6b5cdeSAxel Dörfler // The window will be shown on screen automatically 167cd6b5cdeSAxel Dörfler Run(); 16813afa642SPhil Greenway } 16913afa642SPhil Greenway 170efa8b4f3SAxel Dörfler 17113afa642SPhil Greenway ShowImageWindow::~ShowImageWindow() 17213afa642SPhil Greenway { 17313afa642SPhil Greenway } 17413afa642SPhil Greenway 175efa8b4f3SAxel Dörfler 176cdb89ebbSMatthew Wilber void 177d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu) 178d9f6762dSMichael Pfeiffer { 179fd952aefSRyan Leavengood _BuildViewMenu(menu, true); 180d9f6762dSMichael Pfeiffer } 181efa8b4f3SAxel Dörfler 18256b0c7b9SKarsten Heimrich 1834eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT 1844eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus" 1851ed4535fSStephan Aßmus 1866046b973SAxel Dörfler 187cdb89ebbSMatthew Wilber void 188fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) 189da87390fSMichael Pfeiffer { 190905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this); 191fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted()); 192905c8c8cSMatt Madia BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay")); 193efa8b4f3SAxel Dörfler if (fSlideShowDelay == NULL) 194efa8b4f3SAxel Dörfler fSlideShowDelay = delayMenu; 195efa8b4f3SAxel Dörfler 196efa8b4f3SAxel Dörfler delayMenu->SetRadioMode(true); 19756b0c7b9SKarsten Heimrich // Note: ShowImage loads images in window thread so it becomes unresponsive 19856b0c7b9SKarsten Heimrich // if slide show delay is too short! (Especially if loading the image 19956b0c7b9SKarsten Heimrich // takes as long as or longer than the slide show delay). Should load 20056b0c7b9SKarsten Heimrich // in background thread! 201905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("3 seconds"), 3); 202905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("4 seconds"), 4); 203905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("5 seconds"), 5); 204905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("6 seconds"), 6); 205905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("7 seconds"), 7); 206905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("8 seconds"), 8); 207905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("9 seconds"), 9); 208905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("10 seconds"), 10); 209905c8c8cSMatt Madia _AddDelayItem(delayMenu, B_TRANSLATE("20 seconds"), 20); 210efa8b4f3SAxel Dörfler menu->AddItem(delayMenu); 21130060f17SMatthew Wilber 212efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 213efa8b4f3SAxel Dörfler 214905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Original size"), 215905c8c8cSMatt Madia MSG_ORIGINAL_SIZE, '1', 0, this); 216905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this); 217905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this); 218efa8b4f3SAxel Dörfler 219efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 220efa8b4f3SAxel Dörfler 2214fd570d3SAxel Dörfler if (!popupMenu || fFullScreen) { 222905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), 223905c8c8cSMatt Madia MSG_SCALE_BILINEAR, 0, 0, this); 224efa8b4f3SAxel Dörfler 225efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 226efa8b4f3SAxel Dörfler 227905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Shrink to window"), 228905c8c8cSMatt Madia MSG_SHRINK_TO_WINDOW, 0, 0, this); 2294fd570d3SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Stretch to window"), 2304fd570d3SAxel Dörfler MSG_STRETCH_TO_WINDOW, 0, 0, this); 231efa8b4f3SAxel Dörfler 232efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 23332c22143SAxel Dörfler } 234efa8b4f3SAxel Dörfler 235905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Full screen"), 236905c8c8cSMatt Madia MSG_FULL_SCREEN, B_ENTER, 0, this); 237fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen); 238efa8b4f3SAxel Dörfler 239905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"), 240905c8c8cSMatt Madia MSG_SHOW_CAPTION, 0, 0, this); 241fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption); 242efa8b4f3SAxel Dörfler 243fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear()); 2446db01936SAxel Dörfler _MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, fImageView->ShrinksToBounds()); 2456db01936SAxel Dörfler _MarkMenuItem(menu, MSG_STRETCH_TO_WINDOW, fImageView->StretchesToBounds()); 246a60adbf9SAxel Dörfler 247d9f6762dSMichael Pfeiffer if (popupMenu) { 248a60adbf9SAxel Dörfler menu->AddSeparatorItem(); 249905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 2501ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 251d9f6762dSMichael Pfeiffer } 252da87390fSMichael Pfeiffer } 253da87390fSMichael Pfeiffer 254efa8b4f3SAxel Dörfler 255da87390fSMichael Pfeiffer void 256b9767a83SAxel Dörfler ShowImageWindow::_AddMenus(BMenuBar* bar) 25713afa642SPhil Greenway { 258905c8c8cSMatt Madia BMenu* menu = new BMenu(B_TRANSLATE("File")); 25936272f0dSAxel Dörfler 26036272f0dSAxel Dörfler // Add recent files to "Open File" entry as sub-menu. 26136272f0dSAxel Dörfler BMenuItem* item = new BMenuItem(BRecentFilesList::NewFileListMenu( 26236272f0dSAxel Dörfler B_TRANSLATE("Open"B_UTF8_ELLIPSIS), NULL, NULL, be_app, 10, true, 26336272f0dSAxel Dörfler NULL, kApplicationSignature), new BMessage(MSG_FILE_OPEN)); 26436272f0dSAxel Dörfler item->SetShortcut('O', 0); 26536272f0dSAxel Dörfler item->SetTarget(be_app); 26636272f0dSAxel Dörfler menu->AddItem(item); 267efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 26836272f0dSAxel Dörfler 2696db01936SAxel Dörfler BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS), 2701ed4535fSStephan Aßmus B_ITEMS_IN_COLUMN); 2716db01936SAxel Dörfler BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP); 272fc0a275bSMatthew Wilber // Fill Save As submenu with all types that can be converted 273fc0a275bSMatthew Wilber // to from the Be bitmap image format 2746db01936SAxel Dörfler menu->AddItem(menuSaveAs); 275905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this); 276efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 277905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS), 2781ed4535fSStephan Aßmus MSG_PAGE_SETUP, 0, 0, this); 279905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS), 2801ed4535fSStephan Aßmus MSG_PREPARE_PRINT, 'P', 0, this); 281efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 282905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("About ShowImage" B_UTF8_ELLIPSIS), 2831ed4535fSStephan Aßmus B_ABOUT_REQUESTED, 0, 0, be_app); 284efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 285905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app); 286efa8b4f3SAxel Dörfler bar->AddItem(menu); 28713afa642SPhil Greenway 288905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Edit")); 289905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Undo"), B_UNDO, 'Z', 0, this, false); 290efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 291905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false); 292efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 2936db01936SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Selection Mode"), MSG_SELECTION_MODE, 0, 0, 2946db01936SAxel Dörfler this); 29532c22143SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Clear selection"), 29632c22143SAxel Dörfler MSG_CLEAR_SELECT, 0, 0, this, false); 297905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Select all"), 298905c8c8cSMatt Madia MSG_SELECT_ALL, 'A', 0, this); 299efa8b4f3SAxel Dörfler bar->AddItem(menu); 30013afa642SPhil Greenway 301905c8c8cSMatt Madia menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse")); 302905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("First page"), 3031ed4535fSStephan Aßmus MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this); 304905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Last page"), 3051ed4535fSStephan Aßmus MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this); 306905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous page"), 307905c8c8cSMatt Madia MSG_PAGE_PREV, B_LEFT_ARROW, 0, this); 308905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next page"), 309905c8c8cSMatt Madia MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this); 310905c8c8cSMatt Madia fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page")); 3115e427b6aSMichael Pfeiffer fGoToPageMenu->SetRadioMode(true); 312efa8b4f3SAxel Dörfler menu->AddItem(fGoToPageMenu); 313efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 314905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous file"), 315905c8c8cSMatt Madia MSG_FILE_PREV, B_UP_ARROW, 0, this); 316905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next file"), 317905c8c8cSMatt Madia MSG_FILE_NEXT, B_DOWN_ARROW, 0, this); 318efa8b4f3SAxel Dörfler bar->AddItem(menu); 31903839579SMatthew Wilber 320905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Image")); 321905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"), 322905c8c8cSMatt Madia MSG_ROTATE_90, 'R', 0, this); 323905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"), 3241ed4535fSStephan Aßmus MSG_ROTATE_270, 'R', B_SHIFT_KEY, this); 325efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 326905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip left to right"), 3271ed4535fSStephan Aßmus MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this); 328905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"), 3291ed4535fSStephan Aßmus MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this); 330efa8b4f3SAxel Dörfler menu->AddSeparatorItem(); 331905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS), 3321ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this); 33304f96544SAxel Dörfler 33404f96544SAxel Dörfler bar->AddItem(menu); 33513afa642SPhil Greenway } 33613afa642SPhil Greenway 337efa8b4f3SAxel Dörfler 338cdb89ebbSMatthew Wilber BMenuItem* 339fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what, 3404fd570d3SAxel Dörfler char shortcut, uint32 modifier, const BHandler* target, bool enabled) 341cdb89ebbSMatthew Wilber { 3424fd570d3SAxel Dörfler BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut, 3434fd570d3SAxel Dörfler modifier); 344efa8b4f3SAxel Dörfler menu->AddItem(item); 345efa8b4f3SAxel Dörfler 3466163f333SKarsten Heimrich item->SetTarget(target); 3476163f333SKarsten Heimrich item->SetEnabled(enabled); 3486163f333SKarsten Heimrich 349efa8b4f3SAxel Dörfler return item; 35013afa642SPhil Greenway } 35113afa642SPhil Greenway 352efa8b4f3SAxel Dörfler 353ad13f387SMichael Pfeiffer BMenuItem* 354fd952aefSRyan Leavengood ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, float value) 355ad13f387SMichael Pfeiffer { 356efa8b4f3SAxel Dörfler BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY); 357efa8b4f3SAxel Dörfler message->AddFloat("value", value); 358ad13f387SMichael Pfeiffer 3596163f333SKarsten Heimrich BMenuItem* item = new BMenuItem(label, message, 0); 360efa8b4f3SAxel Dörfler item->SetTarget(this); 361ad13f387SMichael Pfeiffer 362d3046f7dSMichael Pfeiffer bool marked = fImageView->GetSlideShowDelay() == value; 363efa8b4f3SAxel Dörfler if (marked) 364efa8b4f3SAxel Dörfler item->SetMarked(true); 365ad13f387SMichael Pfeiffer 366efa8b4f3SAxel Dörfler menu->AddItem(item); 367efa8b4f3SAxel Dörfler return item; 368ad13f387SMichael Pfeiffer } 369ad13f387SMichael Pfeiffer 370efa8b4f3SAxel Dörfler 371cdb89ebbSMatthew Wilber void 372b9767a83SAxel Dörfler ShowImageWindow::_WindowRedimension(BBitmap* bitmap) 37313afa642SPhil Greenway { 374d10d5947SMichael Pfeiffer BScreen screen; 37571a34702SAxel Dörfler if (!screen.IsValid()) 376efa8b4f3SAxel Dörfler return; 377efa8b4f3SAxel Dörfler 3781076d97bSAxel Dörfler // TODO: use View::GetPreferredSize() instead? 3791076d97bSAxel Dörfler BRect r(bitmap->Bounds()); 3801076d97bSAxel Dörfler float width = r.Width() + B_V_SCROLL_BAR_WIDTH; 3811076d97bSAxel Dörfler float height = r.Height() + 1 + fBar->Frame().Height() 3821076d97bSAxel Dörfler + B_H_SCROLL_BAR_HEIGHT; 383cdb89ebbSMatthew Wilber 3846163f333SKarsten Heimrich BRect frame = screen.Frame(); 3856163f333SKarsten Heimrich const float windowBorder = 5; 386d10d5947SMichael Pfeiffer // dimensions so that window does not reach outside of screen 3876163f333SKarsten Heimrich float maxWidth = frame.Width() + 1 - windowBorder - Frame().left; 3886163f333SKarsten Heimrich float maxHeight = frame.Height() + 1 - windowBorder - Frame().top; 389cdb89ebbSMatthew Wilber 390a8fc7138SMichael Pfeiffer // We have to check size limits manually, otherwise 391a8fc7138SMichael Pfeiffer // menu bar will be too short for small images. 392efa8b4f3SAxel Dörfler 393fc5ca95dSStephan Aßmus float minW, maxW, minH, maxH; 394a8fc7138SMichael Pfeiffer GetSizeLimits(&minW, &maxW, &minH, &maxH); 395efa8b4f3SAxel Dörfler if (maxWidth > maxW) 396efa8b4f3SAxel Dörfler maxWidth = maxW; 397efa8b4f3SAxel Dörfler if (maxHeight > maxH) 398efa8b4f3SAxel Dörfler maxHeight = maxH; 399efa8b4f3SAxel Dörfler if (width < minW) 400efa8b4f3SAxel Dörfler width = minW; 401efa8b4f3SAxel Dörfler if (height < minH) 402efa8b4f3SAxel Dörfler height = minH; 403a8fc7138SMichael Pfeiffer 404efa8b4f3SAxel Dörfler if (width > maxWidth) 405efa8b4f3SAxel Dörfler width = maxWidth; 406efa8b4f3SAxel Dörfler if (height > maxHeight) 407efa8b4f3SAxel Dörfler height = maxHeight; 408d10d5947SMichael Pfeiffer 409d10d5947SMichael Pfeiffer ResizeTo(width, height); 41013afa642SPhil Greenway } 41113afa642SPhil Greenway 412efa8b4f3SAxel Dörfler 413cdb89ebbSMatthew Wilber void 414cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height) 41513afa642SPhil Greenway { 4166163f333SKarsten Heimrich BWindow::FrameResized(width, height); 41713afa642SPhil Greenway } 41813afa642SPhil Greenway 419efa8b4f3SAxel Dörfler 4207eca0987SMichael Pfeiffer bool 421fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what) 4227eca0987SMichael Pfeiffer { 4237eca0987SMichael Pfeiffer bool marked = false; 4246163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(what); 4257eca0987SMichael Pfeiffer if (item != NULL) { 4267eca0987SMichael Pfeiffer marked = !item->IsMarked(); 4277eca0987SMichael Pfeiffer item->SetMarked(marked); 4287eca0987SMichael Pfeiffer } 4297eca0987SMichael Pfeiffer return marked; 4307eca0987SMichael Pfeiffer } 4317eca0987SMichael Pfeiffer 432efa8b4f3SAxel Dörfler 433cdb89ebbSMatthew Wilber void 434fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable) 435e6a50d9cSMichael Pfeiffer { 4366163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 4376163f333SKarsten Heimrich if (item && item->IsEnabled() != enable) 438e6a50d9cSMichael Pfeiffer item->SetEnabled(enable); 439e6a50d9cSMichael Pfeiffer } 440e6a50d9cSMichael Pfeiffer 441efa8b4f3SAxel Dörfler 442e6a50d9cSMichael Pfeiffer void 443fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked) 444e6a50d9cSMichael Pfeiffer { 4456163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what); 4466163f333SKarsten Heimrich if (item && item->IsMarked() != marked) 447e6a50d9cSMichael Pfeiffer item->SetMarked(marked); 448e6a50d9cSMichael Pfeiffer } 449e6a50d9cSMichael Pfeiffer 450efa8b4f3SAxel Dörfler 451da87390fSMichael Pfeiffer void 452fd952aefSRyan Leavengood ShowImageWindow::_MarkSlideShowDelay(float value) 453da87390fSMichael Pfeiffer { 454d3046f7dSMichael Pfeiffer const int32 n = fSlideShowDelay->CountItems(); 455da87390fSMichael Pfeiffer float v; 456da87390fSMichael Pfeiffer for (int32 i = 0; i < n; i ++) { 457d3046f7dSMichael Pfeiffer BMenuItem* item = fSlideShowDelay->ItemAt(i); 458da87390fSMichael Pfeiffer if (item) { 459da87390fSMichael Pfeiffer if (item->Message()->FindFloat("value", &v) == B_OK && v == value) { 4606163f333SKarsten Heimrich if (!item->IsMarked()) 461da87390fSMichael Pfeiffer item->SetMarked(true); 462da87390fSMichael Pfeiffer return; 463da87390fSMichael Pfeiffer } 464da87390fSMichael Pfeiffer } 465da87390fSMichael Pfeiffer } 466da87390fSMichael Pfeiffer } 467e6a50d9cSMichael Pfeiffer 46819c76de4SMichael Pfeiffer 46919c76de4SMichael Pfeiffer void 470fd952aefSRyan Leavengood ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what) 47119c76de4SMichael Pfeiffer { 472fd952aefSRyan Leavengood bool enabled = _ToggleMenuItem(what); 4736163f333SKarsten Heimrich if (shrink) 474d3046f7dSMichael Pfeiffer fImageView->SetShrinkToBounds(enabled); 4756163f333SKarsten Heimrich else 4764fd570d3SAxel Dörfler fImageView->SetStretchToBounds(enabled); 47719c76de4SMichael Pfeiffer } 47819c76de4SMichael Pfeiffer 479efa8b4f3SAxel Dörfler 480e6a50d9cSMichael Pfeiffer void 481efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message) 48213afa642SPhil Greenway { 483efa8b4f3SAxel Dörfler switch (message->what) { 484cd6b5cdeSAxel Dörfler case kMsgImageLoaded: 485cd6b5cdeSAxel Dörfler { 486cd6b5cdeSAxel Dörfler bool first = fImageView->Bitmap() == NULL; 487b9767a83SAxel Dörfler entry_ref ref; 488b9767a83SAxel Dörfler message->FindRef("ref", &ref); 489b9767a83SAxel Dörfler if (!first && ref != fNavigator.CurrentRef()) { 490b9767a83SAxel Dörfler // ignore older images 491b9767a83SAxel Dörfler break; 492b9767a83SAxel Dörfler } 493cd6b5cdeSAxel Dörfler 494cd6b5cdeSAxel Dörfler status_t status = fImageView->SetImage(message); 495cd6b5cdeSAxel Dörfler if (status != B_OK) { 496cd6b5cdeSAxel Dörfler _LoadError(ref); 497cd6b5cdeSAxel Dörfler 498cd6b5cdeSAxel Dörfler // quit if file could not be opened 499cd6b5cdeSAxel Dörfler if (first) 500cd6b5cdeSAxel Dörfler Quit(); 501cd6b5cdeSAxel Dörfler break; 502cd6b5cdeSAxel Dörfler } 503cd6b5cdeSAxel Dörfler 504cd6b5cdeSAxel Dörfler fImageType = message->FindString("type"); 505b9767a83SAxel Dörfler fNavigator.SetTo(ref, message->FindInt32("page"), 506b9767a83SAxel Dörfler message->FindInt32("pageCount")); 507cd6b5cdeSAxel Dörfler 508cd6b5cdeSAxel Dörfler if (first) { 509b9767a83SAxel Dörfler _WindowRedimension(fImageView->Bitmap()); 510cd6b5cdeSAxel Dörfler fImageView->ResetZoom(); 511cd6b5cdeSAxel Dörfler fImageView->MakeFocus(true); 512cd6b5cdeSAxel Dörfler // to receive key messages 513cd6b5cdeSAxel Dörfler 514cd6b5cdeSAxel Dörfler Show(); 515cd6b5cdeSAxel Dörfler } else { 516cd6b5cdeSAxel Dörfler if (!fImageView->StretchesToBounds() 517cd6b5cdeSAxel Dörfler && !fImageView->ShrinksToBounds() 518cd6b5cdeSAxel Dörfler && !fFullScreen) 519b9767a83SAxel Dörfler _WindowRedimension(fImageView->Bitmap()); 520cd6b5cdeSAxel Dörfler } 521cd6b5cdeSAxel Dörfler break; 522cd6b5cdeSAxel Dörfler } 523cd6b5cdeSAxel Dörfler 524ee7b4f39SMatthew Wilber case MSG_MODIFIED: 525ee7b4f39SMatthew Wilber // If image has been modified due to a Cut or Paste 526ee7b4f39SMatthew Wilber fModified = true; 527ee7b4f39SMatthew Wilber break; 528ee7b4f39SMatthew Wilber 529fc0a275bSMatthew Wilber case MSG_OUTPUT_TYPE: 530fc0a275bSMatthew Wilber // User clicked Save As then choose an output format 531d3046f7dSMichael Pfeiffer if (!fSavePanel) 532cdb89ebbSMatthew Wilber // If user doesn't already have a save panel open 533fd952aefSRyan Leavengood _SaveAs(message); 53413afa642SPhil Greenway break; 535fc0a275bSMatthew Wilber 536fc0a275bSMatthew Wilber case MSG_SAVE_PANEL: 537fc0a275bSMatthew Wilber // User specified where to save the output image 538fd952aefSRyan Leavengood _SaveToFile(message); 53907caaa8eSMatthew Wilber break; 54007caaa8eSMatthew Wilber 541cdb89ebbSMatthew Wilber case B_CANCEL: 542d3046f7dSMichael Pfeiffer delete fSavePanel; 543d3046f7dSMichael Pfeiffer fSavePanel = NULL; 544cdb89ebbSMatthew Wilber break; 545cdb89ebbSMatthew Wilber 5466db01936SAxel Dörfler case MSG_UPDATE_STATUS: 5476db01936SAxel Dörfler { 548cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 549cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 5506c305411SMatthew Wilber 551cd6b5cdeSAxel Dörfler bool enable = pages > 1 ? true : false; 55236c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_FIRST, enable); 55336c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_LAST, enable); 55436c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_NEXT, enable); 55536c17651SRyan Leavengood _EnableMenuItem(fBar, MSG_PAGE_PREV, enable); 55636c17651SRyan Leavengood fGoToPageMenu->SetEnabled(enable); 5571d592070SMatthew Wilber 558cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile()); 559cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile()); 560134d6076SMichael Pfeiffer 561d3046f7dSMichael Pfeiffer if (fGoToPageMenu->CountItems() != pages) { 5626c305411SMatthew Wilber // Only rebuild the submenu if the number of 5636c305411SMatthew Wilber // pages is different 5646c305411SMatthew Wilber 565cd6b5cdeSAxel Dörfler while (fGoToPageMenu->CountItems() > 0) { 5666c305411SMatthew Wilber // Remove all page numbers 567d3046f7dSMichael Pfeiffer delete fGoToPageMenu->RemoveItem(0L); 568cd6b5cdeSAxel Dörfler } 5696c305411SMatthew Wilber 570780d8a62SMichael Pfeiffer for (int32 i = 1; i <= pages; i++) { 5716c305411SMatthew Wilber // Fill Go To page submenu with an entry for each page 572cd6b5cdeSAxel Dörfler BMessage* goTo = new BMessage(MSG_GOTO_PAGE); 573cd6b5cdeSAxel Dörfler goTo->AddInt32("page", i); 5746163f333SKarsten Heimrich 5756163f333SKarsten Heimrich char shortcut = 0; 576cd6b5cdeSAxel Dörfler if (i < 10) 577780d8a62SMichael Pfeiffer shortcut = '0' + i; 5786163f333SKarsten Heimrich 5796163f333SKarsten Heimrich BString strCaption; 5806163f333SKarsten Heimrich strCaption << i; 5816163f333SKarsten Heimrich 582cd6b5cdeSAxel Dörfler BMenuItem* item = new BMenuItem(strCaption.String(), goTo, 583ddcb5a2cSAxel Dörfler B_SHIFT_KEY, shortcut); 584cd6b5cdeSAxel Dörfler if (currentPage == i) 585efa8b4f3SAxel Dörfler item->SetMarked(true); 586efa8b4f3SAxel Dörfler fGoToPageMenu->AddItem(item); 5876c305411SMatthew Wilber } 5886c305411SMatthew Wilber } else { 5896c305411SMatthew Wilber // Make sure the correct page is marked 590cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 591cd6b5cdeSAxel Dörfler if (currentItem != NULL && !currentItem->IsMarked()) 592cd6b5cdeSAxel Dörfler currentItem->SetMarked(true); 5936c305411SMatthew Wilber } 5946c305411SMatthew Wilber 595cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 596b9767a83SAxel Dörfler 597b9767a83SAxel Dörfler BPath path(fImageView->Image()); 598b9767a83SAxel Dörfler SetTitle(path.Path()); 5996db01936SAxel Dörfler break; 6006db01936SAxel Dörfler } 60103839579SMatthew Wilber 6026db01936SAxel Dörfler case MSG_UPDATE_STATUS_TEXT: 6036db01936SAxel Dörfler { 604cd6b5cdeSAxel Dörfler _UpdateStatusText(message); 6056db01936SAxel Dörfler break; 6066db01936SAxel Dörfler } 6078f5fd23fSRyan Leavengood 6086db01936SAxel Dörfler case MSG_SELECTION: 6096db01936SAxel Dörfler { 6108ad30bcfSMatthew Wilber // The view sends this message when a selection is 6118ad30bcfSMatthew Wilber // made or the selection is cleared so that the window 6128ad30bcfSMatthew Wilber // can update the state of the appropriate menu items 6136db01936SAxel Dörfler bool enable; 6146db01936SAxel Dörfler if (message->FindBool("has_selection", &enable) == B_OK) { 6156db01936SAxel Dörfler _EnableMenuItem(fBar, B_COPY, enable); 6166db01936SAxel Dörfler _EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable); 6178ad30bcfSMatthew Wilber } 6186db01936SAxel Dörfler break; 6196db01936SAxel Dörfler } 6208ad30bcfSMatthew Wilber 6216db01936SAxel Dörfler case MSG_UNDO_STATE: 6226db01936SAxel Dörfler { 6236db01936SAxel Dörfler bool enable; 6246db01936SAxel Dörfler if (message->FindBool("can_undo", &enable) == B_OK) 6256db01936SAxel Dörfler _EnableMenuItem(fBar, B_UNDO, enable); 6266db01936SAxel Dörfler break; 6276db01936SAxel Dörfler } 628402c09e5SMatthew Wilber 62913afa642SPhil Greenway case B_UNDO: 6307598450eSMatthew Wilber fImageView->Undo(); 63113afa642SPhil Greenway break; 6326163f333SKarsten Heimrich 63313afa642SPhil Greenway case B_COPY: 634d3046f7dSMichael Pfeiffer fImageView->CopySelectionToClipboard(); 63513afa642SPhil Greenway break; 6366163f333SKarsten Heimrich 6376db01936SAxel Dörfler case MSG_SELECTION_MODE: 6386db01936SAxel Dörfler fImageView->SetSelectionMode(_ToggleMenuItem(MSG_SELECTION_MODE)); 6396db01936SAxel Dörfler break; 6406db01936SAxel Dörfler 64113afa642SPhil Greenway case MSG_CLEAR_SELECT: 642d3046f7dSMichael Pfeiffer fImageView->ClearSelection(); 64313afa642SPhil Greenway break; 6446163f333SKarsten Heimrich 64513afa642SPhil Greenway case MSG_SELECT_ALL: 646d3046f7dSMichael Pfeiffer fImageView->SelectAll(); 64713afa642SPhil Greenway break; 64813afa642SPhil Greenway 64903839579SMatthew Wilber case MSG_PAGE_FIRST: 650b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.FirstPage()) 651b9767a83SAxel Dörfler _LoadImage(); 65203839579SMatthew Wilber break; 65303839579SMatthew Wilber 65403839579SMatthew Wilber case MSG_PAGE_LAST: 655b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.LastPage()) 656b9767a83SAxel Dörfler _LoadImage(); 65703839579SMatthew Wilber break; 65803839579SMatthew Wilber 65903839579SMatthew Wilber case MSG_PAGE_NEXT: 660b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextPage()) 661b9767a83SAxel Dörfler _LoadImage(); 66203839579SMatthew Wilber break; 66303839579SMatthew Wilber 66403839579SMatthew Wilber case MSG_PAGE_PREV: 665b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousPage()) 666b9767a83SAxel Dörfler _LoadImage(); 66703839579SMatthew Wilber break; 66803839579SMatthew Wilber 669cd6b5cdeSAxel Dörfler case MSG_GOTO_PAGE: 670cd6b5cdeSAxel Dörfler { 671fd952aefSRyan Leavengood if (!_ClosePrompt()) 672ee7b4f39SMatthew Wilber break; 673ee7b4f39SMatthew Wilber 6746163f333SKarsten Heimrich int32 newPage; 6756163f333SKarsten Heimrich if (message->FindInt32("page", &newPage) != B_OK) 6766163f333SKarsten Heimrich break; 6776163f333SKarsten Heimrich 678cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage(); 679cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount(); 6806c305411SMatthew Wilber 681b9767a83SAxel Dörfler // TODO: use radio mode instead! 6826c305411SMatthew Wilber if (newPage > 0 && newPage <= pages) { 683cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1); 684cd6b5cdeSAxel Dörfler BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1); 685cd6b5cdeSAxel Dörfler if (currentItem != NULL && newItem != NULL) { 686cd6b5cdeSAxel Dörfler currentItem->SetMarked(false); 687cd6b5cdeSAxel Dörfler newItem->SetMarked(true); 688b9767a83SAxel Dörfler if (fNavigator.GoToPage(newPage)) 689b9767a83SAxel Dörfler _LoadImage(); 6906c305411SMatthew Wilber } 6916c305411SMatthew Wilber } 692cd6b5cdeSAxel Dörfler break; 693cd6b5cdeSAxel Dörfler } 6946c305411SMatthew Wilber 69519c76de4SMichael Pfeiffer case MSG_SHRINK_TO_WINDOW: 696fd952aefSRyan Leavengood _ResizeToWindow(true, message->what); 69719c76de4SMichael Pfeiffer break; 6986163f333SKarsten Heimrich 6994fd570d3SAxel Dörfler case MSG_STRETCH_TO_WINDOW: 700fd952aefSRyan Leavengood _ResizeToWindow(false, message->what); 7017eca0987SMichael Pfeiffer break; 7027eca0987SMichael Pfeiffer 7037eca0987SMichael Pfeiffer case MSG_FILE_PREV: 704b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousFile()) 705*a569816bSAxel Dörfler _LoadImage(false); 7067eca0987SMichael Pfeiffer break; 7077eca0987SMichael Pfeiffer 7087eca0987SMichael Pfeiffer case MSG_FILE_NEXT: 709b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextFile()) 710b9767a83SAxel Dörfler _LoadImage(); 71113afa642SPhil Greenway break; 71213afa642SPhil Greenway 713328932acSAxel Dörfler case kMsgDeleteCurrentFile: 714b9767a83SAxel Dörfler { 715b9767a83SAxel Dörfler if (fNavigator.MoveFileToTrash()) 716b9767a83SAxel Dörfler _LoadImage(); 717b9767a83SAxel Dörfler else 718328932acSAxel Dörfler PostMessage(B_QUIT_REQUESTED); 719328932acSAxel Dörfler break; 720b9767a83SAxel Dörfler } 721328932acSAxel Dörfler 722bf461dbeSMatthew Wilber case MSG_ROTATE_90: 723d3046f7dSMichael Pfeiffer fImageView->Rotate(90); 724ad13f387SMichael Pfeiffer break; 7256163f333SKarsten Heimrich 726bf461dbeSMatthew Wilber case MSG_ROTATE_270: 727d3046f7dSMichael Pfeiffer fImageView->Rotate(270); 728ad13f387SMichael Pfeiffer break; 7296163f333SKarsten Heimrich 73069eee339SRyan Leavengood case MSG_FLIP_LEFT_TO_RIGHT: 73161ddc257SRyan Leavengood fImageView->Flip(true); 732ad13f387SMichael Pfeiffer break; 7336163f333SKarsten Heimrich 73469eee339SRyan Leavengood case MSG_FLIP_TOP_TO_BOTTOM: 73561ddc257SRyan Leavengood fImageView->Flip(false); 736ad13f387SMichael Pfeiffer break; 7376163f333SKarsten Heimrich 7381076d97bSAxel Dörfler case MSG_SLIDE_SHOW: 7391076d97bSAxel Dörfler { 7406163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(message->what); 741ee7b4f39SMatthew Wilber if (!item) 742ee7b4f39SMatthew Wilber break; 743ee7b4f39SMatthew Wilber if (item->IsMarked()) { 744ee7b4f39SMatthew Wilber item->SetMarked(false); 745d3046f7dSMichael Pfeiffer fImageView->StopSlideShow(); 746fd952aefSRyan Leavengood } else if (_ClosePrompt()) { 747ee7b4f39SMatthew Wilber item->SetMarked(true); 748ee7b4f39SMatthew Wilber fImageView->StartSlideShow(); 749ad13f387SMichael Pfeiffer } 7501076d97bSAxel Dörfler break; 7511076d97bSAxel Dörfler } 752ee7b4f39SMatthew Wilber 7531076d97bSAxel Dörfler case MSG_SLIDE_SHOW_DELAY: 7541076d97bSAxel Dörfler { 755ad13f387SMichael Pfeiffer float value; 756efa8b4f3SAxel Dörfler if (message->FindFloat("value", &value) == B_OK) { 757d3046f7dSMichael Pfeiffer fImageView->SetSlideShowDelay(value); 758da87390fSMichael Pfeiffer // in case message is sent from popup menu 759fd952aefSRyan Leavengood _MarkSlideShowDelay(value); 760ad13f387SMichael Pfeiffer } 7611076d97bSAxel Dörfler break; 7621076d97bSAxel Dörfler } 763ad13f387SMichael Pfeiffer 764ad13f387SMichael Pfeiffer case MSG_FULL_SCREEN: 765fd952aefSRyan Leavengood _ToggleFullScreen(); 766ad13f387SMichael Pfeiffer break; 7676163f333SKarsten Heimrich 768fc5ca95dSStephan Aßmus case MSG_EXIT_FULL_SCREEN: 769fc5ca95dSStephan Aßmus if (fFullScreen) 770fd952aefSRyan Leavengood _ToggleFullScreen(); 771fc5ca95dSStephan Aßmus break; 7726163f333SKarsten Heimrich 7736163f333SKarsten Heimrich case MSG_SHOW_CAPTION: { 774fd952aefSRyan Leavengood fShowCaption = _ToggleMenuItem(message->what); 775efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 776efa8b4f3SAxel Dörfler 777d3046f7dSMichael Pfeiffer if (settings->Lock()) { 778d3046f7dSMichael Pfeiffer settings->SetBool("ShowCaption", fShowCaption); 779d3046f7dSMichael Pfeiffer settings->Unlock(); 780d3046f7dSMichael Pfeiffer } 781efa8b4f3SAxel Dörfler if (fFullScreen) 782d3046f7dSMichael Pfeiffer fImageView->SetShowCaption(fShowCaption); 7836163f333SKarsten Heimrich } break; 784ad13f387SMichael Pfeiffer 785780d8a62SMichael Pfeiffer case MSG_PAGE_SETUP: 786fd952aefSRyan Leavengood _PageSetup(); 787780d8a62SMichael Pfeiffer break; 7886163f333SKarsten Heimrich 789780d8a62SMichael Pfeiffer case MSG_PREPARE_PRINT: 790fd952aefSRyan Leavengood _PrepareForPrint(); 791780d8a62SMichael Pfeiffer break; 7926163f333SKarsten Heimrich 793780d8a62SMichael Pfeiffer case MSG_PRINT: 794fd952aefSRyan Leavengood _Print(message); 795780d8a62SMichael Pfeiffer break; 796780d8a62SMichael Pfeiffer 797780d8a62SMichael Pfeiffer case MSG_ZOOM_IN: 798d3046f7dSMichael Pfeiffer fImageView->ZoomIn(); 799780d8a62SMichael Pfeiffer break; 8006163f333SKarsten Heimrich 801780d8a62SMichael Pfeiffer case MSG_ZOOM_OUT: 802d3046f7dSMichael Pfeiffer fImageView->ZoomOut(); 803780d8a62SMichael Pfeiffer break; 8046163f333SKarsten Heimrich 805780d8a62SMichael Pfeiffer case MSG_ORIGINAL_SIZE: 8064fd570d3SAxel Dörfler fImageView->SetZoom(1.0); 807780d8a62SMichael Pfeiffer break; 8086163f333SKarsten Heimrich 80981b9c776SMichael Pfeiffer case MSG_SCALE_BILINEAR: 810fd952aefSRyan Leavengood fImageView->SetScaleBilinear(_ToggleMenuItem(message->what)); 81181b9c776SMichael Pfeiffer break; 812780d8a62SMichael Pfeiffer 813cd6b5cdeSAxel Dörfler case MSG_DESKTOP_BACKGROUND: 814cd6b5cdeSAxel Dörfler { 8150a74004cSRyan Leavengood BMessage message(B_REFS_RECEIVED); 8160a74004cSRyan Leavengood message.AddRef("refs", fImageView->Image()); 8170a74004cSRyan Leavengood // This is used in the Backgrounds code for scaled placement 8180a74004cSRyan Leavengood message.AddInt32("placement", 'scpl'); 8190a74004cSRyan Leavengood be_roster->Launch("application/x-vnd.haiku-backgrounds", &message); 820cd6b5cdeSAxel Dörfler break; 821cd6b5cdeSAxel Dörfler } 822a60adbf9SAxel Dörfler 82313afa642SPhil Greenway default: 824efa8b4f3SAxel Dörfler BWindow::MessageReceived(message); 82513afa642SPhil Greenway break; 82613afa642SPhil Greenway } 82713afa642SPhil Greenway } 828fc0a275bSMatthew Wilber 829efa8b4f3SAxel Dörfler 830fc0a275bSMatthew Wilber void 831cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message) 832cd6b5cdeSAxel Dörfler { 833cd6b5cdeSAxel Dörfler BString status; 834cd6b5cdeSAxel Dörfler if (fImageView->Bitmap() != NULL) { 835cd6b5cdeSAxel Dörfler BRect bounds = fImageView->Bitmap()->Bounds(); 836cd6b5cdeSAxel Dörfler status << bounds.IntegerWidth() + 1 837cd6b5cdeSAxel Dörfler << "x" << bounds.IntegerHeight() + 1 << ", " << fImageType; 838cd6b5cdeSAxel Dörfler } 839cd6b5cdeSAxel Dörfler 840cd6b5cdeSAxel Dörfler BString text; 841cd6b5cdeSAxel Dörfler if (message != NULL && message->FindString("status", &text) == B_OK 842cd6b5cdeSAxel Dörfler && text.Length() > 0) { 843cd6b5cdeSAxel Dörfler status << ", " << text; 844cd6b5cdeSAxel Dörfler } 845cd6b5cdeSAxel Dörfler 846b9767a83SAxel Dörfler fStatusView->Update(fNavigator.CurrentRef(), status); 847cd6b5cdeSAxel Dörfler } 848cd6b5cdeSAxel Dörfler 849cd6b5cdeSAxel Dörfler 850cd6b5cdeSAxel Dörfler void 851cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref) 852cd6b5cdeSAxel Dörfler { 853cd6b5cdeSAxel Dörfler // TODO: give a better error message! 854cd6b5cdeSAxel Dörfler BAlert* alert = new BAlert(B_TRANSLATE("ShowImage"), 855ddcb5a2cSAxel Dörfler B_TRANSLATE_WITH_CONTEXT("Could not load image! Either the " 856ddcb5a2cSAxel Dörfler "file or an image translator for it does not exist.", 857ddcb5a2cSAxel Dörfler "LoadAlerts"), 858ddcb5a2cSAxel Dörfler B_TRANSLATE_WITH_CONTEXT("OK", "Alerts"), NULL, NULL, 859cd6b5cdeSAxel Dörfler B_WIDTH_AS_USUAL, B_INFO_ALERT); 860cd6b5cdeSAxel Dörfler alert->Go(); 861cd6b5cdeSAxel Dörfler } 862cd6b5cdeSAxel Dörfler 863cd6b5cdeSAxel Dörfler 864cd6b5cdeSAxel Dörfler void 865fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message) 866fc0a275bSMatthew Wilber { 867cdb89ebbSMatthew Wilber // Read the translator and output type the user chose 868cdb89ebbSMatthew Wilber translator_id outTranslator; 869cdb89ebbSMatthew Wilber uint32 outType; 8706163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 871efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 8726163f333SKarsten Heimrich || message->FindInt32(kTypeField, 873cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 874fc0a275bSMatthew Wilber return; 875fc0a275bSMatthew Wilber 876cdb89ebbSMatthew Wilber // Add the chosen translator and output type to the 877cdb89ebbSMatthew Wilber // message that the save panel will send back 878c1a10c14SKarsten Heimrich BMessage panelMsg(MSG_SAVE_PANEL); 879c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTranslatorField, outTranslator); 880c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTypeField, outType); 881cdb89ebbSMatthew Wilber 882cdb89ebbSMatthew Wilber // Create save panel and show it 8836163f333SKarsten Heimrich BMessenger target(this); 884efa8b4f3SAxel Dörfler fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL, 885c1a10c14SKarsten Heimrich &target, NULL, 0, false, &panelMsg); 886d3046f7dSMichael Pfeiffer if (!fSavePanel) 887fc0a275bSMatthew Wilber return; 888a60adbf9SAxel Dörfler 889d3046f7dSMichael Pfeiffer fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE); 890d3046f7dSMichael Pfeiffer fSavePanel->Show(); 891fc0a275bSMatthew Wilber } 892fc0a275bSMatthew Wilber 893efa8b4f3SAxel Dörfler 894fc0a275bSMatthew Wilber void 895fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message) 896fc0a275bSMatthew Wilber { 897cdb89ebbSMatthew Wilber // Read in where the file should be saved 898efa8b4f3SAxel Dörfler entry_ref dirRef; 899efa8b4f3SAxel Dörfler if (message->FindRef("directory", &dirRef) != B_OK) 900fc0a275bSMatthew Wilber return; 901efa8b4f3SAxel Dörfler 902fc0a275bSMatthew Wilber const char* filename; 903efa8b4f3SAxel Dörfler if (message->FindString("name", &filename) != B_OK) 904fc0a275bSMatthew Wilber return; 905fc0a275bSMatthew Wilber 906cdb89ebbSMatthew Wilber // Read in the translator and type to be used 907cdb89ebbSMatthew Wilber // to save the output image 908cdb89ebbSMatthew Wilber translator_id outTranslator; 909cdb89ebbSMatthew Wilber uint32 outType; 9106163f333SKarsten Heimrich if (message->FindInt32(kTranslatorField, 911efa8b4f3SAxel Dörfler reinterpret_cast<int32 *>(&outTranslator)) != B_OK 9126163f333SKarsten Heimrich || message->FindInt32(kTypeField, 913cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 914cdb89ebbSMatthew Wilber return; 915cdb89ebbSMatthew Wilber 916a7e78e3bSMatthew Wilber // Find the translator_format information needed to 917a7e78e3bSMatthew Wilber // write a MIME attribute for the image file 918a7e78e3bSMatthew Wilber BTranslatorRoster* roster = BTranslatorRoster::Default(); 919efa8b4f3SAxel Dörfler const translation_format* outFormat = NULL; 920efa8b4f3SAxel Dörfler int32 outCount = 0; 921efa8b4f3SAxel Dörfler if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK 922efa8b4f3SAxel Dörfler || outCount < 1) 923a7e78e3bSMatthew Wilber return; 924efa8b4f3SAxel Dörfler 925a7e78e3bSMatthew Wilber int32 i; 926efa8b4f3SAxel Dörfler for (i = 0; i < outCount; i++) { 927efa8b4f3SAxel Dörfler if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType) 928a7e78e3bSMatthew Wilber break; 929a7e78e3bSMatthew Wilber } 930efa8b4f3SAxel Dörfler if (i == outCount) 931fc0a275bSMatthew Wilber return; 932fc0a275bSMatthew Wilber 933a7e78e3bSMatthew Wilber // Write out the image file 934efa8b4f3SAxel Dörfler BDirectory dir(&dirRef); 935efa8b4f3SAxel Dörfler fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]); 936fc0a275bSMatthew Wilber } 937fc0a275bSMatthew Wilber 938efa8b4f3SAxel Dörfler 9394eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT 9404eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "ClosePrompt" 9411ed4535fSStephan Aßmus 942b9767a83SAxel Dörfler 943cdb89ebbSMatthew Wilber bool 944fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt() 945ee7b4f39SMatthew Wilber { 946ee7b4f39SMatthew Wilber if (!fModified) 947ee7b4f39SMatthew Wilber return true; 948efa8b4f3SAxel Dörfler 949cd6b5cdeSAxel Dörfler int32 count = fNavigator.PageCount(); 950cd6b5cdeSAxel Dörfler int32 page = fNavigator.CurrentPage(); 951cd6b5cdeSAxel Dörfler BString prompt; 952efa8b4f3SAxel Dörfler 9531ed4535fSStephan Aßmus if (count > 1) { 9541ed4535fSStephan Aßmus bs_printf(&prompt, 955905c8c8cSMatt Madia B_TRANSLATE("The document '%s' (page %d) has been changed. Do you " 956905c8c8cSMatt Madia "want to close the document?"), 957cd6b5cdeSAxel Dörfler fImageView->Image()->name, page); 9581ed4535fSStephan Aßmus } else { 9591ed4535fSStephan Aßmus bs_printf(&prompt, 960905c8c8cSMatt Madia B_TRANSLATE("The document '%s' has been changed. Do you want to " 961905c8c8cSMatt Madia "close the document?"), 962cd6b5cdeSAxel Dörfler fImageView->Image()->name); 9631ed4535fSStephan Aßmus } 9641ed4535fSStephan Aßmus 965cd6b5cdeSAxel Dörfler BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(), 966905c8c8cSMatt Madia B_TRANSLATE("Cancel"), B_TRANSLATE("Close")); 967cd6b5cdeSAxel Dörfler if (alert->Go() == 0) { 968ee7b4f39SMatthew Wilber // Cancel 969ee7b4f39SMatthew Wilber return false; 970cd6b5cdeSAxel Dörfler } 971cd6b5cdeSAxel Dörfler 972ee7b4f39SMatthew Wilber // Close 973187f0b8aSMatthew Wilber fModified = false; 974ee7b4f39SMatthew Wilber return true; 975ee7b4f39SMatthew Wilber } 976ee7b4f39SMatthew Wilber 977cdb89ebbSMatthew Wilber 978b9767a83SAxel Dörfler status_t 979*a569816bSAxel Dörfler ShowImageWindow::_LoadImage(bool forward) 980b9767a83SAxel Dörfler { 981b9767a83SAxel Dörfler BMessenger us(this); 982*a569816bSAxel Dörfler status_t status = ImageCache::Default().RetrieveImage( 983*a569816bSAxel Dörfler fNavigator.CurrentRef(), fNavigator.CurrentPage(), &us); 984*a569816bSAxel Dörfler if (status != B_OK) 985*a569816bSAxel Dörfler return status; 986*a569816bSAxel Dörfler 987*a569816bSAxel Dörfler // Preload previous/next images - two in the navigation direction, one 988*a569816bSAxel Dörfler // in the opposite direction. 989*a569816bSAxel Dörfler 990*a569816bSAxel Dörfler entry_ref nextRef = fNavigator.CurrentRef(); 991*a569816bSAxel Dörfler if (_PreloadImage(forward, nextRef)) 992*a569816bSAxel Dörfler _PreloadImage(forward, nextRef); 993*a569816bSAxel Dörfler 994*a569816bSAxel Dörfler entry_ref previousRef = fNavigator.CurrentRef(); 995*a569816bSAxel Dörfler _PreloadImage(!forward, previousRef); 996*a569816bSAxel Dörfler 997*a569816bSAxel Dörfler return B_OK; 998*a569816bSAxel Dörfler } 999*a569816bSAxel Dörfler 1000*a569816bSAxel Dörfler 1001*a569816bSAxel Dörfler bool 1002*a569816bSAxel Dörfler ShowImageWindow::_PreloadImage(bool forward, entry_ref& ref) 1003*a569816bSAxel Dörfler { 1004*a569816bSAxel Dörfler entry_ref currentRef = ref; 1005*a569816bSAxel Dörfler if ((forward && !fNavigator.GetNextFile(currentRef, ref)) 1006*a569816bSAxel Dörfler || (!forward && !fNavigator.GetPreviousFile(currentRef, ref))) 1007*a569816bSAxel Dörfler return false; 1008*a569816bSAxel Dörfler 1009*a569816bSAxel Dörfler return ImageCache::Default().RetrieveImage(ref) == B_OK; 1010b9767a83SAxel Dörfler } 1011b9767a83SAxel Dörfler 1012b9767a83SAxel Dörfler 1013ad13f387SMichael Pfeiffer void 1014fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen() 1015ad13f387SMichael Pfeiffer { 1016ad13f387SMichael Pfeiffer BRect frame; 1017ad13f387SMichael Pfeiffer fFullScreen = !fFullScreen; 1018ad13f387SMichael Pfeiffer if (fFullScreen) { 1019ad13f387SMichael Pfeiffer BScreen screen; 1020ad13f387SMichael Pfeiffer fWindowFrame = Frame(); 1021ad13f387SMichael Pfeiffer frame = screen.Frame(); 1022d3046f7dSMichael Pfeiffer frame.top -= fBar->Bounds().Height()+1; 1023ad13f387SMichael Pfeiffer frame.right += B_V_SCROLL_BAR_WIDTH; 1024ad13f387SMichael Pfeiffer frame.bottom += B_H_SCROLL_BAR_HEIGHT; 1025ad13f387SMichael Pfeiffer frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView 1026ad13f387SMichael Pfeiffer 1027ad13f387SMichael Pfeiffer SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE); 1028c0b16687SAxel Dörfler 1029c0b16687SAxel Dörfler Activate(); 1030c0b16687SAxel Dörfler // make the window frontmost 1031ad13f387SMichael Pfeiffer } else { 1032ad13f387SMichael Pfeiffer frame = fWindowFrame; 1033ad13f387SMichael Pfeiffer 1034ad13f387SMichael Pfeiffer SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); 1035ad13f387SMichael Pfeiffer } 1036efa8b4f3SAxel Dörfler 103776d115d8SRyan Leavengood fImageView->SetFullScreen(fFullScreen); 1038d3046f7dSMichael Pfeiffer fImageView->SetShowCaption(fFullScreen && fShowCaption); 1039ad13f387SMichael Pfeiffer MoveTo(frame.left, frame.top); 1040ad13f387SMichael Pfeiffer ResizeTo(frame.Width(), frame.Height()); 1041ad13f387SMichael Pfeiffer } 1042ad13f387SMichael Pfeiffer 1043efa8b4f3SAxel Dörfler 1044d3046f7dSMichael Pfeiffer void 10452281340dSAxel Dörfler ShowImageWindow::_ApplySettings() 1046d3046f7dSMichael Pfeiffer { 1047efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1048efa8b4f3SAxel Dörfler 1049d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1050d3046f7dSMichael Pfeiffer fShowCaption = settings->GetBool("ShowCaption", fShowCaption); 1051d3046f7dSMichael Pfeiffer fPrintOptions.SetBounds(BRect(0, 0, 1023, 767)); 1052d3046f7dSMichael Pfeiffer 1053efa8b4f3SAxel Dörfler int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option()); 1054d3046f7dSMichael Pfeiffer fPrintOptions.SetOption((enum PrintOptions::Option)op); 1055d3046f7dSMichael Pfeiffer 1056efa8b4f3SAxel Dörfler float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor()); 1057d3046f7dSMichael Pfeiffer fPrintOptions.SetZoomFactor(f); 1058d3046f7dSMichael Pfeiffer 1059d3046f7dSMichael Pfeiffer f = settings->GetFloat("PO:DPI", fPrintOptions.DPI()); 1060d3046f7dSMichael Pfeiffer fPrintOptions.SetDPI(f); 1061d3046f7dSMichael Pfeiffer 1062d3046f7dSMichael Pfeiffer f = settings->GetFloat("PO:Width", fPrintOptions.Width()); 1063d3046f7dSMichael Pfeiffer fPrintOptions.SetWidth(f); 1064d3046f7dSMichael Pfeiffer 1065d3046f7dSMichael Pfeiffer f = settings->GetFloat("PO:Height", fPrintOptions.Height()); 1066d3046f7dSMichael Pfeiffer fPrintOptions.SetHeight(f); 1067d3046f7dSMichael Pfeiffer 1068d3046f7dSMichael Pfeiffer settings->Unlock(); 1069d3046f7dSMichael Pfeiffer } 1070d3046f7dSMichael Pfeiffer } 1071d3046f7dSMichael Pfeiffer 1072efa8b4f3SAxel Dörfler 1073d3046f7dSMichael Pfeiffer void 1074fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions() 1075d3046f7dSMichael Pfeiffer { 1076efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings(); 1077efa8b4f3SAxel Dörfler 1078d3046f7dSMichael Pfeiffer if (settings->Lock()) { 1079d3046f7dSMichael Pfeiffer settings->SetInt32("PO:Option", fPrintOptions.Option()); 1080d3046f7dSMichael Pfeiffer settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor()); 1081d3046f7dSMichael Pfeiffer settings->SetFloat("PO:DPI", fPrintOptions.DPI()); 1082d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Width", fPrintOptions.Width()); 1083d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Height", fPrintOptions.Height()); 1084d3046f7dSMichael Pfeiffer settings->Unlock(); 1085d3046f7dSMichael Pfeiffer } 1086d3046f7dSMichael Pfeiffer } 1087d3046f7dSMichael Pfeiffer 1088efa8b4f3SAxel Dörfler 1089cdb89ebbSMatthew Wilber bool 1090fd952aefSRyan Leavengood ShowImageWindow::_PageSetup() 1091780d8a62SMichael Pfeiffer { 1092cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 1093efa8b4f3SAxel Dörfler if (fPrintSettings != NULL) 1094780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 1095efa8b4f3SAxel Dörfler 10966163f333SKarsten Heimrich status_t status = printJob.ConfigPage(); 10976163f333SKarsten Heimrich if (status == B_OK) { 1098780d8a62SMichael Pfeiffer delete fPrintSettings; 1099780d8a62SMichael Pfeiffer fPrintSettings = printJob.Settings(); 1100780d8a62SMichael Pfeiffer } 1101efa8b4f3SAxel Dörfler 11026163f333SKarsten Heimrich return status == B_OK; 1103780d8a62SMichael Pfeiffer } 1104780d8a62SMichael Pfeiffer 1105efa8b4f3SAxel Dörfler 1106780d8a62SMichael Pfeiffer void 1107fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint() 1108780d8a62SMichael Pfeiffer { 11096163f333SKarsten Heimrich if (fPrintSettings == NULL) { 1110cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 11116163f333SKarsten Heimrich if (printJob.ConfigJob() == B_OK) 11126163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 11136163f333SKarsten Heimrich } 1114780d8a62SMichael Pfeiffer 1115cd6b5cdeSAxel Dörfler fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds()); 1116cd6b5cdeSAxel Dörfler fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1); 1117780d8a62SMichael Pfeiffer 1118efa8b4f3SAxel Dörfler new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50), 1119efa8b4f3SAxel Dörfler &fPrintOptions, this); 1120780d8a62SMichael Pfeiffer } 1121780d8a62SMichael Pfeiffer 1122efa8b4f3SAxel Dörfler 1123780d8a62SMichael Pfeiffer void 1124fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg) 1125780d8a62SMichael Pfeiffer { 1126780d8a62SMichael Pfeiffer status_t st; 1127efa8b4f3SAxel Dörfler if (msg->FindInt32("status", &st) != B_OK || st != B_OK) 1128780d8a62SMichael Pfeiffer return; 1129780d8a62SMichael Pfeiffer 1130fd952aefSRyan Leavengood _SavePrintOptions(); 1131d3046f7dSMichael Pfeiffer 1132cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name); 11336163f333SKarsten Heimrich if (fPrintSettings) 1134780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings)); 11356163f333SKarsten Heimrich 1136780d8a62SMichael Pfeiffer if (printJob.ConfigJob() == B_OK) { 11376163f333SKarsten Heimrich delete fPrintSettings; 11386163f333SKarsten Heimrich fPrintSettings = printJob.Settings(); 1139780d8a62SMichael Pfeiffer 1140780d8a62SMichael Pfeiffer // first/lastPage is unused for now 11413177ae77SStefano Ceccherini int32 firstPage = printJob.FirstPage(); 11423177ae77SStefano Ceccherini int32 lastPage = printJob.LastPage(); 11436163f333SKarsten Heimrich BRect printableRect = printJob.PrintableRect(); 11446163f333SKarsten Heimrich 1145efa8b4f3SAxel Dörfler if (firstPage < 1) 1146780d8a62SMichael Pfeiffer firstPage = 1; 1147efa8b4f3SAxel Dörfler if (lastPage < firstPage) 1148780d8a62SMichael Pfeiffer lastPage = firstPage; 1149780d8a62SMichael Pfeiffer 1150cd6b5cdeSAxel Dörfler BBitmap* bitmap = fImageView->Bitmap(); 11513177ae77SStefano Ceccherini float imageWidth = bitmap->Bounds().Width() + 1.0; 11523177ae77SStefano Ceccherini float imageHeight = bitmap->Bounds().Height() + 1.0; 1153780d8a62SMichael Pfeiffer 11546163f333SKarsten Heimrich float width; 1155780d8a62SMichael Pfeiffer switch (fPrintOptions.Option()) { 11566163f333SKarsten Heimrich case PrintOptions::kFitToPage: { 11576163f333SKarsten Heimrich float w1 = printableRect.Width()+1; 1158cd6b5cdeSAxel Dörfler float w2 = imageWidth * (printableRect.Height() + 1) 1159cd6b5cdeSAxel Dörfler / imageHeight; 1160efa8b4f3SAxel Dörfler if (w2 < w1) 1161780d8a62SMichael Pfeiffer width = w2; 1162efa8b4f3SAxel Dörfler else 1163780d8a62SMichael Pfeiffer width = w1; 11646163f333SKarsten Heimrich } break; 1165780d8a62SMichael Pfeiffer case PrintOptions::kZoomFactor: 1166780d8a62SMichael Pfeiffer width = imageWidth * fPrintOptions.ZoomFactor(); 1167780d8a62SMichael Pfeiffer break; 1168780d8a62SMichael Pfeiffer case PrintOptions::kDPI: 1169780d8a62SMichael Pfeiffer width = imageWidth * 72.0 / fPrintOptions.DPI(); 1170780d8a62SMichael Pfeiffer break; 1171780d8a62SMichael Pfeiffer case PrintOptions::kWidth: 1172780d8a62SMichael Pfeiffer case PrintOptions::kHeight: 1173780d8a62SMichael Pfeiffer width = fPrintOptions.Width(); 1174780d8a62SMichael Pfeiffer break; 1175efa8b4f3SAxel Dörfler 1176780d8a62SMichael Pfeiffer default: 1177780d8a62SMichael Pfeiffer // keep compiler silent; should not reach here 1178780d8a62SMichael Pfeiffer width = imageWidth; 1179780d8a62SMichael Pfeiffer } 1180780d8a62SMichael Pfeiffer 1181efa8b4f3SAxel Dörfler // TODO: eventually print large images on several pages 1182780d8a62SMichael Pfeiffer printJob.BeginJob(); 1183d3046f7dSMichael Pfeiffer fImageView->SetScale(width / imageWidth); 11845eb50e46SMichael Pfeiffer // coordinates are relative to printable rectangle 11855eb50e46SMichael Pfeiffer BRect bounds(bitmap->Bounds()); 11865eb50e46SMichael Pfeiffer printJob.DrawView(fImageView, bounds, BPoint(0, 0)); 1187d3046f7dSMichael Pfeiffer fImageView->SetScale(1.0); 1188780d8a62SMichael Pfeiffer printJob.SpoolPage(); 1189780d8a62SMichael Pfeiffer printJob.CommitJob(); 1190780d8a62SMichael Pfeiffer } 1191780d8a62SMichael Pfeiffer } 1192780d8a62SMichael Pfeiffer 119356b0c7b9SKarsten Heimrich 1194780d8a62SMichael Pfeiffer bool 1195cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested() 1196cdb89ebbSMatthew Wilber { 1197efa8b4f3SAxel Dörfler if (fSavePanel) { 1198efa8b4f3SAxel Dörfler // Don't allow this window to be closed if a save panel is open 1199efa8b4f3SAxel Dörfler return false; 1200cdb89ebbSMatthew Wilber } 1201cdb89ebbSMatthew Wilber 1202fd952aefSRyan Leavengood bool quit = _ClosePrompt(); 1203efa8b4f3SAxel Dörfler if (quit) { 120407caaa8eSMatthew Wilber // tell the app to forget about this window 120507caaa8eSMatthew Wilber be_app->PostMessage(MSG_WINDOW_QUIT); 120607caaa8eSMatthew Wilber } 1207fc0a275bSMatthew Wilber 1208efa8b4f3SAxel Dörfler return quit; 1209efa8b4f3SAxel Dörfler } 1210