1efa8b4f3SAxel Dörfler /*
2d5647665SHumdinger * Copyright 2003-2014, Haiku, Inc. All Rights Reserved.
3d9f6762dSMichael Pfeiffer * Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
4d9f6762dSMichael Pfeiffer * Copyright 2006 Bernd Korz. All Rights Reserved
5efa8b4f3SAxel Dörfler * Distributed under the terms of the MIT License.
6efa8b4f3SAxel Dörfler *
7efa8b4f3SAxel Dörfler * Authors:
8efa8b4f3SAxel Dörfler * Fernando Francisco de Oliveira
9efa8b4f3SAxel Dörfler * Michael Wilber
10efa8b4f3SAxel Dörfler * Michael Pfeiffer
11d9f6762dSMichael Pfeiffer * yellowTAB GmbH
12d9f6762dSMichael Pfeiffer * Bernd Korz
13e2069723SAxel Dörfler * Axel Dörfler, axeld@pinc-software.de
149b13c418SStephan Aßmus * Stephan Aßmus <superstippi@gmx.de>
15efa8b4f3SAxel Dörfler */
1613afa642SPhil Greenway
174fd570d3SAxel Dörfler
18efa8b4f3SAxel Dörfler #include "ShowImageWindow.h"
19efa8b4f3SAxel Dörfler
20fd952aefSRyan Leavengood #include <new>
21fd952aefSRyan Leavengood #include <stdio.h>
2204f96544SAxel Dörfler #include <stdlib.h>
236163f333SKarsten Heimrich
24efa8b4f3SAxel Dörfler #include <Alert.h>
2513afa642SPhil Greenway #include <Application.h>
2613afa642SPhil Greenway #include <Bitmap.h>
27fc0a275bSMatthew Wilber #include <BitmapStream.h>
28554e2073SAdrien Destugues #include <Button.h>
291ed4535fSStephan Aßmus #include <Catalog.h>
30efa8b4f3SAxel Dörfler #include <Clipboard.h>
3160c23976SJanus #include <ControlLook.h>
3203ad73fcSAdrien Destugues #include <DurationFormat.h>
3313afa642SPhil Greenway #include <Entry.h>
34fc0a275bSMatthew Wilber #include <File.h>
356163f333SKarsten Heimrich #include <FilePanel.h>
3620e18366SAugustin Cavalier #include <GridLayout.h>
371ed4535fSStephan Aßmus #include <Locale.h>
3813afa642SPhil Greenway #include <Menu.h>
3913afa642SPhil Greenway #include <MenuBar.h>
4013afa642SPhil Greenway #include <MenuItem.h>
414aa63633SAxel Dörfler #include <MessageRunner.h>
4213afa642SPhil Greenway #include <Path.h>
43efa8b4f3SAxel Dörfler #include <PrintJob.h>
4436272f0dSAxel Dörfler #include <RecentItems.h>
45efa8b4f3SAxel Dörfler #include <Roster.h>
46efa8b4f3SAxel Dörfler #include <Screen.h>
4713afa642SPhil Greenway #include <ScrollView.h>
486163f333SKarsten Heimrich #include <String.h>
49efa8b4f3SAxel Dörfler #include <SupportDefs.h>
506163f333SKarsten Heimrich #include <TranslationDefs.h>
5113afa642SPhil Greenway #include <TranslationUtils.h>
5213afa642SPhil Greenway #include <TranslatorRoster.h>
5313afa642SPhil Greenway
54b9767a83SAxel Dörfler #include "ImageCache.h"
55e2069723SAxel Dörfler #include "ProgressWindow.h"
56fd952aefSRyan Leavengood #include "ShowImageApp.h"
57fd952aefSRyan Leavengood #include "ShowImageConstants.h"
58fd952aefSRyan Leavengood #include "ShowImageStatusView.h"
59fd952aefSRyan Leavengood #include "ShowImageView.h"
6032ed03a5SHumdinger #include "SupportingAppsMenu.h"
61cf0d8308SStephan Aßmus #include "ToolBarIcons.h"
6213afa642SPhil Greenway
63a8fc7138SMichael Pfeiffer
64cd6b5cdeSAxel Dörfler // BMessage field names used in Save messages
65cd6b5cdeSAxel Dörfler const char* kTypeField = "be:type";
66cd6b5cdeSAxel Dörfler const char* kTranslatorField = "be:translator";
67cd6b5cdeSAxel Dörfler
684aa63633SAxel Dörfler const bigtime_t kDefaultSlideShowDelay = 3000000;
694aa63633SAxel Dörfler // 3 seconds
704aa63633SAxel Dörfler
71cd6b5cdeSAxel Dörfler
72e2069723SAxel Dörfler // message constants
73e2069723SAxel Dörfler enum {
74e2069723SAxel Dörfler MSG_CAPTURE_MOUSE = 'mCPM',
75e2069723SAxel Dörfler MSG_CHANGE_FOCUS = 'mCFS',
76e2069723SAxel Dörfler MSG_WINDOW_QUIT = 'mWQT',
77e2069723SAxel Dörfler MSG_OUTPUT_TYPE = 'BTMN',
78e2069723SAxel Dörfler MSG_SAVE_PANEL = 'mFSP',
79e2069723SAxel Dörfler MSG_CLEAR_SELECT = 'mCSL',
80e2069723SAxel Dörfler MSG_SELECT_ALL = 'mSAL',
81e2069723SAxel Dörfler MSG_SELECTION_MODE = 'mSLM',
82e2069723SAxel Dörfler MSG_PAGE_FIRST = 'mPGF',
83e2069723SAxel Dörfler MSG_PAGE_LAST = 'mPGL',
84e2069723SAxel Dörfler MSG_PAGE_NEXT = 'mPGN',
85e2069723SAxel Dörfler MSG_PAGE_PREV = 'mPGP',
86e2069723SAxel Dörfler MSG_GOTO_PAGE = 'mGTP',
87e2069723SAxel Dörfler MSG_ZOOM_IN = 'mZIN',
88e2069723SAxel Dörfler MSG_ZOOM_OUT = 'mZOU',
89e2069723SAxel Dörfler MSG_SCALE_BILINEAR = 'mSBL',
90e2069723SAxel Dörfler MSG_DESKTOP_BACKGROUND = 'mDBG',
91e2069723SAxel Dörfler MSG_ROTATE_90 = 'mR90',
92e2069723SAxel Dörfler MSG_ROTATE_270 = 'mR27',
93e2069723SAxel Dörfler MSG_FLIP_LEFT_TO_RIGHT = 'mFLR',
94e2069723SAxel Dörfler MSG_FLIP_TOP_TO_BOTTOM = 'mFTB',
95e2069723SAxel Dörfler MSG_SLIDE_SHOW_DELAY = 'mSSD',
96e2069723SAxel Dörfler MSG_SHOW_CAPTION = 'mSCP',
97e2069723SAxel Dörfler MSG_PAGE_SETUP = 'mPSU',
98e2069723SAxel Dörfler MSG_PREPARE_PRINT = 'mPPT',
99fb94ed11SAvi Brenner MSG_GET_INFO = 'mGFI',
1005b76e505SStephan Aßmus MSG_SET_RATING = 'mSRT',
101e2069723SAxel Dörfler kMsgFitToWindow = 'mFtW',
102e2069723SAxel Dörfler kMsgOriginalSize = 'mOSZ',
1034aa63633SAxel Dörfler kMsgStretchToWindow = 'mStW',
104cf0d8308SStephan Aßmus kMsgNextSlide = 'mNxS',
10594fd9498SStephan Aßmus kMsgToggleToolBar = 'mTTB',
10694fd9498SStephan Aßmus kMsgSlideToolBar = 'mSTB',
10794fd9498SStephan Aßmus kMsgFinishSlidingToolBar = 'mFST'
108e2069723SAxel Dörfler };
109e2069723SAxel Dörfler
110e2069723SAxel Dörfler
111cd6b5cdeSAxel Dörfler // This is temporary solution for building BString with printf like format.
112cd6b5cdeSAxel Dörfler // will be removed in the future.
113cd6b5cdeSAxel Dörfler static void
bs_printf(BString * string,const char * format,...)114cd6b5cdeSAxel Dörfler bs_printf(BString* string, const char* format, ...)
115cd6b5cdeSAxel Dörfler {
116cd6b5cdeSAxel Dörfler va_list ap;
117cd6b5cdeSAxel Dörfler char* buf;
118cd6b5cdeSAxel Dörfler
119cd6b5cdeSAxel Dörfler va_start(ap, format);
120cd6b5cdeSAxel Dörfler vasprintf(&buf, format, ap);
121cd6b5cdeSAxel Dörfler string->SetTo(buf);
122cd6b5cdeSAxel Dörfler free(buf);
123cd6b5cdeSAxel Dörfler va_end(ap);
124cd6b5cdeSAxel Dörfler }
125cd6b5cdeSAxel Dörfler
126cd6b5cdeSAxel Dörfler
1276163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow
1286163f333SKarsten Heimrich
1296163f333SKarsten Heimrich
130546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
131546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Menus"
132cf0d8308SStephan Aßmus
133cf0d8308SStephan Aßmus
ShowImageWindow(BRect frame,const entry_ref & ref,const BMessenger & trackerMessenger)1345b76e505SStephan Aßmus ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref,
135efa8b4f3SAxel Dörfler const BMessenger& trackerMessenger)
136fd952aefSRyan Leavengood :
13720e18366SAugustin Cavalier BWindow(frame, "", B_DOCUMENT_WINDOW, 0),
138b9767a83SAxel Dörfler fNavigator(ref, trackerMessenger),
139fd952aefSRyan Leavengood fSavePanel(NULL),
140fd952aefSRyan Leavengood fBar(NULL),
141fd952aefSRyan Leavengood fBrowseMenu(NULL),
142fd952aefSRyan Leavengood fGoToPageMenu(NULL),
1434aa63633SAxel Dörfler fSlideShowDelayMenu(NULL),
14494a4c1c4SAugustin Cavalier fToolBar(NULL),
145fd952aefSRyan Leavengood fImageView(NULL),
146fd952aefSRyan Leavengood fStatusView(NULL),
147e2069723SAxel Dörfler fProgressWindow(new ProgressWindow()),
148fd952aefSRyan Leavengood fModified(false),
149fd952aefSRyan Leavengood fFullScreen(false),
150fd952aefSRyan Leavengood fShowCaption(true),
151cf0d8308SStephan Aßmus fShowToolBar(true),
1524aa63633SAxel Dörfler fPrintSettings(NULL),
1534aa63633SAxel Dörfler fSlideShowRunner(NULL),
1544aa63633SAxel Dörfler fSlideShowDelay(kDefaultSlideShowDelay)
15513afa642SPhil Greenway {
1562281340dSAxel Dörfler _ApplySettings();
157fc0a275bSMatthew Wilber
15894fd9498SStephan Aßmus SetLayout(new BGroupLayout(B_VERTICAL, 0));
15994fd9498SStephan Aßmus
16013afa642SPhil Greenway // create menu bar
16194fd9498SStephan Aßmus fBar = new BMenuBar("menu_bar");
162b9767a83SAxel Dörfler _AddMenus(fBar);
16394fd9498SStephan Aßmus float menuBarMinWidth = fBar->MinSize().width;
164e9dcd874SAxel Dörfler AddChild(fBar);
16513afa642SPhil Greenway
16694fd9498SStephan Aßmus // Add a content view so the tool bar can be moved outside of the
16794fd9498SStephan Aßmus // visible portion without colliding with the menu bar.
168cf0d8308SStephan Aßmus
16994fd9498SStephan Aßmus BView* contentView = new BView(BRect(), "content", B_FOLLOW_NONE, 0);
170fa19dd44Slooncraz contentView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
17194fd9498SStephan Aßmus contentView->SetExplicitMinSize(BSize(250, 100));
17294fd9498SStephan Aßmus AddChild(contentView);
17394fd9498SStephan Aßmus
17494fd9498SStephan Aßmus // Create the tool bar
17594fd9498SStephan Aßmus BRect viewFrame = contentView->Bounds();
17694a4c1c4SAugustin Cavalier fToolBar = new BToolBar(viewFrame);
177cf0d8308SStephan Aßmus
178cf0d8308SStephan Aßmus // Add the tool icons.
179cf0d8308SStephan Aßmus
18094a4c1c4SAugustin Cavalier // fToolBar->AddAction(MSG_FILE_OPEN, be_app,
181cf0d8308SStephan Aßmus // tool_bar_icon(kIconDocumentOpen), B_TRANSLATE("Open" B_UTF8_ELLIPSIS));
18294a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FILE_PREV, this,
18358ee42e9SAugustin Cavalier tool_bar_icon(kIconGoPrevious), B_TRANSLATE("Previous file"));
18494a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FILE_NEXT, this, tool_bar_icon(kIconGoNext),
18558ee42e9SAugustin Cavalier B_TRANSLATE("Next file"));
186a877c0e7SStephan Aßmus BMessage* fullScreenSlideShow = new BMessage(MSG_SLIDE_SHOW);
187a877c0e7SStephan Aßmus fullScreenSlideShow->AddBool("full screen", true);
18894a4c1c4SAugustin Cavalier fToolBar->AddAction(fullScreenSlideShow, this,
18958ee42e9SAugustin Cavalier tool_bar_icon(kIconMediaMovieLibrary), B_TRANSLATE("Slide show"));
19094a4c1c4SAugustin Cavalier fToolBar->AddSeparator();
19194a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_SELECTION_MODE, this,
192cf0d8308SStephan Aßmus tool_bar_icon(kIconDrawRectangularSelection),
19358ee42e9SAugustin Cavalier B_TRANSLATE("Selection mode"));
19494a4c1c4SAugustin Cavalier fToolBar->AddSeparator();
19594a4c1c4SAugustin Cavalier fToolBar->AddAction(kMsgOriginalSize, this,
19658ee42e9SAugustin Cavalier tool_bar_icon(kIconZoomOriginal), B_TRANSLATE("Original size"), NULL,
19758ee42e9SAugustin Cavalier true);
19894a4c1c4SAugustin Cavalier fToolBar->AddAction(kMsgFitToWindow, this,
19958ee42e9SAugustin Cavalier tool_bar_icon(kIconZoomFitBest), B_TRANSLATE("Fit to window"));
20094a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_ZOOM_IN, this, tool_bar_icon(kIconZoomIn),
20158ee42e9SAugustin Cavalier B_TRANSLATE("Zoom in"));
20294a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_ZOOM_OUT, this, tool_bar_icon(kIconZoomOut),
20358ee42e9SAugustin Cavalier B_TRANSLATE("Zoom out"));
204442e457dSGerasim Troeglazov fToolBar->AddSeparator();
205442e457dSGerasim Troeglazov fToolBar->AddAction(MSG_PAGE_PREV, this, tool_bar_icon(kIconPagePrevious),
20658ee42e9SAugustin Cavalier B_TRANSLATE("Previous page"));
207442e457dSGerasim Troeglazov fToolBar->AddAction(MSG_PAGE_NEXT, this, tool_bar_icon(kIconPageNext),
20858ee42e9SAugustin Cavalier B_TRANSLATE("Next page"));
20994a4c1c4SAugustin Cavalier fToolBar->AddGlue();
21094a4c1c4SAugustin Cavalier fToolBar->AddAction(MSG_FULL_SCREEN, this,
21158ee42e9SAugustin Cavalier tool_bar_icon(kIconViewWindowed), B_TRANSLATE("Leave full screen"));
21294a4c1c4SAugustin Cavalier fToolBar->SetActionVisible(MSG_FULL_SCREEN, false);
213cf0d8308SStephan Aßmus
21494a4c1c4SAugustin Cavalier fToolBar->ResizeTo(viewFrame.Width(), fToolBar->MinSize().height);
215cf0d8308SStephan Aßmus
21694a4c1c4SAugustin Cavalier contentView->AddChild(fToolBar);
217cf0d8308SStephan Aßmus
218cf0d8308SStephan Aßmus if (fShowToolBar)
21994a4c1c4SAugustin Cavalier viewFrame.top = fToolBar->Frame().bottom + 1;
220cf0d8308SStephan Aßmus else
22194a4c1c4SAugustin Cavalier fToolBar->Hide();
222cf0d8308SStephan Aßmus
22395667008SJanus fToolBarVisible = fShowToolBar;
22495667008SJanus
22594fd9498SStephan Aßmus viewFrame.bottom = contentView->Bounds().bottom;
22620e18366SAugustin Cavalier
22720e18366SAugustin Cavalier // create the scroll area
22820e18366SAugustin Cavalier fScrollArea = new BScrollView("image_scroller", NULL, 0,
22920e18366SAugustin Cavalier false, false, B_PLAIN_BORDER);
23020e18366SAugustin Cavalier BGridLayout* gridLayout = new BGridLayout(0, 0);
23120e18366SAugustin Cavalier fScrollArea->SetLayout(gridLayout);
2322b50f775SHumdinger gridLayout->SetInsets(0, 1, -1, -1);
23320e18366SAugustin Cavalier
23420e18366SAugustin Cavalier fScrollArea->MoveTo(viewFrame.LeftTop());
23520e18366SAugustin Cavalier fScrollArea->ResizeTo(viewFrame.Size());
23620e18366SAugustin Cavalier fScrollArea->SetResizingMode(B_FOLLOW_ALL);
23720e18366SAugustin Cavalier contentView->AddChild(fScrollArea);
23813afa642SPhil Greenway
23913afa642SPhil Greenway // create the image view
24020e18366SAugustin Cavalier fImageView = new ShowImageView("image_view",
241e2069723SAxel Dörfler B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED
242e2069723SAxel Dörfler | B_FRAME_EVENTS);
24320e18366SAugustin Cavalier fImageView->SetExplicitMinSize(BSize(0, 0));
24420e18366SAugustin Cavalier gridLayout->AddView(fImageView, 0, 0, 2, 1);
24513afa642SPhil Greenway
24620e18366SAugustin Cavalier // create the scroll bars (wrapped to avoid double borders)
24720e18366SAugustin Cavalier fVScrollBar = new BScrollBar(NULL, NULL, 0, 0, B_VERTICAL); {
24820e18366SAugustin Cavalier BGroupView* vScrollBarContainer = new BGroupView(B_VERTICAL, 0);
24920e18366SAugustin Cavalier vScrollBarContainer->GroupLayout()->AddView(fVScrollBar);
25020e18366SAugustin Cavalier vScrollBarContainer->GroupLayout()->SetInsets(0, -1, 0, -1);
25120e18366SAugustin Cavalier gridLayout->AddView(vScrollBarContainer, 2, 0);
25220e18366SAugustin Cavalier }
25320e18366SAugustin Cavalier
25420e18366SAugustin Cavalier fHScrollBar = new BScrollBar(NULL, NULL, 0, 0, B_HORIZONTAL); {
25520e18366SAugustin Cavalier BGroupView* hScrollBarContainer = new BGroupView(B_VERTICAL, 0);
25620e18366SAugustin Cavalier hScrollBarContainer->GroupLayout()->AddView(fHScrollBar);
25720e18366SAugustin Cavalier hScrollBarContainer->GroupLayout()->SetInsets(0, -1, -1, -1);
25820e18366SAugustin Cavalier gridLayout->AddView(hScrollBarContainer, 1, 1);
25920e18366SAugustin Cavalier }
26020e18366SAugustin Cavalier
26120e18366SAugustin Cavalier fVScrollBar->SetTarget(fImageView);
26220e18366SAugustin Cavalier fHScrollBar->SetTarget(fImageView);
26320e18366SAugustin Cavalier
26420e18366SAugustin Cavalier fStatusView = new ShowImageStatusView;
26520e18366SAugustin Cavalier gridLayout->AddView(fStatusView, 0, 1);
26613afa642SPhil Greenway
2679b13c418SStephan Aßmus // Update minimum window size
26894a4c1c4SAugustin Cavalier float toolBarMinWidth = fToolBar->MinSize().width;
26920e18366SAugustin Cavalier SetSizeLimits(std::max(menuBarMinWidth, toolBarMinWidth), 100000,
27020e18366SAugustin Cavalier fBar->MinSize().height + gridLayout->MinSize().height, 100000);
27113afa642SPhil Greenway
272134d6076SMichael Pfeiffer // finish creating the window
273b9767a83SAxel Dörfler if (_LoadImage() != B_OK) {
274ba3217eeSAxel Dörfler _LoadError(ref);
2755e09d5dbSRyan Leavengood Quit();
27601939af6SAxel Dörfler return;
277d10d5947SMichael Pfeiffer }
278402c09e5SMatthew Wilber
279d9f6762dSMichael Pfeiffer // add View menu here so it can access ShowImageView methods
280546208a5SOliver Tappe BMenu* menu = new BMenu(B_TRANSLATE_CONTEXT("View", "Menus"));
281fd952aefSRyan Leavengood _BuildViewMenu(menu, false);
282d9f6762dSMichael Pfeiffer fBar->AddItem(menu);
283d9f6762dSMichael Pfeiffer
28415305513SHumdinger menu = new BMenu(B_TRANSLATE_CONTEXT("Attributes", "Menus"));
28515305513SHumdinger menu->AddItem(_BuildRatingMenu());
28615305513SHumdinger BMessage* message = new BMessage(MSG_SET_RATING);
28715305513SHumdinger message->AddInt32("rating", 0);
28815305513SHumdinger fResetRatingItem = new BMenuItem(B_TRANSLATE("Reset rating"), message);
28915305513SHumdinger menu->AddItem(fResetRatingItem);
29015305513SHumdinger fBar->AddItem(menu);
2915b76e505SStephan Aßmus
292d9f6762dSMichael Pfeiffer SetPulseRate(100000);
293d9f6762dSMichael Pfeiffer // every 1/10 second; ShowImageView needs it for marching ants
294d9f6762dSMichael Pfeiffer
2956db01936SAxel Dörfler _MarkMenuItem(menu, MSG_SELECTION_MODE,
2966db01936SAxel Dörfler fImageView->IsSelectionModeEnabled());
2976db01936SAxel Dörfler
298402c09e5SMatthew Wilber // Tell application object to query the clipboard
299402c09e5SMatthew Wilber // and tell this window if it contains interesting data or not
300402c09e5SMatthew Wilber be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
301cd6b5cdeSAxel Dörfler
302cd6b5cdeSAxel Dörfler // The window will be shown on screen automatically
303cd6b5cdeSAxel Dörfler Run();
30413afa642SPhil Greenway }
30513afa642SPhil Greenway
306efa8b4f3SAxel Dörfler
~ShowImageWindow()30713afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
30813afa642SPhil Greenway {
309e2069723SAxel Dörfler fProgressWindow->Lock();
310e2069723SAxel Dörfler fProgressWindow->Quit();
3114aa63633SAxel Dörfler
3124aa63633SAxel Dörfler _StopSlideShow();
31313afa642SPhil Greenway }
31413afa642SPhil Greenway
315efa8b4f3SAxel Dörfler
316cdb89ebbSMatthew Wilber void
BuildContextMenu(BMenu * menu)317d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu)
318d9f6762dSMichael Pfeiffer {
319fd952aefSRyan Leavengood _BuildViewMenu(menu, true);
320d9f6762dSMichael Pfeiffer }
321efa8b4f3SAxel Dörfler
32256b0c7b9SKarsten Heimrich
323cdb89ebbSMatthew Wilber void
_BuildViewMenu(BMenu * menu,bool popupMenu)324fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
325da87390fSMichael Pfeiffer {
326905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this);
3274aa63633SAxel Dörfler _MarkMenuItem(menu, MSG_SLIDE_SHOW, fSlideShowRunner != NULL);
328905c8c8cSMatt Madia BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay"));
3294aa63633SAxel Dörfler if (fSlideShowDelayMenu == NULL)
3304aa63633SAxel Dörfler fSlideShowDelayMenu = delayMenu;
331efa8b4f3SAxel Dörfler
332efa8b4f3SAxel Dörfler delayMenu->SetRadioMode(true);
3334aa63633SAxel Dörfler
3344aa63633SAxel Dörfler int32 kDelays[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 20};
3354aa63633SAxel Dörfler for (uint32 i = 0; i < sizeof(kDelays) / sizeof(kDelays[0]); i++) {
33603ad73fcSAdrien Destugues BString text;
33703ad73fcSAdrien Destugues BDurationFormat format;
33803ad73fcSAdrien Destugues text.Truncate(0);
33903ad73fcSAdrien Destugues format.Format(text, 0, kDelays[i] * 1000000LL);
3404aa63633SAxel Dörfler
3414aa63633SAxel Dörfler _AddDelayItem(delayMenu, text.String(), kDelays[i] * 1000000LL);
3424aa63633SAxel Dörfler }
343efa8b4f3SAxel Dörfler menu->AddItem(delayMenu);
34430060f17SMatthew Wilber
345efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
346efa8b4f3SAxel Dörfler
347905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Original size"),
348e2069723SAxel Dörfler kMsgOriginalSize, '1', 0, this);
349e2069723SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Fit to window"),
350e2069723SAxel Dörfler kMsgFitToWindow, '0', 0, this);
351905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this);
352905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this);
353efa8b4f3SAxel Dörfler
354efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
355efa8b4f3SAxel Dörfler
3564fd570d3SAxel Dörfler if (!popupMenu || fFullScreen) {
357905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
358905c8c8cSMatt Madia MSG_SCALE_BILINEAR, 0, 0, this);
3594fd570d3SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Stretch to window"),
360e2069723SAxel Dörfler kMsgStretchToWindow, 0, 0, this);
361efa8b4f3SAxel Dörfler
362efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
36332c22143SAxel Dörfler }
364efa8b4f3SAxel Dörfler
365905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Full screen"),
366905c8c8cSMatt Madia MSG_FULL_SCREEN, B_ENTER, 0, this);
367fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
368efa8b4f3SAxel Dörfler
369905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"),
370905c8c8cSMatt Madia MSG_SHOW_CAPTION, 0, 0, this);
371fd952aefSRyan Leavengood _MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
372efa8b4f3SAxel Dörfler
373e2069723SAxel Dörfler _MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->ScaleBilinear());
374e2069723SAxel Dörfler _MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds());
375a60adbf9SAxel Dörfler
376cf0d8308SStephan Aßmus if (!popupMenu) {
37794fd9498SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar,
378d5647665SHumdinger 'B', 0, this);
379cf0d8308SStephan Aßmus _MarkMenuItem(menu, kMsgToggleToolBar,
38094a4c1c4SAugustin Cavalier !fToolBar->IsHidden(fToolBar));
381cf0d8308SStephan Aßmus }
382cf0d8308SStephan Aßmus
383d9f6762dSMichael Pfeiffer if (popupMenu) {
384a60adbf9SAxel Dörfler menu->AddSeparatorItem();
385905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
3861ed4535fSStephan Aßmus MSG_DESKTOP_BACKGROUND, 0, 0, this);
38732ed03a5SHumdinger
38832ed03a5SHumdinger BMenu* openWithMenu = new BMenu(B_TRANSLATE("Open with" B_UTF8_ELLIPSIS));
38932ed03a5SHumdinger _UpdateOpenWithMenu(openWithMenu);
39032ed03a5SHumdinger BMenuItem* item = new BMenuItem(openWithMenu, NULL);
39132ed03a5SHumdinger menu->AddItem(item);
392d9f6762dSMichael Pfeiffer }
393da87390fSMichael Pfeiffer }
394da87390fSMichael Pfeiffer
395efa8b4f3SAxel Dörfler
39632ed03a5SHumdinger void
_UpdateOpenWithMenu(BMenu * menu)39732ed03a5SHumdinger ShowImageWindow::_UpdateOpenWithMenu(BMenu* menu)
39832ed03a5SHumdinger {
39932ed03a5SHumdinger update_supporting_apps_menu(menu, fMimeType, MSG_OPEN_WITH, this);
40032ed03a5SHumdinger }
40132ed03a5SHumdinger
40232ed03a5SHumdinger
4035b76e505SStephan Aßmus BMenu*
_BuildRatingMenu()4045b76e505SStephan Aßmus ShowImageWindow::_BuildRatingMenu()
4055b76e505SStephan Aßmus {
4065b76e505SStephan Aßmus fRatingMenu = new BMenu(B_TRANSLATE("Rating"));
4075b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) {
40815305513SHumdinger BMessage* message = new BMessage(MSG_SET_RATING);
4095b76e505SStephan Aßmus BString label;
410dae087edSEmir SARI fNumberFormat.Format(label, i);
4115b76e505SStephan Aßmus message->AddInt32("rating", i);
4125b76e505SStephan Aßmus fRatingMenu->AddItem(new BMenuItem(label.String(), message));
4135b76e505SStephan Aßmus }
41415305513SHumdinger
4155b76e505SStephan Aßmus return fRatingMenu;
4165b76e505SStephan Aßmus }
4175b76e505SStephan Aßmus
4185b76e505SStephan Aßmus
419da87390fSMichael Pfeiffer void
_AddMenus(BMenuBar * bar)420b9767a83SAxel Dörfler ShowImageWindow::_AddMenus(BMenuBar* bar)
42113afa642SPhil Greenway {
422905c8c8cSMatt Madia BMenu* menu = new BMenu(B_TRANSLATE("File"));
42336272f0dSAxel Dörfler
42436272f0dSAxel Dörfler // Add recent files to "Open File" entry as sub-menu.
42536272f0dSAxel Dörfler BMenuItem* item = new BMenuItem(BRecentFilesList::NewFileListMenu(
42636272f0dSAxel Dörfler B_TRANSLATE("Open" B_UTF8_ELLIPSIS), NULL, NULL, be_app, 10, true,
42736272f0dSAxel Dörfler NULL, kApplicationSignature), new BMessage(MSG_FILE_OPEN));
42836272f0dSAxel Dörfler item->SetShortcut('O', 0);
42936272f0dSAxel Dörfler item->SetTarget(be_app);
43036272f0dSAxel Dörfler menu->AddItem(item);
43132ed03a5SHumdinger
432efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
43336272f0dSAxel Dörfler
43432ed03a5SHumdinger fOpenWithMenu = new BMenu(B_TRANSLATE("Open with" B_UTF8_ELLIPSIS));
43532ed03a5SHumdinger item = new BMenuItem(fOpenWithMenu, NULL);
43632ed03a5SHumdinger menu->AddItem(item);
43732ed03a5SHumdinger
4386db01936SAxel Dörfler BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS),
4391ed4535fSStephan Aßmus B_ITEMS_IN_COLUMN);
4406db01936SAxel Dörfler BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP);
441fc0a275bSMatthew Wilber // Fill Save As submenu with all types that can be converted
442fc0a275bSMatthew Wilber // to from the Be bitmap image format
4436db01936SAxel Dörfler menu->AddItem(menuSaveAs);
444d5647665SHumdinger _AddItemMenu(menu, B_TRANSLATE("Move to Trash"), kMsgDeleteCurrentFile, 'T', 0, this);
4454391f32bSHumdinger _AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
4464391f32bSHumdinger MSG_DESKTOP_BACKGROUND, 0, 0, this);
447*de2a79ceSHumdinger _AddItemMenu(menu, B_TRANSLATE("Get info"), MSG_GET_INFO, 'I', 0, this);
448efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
449905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS),
4501ed4535fSStephan Aßmus MSG_PAGE_SETUP, 0, 0, this);
451905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS),
4521ed4535fSStephan Aßmus MSG_PREPARE_PRINT, 'P', 0, this);
453efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
4544391f32bSHumdinger _AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this);
455905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app);
456efa8b4f3SAxel Dörfler bar->AddItem(menu);
45713afa642SPhil Greenway
458905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Edit"));
459905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false);
460efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
461cf0d8308SStephan Aßmus _AddItemMenu(menu, B_TRANSLATE("Selection mode"), MSG_SELECTION_MODE, 0, 0,
4626db01936SAxel Dörfler this);
46332c22143SAxel Dörfler _AddItemMenu(menu, B_TRANSLATE("Clear selection"),
46432c22143SAxel Dörfler MSG_CLEAR_SELECT, 0, 0, this, false);
465905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Select all"),
466905c8c8cSMatt Madia MSG_SELECT_ALL, 'A', 0, this);
467efa8b4f3SAxel Dörfler bar->AddItem(menu);
46813afa642SPhil Greenway
469905c8c8cSMatt Madia menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse"));
470905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("First page"),
4711ed4535fSStephan Aßmus MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this);
472905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Last page"),
4731ed4535fSStephan Aßmus MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this);
474905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous page"),
475905c8c8cSMatt Madia MSG_PAGE_PREV, B_LEFT_ARROW, 0, this);
476905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next page"),
477905c8c8cSMatt Madia MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this);
478905c8c8cSMatt Madia fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page"));
4795e427b6aSMichael Pfeiffer fGoToPageMenu->SetRadioMode(true);
480efa8b4f3SAxel Dörfler menu->AddItem(fGoToPageMenu);
481efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
482905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Previous file"),
483905c8c8cSMatt Madia MSG_FILE_PREV, B_UP_ARROW, 0, this);
484905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Next file"),
485905c8c8cSMatt Madia MSG_FILE_NEXT, B_DOWN_ARROW, 0, this);
486efa8b4f3SAxel Dörfler bar->AddItem(menu);
48703839579SMatthew Wilber
488905c8c8cSMatt Madia menu = new BMenu(B_TRANSLATE("Image"));
489905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"),
490905c8c8cSMatt Madia MSG_ROTATE_90, 'R', 0, this);
491905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"),
4921ed4535fSStephan Aßmus MSG_ROTATE_270, 'R', B_SHIFT_KEY, this);
493efa8b4f3SAxel Dörfler menu->AddSeparatorItem();
494905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip left to right"),
4951ed4535fSStephan Aßmus MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this);
496905c8c8cSMatt Madia _AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"),
4971ed4535fSStephan Aßmus MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this);
49804f96544SAxel Dörfler
49904f96544SAxel Dörfler bar->AddItem(menu);
50013afa642SPhil Greenway }
50113afa642SPhil Greenway
502efa8b4f3SAxel Dörfler
503cdb89ebbSMatthew Wilber BMenuItem*
_AddItemMenu(BMenu * menu,const char * label,uint32 what,char shortcut,uint32 modifier,const BHandler * target,bool enabled)504fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what,
5054fd570d3SAxel Dörfler char shortcut, uint32 modifier, const BHandler* target, bool enabled)
506cdb89ebbSMatthew Wilber {
5074fd570d3SAxel Dörfler BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut,
5084fd570d3SAxel Dörfler modifier);
509efa8b4f3SAxel Dörfler menu->AddItem(item);
510efa8b4f3SAxel Dörfler
5116163f333SKarsten Heimrich item->SetTarget(target);
5126163f333SKarsten Heimrich item->SetEnabled(enabled);
5136163f333SKarsten Heimrich
514efa8b4f3SAxel Dörfler return item;
51513afa642SPhil Greenway }
51613afa642SPhil Greenway
517efa8b4f3SAxel Dörfler
518ad13f387SMichael Pfeiffer BMenuItem*
_AddDelayItem(BMenu * menu,const char * label,bigtime_t delay)5194aa63633SAxel Dörfler ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, bigtime_t delay)
520ad13f387SMichael Pfeiffer {
521efa8b4f3SAxel Dörfler BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
5224aa63633SAxel Dörfler message->AddInt64("delay", delay);
523ad13f387SMichael Pfeiffer
5246163f333SKarsten Heimrich BMenuItem* item = new BMenuItem(label, message, 0);
525efa8b4f3SAxel Dörfler item->SetTarget(this);
526ad13f387SMichael Pfeiffer
5274aa63633SAxel Dörfler if (delay == fSlideShowDelay)
528efa8b4f3SAxel Dörfler item->SetMarked(true);
529ad13f387SMichael Pfeiffer
530efa8b4f3SAxel Dörfler menu->AddItem(item);
531efa8b4f3SAxel Dörfler return item;
532ad13f387SMichael Pfeiffer }
533ad13f387SMichael Pfeiffer
534efa8b4f3SAxel Dörfler
535cdb89ebbSMatthew Wilber void
_ResizeWindowToImage()536e2069723SAxel Dörfler ShowImageWindow::_ResizeWindowToImage()
53713afa642SPhil Greenway {
538e2069723SAxel Dörfler BBitmap* bitmap = fImageView->Bitmap();
539d10d5947SMichael Pfeiffer BScreen screen;
540e2069723SAxel Dörfler if (bitmap == NULL || !screen.IsValid())
541efa8b4f3SAxel Dörfler return;
542efa8b4f3SAxel Dörfler
5431076d97bSAxel Dörfler // TODO: use View::GetPreferredSize() instead?
5441076d97bSAxel Dörfler BRect r(bitmap->Bounds());
545893d5930SAdrien Destugues float width = r.Width() + be_control_look->GetScrollBarWidth(B_VERTICAL);
5461076d97bSAxel Dörfler float height = r.Height() + 1 + fBar->Frame().Height()
547893d5930SAdrien Destugues + be_control_look->GetScrollBarWidth(B_HORIZONTAL);
548cdb89ebbSMatthew Wilber
5496163f333SKarsten Heimrich BRect frame = screen.Frame();
5506163f333SKarsten Heimrich const float windowBorder = 5;
551d10d5947SMichael Pfeiffer // dimensions so that window does not reach outside of screen
5526163f333SKarsten Heimrich float maxWidth = frame.Width() + 1 - windowBorder - Frame().left;
5536163f333SKarsten Heimrich float maxHeight = frame.Height() + 1 - windowBorder - Frame().top;
554cdb89ebbSMatthew Wilber
555a8fc7138SMichael Pfeiffer // We have to check size limits manually, otherwise
556a8fc7138SMichael Pfeiffer // menu bar will be too short for small images.
557efa8b4f3SAxel Dörfler
558fc5ca95dSStephan Aßmus float minW, maxW, minH, maxH;
559a8fc7138SMichael Pfeiffer GetSizeLimits(&minW, &maxW, &minH, &maxH);
560efa8b4f3SAxel Dörfler if (maxWidth > maxW)
561efa8b4f3SAxel Dörfler maxWidth = maxW;
562efa8b4f3SAxel Dörfler if (maxHeight > maxH)
563efa8b4f3SAxel Dörfler maxHeight = maxH;
564efa8b4f3SAxel Dörfler if (width < minW)
565efa8b4f3SAxel Dörfler width = minW;
566efa8b4f3SAxel Dörfler if (height < minH)
567efa8b4f3SAxel Dörfler height = minH;
568a8fc7138SMichael Pfeiffer
569efa8b4f3SAxel Dörfler if (width > maxWidth)
570efa8b4f3SAxel Dörfler width = maxWidth;
571efa8b4f3SAxel Dörfler if (height > maxHeight)
572efa8b4f3SAxel Dörfler height = maxHeight;
573d10d5947SMichael Pfeiffer
574d10d5947SMichael Pfeiffer ResizeTo(width, height);
57513afa642SPhil Greenway }
57613afa642SPhil Greenway
577efa8b4f3SAxel Dörfler
5787eca0987SMichael Pfeiffer bool
_ToggleMenuItem(uint32 what)579fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what)
5807eca0987SMichael Pfeiffer {
5817eca0987SMichael Pfeiffer bool marked = false;
5826163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(what);
5837eca0987SMichael Pfeiffer if (item != NULL) {
5847eca0987SMichael Pfeiffer marked = !item->IsMarked();
5857eca0987SMichael Pfeiffer item->SetMarked(marked);
5867eca0987SMichael Pfeiffer }
58794a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(what, marked);
5887eca0987SMichael Pfeiffer return marked;
5897eca0987SMichael Pfeiffer }
5907eca0987SMichael Pfeiffer
591efa8b4f3SAxel Dörfler
592cdb89ebbSMatthew Wilber void
_EnableMenuItem(BMenu * menu,uint32 what,bool enable)593fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable)
594e6a50d9cSMichael Pfeiffer {
5956163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what);
5966163f333SKarsten Heimrich if (item && item->IsEnabled() != enable)
597e6a50d9cSMichael Pfeiffer item->SetEnabled(enable);
59894a4c1c4SAugustin Cavalier fToolBar->SetActionEnabled(what, enable);
599e6a50d9cSMichael Pfeiffer }
600e6a50d9cSMichael Pfeiffer
601efa8b4f3SAxel Dörfler
602e6a50d9cSMichael Pfeiffer void
_MarkMenuItem(BMenu * menu,uint32 what,bool marked)603fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked)
604e6a50d9cSMichael Pfeiffer {
6056163f333SKarsten Heimrich BMenuItem* item = menu->FindItem(what);
6066163f333SKarsten Heimrich if (item && item->IsMarked() != marked)
607e6a50d9cSMichael Pfeiffer item->SetMarked(marked);
60894a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(what, marked);
609e6a50d9cSMichael Pfeiffer }
610e6a50d9cSMichael Pfeiffer
611efa8b4f3SAxel Dörfler
612da87390fSMichael Pfeiffer void
_MarkSlideShowDelay(bigtime_t delay)6134aa63633SAxel Dörfler ShowImageWindow::_MarkSlideShowDelay(bigtime_t delay)
614da87390fSMichael Pfeiffer {
6154aa63633SAxel Dörfler const int32 count = fSlideShowDelayMenu->CountItems();
6164aa63633SAxel Dörfler for (int32 i = 0; i < count; i ++) {
6174aa63633SAxel Dörfler BMenuItem* item = fSlideShowDelayMenu->ItemAt(i);
6184aa63633SAxel Dörfler if (item != NULL) {
6194aa63633SAxel Dörfler bigtime_t itemDelay;
6204aa63633SAxel Dörfler if (item->Message()->FindInt64("delay", &itemDelay) == B_OK
6214aa63633SAxel Dörfler && itemDelay == delay) {
622da87390fSMichael Pfeiffer item->SetMarked(true);
623da87390fSMichael Pfeiffer return;
624da87390fSMichael Pfeiffer }
625da87390fSMichael Pfeiffer }
626da87390fSMichael Pfeiffer }
627da87390fSMichael Pfeiffer }
628e6a50d9cSMichael Pfeiffer
62919c76de4SMichael Pfeiffer
63019c76de4SMichael Pfeiffer void
Zoom(BPoint origin,float width,float height)631e2069723SAxel Dörfler ShowImageWindow::Zoom(BPoint origin, float width, float height)
63219c76de4SMichael Pfeiffer {
633e2069723SAxel Dörfler _ToggleFullScreen();
63419c76de4SMichael Pfeiffer }
63519c76de4SMichael Pfeiffer
636efa8b4f3SAxel Dörfler
637e6a50d9cSMichael Pfeiffer void
MessageReceived(BMessage * message)638efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message)
63913afa642SPhil Greenway {
640e2069723SAxel Dörfler if (message->WasDropped()) {
641e2069723SAxel Dörfler uint32 type;
642e2069723SAxel Dörfler int32 count;
643e2069723SAxel Dörfler status_t status = message->GetInfo("refs", &type, &count);
644e2069723SAxel Dörfler if (status == B_OK && type == B_REF_TYPE) {
645e2069723SAxel Dörfler message->what = B_REFS_RECEIVED;
646e2069723SAxel Dörfler be_app->PostMessage(message);
647e2069723SAxel Dörfler }
648e2069723SAxel Dörfler }
649e2069723SAxel Dörfler
650efa8b4f3SAxel Dörfler switch (message->what) {
651e2069723SAxel Dörfler case kMsgImageCacheImageLoaded:
652cd6b5cdeSAxel Dörfler {
653e2069723SAxel Dörfler fProgressWindow->Stop();
654e2069723SAxel Dörfler
655df942b3eSAxel Dörfler BitmapOwner* bitmapOwner = NULL;
656df942b3eSAxel Dörfler message->FindPointer("bitmapOwner", (void**)&bitmapOwner);
657df942b3eSAxel Dörfler
658cd6b5cdeSAxel Dörfler bool first = fImageView->Bitmap() == NULL;
659b9767a83SAxel Dörfler entry_ref ref;
660b9767a83SAxel Dörfler message->FindRef("ref", &ref);
661b9767a83SAxel Dörfler if (!first && ref != fNavigator.CurrentRef()) {
662b9767a83SAxel Dörfler // ignore older images
663df942b3eSAxel Dörfler if (bitmapOwner != NULL)
664df942b3eSAxel Dörfler bitmapOwner->ReleaseReference();
665b9767a83SAxel Dörfler break;
666b9767a83SAxel Dörfler }
667cd6b5cdeSAxel Dörfler
668baa27ccbSJanus int32 page = message->FindInt32("page");
669baa27ccbSJanus int32 pageCount = message->FindInt32("pageCount");
670baa27ccbSJanus if (!first && page != fNavigator.CurrentPage()) {
671baa27ccbSJanus // ignore older pages
672baa27ccbSJanus if (bitmapOwner != NULL)
673baa27ccbSJanus bitmapOwner->ReleaseReference();
674baa27ccbSJanus break;
675baa27ccbSJanus }
676baa27ccbSJanus
677cd6b5cdeSAxel Dörfler status_t status = fImageView->SetImage(message);
678cd6b5cdeSAxel Dörfler if (status != B_OK) {
679df942b3eSAxel Dörfler if (bitmapOwner != NULL)
680df942b3eSAxel Dörfler bitmapOwner->ReleaseReference();
681df942b3eSAxel Dörfler
682cd6b5cdeSAxel Dörfler _LoadError(ref);
683cd6b5cdeSAxel Dörfler
684cd6b5cdeSAxel Dörfler // quit if file could not be opened
685cd6b5cdeSAxel Dörfler if (first)
686cd6b5cdeSAxel Dörfler Quit();
687cd6b5cdeSAxel Dörfler break;
688cd6b5cdeSAxel Dörfler }
689cd6b5cdeSAxel Dörfler
690cd6b5cdeSAxel Dörfler fImageType = message->FindString("type");
691baa27ccbSJanus fNavigator.SetTo(ref, page, pageCount);
692cd6b5cdeSAxel Dörfler
693e2069723SAxel Dörfler fImageView->FitToBounds();
694cd6b5cdeSAxel Dörfler if (first) {
695cd6b5cdeSAxel Dörfler fImageView->MakeFocus(true);
696cd6b5cdeSAxel Dörfler // to receive key messages
697cd6b5cdeSAxel Dörfler Show();
698e2069723SAxel Dörfler }
69932ed03a5SHumdinger
70032ed03a5SHumdinger fMimeType = new BMimeType(message->FindString("mime"));
70132ed03a5SHumdinger _UpdateOpenWithMenu(fOpenWithMenu);
7025b76e505SStephan Aßmus _UpdateRatingMenu();
703e62a6973SJanus // Set width and height attributes of the currently showed file.
704e62a6973SJanus // This should only be a temporary solution.
705e62a6973SJanus _SaveWidthAndHeight();
706e2069723SAxel Dörfler break;
707e2069723SAxel Dörfler }
708e2069723SAxel Dörfler
709e2069723SAxel Dörfler case kMsgImageCacheProgressUpdate:
710e2069723SAxel Dörfler {
711e2069723SAxel Dörfler entry_ref ref;
712e2069723SAxel Dörfler if (message->FindRef("ref", &ref) == B_OK
713e2069723SAxel Dörfler && ref == fNavigator.CurrentRef()) {
714e2069723SAxel Dörfler message->what = kMsgProgressUpdate;
715e2069723SAxel Dörfler fProgressWindow->PostMessage(message);
716cd6b5cdeSAxel Dörfler }
717cd6b5cdeSAxel Dörfler break;
718cd6b5cdeSAxel Dörfler }
719cd6b5cdeSAxel Dörfler
720ee7b4f39SMatthew Wilber case MSG_MODIFIED:
721ee7b4f39SMatthew Wilber // If image has been modified due to a Cut or Paste
722ee7b4f39SMatthew Wilber fModified = true;
723ee7b4f39SMatthew Wilber break;
724ee7b4f39SMatthew Wilber
725fc0a275bSMatthew Wilber case MSG_OUTPUT_TYPE:
726fc0a275bSMatthew Wilber // User clicked Save As then choose an output format
727d3046f7dSMichael Pfeiffer if (!fSavePanel)
728cdb89ebbSMatthew Wilber // If user doesn't already have a save panel open
729fd952aefSRyan Leavengood _SaveAs(message);
73013afa642SPhil Greenway break;
731fc0a275bSMatthew Wilber
732fc0a275bSMatthew Wilber case MSG_SAVE_PANEL:
733fc0a275bSMatthew Wilber // User specified where to save the output image
734fd952aefSRyan Leavengood _SaveToFile(message);
73507caaa8eSMatthew Wilber break;
73607caaa8eSMatthew Wilber
737cdb89ebbSMatthew Wilber case B_CANCEL:
738d3046f7dSMichael Pfeiffer delete fSavePanel;
739d3046f7dSMichael Pfeiffer fSavePanel = NULL;
740cdb89ebbSMatthew Wilber break;
741cdb89ebbSMatthew Wilber
7426db01936SAxel Dörfler case MSG_UPDATE_STATUS:
7436db01936SAxel Dörfler {
744cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount();
745cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage();
7466c305411SMatthew Wilber
747baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_FIRST,
748baa27ccbSJanus fNavigator.HasPreviousPage());
749baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_LAST, fNavigator.HasNextPage());
750baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_NEXT, fNavigator.HasNextPage());
751baa27ccbSJanus _EnableMenuItem(fBar, MSG_PAGE_PREV, fNavigator.HasPreviousPage());
752baa27ccbSJanus fGoToPageMenu->SetEnabled(pages > 1);
7531d592070SMatthew Wilber
754cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile());
755cd6b5cdeSAxel Dörfler _EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile());
756134d6076SMichael Pfeiffer
757d3046f7dSMichael Pfeiffer if (fGoToPageMenu->CountItems() != pages) {
7586c305411SMatthew Wilber // Only rebuild the submenu if the number of
7596c305411SMatthew Wilber // pages is different
7606c305411SMatthew Wilber
761cd6b5cdeSAxel Dörfler while (fGoToPageMenu->CountItems() > 0) {
7626c305411SMatthew Wilber // Remove all page numbers
7637f4d1af4SSergei Reznikov delete fGoToPageMenu->RemoveItem((int32)0);
764cd6b5cdeSAxel Dörfler }
7656c305411SMatthew Wilber
766780d8a62SMichael Pfeiffer for (int32 i = 1; i <= pages; i++) {
7676c305411SMatthew Wilber // Fill Go To page submenu with an entry for each page
768cd6b5cdeSAxel Dörfler BMessage* goTo = new BMessage(MSG_GOTO_PAGE);
769cd6b5cdeSAxel Dörfler goTo->AddInt32("page", i);
7706163f333SKarsten Heimrich
7716163f333SKarsten Heimrich char shortcut = 0;
772cd6b5cdeSAxel Dörfler if (i < 10)
773780d8a62SMichael Pfeiffer shortcut = '0' + i;
7746163f333SKarsten Heimrich
7756163f333SKarsten Heimrich BString strCaption;
7766163f333SKarsten Heimrich strCaption << i;
7776163f333SKarsten Heimrich
778cd6b5cdeSAxel Dörfler BMenuItem* item = new BMenuItem(strCaption.String(), goTo,
779a8199d69Sthreedeyes shortcut, B_SHIFT_KEY);
780cd6b5cdeSAxel Dörfler if (currentPage == i)
781efa8b4f3SAxel Dörfler item->SetMarked(true);
782efa8b4f3SAxel Dörfler fGoToPageMenu->AddItem(item);
7836c305411SMatthew Wilber }
7846c305411SMatthew Wilber } else {
7856c305411SMatthew Wilber // Make sure the correct page is marked
786cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
787cd6b5cdeSAxel Dörfler if (currentItem != NULL && !currentItem->IsMarked())
788cd6b5cdeSAxel Dörfler currentItem->SetMarked(true);
7896c305411SMatthew Wilber }
7906c305411SMatthew Wilber
791cd6b5cdeSAxel Dörfler _UpdateStatusText(message);
792b9767a83SAxel Dörfler
793b9767a83SAxel Dörfler BPath path(fImageView->Image());
794b9767a83SAxel Dörfler SetTitle(path.Path());
7956db01936SAxel Dörfler break;
7966db01936SAxel Dörfler }
79703839579SMatthew Wilber
7986db01936SAxel Dörfler case MSG_UPDATE_STATUS_TEXT:
7996db01936SAxel Dörfler {
800cd6b5cdeSAxel Dörfler _UpdateStatusText(message);
8016db01936SAxel Dörfler break;
8026db01936SAxel Dörfler }
8038f5fd23fSRyan Leavengood
80432ed03a5SHumdinger case MSG_OPEN_WITH:
80532ed03a5SHumdinger {
80632ed03a5SHumdinger BString appSig = "";
80732ed03a5SHumdinger message->FindString("signature", &appSig);
80832ed03a5SHumdinger entry_ref ref = fNavigator.CurrentRef();
80932ed03a5SHumdinger BMessage openMsg(B_REFS_RECEIVED);
81032ed03a5SHumdinger openMsg.AddRef("refs", &ref);
81132ed03a5SHumdinger be_roster->Launch(appSig.String(), &openMsg);
81232ed03a5SHumdinger break;
81332ed03a5SHumdinger }
81432ed03a5SHumdinger
8156db01936SAxel Dörfler case MSG_SELECTION:
8166db01936SAxel Dörfler {
8178ad30bcfSMatthew Wilber // The view sends this message when a selection is
8188ad30bcfSMatthew Wilber // made or the selection is cleared so that the window
8198ad30bcfSMatthew Wilber // can update the state of the appropriate menu items
8206db01936SAxel Dörfler bool enable;
8216db01936SAxel Dörfler if (message->FindBool("has_selection", &enable) == B_OK) {
8226db01936SAxel Dörfler _EnableMenuItem(fBar, B_COPY, enable);
8236db01936SAxel Dörfler _EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable);
8248ad30bcfSMatthew Wilber }
8256db01936SAxel Dörfler break;
8266db01936SAxel Dörfler }
8278ad30bcfSMatthew Wilber
82813afa642SPhil Greenway case B_COPY:
829d3046f7dSMichael Pfeiffer fImageView->CopySelectionToClipboard();
83013afa642SPhil Greenway break;
8316163f333SKarsten Heimrich
8326db01936SAxel Dörfler case MSG_SELECTION_MODE:
833cf0d8308SStephan Aßmus {
834cf0d8308SStephan Aßmus bool selectionMode = _ToggleMenuItem(MSG_SELECTION_MODE);
835cf0d8308SStephan Aßmus fImageView->SetSelectionMode(selectionMode);
836cf0d8308SStephan Aßmus if (!selectionMode)
837cf0d8308SStephan Aßmus fImageView->ClearSelection();
8386db01936SAxel Dörfler break;
839cf0d8308SStephan Aßmus }
8406db01936SAxel Dörfler
84113afa642SPhil Greenway case MSG_CLEAR_SELECT:
842d3046f7dSMichael Pfeiffer fImageView->ClearSelection();
84313afa642SPhil Greenway break;
8446163f333SKarsten Heimrich
84513afa642SPhil Greenway case MSG_SELECT_ALL:
846d3046f7dSMichael Pfeiffer fImageView->SelectAll();
84713afa642SPhil Greenway break;
84813afa642SPhil Greenway
84903839579SMatthew Wilber case MSG_PAGE_FIRST:
850b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.FirstPage())
851b9767a83SAxel Dörfler _LoadImage();
85203839579SMatthew Wilber break;
85303839579SMatthew Wilber
85403839579SMatthew Wilber case MSG_PAGE_LAST:
855b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.LastPage())
856b9767a83SAxel Dörfler _LoadImage();
85703839579SMatthew Wilber break;
85803839579SMatthew Wilber
85903839579SMatthew Wilber case MSG_PAGE_NEXT:
860b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.NextPage())
861b9767a83SAxel Dörfler _LoadImage();
86203839579SMatthew Wilber break;
86303839579SMatthew Wilber
86403839579SMatthew Wilber case MSG_PAGE_PREV:
865b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousPage())
866b9767a83SAxel Dörfler _LoadImage();
86703839579SMatthew Wilber break;
86803839579SMatthew Wilber
869cd6b5cdeSAxel Dörfler case MSG_GOTO_PAGE:
870cd6b5cdeSAxel Dörfler {
871fd952aefSRyan Leavengood if (!_ClosePrompt())
872ee7b4f39SMatthew Wilber break;
873ee7b4f39SMatthew Wilber
8746163f333SKarsten Heimrich int32 newPage;
8756163f333SKarsten Heimrich if (message->FindInt32("page", &newPage) != B_OK)
8766163f333SKarsten Heimrich break;
8776163f333SKarsten Heimrich
878cd6b5cdeSAxel Dörfler int32 currentPage = fNavigator.CurrentPage();
879cd6b5cdeSAxel Dörfler int32 pages = fNavigator.PageCount();
8806c305411SMatthew Wilber
881b9767a83SAxel Dörfler // TODO: use radio mode instead!
8826c305411SMatthew Wilber if (newPage > 0 && newPage <= pages) {
883cd6b5cdeSAxel Dörfler BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
884cd6b5cdeSAxel Dörfler BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1);
885cd6b5cdeSAxel Dörfler if (currentItem != NULL && newItem != NULL) {
886cd6b5cdeSAxel Dörfler currentItem->SetMarked(false);
887cd6b5cdeSAxel Dörfler newItem->SetMarked(true);
888b9767a83SAxel Dörfler if (fNavigator.GoToPage(newPage))
889b9767a83SAxel Dörfler _LoadImage();
8906c305411SMatthew Wilber }
8916c305411SMatthew Wilber }
892cd6b5cdeSAxel Dörfler break;
893cd6b5cdeSAxel Dörfler }
8946c305411SMatthew Wilber
895e2069723SAxel Dörfler case kMsgFitToWindow:
896e2069723SAxel Dörfler fImageView->FitToBounds();
89719c76de4SMichael Pfeiffer break;
8986163f333SKarsten Heimrich
899e2069723SAxel Dörfler case kMsgStretchToWindow:
900e2069723SAxel Dörfler fImageView->SetStretchToBounds(
901e2069723SAxel Dörfler _ToggleMenuItem(kMsgStretchToWindow));
9027eca0987SMichael Pfeiffer break;
9037eca0987SMichael Pfeiffer
9047eca0987SMichael Pfeiffer case MSG_FILE_PREV:
905b9767a83SAxel Dörfler if (_ClosePrompt() && fNavigator.PreviousFile())
906a569816bSAxel Dörfler _LoadImage(false);
9077eca0987SMichael Pfeiffer break;
9087eca0987SMichael Pfeiffer
9097eca0987SMichael Pfeiffer case MSG_FILE_NEXT:
9104aa63633SAxel Dörfler case kMsgNextSlide:
91147df2afbSRyan Leavengood if (_ClosePrompt()) {
91247df2afbSRyan Leavengood if (!fNavigator.NextFile()) {
91347df2afbSRyan Leavengood // Wrap back around
91447df2afbSRyan Leavengood fNavigator.FirstFile();
91547df2afbSRyan Leavengood }
916b9767a83SAxel Dörfler _LoadImage();
91747df2afbSRyan Leavengood }
91813afa642SPhil Greenway break;
91913afa642SPhil Greenway
920328932acSAxel Dörfler case kMsgDeleteCurrentFile:
921b9767a83SAxel Dörfler {
922b9767a83SAxel Dörfler if (fNavigator.MoveFileToTrash())
923b9767a83SAxel Dörfler _LoadImage();
924b9767a83SAxel Dörfler else
925328932acSAxel Dörfler PostMessage(B_QUIT_REQUESTED);
926328932acSAxel Dörfler break;
927b9767a83SAxel Dörfler }
928328932acSAxel Dörfler
929bf461dbeSMatthew Wilber case MSG_ROTATE_90:
930d3046f7dSMichael Pfeiffer fImageView->Rotate(90);
931ad13f387SMichael Pfeiffer break;
9326163f333SKarsten Heimrich
933bf461dbeSMatthew Wilber case MSG_ROTATE_270:
934d3046f7dSMichael Pfeiffer fImageView->Rotate(270);
935ad13f387SMichael Pfeiffer break;
9366163f333SKarsten Heimrich
93769eee339SRyan Leavengood case MSG_FLIP_LEFT_TO_RIGHT:
93861ddc257SRyan Leavengood fImageView->Flip(true);
939ad13f387SMichael Pfeiffer break;
9406163f333SKarsten Heimrich
94169eee339SRyan Leavengood case MSG_FLIP_TOP_TO_BOTTOM:
94261ddc257SRyan Leavengood fImageView->Flip(false);
943ad13f387SMichael Pfeiffer break;
9446163f333SKarsten Heimrich
945fb94ed11SAvi Brenner case MSG_GET_INFO:
946fb94ed11SAvi Brenner _GetFileInfo(fNavigator.CurrentRef());
947fb94ed11SAvi Brenner break;
948fb94ed11SAvi Brenner
9491076d97bSAxel Dörfler case MSG_SLIDE_SHOW:
9501076d97bSAxel Dörfler {
95194fd9498SStephan Aßmus bool fullScreen = false;
95294fd9498SStephan Aßmus message->FindBool("full screen", &fullScreen);
953a877c0e7SStephan Aßmus
9546163f333SKarsten Heimrich BMenuItem* item = fBar->FindItem(message->what);
9554aa63633SAxel Dörfler if (item == NULL)
956ee7b4f39SMatthew Wilber break;
9574aa63633SAxel Dörfler
958ee7b4f39SMatthew Wilber if (item->IsMarked()) {
959ee7b4f39SMatthew Wilber item->SetMarked(false);
9604aa63633SAxel Dörfler _StopSlideShow();
96194a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false);
962fd952aefSRyan Leavengood } else if (_ClosePrompt()) {
963ee7b4f39SMatthew Wilber item->SetMarked(true);
96494fd9498SStephan Aßmus if (!fFullScreen && fullScreen)
96594fd9498SStephan Aßmus _ToggleFullScreen();
9664aa63633SAxel Dörfler _StartSlideShow();
96794a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, true);
968ad13f387SMichael Pfeiffer }
9691076d97bSAxel Dörfler break;
9701076d97bSAxel Dörfler }
971ee7b4f39SMatthew Wilber
9724aa63633SAxel Dörfler case kMsgStopSlideShow:
9734aa63633SAxel Dörfler {
9744aa63633SAxel Dörfler BMenuItem* item = fBar->FindItem(MSG_SLIDE_SHOW);
9754aa63633SAxel Dörfler if (item != NULL)
9764aa63633SAxel Dörfler item->SetMarked(false);
9774aa63633SAxel Dörfler
9784aa63633SAxel Dörfler _StopSlideShow();
97994a4c1c4SAugustin Cavalier fToolBar->SetActionPressed(MSG_SLIDE_SHOW, false);
9804aa63633SAxel Dörfler break;
9814aa63633SAxel Dörfler }
9824aa63633SAxel Dörfler
9831076d97bSAxel Dörfler case MSG_SLIDE_SHOW_DELAY:
9841076d97bSAxel Dörfler {
9854aa63633SAxel Dörfler bigtime_t delay;
9864aa63633SAxel Dörfler if (message->FindInt64("delay", &delay) == B_OK) {
9874aa63633SAxel Dörfler _SetSlideShowDelay(delay);
988da87390fSMichael Pfeiffer // in case message is sent from popup menu
9894aa63633SAxel Dörfler _MarkSlideShowDelay(delay);
990ad13f387SMichael Pfeiffer }
9911076d97bSAxel Dörfler break;
9921076d97bSAxel Dörfler }
993ad13f387SMichael Pfeiffer
994ad13f387SMichael Pfeiffer case MSG_FULL_SCREEN:
995fd952aefSRyan Leavengood _ToggleFullScreen();
996ad13f387SMichael Pfeiffer break;
9976163f333SKarsten Heimrich
998fc5ca95dSStephan Aßmus case MSG_EXIT_FULL_SCREEN:
999fc5ca95dSStephan Aßmus if (fFullScreen)
1000fd952aefSRyan Leavengood _ToggleFullScreen();
1001fc5ca95dSStephan Aßmus break;
10026163f333SKarsten Heimrich
1003cf0d8308SStephan Aßmus case MSG_SHOW_CAPTION:
1004cf0d8308SStephan Aßmus {
1005fd952aefSRyan Leavengood fShowCaption = _ToggleMenuItem(message->what);
1006efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings();
1007efa8b4f3SAxel Dörfler
1008d3046f7dSMichael Pfeiffer if (settings->Lock()) {
1009d3046f7dSMichael Pfeiffer settings->SetBool("ShowCaption", fShowCaption);
1010d3046f7dSMichael Pfeiffer settings->Unlock();
1011d3046f7dSMichael Pfeiffer }
1012efa8b4f3SAxel Dörfler if (fFullScreen)
1013d3046f7dSMichael Pfeiffer fImageView->SetShowCaption(fShowCaption);
10146163f333SKarsten Heimrich } break;
1015ad13f387SMichael Pfeiffer
1016780d8a62SMichael Pfeiffer case MSG_PAGE_SETUP:
1017fd952aefSRyan Leavengood _PageSetup();
1018780d8a62SMichael Pfeiffer break;
10196163f333SKarsten Heimrich
1020780d8a62SMichael Pfeiffer case MSG_PREPARE_PRINT:
1021fd952aefSRyan Leavengood _PrepareForPrint();
1022780d8a62SMichael Pfeiffer break;
10236163f333SKarsten Heimrich
1024780d8a62SMichael Pfeiffer case MSG_PRINT:
1025fd952aefSRyan Leavengood _Print(message);
1026780d8a62SMichael Pfeiffer break;
1027780d8a62SMichael Pfeiffer
1028780d8a62SMichael Pfeiffer case MSG_ZOOM_IN:
1029d3046f7dSMichael Pfeiffer fImageView->ZoomIn();
1030780d8a62SMichael Pfeiffer break;
10316163f333SKarsten Heimrich
1032780d8a62SMichael Pfeiffer case MSG_ZOOM_OUT:
1033d3046f7dSMichael Pfeiffer fImageView->ZoomOut();
1034780d8a62SMichael Pfeiffer break;
10356163f333SKarsten Heimrich
1036cae52eadSJanus case MSG_UPDATE_STATUS_ZOOM:
1037cae52eadSJanus fStatusView->SetZoom(fImageView->Zoom());
1038cae52eadSJanus break;
1039cae52eadSJanus
1040e2069723SAxel Dörfler case kMsgOriginalSize:
10418073fcbbSAdrien Destugues if (message->FindInt32("behavior") == BButton::B_TOGGLE_BEHAVIOR) {
10428073fcbbSAdrien Destugues bool force = (message->FindInt32("be:value") == B_CONTROL_ON);
1043554e2073SAdrien Destugues fImageView->ForceOriginalSize(force);
1044554e2073SAdrien Destugues if (!force)
1045554e2073SAdrien Destugues break;
1046554e2073SAdrien Destugues }
10474fd570d3SAxel Dörfler fImageView->SetZoom(1.0);
1048780d8a62SMichael Pfeiffer break;
10496163f333SKarsten Heimrich
105081b9c776SMichael Pfeiffer case MSG_SCALE_BILINEAR:
1051fd952aefSRyan Leavengood fImageView->SetScaleBilinear(_ToggleMenuItem(message->what));
105281b9c776SMichael Pfeiffer break;
1053780d8a62SMichael Pfeiffer
1054cd6b5cdeSAxel Dörfler case MSG_DESKTOP_BACKGROUND:
1055cd6b5cdeSAxel Dörfler {
10569617074cSRyan Leavengood BMessage backgroundsMessage(B_REFS_RECEIVED);
10579617074cSRyan Leavengood backgroundsMessage.AddRef("refs", fImageView->Image());
10580a74004cSRyan Leavengood // This is used in the Backgrounds code for scaled placement
10599617074cSRyan Leavengood backgroundsMessage.AddInt32("placement", 'scpl');
1060537a273cSHumdinger be_roster->Launch("application/x-vnd.haiku-backgrounds",
1061537a273cSHumdinger &backgroundsMessage);
1062cd6b5cdeSAxel Dörfler break;
1063cd6b5cdeSAxel Dörfler }
1064a60adbf9SAxel Dörfler
10655b76e505SStephan Aßmus case MSG_SET_RATING:
10665b76e505SStephan Aßmus {
10675b76e505SStephan Aßmus int32 rating;
10685b76e505SStephan Aßmus if (message->FindInt32("rating", &rating) != B_OK)
10695b76e505SStephan Aßmus break;
10705b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_WRITE_ONLY);
10715b76e505SStephan Aßmus if (file.InitCheck() != B_OK)
10725b76e505SStephan Aßmus break;
10735b76e505SStephan Aßmus file.WriteAttr("Media:Rating", B_INT32_TYPE, 0, &rating,
10745b76e505SStephan Aßmus sizeof(rating));
10755b76e505SStephan Aßmus _UpdateRatingMenu();
10765b76e505SStephan Aßmus break;
10775b76e505SStephan Aßmus }
10785b76e505SStephan Aßmus
1079cf0d8308SStephan Aßmus case kMsgToggleToolBar:
1080cf0d8308SStephan Aßmus {
1081cf0d8308SStephan Aßmus fShowToolBar = _ToggleMenuItem(message->what);
108294fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar, true);
1083cf0d8308SStephan Aßmus
1084cf0d8308SStephan Aßmus ShowImageSettings* settings = my_app->Settings();
1085cf0d8308SStephan Aßmus
1086cf0d8308SStephan Aßmus if (settings->Lock()) {
1087cf0d8308SStephan Aßmus settings->SetBool("ShowToolBar", fShowToolBar);
1088cf0d8308SStephan Aßmus settings->Unlock();
1089cf0d8308SStephan Aßmus }
1090cf0d8308SStephan Aßmus break;
1091cf0d8308SStephan Aßmus }
109294fd9498SStephan Aßmus case kShowToolBarIfEnabled:
109394fd9498SStephan Aßmus {
109494fd9498SStephan Aßmus bool show;
109594fd9498SStephan Aßmus if (message->FindBool("show", &show) != B_OK)
109694fd9498SStephan Aßmus break;
109794fd9498SStephan Aßmus _SetToolBarVisible(fShowToolBar && show, true);
109894fd9498SStephan Aßmus break;
109994fd9498SStephan Aßmus }
110094fd9498SStephan Aßmus case kMsgSlideToolBar:
110194fd9498SStephan Aßmus {
110294fd9498SStephan Aßmus float offset;
110394fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK) {
110494a4c1c4SAugustin Cavalier fToolBar->MoveBy(0, offset);
110520e18366SAugustin Cavalier fScrollArea->ResizeBy(0, -offset);
110620e18366SAugustin Cavalier fScrollArea->MoveBy(0, offset);
110794fd9498SStephan Aßmus UpdateIfNeeded();
110894fd9498SStephan Aßmus snooze(15000);
110994fd9498SStephan Aßmus }
111094fd9498SStephan Aßmus break;
111194fd9498SStephan Aßmus }
111294fd9498SStephan Aßmus case kMsgFinishSlidingToolBar:
111394fd9498SStephan Aßmus {
111494fd9498SStephan Aßmus float offset;
111594fd9498SStephan Aßmus bool show;
111694fd9498SStephan Aßmus if (message->FindFloat("offset", &offset) == B_OK
111794fd9498SStephan Aßmus && message->FindBool("show", &show) == B_OK) {
111894fd9498SStephan Aßmus // Compensate rounding errors with the final placement
111994a4c1c4SAugustin Cavalier fToolBar->MoveTo(fToolBar->Frame().left, offset);
112095667008SJanus if (!show)
112194a4c1c4SAugustin Cavalier fToolBar->Hide();
112294a4c1c4SAugustin Cavalier BRect frame = fToolBar->Parent()->Bounds();
112394a4c1c4SAugustin Cavalier frame.top = fToolBar->Frame().bottom + 1;
112420e18366SAugustin Cavalier fScrollArea->MoveTo(fScrollArea->Frame().left, frame.top);
112520e18366SAugustin Cavalier fScrollArea->ResizeTo(fScrollArea->Bounds().Width(),
1126cae52eadSJanus frame.Height() + 1);
112794fd9498SStephan Aßmus }
112894fd9498SStephan Aßmus break;
112994fd9498SStephan Aßmus }
1130cf0d8308SStephan Aßmus
113113afa642SPhil Greenway default:
1132efa8b4f3SAxel Dörfler BWindow::MessageReceived(message);
113313afa642SPhil Greenway break;
113413afa642SPhil Greenway }
113513afa642SPhil Greenway }
1136fc0a275bSMatthew Wilber
1137efa8b4f3SAxel Dörfler
1138fc0a275bSMatthew Wilber void
_GetFileInfo(const entry_ref & ref)1139fb94ed11SAvi Brenner ShowImageWindow::_GetFileInfo(const entry_ref& ref)
1140fb94ed11SAvi Brenner {
1141fb94ed11SAvi Brenner BMessage message('Tinf');
1142fb94ed11SAvi Brenner BMessenger tracker("application/x-vnd.Be-TRAK");
1143fb94ed11SAvi Brenner message.AddRef("refs", &ref);
1144fb94ed11SAvi Brenner tracker.SendMessage(&message);
1145fb94ed11SAvi Brenner }
1146fb94ed11SAvi Brenner
1147fb94ed11SAvi Brenner
1148fb94ed11SAvi Brenner void
_UpdateStatusText(const BMessage * message)1149cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message)
1150cd6b5cdeSAxel Dörfler {
1151dae087edSEmir SARI BString frameText, height, width;
1152cd6b5cdeSAxel Dörfler if (fImageView->Bitmap() != NULL) {
1153cd6b5cdeSAxel Dörfler BRect bounds = fImageView->Bitmap()->Bounds();
1154dae087edSEmir SARI fNumberFormat.Format(width, bounds.IntegerWidth() + 1);
1155dae087edSEmir SARI fNumberFormat.Format(height, bounds.IntegerHeight() + 1);
1156dae087edSEmir SARI frameText.SetToFormat("%s × %s", width.String(), height.String());
1157cd6b5cdeSAxel Dörfler }
1158dae087edSEmir SARI
1159dae087edSEmir SARI BString currentPage, pageCount, pages;
1160dae087edSEmir SARI if (fNavigator.PageCount() > 1) {
1161dae087edSEmir SARI fNumberFormat.Format(currentPage, fNavigator.CurrentPage());
1162dae087edSEmir SARI fNumberFormat.Format(pageCount, fNavigator.PageCount());
1163dae087edSEmir SARI pages.SetToFormat("%s / %s", currentPage.String(), pageCount.String());
1164dae087edSEmir SARI }
1165dae087edSEmir SARI
1166baa27ccbSJanus fStatusView->Update(fNavigator.CurrentRef(), frameText, pages, fImageType,
1167cae52eadSJanus fImageView->Zoom());
1168cd6b5cdeSAxel Dörfler }
1169cd6b5cdeSAxel Dörfler
1170cd6b5cdeSAxel Dörfler
1171cd6b5cdeSAxel Dörfler void
_LoadError(const entry_ref & ref)1172cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref)
1173cd6b5cdeSAxel Dörfler {
1174cd6b5cdeSAxel Dörfler // TODO: give a better error message!
1175560ff447SJonas Sundström BAlert* alert = new BAlert(B_TRANSLATE_SYSTEM_NAME("ShowImage"),
1176546208a5SOliver Tappe B_TRANSLATE_CONTEXT("Could not load image! Either the "
1177ddcb5a2cSAxel Dörfler "file or an image translator for it does not exist.",
1178ddcb5a2cSAxel Dörfler "LoadAlerts"),
1179546208a5SOliver Tappe B_TRANSLATE_CONTEXT("OK", "Alerts"), NULL, NULL,
11805df9097aSJohn Scipione B_WIDTH_AS_USUAL, B_STOP_ALERT);
1181aed35104SHumdinger alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
1182cd6b5cdeSAxel Dörfler alert->Go();
1183cd6b5cdeSAxel Dörfler }
1184cd6b5cdeSAxel Dörfler
1185cd6b5cdeSAxel Dörfler
1186cd6b5cdeSAxel Dörfler void
_SaveAs(BMessage * message)1187fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message)
1188fc0a275bSMatthew Wilber {
1189cdb89ebbSMatthew Wilber // Read the translator and output type the user chose
1190345265c3SHumdinger int32 outTranslator;
1191cdb89ebbSMatthew Wilber uint32 outType;
1192345265c3SHumdinger if (message->FindInt32(kTranslatorField, &outTranslator) != B_OK
11936163f333SKarsten Heimrich || message->FindInt32(kTypeField,
1194cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK)
1195fc0a275bSMatthew Wilber return;
1196fc0a275bSMatthew Wilber
1197cdb89ebbSMatthew Wilber // Add the chosen translator and output type to the
1198cdb89ebbSMatthew Wilber // message that the save panel will send back
1199c1a10c14SKarsten Heimrich BMessage panelMsg(MSG_SAVE_PANEL);
1200c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTranslatorField, outTranslator);
1201c1a10c14SKarsten Heimrich panelMsg.AddInt32(kTypeField, outType);
1202cdb89ebbSMatthew Wilber
1203cdb89ebbSMatthew Wilber // Create save panel and show it
12046163f333SKarsten Heimrich BMessenger target(this);
1205efa8b4f3SAxel Dörfler fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
1206c1a10c14SKarsten Heimrich &target, NULL, 0, false, &panelMsg);
1207345265c3SHumdinger
1208d3046f7dSMichael Pfeiffer if (!fSavePanel)
1209fc0a275bSMatthew Wilber return;
1210a60adbf9SAxel Dörfler
12113000afd7SJanus // Retrieve save directory from settings;
12123000afd7SJanus ShowImageSettings* settings = my_app->Settings();
12133000afd7SJanus if (settings->Lock()) {
12143000afd7SJanus fSavePanel->SetPanelDirectory(
12153000afd7SJanus settings->GetString("SaveDirectory", NULL));
12163000afd7SJanus settings->Unlock();
12173000afd7SJanus }
12183000afd7SJanus
1219345265c3SHumdinger // Prefill current image's file name in save dialog
1220345265c3SHumdinger BEntry entry = fImageView->Image();
1221345265c3SHumdinger BPath path(&entry);
1222345265c3SHumdinger const char* filename = path.Leaf();
1223345265c3SHumdinger fSavePanel->SetSaveText(filename);
1224345265c3SHumdinger
1225d3046f7dSMichael Pfeiffer fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
1226d3046f7dSMichael Pfeiffer fSavePanel->Show();
1227fc0a275bSMatthew Wilber }
1228fc0a275bSMatthew Wilber
1229efa8b4f3SAxel Dörfler
1230fc0a275bSMatthew Wilber void
_SaveToFile(BMessage * message)1231fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message)
1232fc0a275bSMatthew Wilber {
1233cdb89ebbSMatthew Wilber // Read in where the file should be saved
1234efa8b4f3SAxel Dörfler entry_ref dirRef;
1235efa8b4f3SAxel Dörfler if (message->FindRef("directory", &dirRef) != B_OK)
1236fc0a275bSMatthew Wilber return;
1237efa8b4f3SAxel Dörfler
1238fc0a275bSMatthew Wilber const char* filename;
1239efa8b4f3SAxel Dörfler if (message->FindString("name", &filename) != B_OK)
1240fc0a275bSMatthew Wilber return;
1241fc0a275bSMatthew Wilber
1242cdb89ebbSMatthew Wilber // Read in the translator and type to be used
1243cdb89ebbSMatthew Wilber // to save the output image
1244345265c3SHumdinger int32 outTranslator;
1245cdb89ebbSMatthew Wilber uint32 outType;
1246345265c3SHumdinger if (message->FindInt32(kTranslatorField, &outTranslator) != B_OK
12476163f333SKarsten Heimrich || message->FindInt32(kTypeField,
1248cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK)
1249cdb89ebbSMatthew Wilber return;
1250cdb89ebbSMatthew Wilber
1251a7e78e3bSMatthew Wilber // Find the translator_format information needed to
1252a7e78e3bSMatthew Wilber // write a MIME attribute for the image file
1253a7e78e3bSMatthew Wilber BTranslatorRoster* roster = BTranslatorRoster::Default();
1254efa8b4f3SAxel Dörfler const translation_format* outFormat = NULL;
1255efa8b4f3SAxel Dörfler int32 outCount = 0;
1256efa8b4f3SAxel Dörfler if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
1257efa8b4f3SAxel Dörfler || outCount < 1)
1258a7e78e3bSMatthew Wilber return;
1259efa8b4f3SAxel Dörfler
1260a7e78e3bSMatthew Wilber int32 i;
1261efa8b4f3SAxel Dörfler for (i = 0; i < outCount; i++) {
1262537a273cSHumdinger if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type
1263537a273cSHumdinger == outType)
1264a7e78e3bSMatthew Wilber break;
1265a7e78e3bSMatthew Wilber }
1266efa8b4f3SAxel Dörfler if (i == outCount)
1267fc0a275bSMatthew Wilber return;
1268fc0a275bSMatthew Wilber
1269a7e78e3bSMatthew Wilber // Write out the image file
1270efa8b4f3SAxel Dörfler BDirectory dir(&dirRef);
1271efa8b4f3SAxel Dörfler fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
12723000afd7SJanus
12733000afd7SJanus // Store Save directory in settings;
12743000afd7SJanus ShowImageSettings* settings = my_app->Settings();
12753000afd7SJanus if (settings->Lock()) {
12763000afd7SJanus BPath path(&dirRef);
12773000afd7SJanus settings->SetString("SaveDirectory", path.Path());
12783000afd7SJanus settings->Unlock();
12793000afd7SJanus }
1280fc0a275bSMatthew Wilber }
1281fc0a275bSMatthew Wilber
1282efa8b4f3SAxel Dörfler
1283546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
1284546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "ClosePrompt"
12851ed4535fSStephan Aßmus
1286b9767a83SAxel Dörfler
1287cdb89ebbSMatthew Wilber bool
_ClosePrompt()1288fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt()
1289ee7b4f39SMatthew Wilber {
1290ee7b4f39SMatthew Wilber if (!fModified)
1291ee7b4f39SMatthew Wilber return true;
1292efa8b4f3SAxel Dörfler
1293cd6b5cdeSAxel Dörfler int32 count = fNavigator.PageCount();
1294cd6b5cdeSAxel Dörfler int32 page = fNavigator.CurrentPage();
1295cd6b5cdeSAxel Dörfler BString prompt;
1296efa8b4f3SAxel Dörfler
12971ed4535fSStephan Aßmus if (count > 1) {
12981ed4535fSStephan Aßmus bs_printf(&prompt,
1299905c8c8cSMatt Madia B_TRANSLATE("The document '%s' (page %d) has been changed. Do you "
1300905c8c8cSMatt Madia "want to close the document?"),
1301cd6b5cdeSAxel Dörfler fImageView->Image()->name, page);
13021ed4535fSStephan Aßmus } else {
13031ed4535fSStephan Aßmus bs_printf(&prompt,
1304905c8c8cSMatt Madia B_TRANSLATE("The document '%s' has been changed. Do you want to "
1305905c8c8cSMatt Madia "close the document?"),
1306cd6b5cdeSAxel Dörfler fImageView->Image()->name);
13071ed4535fSStephan Aßmus }
13081ed4535fSStephan Aßmus
1309cd6b5cdeSAxel Dörfler BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(),
1310905c8c8cSMatt Madia B_TRANSLATE("Cancel"), B_TRANSLATE("Close"));
1311aed35104SHumdinger alert->SetShortcut(0, B_ESCAPE);
1312aed35104SHumdinger
1313cd6b5cdeSAxel Dörfler if (alert->Go() == 0) {
1314ee7b4f39SMatthew Wilber // Cancel
1315ee7b4f39SMatthew Wilber return false;
1316cd6b5cdeSAxel Dörfler }
1317cd6b5cdeSAxel Dörfler
1318ee7b4f39SMatthew Wilber // Close
1319187f0b8aSMatthew Wilber fModified = false;
1320ee7b4f39SMatthew Wilber return true;
1321ee7b4f39SMatthew Wilber }
1322ee7b4f39SMatthew Wilber
1323cdb89ebbSMatthew Wilber
1324b9767a83SAxel Dörfler status_t
_LoadImage(bool forward)1325a569816bSAxel Dörfler ShowImageWindow::_LoadImage(bool forward)
1326b9767a83SAxel Dörfler {
1327a4462d20SHumdinger // If the user triggered a _LoadImage while in a slide show,
1328a4462d20SHumdinger // make sure the new image is shown for the set delay:
1329a4462d20SHumdinger _ResetSlideShowDelay();
1330a4462d20SHumdinger
1331b9767a83SAxel Dörfler BMessenger us(this);
1332be63ec85SJanus status_t status = my_app->DefaultCache().RetrieveImage(
1333a569816bSAxel Dörfler fNavigator.CurrentRef(), fNavigator.CurrentPage(), &us);
1334a569816bSAxel Dörfler if (status != B_OK)
1335a569816bSAxel Dörfler return status;
1336a569816bSAxel Dörfler
1337e2069723SAxel Dörfler fProgressWindow->Start(this);
1338e2069723SAxel Dörfler
1339a569816bSAxel Dörfler // Preload previous/next images - two in the navigation direction, one
1340a569816bSAxel Dörfler // in the opposite direction.
1341a569816bSAxel Dörfler
1342a569816bSAxel Dörfler entry_ref nextRef = fNavigator.CurrentRef();
1343a569816bSAxel Dörfler if (_PreloadImage(forward, nextRef))
1344a569816bSAxel Dörfler _PreloadImage(forward, nextRef);
1345a569816bSAxel Dörfler
1346a569816bSAxel Dörfler entry_ref previousRef = fNavigator.CurrentRef();
1347a569816bSAxel Dörfler _PreloadImage(!forward, previousRef);
1348a569816bSAxel Dörfler
1349a569816bSAxel Dörfler return B_OK;
1350a569816bSAxel Dörfler }
1351a569816bSAxel Dörfler
1352a569816bSAxel Dörfler
1353a569816bSAxel Dörfler bool
_PreloadImage(bool forward,entry_ref & ref)1354a569816bSAxel Dörfler ShowImageWindow::_PreloadImage(bool forward, entry_ref& ref)
1355a569816bSAxel Dörfler {
1356a569816bSAxel Dörfler entry_ref currentRef = ref;
1357a569816bSAxel Dörfler if ((forward && !fNavigator.GetNextFile(currentRef, ref))
1358a569816bSAxel Dörfler || (!forward && !fNavigator.GetPreviousFile(currentRef, ref)))
1359a569816bSAxel Dörfler return false;
1360a569816bSAxel Dörfler
1361be63ec85SJanus return my_app->DefaultCache().RetrieveImage(ref) == B_OK;
1362b9767a83SAxel Dörfler }
1363b9767a83SAxel Dörfler
1364b9767a83SAxel Dörfler
1365ad13f387SMichael Pfeiffer void
_ToggleFullScreen()1366fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen()
1367ad13f387SMichael Pfeiffer {
1368ad13f387SMichael Pfeiffer BRect frame;
1369ad13f387SMichael Pfeiffer fFullScreen = !fFullScreen;
1370ad13f387SMichael Pfeiffer if (fFullScreen) {
1371ad13f387SMichael Pfeiffer BScreen screen;
1372ad13f387SMichael Pfeiffer fWindowFrame = Frame();
1373ad13f387SMichael Pfeiffer frame = screen.Frame();
1374d3046f7dSMichael Pfeiffer frame.top -= fBar->Bounds().Height() + 1;
1375893d5930SAdrien Destugues frame.right += be_control_look->GetScrollBarWidth(B_VERTICAL);
1376893d5930SAdrien Destugues frame.bottom += be_control_look->GetScrollBarWidth(B_HORIZONTAL);
1377ad13f387SMichael Pfeiffer
1378ad13f387SMichael Pfeiffer SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
1379c0b16687SAxel Dörfler
1380c0b16687SAxel Dörfler Activate();
1381c0b16687SAxel Dörfler // make the window frontmost
1382ad13f387SMichael Pfeiffer } else {
1383ad13f387SMichael Pfeiffer frame = fWindowFrame;
1384ad13f387SMichael Pfeiffer
1385ad13f387SMichael Pfeiffer SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
1386ad13f387SMichael Pfeiffer }
1387efa8b4f3SAxel Dörfler
138894a4c1c4SAugustin Cavalier fToolBar->SetActionVisible(MSG_FULL_SCREEN, fFullScreen);
1389cf0d8308SStephan Aßmus _SetToolBarVisible(!fFullScreen && fShowToolBar);
139060c23976SJanus _SetToolBarBorder(!fFullScreen);
1391cf0d8308SStephan Aßmus
1392ad13f387SMichael Pfeiffer MoveTo(frame.left, frame.top);
1393ad13f387SMichael Pfeiffer ResizeTo(frame.Width(), frame.Height());
1394e2069723SAxel Dörfler
1395e2069723SAxel Dörfler fImageView->SetHideIdlingCursor(fFullScreen);
1396e2069723SAxel Dörfler fImageView->SetShowCaption(fFullScreen && fShowCaption);
1397eaa910c5SAxel Dörfler
139848ae3e38SAxel Dörfler Layout(false);
139948ae3e38SAxel Dörfler // We need to manually relayout here, as the views are layouted
140048ae3e38SAxel Dörfler // asynchronously, and FitToBounds() would still have the wrong size
1401e2069723SAxel Dörfler fImageView->FitToBounds();
1402ad13f387SMichael Pfeiffer }
1403ad13f387SMichael Pfeiffer
1404efa8b4f3SAxel Dörfler
1405d3046f7dSMichael Pfeiffer void
_ApplySettings()14062281340dSAxel Dörfler ShowImageWindow::_ApplySettings()
1407d3046f7dSMichael Pfeiffer {
1408efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings();
1409efa8b4f3SAxel Dörfler
1410d3046f7dSMichael Pfeiffer if (settings->Lock()) {
1411d3046f7dSMichael Pfeiffer fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
1412d3046f7dSMichael Pfeiffer fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
1413d3046f7dSMichael Pfeiffer
14144aa63633SAxel Dörfler fSlideShowDelay = settings->GetTime("SlideShowDelay", fSlideShowDelay);
1415d3046f7dSMichael Pfeiffer
14164aa63633SAxel Dörfler fPrintOptions.SetOption((enum PrintOptions::Option)settings->GetInt32(
14174aa63633SAxel Dörfler "PO:Option", fPrintOptions.Option()));
14184aa63633SAxel Dörfler fPrintOptions.SetZoomFactor(
14194aa63633SAxel Dörfler settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor()));
14204aa63633SAxel Dörfler fPrintOptions.SetDPI(settings->GetFloat("PO:DPI", fPrintOptions.DPI()));
14214aa63633SAxel Dörfler fPrintOptions.SetWidth(
14224aa63633SAxel Dörfler settings->GetFloat("PO:Width", fPrintOptions.Width()));
14234aa63633SAxel Dörfler fPrintOptions.SetHeight(
14244aa63633SAxel Dörfler settings->GetFloat("PO:Height", fPrintOptions.Height()));
1425d3046f7dSMichael Pfeiffer
1426cf0d8308SStephan Aßmus fShowToolBar = settings->GetBool("ShowToolBar", fShowToolBar);
1427cf0d8308SStephan Aßmus
1428d3046f7dSMichael Pfeiffer settings->Unlock();
1429d3046f7dSMichael Pfeiffer }
1430d3046f7dSMichael Pfeiffer }
1431d3046f7dSMichael Pfeiffer
1432efa8b4f3SAxel Dörfler
1433d3046f7dSMichael Pfeiffer void
_SavePrintOptions()1434fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions()
1435d3046f7dSMichael Pfeiffer {
1436efa8b4f3SAxel Dörfler ShowImageSettings* settings = my_app->Settings();
1437efa8b4f3SAxel Dörfler
1438d3046f7dSMichael Pfeiffer if (settings->Lock()) {
1439d3046f7dSMichael Pfeiffer settings->SetInt32("PO:Option", fPrintOptions.Option());
1440d3046f7dSMichael Pfeiffer settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1441d3046f7dSMichael Pfeiffer settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1442d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Width", fPrintOptions.Width());
1443d3046f7dSMichael Pfeiffer settings->SetFloat("PO:Height", fPrintOptions.Height());
1444d3046f7dSMichael Pfeiffer settings->Unlock();
1445d3046f7dSMichael Pfeiffer }
1446d3046f7dSMichael Pfeiffer }
1447d3046f7dSMichael Pfeiffer
1448efa8b4f3SAxel Dörfler
1449cdb89ebbSMatthew Wilber bool
_PageSetup()1450fd952aefSRyan Leavengood ShowImageWindow::_PageSetup()
1451780d8a62SMichael Pfeiffer {
1452cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name);
1453efa8b4f3SAxel Dörfler if (fPrintSettings != NULL)
1454780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings));
1455efa8b4f3SAxel Dörfler
14566163f333SKarsten Heimrich status_t status = printJob.ConfigPage();
14576163f333SKarsten Heimrich if (status == B_OK) {
1458780d8a62SMichael Pfeiffer delete fPrintSettings;
1459780d8a62SMichael Pfeiffer fPrintSettings = printJob.Settings();
1460780d8a62SMichael Pfeiffer }
1461efa8b4f3SAxel Dörfler
14626163f333SKarsten Heimrich return status == B_OK;
1463780d8a62SMichael Pfeiffer }
1464780d8a62SMichael Pfeiffer
1465efa8b4f3SAxel Dörfler
1466780d8a62SMichael Pfeiffer void
_PrepareForPrint()1467fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint()
1468780d8a62SMichael Pfeiffer {
14696163f333SKarsten Heimrich if (fPrintSettings == NULL) {
1470cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name);
14716163f333SKarsten Heimrich if (printJob.ConfigJob() == B_OK)
14726163f333SKarsten Heimrich fPrintSettings = printJob.Settings();
14736163f333SKarsten Heimrich }
1474780d8a62SMichael Pfeiffer
1475cd6b5cdeSAxel Dörfler fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds());
1476cd6b5cdeSAxel Dörfler fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1);
1477780d8a62SMichael Pfeiffer
1478efa8b4f3SAxel Dörfler new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50),
1479efa8b4f3SAxel Dörfler &fPrintOptions, this);
1480780d8a62SMichael Pfeiffer }
1481780d8a62SMichael Pfeiffer
1482efa8b4f3SAxel Dörfler
1483780d8a62SMichael Pfeiffer void
_Print(BMessage * msg)1484fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg)
1485780d8a62SMichael Pfeiffer {
1486780d8a62SMichael Pfeiffer status_t st;
1487efa8b4f3SAxel Dörfler if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1488780d8a62SMichael Pfeiffer return;
1489780d8a62SMichael Pfeiffer
1490fd952aefSRyan Leavengood _SavePrintOptions();
1491d3046f7dSMichael Pfeiffer
1492cd6b5cdeSAxel Dörfler BPrintJob printJob(fImageView->Image()->name);
14936163f333SKarsten Heimrich if (fPrintSettings)
1494780d8a62SMichael Pfeiffer printJob.SetSettings(new BMessage(*fPrintSettings));
14956163f333SKarsten Heimrich
1496780d8a62SMichael Pfeiffer if (printJob.ConfigJob() == B_OK) {
14976163f333SKarsten Heimrich delete fPrintSettings;
14986163f333SKarsten Heimrich fPrintSettings = printJob.Settings();
1499780d8a62SMichael Pfeiffer
1500780d8a62SMichael Pfeiffer // first/lastPage is unused for now
15013177ae77SStefano Ceccherini int32 firstPage = printJob.FirstPage();
15023177ae77SStefano Ceccherini int32 lastPage = printJob.LastPage();
15036163f333SKarsten Heimrich BRect printableRect = printJob.PrintableRect();
15046163f333SKarsten Heimrich
1505efa8b4f3SAxel Dörfler if (firstPage < 1)
1506780d8a62SMichael Pfeiffer firstPage = 1;
1507efa8b4f3SAxel Dörfler if (lastPage < firstPage)
1508780d8a62SMichael Pfeiffer lastPage = firstPage;
1509780d8a62SMichael Pfeiffer
1510cd6b5cdeSAxel Dörfler BBitmap* bitmap = fImageView->Bitmap();
15113177ae77SStefano Ceccherini float imageWidth = bitmap->Bounds().Width() + 1.0;
15123177ae77SStefano Ceccherini float imageHeight = bitmap->Bounds().Height() + 1.0;
1513780d8a62SMichael Pfeiffer
15146163f333SKarsten Heimrich float width;
1515780d8a62SMichael Pfeiffer switch (fPrintOptions.Option()) {
15166163f333SKarsten Heimrich case PrintOptions::kFitToPage: {
15176163f333SKarsten Heimrich float w1 = printableRect.Width() + 1;
1518cd6b5cdeSAxel Dörfler float w2 = imageWidth * (printableRect.Height() + 1)
1519cd6b5cdeSAxel Dörfler / imageHeight;
1520efa8b4f3SAxel Dörfler if (w2 < w1)
1521780d8a62SMichael Pfeiffer width = w2;
1522efa8b4f3SAxel Dörfler else
1523780d8a62SMichael Pfeiffer width = w1;
15246163f333SKarsten Heimrich } break;
1525780d8a62SMichael Pfeiffer case PrintOptions::kZoomFactor:
1526780d8a62SMichael Pfeiffer width = imageWidth * fPrintOptions.ZoomFactor();
1527780d8a62SMichael Pfeiffer break;
1528780d8a62SMichael Pfeiffer case PrintOptions::kDPI:
1529780d8a62SMichael Pfeiffer width = imageWidth * 72.0 / fPrintOptions.DPI();
1530780d8a62SMichael Pfeiffer break;
1531780d8a62SMichael Pfeiffer case PrintOptions::kWidth:
1532780d8a62SMichael Pfeiffer case PrintOptions::kHeight:
1533780d8a62SMichael Pfeiffer width = fPrintOptions.Width();
1534780d8a62SMichael Pfeiffer break;
1535efa8b4f3SAxel Dörfler
1536780d8a62SMichael Pfeiffer default:
1537780d8a62SMichael Pfeiffer // keep compiler silent; should not reach here
1538780d8a62SMichael Pfeiffer width = imageWidth;
1539780d8a62SMichael Pfeiffer }
1540780d8a62SMichael Pfeiffer
1541efa8b4f3SAxel Dörfler // TODO: eventually print large images on several pages
1542780d8a62SMichael Pfeiffer printJob.BeginJob();
1543d3046f7dSMichael Pfeiffer fImageView->SetScale(width / imageWidth);
15445eb50e46SMichael Pfeiffer // coordinates are relative to printable rectangle
15455eb50e46SMichael Pfeiffer BRect bounds(bitmap->Bounds());
15465eb50e46SMichael Pfeiffer printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1547d3046f7dSMichael Pfeiffer fImageView->SetScale(1.0);
1548780d8a62SMichael Pfeiffer printJob.SpoolPage();
1549780d8a62SMichael Pfeiffer printJob.CommitJob();
1550780d8a62SMichael Pfeiffer }
1551780d8a62SMichael Pfeiffer }
1552780d8a62SMichael Pfeiffer
155356b0c7b9SKarsten Heimrich
15544aa63633SAxel Dörfler void
_SetSlideShowDelay(bigtime_t delay)15554aa63633SAxel Dörfler ShowImageWindow::_SetSlideShowDelay(bigtime_t delay)
15564aa63633SAxel Dörfler {
15574aa63633SAxel Dörfler if (fSlideShowDelay == delay)
15584aa63633SAxel Dörfler return;
15594aa63633SAxel Dörfler
15604aa63633SAxel Dörfler fSlideShowDelay = delay;
15614aa63633SAxel Dörfler
15624aa63633SAxel Dörfler ShowImageSettings* settings = my_app->Settings();
15634aa63633SAxel Dörfler if (settings->Lock()) {
15644aa63633SAxel Dörfler settings->SetTime("SlideShowDelay", fSlideShowDelay);
15654aa63633SAxel Dörfler settings->Unlock();
15664aa63633SAxel Dörfler }
15674aa63633SAxel Dörfler
15684aa63633SAxel Dörfler if (fSlideShowRunner != NULL)
15694aa63633SAxel Dörfler _StartSlideShow();
15704aa63633SAxel Dörfler }
15714aa63633SAxel Dörfler
15724aa63633SAxel Dörfler
15734aa63633SAxel Dörfler void
_StartSlideShow()15744aa63633SAxel Dörfler ShowImageWindow::_StartSlideShow()
15754aa63633SAxel Dörfler {
15764aa63633SAxel Dörfler _StopSlideShow();
15774aa63633SAxel Dörfler
15784aa63633SAxel Dörfler BMessage nextSlide(kMsgNextSlide);
15794aa63633SAxel Dörfler fSlideShowRunner = new BMessageRunner(this, &nextSlide, fSlideShowDelay);
15804aa63633SAxel Dörfler }
15814aa63633SAxel Dörfler
15824aa63633SAxel Dörfler
15834aa63633SAxel Dörfler void
_StopSlideShow()15844aa63633SAxel Dörfler ShowImageWindow::_StopSlideShow()
15854aa63633SAxel Dörfler {
15864aa63633SAxel Dörfler if (fSlideShowRunner != NULL) {
15874aa63633SAxel Dörfler delete fSlideShowRunner;
15884aa63633SAxel Dörfler fSlideShowRunner = NULL;
15894aa63633SAxel Dörfler }
15904aa63633SAxel Dörfler }
15914aa63633SAxel Dörfler
15924aa63633SAxel Dörfler
15935b76e505SStephan Aßmus void
_ResetSlideShowDelay()1594a4462d20SHumdinger ShowImageWindow::_ResetSlideShowDelay()
1595a4462d20SHumdinger {
1596a4462d20SHumdinger if (fSlideShowRunner != NULL)
1597a4462d20SHumdinger fSlideShowRunner->SetInterval(fSlideShowDelay);
1598a4462d20SHumdinger }
1599a4462d20SHumdinger
1600a4462d20SHumdinger
1601a4462d20SHumdinger void
_UpdateRatingMenu()16025b76e505SStephan Aßmus ShowImageWindow::_UpdateRatingMenu()
16035b76e505SStephan Aßmus {
16045b76e505SStephan Aßmus BFile file(&fNavigator.CurrentRef(), B_READ_ONLY);
16055b76e505SStephan Aßmus if (file.InitCheck() != B_OK)
16065b76e505SStephan Aßmus return;
16075b76e505SStephan Aßmus int32 rating;
16085b76e505SStephan Aßmus ssize_t size = sizeof(rating);
16095b76e505SStephan Aßmus if (file.ReadAttr("Media:Rating", B_INT32_TYPE, 0, &rating, size) != size)
16105b76e505SStephan Aßmus rating = 0;
16115b76e505SStephan Aßmus // TODO: Finding the correct item could be more robust, like by looking
16125b76e505SStephan Aßmus // at the message of each item.
16135b76e505SStephan Aßmus for (int32 i = 1; i <= 10; i++) {
16145b76e505SStephan Aßmus BMenuItem* item = fRatingMenu->ItemAt(i - 1);
16155b76e505SStephan Aßmus if (item == NULL)
16165b76e505SStephan Aßmus break;
16175b76e505SStephan Aßmus item->SetMarked(i == rating);
16185b76e505SStephan Aßmus }
161915305513SHumdinger fResetRatingItem->SetEnabled(rating > 0);
16205b76e505SStephan Aßmus }
16215b76e505SStephan Aßmus
16225b76e505SStephan Aßmus
1623cf0d8308SStephan Aßmus void
_SaveWidthAndHeight()1624e62a6973SJanus ShowImageWindow::_SaveWidthAndHeight()
1625e62a6973SJanus {
1626e62a6973SJanus if (fNavigator.CurrentPage() != 1)
1627e62a6973SJanus return;
1628e62a6973SJanus
1629e62a6973SJanus if (fImageView->Bitmap() == NULL)
1630e62a6973SJanus return;
1631e62a6973SJanus
1632e62a6973SJanus BRect bounds = fImageView->Bitmap()->Bounds();
1633c1994be8SJanus int32 width = bounds.IntegerWidth() + 1;
1634c1994be8SJanus int32 height = bounds.IntegerHeight() + 1;
1635e62a6973SJanus
16369c1f5f4dSJanus BNode node(&fNavigator.CurrentRef());
16379c1f5f4dSJanus if (node.InitCheck() != B_OK)
1638e62a6973SJanus return;
1639e62a6973SJanus
16409c1f5f4dSJanus const char* kWidthAttrName = "Media:Width";
16419c1f5f4dSJanus const char* kHeightAttrName = "Media:Height";
16429c1f5f4dSJanus
16439c1f5f4dSJanus int32 widthAttr;
1644b41cdcb3SJanus ssize_t attrSize = node.ReadAttr(kWidthAttrName, B_INT32_TYPE, 0,
1645b41cdcb3SJanus &widthAttr, sizeof(widthAttr));
16469c1f5f4dSJanus if (attrSize <= 0 || widthAttr != width)
16479c1f5f4dSJanus node.WriteAttr(kWidthAttrName, B_INT32_TYPE, 0, &width, sizeof(width));
16489c1f5f4dSJanus
16499c1f5f4dSJanus int32 heightAttr;
1650b41cdcb3SJanus attrSize = node.ReadAttr(kHeightAttrName, B_INT32_TYPE, 0,
1651b41cdcb3SJanus &heightAttr, sizeof(heightAttr));
16529c1f5f4dSJanus if (attrSize <= 0 || heightAttr != height)
16539c1f5f4dSJanus node.WriteAttr(kHeightAttrName, B_INT32_TYPE, 0, &height, sizeof(height));
1654e62a6973SJanus }
1655e62a6973SJanus
1656e62a6973SJanus
1657e62a6973SJanus void
_SetToolBarVisible(bool visible,bool animate)165894fd9498SStephan Aßmus ShowImageWindow::_SetToolBarVisible(bool visible, bool animate)
1659cf0d8308SStephan Aßmus {
166095667008SJanus if (visible == fToolBarVisible)
1661cf0d8308SStephan Aßmus return;
1662cf0d8308SStephan Aßmus
166395667008SJanus fToolBarVisible = visible;
166494a4c1c4SAugustin Cavalier float diff = fToolBar->Bounds().Height() + 2;
166594fd9498SStephan Aßmus if (!visible)
1666cf0d8308SStephan Aßmus diff = -diff;
166794fd9498SStephan Aßmus else
166894a4c1c4SAugustin Cavalier fToolBar->Show();
1669cf0d8308SStephan Aßmus
167094fd9498SStephan Aßmus if (animate) {
167194fd9498SStephan Aßmus // Slide the controls into view. We do this with messages in order
167294fd9498SStephan Aßmus // not to block the window thread.
167394fd9498SStephan Aßmus const float kAnimationOffsets[] = { 0.05, 0.2, 0.5, 0.2, 0.05 };
167494fd9498SStephan Aßmus const int32 steps = sizeof(kAnimationOffsets) / sizeof(float);
167594fd9498SStephan Aßmus for (int32 i = 0; i < steps; i++) {
167694fd9498SStephan Aßmus BMessage message(kMsgSlideToolBar);
167794fd9498SStephan Aßmus message.AddFloat("offset", floorf(diff * kAnimationOffsets[i]));
167894fd9498SStephan Aßmus PostMessage(&message, this);
167994fd9498SStephan Aßmus }
168094fd9498SStephan Aßmus BMessage finalMessage(kMsgFinishSlidingToolBar);
168195667008SJanus finalMessage.AddFloat("offset", visible ? 0 : diff);
168294fd9498SStephan Aßmus finalMessage.AddBool("show", visible);
168394fd9498SStephan Aßmus PostMessage(&finalMessage, this);
168494fd9498SStephan Aßmus } else {
168520e18366SAugustin Cavalier fScrollArea->ResizeBy(0, -diff);
168620e18366SAugustin Cavalier fScrollArea->MoveBy(0, diff);
168794a4c1c4SAugustin Cavalier fToolBar->MoveBy(0, diff);
168894fd9498SStephan Aßmus if (!visible)
168994a4c1c4SAugustin Cavalier fToolBar->Hide();
169094fd9498SStephan Aßmus }
1691cf0d8308SStephan Aßmus }
1692cf0d8308SStephan Aßmus
1693cf0d8308SStephan Aßmus
169460c23976SJanus void
_SetToolBarBorder(bool visible)169560c23976SJanus ShowImageWindow::_SetToolBarBorder(bool visible)
169660c23976SJanus {
169760c23976SJanus float inset = visible
169860c23976SJanus ? ceilf(be_control_look->DefaultItemSpacing() / 2) : 0;
169960c23976SJanus
170060c23976SJanus fToolBar->GroupLayout()->SetInsets(inset, 0, inset, 0);
170160c23976SJanus }
170260c23976SJanus
170360c23976SJanus
1704780d8a62SMichael Pfeiffer bool
QuitRequested()1705cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1706cdb89ebbSMatthew Wilber {
1707efa8b4f3SAxel Dörfler if (fSavePanel) {
1708efa8b4f3SAxel Dörfler // Don't allow this window to be closed if a save panel is open
1709efa8b4f3SAxel Dörfler return false;
1710cdb89ebbSMatthew Wilber }
1711cdb89ebbSMatthew Wilber
17125b76e505SStephan Aßmus if (!_ClosePrompt())
17135b76e505SStephan Aßmus return false;
17145b76e505SStephan Aßmus
17155b76e505SStephan Aßmus ShowImageSettings* settings = my_app->Settings();
17165b76e505SStephan Aßmus if (settings->Lock()) {
1717c418e2beSStephan Aßmus if (fFullScreen)
1718c418e2beSStephan Aßmus settings->SetRect("WindowFrame", fWindowFrame);
1719c418e2beSStephan Aßmus else
17205b76e505SStephan Aßmus settings->SetRect("WindowFrame", Frame());
17215b76e505SStephan Aßmus settings->Unlock();
17225b76e505SStephan Aßmus }
17235b76e505SStephan Aßmus
17245b76e505SStephan Aßmus be_app->PostMessage(MSG_WINDOW_HAS_QUIT);
17255b76e505SStephan Aßmus
17265b76e505SStephan Aßmus return true;
1727efa8b4f3SAxel Dörfler }
1728