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