xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision fd952aef9b43f8631cd97afc27d12b261d68a917)
1efa8b4f3SAxel Dörfler /*
2*fd952aefSRyan 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 
17*fd952aefSRyan Leavengood #include <new>
18*fd952aefSRyan 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>
24efa8b4f3SAxel Dörfler #include <Clipboard.h>
2513afa642SPhil Greenway #include <Entry.h>
26fc0a275bSMatthew Wilber #include <File.h>
276163f333SKarsten Heimrich #include <FilePanel.h>
2813afa642SPhil Greenway #include <Menu.h>
2913afa642SPhil Greenway #include <MenuBar.h>
3013afa642SPhil Greenway #include <MenuItem.h>
3113afa642SPhil Greenway #include <Path.h>
32efa8b4f3SAxel Dörfler #include <PrintJob.h>
33efa8b4f3SAxel Dörfler #include <Roster.h>
34efa8b4f3SAxel Dörfler #include <Screen.h>
3513afa642SPhil Greenway #include <ScrollView.h>
366163f333SKarsten Heimrich #include <String.h>
37efa8b4f3SAxel Dörfler #include <SupportDefs.h>
386163f333SKarsten Heimrich #include <TranslationDefs.h>
3913afa642SPhil Greenway #include <TranslationUtils.h>
4013afa642SPhil Greenway #include <TranslatorRoster.h>
4113afa642SPhil Greenway 
42*fd952aefSRyan Leavengood #include "BackgroundImage.h"
43*fd952aefSRyan Leavengood #include "EntryMenuItem.h"
44*fd952aefSRyan Leavengood #include "ResizerWindow.h"
45*fd952aefSRyan Leavengood #include "ShowImageApp.h"
46*fd952aefSRyan Leavengood #include "ShowImageConstants.h"
47*fd952aefSRyan Leavengood #include "ShowImageStatusView.h"
48*fd952aefSRyan Leavengood #include "ShowImageView.h"
4913afa642SPhil Greenway 
50a8fc7138SMichael Pfeiffer 
516163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow::RecentDocumentsMenu
526163f333SKarsten Heimrich 
536163f333SKarsten Heimrich class ShowImageWindow::RecentDocumentsMenu : public BMenu {
546163f333SKarsten Heimrich public:
556163f333SKarsten Heimrich 			RecentDocumentsMenu(const char *title,
566163f333SKarsten Heimrich 				menu_layout layout = B_ITEMS_IN_COLUMN);
576163f333SKarsten Heimrich 	bool	AddDynamicItem(add_state addState);
586163f333SKarsten Heimrich 
596163f333SKarsten Heimrich private:
606163f333SKarsten Heimrich 	void	UpdateRecentDocumentsMenu();
616163f333SKarsten Heimrich };
626163f333SKarsten Heimrich 
636163f333SKarsten Heimrich 
646163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::RecentDocumentsMenu(const char *title,
656163f333SKarsten Heimrich 	menu_layout layout)
66*fd952aefSRyan Leavengood 	:
67*fd952aefSRyan Leavengood 	BMenu(title, layout)
68a8fc7138SMichael Pfeiffer {
69a8fc7138SMichael Pfeiffer }
70a8fc7138SMichael Pfeiffer 
71efa8b4f3SAxel Dörfler 
72a8fc7138SMichael Pfeiffer bool
736163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::AddDynamicItem(add_state addState)
74a8fc7138SMichael Pfeiffer {
75a60adbf9SAxel Dörfler 	if (addState != B_INITIAL_ADD)
76efa8b4f3SAxel Dörfler 		return false;
77a8fc7138SMichael Pfeiffer 
786163f333SKarsten Heimrich 	while (CountItems() > 0)
796163f333SKarsten Heimrich 		delete RemoveItem(0L);
806163f333SKarsten Heimrich 
81a8fc7138SMichael Pfeiffer 	BMenuItem *item;
82a8fc7138SMichael Pfeiffer 	BMessage list, *msg;
83a8fc7138SMichael Pfeiffer 	entry_ref ref;
84a8fc7138SMichael Pfeiffer 	char name[B_FILE_NAME_LENGTH];
85a8fc7138SMichael Pfeiffer 
86efa8b4f3SAxel Dörfler 	be_roster->GetRecentDocuments(&list, 20, NULL, kApplicationSignature);
87a8fc7138SMichael Pfeiffer 	for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
88a8fc7138SMichael Pfeiffer 		BEntry entry(&ref);
89a8fc7138SMichael Pfeiffer 		if (entry.Exists() && entry.GetName(name) == B_OK) {
90a8fc7138SMichael Pfeiffer 			msg = new BMessage(B_REFS_RECEIVED);
91a8fc7138SMichael Pfeiffer 			msg->AddRef("refs", &ref);
92a8fc7138SMichael Pfeiffer 			item = new EntryMenuItem(&ref, name, msg, 0, 0);
93a8fc7138SMichael Pfeiffer 			AddItem(item);
94a8fc7138SMichael Pfeiffer 			item->SetTarget(be_app, NULL);
95a8fc7138SMichael Pfeiffer 		}
96a8fc7138SMichael Pfeiffer 	}
97a8fc7138SMichael Pfeiffer 
98a8fc7138SMichael Pfeiffer 	return false;
99a8fc7138SMichael Pfeiffer }
100a8fc7138SMichael Pfeiffer 
101a8fc7138SMichael Pfeiffer 
1026163f333SKarsten Heimrich //	#pragma mark -- ShowImageWindow
1036163f333SKarsten Heimrich 
1046163f333SKarsten Heimrich 
1056163f333SKarsten Heimrich // BMessage field names used in Save messages
1066163f333SKarsten Heimrich const char* kTypeField = "be:type";
1076163f333SKarsten Heimrich const char* kTranslatorField = "be:translator";
108a8fc7138SMichael Pfeiffer 
109efa8b4f3SAxel Dörfler 
110efa8b4f3SAxel Dörfler ShowImageWindow::ShowImageWindow(const entry_ref *ref,
111efa8b4f3SAxel Dörfler 	const BMessenger& trackerMessenger)
112*fd952aefSRyan Leavengood 	:
113*fd952aefSRyan Leavengood 	BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0),
114*fd952aefSRyan Leavengood 	fSavePanel(NULL),
115*fd952aefSRyan Leavengood 	fBar(NULL),
116*fd952aefSRyan Leavengood 	fOpenMenu(NULL),
117*fd952aefSRyan Leavengood 	fBrowseMenu(NULL),
118*fd952aefSRyan Leavengood 	fGoToPageMenu(NULL),
119*fd952aefSRyan Leavengood 	fSlideShowDelay(NULL),
120*fd952aefSRyan Leavengood 	fImageView(NULL),
121*fd952aefSRyan Leavengood 	fStatusView(NULL),
122*fd952aefSRyan Leavengood 	fModified(false),
123*fd952aefSRyan Leavengood 	fFullScreen(false),
124*fd952aefSRyan Leavengood 	fShowCaption(true),
125*fd952aefSRyan Leavengood 	fPrintSettings(NULL),
126*fd952aefSRyan Leavengood 	fResizerWindowMessenger(NULL),
127*fd952aefSRyan Leavengood 	fResizeItem(NULL),
128*fd952aefSRyan Leavengood 	fHeight(0),
129*fd952aefSRyan Leavengood 	fWidth(0)
13013afa642SPhil Greenway {
131*fd952aefSRyan Leavengood 	_LoadSettings();
132fc0a275bSMatthew Wilber 
13313afa642SPhil Greenway 	// create menu bar
134e9dcd874SAxel Dörfler 	fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar");
135efa8b4f3SAxel Dörfler 	AddMenus(fBar);
136e9dcd874SAxel Dörfler 	AddChild(fBar);
13713afa642SPhil Greenway 
13813afa642SPhil Greenway 	BRect viewFrame = Bounds();
139e9dcd874SAxel Dörfler 	viewFrame.top = fBar->Bounds().Height() + 1;
14013afa642SPhil Greenway 	viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
14113afa642SPhil Greenway 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
14213afa642SPhil Greenway 
14313afa642SPhil Greenway 	// create the image view
144d3046f7dSMichael Pfeiffer 	fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
1457eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
14613afa642SPhil Greenway 	// wrap a scroll view around the view
147efa8b4f3SAxel Dörfler 	BScrollView *scrollView = new BScrollView("image_scroller", fImageView,
148cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
149efa8b4f3SAxel Dörfler 	AddChild(scrollView);
15013afa642SPhil Greenway 
15107caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
152cdb89ebbSMatthew Wilber 	BRect rect;
15313afa642SPhil Greenway 	rect = Bounds();
15413afa642SPhil Greenway 	rect.top	= viewFrame.bottom + 1;
15507caaa8eSMatthew Wilber 	rect.left 	= viewFrame.left + kstatusWidth;
1560916ab53SMatthew Wilber 	rect.right	= viewFrame.right + 1;
1570916ab53SMatthew Wilber 	rect.bottom += 1;
158efa8b4f3SAxel Dörfler 	BScrollBar *horizontalScrollBar = new BScrollBar(rect, "hscroll",
159efa8b4f3SAxel Dörfler 		fImageView, 0, 150, B_HORIZONTAL);
160efa8b4f3SAxel Dörfler 	AddChild(horizontalScrollBar);
16113afa642SPhil Greenway 
16213afa642SPhil Greenway 	rect.left = 0;
16307caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
1640cd4ecd8SStephan Aßmus 	rect.bottom -= 1;
165d3046f7dSMichael Pfeiffer 	fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
166cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
167d3046f7dSMichael Pfeiffer 	AddChild(fStatusView);
16813afa642SPhil Greenway 
16913afa642SPhil Greenway 	rect = Bounds();
1700916ab53SMatthew Wilber 	rect.top	= viewFrame.top - 1;
17113afa642SPhil Greenway 	rect.left	= viewFrame.right + 1;
1720916ab53SMatthew Wilber 	rect.bottom	= viewFrame.bottom + 1;
1730916ab53SMatthew Wilber 	rect.right	+= 1;
174efa8b4f3SAxel Dörfler 	BScrollBar *verticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
175efa8b4f3SAxel Dörfler 		0, 150, B_VERTICAL);
176efa8b4f3SAxel Dörfler 	AddChild(verticalScrollBar);
17713afa642SPhil Greenway 
17803839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
17913afa642SPhil Greenway 
180134d6076SMichael Pfeiffer 	// finish creating the window
181efa8b4f3SAxel Dörfler 	fImageView->SetImage(ref);
182134d6076SMichael Pfeiffer 	fImageView->SetTrackerMessenger(trackerMessenger);
1837eca0987SMichael Pfeiffer 
184d9f6762dSMichael Pfeiffer 	if (InitCheck() != B_OK) {
185e6a50d9cSMichael Pfeiffer 		BAlert* alert;
186e6a50d9cSMichael Pfeiffer 		alert = new BAlert("ShowImage",
18756b0c7b9SKarsten Heimrich 			"Could not load image! Either the file or an image translator for "
18856b0c7b9SKarsten Heimrich 			"it does not exist.", "OK", NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
189e6a50d9cSMichael Pfeiffer 		alert->Go();
190efa8b4f3SAxel Dörfler 
1915e09d5dbSRyan Leavengood 		// quit if file could not be opened
1925e09d5dbSRyan Leavengood 		Quit();
193efa8b4f3SAxel Dörfler 		return;
194d10d5947SMichael Pfeiffer 	}
195402c09e5SMatthew Wilber 
196d9f6762dSMichael Pfeiffer 	// add View menu here so it can access ShowImageView methods
197d9f6762dSMichael Pfeiffer 	BMenu* menu = new BMenu("View");
198*fd952aefSRyan Leavengood 	_BuildViewMenu(menu, false);
199d9f6762dSMichael Pfeiffer 	fBar->AddItem(menu);
200*fd952aefSRyan Leavengood 	_MarkMenuItem(fBar, MSG_DITHER_IMAGE, fImageView->GetDither());
201d9f6762dSMichael Pfeiffer 	UpdateTitle();
202d9f6762dSMichael Pfeiffer 
203d9f6762dSMichael Pfeiffer 	SetPulseRate(100000);
204d9f6762dSMichael Pfeiffer 		// every 1/10 second; ShowImageView needs it for marching ants
205d9f6762dSMichael Pfeiffer 
206d9f6762dSMichael Pfeiffer 	WindowRedimension(fImageView->GetBitmap());
207d9f6762dSMichael Pfeiffer 	fImageView->MakeFocus(true); // to receive KeyDown messages
208d9f6762dSMichael Pfeiffer 	Show();
209d9f6762dSMichael Pfeiffer 
210402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
211402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
212402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
21313afa642SPhil Greenway }
21413afa642SPhil Greenway 
215efa8b4f3SAxel Dörfler 
21613afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
21713afa642SPhil Greenway {
2186163f333SKarsten Heimrich 	delete fResizerWindowMessenger;
21913afa642SPhil Greenway }
22013afa642SPhil Greenway 
221efa8b4f3SAxel Dörfler 
222cdb89ebbSMatthew Wilber status_t
223cdb89ebbSMatthew Wilber ShowImageWindow::InitCheck()
22413afa642SPhil Greenway {
225d3046f7dSMichael Pfeiffer 	if (!fImageView || fImageView->GetBitmap() == NULL)
22613afa642SPhil Greenway 		return B_ERROR;
227efa8b4f3SAxel Dörfler 
22813afa642SPhil Greenway 	return B_OK;
22913afa642SPhil Greenway }
230cdb89ebbSMatthew Wilber 
231efa8b4f3SAxel Dörfler 
232cdb89ebbSMatthew Wilber void
233cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
23413afa642SPhil Greenway {
235e6a50d9cSMichael Pfeiffer 	BString path;
236d3046f7dSMichael Pfeiffer 	fImageView->GetPath(&path);
237e6a50d9cSMichael Pfeiffer 	SetTitle(path.String());
23813afa642SPhil Greenway }
23913afa642SPhil Greenway 
24056b0c7b9SKarsten Heimrich 
241d9f6762dSMichael Pfeiffer void
242d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu *menu)
243d9f6762dSMichael Pfeiffer {
244*fd952aefSRyan Leavengood 	_BuildViewMenu(menu, true);
245d9f6762dSMichael Pfeiffer }
246efa8b4f3SAxel Dörfler 
24756b0c7b9SKarsten Heimrich 
248cdb89ebbSMatthew Wilber void
249*fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu *menu, bool popupMenu)
250da87390fSMichael Pfeiffer {
251*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, this);
252*fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
253efa8b4f3SAxel Dörfler 	BMenu* delayMenu = new BMenu("Slide Delay");
254efa8b4f3SAxel Dörfler 	if (fSlideShowDelay == NULL)
255efa8b4f3SAxel Dörfler 		fSlideShowDelay = delayMenu;
256efa8b4f3SAxel Dörfler 
257efa8b4f3SAxel Dörfler 	delayMenu->SetRadioMode(true);
25856b0c7b9SKarsten Heimrich 	// Note: ShowImage loads images in window thread so it becomes unresponsive
25956b0c7b9SKarsten Heimrich 	//		 if slide show delay is too short! (Especially if loading the image
26056b0c7b9SKarsten Heimrich 	//		 takes as long as or longer than the slide show delay). Should load
26156b0c7b9SKarsten Heimrich 	//		 in background thread!
262*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Three Seconds", 3);
263*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Four Second", 4);
264*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Five Seconds", 5);
265*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Six Seconds", 6);
266*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Seven Seconds", 7);
267*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Eight Seconds", 8);
268*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Nine Seconds", 9);
269*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Ten Seconds", 10);
270*fd952aefSRyan Leavengood 	_AddDelayItem(delayMenu, "Twenty Seconds", 20);
271efa8b4f3SAxel Dörfler 	menu->AddItem(delayMenu);
27230060f17SMatthew Wilber 
273efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
274efa8b4f3SAxel Dörfler 
275*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Original Size", MSG_ORIGINAL_SIZE, 0, 0, this);
276*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Zoom In", MSG_ZOOM_IN, '+', 0, this);
277*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Zoom Out", MSG_ZOOM_OUT, '-', 0, this);
278efa8b4f3SAxel Dörfler 
279efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
280efa8b4f3SAxel Dörfler 
281*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "High-Quality Zooming", MSG_SCALE_BILINEAR, 0, 0, this);
282efa8b4f3SAxel Dörfler 
283efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
284efa8b4f3SAxel Dörfler 
285*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Shrink to Window", MSG_SHRINK_TO_WINDOW, 0, 0, this);
286*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Zoom to Window", MSG_ZOOM_TO_WINDOW, 0, 0, this);
287efa8b4f3SAxel Dörfler 
288efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
289efa8b4f3SAxel Dörfler 
290*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Full Screen", MSG_FULL_SCREEN, 'F', 0, this);
291*fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
292efa8b4f3SAxel Dörfler 
293efa8b4f3SAxel Dörfler 	AddShortcut(B_ENTER, 0, new BMessage(MSG_FULL_SCREEN));
294efa8b4f3SAxel Dörfler 
295*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Show Caption in Full Screen Mode", MSG_SHOW_CAPTION, 0,
2966163f333SKarsten Heimrich 		0, this);
297*fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
298efa8b4f3SAxel Dörfler 
299*fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
300da87390fSMichael Pfeiffer 
30119c76de4SMichael Pfeiffer 	bool shrink, zoom, enabled;
302efa8b4f3SAxel Dörfler 
303d3046f7dSMichael Pfeiffer 	shrink = fImageView->GetShrinkToBounds();
304d3046f7dSMichael Pfeiffer 	zoom = fImageView->GetZoomToBounds();
305*fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, shrink);
306*fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_ZOOM_TO_WINDOW, zoom);
307efa8b4f3SAxel Dörfler 
30819c76de4SMichael Pfeiffer 	enabled = !(shrink || zoom);
309*fd952aefSRyan Leavengood 	_EnableMenuItem(menu, MSG_ORIGINAL_SIZE, enabled);
310*fd952aefSRyan Leavengood 	_EnableMenuItem(menu, MSG_ZOOM_IN, enabled);
311*fd952aefSRyan Leavengood 	_EnableMenuItem(menu, MSG_ZOOM_OUT, enabled);
312a60adbf9SAxel Dörfler 
313d9f6762dSMichael Pfeiffer 	if (popupMenu) {
314a60adbf9SAxel Dörfler 		menu->AddSeparatorItem();
315*fd952aefSRyan Leavengood 		_AddItemMenu(menu, "As Desktop Background", MSG_DESKTOP_BACKGROUND, 0, 0,
3166163f333SKarsten Heimrich 			this);
317d9f6762dSMichael Pfeiffer 	}
318da87390fSMichael Pfeiffer }
319da87390fSMichael Pfeiffer 
320efa8b4f3SAxel Dörfler 
321da87390fSMichael Pfeiffer void
322efa8b4f3SAxel Dörfler ShowImageWindow::AddMenus(BMenuBar *bar)
32313afa642SPhil Greenway {
324efa8b4f3SAxel Dörfler 	BMenu *menu = new BMenu("File");
325a8fc7138SMichael Pfeiffer 	fOpenMenu = new RecentDocumentsMenu("Open");
326efa8b4f3SAxel Dörfler 	menu->AddItem(fOpenMenu);
327d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTrigger('O');
328d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
329d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTarget(be_app);
330d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetShortcut('O', 0);
331efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
332780d8a62SMichael Pfeiffer 	BMenu *pmenuSaveAs = new BMenu("Save As" B_UTF8_ELLIPSIS, B_ITEMS_IN_COLUMN);
333cdb89ebbSMatthew Wilber 	BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP);
334fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
335fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
336efa8b4f3SAxel Dörfler 	menu->AddItem(pmenuSaveAs);
337*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Close", B_QUIT_REQUESTED, 'W', 0, this);
338efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
339*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Page Setup" B_UTF8_ELLIPSIS, MSG_PAGE_SETUP, 0, 0, this);
340*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "_Print" B_UTF8_ELLIPSIS, MSG_PREPARE_PRINT, 'P', 0, this);
341efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
342*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "About ShowImage" B_UTF8_ELLIPSIS, B_ABOUT_REQUESTED, 0, 0,
3436163f333SKarsten Heimrich 		be_app);
344efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
345*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Quit", B_QUIT_REQUESTED, 'Q', 0, be_app);
346efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
34713afa642SPhil Greenway 
348efa8b4f3SAxel Dörfler 	menu = new BMenu("Edit");
349*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Undo", B_UNDO, 'Z', 0, this, false);
350efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
351*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Cut", B_CUT, 'X', 0, this, false);
352*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Copy", B_COPY, 'C', 0, this, false);
353*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Paste", B_PASTE, 'V', 0, this, false);
354*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Clear", MSG_CLEAR_SELECT, 0, 0, this, false);
355efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
356*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Select All", MSG_SELECT_ALL, 'A', 0, this);
357efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
35813afa642SPhil Greenway 
359efa8b4f3SAxel Dörfler 	menu = fBrowseMenu = new BMenu("Browse");
360*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "First Page", MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this);
361*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Last Page", MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this);
362*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Previous Page", MSG_PAGE_PREV, B_LEFT_ARROW, 0, this);
363*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Next Page", MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this);
364a5360d40SDarkWyrm 	fGoToPageMenu = new BMenu("Go to Page");
3655e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
366efa8b4f3SAxel Dörfler 	menu->AddItem(fGoToPageMenu);
367efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
368*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Previous File", MSG_FILE_PREV, B_UP_ARROW, 0, this);
369*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Next File", MSG_FILE_NEXT, B_DOWN_ARROW, 0, this);
370efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
37103839579SMatthew Wilber 
372efa8b4f3SAxel Dörfler 	menu = new BMenu("Image");
373*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Rotate Counterclockwise", MSG_ROTATE_270, '[', 0, this);
374*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Rotate Clockwise", MSG_ROTATE_90, ']', 0, this);
375efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
376*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Flip Left to Right", MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this);
377*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Flip Top to Bottom", MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this);
378efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
379*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Invert Colors", MSG_INVERT, 0, 0, this);
380d9f6762dSMichael Pfeiffer 	menu->AddSeparatorItem();
381*fd952aefSRyan Leavengood 	fResizeItem = _AddItemMenu(menu, "Resize" B_UTF8_ELLIPSIS,
3826163f333SKarsten Heimrich 		MSG_OPEN_RESIZER_WINDOW, 0, 0, this);
383efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
384d9f6762dSMichael Pfeiffer 	menu->AddSeparatorItem();
385*fd952aefSRyan Leavengood 	_AddItemMenu(menu, "Use as Desktop Background", MSG_DESKTOP_BACKGROUND, 0, 0,
3866163f333SKarsten Heimrich 		this);
38713afa642SPhil Greenway }
38813afa642SPhil Greenway 
389efa8b4f3SAxel Dörfler 
390cdb89ebbSMatthew Wilber BMenuItem*
391*fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu *menu, const char *label, uint32 what,
3926163f333SKarsten Heimrich 	const char shortcut, uint32 modifier, const BHandler *target, bool enabled)
393cdb89ebbSMatthew Wilber {
3946163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut, modifier);
395efa8b4f3SAxel Dörfler 	menu->AddItem(item);
396efa8b4f3SAxel Dörfler 
3976163f333SKarsten Heimrich 	item->SetTarget(target);
3986163f333SKarsten Heimrich 	item->SetEnabled(enabled);
3996163f333SKarsten Heimrich 
400efa8b4f3SAxel Dörfler 	return item;
40113afa642SPhil Greenway }
40213afa642SPhil Greenway 
403efa8b4f3SAxel Dörfler 
404ad13f387SMichael Pfeiffer BMenuItem*
405*fd952aefSRyan Leavengood ShowImageWindow::_AddDelayItem(BMenu *menu, const char *label, float value)
406ad13f387SMichael Pfeiffer {
407efa8b4f3SAxel Dörfler 	BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
408efa8b4f3SAxel Dörfler 	message->AddFloat("value", value);
409ad13f387SMichael Pfeiffer 
4106163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, message, 0);
411efa8b4f3SAxel Dörfler 	item->SetTarget(this);
412ad13f387SMichael Pfeiffer 
413d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
414efa8b4f3SAxel Dörfler 	if (marked)
415efa8b4f3SAxel Dörfler 		item->SetMarked(true);
416ad13f387SMichael Pfeiffer 
417efa8b4f3SAxel Dörfler 	menu->AddItem(item);
418efa8b4f3SAxel Dörfler 	return item;
419ad13f387SMichael Pfeiffer }
420ad13f387SMichael Pfeiffer 
421efa8b4f3SAxel Dörfler 
422cdb89ebbSMatthew Wilber void
423cdb89ebbSMatthew Wilber ShowImageWindow::WindowRedimension(BBitmap *pbitmap)
42413afa642SPhil Greenway {
425d10d5947SMichael Pfeiffer 	BScreen screen;
42671a34702SAxel Dörfler 	if (!screen.IsValid())
427efa8b4f3SAxel Dörfler 		return;
428efa8b4f3SAxel Dörfler 
429d10d5947SMichael Pfeiffer 	BRect r(pbitmap->Bounds());
430fc5ca95dSStephan Aßmus 	float width = r.Width() + 2 * PEN_SIZE + B_V_SCROLL_BAR_WIDTH;
43156b0c7b9SKarsten Heimrich 	float height = r.Height() + 2 * PEN_SIZE + 1 + fBar->Frame().Height() +
43256b0c7b9SKarsten Heimrich 		B_H_SCROLL_BAR_HEIGHT;
433cdb89ebbSMatthew Wilber 
4346163f333SKarsten Heimrich 	BRect frame = screen.Frame();
4356163f333SKarsten Heimrich 	const float windowBorder = 5;
436d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
4376163f333SKarsten Heimrich 	float maxWidth = frame.Width() + 1 - windowBorder - Frame().left;
4386163f333SKarsten Heimrich 	float maxHeight = frame.Height() + 1 - windowBorder - Frame().top;
439cdb89ebbSMatthew Wilber 
440a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
441a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
442efa8b4f3SAxel Dörfler 
443fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
444a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
445efa8b4f3SAxel Dörfler 	if (maxWidth > maxW)
446efa8b4f3SAxel Dörfler 		maxWidth = maxW;
447efa8b4f3SAxel Dörfler 	if (maxHeight > maxH)
448efa8b4f3SAxel Dörfler 		maxHeight = maxH;
449efa8b4f3SAxel Dörfler 	if (width < minW)
450efa8b4f3SAxel Dörfler 		width = minW;
451efa8b4f3SAxel Dörfler 	if (height < minH)
452efa8b4f3SAxel Dörfler 		height = minH;
453a8fc7138SMichael Pfeiffer 
454efa8b4f3SAxel Dörfler 	if (width > maxWidth)
455efa8b4f3SAxel Dörfler 		width = maxWidth;
456efa8b4f3SAxel Dörfler 	if (height > maxHeight)
457efa8b4f3SAxel Dörfler 		height = maxHeight;
458d10d5947SMichael Pfeiffer 
459d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
46013afa642SPhil Greenway }
46113afa642SPhil Greenway 
462efa8b4f3SAxel Dörfler 
463cdb89ebbSMatthew Wilber void
464cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
46513afa642SPhil Greenway {
4666163f333SKarsten Heimrich 	BWindow::FrameResized(width, height);
46713afa642SPhil Greenway }
46813afa642SPhil Greenway 
469efa8b4f3SAxel Dörfler 
4707eca0987SMichael Pfeiffer bool
471*fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what)
4727eca0987SMichael Pfeiffer {
4737eca0987SMichael Pfeiffer 	bool marked = false;
4746163f333SKarsten Heimrich 	BMenuItem *item = fBar->FindItem(what);
4757eca0987SMichael Pfeiffer 	if (item != NULL) {
4767eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
4777eca0987SMichael Pfeiffer 		item->SetMarked(marked);
4787eca0987SMichael Pfeiffer 	}
4797eca0987SMichael Pfeiffer 	return marked;
4807eca0987SMichael Pfeiffer }
4817eca0987SMichael Pfeiffer 
482efa8b4f3SAxel Dörfler 
483cdb89ebbSMatthew Wilber void
484*fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu *menu, uint32 what, bool enable)
485e6a50d9cSMichael Pfeiffer {
4866163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
4876163f333SKarsten Heimrich 	if (item && item->IsEnabled() != enable)
488e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
489e6a50d9cSMichael Pfeiffer }
490e6a50d9cSMichael Pfeiffer 
491efa8b4f3SAxel Dörfler 
492e6a50d9cSMichael Pfeiffer void
493*fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu *menu, uint32 what, bool marked)
494e6a50d9cSMichael Pfeiffer {
4956163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
4966163f333SKarsten Heimrich 	if (item && item->IsMarked() != marked)
497e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
498e6a50d9cSMichael Pfeiffer }
499e6a50d9cSMichael Pfeiffer 
500efa8b4f3SAxel Dörfler 
501da87390fSMichael Pfeiffer void
502*fd952aefSRyan Leavengood ShowImageWindow::_MarkSlideShowDelay(float value)
503da87390fSMichael Pfeiffer {
504d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
505da87390fSMichael Pfeiffer 	float v;
506da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
507d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
508da87390fSMichael Pfeiffer 		if (item) {
509da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
5106163f333SKarsten Heimrich 				if (!item->IsMarked())
511da87390fSMichael Pfeiffer 					item->SetMarked(true);
512da87390fSMichael Pfeiffer 				return;
513da87390fSMichael Pfeiffer 			}
514da87390fSMichael Pfeiffer 		}
515da87390fSMichael Pfeiffer 	}
516da87390fSMichael Pfeiffer }
517e6a50d9cSMichael Pfeiffer 
51819c76de4SMichael Pfeiffer 
51919c76de4SMichael Pfeiffer void
520*fd952aefSRyan Leavengood ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what)
52119c76de4SMichael Pfeiffer {
522*fd952aefSRyan Leavengood 	bool enabled = _ToggleMenuItem(what);
5236163f333SKarsten Heimrich 	if (shrink)
524d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
5256163f333SKarsten Heimrich 	else
526d3046f7dSMichael Pfeiffer 		fImageView->SetZoomToBounds(enabled);
5276163f333SKarsten Heimrich 
528d3046f7dSMichael Pfeiffer 	enabled = !(fImageView->GetShrinkToBounds() || fImageView->GetZoomToBounds());
529*fd952aefSRyan Leavengood 	_EnableMenuItem(fBar, MSG_ORIGINAL_SIZE, enabled);
530*fd952aefSRyan Leavengood 	_EnableMenuItem(fBar, MSG_ZOOM_IN, enabled);
531*fd952aefSRyan Leavengood 	_EnableMenuItem(fBar, MSG_ZOOM_OUT, enabled);
53219c76de4SMichael Pfeiffer }
53319c76de4SMichael Pfeiffer 
534efa8b4f3SAxel Dörfler 
535e6a50d9cSMichael Pfeiffer void
536efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage *message)
53713afa642SPhil Greenway {
538efa8b4f3SAxel Dörfler 	switch (message->what) {
539ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
540ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
541ee7b4f39SMatthew Wilber 			fModified = true;
542ee7b4f39SMatthew Wilber 			break;
543ee7b4f39SMatthew Wilber 
544fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
545fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
546d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
547cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
548*fd952aefSRyan Leavengood 				_SaveAs(message);
54913afa642SPhil Greenway 			break;
550fc0a275bSMatthew Wilber 
551fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
552fc0a275bSMatthew Wilber 			// User specified where to save the output image
553*fd952aefSRyan Leavengood 			_SaveToFile(message);
55407caaa8eSMatthew Wilber 			break;
55507caaa8eSMatthew Wilber 
556cdb89ebbSMatthew Wilber 		case B_CANCEL:
557d3046f7dSMichael Pfeiffer 			delete fSavePanel;
558d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
559cdb89ebbSMatthew Wilber 			break;
560cdb89ebbSMatthew Wilber 
5616163f333SKarsten Heimrich 		case MSG_UPDATE_STATUS: {
5626163f333SKarsten Heimrich 			int32 pages = fImageView->PageCount();
5636163f333SKarsten Heimrich 			int32 curPage = fImageView->CurrentPage();
5646c305411SMatthew Wilber 
5656c305411SMatthew Wilber 			bool benable = (pages > 1) ? true : false;
566*fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_FIRST, benable);
567*fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_LAST, benable);
568*fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_NEXT, benable);
569*fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_PREV, benable);
5701d592070SMatthew Wilber 
571*fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_FILE_NEXT, fImageView->HasNextFile());
572*fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_FILE_PREV, fImageView->HasPrevFile());
573134d6076SMichael Pfeiffer 
574d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
5756c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
5766c305411SMatthew Wilber 				// pages is different
5776c305411SMatthew Wilber 
578d3046f7dSMichael Pfeiffer 				while (fGoToPageMenu->CountItems() > 0)
5796c305411SMatthew Wilber 					// Remove all page numbers
580d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
5816c305411SMatthew Wilber 
582780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
5836c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
5846163f333SKarsten Heimrich 					BMessage *pgomsg = new BMessage(MSG_GOTO_PAGE);
5856c305411SMatthew Wilber 					pgomsg->AddInt32("page", i);
5866163f333SKarsten Heimrich 
5876163f333SKarsten Heimrich 					char shortcut = 0;
588780d8a62SMichael Pfeiffer 					if (i < 10) {
589780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
590780d8a62SMichael Pfeiffer 					} else if (i == 10) {
591780d8a62SMichael Pfeiffer 						shortcut = '0';
592780d8a62SMichael Pfeiffer 					}
5936163f333SKarsten Heimrich 
5946163f333SKarsten Heimrich 					BString strCaption;
5956163f333SKarsten Heimrich 					strCaption << i;
5966163f333SKarsten Heimrich 
5976163f333SKarsten Heimrich 					BMenuItem *item = new BMenuItem(strCaption.String(), pgomsg,
5986163f333SKarsten Heimrich 						shortcut);
5996c305411SMatthew Wilber 					if (curPage == i)
600efa8b4f3SAxel Dörfler 						item->SetMarked(true);
601efa8b4f3SAxel Dörfler 					fGoToPageMenu->AddItem(item);
6026c305411SMatthew Wilber 				}
6036c305411SMatthew Wilber 			} else {
6046c305411SMatthew Wilber 				// Make sure the correct page is marked
6056c305411SMatthew Wilber 				BMenuItem *pcurItem;
606d3046f7dSMichael Pfeiffer 				pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
6076c305411SMatthew Wilber 				if (!pcurItem->IsMarked()) {
6086c305411SMatthew Wilber 					pcurItem->SetMarked(true);
6096c305411SMatthew Wilber 				}
6106c305411SMatthew Wilber 			}
6116c305411SMatthew Wilber 
61216b663b7SMatthew Wilber 			// Disable the Invert menu item if the bitmap color space
61316b663b7SMatthew Wilber 			// is B_CMAP8. (B_CMAP8 is currently unsupported by the
61416b663b7SMatthew Wilber 			// invert algorithm)
61516b663b7SMatthew Wilber 			color_space colors = B_NO_COLOR_SPACE;
616efa8b4f3SAxel Dörfler 			message->FindInt32("colors", reinterpret_cast<int32 *>(&colors));
617*fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_INVERT, (colors != B_CMAP8));
61816b663b7SMatthew Wilber 
6190cd4ecd8SStephan Aßmus 			BString status;
620d9f6762dSMichael Pfeiffer 			bool messageProvidesSize = false;
6218f5fd23fSRyan Leavengood 			if (message->FindInt32("width", &fWidth) >= B_OK
6228f5fd23fSRyan Leavengood 				&& message->FindInt32("height", &fHeight) >= B_OK) {
6238f5fd23fSRyan Leavengood 				status << fWidth << "x" << fHeight;
624d9f6762dSMichael Pfeiffer 				messageProvidesSize = true;
6250cd4ecd8SStephan Aßmus 			}
6260cd4ecd8SStephan Aßmus 
62703839579SMatthew Wilber 			BString str;
6280acb8cc4SMichael Pfeiffer 			if (message->FindString("status", &str) == B_OK && str.Length() > 0) {
6290acb8cc4SMichael Pfeiffer 				if (status.Length() > 0)
6300acb8cc4SMichael Pfeiffer 					status << ", ";
6310cd4ecd8SStephan Aßmus 				status << str;
6325eb50e46SMichael Pfeiffer 			}
6330cd4ecd8SStephan Aßmus 
634d9f6762dSMichael Pfeiffer 			if (messageProvidesSize) {
635*fd952aefSRyan Leavengood 				_UpdateResizerWindow(fWidth, fHeight);
636d9f6762dSMichael Pfeiffer 			}
637d9f6762dSMichael Pfeiffer 
6380cd4ecd8SStephan Aßmus 			fStatusView->SetText(status);
6397eca0987SMichael Pfeiffer 
6407eca0987SMichael Pfeiffer 			UpdateTitle();
6416163f333SKarsten Heimrich 		}	break;
64203839579SMatthew Wilber 
6436163f333SKarsten Heimrich 		case MSG_UPDATE_STATUS_TEXT: {
6448f5fd23fSRyan Leavengood 			BString status;
6458f5fd23fSRyan Leavengood 			status << fWidth << "x" << fHeight;
6468f5fd23fSRyan Leavengood 			BString str;
6478f5fd23fSRyan Leavengood 			if (message->FindString("status", &str) == B_OK && str.Length() > 0) {
6488f5fd23fSRyan Leavengood 				status << ", " << str;
6498f5fd23fSRyan Leavengood 				fStatusView->SetText(status);
6508f5fd23fSRyan Leavengood 			}
6516163f333SKarsten Heimrich 		}	break;
6528f5fd23fSRyan Leavengood 
6536163f333SKarsten Heimrich 		case MSG_SELECTION: {
6548ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
6558ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
6568ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
6578ad30bcfSMatthew Wilber 			bool benable;
658efa8b4f3SAxel Dörfler 			if (message->FindBool("has_selection", &benable) == B_OK) {
659*fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_CUT, benable);
660*fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_COPY, benable);
661*fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, MSG_CLEAR_SELECT, benable);
6628ad30bcfSMatthew Wilber 			}
6636163f333SKarsten Heimrich 		}	break;
6648ad30bcfSMatthew Wilber 
6656163f333SKarsten Heimrich 		case MSG_UNDO_STATE: {
6667598450eSMatthew Wilber 			bool benable;
667efa8b4f3SAxel Dörfler 			if (message->FindBool("can_undo", &benable) == B_OK)
668*fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_UNDO, benable);
6696163f333SKarsten Heimrich 		}	break;
6707598450eSMatthew Wilber 
6716163f333SKarsten Heimrich 		case MSG_CLIPBOARD_CHANGED: {
6726163f333SKarsten Heimrich 			// The app sends this message after it examines the clipboard in
6736163f333SKarsten Heimrich 			// response to a B_CLIPBOARD_CHANGED message
674402c09e5SMatthew Wilber 			bool bdata;
675efa8b4f3SAxel Dörfler 			if (message->FindBool("data_available", &bdata) == B_OK)
676*fd952aefSRyan Leavengood 				_EnableMenuItem(fBar, B_PASTE, bdata);
6776163f333SKarsten Heimrich 		}	break;
678402c09e5SMatthew Wilber 
67913afa642SPhil Greenway 		case B_UNDO:
6807598450eSMatthew Wilber 			fImageView->Undo();
68113afa642SPhil Greenway 			break;
6826163f333SKarsten Heimrich 
68313afa642SPhil Greenway 		case B_CUT:
684d3046f7dSMichael Pfeiffer 			fImageView->Cut();
68513afa642SPhil Greenway 			break;
6866163f333SKarsten Heimrich 
68713afa642SPhil Greenway 		case B_COPY:
688d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
68913afa642SPhil Greenway 			break;
6906163f333SKarsten Heimrich 
69113afa642SPhil Greenway 		case B_PASTE:
692d3046f7dSMichael Pfeiffer 			fImageView->Paste();
69313afa642SPhil Greenway 			break;
6946163f333SKarsten Heimrich 
69513afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
696d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
69713afa642SPhil Greenway 			break;
6986163f333SKarsten Heimrich 
69913afa642SPhil Greenway 		case MSG_SELECT_ALL:
700d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
70113afa642SPhil Greenway 			break;
70213afa642SPhil Greenway 
70303839579SMatthew Wilber 		case MSG_PAGE_FIRST:
704*fd952aefSRyan Leavengood 			if (_ClosePrompt())
705d3046f7dSMichael Pfeiffer 				fImageView->FirstPage();
70603839579SMatthew Wilber 			break;
70703839579SMatthew Wilber 
70803839579SMatthew Wilber 		case MSG_PAGE_LAST:
709*fd952aefSRyan Leavengood 			if (_ClosePrompt())
710d3046f7dSMichael Pfeiffer 				fImageView->LastPage();
71103839579SMatthew Wilber 			break;
71203839579SMatthew Wilber 
71303839579SMatthew Wilber 		case MSG_PAGE_NEXT:
714*fd952aefSRyan Leavengood 			if (_ClosePrompt())
715d3046f7dSMichael Pfeiffer 				fImageView->NextPage();
71603839579SMatthew Wilber 			break;
71703839579SMatthew Wilber 
71803839579SMatthew Wilber 		case MSG_PAGE_PREV:
719*fd952aefSRyan Leavengood 			if (_ClosePrompt())
720d3046f7dSMichael Pfeiffer 				fImageView->PrevPage();
72103839579SMatthew Wilber 			break;
72203839579SMatthew Wilber 
7236163f333SKarsten Heimrich 		case MSG_GOTO_PAGE: {
724*fd952aefSRyan Leavengood 			if (!_ClosePrompt())
725ee7b4f39SMatthew Wilber 				break;
726ee7b4f39SMatthew Wilber 
7276163f333SKarsten Heimrich 			int32 newPage;
7286163f333SKarsten Heimrich 			if (message->FindInt32("page", &newPage) != B_OK)
7296163f333SKarsten Heimrich 				break;
7306163f333SKarsten Heimrich 
7316163f333SKarsten Heimrich 			int32 curPage = fImageView->CurrentPage();
7326163f333SKarsten Heimrich 			int32 pages = fImageView->PageCount();
7336c305411SMatthew Wilber 
7346c305411SMatthew Wilber 			if (newPage > 0 && newPage <= pages) {
7356163f333SKarsten Heimrich 				BMenuItem* pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
7366163f333SKarsten Heimrich 				BMenuItem* pnewItem = fGoToPageMenu->ItemAt(newPage - 1);
7376163f333SKarsten Heimrich 				if (pcurItem && pnewItem) {
7386c305411SMatthew Wilber 					pcurItem->SetMarked(false);
7396c305411SMatthew Wilber 					pnewItem->SetMarked(true);
740d3046f7dSMichael Pfeiffer 					fImageView->GoToPage(newPage);
7416c305411SMatthew Wilber 				}
7426c305411SMatthew Wilber 			}
7436163f333SKarsten Heimrich 		}	break;
7446c305411SMatthew Wilber 
745cdb89ebbSMatthew Wilber 		case MSG_DITHER_IMAGE:
746*fd952aefSRyan Leavengood 			fImageView->SetDither(_ToggleMenuItem(message->what));
7477eca0987SMichael Pfeiffer 			break;
7487eca0987SMichael Pfeiffer 
74919c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
750*fd952aefSRyan Leavengood 			_ResizeToWindow(true, message->what);
75119c76de4SMichael Pfeiffer 			break;
7526163f333SKarsten Heimrich 
75319c76de4SMichael Pfeiffer 		case MSG_ZOOM_TO_WINDOW:
754*fd952aefSRyan Leavengood 			_ResizeToWindow(false, message->what);
7557eca0987SMichael Pfeiffer 			break;
7567eca0987SMichael Pfeiffer 
7577eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
758*fd952aefSRyan Leavengood 			if (_ClosePrompt())
759d3046f7dSMichael Pfeiffer 				fImageView->PrevFile();
7607eca0987SMichael Pfeiffer 			break;
7617eca0987SMichael Pfeiffer 
7627eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
763*fd952aefSRyan Leavengood 			if (_ClosePrompt())
764d3046f7dSMichael Pfeiffer 				fImageView->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 
783ad13f387SMichael Pfeiffer 		case MSG_INVERT:
784d3046f7dSMichael Pfeiffer 			fImageView->Invert();
785ad13f387SMichael Pfeiffer 			break;
7866163f333SKarsten Heimrich 
7876163f333SKarsten Heimrich 		case MSG_SLIDE_SHOW: {
7886163f333SKarsten Heimrich 			BMenuItem *item = fBar->FindItem(message->what);
789ee7b4f39SMatthew Wilber 			if (!item)
790ee7b4f39SMatthew Wilber 				break;
791ee7b4f39SMatthew Wilber 			if (item->IsMarked()) {
792ee7b4f39SMatthew Wilber 				item->SetMarked(false);
793ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(true);
794d3046f7dSMichael Pfeiffer 				fImageView->StopSlideShow();
795*fd952aefSRyan Leavengood 			} else if (_ClosePrompt()) {
796ee7b4f39SMatthew Wilber 				item->SetMarked(true);
797ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(false);
798ee7b4f39SMatthew Wilber 				fImageView->StartSlideShow();
799ad13f387SMichael Pfeiffer 			}
8006163f333SKarsten Heimrich 		}	break;
801ee7b4f39SMatthew Wilber 
8026163f333SKarsten Heimrich 		case MSG_SLIDE_SHOW_DELAY: {
803ad13f387SMichael Pfeiffer 			float value;
804efa8b4f3SAxel Dörfler 			if (message->FindFloat("value", &value) == B_OK) {
805d3046f7dSMichael Pfeiffer 				fImageView->SetSlideShowDelay(value);
806da87390fSMichael Pfeiffer 				// in case message is sent from popup menu
807*fd952aefSRyan Leavengood 				_MarkSlideShowDelay(value);
808ad13f387SMichael Pfeiffer 			}
8096163f333SKarsten Heimrich 		}	break;
810ad13f387SMichael Pfeiffer 
811ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
812*fd952aefSRyan Leavengood 			_ToggleFullScreen();
813ad13f387SMichael Pfeiffer 			break;
8146163f333SKarsten Heimrich 
815fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
816fc5ca95dSStephan Aßmus 			if (fFullScreen)
817*fd952aefSRyan Leavengood 				_ToggleFullScreen();
818fc5ca95dSStephan Aßmus 			break;
8196163f333SKarsten Heimrich 
8206163f333SKarsten Heimrich 		case MSG_SHOW_CAPTION: {
821*fd952aefSRyan 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:
833*fd952aefSRyan Leavengood 			_PageSetup();
834780d8a62SMichael Pfeiffer 			break;
8356163f333SKarsten Heimrich 
836780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
837*fd952aefSRyan Leavengood 			_PrepareForPrint();
838780d8a62SMichael Pfeiffer 			break;
8396163f333SKarsten Heimrich 
840780d8a62SMichael Pfeiffer 		case MSG_PRINT:
841*fd952aefSRyan 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:
853d3046f7dSMichael Pfeiffer 			fImageView->SetZoom(1.0);
854780d8a62SMichael Pfeiffer 			break;
8556163f333SKarsten Heimrich 
85681b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
857*fd952aefSRyan Leavengood 			fImageView->SetScaleBilinear(_ToggleMenuItem(message->what));
85881b9c776SMichael Pfeiffer 			break;
859780d8a62SMichael Pfeiffer 
8606163f333SKarsten Heimrich 		case MSG_OPEN_RESIZER_WINDOW: {
8616163f333SKarsten Heimrich 			if (fImageView->GetBitmap() != NULL) {
862d9f6762dSMichael Pfeiffer 				BRect rect = fImageView->GetBitmap()->Bounds();
863*fd952aefSRyan Leavengood 				_OpenResizerWindow(rect.IntegerWidth()+1, rect.IntegerHeight()+1);
864d9f6762dSMichael Pfeiffer 			}
8656163f333SKarsten Heimrich 		}	break;
8666163f333SKarsten Heimrich 
8676163f333SKarsten Heimrich 		case MSG_RESIZE: {
868d9f6762dSMichael Pfeiffer 			int w = message->FindInt32("w");
869d9f6762dSMichael Pfeiffer 			int h = message->FindInt32("h");
870d9f6762dSMichael Pfeiffer 			fImageView->ResizeImage(w, h);
8716163f333SKarsten Heimrich 		} break;
8726163f333SKarsten Heimrich 
873880be331SRyan Leavengood 		case MSG_RESIZER_WINDOW_QUIT:
8746163f333SKarsten Heimrich 			delete fResizerWindowMessenger;
875d9f6762dSMichael Pfeiffer 			fResizerWindowMessenger = NULL;
876d9f6762dSMichael Pfeiffer 			break;
877d9f6762dSMichael Pfeiffer 
8786163f333SKarsten Heimrich 		case MSG_DESKTOP_BACKGROUND: {
879a60adbf9SAxel Dörfler 			BPath path;
880a60adbf9SAxel Dörfler 			if (path.SetTo(fImageView->Image()) == B_OK) {
8815921f4e2SAxel Dörfler 				BackgroundImage::SetDesktopImage(B_CURRENT_WORKSPACE,
8825921f4e2SAxel Dörfler 					path.Path(), BackgroundImage::kScaledToFit,
8835921f4e2SAxel Dörfler 					BPoint(0, 0), false);
884a60adbf9SAxel Dörfler 			}
8856163f333SKarsten Heimrich 		}	break;
886a60adbf9SAxel Dörfler 
88713afa642SPhil Greenway 		default:
888efa8b4f3SAxel Dörfler 			BWindow::MessageReceived(message);
88913afa642SPhil Greenway 			break;
89013afa642SPhil Greenway 	}
89113afa642SPhil Greenway }
892fc0a275bSMatthew Wilber 
893efa8b4f3SAxel Dörfler 
894fc0a275bSMatthew Wilber void
895*fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage *message)
896fc0a275bSMatthew Wilber {
897cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
898cdb89ebbSMatthew Wilber 	translator_id outTranslator;
899cdb89ebbSMatthew Wilber 	uint32 outType;
9006163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
901efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9026163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
903cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
904fc0a275bSMatthew Wilber 		return;
905fc0a275bSMatthew Wilber 
906cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
907cdb89ebbSMatthew Wilber 	// message that the save panel will send back
908c1a10c14SKarsten Heimrich 	BMessage panelMsg(MSG_SAVE_PANEL);
909c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTranslatorField, outTranslator);
910c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTypeField, outType);
911cdb89ebbSMatthew Wilber 
912cdb89ebbSMatthew Wilber 	// Create save panel and show it
9136163f333SKarsten Heimrich 	BMessenger target(this);
914efa8b4f3SAxel Dörfler 	fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
915c1a10c14SKarsten Heimrich 		&target, NULL, 0, false, &panelMsg);
916d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
917fc0a275bSMatthew Wilber 		return;
918a60adbf9SAxel Dörfler 
919d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
920d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
921fc0a275bSMatthew Wilber }
922fc0a275bSMatthew Wilber 
923efa8b4f3SAxel Dörfler 
924fc0a275bSMatthew Wilber void
925*fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage *message)
926fc0a275bSMatthew Wilber {
927cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
928efa8b4f3SAxel Dörfler 	entry_ref dirRef;
929efa8b4f3SAxel Dörfler 	if (message->FindRef("directory", &dirRef) != B_OK)
930fc0a275bSMatthew Wilber 		return;
931efa8b4f3SAxel Dörfler 
932fc0a275bSMatthew Wilber 	const char *filename;
933efa8b4f3SAxel Dörfler 	if (message->FindString("name", &filename) != B_OK)
934fc0a275bSMatthew Wilber 		return;
935fc0a275bSMatthew Wilber 
936cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
937cdb89ebbSMatthew Wilber 	// to save the output image
938cdb89ebbSMatthew Wilber 	translator_id outTranslator;
939cdb89ebbSMatthew Wilber 	uint32 outType;
9406163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
941efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9426163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
943cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
944cdb89ebbSMatthew Wilber 		return;
945cdb89ebbSMatthew Wilber 
946a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
947a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
948a7e78e3bSMatthew Wilber 	BTranslatorRoster *roster = BTranslatorRoster::Default();
949efa8b4f3SAxel Dörfler 	const translation_format *outFormat = NULL;
950efa8b4f3SAxel Dörfler 	int32 outCount = 0;
951efa8b4f3SAxel Dörfler 	if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
952efa8b4f3SAxel Dörfler 		|| outCount < 1)
953a7e78e3bSMatthew Wilber 		return;
954efa8b4f3SAxel Dörfler 
955a7e78e3bSMatthew Wilber 	int32 i;
956efa8b4f3SAxel Dörfler 	for (i = 0; i < outCount; i++) {
957efa8b4f3SAxel Dörfler 		if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
958a7e78e3bSMatthew Wilber 			break;
959a7e78e3bSMatthew Wilber 	}
960efa8b4f3SAxel Dörfler 	if (i == outCount)
961fc0a275bSMatthew Wilber 		return;
962fc0a275bSMatthew Wilber 
963a7e78e3bSMatthew Wilber 	// Write out the image file
964efa8b4f3SAxel Dörfler 	BDirectory dir(&dirRef);
965efa8b4f3SAxel Dörfler 	fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
966fc0a275bSMatthew Wilber }
967fc0a275bSMatthew Wilber 
968efa8b4f3SAxel Dörfler 
969cdb89ebbSMatthew Wilber bool
970*fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt()
971ee7b4f39SMatthew Wilber {
972ee7b4f39SMatthew Wilber 	if (!fModified)
973ee7b4f39SMatthew Wilber 		return true;
974efa8b4f3SAxel Dörfler 
975ee7b4f39SMatthew Wilber 	int32 page, count;
976ee7b4f39SMatthew Wilber 	count = fImageView->PageCount();
977ee7b4f39SMatthew Wilber 	page = fImageView->CurrentPage();
978ee7b4f39SMatthew Wilber 	BString prompt, name;
979ee7b4f39SMatthew Wilber 	fImageView->GetName(&name);
980ee7b4f39SMatthew Wilber 	prompt << "The document '" << name << "'";
981ee7b4f39SMatthew Wilber 	if (count > 1)
982ee7b4f39SMatthew Wilber 		prompt << " (page " << page << ")";
983efa8b4f3SAxel Dörfler 
984ee7b4f39SMatthew Wilber 	prompt << " has been changed. "
985ee7b4f39SMatthew Wilber 		   << "Do you want to close the document?";
986ee7b4f39SMatthew Wilber 	BAlert *pAlert = new BAlert("Close document", prompt.String(),
987ee7b4f39SMatthew Wilber 		"Cancel", "Close");
988efa8b4f3SAxel Dörfler 	if (pAlert->Go() == 0) {
989ee7b4f39SMatthew Wilber 		// Cancel
990ee7b4f39SMatthew Wilber 		return false;
991efa8b4f3SAxel Dörfler 	} else {
992ee7b4f39SMatthew Wilber 		// Close
993187f0b8aSMatthew Wilber 		fModified = false;
994ee7b4f39SMatthew Wilber 		return true;
995ee7b4f39SMatthew Wilber 	}
996ee7b4f39SMatthew Wilber }
997ee7b4f39SMatthew Wilber 
998cdb89ebbSMatthew Wilber 
999ad13f387SMichael Pfeiffer void
1000*fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen()
1001ad13f387SMichael Pfeiffer {
1002ad13f387SMichael Pfeiffer 	BRect frame;
1003ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
1004ad13f387SMichael Pfeiffer 	if (fFullScreen) {
1005ad13f387SMichael Pfeiffer 		BScreen screen;
1006ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
1007ad13f387SMichael Pfeiffer 		frame = screen.Frame();
1008d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
1009ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
1010ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
1011ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
1012ad13f387SMichael Pfeiffer 
1013ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
1014c0b16687SAxel Dörfler 
1015c0b16687SAxel Dörfler 		Activate();
1016c0b16687SAxel Dörfler 			// make the window frontmost
1017ad13f387SMichael Pfeiffer 	} else {
1018ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
1019ad13f387SMichael Pfeiffer 
1020ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
1021ad13f387SMichael Pfeiffer 	}
1022efa8b4f3SAxel Dörfler 
102376d115d8SRyan Leavengood 	fImageView->SetFullScreen(fFullScreen);
1024d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
1025ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
1026ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
1027ad13f387SMichael Pfeiffer }
1028ad13f387SMichael Pfeiffer 
1029efa8b4f3SAxel Dörfler 
1030d3046f7dSMichael Pfeiffer void
1031*fd952aefSRyan Leavengood ShowImageWindow::_LoadSettings()
1032d3046f7dSMichael Pfeiffer {
1033efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1034efa8b4f3SAxel Dörfler 
1035d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1036d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
1037d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
1038d3046f7dSMichael Pfeiffer 
1039efa8b4f3SAxel Dörfler 		int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option());
1040d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
1041d3046f7dSMichael Pfeiffer 
1042efa8b4f3SAxel Dörfler 		float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1043d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
1044d3046f7dSMichael Pfeiffer 
1045d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
1046d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
1047d3046f7dSMichael Pfeiffer 
1048d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
1049d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
1050d3046f7dSMichael Pfeiffer 
1051d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
1052d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
1053d3046f7dSMichael Pfeiffer 
1054d3046f7dSMichael Pfeiffer 		settings->Unlock();
1055d3046f7dSMichael Pfeiffer 	}
1056d3046f7dSMichael Pfeiffer }
1057d3046f7dSMichael Pfeiffer 
1058efa8b4f3SAxel Dörfler 
1059d3046f7dSMichael Pfeiffer void
1060*fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions()
1061d3046f7dSMichael Pfeiffer {
1062efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1063efa8b4f3SAxel Dörfler 
1064d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1065d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
1066d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1067d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1068d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
1069d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
1070d3046f7dSMichael Pfeiffer 		settings->Unlock();
1071d3046f7dSMichael Pfeiffer 	}
1072d3046f7dSMichael Pfeiffer }
1073d3046f7dSMichael Pfeiffer 
1074efa8b4f3SAxel Dörfler 
1075cdb89ebbSMatthew Wilber bool
1076*fd952aefSRyan Leavengood ShowImageWindow::_PageSetup()
1077780d8a62SMichael Pfeiffer {
1078780d8a62SMichael Pfeiffer 	BString name;
1079d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
1080780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
1081efa8b4f3SAxel Dörfler 	if (fPrintSettings != NULL)
1082780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
1083efa8b4f3SAxel Dörfler 
10846163f333SKarsten Heimrich 	status_t status = printJob.ConfigPage();
10856163f333SKarsten Heimrich 	if (status == B_OK) {
1086780d8a62SMichael Pfeiffer 		delete fPrintSettings;
1087780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
1088780d8a62SMichael Pfeiffer 	}
1089efa8b4f3SAxel Dörfler 
10906163f333SKarsten Heimrich 	return status == B_OK;
1091780d8a62SMichael Pfeiffer }
1092780d8a62SMichael Pfeiffer 
1093efa8b4f3SAxel Dörfler 
1094780d8a62SMichael Pfeiffer void
1095*fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint()
1096780d8a62SMichael Pfeiffer {
10976163f333SKarsten Heimrich 	if (fPrintSettings == NULL) {
10986163f333SKarsten Heimrich 		BString name;
10996163f333SKarsten Heimrich 		fImageView->GetName(&name);
11006163f333SKarsten Heimrich 
11016163f333SKarsten Heimrich 		BPrintJob printJob("");
11026163f333SKarsten Heimrich 		if (printJob.ConfigJob() == B_OK)
11036163f333SKarsten Heimrich 			fPrintSettings = printJob.Settings();
11046163f333SKarsten Heimrich 	}
1105780d8a62SMichael Pfeiffer 
1106d3046f7dSMichael Pfeiffer 	fPrintOptions.SetBounds(fImageView->GetBitmap()->Bounds());
1107d3046f7dSMichael Pfeiffer 	fPrintOptions.SetWidth(fImageView->GetBitmap()->Bounds().Width()+1);
1108780d8a62SMichael Pfeiffer 
1109efa8b4f3SAxel Dörfler 	new PrintOptionsWindow(BPoint(Frame().left+30, Frame().top+50),
1110efa8b4f3SAxel Dörfler 		&fPrintOptions, this);
1111780d8a62SMichael Pfeiffer }
1112780d8a62SMichael Pfeiffer 
1113efa8b4f3SAxel Dörfler 
1114780d8a62SMichael Pfeiffer void
1115*fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage *msg)
1116780d8a62SMichael Pfeiffer {
1117780d8a62SMichael Pfeiffer 	status_t st;
1118efa8b4f3SAxel Dörfler 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1119780d8a62SMichael Pfeiffer 		return;
1120780d8a62SMichael Pfeiffer 
1121*fd952aefSRyan Leavengood 	_SavePrintOptions();
1122d3046f7dSMichael Pfeiffer 
1123780d8a62SMichael Pfeiffer 	BString name;
1124d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
11256163f333SKarsten Heimrich 
1126780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
11276163f333SKarsten Heimrich 	if (fPrintSettings)
1128780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
11296163f333SKarsten Heimrich 
1130780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
11316163f333SKarsten Heimrich 		delete fPrintSettings;
11326163f333SKarsten Heimrich 		fPrintSettings = printJob.Settings();
1133780d8a62SMichael Pfeiffer 
1134780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
11353177ae77SStefano Ceccherini 		int32 firstPage = printJob.FirstPage();
11363177ae77SStefano Ceccherini 		int32 lastPage = printJob.LastPage();
11376163f333SKarsten Heimrich 		BRect printableRect = printJob.PrintableRect();
11386163f333SKarsten Heimrich 
1139efa8b4f3SAxel Dörfler 		if (firstPage < 1)
1140780d8a62SMichael Pfeiffer 			firstPage = 1;
1141efa8b4f3SAxel Dörfler 		if (lastPage < firstPage)
1142780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1143780d8a62SMichael Pfeiffer 
11443177ae77SStefano Ceccherini 		BBitmap* bitmap = fImageView->GetBitmap();
11453177ae77SStefano Ceccherini 		float imageWidth = bitmap->Bounds().Width() + 1.0;
11463177ae77SStefano Ceccherini 		float imageHeight = bitmap->Bounds().Height() + 1.0;
1147780d8a62SMichael Pfeiffer 
11486163f333SKarsten Heimrich 		float width;
1149780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
11506163f333SKarsten Heimrich 			case PrintOptions::kFitToPage: {
11516163f333SKarsten Heimrich 				float w1 = printableRect.Width()+1;
11526163f333SKarsten Heimrich 				float w2 = imageWidth * (printableRect.Height() + 1) / imageHeight;
1153efa8b4f3SAxel Dörfler 				if (w2 < w1)
1154780d8a62SMichael Pfeiffer 					width = w2;
1155efa8b4f3SAxel Dörfler 				else
1156780d8a62SMichael Pfeiffer 					width = w1;
11576163f333SKarsten Heimrich 			}	break;
1158780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1159780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1160780d8a62SMichael Pfeiffer 				break;
1161780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1162780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1163780d8a62SMichael Pfeiffer 				break;
1164780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1165780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1166780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1167780d8a62SMichael Pfeiffer 				break;
1168efa8b4f3SAxel Dörfler 
1169780d8a62SMichael Pfeiffer 			default:
1170780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1171780d8a62SMichael Pfeiffer 				width = imageWidth;
1172780d8a62SMichael Pfeiffer 		}
1173780d8a62SMichael Pfeiffer 
1174efa8b4f3SAxel Dörfler 		// TODO: eventually print large images on several pages
1175780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1176d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
11775eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
11785eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
11795eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1180d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1181780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1182780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1183780d8a62SMichael Pfeiffer 	}
1184780d8a62SMichael Pfeiffer }
1185780d8a62SMichael Pfeiffer 
118656b0c7b9SKarsten Heimrich 
1187d9f6762dSMichael Pfeiffer void
1188*fd952aefSRyan Leavengood ShowImageWindow::_OpenResizerWindow(int32 width, int32 height)
1189d9f6762dSMichael Pfeiffer {
1190d9f6762dSMichael Pfeiffer 	if (fResizerWindowMessenger == NULL) {
1191d9f6762dSMichael Pfeiffer 		// open window if it is not already opened
1192d9f6762dSMichael Pfeiffer 		BWindow* window = new ResizerWindow(this, width, height);
1193d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger = new BMessenger(window);
1194d9f6762dSMichael Pfeiffer 		window->Show();
11956163f333SKarsten Heimrich 	} else {
1196d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger->SendMessage(ResizerWindow::kActivateMsg);
1197d9f6762dSMichael Pfeiffer 	}
11986163f333SKarsten Heimrich }
1199d9f6762dSMichael Pfeiffer 
120056b0c7b9SKarsten Heimrich 
1201d9f6762dSMichael Pfeiffer void
1202*fd952aefSRyan Leavengood ShowImageWindow::_UpdateResizerWindow(int32 width, int32 height)
1203d9f6762dSMichael Pfeiffer {
12046163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1205d9f6762dSMichael Pfeiffer 		return;
1206d9f6762dSMichael Pfeiffer 
1207d9f6762dSMichael Pfeiffer 	BMessage updateMsg(ResizerWindow::kUpdateMsg);
12080acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("width", width);
12090acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("height", height);
1210d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(&updateMsg);
1211d9f6762dSMichael Pfeiffer }
1212d9f6762dSMichael Pfeiffer 
121356b0c7b9SKarsten Heimrich 
1214d9f6762dSMichael Pfeiffer void
1215*fd952aefSRyan Leavengood ShowImageWindow::_CloseResizerWindow()
1216d9f6762dSMichael Pfeiffer {
12176163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1218d9f6762dSMichael Pfeiffer 		return;
12196163f333SKarsten Heimrich 
1220d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(B_QUIT_REQUESTED);
12216163f333SKarsten Heimrich 	delete fResizerWindowMessenger;
1222d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger = NULL;
1223d9f6762dSMichael Pfeiffer }
1224efa8b4f3SAxel Dörfler 
122556b0c7b9SKarsten Heimrich 
1226780d8a62SMichael Pfeiffer bool
1227cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1228cdb89ebbSMatthew Wilber {
1229efa8b4f3SAxel Dörfler 	if (fSavePanel) {
1230efa8b4f3SAxel Dörfler 		// Don't allow this window to be closed if a save panel is open
1231efa8b4f3SAxel Dörfler 		return false;
1232cdb89ebbSMatthew Wilber 	}
1233cdb89ebbSMatthew Wilber 
1234*fd952aefSRyan Leavengood 	bool quit = _ClosePrompt();
1235efa8b4f3SAxel Dörfler 
1236efa8b4f3SAxel Dörfler 	if (quit) {
1237*fd952aefSRyan Leavengood 		_CloseResizerWindow();
1238d9f6762dSMichael Pfeiffer 
123907caaa8eSMatthew Wilber 		// tell the app to forget about this window
124007caaa8eSMatthew Wilber 		be_app->PostMessage(MSG_WINDOW_QUIT);
124107caaa8eSMatthew Wilber 	}
1242fc0a275bSMatthew Wilber 
1243efa8b4f3SAxel Dörfler 	return quit;
1244efa8b4f3SAxel Dörfler }
1245efa8b4f3SAxel Dörfler 
1246efa8b4f3SAxel Dörfler 
1247a9ab9d2cSDarkWyrm void
1248a9ab9d2cSDarkWyrm ShowImageWindow::ScreenChanged(BRect frame, color_space mode)
1249a9ab9d2cSDarkWyrm {
1250a9ab9d2cSDarkWyrm 	fImageView->SetDither(mode == B_CMAP8);
1251a9ab9d2cSDarkWyrm }
1252