xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision 36c176518ba399477369bc6a24a85ca4f6726b51)
1efa8b4f3SAxel Dörfler /*
2fd952aefSRyan Leavengood  * Copyright 2003-2009, 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 
15efa8b4f3SAxel Dörfler #include "ShowImageWindow.h"
16efa8b4f3SAxel Dörfler 
17fd952aefSRyan Leavengood #include <new>
18fd952aefSRyan Leavengood #include <stdio.h>
196163f333SKarsten Heimrich 
20efa8b4f3SAxel Dörfler #include <Alert.h>
2113afa642SPhil Greenway #include <Application.h>
2213afa642SPhil Greenway #include <Bitmap.h>
23fc0a275bSMatthew Wilber #include <BitmapStream.h>
241ed4535fSStephan Aßmus #include <Catalog.h>
25efa8b4f3SAxel Dörfler #include <Clipboard.h>
2613afa642SPhil Greenway #include <Entry.h>
27fc0a275bSMatthew Wilber #include <File.h>
286163f333SKarsten Heimrich #include <FilePanel.h>
291ed4535fSStephan Aßmus #include <Locale.h>
3013afa642SPhil Greenway #include <Menu.h>
3113afa642SPhil Greenway #include <MenuBar.h>
3213afa642SPhil Greenway #include <MenuItem.h>
3313afa642SPhil Greenway #include <Path.h>
34efa8b4f3SAxel Dörfler #include <PrintJob.h>
35efa8b4f3SAxel Dörfler #include <Roster.h>
36efa8b4f3SAxel Dörfler #include <Screen.h>
3713afa642SPhil Greenway #include <ScrollView.h>
386163f333SKarsten Heimrich #include <String.h>
39efa8b4f3SAxel Dörfler #include <SupportDefs.h>
406163f333SKarsten Heimrich #include <TranslationDefs.h>
4113afa642SPhil Greenway #include <TranslationUtils.h>
4213afa642SPhil Greenway #include <TranslatorRoster.h>
431ed4535fSStephan Aßmus #include <stdlib.h> // for bs_printf()
4413afa642SPhil Greenway 
45fd952aefSRyan Leavengood #include "EntryMenuItem.h"
46fd952aefSRyan Leavengood #include "ResizerWindow.h"
47fd952aefSRyan Leavengood #include "ShowImageApp.h"
48fd952aefSRyan Leavengood #include "ShowImageConstants.h"
49fd952aefSRyan Leavengood #include "ShowImageStatusView.h"
50fd952aefSRyan Leavengood #include "ShowImageView.h"
5113afa642SPhil Greenway 
52a8fc7138SMichael Pfeiffer 
536163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow::RecentDocumentsMenu
546163f333SKarsten Heimrich 
556163f333SKarsten Heimrich class ShowImageWindow::RecentDocumentsMenu : public BMenu {
566163f333SKarsten Heimrich public:
576163f333SKarsten Heimrich 			RecentDocumentsMenu(const char* title,
586163f333SKarsten Heimrich 				menu_layout layout = B_ITEMS_IN_COLUMN);
596163f333SKarsten Heimrich 	bool	AddDynamicItem(add_state addState);
606163f333SKarsten Heimrich 
616163f333SKarsten Heimrich private:
626163f333SKarsten Heimrich 	void	UpdateRecentDocumentsMenu();
636163f333SKarsten Heimrich };
646163f333SKarsten Heimrich 
656163f333SKarsten Heimrich 
666163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::RecentDocumentsMenu(const char* title,
676163f333SKarsten Heimrich 	menu_layout layout)
68fd952aefSRyan Leavengood 	:
69fd952aefSRyan Leavengood 	BMenu(title, layout)
70a8fc7138SMichael Pfeiffer {
71a8fc7138SMichael Pfeiffer }
72a8fc7138SMichael Pfeiffer 
73efa8b4f3SAxel Dörfler 
74a8fc7138SMichael Pfeiffer bool
756163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::AddDynamicItem(add_state addState)
76a8fc7138SMichael Pfeiffer {
77a60adbf9SAxel Dörfler 	if (addState != B_INITIAL_ADD)
78efa8b4f3SAxel Dörfler 		return false;
79a8fc7138SMichael Pfeiffer 
806163f333SKarsten Heimrich 	while (CountItems() > 0)
816163f333SKarsten Heimrich 		delete RemoveItem(0L);
826163f333SKarsten Heimrich 
83a8fc7138SMichael Pfeiffer 	BMenuItem* item;
84a8fc7138SMichael Pfeiffer 	BMessage list, *msg;
85a8fc7138SMichael Pfeiffer 	entry_ref ref;
86a8fc7138SMichael Pfeiffer 	char name[B_FILE_NAME_LENGTH];
87a8fc7138SMichael Pfeiffer 
88efa8b4f3SAxel Dörfler 	be_roster->GetRecentDocuments(&list, 20, NULL, kApplicationSignature);
89a8fc7138SMichael Pfeiffer 	for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
90a8fc7138SMichael Pfeiffer 		BEntry entry(&ref);
91a8fc7138SMichael Pfeiffer 		if (entry.Exists() && entry.GetName(name) == B_OK) {
92a8fc7138SMichael Pfeiffer 			msg = new BMessage(B_REFS_RECEIVED);
93a8fc7138SMichael Pfeiffer 			msg->AddRef("refs", &ref);
94a8fc7138SMichael Pfeiffer 			item = new EntryMenuItem(&ref, name, msg, 0, 0);
95a8fc7138SMichael Pfeiffer 			AddItem(item);
96a8fc7138SMichael Pfeiffer 			item->SetTarget(be_app, NULL);
97a8fc7138SMichael Pfeiffer 		}
98a8fc7138SMichael Pfeiffer 	}
99a8fc7138SMichael Pfeiffer 
100a8fc7138SMichael Pfeiffer 	return false;
101a8fc7138SMichael Pfeiffer }
102a8fc7138SMichael Pfeiffer 
103a8fc7138SMichael Pfeiffer 
1046163f333SKarsten Heimrich //	#pragma mark -- ShowImageWindow
1056163f333SKarsten Heimrich 
1066163f333SKarsten Heimrich 
1076163f333SKarsten Heimrich // BMessage field names used in Save messages
1086163f333SKarsten Heimrich const char* kTypeField = "be:type";
1096163f333SKarsten Heimrich const char* kTranslatorField = "be:translator";
110a8fc7138SMichael Pfeiffer 
111efa8b4f3SAxel Dörfler 
112efa8b4f3SAxel Dörfler ShowImageWindow::ShowImageWindow(const entry_ref* ref,
113efa8b4f3SAxel Dörfler 	const BMessenger& trackerMessenger)
114fd952aefSRyan Leavengood 	:
115fd952aefSRyan Leavengood 	BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0),
116fd952aefSRyan Leavengood 	fSavePanel(NULL),
117fd952aefSRyan Leavengood 	fBar(NULL),
118fd952aefSRyan Leavengood 	fOpenMenu(NULL),
119fd952aefSRyan Leavengood 	fBrowseMenu(NULL),
120fd952aefSRyan Leavengood 	fGoToPageMenu(NULL),
121fd952aefSRyan Leavengood 	fSlideShowDelay(NULL),
122fd952aefSRyan Leavengood 	fImageView(NULL),
123fd952aefSRyan Leavengood 	fStatusView(NULL),
124fd952aefSRyan Leavengood 	fModified(false),
125fd952aefSRyan Leavengood 	fFullScreen(false),
126fd952aefSRyan Leavengood 	fShowCaption(true),
127fd952aefSRyan Leavengood 	fPrintSettings(NULL),
128fd952aefSRyan Leavengood 	fResizerWindowMessenger(NULL),
129fd952aefSRyan Leavengood 	fResizeItem(NULL),
130fd952aefSRyan Leavengood 	fHeight(0),
131fd952aefSRyan Leavengood 	fWidth(0)
13213afa642SPhil Greenway {
133fd952aefSRyan Leavengood 	_LoadSettings();
134fc0a275bSMatthew Wilber 
13513afa642SPhil Greenway 	// create menu bar
136e9dcd874SAxel Dörfler 	fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar");
137efa8b4f3SAxel Dörfler 	AddMenus(fBar);
138e9dcd874SAxel Dörfler 	AddChild(fBar);
13913afa642SPhil Greenway 
14013afa642SPhil Greenway 	BRect viewFrame = Bounds();
141e9dcd874SAxel Dörfler 	viewFrame.top = fBar->Bounds().Height() + 1;
14213afa642SPhil Greenway 	viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
14313afa642SPhil Greenway 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
14413afa642SPhil Greenway 
14513afa642SPhil Greenway 	// create the image view
146d3046f7dSMichael Pfeiffer 	fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
1477eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
14813afa642SPhil Greenway 	// wrap a scroll view around the view
149efa8b4f3SAxel Dörfler 	BScrollView* scrollView = new BScrollView("image_scroller", fImageView,
150cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
151efa8b4f3SAxel Dörfler 	AddChild(scrollView);
15213afa642SPhil Greenway 
15307caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
154cdb89ebbSMatthew Wilber 	BRect rect;
15513afa642SPhil Greenway 	rect = Bounds();
15613afa642SPhil Greenway 	rect.top	= viewFrame.bottom + 1;
15707caaa8eSMatthew Wilber 	rect.left 	= viewFrame.left + kstatusWidth;
1580916ab53SMatthew Wilber 	rect.right	= viewFrame.right + 1;
1590916ab53SMatthew Wilber 	rect.bottom += 1;
160efa8b4f3SAxel Dörfler 	BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll",
161efa8b4f3SAxel Dörfler 		fImageView, 0, 150, B_HORIZONTAL);
162efa8b4f3SAxel Dörfler 	AddChild(horizontalScrollBar);
16313afa642SPhil Greenway 
16413afa642SPhil Greenway 	rect.left = 0;
16507caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
1660cd4ecd8SStephan Aßmus 	rect.bottom -= 1;
167d3046f7dSMichael Pfeiffer 	fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
168cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
169d3046f7dSMichael Pfeiffer 	AddChild(fStatusView);
17013afa642SPhil Greenway 
17113afa642SPhil Greenway 	rect = Bounds();
1720916ab53SMatthew Wilber 	rect.top	= viewFrame.top - 1;
17313afa642SPhil Greenway 	rect.left	= viewFrame.right + 1;
1740916ab53SMatthew Wilber 	rect.bottom	= viewFrame.bottom + 1;
1750916ab53SMatthew Wilber 	rect.right	+= 1;
176efa8b4f3SAxel Dörfler 	BScrollBar* verticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
177efa8b4f3SAxel Dörfler 		0, 150, B_VERTICAL);
178efa8b4f3SAxel Dörfler 	AddChild(verticalScrollBar);
17913afa642SPhil Greenway 
18003839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
18113afa642SPhil Greenway 
182134d6076SMichael Pfeiffer 	// finish creating the window
183efa8b4f3SAxel Dörfler 	fImageView->SetImage(ref);
184134d6076SMichael Pfeiffer 	fImageView->SetTrackerMessenger(trackerMessenger);
1857eca0987SMichael Pfeiffer 
1864eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
1874eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "LoadAlerts"
1881ed4535fSStephan Aßmus 
189d9f6762dSMichael Pfeiffer 	if (InitCheck() != B_OK) {
190e6a50d9cSMichael Pfeiffer 		BAlert* alert;
191905c8c8cSMatt Madia 		alert = new BAlert(
192905c8c8cSMatt Madia 			B_TRANSLATE("ShowImage"),
193905c8c8cSMatt Madia 			B_TRANSLATE("Could not load image! Either the file or an image "
194905c8c8cSMatt Madia 				"translator for it does not exist."),
195905c8c8cSMatt Madia 			B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
196e6a50d9cSMichael Pfeiffer 		alert->Go();
197efa8b4f3SAxel Dörfler 
1985e09d5dbSRyan Leavengood 		// quit if file could not be opened
1995e09d5dbSRyan Leavengood 		Quit();
200efa8b4f3SAxel Dörfler 		return;
201d10d5947SMichael Pfeiffer 	}
202402c09e5SMatthew Wilber 
2034eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
2044eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus"
2051ed4535fSStephan Aßmus 
206d9f6762dSMichael Pfeiffer 	// add View menu here so it can access ShowImageView methods
207905c8c8cSMatt Madia 	BMenu* menu = new BMenu(B_TRANSLATE("View"));
208fd952aefSRyan Leavengood 	_BuildViewMenu(menu, false);
209d9f6762dSMichael Pfeiffer 	fBar->AddItem(menu);
210fd952aefSRyan Leavengood 	_MarkMenuItem(fBar, MSG_DITHER_IMAGE, fImageView->GetDither());
211d9f6762dSMichael Pfeiffer 	UpdateTitle();
212d9f6762dSMichael Pfeiffer 
213d9f6762dSMichael Pfeiffer 	SetPulseRate(100000);
214d9f6762dSMichael Pfeiffer 		// every 1/10 second; ShowImageView needs it for marching ants
215d9f6762dSMichael Pfeiffer 
216d9f6762dSMichael Pfeiffer 	WindowRedimension(fImageView->GetBitmap());
217d9f6762dSMichael Pfeiffer 	fImageView->MakeFocus(true); // to receive KeyDown messages
218d9f6762dSMichael Pfeiffer 	Show();
219d9f6762dSMichael Pfeiffer 
220402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
221402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
222402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
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 status_t
233cdb89ebbSMatthew Wilber ShowImageWindow::InitCheck()
23413afa642SPhil Greenway {
235d3046f7dSMichael Pfeiffer 	if (!fImageView || fImageView->GetBitmap() == NULL)
23613afa642SPhil Greenway 		return B_ERROR;
237efa8b4f3SAxel Dörfler 
23813afa642SPhil Greenway 	return B_OK;
23913afa642SPhil Greenway }
240cdb89ebbSMatthew Wilber 
241efa8b4f3SAxel Dörfler 
242cdb89ebbSMatthew Wilber void
243cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
24413afa642SPhil Greenway {
245e6a50d9cSMichael Pfeiffer 	BString path;
246d3046f7dSMichael Pfeiffer 	fImageView->GetPath(&path);
247e6a50d9cSMichael Pfeiffer 	SetTitle(path.String());
24813afa642SPhil Greenway }
24913afa642SPhil Greenway 
25056b0c7b9SKarsten Heimrich 
251d9f6762dSMichael Pfeiffer void
252d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu)
253d9f6762dSMichael Pfeiffer {
254fd952aefSRyan Leavengood 	_BuildViewMenu(menu, true);
255d9f6762dSMichael Pfeiffer }
256efa8b4f3SAxel Dörfler 
25756b0c7b9SKarsten Heimrich 
2584eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
2594eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus"
2601ed4535fSStephan Aßmus 
261cdb89ebbSMatthew Wilber void
262fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
263da87390fSMichael Pfeiffer {
264905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this);
265fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
266905c8c8cSMatt Madia 	BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay"));
267efa8b4f3SAxel Dörfler 	if (fSlideShowDelay == NULL)
268efa8b4f3SAxel Dörfler 		fSlideShowDelay = delayMenu;
269efa8b4f3SAxel Dörfler 
270efa8b4f3SAxel Dörfler 	delayMenu->SetRadioMode(true);
27156b0c7b9SKarsten Heimrich 	// Note: ShowImage loads images in window thread so it becomes unresponsive
27256b0c7b9SKarsten Heimrich 	//		 if slide show delay is too short! (Especially if loading the image
27356b0c7b9SKarsten Heimrich 	//		 takes as long as or longer than the slide show delay). Should load
27456b0c7b9SKarsten Heimrich 	//		 in background thread!
275905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("3 seconds"), 3);
276905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("4 seconds"), 4);
277905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("5 seconds"), 5);
278905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("6 seconds"), 6);
279905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("7 seconds"), 7);
280905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("8 seconds"), 8);
281905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("9 seconds"), 9);
282905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("10 seconds"), 10);
283905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("20 seconds"), 20);
284efa8b4f3SAxel Dörfler 	menu->AddItem(delayMenu);
28530060f17SMatthew Wilber 
286efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
287efa8b4f3SAxel Dörfler 
288905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Original size"),
289905c8c8cSMatt Madia 		MSG_ORIGINAL_SIZE, '1', 0, this);
290905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this);
291905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this);
292efa8b4f3SAxel Dörfler 
293efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
294efa8b4f3SAxel Dörfler 
295905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
296905c8c8cSMatt Madia 		MSG_SCALE_BILINEAR, 0, 0, this);
297efa8b4f3SAxel Dörfler 
298efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
299efa8b4f3SAxel Dörfler 
300905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Shrink to window"),
301905c8c8cSMatt Madia 		MSG_SHRINK_TO_WINDOW, 0, 0, this);
302905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom to window"),
303905c8c8cSMatt Madia 		MSG_ZOOM_TO_WINDOW, 0, 0, this);
304efa8b4f3SAxel Dörfler 
305efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
306efa8b4f3SAxel Dörfler 
307905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Full screen"),
308905c8c8cSMatt Madia 		MSG_FULL_SCREEN, B_ENTER, 0, this);
309fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
310efa8b4f3SAxel Dörfler 
311905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"),
312905c8c8cSMatt Madia 		MSG_SHOW_CAPTION, 0, 0, this);
313fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
314efa8b4f3SAxel Dörfler 
315fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
316da87390fSMichael Pfeiffer 
31719c76de4SMichael Pfeiffer 	bool shrink, zoom, enabled;
318efa8b4f3SAxel Dörfler 
319d3046f7dSMichael Pfeiffer 	shrink = fImageView->GetShrinkToBounds();
320d3046f7dSMichael Pfeiffer 	zoom = fImageView->GetZoomToBounds();
321fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, shrink);
322fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_ZOOM_TO_WINDOW, zoom);
323efa8b4f3SAxel Dörfler 
32419c76de4SMichael Pfeiffer 	enabled = !(shrink || zoom);
325fd952aefSRyan Leavengood 	_EnableMenuItem(menu, MSG_ORIGINAL_SIZE, enabled);
326fd952aefSRyan Leavengood 	_EnableMenuItem(menu, MSG_ZOOM_IN, enabled);
327fd952aefSRyan Leavengood 	_EnableMenuItem(menu, MSG_ZOOM_OUT, enabled);
328a60adbf9SAxel Dörfler 
329d9f6762dSMichael Pfeiffer 	if (popupMenu) {
330a60adbf9SAxel 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);
333d9f6762dSMichael Pfeiffer 	}
334da87390fSMichael Pfeiffer }
335da87390fSMichael Pfeiffer 
336efa8b4f3SAxel Dörfler 
337da87390fSMichael Pfeiffer void
338efa8b4f3SAxel Dörfler ShowImageWindow::AddMenus(BMenuBar* bar)
33913afa642SPhil Greenway {
340905c8c8cSMatt Madia 	BMenu* menu = new BMenu(B_TRANSLATE("File"));
341905c8c8cSMatt Madia 	fOpenMenu = new RecentDocumentsMenu(B_TRANSLATE("Open"));
342efa8b4f3SAxel Dörfler 	menu->AddItem(fOpenMenu);
343d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTrigger('O');
344d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
345d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTarget(be_app);
346d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetShortcut('O', 0);
347efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
348905c8c8cSMatt Madia 	BMenu *pmenuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS),
3491ed4535fSStephan Aßmus 		B_ITEMS_IN_COLUMN);
350cdb89ebbSMatthew Wilber 	BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP);
351fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
352fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
353efa8b4f3SAxel Dörfler 	menu->AddItem(pmenuSaveAs);
354905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this);
355efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
356905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS),
3571ed4535fSStephan Aßmus 		MSG_PAGE_SETUP, 0, 0, this);
358905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS),
3591ed4535fSStephan Aßmus 		MSG_PREPARE_PRINT, 'P', 0, this);
360efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
361905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("About ShowImage" B_UTF8_ELLIPSIS),
3621ed4535fSStephan Aßmus 		B_ABOUT_REQUESTED, 0, 0, 	be_app);
363efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
364905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app);
365efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
36613afa642SPhil Greenway 
367905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Edit"));
368905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Undo"), B_UNDO, 'Z', 0, this, false);
369efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
370905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Cut"), B_CUT, 'X', 0, this, false);
371905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false);
372905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Paste"), B_PASTE, 'V', 0, this, false);
373905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Clear"),
374905c8c8cSMatt Madia 		MSG_CLEAR_SELECT, 0, 0, this, false);
375efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
376905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Select all"),
377905c8c8cSMatt Madia 		MSG_SELECT_ALL, 'A', 0, this);
378efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
37913afa642SPhil Greenway 
380905c8c8cSMatt Madia 	menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse"));
381905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("First page"),
3821ed4535fSStephan Aßmus 		MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this);
383905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Last page"),
3841ed4535fSStephan Aßmus 		MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this);
385905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous page"),
386905c8c8cSMatt Madia 		MSG_PAGE_PREV, B_LEFT_ARROW, 0, this);
387905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next page"),
388905c8c8cSMatt Madia 		MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this);
389905c8c8cSMatt Madia 	fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page"));
3905e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
391efa8b4f3SAxel Dörfler 	menu->AddItem(fGoToPageMenu);
392efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
393905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous file"),
394905c8c8cSMatt Madia 		MSG_FILE_PREV, B_UP_ARROW, 0, this);
395905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next file"),
396905c8c8cSMatt Madia 		MSG_FILE_NEXT, B_DOWN_ARROW, 0, this);
397efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
39803839579SMatthew Wilber 
399905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Image"));
400905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"),
401905c8c8cSMatt Madia 		MSG_ROTATE_90, 'R', 0, this);
402905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"),
4031ed4535fSStephan Aßmus 		MSG_ROTATE_270, 'R', B_SHIFT_KEY, this);
404efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
405905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip left to right"),
4061ed4535fSStephan Aßmus 		MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this);
407905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"),
4081ed4535fSStephan Aßmus 		MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this);
409efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
410905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Invert colors"), MSG_INVERT, 0, 0, this);
411d9f6762dSMichael Pfeiffer 	menu->AddSeparatorItem();
412905c8c8cSMatt Madia 	fResizeItem = _AddItemMenu(menu, B_TRANSLATE("Resize" B_UTF8_ELLIPSIS),
4136163f333SKarsten Heimrich 		MSG_OPEN_RESIZER_WINDOW, 0, 0, this);
414efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
415d9f6762dSMichael Pfeiffer 	menu->AddSeparatorItem();
416905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
4171ed4535fSStephan Aßmus 		MSG_DESKTOP_BACKGROUND, 0, 0, this);
41813afa642SPhil Greenway }
41913afa642SPhil Greenway 
420efa8b4f3SAxel Dörfler 
421cdb89ebbSMatthew Wilber BMenuItem*
422fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what,
4236163f333SKarsten Heimrich 	const char shortcut, uint32 modifier, const BHandler* target, bool enabled)
424cdb89ebbSMatthew Wilber {
4256163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut, modifier);
426efa8b4f3SAxel Dörfler 	menu->AddItem(item);
427efa8b4f3SAxel Dörfler 
4286163f333SKarsten Heimrich 	item->SetTarget(target);
4296163f333SKarsten Heimrich 	item->SetEnabled(enabled);
4306163f333SKarsten Heimrich 
431efa8b4f3SAxel Dörfler 	return item;
43213afa642SPhil Greenway }
43313afa642SPhil Greenway 
434efa8b4f3SAxel Dörfler 
435ad13f387SMichael Pfeiffer BMenuItem*
436fd952aefSRyan Leavengood ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, float value)
437ad13f387SMichael Pfeiffer {
438efa8b4f3SAxel Dörfler 	BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
439efa8b4f3SAxel Dörfler 	message->AddFloat("value", value);
440ad13f387SMichael Pfeiffer 
4416163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, message, 0);
442efa8b4f3SAxel Dörfler 	item->SetTarget(this);
443ad13f387SMichael Pfeiffer 
444d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
445efa8b4f3SAxel Dörfler 	if (marked)
446efa8b4f3SAxel Dörfler 		item->SetMarked(true);
447ad13f387SMichael Pfeiffer 
448efa8b4f3SAxel Dörfler 	menu->AddItem(item);
449efa8b4f3SAxel Dörfler 	return item;
450ad13f387SMichael Pfeiffer }
451ad13f387SMichael Pfeiffer 
452efa8b4f3SAxel Dörfler 
453cdb89ebbSMatthew Wilber void
454cdb89ebbSMatthew Wilber ShowImageWindow::WindowRedimension(BBitmap* pbitmap)
45513afa642SPhil Greenway {
456d10d5947SMichael Pfeiffer 	BScreen screen;
45771a34702SAxel Dörfler 	if (!screen.IsValid())
458efa8b4f3SAxel Dörfler 		return;
459efa8b4f3SAxel Dörfler 
460d10d5947SMichael Pfeiffer 	BRect r(pbitmap->Bounds());
461fc5ca95dSStephan Aßmus 	float width = r.Width() + 2 * PEN_SIZE + B_V_SCROLL_BAR_WIDTH;
46256b0c7b9SKarsten Heimrich 	float height = r.Height() + 2 * PEN_SIZE + 1 + fBar->Frame().Height() +
46356b0c7b9SKarsten Heimrich 		B_H_SCROLL_BAR_HEIGHT;
464cdb89ebbSMatthew Wilber 
4656163f333SKarsten Heimrich 	BRect frame = screen.Frame();
4666163f333SKarsten Heimrich 	const float windowBorder = 5;
467d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
4686163f333SKarsten Heimrich 	float maxWidth = frame.Width() + 1 - windowBorder - Frame().left;
4696163f333SKarsten Heimrich 	float maxHeight = frame.Height() + 1 - windowBorder - Frame().top;
470cdb89ebbSMatthew Wilber 
471a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
472a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
473efa8b4f3SAxel Dörfler 
474fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
475a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
476efa8b4f3SAxel Dörfler 	if (maxWidth > maxW)
477efa8b4f3SAxel Dörfler 		maxWidth = maxW;
478efa8b4f3SAxel Dörfler 	if (maxHeight > maxH)
479efa8b4f3SAxel Dörfler 		maxHeight = maxH;
480efa8b4f3SAxel Dörfler 	if (width < minW)
481efa8b4f3SAxel Dörfler 		width = minW;
482efa8b4f3SAxel Dörfler 	if (height < minH)
483efa8b4f3SAxel Dörfler 		height = minH;
484a8fc7138SMichael Pfeiffer 
485efa8b4f3SAxel Dörfler 	if (width > maxWidth)
486efa8b4f3SAxel Dörfler 		width = maxWidth;
487efa8b4f3SAxel Dörfler 	if (height > maxHeight)
488efa8b4f3SAxel Dörfler 		height = maxHeight;
489d10d5947SMichael Pfeiffer 
490d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
49113afa642SPhil Greenway }
49213afa642SPhil Greenway 
493efa8b4f3SAxel Dörfler 
494cdb89ebbSMatthew Wilber void
495cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
49613afa642SPhil Greenway {
4976163f333SKarsten Heimrich 	BWindow::FrameResized(width, height);
49813afa642SPhil Greenway }
49913afa642SPhil Greenway 
500efa8b4f3SAxel Dörfler 
5017eca0987SMichael Pfeiffer bool
502fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what)
5037eca0987SMichael Pfeiffer {
5047eca0987SMichael Pfeiffer 	bool marked = false;
5056163f333SKarsten Heimrich 	BMenuItem* item = fBar->FindItem(what);
5067eca0987SMichael Pfeiffer 	if (item != NULL) {
5077eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
5087eca0987SMichael Pfeiffer 		item->SetMarked(marked);
5097eca0987SMichael Pfeiffer 	}
5107eca0987SMichael Pfeiffer 	return marked;
5117eca0987SMichael Pfeiffer }
5127eca0987SMichael Pfeiffer 
513efa8b4f3SAxel Dörfler 
514cdb89ebbSMatthew Wilber void
515fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable)
516e6a50d9cSMichael Pfeiffer {
5176163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
5186163f333SKarsten Heimrich 	if (item && item->IsEnabled() != enable)
519e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
520e6a50d9cSMichael Pfeiffer }
521e6a50d9cSMichael Pfeiffer 
522efa8b4f3SAxel Dörfler 
523e6a50d9cSMichael Pfeiffer void
524fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked)
525e6a50d9cSMichael Pfeiffer {
5266163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
5276163f333SKarsten Heimrich 	if (item && item->IsMarked() != marked)
528e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
529e6a50d9cSMichael Pfeiffer }
530e6a50d9cSMichael Pfeiffer 
531efa8b4f3SAxel Dörfler 
532da87390fSMichael Pfeiffer void
533fd952aefSRyan Leavengood ShowImageWindow::_MarkSlideShowDelay(float value)
534da87390fSMichael Pfeiffer {
535d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
536da87390fSMichael Pfeiffer 	float v;
537da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
538d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
539da87390fSMichael Pfeiffer 		if (item) {
540da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
5416163f333SKarsten Heimrich 				if (!item->IsMarked())
542da87390fSMichael Pfeiffer 					item->SetMarked(true);
543da87390fSMichael Pfeiffer 				return;
544da87390fSMichael Pfeiffer 			}
545da87390fSMichael Pfeiffer 		}
546da87390fSMichael Pfeiffer 	}
547da87390fSMichael Pfeiffer }
548e6a50d9cSMichael Pfeiffer 
54919c76de4SMichael Pfeiffer 
55019c76de4SMichael Pfeiffer void
551fd952aefSRyan Leavengood ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what)
55219c76de4SMichael Pfeiffer {
553fd952aefSRyan Leavengood 	bool enabled = _ToggleMenuItem(what);
5546163f333SKarsten Heimrich 	if (shrink)
555d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
5566163f333SKarsten Heimrich 	else
557d3046f7dSMichael Pfeiffer 		fImageView->SetZoomToBounds(enabled);
5586163f333SKarsten Heimrich 
559d3046f7dSMichael Pfeiffer 	enabled = !(fImageView->GetShrinkToBounds() || fImageView->GetZoomToBounds());
560fd952aefSRyan Leavengood 	_EnableMenuItem(fBar, MSG_ORIGINAL_SIZE, enabled);
561fd952aefSRyan Leavengood 	_EnableMenuItem(fBar, MSG_ZOOM_IN, enabled);
562fd952aefSRyan Leavengood 	_EnableMenuItem(fBar, MSG_ZOOM_OUT, enabled);
56319c76de4SMichael Pfeiffer }
56419c76de4SMichael Pfeiffer 
565efa8b4f3SAxel Dörfler 
566e6a50d9cSMichael Pfeiffer void
567efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message)
56813afa642SPhil Greenway {
569efa8b4f3SAxel Dörfler 	switch (message->what) {
570ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
571ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
572ee7b4f39SMatthew Wilber 			fModified = true;
573ee7b4f39SMatthew Wilber 			break;
574ee7b4f39SMatthew Wilber 
575fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
576fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
577d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
578cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
579fd952aefSRyan Leavengood 				_SaveAs(message);
58013afa642SPhil Greenway 			break;
581fc0a275bSMatthew Wilber 
582fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
583fc0a275bSMatthew Wilber 			// User specified where to save the output image
584fd952aefSRyan Leavengood 			_SaveToFile(message);
58507caaa8eSMatthew Wilber 			break;
58607caaa8eSMatthew Wilber 
587cdb89ebbSMatthew Wilber 		case B_CANCEL:
588d3046f7dSMichael Pfeiffer 			delete fSavePanel;
589d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
590cdb89ebbSMatthew Wilber 			break;
591cdb89ebbSMatthew Wilber 
5926163f333SKarsten Heimrich 		case MSG_UPDATE_STATUS: {
5936163f333SKarsten Heimrich 			int32 pages = fImageView->PageCount();
5946163f333SKarsten Heimrich 			int32 curPage = fImageView->CurrentPage();
5956c305411SMatthew Wilber 
596*36c17651SRyan Leavengood 			bool enable = (pages > 1) ? true : false;
597*36c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_FIRST, enable);
598*36c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_LAST, enable);
599*36c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_NEXT, enable);
600*36c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_PREV, enable);
601*36c17651SRyan Leavengood 			fGoToPageMenu->SetEnabled(enable);
6021d592070SMatthew Wilber 
603fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_FILE_NEXT, fImageView->HasNextFile());
604fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_FILE_PREV, fImageView->HasPrevFile());
605134d6076SMichael Pfeiffer 
606d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
6076c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
6086c305411SMatthew Wilber 				// pages is different
6096c305411SMatthew Wilber 
610d3046f7dSMichael Pfeiffer 				while (fGoToPageMenu->CountItems() > 0)
6116c305411SMatthew Wilber 					// Remove all page numbers
612d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
6136c305411SMatthew Wilber 
614780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
6156c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
6166163f333SKarsten Heimrich 					BMessage* pgomsg = new BMessage(MSG_GOTO_PAGE);
6176c305411SMatthew Wilber 					pgomsg->AddInt32("page", i);
6186163f333SKarsten Heimrich 
6196163f333SKarsten Heimrich 					char shortcut = 0;
620780d8a62SMichael Pfeiffer 					if (i < 10) {
621780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
622780d8a62SMichael Pfeiffer 					} else if (i == 10) {
623780d8a62SMichael Pfeiffer 						shortcut = '0';
624780d8a62SMichael Pfeiffer 					}
6256163f333SKarsten Heimrich 
6266163f333SKarsten Heimrich 					BString strCaption;
6276163f333SKarsten Heimrich 					strCaption << i;
6286163f333SKarsten Heimrich 
6296163f333SKarsten Heimrich 					BMenuItem* item = new BMenuItem(strCaption.String(), pgomsg,
6306163f333SKarsten Heimrich 						shortcut);
6316c305411SMatthew Wilber 					if (curPage == i)
632efa8b4f3SAxel Dörfler 						item->SetMarked(true);
633efa8b4f3SAxel Dörfler 					fGoToPageMenu->AddItem(item);
6346c305411SMatthew Wilber 				}
6356c305411SMatthew Wilber 			} else {
6366c305411SMatthew Wilber 				// Make sure the correct page is marked
6376c305411SMatthew Wilber 				BMenuItem *pcurItem;
638d3046f7dSMichael Pfeiffer 				pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
6396c305411SMatthew Wilber 				if (!pcurItem->IsMarked()) {
6406c305411SMatthew Wilber 					pcurItem->SetMarked(true);
6416c305411SMatthew Wilber 				}
6426c305411SMatthew Wilber 			}
6436c305411SMatthew Wilber 
64416b663b7SMatthew Wilber 			// Disable the Invert menu item if the bitmap color space
64516b663b7SMatthew Wilber 			// is B_CMAP8. (B_CMAP8 is currently unsupported by the
64616b663b7SMatthew Wilber 			// invert algorithm)
64716b663b7SMatthew Wilber 			color_space colors = B_NO_COLOR_SPACE;
648efa8b4f3SAxel Dörfler 			message->FindInt32("colors", reinterpret_cast<int32 *>(&colors));
649fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_INVERT, (colors != B_CMAP8));
65016b663b7SMatthew Wilber 
6510cd4ecd8SStephan Aßmus 			BString status;
652d9f6762dSMichael Pfeiffer 			bool messageProvidesSize = false;
6538f5fd23fSRyan Leavengood 			if (message->FindInt32("width", &fWidth) >= B_OK
6548f5fd23fSRyan Leavengood 				&& message->FindInt32("height", &fHeight) >= B_OK) {
6558f5fd23fSRyan Leavengood 				status << fWidth << "x" << fHeight;
656d9f6762dSMichael Pfeiffer 				messageProvidesSize = true;
6570cd4ecd8SStephan Aßmus 			}
6580cd4ecd8SStephan Aßmus 
65903839579SMatthew Wilber 			BString str;
6600acb8cc4SMichael Pfeiffer 			if (message->FindString("status", &str) == B_OK && str.Length() > 0) {
6610acb8cc4SMichael Pfeiffer 				if (status.Length() > 0)
6620acb8cc4SMichael Pfeiffer 					status << ", ";
6630cd4ecd8SStephan Aßmus 				status << str;
6645eb50e46SMichael Pfeiffer 			}
6650cd4ecd8SStephan Aßmus 
666d9f6762dSMichael Pfeiffer 			if (messageProvidesSize) {
667fd952aefSRyan Leavengood 				_UpdateResizerWindow(fWidth, fHeight);
66829c4d5a9SPhilippe Saint-Pierre 				if (!fImageView->GetZoomToBounds()
669f75975a9SPhilippe Saint-Pierre 					&& !fImageView->GetShrinkToBounds()
670f75975a9SPhilippe Saint-Pierre 					&& !fFullScreen)
67129c4d5a9SPhilippe Saint-Pierre 					WindowRedimension(fImageView->GetBitmap());
672d9f6762dSMichael Pfeiffer 			}
673d9f6762dSMichael Pfeiffer 
6740cd4ecd8SStephan Aßmus 			fStatusView->SetText(status);
6757eca0987SMichael Pfeiffer 
6767eca0987SMichael Pfeiffer 			UpdateTitle();
6776163f333SKarsten Heimrich 		}	break;
67803839579SMatthew Wilber 
6796163f333SKarsten Heimrich 		case MSG_UPDATE_STATUS_TEXT: {
6808f5fd23fSRyan Leavengood 			BString status;
6818f5fd23fSRyan Leavengood 			status << fWidth << "x" << fHeight;
6828f5fd23fSRyan Leavengood 			BString str;
6838f5fd23fSRyan Leavengood 			if (message->FindString("status", &str) == B_OK && str.Length() > 0) {
6848f5fd23fSRyan Leavengood 				status << ", " << str;
6858f5fd23fSRyan Leavengood 				fStatusView->SetText(status);
6868f5fd23fSRyan Leavengood 			}
6876163f333SKarsten Heimrich 		}	break;
6888f5fd23fSRyan Leavengood 
6896163f333SKarsten Heimrich 		case MSG_SELECTION: {
6908ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
6918ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
6928ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
6938ad30bcfSMatthew Wilber 			bool benable;
694efa8b4f3SAxel Dörfler 			if (message->FindBool("has_selection", &benable) == B_OK) {
695fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_CUT, benable);
696fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_COPY, benable);
697fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, MSG_CLEAR_SELECT, benable);
6988ad30bcfSMatthew Wilber 			}
6996163f333SKarsten Heimrich 		}	break;
7008ad30bcfSMatthew Wilber 
7016163f333SKarsten Heimrich 		case MSG_UNDO_STATE: {
7027598450eSMatthew Wilber 			bool benable;
703efa8b4f3SAxel Dörfler 			if (message->FindBool("can_undo", &benable) == B_OK)
704fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_UNDO, benable);
7056163f333SKarsten Heimrich 		}	break;
7067598450eSMatthew Wilber 
7076163f333SKarsten Heimrich 		case MSG_CLIPBOARD_CHANGED: {
7086163f333SKarsten Heimrich 			// The app sends this message after it examines the clipboard in
7096163f333SKarsten Heimrich 			// response to a B_CLIPBOARD_CHANGED message
710402c09e5SMatthew Wilber 			bool bdata;
711efa8b4f3SAxel Dörfler 			if (message->FindBool("data_available", &bdata) == B_OK)
712fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_PASTE, bdata);
7136163f333SKarsten Heimrich 		}	break;
714402c09e5SMatthew Wilber 
71513afa642SPhil Greenway 		case B_UNDO:
7167598450eSMatthew Wilber 			fImageView->Undo();
71713afa642SPhil Greenway 			break;
7186163f333SKarsten Heimrich 
71913afa642SPhil Greenway 		case B_CUT:
720d3046f7dSMichael Pfeiffer 			fImageView->Cut();
72113afa642SPhil Greenway 			break;
7226163f333SKarsten Heimrich 
72313afa642SPhil Greenway 		case B_COPY:
724d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
72513afa642SPhil Greenway 			break;
7266163f333SKarsten Heimrich 
72713afa642SPhil Greenway 		case B_PASTE:
728d3046f7dSMichael Pfeiffer 			fImageView->Paste();
72913afa642SPhil Greenway 			break;
7306163f333SKarsten Heimrich 
73113afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
732d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
73313afa642SPhil Greenway 			break;
7346163f333SKarsten Heimrich 
73513afa642SPhil Greenway 		case MSG_SELECT_ALL:
736d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
73713afa642SPhil Greenway 			break;
73813afa642SPhil Greenway 
73903839579SMatthew Wilber 		case MSG_PAGE_FIRST:
740fd952aefSRyan Leavengood 			if (_ClosePrompt())
741d3046f7dSMichael Pfeiffer 				fImageView->FirstPage();
74203839579SMatthew Wilber 			break;
74303839579SMatthew Wilber 
74403839579SMatthew Wilber 		case MSG_PAGE_LAST:
745fd952aefSRyan Leavengood 			if (_ClosePrompt())
746d3046f7dSMichael Pfeiffer 				fImageView->LastPage();
74703839579SMatthew Wilber 			break;
74803839579SMatthew Wilber 
74903839579SMatthew Wilber 		case MSG_PAGE_NEXT:
750fd952aefSRyan Leavengood 			if (_ClosePrompt())
751d3046f7dSMichael Pfeiffer 				fImageView->NextPage();
75203839579SMatthew Wilber 			break;
75303839579SMatthew Wilber 
75403839579SMatthew Wilber 		case MSG_PAGE_PREV:
755fd952aefSRyan Leavengood 			if (_ClosePrompt())
756d3046f7dSMichael Pfeiffer 				fImageView->PrevPage();
75703839579SMatthew Wilber 			break;
75803839579SMatthew Wilber 
7596163f333SKarsten Heimrich 		case MSG_GOTO_PAGE: {
760fd952aefSRyan Leavengood 			if (!_ClosePrompt())
761ee7b4f39SMatthew Wilber 				break;
762ee7b4f39SMatthew Wilber 
7636163f333SKarsten Heimrich 			int32 newPage;
7646163f333SKarsten Heimrich 			if (message->FindInt32("page", &newPage) != B_OK)
7656163f333SKarsten Heimrich 				break;
7666163f333SKarsten Heimrich 
7676163f333SKarsten Heimrich 			int32 curPage = fImageView->CurrentPage();
7686163f333SKarsten Heimrich 			int32 pages = fImageView->PageCount();
7696c305411SMatthew Wilber 
7706c305411SMatthew Wilber 			if (newPage > 0 && newPage <= pages) {
7716163f333SKarsten Heimrich 				BMenuItem* pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
7726163f333SKarsten Heimrich 				BMenuItem* pnewItem = fGoToPageMenu->ItemAt(newPage - 1);
7736163f333SKarsten Heimrich 				if (pcurItem && pnewItem) {
7746c305411SMatthew Wilber 					pcurItem->SetMarked(false);
7756c305411SMatthew Wilber 					pnewItem->SetMarked(true);
776d3046f7dSMichael Pfeiffer 					fImageView->GoToPage(newPage);
7776c305411SMatthew Wilber 				}
7786c305411SMatthew Wilber 			}
7796163f333SKarsten Heimrich 		}	break;
7806c305411SMatthew Wilber 
781cdb89ebbSMatthew Wilber 		case MSG_DITHER_IMAGE:
782fd952aefSRyan Leavengood 			fImageView->SetDither(_ToggleMenuItem(message->what));
7837eca0987SMichael Pfeiffer 			break;
7847eca0987SMichael Pfeiffer 
78519c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
786fd952aefSRyan Leavengood 			_ResizeToWindow(true, message->what);
78719c76de4SMichael Pfeiffer 			break;
7886163f333SKarsten Heimrich 
78919c76de4SMichael Pfeiffer 		case MSG_ZOOM_TO_WINDOW:
790fd952aefSRyan Leavengood 			_ResizeToWindow(false, message->what);
7917eca0987SMichael Pfeiffer 			break;
7927eca0987SMichael Pfeiffer 
7937eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
794fd952aefSRyan Leavengood 			if (_ClosePrompt())
795d3046f7dSMichael Pfeiffer 				fImageView->PrevFile();
7967eca0987SMichael Pfeiffer 			break;
7977eca0987SMichael Pfeiffer 
7987eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
799fd952aefSRyan Leavengood 			if (_ClosePrompt())
800d3046f7dSMichael Pfeiffer 				fImageView->NextFile();
80113afa642SPhil Greenway 			break;
80213afa642SPhil Greenway 
803bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
804d3046f7dSMichael Pfeiffer 			fImageView->Rotate(90);
805ad13f387SMichael Pfeiffer 			break;
8066163f333SKarsten Heimrich 
807bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
808d3046f7dSMichael Pfeiffer 			fImageView->Rotate(270);
809ad13f387SMichael Pfeiffer 			break;
8106163f333SKarsten Heimrich 
81169eee339SRyan Leavengood 		case MSG_FLIP_LEFT_TO_RIGHT:
81261ddc257SRyan Leavengood 			fImageView->Flip(true);
813ad13f387SMichael Pfeiffer 			break;
8146163f333SKarsten Heimrich 
81569eee339SRyan Leavengood 		case MSG_FLIP_TOP_TO_BOTTOM:
81661ddc257SRyan Leavengood 			fImageView->Flip(false);
817ad13f387SMichael Pfeiffer 			break;
8186163f333SKarsten Heimrich 
819ad13f387SMichael Pfeiffer 		case MSG_INVERT:
820d3046f7dSMichael Pfeiffer 			fImageView->Invert();
821ad13f387SMichael Pfeiffer 			break;
8226163f333SKarsten Heimrich 
8236163f333SKarsten Heimrich 		case MSG_SLIDE_SHOW: {
8246163f333SKarsten Heimrich 			BMenuItem* item = fBar->FindItem(message->what);
825ee7b4f39SMatthew Wilber 			if (!item)
826ee7b4f39SMatthew Wilber 				break;
827ee7b4f39SMatthew Wilber 			if (item->IsMarked()) {
828ee7b4f39SMatthew Wilber 				item->SetMarked(false);
829ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(true);
830d3046f7dSMichael Pfeiffer 				fImageView->StopSlideShow();
831fd952aefSRyan Leavengood 			} else if (_ClosePrompt()) {
832ee7b4f39SMatthew Wilber 				item->SetMarked(true);
833ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(false);
834ee7b4f39SMatthew Wilber 				fImageView->StartSlideShow();
835ad13f387SMichael Pfeiffer 			}
8366163f333SKarsten Heimrich 		}	break;
837ee7b4f39SMatthew Wilber 
8386163f333SKarsten Heimrich 		case MSG_SLIDE_SHOW_DELAY: {
839ad13f387SMichael Pfeiffer 			float value;
840efa8b4f3SAxel Dörfler 			if (message->FindFloat("value", &value) == B_OK) {
841d3046f7dSMichael Pfeiffer 				fImageView->SetSlideShowDelay(value);
842da87390fSMichael Pfeiffer 				// in case message is sent from popup menu
843fd952aefSRyan Leavengood 				_MarkSlideShowDelay(value);
844ad13f387SMichael Pfeiffer 			}
8456163f333SKarsten Heimrich 		}	break;
846ad13f387SMichael Pfeiffer 
847ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
848fd952aefSRyan Leavengood 			_ToggleFullScreen();
849ad13f387SMichael Pfeiffer 			break;
8506163f333SKarsten Heimrich 
851fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
852fc5ca95dSStephan Aßmus 			if (fFullScreen)
853fd952aefSRyan Leavengood 				_ToggleFullScreen();
854fc5ca95dSStephan Aßmus 			break;
8556163f333SKarsten Heimrich 
8566163f333SKarsten Heimrich 		case MSG_SHOW_CAPTION: {
857fd952aefSRyan Leavengood 			fShowCaption = _ToggleMenuItem(message->what);
858efa8b4f3SAxel Dörfler 			ShowImageSettings* settings = my_app->Settings();
859efa8b4f3SAxel Dörfler 
860d3046f7dSMichael Pfeiffer 			if (settings->Lock()) {
861d3046f7dSMichael Pfeiffer 				settings->SetBool("ShowCaption", fShowCaption);
862d3046f7dSMichael Pfeiffer 				settings->Unlock();
863d3046f7dSMichael Pfeiffer 			}
864efa8b4f3SAxel Dörfler 			if (fFullScreen)
865d3046f7dSMichael Pfeiffer 				fImageView->SetShowCaption(fShowCaption);
8666163f333SKarsten Heimrich 		}	break;
867ad13f387SMichael Pfeiffer 
868780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
869fd952aefSRyan Leavengood 			_PageSetup();
870780d8a62SMichael Pfeiffer 			break;
8716163f333SKarsten Heimrich 
872780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
873fd952aefSRyan Leavengood 			_PrepareForPrint();
874780d8a62SMichael Pfeiffer 			break;
8756163f333SKarsten Heimrich 
876780d8a62SMichael Pfeiffer 		case MSG_PRINT:
877fd952aefSRyan Leavengood 			_Print(message);
878780d8a62SMichael Pfeiffer 			break;
879780d8a62SMichael Pfeiffer 
880780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
881d3046f7dSMichael Pfeiffer 			fImageView->ZoomIn();
882780d8a62SMichael Pfeiffer 			break;
8836163f333SKarsten Heimrich 
884780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
885d3046f7dSMichael Pfeiffer 			fImageView->ZoomOut();
886780d8a62SMichael Pfeiffer 			break;
8876163f333SKarsten Heimrich 
888780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
889d3046f7dSMichael Pfeiffer 			fImageView->SetZoom(1.0);
890780d8a62SMichael Pfeiffer 			break;
8916163f333SKarsten Heimrich 
89281b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
893fd952aefSRyan Leavengood 			fImageView->SetScaleBilinear(_ToggleMenuItem(message->what));
89481b9c776SMichael Pfeiffer 			break;
895780d8a62SMichael Pfeiffer 
8966163f333SKarsten Heimrich 		case MSG_OPEN_RESIZER_WINDOW: {
8976163f333SKarsten Heimrich 			if (fImageView->GetBitmap() != NULL) {
898d9f6762dSMichael Pfeiffer 				BRect rect = fImageView->GetBitmap()->Bounds();
899fd952aefSRyan Leavengood 				_OpenResizerWindow(rect.IntegerWidth()+1, rect.IntegerHeight()+1);
900d9f6762dSMichael Pfeiffer 			}
9016163f333SKarsten Heimrich 		}	break;
9026163f333SKarsten Heimrich 
9036163f333SKarsten Heimrich 		case MSG_RESIZE: {
904d9f6762dSMichael Pfeiffer 			int w = message->FindInt32("w");
905d9f6762dSMichael Pfeiffer 			int h = message->FindInt32("h");
906d9f6762dSMichael Pfeiffer 			fImageView->ResizeImage(w, h);
9076163f333SKarsten Heimrich 		} break;
9086163f333SKarsten Heimrich 
909880be331SRyan Leavengood 		case MSG_RESIZER_WINDOW_QUIT:
9106163f333SKarsten Heimrich 			delete fResizerWindowMessenger;
911d9f6762dSMichael Pfeiffer 			fResizerWindowMessenger = NULL;
912d9f6762dSMichael Pfeiffer 			break;
913d9f6762dSMichael Pfeiffer 
9146163f333SKarsten Heimrich 		case MSG_DESKTOP_BACKGROUND: {
9150a74004cSRyan Leavengood 			BMessage message(B_REFS_RECEIVED);
9160a74004cSRyan Leavengood 			message.AddRef("refs", fImageView->Image());
9170a74004cSRyan Leavengood 			// This is used in the Backgrounds code for scaled placement
9180a74004cSRyan Leavengood 			message.AddInt32("placement", 'scpl');
9190a74004cSRyan Leavengood 			be_roster->Launch("application/x-vnd.haiku-backgrounds", &message);
9206163f333SKarsten Heimrich 		}	break;
921a60adbf9SAxel Dörfler 
92213afa642SPhil Greenway 		default:
923efa8b4f3SAxel Dörfler 			BWindow::MessageReceived(message);
92413afa642SPhil Greenway 			break;
92513afa642SPhil Greenway 	}
92613afa642SPhil Greenway }
927fc0a275bSMatthew Wilber 
928efa8b4f3SAxel Dörfler 
929fc0a275bSMatthew Wilber void
930fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message)
931fc0a275bSMatthew Wilber {
932cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
933cdb89ebbSMatthew Wilber 	translator_id outTranslator;
934cdb89ebbSMatthew Wilber 	uint32 outType;
9356163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
936efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9376163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
938cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
939fc0a275bSMatthew Wilber 		return;
940fc0a275bSMatthew Wilber 
941cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
942cdb89ebbSMatthew Wilber 	// message that the save panel will send back
943c1a10c14SKarsten Heimrich 	BMessage panelMsg(MSG_SAVE_PANEL);
944c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTranslatorField, outTranslator);
945c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTypeField, outType);
946cdb89ebbSMatthew Wilber 
947cdb89ebbSMatthew Wilber 	// Create save panel and show it
9486163f333SKarsten Heimrich 	BMessenger target(this);
949efa8b4f3SAxel Dörfler 	fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
950c1a10c14SKarsten Heimrich 		&target, NULL, 0, false, &panelMsg);
951d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
952fc0a275bSMatthew Wilber 		return;
953a60adbf9SAxel Dörfler 
954d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
955d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
956fc0a275bSMatthew Wilber }
957fc0a275bSMatthew Wilber 
958efa8b4f3SAxel Dörfler 
959fc0a275bSMatthew Wilber void
960fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message)
961fc0a275bSMatthew Wilber {
962cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
963efa8b4f3SAxel Dörfler 	entry_ref dirRef;
964efa8b4f3SAxel Dörfler 	if (message->FindRef("directory", &dirRef) != B_OK)
965fc0a275bSMatthew Wilber 		return;
966efa8b4f3SAxel Dörfler 
967fc0a275bSMatthew Wilber 	const char* filename;
968efa8b4f3SAxel Dörfler 	if (message->FindString("name", &filename) != B_OK)
969fc0a275bSMatthew Wilber 		return;
970fc0a275bSMatthew Wilber 
971cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
972cdb89ebbSMatthew Wilber 	// to save the output image
973cdb89ebbSMatthew Wilber 	translator_id outTranslator;
974cdb89ebbSMatthew Wilber 	uint32 outType;
9756163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
976efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9776163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
978cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
979cdb89ebbSMatthew Wilber 		return;
980cdb89ebbSMatthew Wilber 
981a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
982a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
983a7e78e3bSMatthew Wilber 	BTranslatorRoster* roster = BTranslatorRoster::Default();
984efa8b4f3SAxel Dörfler 	const translation_format* outFormat = NULL;
985efa8b4f3SAxel Dörfler 	int32 outCount = 0;
986efa8b4f3SAxel Dörfler 	if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
987efa8b4f3SAxel Dörfler 		|| outCount < 1)
988a7e78e3bSMatthew Wilber 		return;
989efa8b4f3SAxel Dörfler 
990a7e78e3bSMatthew Wilber 	int32 i;
991efa8b4f3SAxel Dörfler 	for (i = 0; i < outCount; i++) {
992efa8b4f3SAxel Dörfler 		if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
993a7e78e3bSMatthew Wilber 			break;
994a7e78e3bSMatthew Wilber 	}
995efa8b4f3SAxel Dörfler 	if (i == outCount)
996fc0a275bSMatthew Wilber 		return;
997fc0a275bSMatthew Wilber 
998a7e78e3bSMatthew Wilber 	// Write out the image file
999efa8b4f3SAxel Dörfler 	BDirectory dir(&dirRef);
1000efa8b4f3SAxel Dörfler 	fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
1001fc0a275bSMatthew Wilber }
1002fc0a275bSMatthew Wilber 
1003efa8b4f3SAxel Dörfler 
10041ed4535fSStephan Aßmus // This is temporary solution for building BString with printf like format.
10051ed4535fSStephan Aßmus // will be removed in the future.
10061ed4535fSStephan Aßmus static void
10071ed4535fSStephan Aßmus bs_printf(BString* string, const char* format, ...)
10081ed4535fSStephan Aßmus {
10091ed4535fSStephan Aßmus 	va_list ap;
10101ed4535fSStephan Aßmus 	char* buf;
10111ed4535fSStephan Aßmus 
10121ed4535fSStephan Aßmus 	va_start(ap, format);
10131ed4535fSStephan Aßmus 	vasprintf(&buf, format, ap);
10141ed4535fSStephan Aßmus 	string->SetTo(buf);
10151ed4535fSStephan Aßmus 	free(buf);
10161ed4535fSStephan Aßmus 	va_end(ap);
10171ed4535fSStephan Aßmus }
10181ed4535fSStephan Aßmus 
10191ed4535fSStephan Aßmus 
10204eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
10214eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "ClosePrompt"
10221ed4535fSStephan Aßmus 
1023cdb89ebbSMatthew Wilber bool
1024fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt()
1025ee7b4f39SMatthew Wilber {
1026ee7b4f39SMatthew Wilber 	if (!fModified)
1027ee7b4f39SMatthew Wilber 		return true;
1028efa8b4f3SAxel Dörfler 
1029ee7b4f39SMatthew Wilber 	int32 page, count;
1030ee7b4f39SMatthew Wilber 	count = fImageView->PageCount();
1031ee7b4f39SMatthew Wilber 	page = fImageView->CurrentPage();
1032ee7b4f39SMatthew Wilber 	BString prompt, name;
1033ee7b4f39SMatthew Wilber 	fImageView->GetName(&name);
1034efa8b4f3SAxel Dörfler 
10351ed4535fSStephan Aßmus 	if (count > 1) {
10361ed4535fSStephan Aßmus 		bs_printf(&prompt,
1037905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' (page %d) has been changed. Do you "
1038905c8c8cSMatt Madia 				"want to close the document?"),
10391ed4535fSStephan Aßmus 			name.String(), page);
10401ed4535fSStephan Aßmus 	} else {
10411ed4535fSStephan Aßmus 		bs_printf(&prompt,
1042905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' has been changed. Do you want to "
1043905c8c8cSMatt Madia 				"close the document?"),
10441ed4535fSStephan Aßmus 			name.String());
10451ed4535fSStephan Aßmus 	}
10461ed4535fSStephan Aßmus 
1047905c8c8cSMatt Madia 	BAlert* pAlert = new BAlert(B_TRANSLATE("Close document"), prompt.String(),
1048905c8c8cSMatt Madia 		B_TRANSLATE("Cancel"), B_TRANSLATE("Close"));
1049efa8b4f3SAxel Dörfler 	if (pAlert->Go() == 0) {
1050ee7b4f39SMatthew Wilber 		// Cancel
1051ee7b4f39SMatthew Wilber 		return false;
1052efa8b4f3SAxel Dörfler 	} else {
1053ee7b4f39SMatthew Wilber 		// Close
1054187f0b8aSMatthew Wilber 		fModified = false;
1055ee7b4f39SMatthew Wilber 		return true;
1056ee7b4f39SMatthew Wilber 	}
1057ee7b4f39SMatthew Wilber }
1058ee7b4f39SMatthew Wilber 
1059cdb89ebbSMatthew Wilber 
1060ad13f387SMichael Pfeiffer void
1061fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen()
1062ad13f387SMichael Pfeiffer {
1063ad13f387SMichael Pfeiffer 	BRect frame;
1064ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
1065ad13f387SMichael Pfeiffer 	if (fFullScreen) {
1066ad13f387SMichael Pfeiffer 		BScreen screen;
1067ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
1068ad13f387SMichael Pfeiffer 		frame = screen.Frame();
1069d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
1070ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
1071ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
1072ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
1073ad13f387SMichael Pfeiffer 
1074ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
1075c0b16687SAxel Dörfler 
1076c0b16687SAxel Dörfler 		Activate();
1077c0b16687SAxel Dörfler 			// make the window frontmost
1078ad13f387SMichael Pfeiffer 	} else {
1079ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
1080ad13f387SMichael Pfeiffer 
1081ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
1082ad13f387SMichael Pfeiffer 	}
1083efa8b4f3SAxel Dörfler 
108476d115d8SRyan Leavengood 	fImageView->SetFullScreen(fFullScreen);
1085d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
1086ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
1087ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
1088ad13f387SMichael Pfeiffer }
1089ad13f387SMichael Pfeiffer 
1090efa8b4f3SAxel Dörfler 
1091d3046f7dSMichael Pfeiffer void
1092fd952aefSRyan Leavengood ShowImageWindow::_LoadSettings()
1093d3046f7dSMichael Pfeiffer {
1094efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1095efa8b4f3SAxel Dörfler 
1096d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1097d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
1098d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
1099d3046f7dSMichael Pfeiffer 
1100efa8b4f3SAxel Dörfler 		int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option());
1101d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
1102d3046f7dSMichael Pfeiffer 
1103efa8b4f3SAxel Dörfler 		float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1104d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
1105d3046f7dSMichael Pfeiffer 
1106d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
1107d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
1108d3046f7dSMichael Pfeiffer 
1109d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
1110d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
1111d3046f7dSMichael Pfeiffer 
1112d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
1113d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
1114d3046f7dSMichael Pfeiffer 
1115d3046f7dSMichael Pfeiffer 		settings->Unlock();
1116d3046f7dSMichael Pfeiffer 	}
1117d3046f7dSMichael Pfeiffer }
1118d3046f7dSMichael Pfeiffer 
1119efa8b4f3SAxel Dörfler 
1120d3046f7dSMichael Pfeiffer void
1121fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions()
1122d3046f7dSMichael Pfeiffer {
1123efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1124efa8b4f3SAxel Dörfler 
1125d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1126d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
1127d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1128d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1129d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
1130d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
1131d3046f7dSMichael Pfeiffer 		settings->Unlock();
1132d3046f7dSMichael Pfeiffer 	}
1133d3046f7dSMichael Pfeiffer }
1134d3046f7dSMichael Pfeiffer 
1135efa8b4f3SAxel Dörfler 
1136cdb89ebbSMatthew Wilber bool
1137fd952aefSRyan Leavengood ShowImageWindow::_PageSetup()
1138780d8a62SMichael Pfeiffer {
1139780d8a62SMichael Pfeiffer 	BString name;
1140d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
1141780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
1142efa8b4f3SAxel Dörfler 	if (fPrintSettings != NULL)
1143780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
1144efa8b4f3SAxel Dörfler 
11456163f333SKarsten Heimrich 	status_t status = printJob.ConfigPage();
11466163f333SKarsten Heimrich 	if (status == B_OK) {
1147780d8a62SMichael Pfeiffer 		delete fPrintSettings;
1148780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
1149780d8a62SMichael Pfeiffer 	}
1150efa8b4f3SAxel Dörfler 
11516163f333SKarsten Heimrich 	return status == B_OK;
1152780d8a62SMichael Pfeiffer }
1153780d8a62SMichael Pfeiffer 
1154efa8b4f3SAxel Dörfler 
1155780d8a62SMichael Pfeiffer void
1156fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint()
1157780d8a62SMichael Pfeiffer {
11586163f333SKarsten Heimrich 	if (fPrintSettings == NULL) {
11596163f333SKarsten Heimrich 		BString name;
11606163f333SKarsten Heimrich 		fImageView->GetName(&name);
11616163f333SKarsten Heimrich 
11626163f333SKarsten Heimrich 		BPrintJob printJob("");
11636163f333SKarsten Heimrich 		if (printJob.ConfigJob() == B_OK)
11646163f333SKarsten Heimrich 			fPrintSettings = printJob.Settings();
11656163f333SKarsten Heimrich 	}
1166780d8a62SMichael Pfeiffer 
1167d3046f7dSMichael Pfeiffer 	fPrintOptions.SetBounds(fImageView->GetBitmap()->Bounds());
1168d3046f7dSMichael Pfeiffer 	fPrintOptions.SetWidth(fImageView->GetBitmap()->Bounds().Width() + 1);
1169780d8a62SMichael Pfeiffer 
1170efa8b4f3SAxel Dörfler 	new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50),
1171efa8b4f3SAxel Dörfler 		&fPrintOptions, this);
1172780d8a62SMichael Pfeiffer }
1173780d8a62SMichael Pfeiffer 
1174efa8b4f3SAxel Dörfler 
1175780d8a62SMichael Pfeiffer void
1176fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg)
1177780d8a62SMichael Pfeiffer {
1178780d8a62SMichael Pfeiffer 	status_t st;
1179efa8b4f3SAxel Dörfler 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1180780d8a62SMichael Pfeiffer 		return;
1181780d8a62SMichael Pfeiffer 
1182fd952aefSRyan Leavengood 	_SavePrintOptions();
1183d3046f7dSMichael Pfeiffer 
1184780d8a62SMichael Pfeiffer 	BString name;
1185d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
11866163f333SKarsten Heimrich 
1187780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
11886163f333SKarsten Heimrich 	if (fPrintSettings)
1189780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
11906163f333SKarsten Heimrich 
1191780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
11926163f333SKarsten Heimrich 		delete fPrintSettings;
11936163f333SKarsten Heimrich 		fPrintSettings = printJob.Settings();
1194780d8a62SMichael Pfeiffer 
1195780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
11963177ae77SStefano Ceccherini 		int32 firstPage = printJob.FirstPage();
11973177ae77SStefano Ceccherini 		int32 lastPage = printJob.LastPage();
11986163f333SKarsten Heimrich 		BRect printableRect = printJob.PrintableRect();
11996163f333SKarsten Heimrich 
1200efa8b4f3SAxel Dörfler 		if (firstPage < 1)
1201780d8a62SMichael Pfeiffer 			firstPage = 1;
1202efa8b4f3SAxel Dörfler 		if (lastPage < firstPage)
1203780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1204780d8a62SMichael Pfeiffer 
12053177ae77SStefano Ceccherini 		BBitmap* bitmap = fImageView->GetBitmap();
12063177ae77SStefano Ceccherini 		float imageWidth = bitmap->Bounds().Width() + 1.0;
12073177ae77SStefano Ceccherini 		float imageHeight = bitmap->Bounds().Height() + 1.0;
1208780d8a62SMichael Pfeiffer 
12096163f333SKarsten Heimrich 		float width;
1210780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
12116163f333SKarsten Heimrich 			case PrintOptions::kFitToPage: {
12126163f333SKarsten Heimrich 				float w1 = printableRect.Width()+1;
12136163f333SKarsten Heimrich 				float w2 = imageWidth * (printableRect.Height() + 1) / imageHeight;
1214efa8b4f3SAxel Dörfler 				if (w2 < w1)
1215780d8a62SMichael Pfeiffer 					width = w2;
1216efa8b4f3SAxel Dörfler 				else
1217780d8a62SMichael Pfeiffer 					width = w1;
12186163f333SKarsten Heimrich 			}	break;
1219780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1220780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1221780d8a62SMichael Pfeiffer 				break;
1222780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1223780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1224780d8a62SMichael Pfeiffer 				break;
1225780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1226780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1227780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1228780d8a62SMichael Pfeiffer 				break;
1229efa8b4f3SAxel Dörfler 
1230780d8a62SMichael Pfeiffer 			default:
1231780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1232780d8a62SMichael Pfeiffer 				width = imageWidth;
1233780d8a62SMichael Pfeiffer 		}
1234780d8a62SMichael Pfeiffer 
1235efa8b4f3SAxel Dörfler 		// TODO: eventually print large images on several pages
1236780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1237d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
12385eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
12395eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
12405eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1241d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1242780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1243780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1244780d8a62SMichael Pfeiffer 	}
1245780d8a62SMichael Pfeiffer }
1246780d8a62SMichael Pfeiffer 
124756b0c7b9SKarsten Heimrich 
1248d9f6762dSMichael Pfeiffer void
1249fd952aefSRyan Leavengood ShowImageWindow::_OpenResizerWindow(int32 width, int32 height)
1250d9f6762dSMichael Pfeiffer {
1251d9f6762dSMichael Pfeiffer 	if (fResizerWindowMessenger == NULL) {
1252d9f6762dSMichael Pfeiffer 		// open window if it is not already opened
1253d9f6762dSMichael Pfeiffer 		BWindow* window = new ResizerWindow(this, width, height);
1254d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger = new BMessenger(window);
1255d9f6762dSMichael Pfeiffer 		window->Show();
12566163f333SKarsten Heimrich 	} else {
1257d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger->SendMessage(ResizerWindow::kActivateMsg);
1258d9f6762dSMichael Pfeiffer 	}
12596163f333SKarsten Heimrich }
1260d9f6762dSMichael Pfeiffer 
126156b0c7b9SKarsten Heimrich 
1262d9f6762dSMichael Pfeiffer void
1263fd952aefSRyan Leavengood ShowImageWindow::_UpdateResizerWindow(int32 width, int32 height)
1264d9f6762dSMichael Pfeiffer {
12656163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1266d9f6762dSMichael Pfeiffer 		return;
1267d9f6762dSMichael Pfeiffer 
1268d9f6762dSMichael Pfeiffer 	BMessage updateMsg(ResizerWindow::kUpdateMsg);
12690acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("width", width);
12700acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("height", height);
1271d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(&updateMsg);
1272d9f6762dSMichael Pfeiffer }
1273d9f6762dSMichael Pfeiffer 
127456b0c7b9SKarsten Heimrich 
1275d9f6762dSMichael Pfeiffer void
1276fd952aefSRyan Leavengood ShowImageWindow::_CloseResizerWindow()
1277d9f6762dSMichael Pfeiffer {
12786163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1279d9f6762dSMichael Pfeiffer 		return;
12806163f333SKarsten Heimrich 
1281d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(B_QUIT_REQUESTED);
12826163f333SKarsten Heimrich 	delete fResizerWindowMessenger;
1283d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger = NULL;
1284d9f6762dSMichael Pfeiffer }
1285efa8b4f3SAxel Dörfler 
128656b0c7b9SKarsten Heimrich 
1287780d8a62SMichael Pfeiffer bool
1288cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1289cdb89ebbSMatthew Wilber {
1290efa8b4f3SAxel Dörfler 	if (fSavePanel) {
1291efa8b4f3SAxel Dörfler 		// Don't allow this window to be closed if a save panel is open
1292efa8b4f3SAxel Dörfler 		return false;
1293cdb89ebbSMatthew Wilber 	}
1294cdb89ebbSMatthew Wilber 
1295fd952aefSRyan Leavengood 	bool quit = _ClosePrompt();
1296efa8b4f3SAxel Dörfler 
1297efa8b4f3SAxel Dörfler 	if (quit) {
1298fd952aefSRyan Leavengood 		_CloseResizerWindow();
1299d9f6762dSMichael Pfeiffer 
130007caaa8eSMatthew Wilber 		// tell the app to forget about this window
130107caaa8eSMatthew Wilber 		be_app->PostMessage(MSG_WINDOW_QUIT);
130207caaa8eSMatthew Wilber 	}
1303fc0a275bSMatthew Wilber 
1304efa8b4f3SAxel Dörfler 	return quit;
1305efa8b4f3SAxel Dörfler }
1306efa8b4f3SAxel Dörfler 
1307efa8b4f3SAxel Dörfler 
1308a9ab9d2cSDarkWyrm void
1309a9ab9d2cSDarkWyrm ShowImageWindow::ScreenChanged(BRect frame, color_space mode)
1310a9ab9d2cSDarkWyrm {
1311a9ab9d2cSDarkWyrm 	fImageView->SetDither(mode == B_CMAP8);
1312a9ab9d2cSDarkWyrm }
1313