xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision cd6b5cde06b9cc9ab9e5aacf03cda9dc853c34e4)
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>
206163f333SKarsten Heimrich 
21efa8b4f3SAxel Dörfler #include <Alert.h>
2213afa642SPhil Greenway #include <Application.h>
2313afa642SPhil Greenway #include <Bitmap.h>
24fc0a275bSMatthew Wilber #include <BitmapStream.h>
251ed4535fSStephan Aßmus #include <Catalog.h>
26efa8b4f3SAxel Dörfler #include <Clipboard.h>
2713afa642SPhil Greenway #include <Entry.h>
28fc0a275bSMatthew Wilber #include <File.h>
296163f333SKarsten Heimrich #include <FilePanel.h>
301ed4535fSStephan Aßmus #include <Locale.h>
3113afa642SPhil Greenway #include <Menu.h>
3213afa642SPhil Greenway #include <MenuBar.h>
3313afa642SPhil Greenway #include <MenuItem.h>
3413afa642SPhil Greenway #include <Path.h>
35efa8b4f3SAxel Dörfler #include <PrintJob.h>
36efa8b4f3SAxel Dörfler #include <Roster.h>
37efa8b4f3SAxel Dörfler #include <Screen.h>
3813afa642SPhil Greenway #include <ScrollView.h>
396163f333SKarsten Heimrich #include <String.h>
40efa8b4f3SAxel Dörfler #include <SupportDefs.h>
416163f333SKarsten Heimrich #include <TranslationDefs.h>
4213afa642SPhil Greenway #include <TranslationUtils.h>
4313afa642SPhil Greenway #include <TranslatorRoster.h>
441ed4535fSStephan Aßmus #include <stdlib.h> // for bs_printf()
4513afa642SPhil Greenway 
46fd952aefSRyan Leavengood #include "EntryMenuItem.h"
47fd952aefSRyan Leavengood #include "ResizerWindow.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 
54*cd6b5cdeSAxel Dörfler // BMessage field names used in Save messages
55*cd6b5cdeSAxel Dörfler const char* kTypeField = "be:type";
56*cd6b5cdeSAxel Dörfler const char* kTranslatorField = "be:translator";
57*cd6b5cdeSAxel Dörfler 
58*cd6b5cdeSAxel Dörfler 
596163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow::RecentDocumentsMenu
606163f333SKarsten Heimrich 
61*cd6b5cdeSAxel Dörfler 
626163f333SKarsten Heimrich class ShowImageWindow::RecentDocumentsMenu : public BMenu {
636163f333SKarsten Heimrich public:
646163f333SKarsten Heimrich 								RecentDocumentsMenu(const char* title,
656163f333SKarsten Heimrich 									menu_layout layout = B_ITEMS_IN_COLUMN);
666163f333SKarsten Heimrich 			bool				AddDynamicItem(add_state addState);
676163f333SKarsten Heimrich };
686163f333SKarsten Heimrich 
696163f333SKarsten Heimrich 
706163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::RecentDocumentsMenu(const char* title,
716163f333SKarsten Heimrich 	menu_layout layout)
72fd952aefSRyan Leavengood 	:
73fd952aefSRyan Leavengood 	BMenu(title, layout)
74a8fc7138SMichael Pfeiffer {
75a8fc7138SMichael Pfeiffer }
76a8fc7138SMichael Pfeiffer 
77efa8b4f3SAxel Dörfler 
78a8fc7138SMichael Pfeiffer bool
796163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::AddDynamicItem(add_state addState)
80a8fc7138SMichael Pfeiffer {
81a60adbf9SAxel Dörfler 	if (addState != B_INITIAL_ADD)
82efa8b4f3SAxel Dörfler 		return false;
83a8fc7138SMichael Pfeiffer 
846163f333SKarsten Heimrich 	while (CountItems() > 0)
856163f333SKarsten Heimrich 		delete RemoveItem(0L);
866163f333SKarsten Heimrich 
87a8fc7138SMichael Pfeiffer 	BMenuItem* item;
88a8fc7138SMichael Pfeiffer 	BMessage list, *msg;
89a8fc7138SMichael Pfeiffer 	entry_ref ref;
90a8fc7138SMichael Pfeiffer 	char name[B_FILE_NAME_LENGTH];
91a8fc7138SMichael Pfeiffer 
92efa8b4f3SAxel Dörfler 	be_roster->GetRecentDocuments(&list, 20, NULL, kApplicationSignature);
93a8fc7138SMichael Pfeiffer 	for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
94a8fc7138SMichael Pfeiffer 		BEntry entry(&ref);
95a8fc7138SMichael Pfeiffer 		if (entry.Exists() && entry.GetName(name) == B_OK) {
96a8fc7138SMichael Pfeiffer 			msg = new BMessage(B_REFS_RECEIVED);
97a8fc7138SMichael Pfeiffer 			msg->AddRef("refs", &ref);
98a8fc7138SMichael Pfeiffer 			item = new EntryMenuItem(&ref, name, msg, 0, 0);
99a8fc7138SMichael Pfeiffer 			AddItem(item);
100a8fc7138SMichael Pfeiffer 			item->SetTarget(be_app, NULL);
101a8fc7138SMichael Pfeiffer 		}
102a8fc7138SMichael Pfeiffer 	}
103a8fc7138SMichael Pfeiffer 
104a8fc7138SMichael Pfeiffer 	return false;
105a8fc7138SMichael Pfeiffer }
106a8fc7138SMichael Pfeiffer 
107a8fc7138SMichael Pfeiffer 
108*cd6b5cdeSAxel Dörfler // #pragma mark
109*cd6b5cdeSAxel Dörfler 
110*cd6b5cdeSAxel Dörfler 
111*cd6b5cdeSAxel Dörfler // This is temporary solution for building BString with printf like format.
112*cd6b5cdeSAxel Dörfler // will be removed in the future.
113*cd6b5cdeSAxel Dörfler static void
114*cd6b5cdeSAxel Dörfler bs_printf(BString* string, const char* format, ...)
115*cd6b5cdeSAxel Dörfler {
116*cd6b5cdeSAxel Dörfler 	va_list ap;
117*cd6b5cdeSAxel Dörfler 	char* buf;
118*cd6b5cdeSAxel Dörfler 
119*cd6b5cdeSAxel Dörfler 	va_start(ap, format);
120*cd6b5cdeSAxel Dörfler 	vasprintf(&buf, format, ap);
121*cd6b5cdeSAxel Dörfler 	string->SetTo(buf);
122*cd6b5cdeSAxel Dörfler 	free(buf);
123*cd6b5cdeSAxel Dörfler 	va_end(ap);
124*cd6b5cdeSAxel Dörfler }
125*cd6b5cdeSAxel Dörfler 
126*cd6b5cdeSAxel Dörfler 
1276163f333SKarsten Heimrich //	#pragma mark -- ShowImageWindow
1286163f333SKarsten Heimrich 
1296163f333SKarsten Heimrich 
130efa8b4f3SAxel Dörfler ShowImageWindow::ShowImageWindow(const entry_ref* ref,
131efa8b4f3SAxel Dörfler 	const BMessenger& trackerMessenger)
132fd952aefSRyan Leavengood 	:
133fd952aefSRyan Leavengood 	BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0),
134*cd6b5cdeSAxel Dörfler 	fNavigator(this),
135fd952aefSRyan Leavengood 	fSavePanel(NULL),
136fd952aefSRyan Leavengood 	fBar(NULL),
137fd952aefSRyan Leavengood 	fOpenMenu(NULL),
138fd952aefSRyan Leavengood 	fBrowseMenu(NULL),
139fd952aefSRyan Leavengood 	fGoToPageMenu(NULL),
140fd952aefSRyan Leavengood 	fSlideShowDelay(NULL),
141fd952aefSRyan Leavengood 	fImageView(NULL),
142fd952aefSRyan Leavengood 	fStatusView(NULL),
143fd952aefSRyan Leavengood 	fModified(false),
144fd952aefSRyan Leavengood 	fFullScreen(false),
145fd952aefSRyan Leavengood 	fShowCaption(true),
146fd952aefSRyan Leavengood 	fPrintSettings(NULL),
147fd952aefSRyan Leavengood 	fResizerWindowMessenger(NULL),
148*cd6b5cdeSAxel Dörfler 	fResizeItem(NULL)
14913afa642SPhil Greenway {
150fd952aefSRyan Leavengood 	_LoadSettings();
151fc0a275bSMatthew Wilber 
15213afa642SPhil Greenway 	// create menu bar
153e9dcd874SAxel Dörfler 	fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar");
154efa8b4f3SAxel Dörfler 	AddMenus(fBar);
155e9dcd874SAxel Dörfler 	AddChild(fBar);
15613afa642SPhil Greenway 
15713afa642SPhil Greenway 	BRect viewFrame = Bounds();
158e9dcd874SAxel Dörfler 	viewFrame.top = fBar->Bounds().Height() + 1;
15913afa642SPhil Greenway 	viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
16013afa642SPhil Greenway 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
16113afa642SPhil Greenway 
16213afa642SPhil Greenway 	// create the image view
163d3046f7dSMichael Pfeiffer 	fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
1647eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
16513afa642SPhil Greenway 	// wrap a scroll view around the view
166efa8b4f3SAxel Dörfler 	BScrollView* scrollView = new BScrollView("image_scroller", fImageView,
167cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
168efa8b4f3SAxel Dörfler 	AddChild(scrollView);
16913afa642SPhil Greenway 
17007caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
171cdb89ebbSMatthew Wilber 	BRect rect;
17213afa642SPhil Greenway 	rect = Bounds();
17313afa642SPhil Greenway 	rect.top = viewFrame.bottom + 1;
17407caaa8eSMatthew Wilber 	rect.left = viewFrame.left + kstatusWidth;
1750916ab53SMatthew Wilber 	rect.right = viewFrame.right + 1;
1760916ab53SMatthew Wilber 	rect.bottom += 1;
177efa8b4f3SAxel Dörfler 	BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll",
178efa8b4f3SAxel Dörfler 		fImageView, 0, 150, B_HORIZONTAL);
179efa8b4f3SAxel Dörfler 	AddChild(horizontalScrollBar);
18013afa642SPhil Greenway 
18113afa642SPhil Greenway 	rect.left = 0;
18207caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
1830cd4ecd8SStephan Aßmus 	rect.bottom -= 1;
184d3046f7dSMichael Pfeiffer 	fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
185cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
186d3046f7dSMichael Pfeiffer 	AddChild(fStatusView);
18713afa642SPhil Greenway 
18813afa642SPhil Greenway 	rect = Bounds();
1890916ab53SMatthew Wilber 	rect.top = viewFrame.top - 1;
19013afa642SPhil Greenway 	rect.left = viewFrame.right + 1;
1910916ab53SMatthew Wilber 	rect.bottom = viewFrame.bottom + 1;
1920916ab53SMatthew Wilber 	rect.right += 1;
193efa8b4f3SAxel Dörfler 	BScrollBar* verticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
194efa8b4f3SAxel Dörfler 		0, 150, B_VERTICAL);
195efa8b4f3SAxel Dörfler 	AddChild(verticalScrollBar);
19613afa642SPhil Greenway 
19703839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
19813afa642SPhil Greenway 
199134d6076SMichael Pfeiffer 	// finish creating the window
200*cd6b5cdeSAxel Dörfler 	fNavigator.SetTrackerMessenger(trackerMessenger);
201*cd6b5cdeSAxel Dörfler 	if (fNavigator.LoadImage(*ref) != B_OK) {
202*cd6b5cdeSAxel Dörfler 		_LoadError(*ref);
2035e09d5dbSRyan Leavengood 		Quit();
204d10d5947SMichael Pfeiffer 	}
205402c09e5SMatthew Wilber 
206d9f6762dSMichael Pfeiffer 	// add View menu here so it can access ShowImageView methods
207*cd6b5cdeSAxel Dörfler 	BMenu* menu = new BMenu(B_TRANSLATE_WITH_CONTEXT("View", "Menus"));
208fd952aefSRyan Leavengood 	_BuildViewMenu(menu, false);
209d9f6762dSMichael Pfeiffer 	fBar->AddItem(menu);
210d9f6762dSMichael Pfeiffer 
211d9f6762dSMichael Pfeiffer 	SetPulseRate(100000);
212d9f6762dSMichael Pfeiffer 		// every 1/10 second; ShowImageView needs it for marching ants
213d9f6762dSMichael Pfeiffer 
2146db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SELECTION_MODE,
2156db01936SAxel Dörfler 		fImageView->IsSelectionModeEnabled());
2166db01936SAxel Dörfler 
217402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
218402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
219402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
220*cd6b5cdeSAxel Dörfler 
221*cd6b5cdeSAxel Dörfler 	// The window will be shown on screen automatically
222*cd6b5cdeSAxel Dörfler 	Run();
22313afa642SPhil Greenway }
22413afa642SPhil Greenway 
225efa8b4f3SAxel Dörfler 
22613afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
22713afa642SPhil Greenway {
2286163f333SKarsten Heimrich 	delete fResizerWindowMessenger;
22913afa642SPhil Greenway }
23013afa642SPhil Greenway 
231efa8b4f3SAxel Dörfler 
232cdb89ebbSMatthew Wilber void
233cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
23413afa642SPhil Greenway {
235*cd6b5cdeSAxel Dörfler 	BPath path(fImageView->Image());
236*cd6b5cdeSAxel Dörfler 	SetTitle(path.Path());
23713afa642SPhil Greenway }
23813afa642SPhil Greenway 
23956b0c7b9SKarsten Heimrich 
240d9f6762dSMichael Pfeiffer void
241d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu)
242d9f6762dSMichael Pfeiffer {
243fd952aefSRyan Leavengood 	_BuildViewMenu(menu, true);
244d9f6762dSMichael Pfeiffer }
245efa8b4f3SAxel Dörfler 
24656b0c7b9SKarsten Heimrich 
2474eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
2484eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus"
2491ed4535fSStephan Aßmus 
2506046b973SAxel Dörfler 
251cdb89ebbSMatthew Wilber void
252fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
253da87390fSMichael Pfeiffer {
254905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this);
255fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
256905c8c8cSMatt Madia 	BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay"));
257efa8b4f3SAxel Dörfler 	if (fSlideShowDelay == NULL)
258efa8b4f3SAxel Dörfler 		fSlideShowDelay = delayMenu;
259efa8b4f3SAxel Dörfler 
260efa8b4f3SAxel Dörfler 	delayMenu->SetRadioMode(true);
26156b0c7b9SKarsten Heimrich 	// Note: ShowImage loads images in window thread so it becomes unresponsive
26256b0c7b9SKarsten Heimrich 	//		 if slide show delay is too short! (Especially if loading the image
26356b0c7b9SKarsten Heimrich 	//		 takes as long as or longer than the slide show delay). Should load
26456b0c7b9SKarsten Heimrich 	//		 in background thread!
265905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("3 seconds"), 3);
266905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("4 seconds"), 4);
267905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("5 seconds"), 5);
268905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("6 seconds"), 6);
269905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("7 seconds"), 7);
270905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("8 seconds"), 8);
271905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("9 seconds"), 9);
272905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("10 seconds"), 10);
273905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("20 seconds"), 20);
274efa8b4f3SAxel Dörfler 	menu->AddItem(delayMenu);
27530060f17SMatthew Wilber 
276efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
277efa8b4f3SAxel Dörfler 
278905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Original size"),
279905c8c8cSMatt Madia 		MSG_ORIGINAL_SIZE, '1', 0, this);
280905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this);
281905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this);
282efa8b4f3SAxel Dörfler 
283efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
284efa8b4f3SAxel Dörfler 
2854fd570d3SAxel Dörfler 	if (!popupMenu || fFullScreen) {
286905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
287905c8c8cSMatt Madia 			MSG_SCALE_BILINEAR, 0, 0, this);
288efa8b4f3SAxel Dörfler 
289efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
290efa8b4f3SAxel Dörfler 
291905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Shrink to window"),
292905c8c8cSMatt Madia 			MSG_SHRINK_TO_WINDOW, 0, 0, this);
2934fd570d3SAxel Dörfler 		_AddItemMenu(menu, B_TRANSLATE("Stretch to window"),
2944fd570d3SAxel Dörfler 			MSG_STRETCH_TO_WINDOW, 0, 0, this);
295efa8b4f3SAxel Dörfler 
296efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
29732c22143SAxel Dörfler 	}
298efa8b4f3SAxel Dörfler 
299905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Full screen"),
300905c8c8cSMatt Madia 		MSG_FULL_SCREEN, B_ENTER, 0, this);
301fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
302efa8b4f3SAxel Dörfler 
303905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"),
304905c8c8cSMatt Madia 		MSG_SHOW_CAPTION, 0, 0, this);
305fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
306efa8b4f3SAxel Dörfler 
307fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
3086db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, fImageView->ShrinksToBounds());
3096db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_STRETCH_TO_WINDOW, fImageView->StretchesToBounds());
310a60adbf9SAxel Dörfler 
311d9f6762dSMichael Pfeiffer 	if (popupMenu) {
312a60adbf9SAxel Dörfler 		menu->AddSeparatorItem();
313905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
3141ed4535fSStephan Aßmus 			MSG_DESKTOP_BACKGROUND, 0, 0, this);
315d9f6762dSMichael Pfeiffer 	}
316da87390fSMichael Pfeiffer }
317da87390fSMichael Pfeiffer 
318efa8b4f3SAxel Dörfler 
319da87390fSMichael Pfeiffer void
320efa8b4f3SAxel Dörfler ShowImageWindow::AddMenus(BMenuBar* bar)
32113afa642SPhil Greenway {
322905c8c8cSMatt Madia 	BMenu* menu = new BMenu(B_TRANSLATE("File"));
323905c8c8cSMatt Madia 	fOpenMenu = new RecentDocumentsMenu(B_TRANSLATE("Open"));
324efa8b4f3SAxel Dörfler 	menu->AddItem(fOpenMenu);
325d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTrigger('O');
326d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
327d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTarget(be_app);
328d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetShortcut('O', 0);
329efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
3306db01936SAxel Dörfler 	BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS),
3311ed4535fSStephan Aßmus 		B_ITEMS_IN_COLUMN);
3326db01936SAxel Dörfler 	BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP);
333fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
334fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
3356db01936SAxel Dörfler 	menu->AddItem(menuSaveAs);
336905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this);
337efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
338905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS),
3391ed4535fSStephan Aßmus 		MSG_PAGE_SETUP, 0, 0, this);
340905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS),
3411ed4535fSStephan Aßmus 		MSG_PREPARE_PRINT, 'P', 0, this);
342efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
343905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("About ShowImage" B_UTF8_ELLIPSIS),
3441ed4535fSStephan Aßmus 		B_ABOUT_REQUESTED, 0, 0, be_app);
345efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
346905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app);
347efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
34813afa642SPhil Greenway 
349905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Edit"));
350905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Undo"), B_UNDO, 'Z', 0, this, false);
351efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
352905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false);
353efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
3546db01936SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Selection Mode"), MSG_SELECTION_MODE, 0, 0,
3556db01936SAxel Dörfler 		this);
35632c22143SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Clear selection"),
35732c22143SAxel Dörfler 		MSG_CLEAR_SELECT, 0, 0, this, false);
358905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Select all"),
359905c8c8cSMatt Madia 		MSG_SELECT_ALL, 'A', 0, this);
360efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
36113afa642SPhil Greenway 
362905c8c8cSMatt Madia 	menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse"));
363905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("First page"),
3641ed4535fSStephan Aßmus 		MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this);
365905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Last page"),
3661ed4535fSStephan Aßmus 		MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this);
367905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous page"),
368905c8c8cSMatt Madia 		MSG_PAGE_PREV, B_LEFT_ARROW, 0, this);
369905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next page"),
370905c8c8cSMatt Madia 		MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this);
371905c8c8cSMatt Madia 	fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page"));
3725e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
373efa8b4f3SAxel Dörfler 	menu->AddItem(fGoToPageMenu);
374efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
375905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous file"),
376905c8c8cSMatt Madia 		MSG_FILE_PREV, B_UP_ARROW, 0, this);
377905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next file"),
378905c8c8cSMatt Madia 		MSG_FILE_NEXT, B_DOWN_ARROW, 0, this);
379efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
38003839579SMatthew Wilber 
381905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Image"));
382905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"),
383905c8c8cSMatt Madia 		MSG_ROTATE_90, 'R', 0, this);
384905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"),
3851ed4535fSStephan Aßmus 		MSG_ROTATE_270, 'R', B_SHIFT_KEY, this);
386efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
387905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip left to right"),
3881ed4535fSStephan Aßmus 		MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this);
389905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"),
3901ed4535fSStephan Aßmus 		MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this);
391efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
392905c8c8cSMatt Madia 	fResizeItem = _AddItemMenu(menu, B_TRANSLATE("Resize" B_UTF8_ELLIPSIS),
3936163f333SKarsten Heimrich 		MSG_OPEN_RESIZER_WINDOW, 0, 0, this);
394efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
395d9f6762dSMichael Pfeiffer 	menu->AddSeparatorItem();
396905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
3971ed4535fSStephan Aßmus 		MSG_DESKTOP_BACKGROUND, 0, 0, this);
39813afa642SPhil Greenway }
39913afa642SPhil Greenway 
400efa8b4f3SAxel Dörfler 
401cdb89ebbSMatthew Wilber BMenuItem*
402fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what,
4034fd570d3SAxel Dörfler 	char shortcut, uint32 modifier, const BHandler* target, bool enabled)
404cdb89ebbSMatthew Wilber {
4054fd570d3SAxel Dörfler 	BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut,
4064fd570d3SAxel Dörfler 		modifier);
407efa8b4f3SAxel Dörfler 	menu->AddItem(item);
408efa8b4f3SAxel Dörfler 
4096163f333SKarsten Heimrich 	item->SetTarget(target);
4106163f333SKarsten Heimrich 	item->SetEnabled(enabled);
4116163f333SKarsten Heimrich 
412efa8b4f3SAxel Dörfler 	return item;
41313afa642SPhil Greenway }
41413afa642SPhil Greenway 
415efa8b4f3SAxel Dörfler 
416ad13f387SMichael Pfeiffer BMenuItem*
417fd952aefSRyan Leavengood ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, float value)
418ad13f387SMichael Pfeiffer {
419efa8b4f3SAxel Dörfler 	BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
420efa8b4f3SAxel Dörfler 	message->AddFloat("value", value);
421ad13f387SMichael Pfeiffer 
4226163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, message, 0);
423efa8b4f3SAxel Dörfler 	item->SetTarget(this);
424ad13f387SMichael Pfeiffer 
425d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
426efa8b4f3SAxel Dörfler 	if (marked)
427efa8b4f3SAxel Dörfler 		item->SetMarked(true);
428ad13f387SMichael Pfeiffer 
429efa8b4f3SAxel Dörfler 	menu->AddItem(item);
430efa8b4f3SAxel Dörfler 	return item;
431ad13f387SMichael Pfeiffer }
432ad13f387SMichael Pfeiffer 
433efa8b4f3SAxel Dörfler 
434cdb89ebbSMatthew Wilber void
4351076d97bSAxel Dörfler ShowImageWindow::WindowRedimension(BBitmap* bitmap)
43613afa642SPhil Greenway {
437d10d5947SMichael Pfeiffer 	BScreen screen;
43871a34702SAxel Dörfler 	if (!screen.IsValid())
439efa8b4f3SAxel Dörfler 		return;
440efa8b4f3SAxel Dörfler 
4411076d97bSAxel Dörfler 	// TODO: use View::GetPreferredSize() instead?
4421076d97bSAxel Dörfler 	BRect r(bitmap->Bounds());
4431076d97bSAxel Dörfler 	float width = r.Width() + B_V_SCROLL_BAR_WIDTH;
4441076d97bSAxel Dörfler 	float height = r.Height() + 1 + fBar->Frame().Height()
4451076d97bSAxel Dörfler 		+ B_H_SCROLL_BAR_HEIGHT;
446cdb89ebbSMatthew Wilber 
4476163f333SKarsten Heimrich 	BRect frame = screen.Frame();
4486163f333SKarsten Heimrich 	const float windowBorder = 5;
449d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
4506163f333SKarsten Heimrich 	float maxWidth = frame.Width() + 1 - windowBorder - Frame().left;
4516163f333SKarsten Heimrich 	float maxHeight = frame.Height() + 1 - windowBorder - Frame().top;
452cdb89ebbSMatthew Wilber 
453a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
454a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
455efa8b4f3SAxel Dörfler 
456fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
457a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
458efa8b4f3SAxel Dörfler 	if (maxWidth > maxW)
459efa8b4f3SAxel Dörfler 		maxWidth = maxW;
460efa8b4f3SAxel Dörfler 	if (maxHeight > maxH)
461efa8b4f3SAxel Dörfler 		maxHeight = maxH;
462efa8b4f3SAxel Dörfler 	if (width < minW)
463efa8b4f3SAxel Dörfler 		width = minW;
464efa8b4f3SAxel Dörfler 	if (height < minH)
465efa8b4f3SAxel Dörfler 		height = minH;
466a8fc7138SMichael Pfeiffer 
467efa8b4f3SAxel Dörfler 	if (width > maxWidth)
468efa8b4f3SAxel Dörfler 		width = maxWidth;
469efa8b4f3SAxel Dörfler 	if (height > maxHeight)
470efa8b4f3SAxel Dörfler 		height = maxHeight;
471d10d5947SMichael Pfeiffer 
472d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
47313afa642SPhil Greenway }
47413afa642SPhil Greenway 
475efa8b4f3SAxel Dörfler 
476cdb89ebbSMatthew Wilber void
477cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
47813afa642SPhil Greenway {
4796163f333SKarsten Heimrich 	BWindow::FrameResized(width, height);
48013afa642SPhil Greenway }
48113afa642SPhil Greenway 
482efa8b4f3SAxel Dörfler 
4837eca0987SMichael Pfeiffer bool
484fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what)
4857eca0987SMichael Pfeiffer {
4867eca0987SMichael Pfeiffer 	bool marked = false;
4876163f333SKarsten Heimrich 	BMenuItem* item = fBar->FindItem(what);
4887eca0987SMichael Pfeiffer 	if (item != NULL) {
4897eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
4907eca0987SMichael Pfeiffer 		item->SetMarked(marked);
4917eca0987SMichael Pfeiffer 	}
4927eca0987SMichael Pfeiffer 	return marked;
4937eca0987SMichael Pfeiffer }
4947eca0987SMichael Pfeiffer 
495efa8b4f3SAxel Dörfler 
496cdb89ebbSMatthew Wilber void
497fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable)
498e6a50d9cSMichael Pfeiffer {
4996163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
5006163f333SKarsten Heimrich 	if (item && item->IsEnabled() != enable)
501e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
502e6a50d9cSMichael Pfeiffer }
503e6a50d9cSMichael Pfeiffer 
504efa8b4f3SAxel Dörfler 
505e6a50d9cSMichael Pfeiffer void
506fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked)
507e6a50d9cSMichael Pfeiffer {
5086163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
5096163f333SKarsten Heimrich 	if (item && item->IsMarked() != marked)
510e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
511e6a50d9cSMichael Pfeiffer }
512e6a50d9cSMichael Pfeiffer 
513efa8b4f3SAxel Dörfler 
514da87390fSMichael Pfeiffer void
515fd952aefSRyan Leavengood ShowImageWindow::_MarkSlideShowDelay(float value)
516da87390fSMichael Pfeiffer {
517d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
518da87390fSMichael Pfeiffer 	float v;
519da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
520d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
521da87390fSMichael Pfeiffer 		if (item) {
522da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
5236163f333SKarsten Heimrich 				if (!item->IsMarked())
524da87390fSMichael Pfeiffer 					item->SetMarked(true);
525da87390fSMichael Pfeiffer 				return;
526da87390fSMichael Pfeiffer 			}
527da87390fSMichael Pfeiffer 		}
528da87390fSMichael Pfeiffer 	}
529da87390fSMichael Pfeiffer }
530e6a50d9cSMichael Pfeiffer 
53119c76de4SMichael Pfeiffer 
53219c76de4SMichael Pfeiffer void
533fd952aefSRyan Leavengood ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what)
53419c76de4SMichael Pfeiffer {
535fd952aefSRyan Leavengood 	bool enabled = _ToggleMenuItem(what);
5366163f333SKarsten Heimrich 	if (shrink)
537d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
5386163f333SKarsten Heimrich 	else
5394fd570d3SAxel Dörfler 		fImageView->SetStretchToBounds(enabled);
54019c76de4SMichael Pfeiffer }
54119c76de4SMichael Pfeiffer 
542efa8b4f3SAxel Dörfler 
543e6a50d9cSMichael Pfeiffer void
544efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message)
54513afa642SPhil Greenway {
546efa8b4f3SAxel Dörfler 	switch (message->what) {
547*cd6b5cdeSAxel Dörfler 		case kMsgImageLoaded:
548*cd6b5cdeSAxel Dörfler 		{
549*cd6b5cdeSAxel Dörfler 			bool first = fImageView->Bitmap() == NULL;
550*cd6b5cdeSAxel Dörfler 
551*cd6b5cdeSAxel Dörfler 			status_t status = fImageView->SetImage(message);
552*cd6b5cdeSAxel Dörfler 			if (status != B_OK) {
553*cd6b5cdeSAxel Dörfler 				entry_ref ref;
554*cd6b5cdeSAxel Dörfler 				message->FindRef("ref", &ref);
555*cd6b5cdeSAxel Dörfler 
556*cd6b5cdeSAxel Dörfler 				_LoadError(ref);
557*cd6b5cdeSAxel Dörfler 
558*cd6b5cdeSAxel Dörfler 				// quit if file could not be opened
559*cd6b5cdeSAxel Dörfler 				if (first)
560*cd6b5cdeSAxel Dörfler 					Quit();
561*cd6b5cdeSAxel Dörfler 				break;
562*cd6b5cdeSAxel Dörfler 			}
563*cd6b5cdeSAxel Dörfler 
564*cd6b5cdeSAxel Dörfler 			fImageType = message->FindString("type");
565*cd6b5cdeSAxel Dörfler 
566*cd6b5cdeSAxel Dörfler 			if (first) {
567*cd6b5cdeSAxel Dörfler 				WindowRedimension(fImageView->Bitmap());
568*cd6b5cdeSAxel Dörfler 				fImageView->ResetZoom();
569*cd6b5cdeSAxel Dörfler 				fImageView->MakeFocus(true);
570*cd6b5cdeSAxel Dörfler 					// to receive key messages
571*cd6b5cdeSAxel Dörfler 
572*cd6b5cdeSAxel Dörfler 				Show();
573*cd6b5cdeSAxel Dörfler 			} else {
574*cd6b5cdeSAxel Dörfler 				if (!fImageView->StretchesToBounds()
575*cd6b5cdeSAxel Dörfler 					&& !fImageView->ShrinksToBounds()
576*cd6b5cdeSAxel Dörfler 					&& !fFullScreen)
577*cd6b5cdeSAxel Dörfler 					WindowRedimension(fImageView->Bitmap());
578*cd6b5cdeSAxel Dörfler 			}
579*cd6b5cdeSAxel Dörfler 			break;
580*cd6b5cdeSAxel Dörfler 		}
581*cd6b5cdeSAxel Dörfler 
582ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
583ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
584ee7b4f39SMatthew Wilber 			fModified = true;
585ee7b4f39SMatthew Wilber 			break;
586ee7b4f39SMatthew Wilber 
587fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
588fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
589d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
590cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
591fd952aefSRyan Leavengood 				_SaveAs(message);
59213afa642SPhil Greenway 			break;
593fc0a275bSMatthew Wilber 
594fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
595fc0a275bSMatthew Wilber 			// User specified where to save the output image
596fd952aefSRyan Leavengood 			_SaveToFile(message);
59707caaa8eSMatthew Wilber 			break;
59807caaa8eSMatthew Wilber 
599cdb89ebbSMatthew Wilber 		case B_CANCEL:
600d3046f7dSMichael Pfeiffer 			delete fSavePanel;
601d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
602cdb89ebbSMatthew Wilber 			break;
603cdb89ebbSMatthew Wilber 
6046db01936SAxel Dörfler 		case MSG_UPDATE_STATUS:
6056db01936SAxel Dörfler 		{
606*cd6b5cdeSAxel Dörfler 			int32 pages = fNavigator.PageCount();
607*cd6b5cdeSAxel Dörfler 			int32 currentPage = fNavigator.CurrentPage();
6086c305411SMatthew Wilber 
609*cd6b5cdeSAxel Dörfler 			bool enable = pages > 1 ? true : false;
61036c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_FIRST, enable);
61136c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_LAST, enable);
61236c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_NEXT, enable);
61336c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_PREV, enable);
61436c17651SRyan Leavengood 			fGoToPageMenu->SetEnabled(enable);
6151d592070SMatthew Wilber 
616*cd6b5cdeSAxel Dörfler 			_EnableMenuItem(fBar, MSG_FILE_NEXT, fNavigator.HasNextFile());
617*cd6b5cdeSAxel Dörfler 			_EnableMenuItem(fBar, MSG_FILE_PREV, fNavigator.HasPreviousFile());
618134d6076SMichael Pfeiffer 
619d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
6206c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
6216c305411SMatthew Wilber 				// pages is different
6226c305411SMatthew Wilber 
623*cd6b5cdeSAxel Dörfler 				while (fGoToPageMenu->CountItems() > 0) {
6246c305411SMatthew Wilber 					// Remove all page numbers
625d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
626*cd6b5cdeSAxel Dörfler 				}
6276c305411SMatthew Wilber 
628780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
6296c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
630*cd6b5cdeSAxel Dörfler 					BMessage* goTo = new BMessage(MSG_GOTO_PAGE);
631*cd6b5cdeSAxel Dörfler 					goTo->AddInt32("page", i);
6326163f333SKarsten Heimrich 
6336163f333SKarsten Heimrich 					char shortcut = 0;
634*cd6b5cdeSAxel Dörfler 					if (i < 10)
635780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
6366163f333SKarsten Heimrich 
6376163f333SKarsten Heimrich 					BString strCaption;
6386163f333SKarsten Heimrich 					strCaption << i;
6396163f333SKarsten Heimrich 
640*cd6b5cdeSAxel Dörfler 					BMenuItem* item = new BMenuItem(strCaption.String(), goTo,
6416163f333SKarsten Heimrich 						shortcut);
642*cd6b5cdeSAxel Dörfler 					if (currentPage == i)
643efa8b4f3SAxel Dörfler 						item->SetMarked(true);
644efa8b4f3SAxel Dörfler 					fGoToPageMenu->AddItem(item);
6456c305411SMatthew Wilber 				}
6466c305411SMatthew Wilber 			} else {
6476c305411SMatthew Wilber 				// Make sure the correct page is marked
648*cd6b5cdeSAxel Dörfler 				BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
649*cd6b5cdeSAxel Dörfler 				if (currentItem != NULL && !currentItem->IsMarked())
650*cd6b5cdeSAxel Dörfler 					currentItem->SetMarked(true);
6516c305411SMatthew Wilber 			}
6526c305411SMatthew Wilber 
653*cd6b5cdeSAxel Dörfler 			_UpdateStatusText(message);
6547eca0987SMichael Pfeiffer 			UpdateTitle();
6556db01936SAxel Dörfler 			break;
6566db01936SAxel Dörfler 		}
65703839579SMatthew Wilber 
6586db01936SAxel Dörfler 		case MSG_UPDATE_STATUS_TEXT:
6596db01936SAxel Dörfler 		{
660*cd6b5cdeSAxel Dörfler 			_UpdateStatusText(message);
6616db01936SAxel Dörfler 			break;
6626db01936SAxel Dörfler 		}
6638f5fd23fSRyan Leavengood 
6646db01936SAxel Dörfler 		case MSG_SELECTION:
6656db01936SAxel Dörfler 		{
6668ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
6678ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
6688ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
6696db01936SAxel Dörfler 			bool enable;
6706db01936SAxel Dörfler 			if (message->FindBool("has_selection", &enable) == B_OK) {
6716db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_COPY, enable);
6726db01936SAxel Dörfler 				_EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable);
6738ad30bcfSMatthew Wilber 			}
6746db01936SAxel Dörfler 			break;
6756db01936SAxel Dörfler 		}
6768ad30bcfSMatthew Wilber 
6776db01936SAxel Dörfler 		case MSG_UNDO_STATE:
6786db01936SAxel Dörfler 		{
6796db01936SAxel Dörfler 			bool enable;
6806db01936SAxel Dörfler 			if (message->FindBool("can_undo", &enable) == B_OK)
6816db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_UNDO, enable);
6826db01936SAxel Dörfler 			break;
6836db01936SAxel Dörfler 		}
684402c09e5SMatthew Wilber 
68513afa642SPhil Greenway 		case B_UNDO:
6867598450eSMatthew Wilber 			fImageView->Undo();
68713afa642SPhil Greenway 			break;
6886163f333SKarsten Heimrich 
68913afa642SPhil Greenway 		case B_COPY:
690d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
69113afa642SPhil Greenway 			break;
6926163f333SKarsten Heimrich 
6936db01936SAxel Dörfler 		case MSG_SELECTION_MODE:
6946db01936SAxel Dörfler 			fImageView->SetSelectionMode(_ToggleMenuItem(MSG_SELECTION_MODE));
6956db01936SAxel Dörfler 			break;
6966db01936SAxel Dörfler 
69713afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
698d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
69913afa642SPhil Greenway 			break;
7006163f333SKarsten Heimrich 
70113afa642SPhil Greenway 		case MSG_SELECT_ALL:
702d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
70313afa642SPhil Greenway 			break;
70413afa642SPhil Greenway 
70503839579SMatthew Wilber 		case MSG_PAGE_FIRST:
706fd952aefSRyan Leavengood 			if (_ClosePrompt())
707*cd6b5cdeSAxel Dörfler 				fNavigator.FirstPage();
70803839579SMatthew Wilber 			break;
70903839579SMatthew Wilber 
71003839579SMatthew Wilber 		case MSG_PAGE_LAST:
711fd952aefSRyan Leavengood 			if (_ClosePrompt())
712*cd6b5cdeSAxel Dörfler 				fNavigator.LastPage();
71303839579SMatthew Wilber 			break;
71403839579SMatthew Wilber 
71503839579SMatthew Wilber 		case MSG_PAGE_NEXT:
716fd952aefSRyan Leavengood 			if (_ClosePrompt())
717*cd6b5cdeSAxel Dörfler 				fNavigator.NextPage();
71803839579SMatthew Wilber 			break;
71903839579SMatthew Wilber 
72003839579SMatthew Wilber 		case MSG_PAGE_PREV:
721fd952aefSRyan Leavengood 			if (_ClosePrompt())
722*cd6b5cdeSAxel Dörfler 				fNavigator.PreviousPage();
72303839579SMatthew Wilber 			break;
72403839579SMatthew Wilber 
725*cd6b5cdeSAxel Dörfler 		case MSG_GOTO_PAGE:
726*cd6b5cdeSAxel Dörfler 		{
727fd952aefSRyan Leavengood 			if (!_ClosePrompt())
728ee7b4f39SMatthew Wilber 				break;
729ee7b4f39SMatthew Wilber 
7306163f333SKarsten Heimrich 			int32 newPage;
7316163f333SKarsten Heimrich 			if (message->FindInt32("page", &newPage) != B_OK)
7326163f333SKarsten Heimrich 				break;
7336163f333SKarsten Heimrich 
734*cd6b5cdeSAxel Dörfler 			int32 currentPage = fNavigator.CurrentPage();
735*cd6b5cdeSAxel Dörfler 			int32 pages = fNavigator.PageCount();
7366c305411SMatthew Wilber 
7376c305411SMatthew Wilber 			if (newPage > 0 && newPage <= pages) {
738*cd6b5cdeSAxel Dörfler 				BMenuItem* currentItem = fGoToPageMenu->ItemAt(currentPage - 1);
739*cd6b5cdeSAxel Dörfler 				BMenuItem* newItem = fGoToPageMenu->ItemAt(newPage - 1);
740*cd6b5cdeSAxel Dörfler 				if (currentItem != NULL && newItem != NULL) {
741*cd6b5cdeSAxel Dörfler 					currentItem->SetMarked(false);
742*cd6b5cdeSAxel Dörfler 					newItem->SetMarked(true);
743*cd6b5cdeSAxel Dörfler 					fNavigator.GoToPage(newPage);
7446c305411SMatthew Wilber 				}
7456c305411SMatthew Wilber 			}
746*cd6b5cdeSAxel Dörfler 			break;
747*cd6b5cdeSAxel Dörfler 		}
7486c305411SMatthew Wilber 
74919c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
750fd952aefSRyan Leavengood 			_ResizeToWindow(true, message->what);
75119c76de4SMichael Pfeiffer 			break;
7526163f333SKarsten Heimrich 
7534fd570d3SAxel Dörfler 		case MSG_STRETCH_TO_WINDOW:
754fd952aefSRyan Leavengood 			_ResizeToWindow(false, message->what);
7557eca0987SMichael Pfeiffer 			break;
7567eca0987SMichael Pfeiffer 
7577eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
758fd952aefSRyan Leavengood 			if (_ClosePrompt())
759*cd6b5cdeSAxel Dörfler 				fNavigator.PreviousFile();
7607eca0987SMichael Pfeiffer 			break;
7617eca0987SMichael Pfeiffer 
7627eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
763fd952aefSRyan Leavengood 			if (_ClosePrompt())
764*cd6b5cdeSAxel Dörfler 				fNavigator.NextFile();
76513afa642SPhil Greenway 			break;
76613afa642SPhil Greenway 
767bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
768d3046f7dSMichael Pfeiffer 			fImageView->Rotate(90);
769ad13f387SMichael Pfeiffer 			break;
7706163f333SKarsten Heimrich 
771bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
772d3046f7dSMichael Pfeiffer 			fImageView->Rotate(270);
773ad13f387SMichael Pfeiffer 			break;
7746163f333SKarsten Heimrich 
77569eee339SRyan Leavengood 		case MSG_FLIP_LEFT_TO_RIGHT:
77661ddc257SRyan Leavengood 			fImageView->Flip(true);
777ad13f387SMichael Pfeiffer 			break;
7786163f333SKarsten Heimrich 
77969eee339SRyan Leavengood 		case MSG_FLIP_TOP_TO_BOTTOM:
78061ddc257SRyan Leavengood 			fImageView->Flip(false);
781ad13f387SMichael Pfeiffer 			break;
7826163f333SKarsten Heimrich 
7831076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW:
7841076d97bSAxel Dörfler 		{
7856163f333SKarsten Heimrich 			BMenuItem* item = fBar->FindItem(message->what);
786ee7b4f39SMatthew Wilber 			if (!item)
787ee7b4f39SMatthew Wilber 				break;
788ee7b4f39SMatthew Wilber 			if (item->IsMarked()) {
789ee7b4f39SMatthew Wilber 				item->SetMarked(false);
790ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(true);
791d3046f7dSMichael Pfeiffer 				fImageView->StopSlideShow();
792fd952aefSRyan Leavengood 			} else if (_ClosePrompt()) {
793ee7b4f39SMatthew Wilber 				item->SetMarked(true);
794ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(false);
795ee7b4f39SMatthew Wilber 				fImageView->StartSlideShow();
796ad13f387SMichael Pfeiffer 			}
7971076d97bSAxel Dörfler 			break;
7981076d97bSAxel Dörfler 		}
799ee7b4f39SMatthew Wilber 
8001076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW_DELAY:
8011076d97bSAxel Dörfler 		{
802ad13f387SMichael Pfeiffer 			float value;
803efa8b4f3SAxel Dörfler 			if (message->FindFloat("value", &value) == B_OK) {
804d3046f7dSMichael Pfeiffer 				fImageView->SetSlideShowDelay(value);
805da87390fSMichael Pfeiffer 				// in case message is sent from popup menu
806fd952aefSRyan Leavengood 				_MarkSlideShowDelay(value);
807ad13f387SMichael Pfeiffer 			}
8081076d97bSAxel Dörfler 			break;
8091076d97bSAxel Dörfler 		}
810ad13f387SMichael Pfeiffer 
811ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
812fd952aefSRyan Leavengood 			_ToggleFullScreen();
813ad13f387SMichael Pfeiffer 			break;
8146163f333SKarsten Heimrich 
815fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
816fc5ca95dSStephan Aßmus 			if (fFullScreen)
817fd952aefSRyan Leavengood 				_ToggleFullScreen();
818fc5ca95dSStephan Aßmus 			break;
8196163f333SKarsten Heimrich 
8206163f333SKarsten Heimrich 		case MSG_SHOW_CAPTION: {
821fd952aefSRyan Leavengood 			fShowCaption = _ToggleMenuItem(message->what);
822efa8b4f3SAxel Dörfler 			ShowImageSettings* settings = my_app->Settings();
823efa8b4f3SAxel Dörfler 
824d3046f7dSMichael Pfeiffer 			if (settings->Lock()) {
825d3046f7dSMichael Pfeiffer 				settings->SetBool("ShowCaption", fShowCaption);
826d3046f7dSMichael Pfeiffer 				settings->Unlock();
827d3046f7dSMichael Pfeiffer 			}
828efa8b4f3SAxel Dörfler 			if (fFullScreen)
829d3046f7dSMichael Pfeiffer 				fImageView->SetShowCaption(fShowCaption);
8306163f333SKarsten Heimrich 		}	break;
831ad13f387SMichael Pfeiffer 
832780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
833fd952aefSRyan Leavengood 			_PageSetup();
834780d8a62SMichael Pfeiffer 			break;
8356163f333SKarsten Heimrich 
836780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
837fd952aefSRyan Leavengood 			_PrepareForPrint();
838780d8a62SMichael Pfeiffer 			break;
8396163f333SKarsten Heimrich 
840780d8a62SMichael Pfeiffer 		case MSG_PRINT:
841fd952aefSRyan Leavengood 			_Print(message);
842780d8a62SMichael Pfeiffer 			break;
843780d8a62SMichael Pfeiffer 
844780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
845d3046f7dSMichael Pfeiffer 			fImageView->ZoomIn();
846780d8a62SMichael Pfeiffer 			break;
8476163f333SKarsten Heimrich 
848780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
849d3046f7dSMichael Pfeiffer 			fImageView->ZoomOut();
850780d8a62SMichael Pfeiffer 			break;
8516163f333SKarsten Heimrich 
852780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
8534fd570d3SAxel Dörfler 			fImageView->SetZoom(1.0);
854780d8a62SMichael Pfeiffer 			break;
8556163f333SKarsten Heimrich 
85681b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
857fd952aefSRyan Leavengood 			fImageView->SetScaleBilinear(_ToggleMenuItem(message->what));
85881b9c776SMichael Pfeiffer 			break;
859780d8a62SMichael Pfeiffer 
860880be331SRyan Leavengood 		case MSG_RESIZER_WINDOW_QUIT:
8616163f333SKarsten Heimrich 			delete fResizerWindowMessenger;
862d9f6762dSMichael Pfeiffer 			fResizerWindowMessenger = NULL;
863d9f6762dSMichael Pfeiffer 			break;
864d9f6762dSMichael Pfeiffer 
865*cd6b5cdeSAxel Dörfler 		case MSG_DESKTOP_BACKGROUND:
866*cd6b5cdeSAxel Dörfler 		{
8670a74004cSRyan Leavengood 			BMessage message(B_REFS_RECEIVED);
8680a74004cSRyan Leavengood 			message.AddRef("refs", fImageView->Image());
8690a74004cSRyan Leavengood 			// This is used in the Backgrounds code for scaled placement
8700a74004cSRyan Leavengood 			message.AddInt32("placement", 'scpl');
8710a74004cSRyan Leavengood 			be_roster->Launch("application/x-vnd.haiku-backgrounds", &message);
872*cd6b5cdeSAxel Dörfler 			break;
873*cd6b5cdeSAxel Dörfler 		}
874a60adbf9SAxel Dörfler 
87513afa642SPhil Greenway 		default:
876efa8b4f3SAxel Dörfler 			BWindow::MessageReceived(message);
87713afa642SPhil Greenway 			break;
87813afa642SPhil Greenway 	}
87913afa642SPhil Greenway }
880fc0a275bSMatthew Wilber 
881efa8b4f3SAxel Dörfler 
882fc0a275bSMatthew Wilber void
883*cd6b5cdeSAxel Dörfler ShowImageWindow::_UpdateStatusText(const BMessage* message)
884*cd6b5cdeSAxel Dörfler {
885*cd6b5cdeSAxel Dörfler 	BString status;
886*cd6b5cdeSAxel Dörfler 	if (fImageView->Bitmap() != NULL) {
887*cd6b5cdeSAxel Dörfler 		BRect bounds = fImageView->Bitmap()->Bounds();
888*cd6b5cdeSAxel Dörfler 		status << bounds.IntegerWidth() + 1
889*cd6b5cdeSAxel Dörfler 			<< "x" << bounds.IntegerHeight() + 1 << ", " << fImageType;
890*cd6b5cdeSAxel Dörfler 	}
891*cd6b5cdeSAxel Dörfler 
892*cd6b5cdeSAxel Dörfler 	BString text;
893*cd6b5cdeSAxel Dörfler 	if (message != NULL && message->FindString("status", &text) == B_OK
894*cd6b5cdeSAxel Dörfler 		&& text.Length() > 0) {
895*cd6b5cdeSAxel Dörfler 		status << ", " << text;
896*cd6b5cdeSAxel Dörfler 	}
897*cd6b5cdeSAxel Dörfler 
898*cd6b5cdeSAxel Dörfler 	fStatusView->SetText(status);
899*cd6b5cdeSAxel Dörfler }
900*cd6b5cdeSAxel Dörfler 
901*cd6b5cdeSAxel Dörfler 
902*cd6b5cdeSAxel Dörfler void
903*cd6b5cdeSAxel Dörfler ShowImageWindow::_LoadError(const entry_ref& ref)
904*cd6b5cdeSAxel Dörfler {
905*cd6b5cdeSAxel Dörfler 	// TODO: give a better error message!
906*cd6b5cdeSAxel Dörfler 	BAlert* alert = new BAlert(B_TRANSLATE("ShowImage"),
907*cd6b5cdeSAxel Dörfler 		B_TRANSLATE_WITH_CONTEXT("Could not load image! Either the "
908*cd6b5cdeSAxel Dörfler 			"file or an image translator for it does not exist.",
909*cd6b5cdeSAxel Dörfler 			"LoadAlerts"),
910*cd6b5cdeSAxel Dörfler 		B_TRANSLATE_WITH_CONTEXT("OK", "Alerts"), NULL, NULL,
911*cd6b5cdeSAxel Dörfler 		B_WIDTH_AS_USUAL, B_INFO_ALERT);
912*cd6b5cdeSAxel Dörfler 	alert->Go();
913*cd6b5cdeSAxel Dörfler }
914*cd6b5cdeSAxel Dörfler 
915*cd6b5cdeSAxel Dörfler 
916*cd6b5cdeSAxel Dörfler void
917fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message)
918fc0a275bSMatthew Wilber {
919cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
920cdb89ebbSMatthew Wilber 	translator_id outTranslator;
921cdb89ebbSMatthew Wilber 	uint32 outType;
9226163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
923efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9246163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
925cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
926fc0a275bSMatthew Wilber 		return;
927fc0a275bSMatthew Wilber 
928cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
929cdb89ebbSMatthew Wilber 	// message that the save panel will send back
930c1a10c14SKarsten Heimrich 	BMessage panelMsg(MSG_SAVE_PANEL);
931c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTranslatorField, outTranslator);
932c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTypeField, outType);
933cdb89ebbSMatthew Wilber 
934cdb89ebbSMatthew Wilber 	// Create save panel and show it
9356163f333SKarsten Heimrich 	BMessenger target(this);
936efa8b4f3SAxel Dörfler 	fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
937c1a10c14SKarsten Heimrich 		&target, NULL, 0, false, &panelMsg);
938d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
939fc0a275bSMatthew Wilber 		return;
940a60adbf9SAxel Dörfler 
941d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
942d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
943fc0a275bSMatthew Wilber }
944fc0a275bSMatthew Wilber 
945efa8b4f3SAxel Dörfler 
946fc0a275bSMatthew Wilber void
947fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message)
948fc0a275bSMatthew Wilber {
949cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
950efa8b4f3SAxel Dörfler 	entry_ref dirRef;
951efa8b4f3SAxel Dörfler 	if (message->FindRef("directory", &dirRef) != B_OK)
952fc0a275bSMatthew Wilber 		return;
953efa8b4f3SAxel Dörfler 
954fc0a275bSMatthew Wilber 	const char* filename;
955efa8b4f3SAxel Dörfler 	if (message->FindString("name", &filename) != B_OK)
956fc0a275bSMatthew Wilber 		return;
957fc0a275bSMatthew Wilber 
958cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
959cdb89ebbSMatthew Wilber 	// to save the output image
960cdb89ebbSMatthew Wilber 	translator_id outTranslator;
961cdb89ebbSMatthew Wilber 	uint32 outType;
9626163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
963efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9646163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
965cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
966cdb89ebbSMatthew Wilber 		return;
967cdb89ebbSMatthew Wilber 
968a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
969a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
970a7e78e3bSMatthew Wilber 	BTranslatorRoster* roster = BTranslatorRoster::Default();
971efa8b4f3SAxel Dörfler 	const translation_format* outFormat = NULL;
972efa8b4f3SAxel Dörfler 	int32 outCount = 0;
973efa8b4f3SAxel Dörfler 	if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
974efa8b4f3SAxel Dörfler 		|| outCount < 1)
975a7e78e3bSMatthew Wilber 		return;
976efa8b4f3SAxel Dörfler 
977a7e78e3bSMatthew Wilber 	int32 i;
978efa8b4f3SAxel Dörfler 	for (i = 0; i < outCount; i++) {
979efa8b4f3SAxel Dörfler 		if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
980a7e78e3bSMatthew Wilber 			break;
981a7e78e3bSMatthew Wilber 	}
982efa8b4f3SAxel Dörfler 	if (i == outCount)
983fc0a275bSMatthew Wilber 		return;
984fc0a275bSMatthew Wilber 
985a7e78e3bSMatthew Wilber 	// Write out the image file
986efa8b4f3SAxel Dörfler 	BDirectory dir(&dirRef);
987efa8b4f3SAxel Dörfler 	fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
988fc0a275bSMatthew Wilber }
989fc0a275bSMatthew Wilber 
990efa8b4f3SAxel Dörfler 
9914eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
9924eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "ClosePrompt"
9931ed4535fSStephan Aßmus 
994cdb89ebbSMatthew Wilber bool
995fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt()
996ee7b4f39SMatthew Wilber {
997ee7b4f39SMatthew Wilber 	if (!fModified)
998ee7b4f39SMatthew Wilber 		return true;
999efa8b4f3SAxel Dörfler 
1000*cd6b5cdeSAxel Dörfler 	int32 count = fNavigator.PageCount();
1001*cd6b5cdeSAxel Dörfler 	int32 page = fNavigator.CurrentPage();
1002*cd6b5cdeSAxel Dörfler 	BString prompt;
1003efa8b4f3SAxel Dörfler 
10041ed4535fSStephan Aßmus 	if (count > 1) {
10051ed4535fSStephan Aßmus 		bs_printf(&prompt,
1006905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' (page %d) has been changed. Do you "
1007905c8c8cSMatt Madia 				"want to close the document?"),
1008*cd6b5cdeSAxel Dörfler 			fImageView->Image()->name, page);
10091ed4535fSStephan Aßmus 	} else {
10101ed4535fSStephan Aßmus 		bs_printf(&prompt,
1011905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' has been changed. Do you want to "
1012905c8c8cSMatt Madia 				"close the document?"),
1013*cd6b5cdeSAxel Dörfler 			fImageView->Image()->name);
10141ed4535fSStephan Aßmus 	}
10151ed4535fSStephan Aßmus 
1016*cd6b5cdeSAxel Dörfler 	BAlert* alert = new BAlert(B_TRANSLATE("Close document"), prompt.String(),
1017905c8c8cSMatt Madia 		B_TRANSLATE("Cancel"), B_TRANSLATE("Close"));
1018*cd6b5cdeSAxel Dörfler 	if (alert->Go() == 0) {
1019ee7b4f39SMatthew Wilber 		// Cancel
1020ee7b4f39SMatthew Wilber 		return false;
1021*cd6b5cdeSAxel Dörfler 	}
1022*cd6b5cdeSAxel Dörfler 
1023ee7b4f39SMatthew Wilber 	// Close
1024187f0b8aSMatthew Wilber 	fModified = false;
1025ee7b4f39SMatthew Wilber 	return true;
1026ee7b4f39SMatthew Wilber }
1027ee7b4f39SMatthew Wilber 
1028cdb89ebbSMatthew Wilber 
1029ad13f387SMichael Pfeiffer void
1030fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen()
1031ad13f387SMichael Pfeiffer {
1032ad13f387SMichael Pfeiffer 	BRect frame;
1033ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
1034ad13f387SMichael Pfeiffer 	if (fFullScreen) {
1035ad13f387SMichael Pfeiffer 		BScreen screen;
1036ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
1037ad13f387SMichael Pfeiffer 		frame = screen.Frame();
1038d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
1039ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
1040ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
1041ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
1042ad13f387SMichael Pfeiffer 
1043ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
1044c0b16687SAxel Dörfler 
1045c0b16687SAxel Dörfler 		Activate();
1046c0b16687SAxel Dörfler 			// make the window frontmost
1047ad13f387SMichael Pfeiffer 	} else {
1048ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
1049ad13f387SMichael Pfeiffer 
1050ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
1051ad13f387SMichael Pfeiffer 	}
1052efa8b4f3SAxel Dörfler 
105376d115d8SRyan Leavengood 	fImageView->SetFullScreen(fFullScreen);
1054d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
1055ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
1056ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
1057ad13f387SMichael Pfeiffer }
1058ad13f387SMichael Pfeiffer 
1059efa8b4f3SAxel Dörfler 
1060d3046f7dSMichael Pfeiffer void
1061fd952aefSRyan Leavengood ShowImageWindow::_LoadSettings()
1062d3046f7dSMichael Pfeiffer {
1063efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1064efa8b4f3SAxel Dörfler 
1065d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1066d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
1067d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
1068d3046f7dSMichael Pfeiffer 
1069efa8b4f3SAxel Dörfler 		int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option());
1070d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
1071d3046f7dSMichael Pfeiffer 
1072efa8b4f3SAxel Dörfler 		float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1073d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
1074d3046f7dSMichael Pfeiffer 
1075d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
1076d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
1077d3046f7dSMichael Pfeiffer 
1078d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
1079d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
1080d3046f7dSMichael Pfeiffer 
1081d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
1082d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
1083d3046f7dSMichael Pfeiffer 
1084d3046f7dSMichael Pfeiffer 		settings->Unlock();
1085d3046f7dSMichael Pfeiffer 	}
1086d3046f7dSMichael Pfeiffer }
1087d3046f7dSMichael Pfeiffer 
1088efa8b4f3SAxel Dörfler 
1089d3046f7dSMichael Pfeiffer void
1090fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions()
1091d3046f7dSMichael Pfeiffer {
1092efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1093efa8b4f3SAxel Dörfler 
1094d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1095d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
1096d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1097d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1098d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
1099d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
1100d3046f7dSMichael Pfeiffer 		settings->Unlock();
1101d3046f7dSMichael Pfeiffer 	}
1102d3046f7dSMichael Pfeiffer }
1103d3046f7dSMichael Pfeiffer 
1104efa8b4f3SAxel Dörfler 
1105cdb89ebbSMatthew Wilber bool
1106fd952aefSRyan Leavengood ShowImageWindow::_PageSetup()
1107780d8a62SMichael Pfeiffer {
1108*cd6b5cdeSAxel Dörfler 	BPrintJob printJob(fImageView->Image()->name);
1109efa8b4f3SAxel Dörfler 	if (fPrintSettings != NULL)
1110780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
1111efa8b4f3SAxel Dörfler 
11126163f333SKarsten Heimrich 	status_t status = printJob.ConfigPage();
11136163f333SKarsten Heimrich 	if (status == B_OK) {
1114780d8a62SMichael Pfeiffer 		delete fPrintSettings;
1115780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
1116780d8a62SMichael Pfeiffer 	}
1117efa8b4f3SAxel Dörfler 
11186163f333SKarsten Heimrich 	return status == B_OK;
1119780d8a62SMichael Pfeiffer }
1120780d8a62SMichael Pfeiffer 
1121efa8b4f3SAxel Dörfler 
1122780d8a62SMichael Pfeiffer void
1123fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint()
1124780d8a62SMichael Pfeiffer {
11256163f333SKarsten Heimrich 	if (fPrintSettings == NULL) {
1126*cd6b5cdeSAxel Dörfler 		BPrintJob printJob(fImageView->Image()->name);
11276163f333SKarsten Heimrich 		if (printJob.ConfigJob() == B_OK)
11286163f333SKarsten Heimrich 			fPrintSettings = printJob.Settings();
11296163f333SKarsten Heimrich 	}
1130780d8a62SMichael Pfeiffer 
1131*cd6b5cdeSAxel Dörfler 	fPrintOptions.SetBounds(fImageView->Bitmap()->Bounds());
1132*cd6b5cdeSAxel Dörfler 	fPrintOptions.SetWidth(fImageView->Bitmap()->Bounds().Width() + 1);
1133780d8a62SMichael Pfeiffer 
1134efa8b4f3SAxel Dörfler 	new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50),
1135efa8b4f3SAxel Dörfler 		&fPrintOptions, this);
1136780d8a62SMichael Pfeiffer }
1137780d8a62SMichael Pfeiffer 
1138efa8b4f3SAxel Dörfler 
1139780d8a62SMichael Pfeiffer void
1140fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg)
1141780d8a62SMichael Pfeiffer {
1142780d8a62SMichael Pfeiffer 	status_t st;
1143efa8b4f3SAxel Dörfler 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1144780d8a62SMichael Pfeiffer 		return;
1145780d8a62SMichael Pfeiffer 
1146fd952aefSRyan Leavengood 	_SavePrintOptions();
1147d3046f7dSMichael Pfeiffer 
1148*cd6b5cdeSAxel Dörfler 	BPrintJob printJob(fImageView->Image()->name);
11496163f333SKarsten Heimrich 	if (fPrintSettings)
1150780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
11516163f333SKarsten Heimrich 
1152780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
11536163f333SKarsten Heimrich 		delete fPrintSettings;
11546163f333SKarsten Heimrich 		fPrintSettings = printJob.Settings();
1155780d8a62SMichael Pfeiffer 
1156780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
11573177ae77SStefano Ceccherini 		int32 firstPage = printJob.FirstPage();
11583177ae77SStefano Ceccherini 		int32 lastPage = printJob.LastPage();
11596163f333SKarsten Heimrich 		BRect printableRect = printJob.PrintableRect();
11606163f333SKarsten Heimrich 
1161efa8b4f3SAxel Dörfler 		if (firstPage < 1)
1162780d8a62SMichael Pfeiffer 			firstPage = 1;
1163efa8b4f3SAxel Dörfler 		if (lastPage < firstPage)
1164780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1165780d8a62SMichael Pfeiffer 
1166*cd6b5cdeSAxel Dörfler 		BBitmap* bitmap = fImageView->Bitmap();
11673177ae77SStefano Ceccherini 		float imageWidth = bitmap->Bounds().Width() + 1.0;
11683177ae77SStefano Ceccherini 		float imageHeight = bitmap->Bounds().Height() + 1.0;
1169780d8a62SMichael Pfeiffer 
11706163f333SKarsten Heimrich 		float width;
1171780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
11726163f333SKarsten Heimrich 			case PrintOptions::kFitToPage: {
11736163f333SKarsten Heimrich 				float w1 = printableRect.Width()+1;
1174*cd6b5cdeSAxel Dörfler 				float w2 = imageWidth * (printableRect.Height() + 1)
1175*cd6b5cdeSAxel Dörfler 					/ imageHeight;
1176efa8b4f3SAxel Dörfler 				if (w2 < w1)
1177780d8a62SMichael Pfeiffer 					width = w2;
1178efa8b4f3SAxel Dörfler 				else
1179780d8a62SMichael Pfeiffer 					width = w1;
11806163f333SKarsten Heimrich 			}	break;
1181780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1182780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1183780d8a62SMichael Pfeiffer 				break;
1184780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1185780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1186780d8a62SMichael Pfeiffer 				break;
1187780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1188780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1189780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1190780d8a62SMichael Pfeiffer 				break;
1191efa8b4f3SAxel Dörfler 
1192780d8a62SMichael Pfeiffer 			default:
1193780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1194780d8a62SMichael Pfeiffer 				width = imageWidth;
1195780d8a62SMichael Pfeiffer 		}
1196780d8a62SMichael Pfeiffer 
1197efa8b4f3SAxel Dörfler 		// TODO: eventually print large images on several pages
1198780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1199d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
12005eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
12015eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
12025eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1203d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1204780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1205780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1206780d8a62SMichael Pfeiffer 	}
1207780d8a62SMichael Pfeiffer }
1208780d8a62SMichael Pfeiffer 
120956b0c7b9SKarsten Heimrich 
1210d9f6762dSMichael Pfeiffer void
1211fd952aefSRyan Leavengood ShowImageWindow::_OpenResizerWindow(int32 width, int32 height)
1212d9f6762dSMichael Pfeiffer {
1213d9f6762dSMichael Pfeiffer 	if (fResizerWindowMessenger == NULL) {
1214d9f6762dSMichael Pfeiffer 		// open window if it is not already opened
1215d9f6762dSMichael Pfeiffer 		BWindow* window = new ResizerWindow(this, width, height);
1216d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger = new BMessenger(window);
1217d9f6762dSMichael Pfeiffer 		window->Show();
12186163f333SKarsten Heimrich 	} else {
1219d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger->SendMessage(ResizerWindow::kActivateMsg);
1220d9f6762dSMichael Pfeiffer 	}
12216163f333SKarsten Heimrich }
1222d9f6762dSMichael Pfeiffer 
122356b0c7b9SKarsten Heimrich 
1224d9f6762dSMichael Pfeiffer void
1225fd952aefSRyan Leavengood ShowImageWindow::_UpdateResizerWindow(int32 width, int32 height)
1226d9f6762dSMichael Pfeiffer {
12276163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1228d9f6762dSMichael Pfeiffer 		return;
1229d9f6762dSMichael Pfeiffer 
1230d9f6762dSMichael Pfeiffer 	BMessage updateMsg(ResizerWindow::kUpdateMsg);
12310acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("width", width);
12320acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("height", height);
1233d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(&updateMsg);
1234d9f6762dSMichael Pfeiffer }
1235d9f6762dSMichael Pfeiffer 
123656b0c7b9SKarsten Heimrich 
1237d9f6762dSMichael Pfeiffer void
1238fd952aefSRyan Leavengood ShowImageWindow::_CloseResizerWindow()
1239d9f6762dSMichael Pfeiffer {
12406163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1241d9f6762dSMichael Pfeiffer 		return;
12426163f333SKarsten Heimrich 
1243d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(B_QUIT_REQUESTED);
12446163f333SKarsten Heimrich 	delete fResizerWindowMessenger;
1245d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger = NULL;
1246d9f6762dSMichael Pfeiffer }
1247efa8b4f3SAxel Dörfler 
124856b0c7b9SKarsten Heimrich 
1249780d8a62SMichael Pfeiffer bool
1250cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1251cdb89ebbSMatthew Wilber {
1252efa8b4f3SAxel Dörfler 	if (fSavePanel) {
1253efa8b4f3SAxel Dörfler 		// Don't allow this window to be closed if a save panel is open
1254efa8b4f3SAxel Dörfler 		return false;
1255cdb89ebbSMatthew Wilber 	}
1256cdb89ebbSMatthew Wilber 
1257fd952aefSRyan Leavengood 	bool quit = _ClosePrompt();
1258efa8b4f3SAxel Dörfler 
1259efa8b4f3SAxel Dörfler 	if (quit) {
1260fd952aefSRyan Leavengood 		_CloseResizerWindow();
1261d9f6762dSMichael Pfeiffer 
126207caaa8eSMatthew Wilber 		// tell the app to forget about this window
126307caaa8eSMatthew Wilber 		be_app->PostMessage(MSG_WINDOW_QUIT);
126407caaa8eSMatthew Wilber 	}
1265fc0a275bSMatthew Wilber 
1266efa8b4f3SAxel Dörfler 	return quit;
1267efa8b4f3SAxel Dörfler }
1268