xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision 328932ac9edb30c87a3928b6d2a21b126bcaa3d4)
1efa8b4f3SAxel Dörfler /*
24fd570d3SAxel Dörfler  * Copyright 2003-2010, Haiku, Inc. All Rights Reserved.
3d9f6762dSMichael Pfeiffer  * Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
4d9f6762dSMichael Pfeiffer  * Copyright 2006 Bernd Korz. All Rights Reserved
5efa8b4f3SAxel Dörfler  * Distributed under the terms of the MIT License.
6efa8b4f3SAxel Dörfler  *
7efa8b4f3SAxel Dörfler  * Authors:
8efa8b4f3SAxel Dörfler  *		Fernando Francisco de Oliveira
9efa8b4f3SAxel Dörfler  *		Michael Wilber
10efa8b4f3SAxel Dörfler  *		Michael Pfeiffer
11d9f6762dSMichael Pfeiffer  *		yellowTAB GmbH
12d9f6762dSMichael Pfeiffer  *		Bernd Korz
13efa8b4f3SAxel Dörfler  */
1413afa642SPhil Greenway 
154fd570d3SAxel Dörfler 
16efa8b4f3SAxel Dörfler #include "ShowImageWindow.h"
17efa8b4f3SAxel Dörfler 
18fd952aefSRyan Leavengood #include <new>
19fd952aefSRyan Leavengood #include <stdio.h>
2004f96544SAxel Dörfler #include <stdlib.h>
216163f333SKarsten Heimrich 
22efa8b4f3SAxel Dörfler #include <Alert.h>
2313afa642SPhil Greenway #include <Application.h>
2413afa642SPhil Greenway #include <Bitmap.h>
25fc0a275bSMatthew Wilber #include <BitmapStream.h>
261ed4535fSStephan Aßmus #include <Catalog.h>
27efa8b4f3SAxel Dörfler #include <Clipboard.h>
2813afa642SPhil Greenway #include <Entry.h>
29fc0a275bSMatthew Wilber #include <File.h>
306163f333SKarsten Heimrich #include <FilePanel.h>
311ed4535fSStephan Aßmus #include <Locale.h>
3213afa642SPhil Greenway #include <Menu.h>
3313afa642SPhil Greenway #include <MenuBar.h>
3413afa642SPhil Greenway #include <MenuItem.h>
3513afa642SPhil Greenway #include <Path.h>
36efa8b4f3SAxel Dörfler #include <PrintJob.h>
3736272f0dSAxel Dörfler #include <RecentItems.h>
38efa8b4f3SAxel Dörfler #include <Roster.h>
39efa8b4f3SAxel Dörfler #include <Screen.h>
4013afa642SPhil Greenway #include <ScrollView.h>
416163f333SKarsten Heimrich #include <String.h>
42efa8b4f3SAxel Dörfler #include <SupportDefs.h>
436163f333SKarsten Heimrich #include <TranslationDefs.h>
4413afa642SPhil Greenway #include <TranslationUtils.h>
4513afa642SPhil Greenway #include <TranslatorRoster.h>
4613afa642SPhil Greenway 
47fd952aefSRyan Leavengood #include "EntryMenuItem.h"
48fd952aefSRyan Leavengood #include "ShowImageApp.h"
49fd952aefSRyan Leavengood #include "ShowImageConstants.h"
50fd952aefSRyan Leavengood #include "ShowImageStatusView.h"
51fd952aefSRyan Leavengood #include "ShowImageView.h"
5213afa642SPhil Greenway 
53a8fc7138SMichael Pfeiffer 
54cd6b5cdeSAxel Dörfler // BMessage field names used in Save messages
55cd6b5cdeSAxel Dörfler const char* kTypeField = "be:type";
56cd6b5cdeSAxel Dörfler const char* kTranslatorField = "be:translator";
57cd6b5cdeSAxel Dörfler 
58cd6b5cdeSAxel Dörfler 
59cd6b5cdeSAxel Dörfler // This is temporary solution for building BString with printf like format.
60cd6b5cdeSAxel Dörfler // will be removed in the future.
61cd6b5cdeSAxel Dörfler static void
62cd6b5cdeSAxel Dörfler bs_printf(BString* string, const char* format, ...)
63cd6b5cdeSAxel Dörfler {
64cd6b5cdeSAxel Dörfler 	va_list ap;
65cd6b5cdeSAxel Dörfler 	char* buf;
66cd6b5cdeSAxel Dörfler 
67cd6b5cdeSAxel Dörfler 	va_start(ap, format);
68cd6b5cdeSAxel Dörfler 	vasprintf(&buf, format, ap);
69cd6b5cdeSAxel Dörfler 	string->SetTo(buf);
70cd6b5cdeSAxel Dörfler 	free(buf);
71cd6b5cdeSAxel Dörfler 	va_end(ap);
72cd6b5cdeSAxel Dörfler }
73cd6b5cdeSAxel Dörfler 
74cd6b5cdeSAxel Dörfler 
756163f333SKarsten Heimrich //	#pragma mark -- ShowImageWindow
766163f333SKarsten Heimrich 
776163f333SKarsten Heimrich 
78ba3217eeSAxel Dörfler ShowImageWindow::ShowImageWindow(const entry_ref& ref,
79efa8b4f3SAxel Dörfler 	const BMessenger& trackerMessenger)
80fd952aefSRyan Leavengood 	:
81fd952aefSRyan Leavengood 	BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0),
82ba3217eeSAxel Dörfler 	fNavigator(this, ref, trackerMessenger),
83fd952aefSRyan Leavengood 	fSavePanel(NULL),
84fd952aefSRyan Leavengood 	fBar(NULL),
85fd952aefSRyan Leavengood 	fBrowseMenu(NULL),
86fd952aefSRyan Leavengood 	fGoToPageMenu(NULL),
87fd952aefSRyan Leavengood 	fSlideShowDelay(NULL),
88fd952aefSRyan Leavengood 	fImageView(NULL),
89fd952aefSRyan Leavengood 	fStatusView(NULL),
90fd952aefSRyan Leavengood 	fModified(false),
91fd952aefSRyan Leavengood 	fFullScreen(false),
92fd952aefSRyan Leavengood 	fShowCaption(true),
9304f96544SAxel Dörfler 	fPrintSettings(NULL)
9413afa642SPhil Greenway {
952281340dSAxel Dörfler 	_ApplySettings();
96fc0a275bSMatthew Wilber 
9713afa642SPhil Greenway 	// create menu bar
98e9dcd874SAxel Dörfler 	fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar");
99efa8b4f3SAxel Dörfler 	AddMenus(fBar);
100e9dcd874SAxel Dörfler 	AddChild(fBar);
10113afa642SPhil Greenway 
10213afa642SPhil Greenway 	BRect viewFrame = Bounds();
103e9dcd874SAxel Dörfler 	viewFrame.top = fBar->Bounds().Height() + 1;
10413afa642SPhil Greenway 	viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
10513afa642SPhil Greenway 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
10613afa642SPhil Greenway 
10713afa642SPhil Greenway 	// create the image view
108d3046f7dSMichael Pfeiffer 	fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
1097eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
11013afa642SPhil Greenway 	// wrap a scroll view around the view
111efa8b4f3SAxel Dörfler 	BScrollView* scrollView = new BScrollView("image_scroller", fImageView,
112cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
113efa8b4f3SAxel Dörfler 	AddChild(scrollView);
11413afa642SPhil Greenway 
11507caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
116cdb89ebbSMatthew Wilber 	BRect rect;
11713afa642SPhil Greenway 	rect = Bounds();
11813afa642SPhil Greenway 	rect.top = viewFrame.bottom + 1;
11907caaa8eSMatthew Wilber 	rect.left = viewFrame.left + kstatusWidth;
1200916ab53SMatthew Wilber 	rect.right = viewFrame.right + 1;
1210916ab53SMatthew Wilber 	rect.bottom += 1;
122efa8b4f3SAxel Dörfler 	BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll",
123efa8b4f3SAxel Dörfler 		fImageView, 0, 150, B_HORIZONTAL);
124efa8b4f3SAxel Dörfler 	AddChild(horizontalScrollBar);
12513afa642SPhil Greenway 
12613afa642SPhil Greenway 	rect.left = 0;
12707caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
1280cd4ecd8SStephan Aßmus 	rect.bottom -= 1;
129d3046f7dSMichael Pfeiffer 	fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
130cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
131d3046f7dSMichael Pfeiffer 	AddChild(fStatusView);
13213afa642SPhil Greenway 
13313afa642SPhil Greenway 	rect = Bounds();
1340916ab53SMatthew Wilber 	rect.top = viewFrame.top - 1;
13513afa642SPhil Greenway 	rect.left = viewFrame.right + 1;
1360916ab53SMatthew Wilber 	rect.bottom = viewFrame.bottom + 1;
1370916ab53SMatthew Wilber 	rect.right += 1;
138efa8b4f3SAxel Dörfler 	BScrollBar* verticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
139efa8b4f3SAxel Dörfler 		0, 150, B_VERTICAL);
140efa8b4f3SAxel Dörfler 	AddChild(verticalScrollBar);
14113afa642SPhil Greenway 
14203839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
14313afa642SPhil Greenway 
144134d6076SMichael Pfeiffer 	// finish creating the window
145ba3217eeSAxel Dörfler 	if (fNavigator.LoadImage(ref) != B_OK) {
146ba3217eeSAxel Dörfler 		_LoadError(ref);
1475e09d5dbSRyan Leavengood 		Quit();
14801939af6SAxel Dörfler 		return;
149d10d5947SMichael Pfeiffer 	}
150402c09e5SMatthew Wilber 
151d9f6762dSMichael Pfeiffer 	// add View menu here so it can access ShowImageView methods
152ddcb5a2cSAxel Dörfler 	BMenu* menu = new BMenu(B_TRANSLATE_WITH_CONTEXT("View", "Menus"));
153fd952aefSRyan Leavengood 	_BuildViewMenu(menu, false);
154d9f6762dSMichael Pfeiffer 	fBar->AddItem(menu);
155d9f6762dSMichael Pfeiffer 
156d9f6762dSMichael Pfeiffer 	SetPulseRate(100000);
157d9f6762dSMichael Pfeiffer 		// every 1/10 second; ShowImageView needs it for marching ants
158d9f6762dSMichael Pfeiffer 
1596db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SELECTION_MODE,
1606db01936SAxel Dörfler 		fImageView->IsSelectionModeEnabled());
1616db01936SAxel Dörfler 
162402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
163402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
164402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
165cd6b5cdeSAxel Dörfler 
166cd6b5cdeSAxel Dörfler 	// The window will be shown on screen automatically
167cd6b5cdeSAxel Dörfler 	Run();
16813afa642SPhil Greenway }
16913afa642SPhil Greenway 
170efa8b4f3SAxel Dörfler 
17113afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
17213afa642SPhil Greenway {
17313afa642SPhil Greenway }
17413afa642SPhil Greenway 
175efa8b4f3SAxel Dörfler 
176cdb89ebbSMatthew Wilber void
177cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
17813afa642SPhil Greenway {
179cd6b5cdeSAxel Dörfler 	BPath path(fImageView->Image());
180cd6b5cdeSAxel Dörfler 	SetTitle(path.Path());
18113afa642SPhil Greenway }
18213afa642SPhil Greenway 
18356b0c7b9SKarsten Heimrich 
184d9f6762dSMichael Pfeiffer void
185d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu)
186d9f6762dSMichael Pfeiffer {
187fd952aefSRyan Leavengood 	_BuildViewMenu(menu, true);
188d9f6762dSMichael Pfeiffer }
189efa8b4f3SAxel Dörfler 
19056b0c7b9SKarsten Heimrich 
1914eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
1924eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus"
1931ed4535fSStephan Aßmus 
1946046b973SAxel Dörfler 
195cdb89ebbSMatthew Wilber void
196fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
197da87390fSMichael Pfeiffer {
198905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this);
199fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
200905c8c8cSMatt Madia 	BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay"));
201efa8b4f3SAxel Dörfler 	if (fSlideShowDelay == NULL)
202efa8b4f3SAxel Dörfler 		fSlideShowDelay = delayMenu;
203efa8b4f3SAxel Dörfler 
204efa8b4f3SAxel Dörfler 	delayMenu->SetRadioMode(true);
20556b0c7b9SKarsten Heimrich 	// Note: ShowImage loads images in window thread so it becomes unresponsive
20656b0c7b9SKarsten Heimrich 	//		 if slide show delay is too short! (Especially if loading the image
20756b0c7b9SKarsten Heimrich 	//		 takes as long as or longer than the slide show delay). Should load
20856b0c7b9SKarsten Heimrich 	//		 in background thread!
209905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("3 seconds"), 3);
210905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("4 seconds"), 4);
211905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("5 seconds"), 5);
212905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("6 seconds"), 6);
213905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("7 seconds"), 7);
214905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("8 seconds"), 8);
215905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("9 seconds"), 9);
216905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("10 seconds"), 10);
217905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("20 seconds"), 20);
218efa8b4f3SAxel Dörfler 	menu->AddItem(delayMenu);
21930060f17SMatthew Wilber 
220efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
221efa8b4f3SAxel Dörfler 
222905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Original size"),
223905c8c8cSMatt Madia 		MSG_ORIGINAL_SIZE, '1', 0, this);
224905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this);
225905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this);
226efa8b4f3SAxel Dörfler 
227efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
228efa8b4f3SAxel Dörfler 
2294fd570d3SAxel Dörfler 	if (!popupMenu || fFullScreen) {
230905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
231905c8c8cSMatt Madia 			MSG_SCALE_BILINEAR, 0, 0, this);
232efa8b4f3SAxel Dörfler 
233efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
234efa8b4f3SAxel Dörfler 
235905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Shrink to window"),
236905c8c8cSMatt Madia 			MSG_SHRINK_TO_WINDOW, 0, 0, this);
2374fd570d3SAxel Dörfler 		_AddItemMenu(menu, B_TRANSLATE("Stretch to window"),
2384fd570d3SAxel Dörfler 			MSG_STRETCH_TO_WINDOW, 0, 0, this);
239efa8b4f3SAxel Dörfler 
240efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
24132c22143SAxel Dörfler 	}
242efa8b4f3SAxel Dörfler 
243905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Full screen"),
244905c8c8cSMatt Madia 		MSG_FULL_SCREEN, B_ENTER, 0, this);
245fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
246efa8b4f3SAxel Dörfler 
247905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"),
248905c8c8cSMatt Madia 		MSG_SHOW_CAPTION, 0, 0, this);
249fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
250efa8b4f3SAxel Dörfler 
251fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
2526db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, fImageView->ShrinksToBounds());
2536db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_STRETCH_TO_WINDOW, fImageView->StretchesToBounds());
254a60adbf9SAxel Dörfler 
255d9f6762dSMichael Pfeiffer 	if (popupMenu) {
256a60adbf9SAxel Dörfler 		menu->AddSeparatorItem();
257905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
2581ed4535fSStephan Aßmus 			MSG_DESKTOP_BACKGROUND, 0, 0, this);
259d9f6762dSMichael Pfeiffer 	}
260da87390fSMichael Pfeiffer }
261da87390fSMichael Pfeiffer 
262efa8b4f3SAxel Dörfler 
263da87390fSMichael Pfeiffer void
264efa8b4f3SAxel Dörfler ShowImageWindow::AddMenus(BMenuBar* bar)
26513afa642SPhil Greenway {
266905c8c8cSMatt Madia 	BMenu* menu = new BMenu(B_TRANSLATE("File"));
26736272f0dSAxel Dörfler 
26836272f0dSAxel Dörfler 	// Add recent files to "Open File" entry as sub-menu.
26936272f0dSAxel Dörfler 	BMenuItem* item = new BMenuItem(BRecentFilesList::NewFileListMenu(
27036272f0dSAxel Dörfler 		B_TRANSLATE("Open"B_UTF8_ELLIPSIS), NULL, NULL, be_app, 10, true,
27136272f0dSAxel Dörfler 		NULL, kApplicationSignature), new BMessage(MSG_FILE_OPEN));
27236272f0dSAxel Dörfler 	item->SetShortcut('O', 0);
27336272f0dSAxel Dörfler 	item->SetTarget(be_app);
27436272f0dSAxel Dörfler 	menu->AddItem(item);
275efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
27636272f0dSAxel Dörfler 
2776db01936SAxel Dörfler 	BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS),
2781ed4535fSStephan Aßmus 		B_ITEMS_IN_COLUMN);
2796db01936SAxel Dörfler 	BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP);
280fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
281fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
2826db01936SAxel Dörfler 	menu->AddItem(menuSaveAs);
283905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this);
284efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
285905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS),
2861ed4535fSStephan Aßmus 		MSG_PAGE_SETUP, 0, 0, this);
287905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS),
2881ed4535fSStephan Aßmus 		MSG_PREPARE_PRINT, 'P', 0, this);
289efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
290905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("About ShowImage" B_UTF8_ELLIPSIS),
2911ed4535fSStephan Aßmus 		B_ABOUT_REQUESTED, 0, 0, be_app);
292efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
293905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app);
294efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
29513afa642SPhil Greenway 
296905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Edit"));
297905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Undo"), B_UNDO, 'Z', 0, this, false);
298efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
299905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false);
300efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
3016db01936SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Selection Mode"), MSG_SELECTION_MODE, 0, 0,
3026db01936SAxel Dörfler 		this);
30332c22143SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Clear selection"),
30432c22143SAxel Dörfler 		MSG_CLEAR_SELECT, 0, 0, this, false);
305905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Select all"),
306905c8c8cSMatt Madia 		MSG_SELECT_ALL, 'A', 0, this);
307efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
30813afa642SPhil Greenway 
309905c8c8cSMatt Madia 	menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse"));
310905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("First page"),
3111ed4535fSStephan Aßmus 		MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this);
312905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Last page"),
3131ed4535fSStephan Aßmus 		MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this);
314905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous page"),
315905c8c8cSMatt Madia 		MSG_PAGE_PREV, B_LEFT_ARROW, 0, this);
316905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next page"),
317905c8c8cSMatt Madia 		MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this);
318905c8c8cSMatt Madia 	fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page"));
3195e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
320efa8b4f3SAxel Dörfler 	menu->AddItem(fGoToPageMenu);
321efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
322905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous file"),
323905c8c8cSMatt Madia 		MSG_FILE_PREV, B_UP_ARROW, 0, this);
324905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next file"),
325905c8c8cSMatt Madia 		MSG_FILE_NEXT, B_DOWN_ARROW, 0, this);
326efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
32703839579SMatthew Wilber 
328905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Image"));
329905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"),
330905c8c8cSMatt Madia 		MSG_ROTATE_90, 'R', 0, this);
331905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"),
3321ed4535fSStephan Aßmus 		MSG_ROTATE_270, 'R', B_SHIFT_KEY, this);
333efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
334905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip left to right"),
3351ed4535fSStephan Aßmus 		MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this);
336905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"),
3371ed4535fSStephan Aßmus 		MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this);
338efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
339905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
3401ed4535fSStephan Aßmus 		MSG_DESKTOP_BACKGROUND, 0, 0, this);
34104f96544SAxel Dörfler 
34204f96544SAxel Dörfler 	bar->AddItem(menu);
34313afa642SPhil Greenway }
34413afa642SPhil Greenway 
345efa8b4f3SAxel Dörfler 
346cdb89ebbSMatthew Wilber BMenuItem*
347fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what,
3484fd570d3SAxel Dörfler 	char shortcut, uint32 modifier, const BHandler* target, bool enabled)
349cdb89ebbSMatthew Wilber {
3504fd570d3SAxel Dörfler 	BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut,
3514fd570d3SAxel Dörfler 		modifier);
352efa8b4f3SAxel Dörfler 	menu->AddItem(item);
353efa8b4f3SAxel Dörfler 
3546163f333SKarsten Heimrich 	item->SetTarget(target);
3556163f333SKarsten Heimrich 	item->SetEnabled(enabled);
3566163f333SKarsten Heimrich 
357efa8b4f3SAxel Dörfler 	return item;
35813afa642SPhil Greenway }
35913afa642SPhil Greenway 
360efa8b4f3SAxel Dörfler 
361ad13f387SMichael Pfeiffer BMenuItem*
362fd952aefSRyan Leavengood ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, float value)
363ad13f387SMichael Pfeiffer {
364efa8b4f3SAxel Dörfler 	BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
365efa8b4f3SAxel Dörfler 	message->AddFloat("value", value);
366ad13f387SMichael Pfeiffer 
3676163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, message, 0);
368efa8b4f3SAxel Dörfler 	item->SetTarget(this);
369ad13f387SMichael Pfeiffer 
370d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
371efa8b4f3SAxel Dörfler 	if (marked)
372efa8b4f3SAxel Dörfler 		item->SetMarked(true);
373ad13f387SMichael Pfeiffer 
374efa8b4f3SAxel Dörfler 	menu->AddItem(item);
375efa8b4f3SAxel Dörfler 	return item;
376ad13f387SMichael Pfeiffer }
377ad13f387SMichael Pfeiffer 
378efa8b4f3SAxel Dörfler 
379cdb89ebbSMatthew Wilber void
3801076d97bSAxel Dörfler ShowImageWindow::WindowRedimension(BBitmap* bitmap)
38113afa642SPhil Greenway {
382d10d5947SMichael Pfeiffer 	BScreen screen;
38371a34702SAxel Dörfler 	if (!screen.IsValid())
384efa8b4f3SAxel Dörfler 		return;
385efa8b4f3SAxel Dörfler 
3861076d97bSAxel Dörfler 	// TODO: use View::GetPreferredSize() instead?
3871076d97bSAxel Dörfler 	BRect r(bitmap->Bounds());
3881076d97bSAxel Dörfler 	float width = r.Width() + B_V_SCROLL_BAR_WIDTH;
3891076d97bSAxel Dörfler 	float height = r.Height() + 1 + fBar->Frame().Height()
3901076d97bSAxel Dörfler 		+ B_H_SCROLL_BAR_HEIGHT;
391cdb89ebbSMatthew Wilber 
3926163f333SKarsten Heimrich 	BRect frame = screen.Frame();
3936163f333SKarsten Heimrich 	const float windowBorder = 5;
394d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
3956163f333SKarsten Heimrich 	float maxWidth = frame.Width() + 1 - windowBorder - Frame().left;
3966163f333SKarsten Heimrich 	float maxHeight = frame.Height() + 1 - windowBorder - Frame().top;
397cdb89ebbSMatthew Wilber 
398a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
399a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
400efa8b4f3SAxel Dörfler 
401fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
402a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
403efa8b4f3SAxel Dörfler 	if (maxWidth > maxW)
404efa8b4f3SAxel Dörfler 		maxWidth = maxW;
405efa8b4f3SAxel Dörfler 	if (maxHeight > maxH)
406efa8b4f3SAxel Dörfler 		maxHeight = maxH;
407efa8b4f3SAxel Dörfler 	if (width < minW)
408efa8b4f3SAxel Dörfler 		width = minW;
409efa8b4f3SAxel Dörfler 	if (height < minH)
410efa8b4f3SAxel Dörfler 		height = minH;
411a8fc7138SMichael Pfeiffer 
412efa8b4f3SAxel Dörfler 	if (width > maxWidth)
413efa8b4f3SAxel Dörfler 		width = maxWidth;
414efa8b4f3SAxel Dörfler 	if (height > maxHeight)
415efa8b4f3SAxel Dörfler 		height = maxHeight;
416d10d5947SMichael Pfeiffer 
417d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
41813afa642SPhil Greenway }
41913afa642SPhil Greenway 
420efa8b4f3SAxel Dörfler 
421cdb89ebbSMatthew Wilber void
422cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
42313afa642SPhil Greenway {
4246163f333SKarsten Heimrich 	BWindow::FrameResized(width, height);
42513afa642SPhil Greenway }
42613afa642SPhil Greenway 
427efa8b4f3SAxel Dörfler 
4287eca0987SMichael Pfeiffer bool
429fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what)
4307eca0987SMichael Pfeiffer {
4317eca0987SMichael Pfeiffer 	bool marked = false;
4326163f333SKarsten Heimrich 	BMenuItem* item = fBar->FindItem(what);
4337eca0987SMichael Pfeiffer 	if (item != NULL) {
4347eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
4357eca0987SMichael Pfeiffer 		item->SetMarked(marked);
4367eca0987SMichael Pfeiffer 	}
4377eca0987SMichael Pfeiffer 	return marked;
4387eca0987SMichael Pfeiffer }
4397eca0987SMichael Pfeiffer 
440efa8b4f3SAxel Dörfler 
441cdb89ebbSMatthew Wilber void
442fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable)
443e6a50d9cSMichael Pfeiffer {
4446163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
4456163f333SKarsten Heimrich 	if (item && item->IsEnabled() != enable)
446e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
447e6a50d9cSMichael Pfeiffer }
448e6a50d9cSMichael Pfeiffer 
449efa8b4f3SAxel Dörfler 
450e6a50d9cSMichael Pfeiffer void
451fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked)
452e6a50d9cSMichael Pfeiffer {
4536163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
4546163f333SKarsten Heimrich 	if (item && item->IsMarked() != marked)
455e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
456e6a50d9cSMichael Pfeiffer }
457e6a50d9cSMichael Pfeiffer 
458efa8b4f3SAxel Dörfler 
459da87390fSMichael Pfeiffer void
460fd952aefSRyan Leavengood ShowImageWindow::_MarkSlideShowDelay(float value)
461da87390fSMichael Pfeiffer {
462d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
463da87390fSMichael Pfeiffer 	float v;
464da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
465d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
466da87390fSMichael Pfeiffer 		if (item) {
467da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
4686163f333SKarsten Heimrich 				if (!item->IsMarked())
469da87390fSMichael Pfeiffer 					item->SetMarked(true);
470da87390fSMichael Pfeiffer 				return;
471da87390fSMichael Pfeiffer 			}
472da87390fSMichael Pfeiffer 		}
473da87390fSMichael Pfeiffer 	}
474da87390fSMichael Pfeiffer }
475e6a50d9cSMichael Pfeiffer 
47619c76de4SMichael Pfeiffer 
47719c76de4SMichael Pfeiffer void
478fd952aefSRyan Leavengood ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what)
47919c76de4SMichael Pfeiffer {
480fd952aefSRyan Leavengood 	bool enabled = _ToggleMenuItem(what);
4816163f333SKarsten Heimrich 	if (shrink)
482d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
4836163f333SKarsten Heimrich 	else
4844fd570d3SAxel Dörfler 		fImageView->SetStretchToBounds(enabled);
48519c76de4SMichael Pfeiffer }
48619c76de4SMichael Pfeiffer 
487efa8b4f3SAxel Dörfler 
488e6a50d9cSMichael Pfeiffer void
489efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message)
49013afa642SPhil Greenway {
491efa8b4f3SAxel Dörfler 	switch (message->what) {
492cd6b5cdeSAxel Dörfler 		case kMsgImageLoaded:
493cd6b5cdeSAxel Dörfler 		{
494cd6b5cdeSAxel Dörfler 			bool first = fImageView->Bitmap() == NULL;
495cd6b5cdeSAxel Dörfler 
496cd6b5cdeSAxel Dörfler 			status_t status = fImageView->SetImage(message);
497cd6b5cdeSAxel Dörfler 			if (status != B_OK) {
498cd6b5cdeSAxel Dörfler 				entry_ref ref;
499cd6b5cdeSAxel Dörfler 				message->FindRef("ref", &ref);
500cd6b5cdeSAxel Dörfler 
501cd6b5cdeSAxel Dörfler 				_LoadError(ref);
502cd6b5cdeSAxel Dörfler 
503cd6b5cdeSAxel Dörfler 				// quit if file could not be opened
504cd6b5cdeSAxel Dörfler 				if (first)
505cd6b5cdeSAxel Dörfler 					Quit();
506cd6b5cdeSAxel Dörfler 				break;
507cd6b5cdeSAxel Dörfler 			}
508cd6b5cdeSAxel Dörfler 
509cd6b5cdeSAxel Dörfler 			fImageType = message->FindString("type");
510cd6b5cdeSAxel Dörfler 
511cd6b5cdeSAxel Dörfler 			if (first) {
512cd6b5cdeSAxel Dörfler 				WindowRedimension(fImageView->Bitmap());
513cd6b5cdeSAxel Dörfler 				fImageView->ResetZoom();
514cd6b5cdeSAxel Dörfler 				fImageView->MakeFocus(true);
515cd6b5cdeSAxel Dörfler 					// to receive key messages
516cd6b5cdeSAxel Dörfler 
517cd6b5cdeSAxel Dörfler 				Show();
518cd6b5cdeSAxel Dörfler 			} else {
519cd6b5cdeSAxel Dörfler 				if (!fImageView->StretchesToBounds()
520cd6b5cdeSAxel Dörfler 					&& !fImageView->ShrinksToBounds()
521cd6b5cdeSAxel Dörfler 					&& !fFullScreen)
522cd6b5cdeSAxel Dörfler 					WindowRedimension(fImageView->Bitmap());
523cd6b5cdeSAxel Dörfler 			}
524cd6b5cdeSAxel Dörfler 			break;
525cd6b5cdeSAxel Dörfler 		}
526cd6b5cdeSAxel Dörfler 
527ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
528ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
529ee7b4f39SMatthew Wilber 			fModified = true;
530ee7b4f39SMatthew Wilber 			break;
531ee7b4f39SMatthew Wilber 
532fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
533fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
534d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
535cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
536fd952aefSRyan Leavengood 				_SaveAs(message);
53713afa642SPhil Greenway 			break;
538fc0a275bSMatthew Wilber 
539fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
540fc0a275bSMatthew Wilber 			// User specified where to save the output image
541fd952aefSRyan Leavengood 			_SaveToFile(message);
54207caaa8eSMatthew Wilber 			break;
54307caaa8eSMatthew Wilber 
544cdb89ebbSMatthew Wilber 		case B_CANCEL:
545d3046f7dSMichael Pfeiffer 			delete fSavePanel;
546d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
547cdb89ebbSMatthew Wilber 			break;
548cdb89ebbSMatthew Wilber 
5496db01936SAxel Dörfler 		case MSG_UPDATE_STATUS:
5506db01936SAxel Dörfler 		{
551cd6b5cdeSAxel Dörfler 			int32 pages = fNavigator.PageCount();
552cd6b5cdeSAxel Dörfler 			int32 currentPage = fNavigator.CurrentPage();
5536c305411SMatthew Wilber 
554cd6b5cdeSAxel Dörfler 			bool enable = pages > 1 ? true : false;
55536c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_FIRST, enable);
55636c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_LAST, enable);
55736c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_NEXT, enable);
55836c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_PREV, enable);
55936c17651SRyan Leavengood 			fGoToPageMenu->SetEnabled(enable);
5601d592070SMatthew Wilber 
561cd6b5cdeSAxel Dörfler 			_EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile());
562cd6b5cdeSAxel Dörfler 			_EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile());
563134d6076SMichael Pfeiffer 
564d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
5656c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
5666c305411SMatthew Wilber 				// pages is different
5676c305411SMatthew Wilber 
568cd6b5cdeSAxel Dörfler 				while (fGoToPageMenu->CountItems() > 0) {
5696c305411SMatthew Wilber 					// Remove all page numbers
570d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
571cd6b5cdeSAxel Dörfler 				}
5726c305411SMatthew Wilber 
573780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
5746c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
575cd6b5cdeSAxel Dörfler 					BMessage* goTo = new BMessage(MSG_GOTO_PAGE);
576cd6b5cdeSAxel Dörfler 					goTo->AddInt32("page", i);
5776163f333SKarsten Heimrich 
5786163f333SKarsten Heimrich 					char shortcut = 0;
579cd6b5cdeSAxel Dörfler 					if (i < 10)
580780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
5816163f333SKarsten Heimrich 
5826163f333SKarsten Heimrich 					BString strCaption;
5836163f333SKarsten Heimrich 					strCaption << i;
5846163f333SKarsten Heimrich 
585cd6b5cdeSAxel Dörfler 					BMenuItem* item = new BMenuItem(strCaption.String(), goTo,
586ddcb5a2cSAxel Dörfler 						B_SHIFT_KEY, shortcut);
587cd6b5cdeSAxel Dörfler 					if (currentPage == i)
588efa8b4f3SAxel Dörfler 						item->SetMarked(true);
589efa8b4f3SAxel Dörfler 					fGoToPageMenu->AddItem(item);
5906c305411SMatthew Wilber 				}
5916c305411SMatthew Wilber 			} else {
5926c305411SMatthew Wilber 				// Make sure the correct page is marked
593cd6b5cdeSAxel Dörfler 				BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
594cd6b5cdeSAxel Dörfler 				if (currentItem != NULL && !currentItem->IsMarked())
595cd6b5cdeSAxel Dörfler 					currentItem->SetMarked(true);
5966c305411SMatthew Wilber 			}
5976c305411SMatthew Wilber 
598cd6b5cdeSAxel Dörfler 			_UpdateStatusText(message);
5997eca0987SMichael Pfeiffer 			UpdateTitle();
6006db01936SAxel Dörfler 			break;
6016db01936SAxel Dörfler 		}
60203839579SMatthew Wilber 
6036db01936SAxel Dörfler 		case MSG_UPDATE_STATUS_TEXT:
6046db01936SAxel Dörfler 		{
605cd6b5cdeSAxel Dörfler 			_UpdateStatusText(message);
6066db01936SAxel Dörfler 			break;
6076db01936SAxel Dörfler 		}
6088f5fd23fSRyan Leavengood 
6096db01936SAxel Dörfler 		case MSG_SELECTION:
6106db01936SAxel Dörfler 		{
6118ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
6128ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
6138ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
6146db01936SAxel Dörfler 			bool enable;
6156db01936SAxel Dörfler 			if (message->FindBool("has_selection", &enable) == B_OK) {
6166db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_COPY, enable);
6176db01936SAxel Dörfler 				_EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable);
6188ad30bcfSMatthew Wilber 			}
6196db01936SAxel Dörfler 			break;
6206db01936SAxel Dörfler 		}
6218ad30bcfSMatthew Wilber 
6226db01936SAxel Dörfler 		case MSG_UNDO_STATE:
6236db01936SAxel Dörfler 		{
6246db01936SAxel Dörfler 			bool enable;
6256db01936SAxel Dörfler 			if (message->FindBool("can_undo", &enable) == B_OK)
6266db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_UNDO, enable);
6276db01936SAxel Dörfler 			break;
6286db01936SAxel Dörfler 		}
629402c09e5SMatthew Wilber 
63013afa642SPhil Greenway 		case B_UNDO:
6317598450eSMatthew Wilber 			fImageView->Undo();
63213afa642SPhil Greenway 			break;
6336163f333SKarsten Heimrich 
63413afa642SPhil Greenway 		case B_COPY:
635d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
63613afa642SPhil Greenway 			break;
6376163f333SKarsten Heimrich 
6386db01936SAxel Dörfler 		case MSG_SELECTION_MODE:
6396db01936SAxel Dörfler 			fImageView->SetSelectionMode(_ToggleMenuItem(MSG_SELECTION_MODE));
6406db01936SAxel Dörfler 			break;
6416db01936SAxel Dörfler 
64213afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
643d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
64413afa642SPhil Greenway 			break;
6456163f333SKarsten Heimrich 
64613afa642SPhil Greenway 		case MSG_SELECT_ALL:
647d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
64813afa642SPhil Greenway 			break;
64913afa642SPhil Greenway 
65003839579SMatthew Wilber 		case MSG_PAGE_FIRST:
651fd952aefSRyan Leavengood 			if (_ClosePrompt())
652cd6b5cdeSAxel Dörfler 				fNavigator.FirstPage();
65303839579SMatthew Wilber 			break;
65403839579SMatthew Wilber 
65503839579SMatthew Wilber 		case MSG_PAGE_LAST:
656fd952aefSRyan Leavengood 			if (_ClosePrompt())
657cd6b5cdeSAxel Dörfler 				fNavigator.LastPage();
65803839579SMatthew Wilber 			break;
65903839579SMatthew Wilber 
66003839579SMatthew Wilber 		case MSG_PAGE_NEXT:
661fd952aefSRyan Leavengood 			if (_ClosePrompt())
662cd6b5cdeSAxel Dörfler 				fNavigator.NextPage();
66303839579SMatthew Wilber 			break;
66403839579SMatthew Wilber 
66503839579SMatthew Wilber 		case MSG_PAGE_PREV:
666fd952aefSRyan Leavengood 			if (_ClosePrompt())
667cd6b5cdeSAxel Dörfler 				fNavigator.PreviousPage();
66803839579SMatthew Wilber 			break;
66903839579SMatthew Wilber 
670cd6b5cdeSAxel Dörfler 		case MSG_GOTO_PAGE:
671cd6b5cdeSAxel Dörfler 		{
672fd952aefSRyan Leavengood 			if (!_ClosePrompt())
673ee7b4f39SMatthew Wilber 				break;
674ee7b4f39SMatthew Wilber 
6756163f333SKarsten Heimrich 			int32 newPage;
6766163f333SKarsten Heimrich 			if (message->FindInt32("page", &newPage) != B_OK)
6776163f333SKarsten Heimrich 				break;
6786163f333SKarsten Heimrich 
679cd6b5cdeSAxel Dörfler 			int32 currentPage = fNavigator.CurrentPage();
680cd6b5cdeSAxel Dörfler 			int32 pages = fNavigator.PageCount();
6816c305411SMatthew Wilber 
6826c305411SMatthew Wilber 			if (newPage > 0 && newPage <= pages) {
683cd6b5cdeSAxel Dörfler 				BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
684cd6b5cdeSAxel Dörfler 				BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1);
685cd6b5cdeSAxel Dörfler 				if (currentItem != NULL && newItem != NULL) {
686cd6b5cdeSAxel Dörfler 					currentItem->SetMarked(false);
687cd6b5cdeSAxel Dörfler 					newItem->SetMarked(true);
688cd6b5cdeSAxel Dörfler 					fNavigator.GoToPage(newPage);
6896c305411SMatthew Wilber 				}
6906c305411SMatthew Wilber 			}
691cd6b5cdeSAxel Dörfler 			break;
692cd6b5cdeSAxel Dörfler 		}
6936c305411SMatthew Wilber 
69419c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
695fd952aefSRyan Leavengood 			_ResizeToWindow(true, message->what);
69619c76de4SMichael Pfeiffer 			break;
6976163f333SKarsten Heimrich 
6984fd570d3SAxel Dörfler 		case MSG_STRETCH_TO_WINDOW:
699fd952aefSRyan Leavengood 			_ResizeToWindow(false, message->what);
7007eca0987SMichael Pfeiffer 			break;
7017eca0987SMichael Pfeiffer 
7027eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
703fd952aefSRyan Leavengood 			if (_ClosePrompt())
704cd6b5cdeSAxel Dörfler 				fNavigator.PreviousFile();
7057eca0987SMichael Pfeiffer 			break;
7067eca0987SMichael Pfeiffer 
7077eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
708fd952aefSRyan Leavengood 			if (_ClosePrompt())
709cd6b5cdeSAxel Dörfler 				fNavigator.NextFile();
71013afa642SPhil Greenway 			break;
71113afa642SPhil Greenway 
712*328932acSAxel Dörfler 		case kMsgDeleteCurrentFile:
713*328932acSAxel Dörfler 			if (!fNavigator.MoveFileToTrash())
714*328932acSAxel Dörfler 				PostMessage(B_QUIT_REQUESTED);
715*328932acSAxel Dörfler 			break;
716*328932acSAxel Dörfler 
717bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
718d3046f7dSMichael Pfeiffer 			fImageView->Rotate(90);
719ad13f387SMichael Pfeiffer 			break;
7206163f333SKarsten Heimrich 
721bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
722d3046f7dSMichael Pfeiffer 			fImageView->Rotate(270);
723ad13f387SMichael Pfeiffer 			break;
7246163f333SKarsten Heimrich 
72569eee339SRyan Leavengood 		case MSG_FLIP_LEFT_TO_RIGHT:
72661ddc257SRyan Leavengood 			fImageView->Flip(true);
727ad13f387SMichael Pfeiffer 			break;
7286163f333SKarsten Heimrich 
72969eee339SRyan Leavengood 		case MSG_FLIP_TOP_TO_BOTTOM:
73061ddc257SRyan Leavengood 			fImageView->Flip(false);
731ad13f387SMichael Pfeiffer 			break;
7326163f333SKarsten Heimrich 
7331076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW:
7341076d97bSAxel Dörfler 		{
7356163f333SKarsten Heimrich 			BMenuItem* item = fBar->FindItem(message->what);
736ee7b4f39SMatthew Wilber 			if (!item)
737ee7b4f39SMatthew Wilber 				break;
738ee7b4f39SMatthew Wilber 			if (item->IsMarked()) {
739ee7b4f39SMatthew Wilber 				item->SetMarked(false);
740d3046f7dSMichael Pfeiffer 				fImageView->StopSlideShow();
741fd952aefSRyan Leavengood 			} else if (_ClosePrompt()) {
742ee7b4f39SMatthew Wilber 				item->SetMarked(true);
743ee7b4f39SMatthew Wilber 				fImageView->StartSlideShow();
744ad13f387SMichael Pfeiffer 			}
7451076d97bSAxel Dörfler 			break;
7461076d97bSAxel Dörfler 		}
747ee7b4f39SMatthew Wilber 
7481076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW_DELAY:
7491076d97bSAxel Dörfler 		{
750ad13f387SMichael Pfeiffer 			float value;
751efa8b4f3SAxel Dörfler 			if (message->FindFloat("value", &value) == B_OK) {
752d3046f7dSMichael Pfeiffer 				fImageView->SetSlideShowDelay(value);
753da87390fSMichael Pfeiffer 				// in case message is sent from popup menu
754fd952aefSRyan Leavengood 				_MarkSlideShowDelay(value);
755ad13f387SMichael Pfeiffer 			}
7561076d97bSAxel Dörfler 			break;
7571076d97bSAxel Dörfler 		}
758ad13f387SMichael Pfeiffer 
759ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
760fd952aefSRyan Leavengood 			_ToggleFullScreen();
761ad13f387SMichael Pfeiffer 			break;
7626163f333SKarsten Heimrich 
763fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
764fc5ca95dSStephan Aßmus 			if (fFullScreen)
765fd952aefSRyan Leavengood 				_ToggleFullScreen();
766fc5ca95dSStephan Aßmus 			break;
7676163f333SKarsten Heimrich 
7686163f333SKarsten Heimrich 		case MSG_SHOW_CAPTION: {
769fd952aefSRyan Leavengood 			fShowCaption = _ToggleMenuItem(message->what);
770efa8b4f3SAxel Dörfler 			ShowImageSettings* settings = my_app->Settings();
771efa8b4f3SAxel Dörfler 
772d3046f7dSMichael Pfeiffer 			if (settings->Lock()) {
773d3046f7dSMichael Pfeiffer 				settings->SetBool("ShowCaption", fShowCaption);
774d3046f7dSMichael Pfeiffer 				settings->Unlock();
775d3046f7dSMichael Pfeiffer 			}
776efa8b4f3SAxel Dörfler 			if (fFullScreen)
777d3046f7dSMichael Pfeiffer 				fImageView->SetShowCaption(fShowCaption);
7786163f333SKarsten Heimrich 		}	break;
779ad13f387SMichael Pfeiffer 
780780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
781fd952aefSRyan Leavengood 			_PageSetup();
782780d8a62SMichael Pfeiffer 			break;
7836163f333SKarsten Heimrich 
784780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
785fd952aefSRyan Leavengood 			_PrepareForPrint();
786780d8a62SMichael Pfeiffer 			break;
7876163f333SKarsten Heimrich 
788780d8a62SMichael Pfeiffer 		case MSG_PRINT:
789fd952aefSRyan Leavengood 			_Print(message);
790780d8a62SMichael Pfeiffer 			break;
791780d8a62SMichael Pfeiffer 
792780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
793d3046f7dSMichael Pfeiffer 			fImageView->ZoomIn();
794780d8a62SMichael Pfeiffer 			break;
7956163f333SKarsten Heimrich 
796780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
797d3046f7dSMichael Pfeiffer 			fImageView->ZoomOut();
798780d8a62SMichael Pfeiffer 			break;
7996163f333SKarsten Heimrich 
800780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
8014fd570d3SAxel Dörfler 			fImageView->SetZoom(1.0);
802780d8a62SMichael Pfeiffer 			break;
8036163f333SKarsten Heimrich 
80481b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
805fd952aefSRyan Leavengood 			fImageView->SetScaleBilinear(_ToggleMenuItem(message->what));
80681b9c776SMichael Pfeiffer 			break;
807780d8a62SMichael Pfeiffer 
808cd6b5cdeSAxel Dörfler 		case MSG_DESKTOP_BACKGROUND:
809cd6b5cdeSAxel Dörfler 		{
8100a74004cSRyan Leavengood 			BMessage message(B_REFS_RECEIVED);
8110a74004cSRyan Leavengood 			message.AddRef("refs", fImageView->Image());
8120a74004cSRyan Leavengood 			// This is used in the Backgrounds code for scaled placement
8130a74004cSRyan Leavengood 			message.AddInt32("placement", 'scpl');
8140a74004cSRyan Leavengood 			be_roster->Launch("application/x-vnd.haiku-backgrounds", &message);
815cd6b5cdeSAxel Dörfler 			break;
816cd6b5cdeSAxel Dörfler 		}
817a60adbf9SAxel Dörfler 
81813afa642SPhil Greenway 		default:
819efa8b4f3SAxel Dörfler 			BWindow::MessageReceived(message);
82013afa642SPhil Greenway 			break;
82113afa642SPhil Greenway 	}
82213afa642SPhil Greenway }
823fc0a275bSMatthew Wilber 
824efa8b4f3SAxel Dörfler 
825fc0a275bSMatthew Wilber void
826cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message)
827cd6b5cdeSAxel Dörfler {
828cd6b5cdeSAxel Dörfler 	BString status;
829cd6b5cdeSAxel Dörfler 	if (fImageView->Bitmap() != NULL) {
830cd6b5cdeSAxel Dörfler 		BRect bounds = fImageView->Bitmap()->Bounds();
831cd6b5cdeSAxel Dörfler 		status << bounds.IntegerWidth() + 1
832cd6b5cdeSAxel Dörfler 			<< "x" << bounds.IntegerHeight() + 1 << ", " << fImageType;
833cd6b5cdeSAxel Dörfler 	}
834cd6b5cdeSAxel Dörfler 
835cd6b5cdeSAxel Dörfler 	BString text;
836cd6b5cdeSAxel Dörfler 	if (message != NULL && message->FindString("status", &text) == B_OK
837cd6b5cdeSAxel Dörfler 		&& text.Length() > 0) {
838cd6b5cdeSAxel Dörfler 		status << ", " << text;
839cd6b5cdeSAxel Dörfler 	}
840cd6b5cdeSAxel Dörfler 
841cd6b5cdeSAxel Dörfler 	fStatusView->SetText(status);
842cd6b5cdeSAxel Dörfler }
843cd6b5cdeSAxel Dörfler 
844cd6b5cdeSAxel Dörfler 
845cd6b5cdeSAxel Dörfler void
846cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref)
847cd6b5cdeSAxel Dörfler {
848cd6b5cdeSAxel Dörfler 	// TODO: give a better error message!
849cd6b5cdeSAxel Dörfler 	BAlert* alert = new BAlert(B_TRANSLATE("ShowImage"),
850ddcb5a2cSAxel Dörfler 		B_TRANSLATE_WITH_CONTEXT("Could not load image! Either the "
851ddcb5a2cSAxel Dörfler 			"file or an image translator for it does not exist.",
852ddcb5a2cSAxel Dörfler 			"LoadAlerts"),
853ddcb5a2cSAxel Dörfler 		B_TRANSLATE_WITH_CONTEXT("OK", "Alerts"), NULL, NULL,
854cd6b5cdeSAxel Dörfler 		B_WIDTH_AS_USUAL, B_INFO_ALERT);
855cd6b5cdeSAxel Dörfler 	alert->Go();
856cd6b5cdeSAxel Dörfler }
857cd6b5cdeSAxel Dörfler 
858cd6b5cdeSAxel Dörfler 
859cd6b5cdeSAxel Dörfler void
860fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message)
861fc0a275bSMatthew Wilber {
862cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
863cdb89ebbSMatthew Wilber 	translator_id outTranslator;
864cdb89ebbSMatthew Wilber 	uint32 outType;
8656163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
866efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
8676163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
868cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
869fc0a275bSMatthew Wilber 		return;
870fc0a275bSMatthew Wilber 
871cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
872cdb89ebbSMatthew Wilber 	// message that the save panel will send back
873c1a10c14SKarsten Heimrich 	BMessage panelMsg(MSG_SAVE_PANEL);
874c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTranslatorField, outTranslator);
875c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTypeField, outType);
876cdb89ebbSMatthew Wilber 
877cdb89ebbSMatthew Wilber 	// Create save panel and show it
8786163f333SKarsten Heimrich 	BMessenger target(this);
879efa8b4f3SAxel Dörfler 	fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
880c1a10c14SKarsten Heimrich 		&target, NULL, 0, false, &panelMsg);
881d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
882fc0a275bSMatthew Wilber 		return;
883a60adbf9SAxel Dörfler 
884d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
885d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
886fc0a275bSMatthew Wilber }
887fc0a275bSMatthew Wilber 
888efa8b4f3SAxel Dörfler 
889fc0a275bSMatthew Wilber void
890fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message)
891fc0a275bSMatthew Wilber {
892cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
893efa8b4f3SAxel Dörfler 	entry_ref dirRef;
894efa8b4f3SAxel Dörfler 	if (message->FindRef("directory", &dirRef) != B_OK)
895fc0a275bSMatthew Wilber 		return;
896efa8b4f3SAxel Dörfler 
897fc0a275bSMatthew Wilber 	const char* filename;
898efa8b4f3SAxel Dörfler 	if (message->FindString("name", &filename) != B_OK)
899fc0a275bSMatthew Wilber 		return;
900fc0a275bSMatthew Wilber 
901cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
902cdb89ebbSMatthew Wilber 	// to save the output image
903cdb89ebbSMatthew Wilber 	translator_id outTranslator;
904cdb89ebbSMatthew Wilber 	uint32 outType;
9056163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
906efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9076163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
908cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
909cdb89ebbSMatthew Wilber 		return;
910cdb89ebbSMatthew Wilber 
911a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
912a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
913a7e78e3bSMatthew Wilber 	BTranslatorRoster* roster = BTranslatorRoster::Default();
914efa8b4f3SAxel Dörfler 	const translation_format* outFormat = NULL;
915efa8b4f3SAxel Dörfler 	int32 outCount = 0;
916efa8b4f3SAxel Dörfler 	if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
917efa8b4f3SAxel Dörfler 		|| outCount < 1)
918a7e78e3bSMatthew Wilber 		return;
919efa8b4f3SAxel Dörfler 
920a7e78e3bSMatthew Wilber 	int32 i;
921efa8b4f3SAxel Dörfler 	for (i = 0; i < outCount; i++) {
922efa8b4f3SAxel Dörfler 		if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
923a7e78e3bSMatthew Wilber 			break;
924a7e78e3bSMatthew Wilber 	}
925efa8b4f3SAxel Dörfler 	if (i == outCount)
926fc0a275bSMatthew Wilber 		return;
927fc0a275bSMatthew Wilber 
928a7e78e3bSMatthew Wilber 	// Write out the image file
929efa8b4f3SAxel Dörfler 	BDirectory dir(&dirRef);
930efa8b4f3SAxel Dörfler 	fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
931fc0a275bSMatthew Wilber }
932fc0a275bSMatthew Wilber 
933efa8b4f3SAxel Dörfler 
9344eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
9354eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "ClosePrompt"
9361ed4535fSStephan Aßmus 
937cdb89ebbSMatthew Wilber bool
938fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt()
939ee7b4f39SMatthew Wilber {
940ee7b4f39SMatthew Wilber 	if (!fModified)
941ee7b4f39SMatthew Wilber 		return true;
942efa8b4f3SAxel Dörfler 
943cd6b5cdeSAxel Dörfler 	int32 count = fNavigator.PageCount();
944cd6b5cdeSAxel Dörfler 	int32 page = fNavigator.CurrentPage();
945cd6b5cdeSAxel Dörfler 	BString prompt;
946efa8b4f3SAxel Dörfler 
9471ed4535fSStephan Aßmus 	if (count > 1) {
9481ed4535fSStephan Aßmus 		bs_printf(&prompt,
949905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' (page %d) has been changed. Do you "
950905c8c8cSMatt Madia 				"want to close the document?"),
951cd6b5cdeSAxel Dörfler 			fImageView->Image()->name, page);
9521ed4535fSStephan Aßmus 	} else {
9531ed4535fSStephan Aßmus 		bs_printf(&prompt,
954905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' has been changed. Do you want to "
955905c8c8cSMatt Madia 				"close the document?"),
956cd6b5cdeSAxel Dörfler 			fImageView->Image()->name);
9571ed4535fSStephan Aßmus 	}
9581ed4535fSStephan Aßmus 
959cd6b5cdeSAxel Dörfler 	BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(),
960905c8c8cSMatt Madia 		B_TRANSLATE("Cancel"), B_TRANSLATE("Close"));
961cd6b5cdeSAxel Dörfler 	if (alert->Go() == 0) {
962ee7b4f39SMatthew Wilber 		// Cancel
963ee7b4f39SMatthew Wilber 		return false;
964cd6b5cdeSAxel Dörfler 	}
965cd6b5cdeSAxel Dörfler 
966ee7b4f39SMatthew Wilber 	// Close
967187f0b8aSMatthew Wilber 	fModified = false;
968ee7b4f39SMatthew Wilber 	return true;
969ee7b4f39SMatthew Wilber }
970ee7b4f39SMatthew Wilber 
971cdb89ebbSMatthew Wilber 
972ad13f387SMichael Pfeiffer void
973fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen()
974ad13f387SMichael Pfeiffer {
975ad13f387SMichael Pfeiffer 	BRect frame;
976ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
977ad13f387SMichael Pfeiffer 	if (fFullScreen) {
978ad13f387SMichael Pfeiffer 		BScreen screen;
979ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
980ad13f387SMichael Pfeiffer 		frame = screen.Frame();
981d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
982ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
983ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
984ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
985ad13f387SMichael Pfeiffer 
986ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
987c0b16687SAxel Dörfler 
988c0b16687SAxel Dörfler 		Activate();
989c0b16687SAxel Dörfler 			// make the window frontmost
990ad13f387SMichael Pfeiffer 	} else {
991ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
992ad13f387SMichael Pfeiffer 
993ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
994ad13f387SMichael Pfeiffer 	}
995efa8b4f3SAxel Dörfler 
99676d115d8SRyan Leavengood 	fImageView->SetFullScreen(fFullScreen);
997d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
998ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
999ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
1000ad13f387SMichael Pfeiffer }
1001ad13f387SMichael Pfeiffer 
1002efa8b4f3SAxel Dörfler 
1003d3046f7dSMichael Pfeiffer void
10042281340dSAxel Dörfler ShowImageWindow::_ApplySettings()
1005d3046f7dSMichael Pfeiffer {
1006efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1007efa8b4f3SAxel Dörfler 
1008d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1009d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
1010d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
1011d3046f7dSMichael Pfeiffer 
1012efa8b4f3SAxel Dörfler 		int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option());
1013d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
1014d3046f7dSMichael Pfeiffer 
1015efa8b4f3SAxel Dörfler 		float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1016d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
1017d3046f7dSMichael Pfeiffer 
1018d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
1019d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
1020d3046f7dSMichael Pfeiffer 
1021d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
1022d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
1023d3046f7dSMichael Pfeiffer 
1024d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
1025d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
1026d3046f7dSMichael Pfeiffer 
1027d3046f7dSMichael Pfeiffer 		settings->Unlock();
1028d3046f7dSMichael Pfeiffer 	}
1029d3046f7dSMichael Pfeiffer }
1030d3046f7dSMichael Pfeiffer 
1031efa8b4f3SAxel Dörfler 
1032d3046f7dSMichael Pfeiffer void
1033fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions()
1034d3046f7dSMichael Pfeiffer {
1035efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1036efa8b4f3SAxel Dörfler 
1037d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1038d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
1039d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1040d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1041d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
1042d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
1043d3046f7dSMichael Pfeiffer 		settings->Unlock();
1044d3046f7dSMichael Pfeiffer 	}
1045d3046f7dSMichael Pfeiffer }
1046d3046f7dSMichael Pfeiffer 
1047efa8b4f3SAxel Dörfler 
1048cdb89ebbSMatthew Wilber bool
1049fd952aefSRyan Leavengood ShowImageWindow::_PageSetup()
1050780d8a62SMichael Pfeiffer {
1051cd6b5cdeSAxel Dörfler 	BPrintJob printJob(fImageView->Image()->name);
1052efa8b4f3SAxel Dörfler 	if (fPrintSettings != NULL)
1053780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
1054efa8b4f3SAxel Dörfler 
10556163f333SKarsten Heimrich 	status_t status = printJob.ConfigPage();
10566163f333SKarsten Heimrich 	if (status == B_OK) {
1057780d8a62SMichael Pfeiffer 		delete fPrintSettings;
1058780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
1059780d8a62SMichael Pfeiffer 	}
1060efa8b4f3SAxel Dörfler 
10616163f333SKarsten Heimrich 	return status == B_OK;
1062780d8a62SMichael Pfeiffer }
1063780d8a62SMichael Pfeiffer 
1064efa8b4f3SAxel Dörfler 
1065780d8a62SMichael Pfeiffer void
1066fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint()
1067780d8a62SMichael Pfeiffer {
10686163f333SKarsten Heimrich 	if (fPrintSettings == NULL) {
1069cd6b5cdeSAxel Dörfler 		BPrintJob printJob(fImageView->Image()->name);
10706163f333SKarsten Heimrich 		if (printJob.ConfigJob() == B_OK)
10716163f333SKarsten Heimrich 			fPrintSettings = printJob.Settings();
10726163f333SKarsten Heimrich 	}
1073780d8a62SMichael Pfeiffer 
1074cd6b5cdeSAxel Dörfler 	fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds());
1075cd6b5cdeSAxel Dörfler 	fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1);
1076780d8a62SMichael Pfeiffer 
1077efa8b4f3SAxel Dörfler 	new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50),
1078efa8b4f3SAxel Dörfler 		&fPrintOptions, this);
1079780d8a62SMichael Pfeiffer }
1080780d8a62SMichael Pfeiffer 
1081efa8b4f3SAxel Dörfler 
1082780d8a62SMichael Pfeiffer void
1083fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg)
1084780d8a62SMichael Pfeiffer {
1085780d8a62SMichael Pfeiffer 	status_t st;
1086efa8b4f3SAxel Dörfler 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1087780d8a62SMichael Pfeiffer 		return;
1088780d8a62SMichael Pfeiffer 
1089fd952aefSRyan Leavengood 	_SavePrintOptions();
1090d3046f7dSMichael Pfeiffer 
1091cd6b5cdeSAxel Dörfler 	BPrintJob printJob(fImageView->Image()->name);
10926163f333SKarsten Heimrich 	if (fPrintSettings)
1093780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
10946163f333SKarsten Heimrich 
1095780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
10966163f333SKarsten Heimrich 		delete fPrintSettings;
10976163f333SKarsten Heimrich 		fPrintSettings = printJob.Settings();
1098780d8a62SMichael Pfeiffer 
1099780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
11003177ae77SStefano Ceccherini 		int32 firstPage = printJob.FirstPage();
11013177ae77SStefano Ceccherini 		int32 lastPage = printJob.LastPage();
11026163f333SKarsten Heimrich 		BRect printableRect = printJob.PrintableRect();
11036163f333SKarsten Heimrich 
1104efa8b4f3SAxel Dörfler 		if (firstPage < 1)
1105780d8a62SMichael Pfeiffer 			firstPage = 1;
1106efa8b4f3SAxel Dörfler 		if (lastPage < firstPage)
1107780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1108780d8a62SMichael Pfeiffer 
1109cd6b5cdeSAxel Dörfler 		BBitmap* bitmap = fImageView->Bitmap();
11103177ae77SStefano Ceccherini 		float imageWidth = bitmap->Bounds().Width() + 1.0;
11113177ae77SStefano Ceccherini 		float imageHeight = bitmap->Bounds().Height() + 1.0;
1112780d8a62SMichael Pfeiffer 
11136163f333SKarsten Heimrich 		float width;
1114780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
11156163f333SKarsten Heimrich 			case PrintOptions::kFitToPage: {
11166163f333SKarsten Heimrich 				float w1 = printableRect.Width()+1;
1117cd6b5cdeSAxel Dörfler 				float w2 = imageWidth * (printableRect.Height() + 1)
1118cd6b5cdeSAxel Dörfler 					/ imageHeight;
1119efa8b4f3SAxel Dörfler 				if (w2 < w1)
1120780d8a62SMichael Pfeiffer 					width = w2;
1121efa8b4f3SAxel Dörfler 				else
1122780d8a62SMichael Pfeiffer 					width = w1;
11236163f333SKarsten Heimrich 			}	break;
1124780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1125780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1126780d8a62SMichael Pfeiffer 				break;
1127780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1128780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1129780d8a62SMichael Pfeiffer 				break;
1130780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1131780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1132780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1133780d8a62SMichael Pfeiffer 				break;
1134efa8b4f3SAxel Dörfler 
1135780d8a62SMichael Pfeiffer 			default:
1136780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1137780d8a62SMichael Pfeiffer 				width = imageWidth;
1138780d8a62SMichael Pfeiffer 		}
1139780d8a62SMichael Pfeiffer 
1140efa8b4f3SAxel Dörfler 		// TODO: eventually print large images on several pages
1141780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1142d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
11435eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
11445eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
11455eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1146d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1147780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1148780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1149780d8a62SMichael Pfeiffer 	}
1150780d8a62SMichael Pfeiffer }
1151780d8a62SMichael Pfeiffer 
115256b0c7b9SKarsten Heimrich 
1153780d8a62SMichael Pfeiffer bool
1154cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1155cdb89ebbSMatthew Wilber {
1156efa8b4f3SAxel Dörfler 	if (fSavePanel) {
1157efa8b4f3SAxel Dörfler 		// Don't allow this window to be closed if a save panel is open
1158efa8b4f3SAxel Dörfler 		return false;
1159cdb89ebbSMatthew Wilber 	}
1160cdb89ebbSMatthew Wilber 
1161fd952aefSRyan Leavengood 	bool quit = _ClosePrompt();
1162efa8b4f3SAxel Dörfler 	if (quit) {
116307caaa8eSMatthew Wilber 		// tell the app to forget about this window
116407caaa8eSMatthew Wilber 		be_app->PostMessage(MSG_WINDOW_QUIT);
116507caaa8eSMatthew Wilber 	}
1166fc0a275bSMatthew Wilber 
1167efa8b4f3SAxel Dörfler 	return quit;
1168efa8b4f3SAxel Dörfler }
1169