xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision 36272f0d4c9b16e96dc8c89552f8f155dbaa9cc9)
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>
37*36272f0dSAxel 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 
78efa8b4f3SAxel 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),
82cd6b5cdeSAxel Dörfler 	fNavigator(this),
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 {
95fd952aefSRyan Leavengood 	_LoadSettings();
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
145cd6b5cdeSAxel Dörfler 	fNavigator.SetTrackerMessenger(trackerMessenger);
146cd6b5cdeSAxel Dörfler 	if (fNavigator.LoadImage(*ref) != B_OK) {
147cd6b5cdeSAxel Dörfler 		_LoadError(*ref);
1485e09d5dbSRyan Leavengood 		Quit();
14901939af6SAxel Dörfler 		return;
150d10d5947SMichael Pfeiffer 	}
151402c09e5SMatthew Wilber 
152d9f6762dSMichael Pfeiffer 	// add View menu here so it can access ShowImageView methods
153ddcb5a2cSAxel Dörfler 	BMenu* menu = new BMenu(B_TRANSLATE_WITH_CONTEXT("View", "Menus"));
154fd952aefSRyan Leavengood 	_BuildViewMenu(menu, false);
155d9f6762dSMichael Pfeiffer 	fBar->AddItem(menu);
156d9f6762dSMichael Pfeiffer 
157d9f6762dSMichael Pfeiffer 	SetPulseRate(100000);
158d9f6762dSMichael Pfeiffer 		// every 1/10 second; ShowImageView needs it for marching ants
159d9f6762dSMichael Pfeiffer 
1606db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SELECTION_MODE,
1616db01936SAxel Dörfler 		fImageView->IsSelectionModeEnabled());
1626db01936SAxel Dörfler 
163402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
164402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
165402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
166cd6b5cdeSAxel Dörfler 
167cd6b5cdeSAxel Dörfler 	// The window will be shown on screen automatically
168cd6b5cdeSAxel Dörfler 	Run();
16913afa642SPhil Greenway }
17013afa642SPhil Greenway 
171efa8b4f3SAxel Dörfler 
17213afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
17313afa642SPhil Greenway {
17413afa642SPhil Greenway }
17513afa642SPhil Greenway 
176efa8b4f3SAxel Dörfler 
177cdb89ebbSMatthew Wilber void
178cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
17913afa642SPhil Greenway {
180cd6b5cdeSAxel Dörfler 	BPath path(fImageView->Image());
181cd6b5cdeSAxel Dörfler 	SetTitle(path.Path());
18213afa642SPhil Greenway }
18313afa642SPhil Greenway 
18456b0c7b9SKarsten Heimrich 
185d9f6762dSMichael Pfeiffer void
186d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu)
187d9f6762dSMichael Pfeiffer {
188fd952aefSRyan Leavengood 	_BuildViewMenu(menu, true);
189d9f6762dSMichael Pfeiffer }
190efa8b4f3SAxel Dörfler 
19156b0c7b9SKarsten Heimrich 
1924eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
1934eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus"
1941ed4535fSStephan Aßmus 
1956046b973SAxel Dörfler 
196cdb89ebbSMatthew Wilber void
197fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
198da87390fSMichael Pfeiffer {
199905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this);
200fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
201905c8c8cSMatt Madia 	BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay"));
202efa8b4f3SAxel Dörfler 	if (fSlideShowDelay == NULL)
203efa8b4f3SAxel Dörfler 		fSlideShowDelay = delayMenu;
204efa8b4f3SAxel Dörfler 
205efa8b4f3SAxel Dörfler 	delayMenu->SetRadioMode(true);
20656b0c7b9SKarsten Heimrich 	// Note: ShowImage loads images in window thread so it becomes unresponsive
20756b0c7b9SKarsten Heimrich 	//		 if slide show delay is too short! (Especially if loading the image
20856b0c7b9SKarsten Heimrich 	//		 takes as long as or longer than the slide show delay). Should load
20956b0c7b9SKarsten Heimrich 	//		 in background thread!
210905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("3 seconds"), 3);
211905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("4 seconds"), 4);
212905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("5 seconds"), 5);
213905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("6 seconds"), 6);
214905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("7 seconds"), 7);
215905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("8 seconds"), 8);
216905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("9 seconds"), 9);
217905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("10 seconds"), 10);
218905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("20 seconds"), 20);
219efa8b4f3SAxel Dörfler 	menu->AddItem(delayMenu);
22030060f17SMatthew Wilber 
221efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
222efa8b4f3SAxel Dörfler 
223905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Original size"),
224905c8c8cSMatt Madia 		MSG_ORIGINAL_SIZE, '1', 0, this);
225905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this);
226905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this);
227efa8b4f3SAxel Dörfler 
228efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
229efa8b4f3SAxel Dörfler 
2304fd570d3SAxel Dörfler 	if (!popupMenu || fFullScreen) {
231905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
232905c8c8cSMatt Madia 			MSG_SCALE_BILINEAR, 0, 0, this);
233efa8b4f3SAxel Dörfler 
234efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
235efa8b4f3SAxel Dörfler 
236905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Shrink to window"),
237905c8c8cSMatt Madia 			MSG_SHRINK_TO_WINDOW, 0, 0, this);
2384fd570d3SAxel Dörfler 		_AddItemMenu(menu, B_TRANSLATE("Stretch to window"),
2394fd570d3SAxel Dörfler 			MSG_STRETCH_TO_WINDOW, 0, 0, this);
240efa8b4f3SAxel Dörfler 
241efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
24232c22143SAxel Dörfler 	}
243efa8b4f3SAxel Dörfler 
244905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Full screen"),
245905c8c8cSMatt Madia 		MSG_FULL_SCREEN, B_ENTER, 0, this);
246fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
247efa8b4f3SAxel Dörfler 
248905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"),
249905c8c8cSMatt Madia 		MSG_SHOW_CAPTION, 0, 0, this);
250fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
251efa8b4f3SAxel Dörfler 
252fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
2536db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, fImageView->ShrinksToBounds());
2546db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_STRETCH_TO_WINDOW, fImageView->StretchesToBounds());
255a60adbf9SAxel Dörfler 
256d9f6762dSMichael Pfeiffer 	if (popupMenu) {
257a60adbf9SAxel Dörfler 		menu->AddSeparatorItem();
258905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
2591ed4535fSStephan Aßmus 			MSG_DESKTOP_BACKGROUND, 0, 0, this);
260d9f6762dSMichael Pfeiffer 	}
261da87390fSMichael Pfeiffer }
262da87390fSMichael Pfeiffer 
263efa8b4f3SAxel Dörfler 
264da87390fSMichael Pfeiffer void
265efa8b4f3SAxel Dörfler ShowImageWindow::AddMenus(BMenuBar* bar)
26613afa642SPhil Greenway {
267905c8c8cSMatt Madia 	BMenu* menu = new BMenu(B_TRANSLATE("File"));
268*36272f0dSAxel Dörfler 
269*36272f0dSAxel Dörfler 	// Add recent files to "Open File" entry as sub-menu.
270*36272f0dSAxel Dörfler 	BMenuItem* item = new BMenuItem(BRecentFilesList::NewFileListMenu(
271*36272f0dSAxel Dörfler 		B_TRANSLATE("Open"B_UTF8_ELLIPSIS), NULL, NULL, be_app, 10, true,
272*36272f0dSAxel Dörfler 		NULL, kApplicationSignature), new BMessage(MSG_FILE_OPEN));
273*36272f0dSAxel Dörfler 	item->SetShortcut('O', 0);
274*36272f0dSAxel Dörfler 	item->SetTarget(be_app);
275*36272f0dSAxel Dörfler 	menu->AddItem(item);
276efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
277*36272f0dSAxel Dörfler 
2786db01936SAxel Dörfler 	BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS),
2791ed4535fSStephan Aßmus 		B_ITEMS_IN_COLUMN);
2806db01936SAxel Dörfler 	BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP);
281fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
282fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
2836db01936SAxel Dörfler 	menu->AddItem(menuSaveAs);
284905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this);
285efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
286905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS),
2871ed4535fSStephan Aßmus 		MSG_PAGE_SETUP, 0, 0, this);
288905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS),
2891ed4535fSStephan Aßmus 		MSG_PREPARE_PRINT, 'P', 0, this);
290efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
291905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("About ShowImage" B_UTF8_ELLIPSIS),
2921ed4535fSStephan Aßmus 		B_ABOUT_REQUESTED, 0, 0, be_app);
293efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
294905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app);
295efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
29613afa642SPhil Greenway 
297905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Edit"));
298905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Undo"), B_UNDO, 'Z', 0, this, false);
299efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
300905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false);
301efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
3026db01936SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Selection Mode"), MSG_SELECTION_MODE, 0, 0,
3036db01936SAxel Dörfler 		this);
30432c22143SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Clear selection"),
30532c22143SAxel Dörfler 		MSG_CLEAR_SELECT, 0, 0, this, false);
306905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Select all"),
307905c8c8cSMatt Madia 		MSG_SELECT_ALL, 'A', 0, this);
308efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
30913afa642SPhil Greenway 
310905c8c8cSMatt Madia 	menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse"));
311905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("First page"),
3121ed4535fSStephan Aßmus 		MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this);
313905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Last page"),
3141ed4535fSStephan Aßmus 		MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this);
315905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous page"),
316905c8c8cSMatt Madia 		MSG_PAGE_PREV, B_LEFT_ARROW, 0, this);
317905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next page"),
318905c8c8cSMatt Madia 		MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this);
319905c8c8cSMatt Madia 	fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page"));
3205e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
321efa8b4f3SAxel Dörfler 	menu->AddItem(fGoToPageMenu);
322efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
323905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous file"),
324905c8c8cSMatt Madia 		MSG_FILE_PREV, B_UP_ARROW, 0, this);
325905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next file"),
326905c8c8cSMatt Madia 		MSG_FILE_NEXT, B_DOWN_ARROW, 0, this);
327efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
32803839579SMatthew Wilber 
329905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Image"));
330905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"),
331905c8c8cSMatt Madia 		MSG_ROTATE_90, 'R', 0, this);
332905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"),
3331ed4535fSStephan Aßmus 		MSG_ROTATE_270, 'R', B_SHIFT_KEY, this);
334efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
335905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip left to right"),
3361ed4535fSStephan Aßmus 		MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this);
337905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"),
3381ed4535fSStephan Aßmus 		MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this);
339efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
340905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
3411ed4535fSStephan Aßmus 		MSG_DESKTOP_BACKGROUND, 0, 0, this);
34204f96544SAxel Dörfler 
34304f96544SAxel Dörfler 	bar->AddItem(menu);
34413afa642SPhil Greenway }
34513afa642SPhil Greenway 
346efa8b4f3SAxel Dörfler 
347cdb89ebbSMatthew Wilber BMenuItem*
348fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what,
3494fd570d3SAxel Dörfler 	char shortcut, uint32 modifier, const BHandler* target, bool enabled)
350cdb89ebbSMatthew Wilber {
3514fd570d3SAxel Dörfler 	BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut,
3524fd570d3SAxel Dörfler 		modifier);
353efa8b4f3SAxel Dörfler 	menu->AddItem(item);
354efa8b4f3SAxel Dörfler 
3556163f333SKarsten Heimrich 	item->SetTarget(target);
3566163f333SKarsten Heimrich 	item->SetEnabled(enabled);
3576163f333SKarsten Heimrich 
358efa8b4f3SAxel Dörfler 	return item;
35913afa642SPhil Greenway }
36013afa642SPhil Greenway 
361efa8b4f3SAxel Dörfler 
362ad13f387SMichael Pfeiffer BMenuItem*
363fd952aefSRyan Leavengood ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, float value)
364ad13f387SMichael Pfeiffer {
365efa8b4f3SAxel Dörfler 	BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
366efa8b4f3SAxel Dörfler 	message->AddFloat("value", value);
367ad13f387SMichael Pfeiffer 
3686163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, message, 0);
369efa8b4f3SAxel Dörfler 	item->SetTarget(this);
370ad13f387SMichael Pfeiffer 
371d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
372efa8b4f3SAxel Dörfler 	if (marked)
373efa8b4f3SAxel Dörfler 		item->SetMarked(true);
374ad13f387SMichael Pfeiffer 
375efa8b4f3SAxel Dörfler 	menu->AddItem(item);
376efa8b4f3SAxel Dörfler 	return item;
377ad13f387SMichael Pfeiffer }
378ad13f387SMichael Pfeiffer 
379efa8b4f3SAxel Dörfler 
380cdb89ebbSMatthew Wilber void
3811076d97bSAxel Dörfler ShowImageWindow::WindowRedimension(BBitmap* bitmap)
38213afa642SPhil Greenway {
383d10d5947SMichael Pfeiffer 	BScreen screen;
38471a34702SAxel Dörfler 	if (!screen.IsValid())
385efa8b4f3SAxel Dörfler 		return;
386efa8b4f3SAxel Dörfler 
3871076d97bSAxel Dörfler 	// TODO: use View::GetPreferredSize() instead?
3881076d97bSAxel Dörfler 	BRect r(bitmap->Bounds());
3891076d97bSAxel Dörfler 	float width = r.Width() + B_V_SCROLL_BAR_WIDTH;
3901076d97bSAxel Dörfler 	float height = r.Height() + 1 + fBar->Frame().Height()
3911076d97bSAxel Dörfler 		+ B_H_SCROLL_BAR_HEIGHT;
392cdb89ebbSMatthew Wilber 
3936163f333SKarsten Heimrich 	BRect frame = screen.Frame();
3946163f333SKarsten Heimrich 	const float windowBorder = 5;
395d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
3966163f333SKarsten Heimrich 	float maxWidth = frame.Width() + 1 - windowBorder - Frame().left;
3976163f333SKarsten Heimrich 	float maxHeight = frame.Height() + 1 - windowBorder - Frame().top;
398cdb89ebbSMatthew Wilber 
399a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
400a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
401efa8b4f3SAxel Dörfler 
402fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
403a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
404efa8b4f3SAxel Dörfler 	if (maxWidth > maxW)
405efa8b4f3SAxel Dörfler 		maxWidth = maxW;
406efa8b4f3SAxel Dörfler 	if (maxHeight > maxH)
407efa8b4f3SAxel Dörfler 		maxHeight = maxH;
408efa8b4f3SAxel Dörfler 	if (width < minW)
409efa8b4f3SAxel Dörfler 		width = minW;
410efa8b4f3SAxel Dörfler 	if (height < minH)
411efa8b4f3SAxel Dörfler 		height = minH;
412a8fc7138SMichael Pfeiffer 
413efa8b4f3SAxel Dörfler 	if (width > maxWidth)
414efa8b4f3SAxel Dörfler 		width = maxWidth;
415efa8b4f3SAxel Dörfler 	if (height > maxHeight)
416efa8b4f3SAxel Dörfler 		height = maxHeight;
417d10d5947SMichael Pfeiffer 
418d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
41913afa642SPhil Greenway }
42013afa642SPhil Greenway 
421efa8b4f3SAxel Dörfler 
422cdb89ebbSMatthew Wilber void
423cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
42413afa642SPhil Greenway {
4256163f333SKarsten Heimrich 	BWindow::FrameResized(width, height);
42613afa642SPhil Greenway }
42713afa642SPhil Greenway 
428efa8b4f3SAxel Dörfler 
4297eca0987SMichael Pfeiffer bool
430fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what)
4317eca0987SMichael Pfeiffer {
4327eca0987SMichael Pfeiffer 	bool marked = false;
4336163f333SKarsten Heimrich 	BMenuItem* item = fBar->FindItem(what);
4347eca0987SMichael Pfeiffer 	if (item != NULL) {
4357eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
4367eca0987SMichael Pfeiffer 		item->SetMarked(marked);
4377eca0987SMichael Pfeiffer 	}
4387eca0987SMichael Pfeiffer 	return marked;
4397eca0987SMichael Pfeiffer }
4407eca0987SMichael Pfeiffer 
441efa8b4f3SAxel Dörfler 
442cdb89ebbSMatthew Wilber void
443fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable)
444e6a50d9cSMichael Pfeiffer {
4456163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
4466163f333SKarsten Heimrich 	if (item && item->IsEnabled() != enable)
447e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
448e6a50d9cSMichael Pfeiffer }
449e6a50d9cSMichael Pfeiffer 
450efa8b4f3SAxel Dörfler 
451e6a50d9cSMichael Pfeiffer void
452fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked)
453e6a50d9cSMichael Pfeiffer {
4546163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
4556163f333SKarsten Heimrich 	if (item && item->IsMarked() != marked)
456e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
457e6a50d9cSMichael Pfeiffer }
458e6a50d9cSMichael Pfeiffer 
459efa8b4f3SAxel Dörfler 
460da87390fSMichael Pfeiffer void
461fd952aefSRyan Leavengood ShowImageWindow::_MarkSlideShowDelay(float value)
462da87390fSMichael Pfeiffer {
463d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
464da87390fSMichael Pfeiffer 	float v;
465da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
466d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
467da87390fSMichael Pfeiffer 		if (item) {
468da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
4696163f333SKarsten Heimrich 				if (!item->IsMarked())
470da87390fSMichael Pfeiffer 					item->SetMarked(true);
471da87390fSMichael Pfeiffer 				return;
472da87390fSMichael Pfeiffer 			}
473da87390fSMichael Pfeiffer 		}
474da87390fSMichael Pfeiffer 	}
475da87390fSMichael Pfeiffer }
476e6a50d9cSMichael Pfeiffer 
47719c76de4SMichael Pfeiffer 
47819c76de4SMichael Pfeiffer void
479fd952aefSRyan Leavengood ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what)
48019c76de4SMichael Pfeiffer {
481fd952aefSRyan Leavengood 	bool enabled = _ToggleMenuItem(what);
4826163f333SKarsten Heimrich 	if (shrink)
483d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
4846163f333SKarsten Heimrich 	else
4854fd570d3SAxel Dörfler 		fImageView->SetStretchToBounds(enabled);
48619c76de4SMichael Pfeiffer }
48719c76de4SMichael Pfeiffer 
488efa8b4f3SAxel Dörfler 
489e6a50d9cSMichael Pfeiffer void
490efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message)
49113afa642SPhil Greenway {
492efa8b4f3SAxel Dörfler 	switch (message->what) {
493cd6b5cdeSAxel Dörfler 		case kMsgImageLoaded:
494cd6b5cdeSAxel Dörfler 		{
495cd6b5cdeSAxel Dörfler 			bool first = fImageView->Bitmap() == NULL;
496cd6b5cdeSAxel Dörfler 
497cd6b5cdeSAxel Dörfler 			status_t status = fImageView->SetImage(message);
498cd6b5cdeSAxel Dörfler 			if (status != B_OK) {
499cd6b5cdeSAxel Dörfler 				entry_ref ref;
500cd6b5cdeSAxel Dörfler 				message->FindRef("ref", &ref);
501cd6b5cdeSAxel Dörfler 
502cd6b5cdeSAxel Dörfler 				_LoadError(ref);
503cd6b5cdeSAxel Dörfler 
504cd6b5cdeSAxel Dörfler 				// quit if file could not be opened
505cd6b5cdeSAxel Dörfler 				if (first)
506cd6b5cdeSAxel Dörfler 					Quit();
507cd6b5cdeSAxel Dörfler 				break;
508cd6b5cdeSAxel Dörfler 			}
509cd6b5cdeSAxel Dörfler 
510cd6b5cdeSAxel Dörfler 			fImageType = message->FindString("type");
511cd6b5cdeSAxel Dörfler 
512cd6b5cdeSAxel Dörfler 			if (first) {
513cd6b5cdeSAxel Dörfler 				WindowRedimension(fImageView->Bitmap());
514cd6b5cdeSAxel Dörfler 				fImageView->ResetZoom();
515cd6b5cdeSAxel Dörfler 				fImageView->MakeFocus(true);
516cd6b5cdeSAxel Dörfler 					// to receive key messages
517cd6b5cdeSAxel Dörfler 
518cd6b5cdeSAxel Dörfler 				Show();
519cd6b5cdeSAxel Dörfler 			} else {
520cd6b5cdeSAxel Dörfler 				if (!fImageView->StretchesToBounds()
521cd6b5cdeSAxel Dörfler 					&& !fImageView->ShrinksToBounds()
522cd6b5cdeSAxel Dörfler 					&& !fFullScreen)
523cd6b5cdeSAxel Dörfler 					WindowRedimension(fImageView->Bitmap());
524cd6b5cdeSAxel Dörfler 			}
525cd6b5cdeSAxel Dörfler 			break;
526cd6b5cdeSAxel Dörfler 		}
527cd6b5cdeSAxel Dörfler 
528ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
529ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
530ee7b4f39SMatthew Wilber 			fModified = true;
531ee7b4f39SMatthew Wilber 			break;
532ee7b4f39SMatthew Wilber 
533fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
534fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
535d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
536cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
537fd952aefSRyan Leavengood 				_SaveAs(message);
53813afa642SPhil Greenway 			break;
539fc0a275bSMatthew Wilber 
540fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
541fc0a275bSMatthew Wilber 			// User specified where to save the output image
542fd952aefSRyan Leavengood 			_SaveToFile(message);
54307caaa8eSMatthew Wilber 			break;
54407caaa8eSMatthew Wilber 
545cdb89ebbSMatthew Wilber 		case B_CANCEL:
546d3046f7dSMichael Pfeiffer 			delete fSavePanel;
547d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
548cdb89ebbSMatthew Wilber 			break;
549cdb89ebbSMatthew Wilber 
5506db01936SAxel Dörfler 		case MSG_UPDATE_STATUS:
5516db01936SAxel Dörfler 		{
552cd6b5cdeSAxel Dörfler 			int32 pages = fNavigator.PageCount();
553cd6b5cdeSAxel Dörfler 			int32 currentPage = fNavigator.CurrentPage();
5546c305411SMatthew Wilber 
555cd6b5cdeSAxel Dörfler 			bool enable = pages > 1 ? true : false;
55636c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_FIRST, enable);
55736c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_LAST, enable);
55836c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_NEXT, enable);
55936c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_PREV, enable);
56036c17651SRyan Leavengood 			fGoToPageMenu->SetEnabled(enable);
5611d592070SMatthew Wilber 
562cd6b5cdeSAxel Dörfler 			_EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile());
563cd6b5cdeSAxel Dörfler 			_EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile());
564134d6076SMichael Pfeiffer 
565d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
5666c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
5676c305411SMatthew Wilber 				// pages is different
5686c305411SMatthew Wilber 
569cd6b5cdeSAxel Dörfler 				while (fGoToPageMenu->CountItems() > 0) {
5706c305411SMatthew Wilber 					// Remove all page numbers
571d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
572cd6b5cdeSAxel Dörfler 				}
5736c305411SMatthew Wilber 
574780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
5756c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
576cd6b5cdeSAxel Dörfler 					BMessage* goTo = new BMessage(MSG_GOTO_PAGE);
577cd6b5cdeSAxel Dörfler 					goTo->AddInt32("page", i);
5786163f333SKarsten Heimrich 
5796163f333SKarsten Heimrich 					char shortcut = 0;
580cd6b5cdeSAxel Dörfler 					if (i < 10)
581780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
5826163f333SKarsten Heimrich 
5836163f333SKarsten Heimrich 					BString strCaption;
5846163f333SKarsten Heimrich 					strCaption << i;
5856163f333SKarsten Heimrich 
586cd6b5cdeSAxel Dörfler 					BMenuItem* item = new BMenuItem(strCaption.String(), goTo,
587ddcb5a2cSAxel Dörfler 						B_SHIFT_KEY, shortcut);
588cd6b5cdeSAxel Dörfler 					if (currentPage == i)
589efa8b4f3SAxel Dörfler 						item->SetMarked(true);
590efa8b4f3SAxel Dörfler 					fGoToPageMenu->AddItem(item);
5916c305411SMatthew Wilber 				}
5926c305411SMatthew Wilber 			} else {
5936c305411SMatthew Wilber 				// Make sure the correct page is marked
594cd6b5cdeSAxel Dörfler 				BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
595cd6b5cdeSAxel Dörfler 				if (currentItem != NULL && !currentItem->IsMarked())
596cd6b5cdeSAxel Dörfler 					currentItem->SetMarked(true);
5976c305411SMatthew Wilber 			}
5986c305411SMatthew Wilber 
599cd6b5cdeSAxel Dörfler 			_UpdateStatusText(message);
6007eca0987SMichael Pfeiffer 			UpdateTitle();
6016db01936SAxel Dörfler 			break;
6026db01936SAxel Dörfler 		}
60303839579SMatthew Wilber 
6046db01936SAxel Dörfler 		case MSG_UPDATE_STATUS_TEXT:
6056db01936SAxel Dörfler 		{
606cd6b5cdeSAxel Dörfler 			_UpdateStatusText(message);
6076db01936SAxel Dörfler 			break;
6086db01936SAxel Dörfler 		}
6098f5fd23fSRyan Leavengood 
6106db01936SAxel Dörfler 		case MSG_SELECTION:
6116db01936SAxel Dörfler 		{
6128ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
6138ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
6148ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
6156db01936SAxel Dörfler 			bool enable;
6166db01936SAxel Dörfler 			if (message->FindBool("has_selection", &enable) == B_OK) {
6176db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_COPY, enable);
6186db01936SAxel Dörfler 				_EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable);
6198ad30bcfSMatthew Wilber 			}
6206db01936SAxel Dörfler 			break;
6216db01936SAxel Dörfler 		}
6228ad30bcfSMatthew Wilber 
6236db01936SAxel Dörfler 		case MSG_UNDO_STATE:
6246db01936SAxel Dörfler 		{
6256db01936SAxel Dörfler 			bool enable;
6266db01936SAxel Dörfler 			if (message->FindBool("can_undo", &enable) == B_OK)
6276db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_UNDO, enable);
6286db01936SAxel Dörfler 			break;
6296db01936SAxel Dörfler 		}
630402c09e5SMatthew Wilber 
63113afa642SPhil Greenway 		case B_UNDO:
6327598450eSMatthew Wilber 			fImageView->Undo();
63313afa642SPhil Greenway 			break;
6346163f333SKarsten Heimrich 
63513afa642SPhil Greenway 		case B_COPY:
636d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
63713afa642SPhil Greenway 			break;
6386163f333SKarsten Heimrich 
6396db01936SAxel Dörfler 		case MSG_SELECTION_MODE:
6406db01936SAxel Dörfler 			fImageView->SetSelectionMode(_ToggleMenuItem(MSG_SELECTION_MODE));
6416db01936SAxel Dörfler 			break;
6426db01936SAxel Dörfler 
64313afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
644d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
64513afa642SPhil Greenway 			break;
6466163f333SKarsten Heimrich 
64713afa642SPhil Greenway 		case MSG_SELECT_ALL:
648d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
64913afa642SPhil Greenway 			break;
65013afa642SPhil Greenway 
65103839579SMatthew Wilber 		case MSG_PAGE_FIRST:
652fd952aefSRyan Leavengood 			if (_ClosePrompt())
653cd6b5cdeSAxel Dörfler 				fNavigator.FirstPage();
65403839579SMatthew Wilber 			break;
65503839579SMatthew Wilber 
65603839579SMatthew Wilber 		case MSG_PAGE_LAST:
657fd952aefSRyan Leavengood 			if (_ClosePrompt())
658cd6b5cdeSAxel Dörfler 				fNavigator.LastPage();
65903839579SMatthew Wilber 			break;
66003839579SMatthew Wilber 
66103839579SMatthew Wilber 		case MSG_PAGE_NEXT:
662fd952aefSRyan Leavengood 			if (_ClosePrompt())
663cd6b5cdeSAxel Dörfler 				fNavigator.NextPage();
66403839579SMatthew Wilber 			break;
66503839579SMatthew Wilber 
66603839579SMatthew Wilber 		case MSG_PAGE_PREV:
667fd952aefSRyan Leavengood 			if (_ClosePrompt())
668cd6b5cdeSAxel Dörfler 				fNavigator.PreviousPage();
66903839579SMatthew Wilber 			break;
67003839579SMatthew Wilber 
671cd6b5cdeSAxel Dörfler 		case MSG_GOTO_PAGE:
672cd6b5cdeSAxel Dörfler 		{
673fd952aefSRyan Leavengood 			if (!_ClosePrompt())
674ee7b4f39SMatthew Wilber 				break;
675ee7b4f39SMatthew Wilber 
6766163f333SKarsten Heimrich 			int32 newPage;
6776163f333SKarsten Heimrich 			if (message->FindInt32("page", &newPage) != B_OK)
6786163f333SKarsten Heimrich 				break;
6796163f333SKarsten Heimrich 
680cd6b5cdeSAxel Dörfler 			int32 currentPage = fNavigator.CurrentPage();
681cd6b5cdeSAxel Dörfler 			int32 pages = fNavigator.PageCount();
6826c305411SMatthew Wilber 
6836c305411SMatthew Wilber 			if (newPage > 0 && newPage <= pages) {
684cd6b5cdeSAxel Dörfler 				BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
685cd6b5cdeSAxel Dörfler 				BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1);
686cd6b5cdeSAxel Dörfler 				if (currentItem != NULL && newItem != NULL) {
687cd6b5cdeSAxel Dörfler 					currentItem->SetMarked(false);
688cd6b5cdeSAxel Dörfler 					newItem->SetMarked(true);
689cd6b5cdeSAxel Dörfler 					fNavigator.GoToPage(newPage);
6906c305411SMatthew Wilber 				}
6916c305411SMatthew Wilber 			}
692cd6b5cdeSAxel Dörfler 			break;
693cd6b5cdeSAxel Dörfler 		}
6946c305411SMatthew Wilber 
69519c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
696fd952aefSRyan Leavengood 			_ResizeToWindow(true, message->what);
69719c76de4SMichael Pfeiffer 			break;
6986163f333SKarsten Heimrich 
6994fd570d3SAxel Dörfler 		case MSG_STRETCH_TO_WINDOW:
700fd952aefSRyan Leavengood 			_ResizeToWindow(false, message->what);
7017eca0987SMichael Pfeiffer 			break;
7027eca0987SMichael Pfeiffer 
7037eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
704fd952aefSRyan Leavengood 			if (_ClosePrompt())
705cd6b5cdeSAxel Dörfler 				fNavigator.PreviousFile();
7067eca0987SMichael Pfeiffer 			break;
7077eca0987SMichael Pfeiffer 
7087eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
709fd952aefSRyan Leavengood 			if (_ClosePrompt())
710cd6b5cdeSAxel Dörfler 				fNavigator.NextFile();
71113afa642SPhil Greenway 			break;
71213afa642SPhil Greenway 
713bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
714d3046f7dSMichael Pfeiffer 			fImageView->Rotate(90);
715ad13f387SMichael Pfeiffer 			break;
7166163f333SKarsten Heimrich 
717bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
718d3046f7dSMichael Pfeiffer 			fImageView->Rotate(270);
719ad13f387SMichael Pfeiffer 			break;
7206163f333SKarsten Heimrich 
72169eee339SRyan Leavengood 		case MSG_FLIP_LEFT_TO_RIGHT:
72261ddc257SRyan Leavengood 			fImageView->Flip(true);
723ad13f387SMichael Pfeiffer 			break;
7246163f333SKarsten Heimrich 
72569eee339SRyan Leavengood 		case MSG_FLIP_TOP_TO_BOTTOM:
72661ddc257SRyan Leavengood 			fImageView->Flip(false);
727ad13f387SMichael Pfeiffer 			break;
7286163f333SKarsten Heimrich 
7291076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW:
7301076d97bSAxel Dörfler 		{
7316163f333SKarsten Heimrich 			BMenuItem* item = fBar->FindItem(message->what);
732ee7b4f39SMatthew Wilber 			if (!item)
733ee7b4f39SMatthew Wilber 				break;
734ee7b4f39SMatthew Wilber 			if (item->IsMarked()) {
735ee7b4f39SMatthew Wilber 				item->SetMarked(false);
736d3046f7dSMichael Pfeiffer 				fImageView->StopSlideShow();
737fd952aefSRyan Leavengood 			} else if (_ClosePrompt()) {
738ee7b4f39SMatthew Wilber 				item->SetMarked(true);
739ee7b4f39SMatthew Wilber 				fImageView->StartSlideShow();
740ad13f387SMichael Pfeiffer 			}
7411076d97bSAxel Dörfler 			break;
7421076d97bSAxel Dörfler 		}
743ee7b4f39SMatthew Wilber 
7441076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW_DELAY:
7451076d97bSAxel Dörfler 		{
746ad13f387SMichael Pfeiffer 			float value;
747efa8b4f3SAxel Dörfler 			if (message->FindFloat("value", &value) == B_OK) {
748d3046f7dSMichael Pfeiffer 				fImageView->SetSlideShowDelay(value);
749da87390fSMichael Pfeiffer 				// in case message is sent from popup menu
750fd952aefSRyan Leavengood 				_MarkSlideShowDelay(value);
751ad13f387SMichael Pfeiffer 			}
7521076d97bSAxel Dörfler 			break;
7531076d97bSAxel Dörfler 		}
754ad13f387SMichael Pfeiffer 
755ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
756fd952aefSRyan Leavengood 			_ToggleFullScreen();
757ad13f387SMichael Pfeiffer 			break;
7586163f333SKarsten Heimrich 
759fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
760fc5ca95dSStephan Aßmus 			if (fFullScreen)
761fd952aefSRyan Leavengood 				_ToggleFullScreen();
762fc5ca95dSStephan Aßmus 			break;
7636163f333SKarsten Heimrich 
7646163f333SKarsten Heimrich 		case MSG_SHOW_CAPTION: {
765fd952aefSRyan Leavengood 			fShowCaption = _ToggleMenuItem(message->what);
766efa8b4f3SAxel Dörfler 			ShowImageSettings* settings = my_app->Settings();
767efa8b4f3SAxel Dörfler 
768d3046f7dSMichael Pfeiffer 			if (settings->Lock()) {
769d3046f7dSMichael Pfeiffer 				settings->SetBool("ShowCaption", fShowCaption);
770d3046f7dSMichael Pfeiffer 				settings->Unlock();
771d3046f7dSMichael Pfeiffer 			}
772efa8b4f3SAxel Dörfler 			if (fFullScreen)
773d3046f7dSMichael Pfeiffer 				fImageView->SetShowCaption(fShowCaption);
7746163f333SKarsten Heimrich 		}	break;
775ad13f387SMichael Pfeiffer 
776780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
777fd952aefSRyan Leavengood 			_PageSetup();
778780d8a62SMichael Pfeiffer 			break;
7796163f333SKarsten Heimrich 
780780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
781fd952aefSRyan Leavengood 			_PrepareForPrint();
782780d8a62SMichael Pfeiffer 			break;
7836163f333SKarsten Heimrich 
784780d8a62SMichael Pfeiffer 		case MSG_PRINT:
785fd952aefSRyan Leavengood 			_Print(message);
786780d8a62SMichael Pfeiffer 			break;
787780d8a62SMichael Pfeiffer 
788780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
789d3046f7dSMichael Pfeiffer 			fImageView->ZoomIn();
790780d8a62SMichael Pfeiffer 			break;
7916163f333SKarsten Heimrich 
792780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
793d3046f7dSMichael Pfeiffer 			fImageView->ZoomOut();
794780d8a62SMichael Pfeiffer 			break;
7956163f333SKarsten Heimrich 
796780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
7974fd570d3SAxel Dörfler 			fImageView->SetZoom(1.0);
798780d8a62SMichael Pfeiffer 			break;
7996163f333SKarsten Heimrich 
80081b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
801fd952aefSRyan Leavengood 			fImageView->SetScaleBilinear(_ToggleMenuItem(message->what));
80281b9c776SMichael Pfeiffer 			break;
803780d8a62SMichael Pfeiffer 
804cd6b5cdeSAxel Dörfler 		case MSG_DESKTOP_BACKGROUND:
805cd6b5cdeSAxel Dörfler 		{
8060a74004cSRyan Leavengood 			BMessage message(B_REFS_RECEIVED);
8070a74004cSRyan Leavengood 			message.AddRef("refs", fImageView->Image());
8080a74004cSRyan Leavengood 			// This is used in the Backgrounds code for scaled placement
8090a74004cSRyan Leavengood 			message.AddInt32("placement", 'scpl');
8100a74004cSRyan Leavengood 			be_roster->Launch("application/x-vnd.haiku-backgrounds", &message);
811cd6b5cdeSAxel Dörfler 			break;
812cd6b5cdeSAxel Dörfler 		}
813a60adbf9SAxel Dörfler 
81413afa642SPhil Greenway 		default:
815efa8b4f3SAxel Dörfler 			BWindow::MessageReceived(message);
81613afa642SPhil Greenway 			break;
81713afa642SPhil Greenway 	}
81813afa642SPhil Greenway }
819fc0a275bSMatthew Wilber 
820efa8b4f3SAxel Dörfler 
821fc0a275bSMatthew Wilber void
822cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message)
823cd6b5cdeSAxel Dörfler {
824cd6b5cdeSAxel Dörfler 	BString status;
825cd6b5cdeSAxel Dörfler 	if (fImageView->Bitmap() != NULL) {
826cd6b5cdeSAxel Dörfler 		BRect bounds = fImageView->Bitmap()->Bounds();
827cd6b5cdeSAxel Dörfler 		status << bounds.IntegerWidth() + 1
828cd6b5cdeSAxel Dörfler 			<< "x" << bounds.IntegerHeight() + 1 << ", " << fImageType;
829cd6b5cdeSAxel Dörfler 	}
830cd6b5cdeSAxel Dörfler 
831cd6b5cdeSAxel Dörfler 	BString text;
832cd6b5cdeSAxel Dörfler 	if (message != NULL && message->FindString("status", &text) == B_OK
833cd6b5cdeSAxel Dörfler 		&& text.Length() > 0) {
834cd6b5cdeSAxel Dörfler 		status << ", " << text;
835cd6b5cdeSAxel Dörfler 	}
836cd6b5cdeSAxel Dörfler 
837cd6b5cdeSAxel Dörfler 	fStatusView->SetText(status);
838cd6b5cdeSAxel Dörfler }
839cd6b5cdeSAxel Dörfler 
840cd6b5cdeSAxel Dörfler 
841cd6b5cdeSAxel Dörfler void
842cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref)
843cd6b5cdeSAxel Dörfler {
844cd6b5cdeSAxel Dörfler 	// TODO: give a better error message!
845cd6b5cdeSAxel Dörfler 	BAlert* alert = new BAlert(B_TRANSLATE("ShowImage"),
846ddcb5a2cSAxel Dörfler 		B_TRANSLATE_WITH_CONTEXT("Could not load image! Either the "
847ddcb5a2cSAxel Dörfler 			"file or an image translator for it does not exist.",
848ddcb5a2cSAxel Dörfler 			"LoadAlerts"),
849ddcb5a2cSAxel Dörfler 		B_TRANSLATE_WITH_CONTEXT("OK", "Alerts"), NULL, NULL,
850cd6b5cdeSAxel Dörfler 		B_WIDTH_AS_USUAL, B_INFO_ALERT);
851cd6b5cdeSAxel Dörfler 	alert->Go();
852cd6b5cdeSAxel Dörfler }
853cd6b5cdeSAxel Dörfler 
854cd6b5cdeSAxel Dörfler 
855cd6b5cdeSAxel Dörfler void
856fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message)
857fc0a275bSMatthew Wilber {
858cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
859cdb89ebbSMatthew Wilber 	translator_id outTranslator;
860cdb89ebbSMatthew Wilber 	uint32 outType;
8616163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
862efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
8636163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
864cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
865fc0a275bSMatthew Wilber 		return;
866fc0a275bSMatthew Wilber 
867cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
868cdb89ebbSMatthew Wilber 	// message that the save panel will send back
869c1a10c14SKarsten Heimrich 	BMessage panelMsg(MSG_SAVE_PANEL);
870c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTranslatorField, outTranslator);
871c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTypeField, outType);
872cdb89ebbSMatthew Wilber 
873cdb89ebbSMatthew Wilber 	// Create save panel and show it
8746163f333SKarsten Heimrich 	BMessenger target(this);
875efa8b4f3SAxel Dörfler 	fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
876c1a10c14SKarsten Heimrich 		&target, NULL, 0, false, &panelMsg);
877d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
878fc0a275bSMatthew Wilber 		return;
879a60adbf9SAxel Dörfler 
880d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
881d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
882fc0a275bSMatthew Wilber }
883fc0a275bSMatthew Wilber 
884efa8b4f3SAxel Dörfler 
885fc0a275bSMatthew Wilber void
886fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message)
887fc0a275bSMatthew Wilber {
888cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
889efa8b4f3SAxel Dörfler 	entry_ref dirRef;
890efa8b4f3SAxel Dörfler 	if (message->FindRef("directory", &dirRef) != B_OK)
891fc0a275bSMatthew Wilber 		return;
892efa8b4f3SAxel Dörfler 
893fc0a275bSMatthew Wilber 	const char* filename;
894efa8b4f3SAxel Dörfler 	if (message->FindString("name", &filename) != B_OK)
895fc0a275bSMatthew Wilber 		return;
896fc0a275bSMatthew Wilber 
897cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
898cdb89ebbSMatthew Wilber 	// to save the output image
899cdb89ebbSMatthew Wilber 	translator_id outTranslator;
900cdb89ebbSMatthew Wilber 	uint32 outType;
9016163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
902efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9036163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
904cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
905cdb89ebbSMatthew Wilber 		return;
906cdb89ebbSMatthew Wilber 
907a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
908a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
909a7e78e3bSMatthew Wilber 	BTranslatorRoster* roster = BTranslatorRoster::Default();
910efa8b4f3SAxel Dörfler 	const translation_format* outFormat = NULL;
911efa8b4f3SAxel Dörfler 	int32 outCount = 0;
912efa8b4f3SAxel Dörfler 	if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
913efa8b4f3SAxel Dörfler 		|| outCount < 1)
914a7e78e3bSMatthew Wilber 		return;
915efa8b4f3SAxel Dörfler 
916a7e78e3bSMatthew Wilber 	int32 i;
917efa8b4f3SAxel Dörfler 	for (i = 0; i < outCount; i++) {
918efa8b4f3SAxel Dörfler 		if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
919a7e78e3bSMatthew Wilber 			break;
920a7e78e3bSMatthew Wilber 	}
921efa8b4f3SAxel Dörfler 	if (i == outCount)
922fc0a275bSMatthew Wilber 		return;
923fc0a275bSMatthew Wilber 
924a7e78e3bSMatthew Wilber 	// Write out the image file
925efa8b4f3SAxel Dörfler 	BDirectory dir(&dirRef);
926efa8b4f3SAxel Dörfler 	fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
927fc0a275bSMatthew Wilber }
928fc0a275bSMatthew Wilber 
929efa8b4f3SAxel Dörfler 
9304eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
9314eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "ClosePrompt"
9321ed4535fSStephan Aßmus 
933cdb89ebbSMatthew Wilber bool
934fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt()
935ee7b4f39SMatthew Wilber {
936ee7b4f39SMatthew Wilber 	if (!fModified)
937ee7b4f39SMatthew Wilber 		return true;
938efa8b4f3SAxel Dörfler 
939cd6b5cdeSAxel Dörfler 	int32 count = fNavigator.PageCount();
940cd6b5cdeSAxel Dörfler 	int32 page = fNavigator.CurrentPage();
941cd6b5cdeSAxel Dörfler 	BString prompt;
942efa8b4f3SAxel Dörfler 
9431ed4535fSStephan Aßmus 	if (count > 1) {
9441ed4535fSStephan Aßmus 		bs_printf(&prompt,
945905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' (page %d) has been changed. Do you "
946905c8c8cSMatt Madia 				"want to close the document?"),
947cd6b5cdeSAxel Dörfler 			fImageView->Image()->name, page);
9481ed4535fSStephan Aßmus 	} else {
9491ed4535fSStephan Aßmus 		bs_printf(&prompt,
950905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' has been changed. Do you want to "
951905c8c8cSMatt Madia 				"close the document?"),
952cd6b5cdeSAxel Dörfler 			fImageView->Image()->name);
9531ed4535fSStephan Aßmus 	}
9541ed4535fSStephan Aßmus 
955cd6b5cdeSAxel Dörfler 	BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(),
956905c8c8cSMatt Madia 		B_TRANSLATE("Cancel"), B_TRANSLATE("Close"));
957cd6b5cdeSAxel Dörfler 	if (alert->Go() == 0) {
958ee7b4f39SMatthew Wilber 		// Cancel
959ee7b4f39SMatthew Wilber 		return false;
960cd6b5cdeSAxel Dörfler 	}
961cd6b5cdeSAxel Dörfler 
962ee7b4f39SMatthew Wilber 	// Close
963187f0b8aSMatthew Wilber 	fModified = false;
964ee7b4f39SMatthew Wilber 	return true;
965ee7b4f39SMatthew Wilber }
966ee7b4f39SMatthew Wilber 
967cdb89ebbSMatthew Wilber 
968ad13f387SMichael Pfeiffer void
969fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen()
970ad13f387SMichael Pfeiffer {
971ad13f387SMichael Pfeiffer 	BRect frame;
972ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
973ad13f387SMichael Pfeiffer 	if (fFullScreen) {
974ad13f387SMichael Pfeiffer 		BScreen screen;
975ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
976ad13f387SMichael Pfeiffer 		frame = screen.Frame();
977d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
978ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
979ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
980ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
981ad13f387SMichael Pfeiffer 
982ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
983c0b16687SAxel Dörfler 
984c0b16687SAxel Dörfler 		Activate();
985c0b16687SAxel Dörfler 			// make the window frontmost
986ad13f387SMichael Pfeiffer 	} else {
987ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
988ad13f387SMichael Pfeiffer 
989ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
990ad13f387SMichael Pfeiffer 	}
991efa8b4f3SAxel Dörfler 
99276d115d8SRyan Leavengood 	fImageView->SetFullScreen(fFullScreen);
993d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
994ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
995ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
996ad13f387SMichael Pfeiffer }
997ad13f387SMichael Pfeiffer 
998efa8b4f3SAxel Dörfler 
999d3046f7dSMichael Pfeiffer void
1000fd952aefSRyan Leavengood ShowImageWindow::_LoadSettings()
1001d3046f7dSMichael Pfeiffer {
1002efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1003efa8b4f3SAxel Dörfler 
1004d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1005d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
1006d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
1007d3046f7dSMichael Pfeiffer 
1008efa8b4f3SAxel Dörfler 		int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option());
1009d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
1010d3046f7dSMichael Pfeiffer 
1011efa8b4f3SAxel Dörfler 		float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1012d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
1013d3046f7dSMichael Pfeiffer 
1014d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
1015d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
1016d3046f7dSMichael Pfeiffer 
1017d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
1018d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
1019d3046f7dSMichael Pfeiffer 
1020d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
1021d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
1022d3046f7dSMichael Pfeiffer 
1023d3046f7dSMichael Pfeiffer 		settings->Unlock();
1024d3046f7dSMichael Pfeiffer 	}
1025d3046f7dSMichael Pfeiffer }
1026d3046f7dSMichael Pfeiffer 
1027efa8b4f3SAxel Dörfler 
1028d3046f7dSMichael Pfeiffer void
1029fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions()
1030d3046f7dSMichael Pfeiffer {
1031efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1032efa8b4f3SAxel Dörfler 
1033d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1034d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
1035d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1036d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1037d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
1038d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
1039d3046f7dSMichael Pfeiffer 		settings->Unlock();
1040d3046f7dSMichael Pfeiffer 	}
1041d3046f7dSMichael Pfeiffer }
1042d3046f7dSMichael Pfeiffer 
1043efa8b4f3SAxel Dörfler 
1044cdb89ebbSMatthew Wilber bool
1045fd952aefSRyan Leavengood ShowImageWindow::_PageSetup()
1046780d8a62SMichael Pfeiffer {
1047cd6b5cdeSAxel Dörfler 	BPrintJob printJob(fImageView->Image()->name);
1048efa8b4f3SAxel Dörfler 	if (fPrintSettings != NULL)
1049780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
1050efa8b4f3SAxel Dörfler 
10516163f333SKarsten Heimrich 	status_t status = printJob.ConfigPage();
10526163f333SKarsten Heimrich 	if (status == B_OK) {
1053780d8a62SMichael Pfeiffer 		delete fPrintSettings;
1054780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
1055780d8a62SMichael Pfeiffer 	}
1056efa8b4f3SAxel Dörfler 
10576163f333SKarsten Heimrich 	return status == B_OK;
1058780d8a62SMichael Pfeiffer }
1059780d8a62SMichael Pfeiffer 
1060efa8b4f3SAxel Dörfler 
1061780d8a62SMichael Pfeiffer void
1062fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint()
1063780d8a62SMichael Pfeiffer {
10646163f333SKarsten Heimrich 	if (fPrintSettings == NULL) {
1065cd6b5cdeSAxel Dörfler 		BPrintJob printJob(fImageView->Image()->name);
10666163f333SKarsten Heimrich 		if (printJob.ConfigJob() == B_OK)
10676163f333SKarsten Heimrich 			fPrintSettings = printJob.Settings();
10686163f333SKarsten Heimrich 	}
1069780d8a62SMichael Pfeiffer 
1070cd6b5cdeSAxel Dörfler 	fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds());
1071cd6b5cdeSAxel Dörfler 	fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1);
1072780d8a62SMichael Pfeiffer 
1073efa8b4f3SAxel Dörfler 	new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50),
1074efa8b4f3SAxel Dörfler 		&fPrintOptions, this);
1075780d8a62SMichael Pfeiffer }
1076780d8a62SMichael Pfeiffer 
1077efa8b4f3SAxel Dörfler 
1078780d8a62SMichael Pfeiffer void
1079fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg)
1080780d8a62SMichael Pfeiffer {
1081780d8a62SMichael Pfeiffer 	status_t st;
1082efa8b4f3SAxel Dörfler 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1083780d8a62SMichael Pfeiffer 		return;
1084780d8a62SMichael Pfeiffer 
1085fd952aefSRyan Leavengood 	_SavePrintOptions();
1086d3046f7dSMichael Pfeiffer 
1087cd6b5cdeSAxel Dörfler 	BPrintJob printJob(fImageView->Image()->name);
10886163f333SKarsten Heimrich 	if (fPrintSettings)
1089780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
10906163f333SKarsten Heimrich 
1091780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
10926163f333SKarsten Heimrich 		delete fPrintSettings;
10936163f333SKarsten Heimrich 		fPrintSettings = printJob.Settings();
1094780d8a62SMichael Pfeiffer 
1095780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
10963177ae77SStefano Ceccherini 		int32 firstPage = printJob.FirstPage();
10973177ae77SStefano Ceccherini 		int32 lastPage = printJob.LastPage();
10986163f333SKarsten Heimrich 		BRect printableRect = printJob.PrintableRect();
10996163f333SKarsten Heimrich 
1100efa8b4f3SAxel Dörfler 		if (firstPage < 1)
1101780d8a62SMichael Pfeiffer 			firstPage = 1;
1102efa8b4f3SAxel Dörfler 		if (lastPage < firstPage)
1103780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1104780d8a62SMichael Pfeiffer 
1105cd6b5cdeSAxel Dörfler 		BBitmap* bitmap = fImageView->Bitmap();
11063177ae77SStefano Ceccherini 		float imageWidth = bitmap->Bounds().Width() + 1.0;
11073177ae77SStefano Ceccherini 		float imageHeight = bitmap->Bounds().Height() + 1.0;
1108780d8a62SMichael Pfeiffer 
11096163f333SKarsten Heimrich 		float width;
1110780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
11116163f333SKarsten Heimrich 			case PrintOptions::kFitToPage: {
11126163f333SKarsten Heimrich 				float w1 = printableRect.Width()+1;
1113cd6b5cdeSAxel Dörfler 				float w2 = imageWidth * (printableRect.Height() + 1)
1114cd6b5cdeSAxel Dörfler 					/ imageHeight;
1115efa8b4f3SAxel Dörfler 				if (w2 < w1)
1116780d8a62SMichael Pfeiffer 					width = w2;
1117efa8b4f3SAxel Dörfler 				else
1118780d8a62SMichael Pfeiffer 					width = w1;
11196163f333SKarsten Heimrich 			}	break;
1120780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1121780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1122780d8a62SMichael Pfeiffer 				break;
1123780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1124780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1125780d8a62SMichael Pfeiffer 				break;
1126780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1127780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1128780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1129780d8a62SMichael Pfeiffer 				break;
1130efa8b4f3SAxel Dörfler 
1131780d8a62SMichael Pfeiffer 			default:
1132780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1133780d8a62SMichael Pfeiffer 				width = imageWidth;
1134780d8a62SMichael Pfeiffer 		}
1135780d8a62SMichael Pfeiffer 
1136efa8b4f3SAxel Dörfler 		// TODO: eventually print large images on several pages
1137780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1138d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
11395eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
11405eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
11415eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1142d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1143780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1144780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1145780d8a62SMichael Pfeiffer 	}
1146780d8a62SMichael Pfeiffer }
1147780d8a62SMichael Pfeiffer 
114856b0c7b9SKarsten Heimrich 
1149780d8a62SMichael Pfeiffer bool
1150cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1151cdb89ebbSMatthew Wilber {
1152efa8b4f3SAxel Dörfler 	if (fSavePanel) {
1153efa8b4f3SAxel Dörfler 		// Don't allow this window to be closed if a save panel is open
1154efa8b4f3SAxel Dörfler 		return false;
1155cdb89ebbSMatthew Wilber 	}
1156cdb89ebbSMatthew Wilber 
1157fd952aefSRyan Leavengood 	bool quit = _ClosePrompt();
1158efa8b4f3SAxel Dörfler 	if (quit) {
115907caaa8eSMatthew Wilber 		// tell the app to forget about this window
116007caaa8eSMatthew Wilber 		be_app->PostMessage(MSG_WINDOW_QUIT);
116107caaa8eSMatthew Wilber 	}
1162fc0a275bSMatthew Wilber 
1163efa8b4f3SAxel Dörfler 	return quit;
1164efa8b4f3SAxel Dörfler }
1165