xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision de2a79cea2c0971f3dfa4155ba8b840bb0b2d140)
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