xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision 6db01936fe4d1635ff2deb07ce5890a00613ee06)
1efa8b4f3SAxel Dörfler /*
24fd570d3SAxel Dörfler  * Copyright 2003-2010, Haiku, Inc. All Rights Reserved.
3d9f6762dSMichael Pfeiffer  * Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
4d9f6762dSMichael Pfeiffer  * Copyright 2006 Bernd Korz. All Rights Reserved
5efa8b4f3SAxel Dörfler  * Distributed under the terms of the MIT License.
6efa8b4f3SAxel Dörfler  *
7efa8b4f3SAxel Dörfler  * Authors:
8efa8b4f3SAxel Dörfler  *		Fernando Francisco de Oliveira
9efa8b4f3SAxel Dörfler  *		Michael Wilber
10efa8b4f3SAxel Dörfler  *		Michael Pfeiffer
11d9f6762dSMichael Pfeiffer  *		yellowTAB GmbH
12d9f6762dSMichael Pfeiffer  *		Bernd Korz
13efa8b4f3SAxel Dörfler  */
1413afa642SPhil Greenway 
154fd570d3SAxel Dörfler 
16efa8b4f3SAxel Dörfler #include "ShowImageWindow.h"
17efa8b4f3SAxel Dörfler 
18fd952aefSRyan Leavengood #include <new>
19fd952aefSRyan Leavengood #include <stdio.h>
206163f333SKarsten Heimrich 
21efa8b4f3SAxel Dörfler #include <Alert.h>
2213afa642SPhil Greenway #include <Application.h>
2313afa642SPhil Greenway #include <Bitmap.h>
24fc0a275bSMatthew Wilber #include <BitmapStream.h>
251ed4535fSStephan Aßmus #include <Catalog.h>
26efa8b4f3SAxel Dörfler #include <Clipboard.h>
2713afa642SPhil Greenway #include <Entry.h>
28fc0a275bSMatthew Wilber #include <File.h>
296163f333SKarsten Heimrich #include <FilePanel.h>
301ed4535fSStephan Aßmus #include <Locale.h>
3113afa642SPhil Greenway #include <Menu.h>
3213afa642SPhil Greenway #include <MenuBar.h>
3313afa642SPhil Greenway #include <MenuItem.h>
3413afa642SPhil Greenway #include <Path.h>
35efa8b4f3SAxel Dörfler #include <PrintJob.h>
36efa8b4f3SAxel Dörfler #include <Roster.h>
37efa8b4f3SAxel Dörfler #include <Screen.h>
3813afa642SPhil Greenway #include <ScrollView.h>
396163f333SKarsten Heimrich #include <String.h>
40efa8b4f3SAxel Dörfler #include <SupportDefs.h>
416163f333SKarsten Heimrich #include <TranslationDefs.h>
4213afa642SPhil Greenway #include <TranslationUtils.h>
4313afa642SPhil Greenway #include <TranslatorRoster.h>
441ed4535fSStephan Aßmus #include <stdlib.h> // for bs_printf()
4513afa642SPhil Greenway 
46fd952aefSRyan Leavengood #include "EntryMenuItem.h"
47fd952aefSRyan Leavengood #include "ResizerWindow.h"
48fd952aefSRyan Leavengood #include "ShowImageApp.h"
49fd952aefSRyan Leavengood #include "ShowImageConstants.h"
50fd952aefSRyan Leavengood #include "ShowImageStatusView.h"
51fd952aefSRyan Leavengood #include "ShowImageView.h"
5213afa642SPhil Greenway 
53a8fc7138SMichael Pfeiffer 
546163f333SKarsten Heimrich // #pragma mark -- ShowImageWindow::RecentDocumentsMenu
556163f333SKarsten Heimrich 
566163f333SKarsten Heimrich class ShowImageWindow::RecentDocumentsMenu : public BMenu {
576163f333SKarsten Heimrich public:
586163f333SKarsten Heimrich 			RecentDocumentsMenu(const char* title,
596163f333SKarsten Heimrich 				menu_layout layout = B_ITEMS_IN_COLUMN);
606163f333SKarsten Heimrich 	bool	AddDynamicItem(add_state addState);
616163f333SKarsten Heimrich 
626163f333SKarsten Heimrich private:
636163f333SKarsten Heimrich 	void	UpdateRecentDocumentsMenu();
646163f333SKarsten Heimrich };
656163f333SKarsten Heimrich 
666163f333SKarsten Heimrich 
676163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::RecentDocumentsMenu(const char* title,
686163f333SKarsten Heimrich 	menu_layout layout)
69fd952aefSRyan Leavengood 	:
70fd952aefSRyan Leavengood 	BMenu(title, layout)
71a8fc7138SMichael Pfeiffer {
72a8fc7138SMichael Pfeiffer }
73a8fc7138SMichael Pfeiffer 
74efa8b4f3SAxel Dörfler 
75a8fc7138SMichael Pfeiffer bool
766163f333SKarsten Heimrich ShowImageWindow::RecentDocumentsMenu::AddDynamicItem(add_state addState)
77a8fc7138SMichael Pfeiffer {
78a60adbf9SAxel Dörfler 	if (addState != B_INITIAL_ADD)
79efa8b4f3SAxel Dörfler 		return false;
80a8fc7138SMichael Pfeiffer 
816163f333SKarsten Heimrich 	while (CountItems() > 0)
826163f333SKarsten Heimrich 		delete RemoveItem(0L);
836163f333SKarsten Heimrich 
84a8fc7138SMichael Pfeiffer 	BMenuItem* item;
85a8fc7138SMichael Pfeiffer 	BMessage list, *msg;
86a8fc7138SMichael Pfeiffer 	entry_ref ref;
87a8fc7138SMichael Pfeiffer 	char name[B_FILE_NAME_LENGTH];
88a8fc7138SMichael Pfeiffer 
89efa8b4f3SAxel Dörfler 	be_roster->GetRecentDocuments(&list, 20, NULL, kApplicationSignature);
90a8fc7138SMichael Pfeiffer 	for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
91a8fc7138SMichael Pfeiffer 		BEntry entry(&ref);
92a8fc7138SMichael Pfeiffer 		if (entry.Exists() && entry.GetName(name) == B_OK) {
93a8fc7138SMichael Pfeiffer 			msg = new BMessage(B_REFS_RECEIVED);
94a8fc7138SMichael Pfeiffer 			msg->AddRef("refs", &ref);
95a8fc7138SMichael Pfeiffer 			item = new EntryMenuItem(&ref, name, msg, 0, 0);
96a8fc7138SMichael Pfeiffer 			AddItem(item);
97a8fc7138SMichael Pfeiffer 			item->SetTarget(be_app, NULL);
98a8fc7138SMichael Pfeiffer 		}
99a8fc7138SMichael Pfeiffer 	}
100a8fc7138SMichael Pfeiffer 
101a8fc7138SMichael Pfeiffer 	return false;
102a8fc7138SMichael Pfeiffer }
103a8fc7138SMichael Pfeiffer 
104a8fc7138SMichael Pfeiffer 
1056163f333SKarsten Heimrich //	#pragma mark -- ShowImageWindow
1066163f333SKarsten Heimrich 
1076163f333SKarsten Heimrich 
1086163f333SKarsten Heimrich // BMessage field names used in Save messages
1096163f333SKarsten Heimrich const char* kTypeField = "be:type";
1106163f333SKarsten Heimrich const char* kTranslatorField = "be:translator";
111a8fc7138SMichael Pfeiffer 
112efa8b4f3SAxel Dörfler 
113efa8b4f3SAxel Dörfler ShowImageWindow::ShowImageWindow(const entry_ref* ref,
114efa8b4f3SAxel Dörfler 	const BMessenger& trackerMessenger)
115fd952aefSRyan Leavengood 	:
116fd952aefSRyan Leavengood 	BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0),
117fd952aefSRyan Leavengood 	fSavePanel(NULL),
118fd952aefSRyan Leavengood 	fBar(NULL),
119fd952aefSRyan Leavengood 	fOpenMenu(NULL),
120fd952aefSRyan Leavengood 	fBrowseMenu(NULL),
121fd952aefSRyan Leavengood 	fGoToPageMenu(NULL),
122fd952aefSRyan Leavengood 	fSlideShowDelay(NULL),
123fd952aefSRyan Leavengood 	fImageView(NULL),
124fd952aefSRyan Leavengood 	fStatusView(NULL),
125fd952aefSRyan Leavengood 	fModified(false),
126fd952aefSRyan Leavengood 	fFullScreen(false),
127fd952aefSRyan Leavengood 	fShowCaption(true),
128fd952aefSRyan Leavengood 	fPrintSettings(NULL),
129fd952aefSRyan Leavengood 	fResizerWindowMessenger(NULL),
130fd952aefSRyan Leavengood 	fResizeItem(NULL),
131fd952aefSRyan Leavengood 	fHeight(0),
132fd952aefSRyan Leavengood 	fWidth(0)
13313afa642SPhil Greenway {
134fd952aefSRyan Leavengood 	_LoadSettings();
135fc0a275bSMatthew Wilber 
13613afa642SPhil Greenway 	// create menu bar
137e9dcd874SAxel Dörfler 	fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar");
138efa8b4f3SAxel Dörfler 	AddMenus(fBar);
139e9dcd874SAxel Dörfler 	AddChild(fBar);
14013afa642SPhil Greenway 
14113afa642SPhil Greenway 	BRect viewFrame = Bounds();
142e9dcd874SAxel Dörfler 	viewFrame.top = fBar->Bounds().Height() + 1;
14313afa642SPhil Greenway 	viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
14413afa642SPhil Greenway 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
14513afa642SPhil Greenway 
14613afa642SPhil Greenway 	// create the image view
147d3046f7dSMichael Pfeiffer 	fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
1487eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
14913afa642SPhil Greenway 	// wrap a scroll view around the view
150efa8b4f3SAxel Dörfler 	BScrollView* scrollView = new BScrollView("image_scroller", fImageView,
151cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
152efa8b4f3SAxel Dörfler 	AddChild(scrollView);
15313afa642SPhil Greenway 
15407caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
155cdb89ebbSMatthew Wilber 	BRect rect;
15613afa642SPhil Greenway 	rect = Bounds();
15713afa642SPhil Greenway 	rect.top = viewFrame.bottom + 1;
15807caaa8eSMatthew Wilber 	rect.left = viewFrame.left + kstatusWidth;
1590916ab53SMatthew Wilber 	rect.right = viewFrame.right + 1;
1600916ab53SMatthew Wilber 	rect.bottom += 1;
161efa8b4f3SAxel Dörfler 	BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll",
162efa8b4f3SAxel Dörfler 		fImageView, 0, 150, B_HORIZONTAL);
163efa8b4f3SAxel Dörfler 	AddChild(horizontalScrollBar);
16413afa642SPhil Greenway 
16513afa642SPhil Greenway 	rect.left = 0;
16607caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
1670cd4ecd8SStephan Aßmus 	rect.bottom -= 1;
168d3046f7dSMichael Pfeiffer 	fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
169cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
170d3046f7dSMichael Pfeiffer 	AddChild(fStatusView);
17113afa642SPhil Greenway 
17213afa642SPhil Greenway 	rect = Bounds();
1730916ab53SMatthew Wilber 	rect.top = viewFrame.top - 1;
17413afa642SPhil Greenway 	rect.left = viewFrame.right + 1;
1750916ab53SMatthew Wilber 	rect.bottom = viewFrame.bottom + 1;
1760916ab53SMatthew Wilber 	rect.right += 1;
177efa8b4f3SAxel Dörfler 	BScrollBar* verticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
178efa8b4f3SAxel Dörfler 		0, 150, B_VERTICAL);
179efa8b4f3SAxel Dörfler 	AddChild(verticalScrollBar);
18013afa642SPhil Greenway 
18103839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
18213afa642SPhil Greenway 
183134d6076SMichael Pfeiffer 	// finish creating the window
184efa8b4f3SAxel Dörfler 	fImageView->SetImage(ref);
185134d6076SMichael Pfeiffer 	fImageView->SetTrackerMessenger(trackerMessenger);
1867eca0987SMichael Pfeiffer 
1874eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
1884eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "LoadAlerts"
1891ed4535fSStephan Aßmus 
190d9f6762dSMichael Pfeiffer 	if (InitCheck() != B_OK) {
191e6a50d9cSMichael Pfeiffer 		BAlert* alert;
192905c8c8cSMatt Madia 		alert = new BAlert(
193905c8c8cSMatt Madia 			B_TRANSLATE("ShowImage"),
194905c8c8cSMatt Madia 			B_TRANSLATE("Could not load image! Either the file or an image "
195905c8c8cSMatt Madia 				"translator for it does not exist."),
196905c8c8cSMatt Madia 			B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
197e6a50d9cSMichael Pfeiffer 		alert->Go();
198efa8b4f3SAxel Dörfler 
1995e09d5dbSRyan Leavengood 		// quit if file could not be opened
2005e09d5dbSRyan Leavengood 		Quit();
201efa8b4f3SAxel Dörfler 		return;
202d10d5947SMichael Pfeiffer 	}
203402c09e5SMatthew Wilber 
2044eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
2054eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus"
2061ed4535fSStephan Aßmus 
207d9f6762dSMichael Pfeiffer 	// add View menu here so it can access ShowImageView methods
208905c8c8cSMatt Madia 	BMenu* menu = new BMenu(B_TRANSLATE("View"));
209fd952aefSRyan Leavengood 	_BuildViewMenu(menu, false);
210d9f6762dSMichael Pfeiffer 	fBar->AddItem(menu);
211d9f6762dSMichael Pfeiffer 	UpdateTitle();
212d9f6762dSMichael Pfeiffer 
213d9f6762dSMichael Pfeiffer 	SetPulseRate(100000);
214d9f6762dSMichael Pfeiffer 		// every 1/10 second; ShowImageView needs it for marching ants
215d9f6762dSMichael Pfeiffer 
216*6db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SELECTION_MODE,
217*6db01936SAxel Dörfler 		fImageView->IsSelectionModeEnabled());
218*6db01936SAxel Dörfler 
219d9f6762dSMichael Pfeiffer 	WindowRedimension(fImageView->GetBitmap());
2204fd570d3SAxel Dörfler 	fImageView->ResetZoom();
221d9f6762dSMichael Pfeiffer 	fImageView->MakeFocus(true); // to receive KeyDown messages
222d9f6762dSMichael Pfeiffer 	Show();
223d9f6762dSMichael Pfeiffer 
224402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
225402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
226402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
22713afa642SPhil Greenway }
22813afa642SPhil Greenway 
229efa8b4f3SAxel Dörfler 
23013afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
23113afa642SPhil Greenway {
2326163f333SKarsten Heimrich 	delete fResizerWindowMessenger;
23313afa642SPhil Greenway }
23413afa642SPhil Greenway 
235efa8b4f3SAxel Dörfler 
236cdb89ebbSMatthew Wilber status_t
237cdb89ebbSMatthew Wilber ShowImageWindow::InitCheck()
23813afa642SPhil Greenway {
239d3046f7dSMichael Pfeiffer 	if (!fImageView || fImageView->GetBitmap() == NULL)
24013afa642SPhil Greenway 		return B_ERROR;
241efa8b4f3SAxel Dörfler 
24213afa642SPhil Greenway 	return B_OK;
24313afa642SPhil Greenway }
244cdb89ebbSMatthew Wilber 
245efa8b4f3SAxel Dörfler 
246cdb89ebbSMatthew Wilber void
247cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
24813afa642SPhil Greenway {
249e6a50d9cSMichael Pfeiffer 	BString path;
250d3046f7dSMichael Pfeiffer 	fImageView->GetPath(&path);
251e6a50d9cSMichael Pfeiffer 	SetTitle(path.String());
25213afa642SPhil Greenway }
25313afa642SPhil Greenway 
25456b0c7b9SKarsten Heimrich 
255d9f6762dSMichael Pfeiffer void
256d9f6762dSMichael Pfeiffer ShowImageWindow::BuildContextMenu(BMenu* menu)
257d9f6762dSMichael Pfeiffer {
258fd952aefSRyan Leavengood 	_BuildViewMenu(menu, true);
259d9f6762dSMichael Pfeiffer }
260efa8b4f3SAxel Dörfler 
26156b0c7b9SKarsten Heimrich 
2624eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
2634eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Menus"
2641ed4535fSStephan Aßmus 
2656046b973SAxel Dörfler 
266cdb89ebbSMatthew Wilber void
267fd952aefSRyan Leavengood ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
268da87390fSMichael Pfeiffer {
269905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Slide show"), MSG_SLIDE_SHOW, 0, 0, this);
270fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
271905c8c8cSMatt Madia 	BMenu* delayMenu = new BMenu(B_TRANSLATE("Slide delay"));
272efa8b4f3SAxel Dörfler 	if (fSlideShowDelay == NULL)
273efa8b4f3SAxel Dörfler 		fSlideShowDelay = delayMenu;
274efa8b4f3SAxel Dörfler 
275efa8b4f3SAxel Dörfler 	delayMenu->SetRadioMode(true);
27656b0c7b9SKarsten Heimrich 	// Note: ShowImage loads images in window thread so it becomes unresponsive
27756b0c7b9SKarsten Heimrich 	//		 if slide show delay is too short! (Especially if loading the image
27856b0c7b9SKarsten Heimrich 	//		 takes as long as or longer than the slide show delay). Should load
27956b0c7b9SKarsten Heimrich 	//		 in background thread!
280905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("3 seconds"), 3);
281905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("4 seconds"), 4);
282905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("5 seconds"), 5);
283905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("6 seconds"), 6);
284905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("7 seconds"), 7);
285905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("8 seconds"), 8);
286905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("9 seconds"), 9);
287905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("10 seconds"), 10);
288905c8c8cSMatt Madia 	_AddDelayItem(delayMenu, B_TRANSLATE("20 seconds"), 20);
289efa8b4f3SAxel Dörfler 	menu->AddItem(delayMenu);
29030060f17SMatthew Wilber 
291efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
292efa8b4f3SAxel Dörfler 
293905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Original size"),
294905c8c8cSMatt Madia 		MSG_ORIGINAL_SIZE, '1', 0, this);
295905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this);
296905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this);
297efa8b4f3SAxel Dörfler 
298efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
299efa8b4f3SAxel Dörfler 
3004fd570d3SAxel Dörfler 	if (!popupMenu || fFullScreen) {
301905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
302905c8c8cSMatt Madia 			MSG_SCALE_BILINEAR, 0, 0, this);
303efa8b4f3SAxel Dörfler 
304efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
305efa8b4f3SAxel Dörfler 
306905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Shrink to window"),
307905c8c8cSMatt Madia 			MSG_SHRINK_TO_WINDOW, 0, 0, this);
3084fd570d3SAxel Dörfler 		_AddItemMenu(menu, B_TRANSLATE("Stretch to window"),
3094fd570d3SAxel Dörfler 			MSG_STRETCH_TO_WINDOW, 0, 0, this);
310efa8b4f3SAxel Dörfler 
311efa8b4f3SAxel Dörfler 		menu->AddSeparatorItem();
31232c22143SAxel Dörfler 	}
313efa8b4f3SAxel Dörfler 
314905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Full screen"),
315905c8c8cSMatt Madia 		MSG_FULL_SCREEN, B_ENTER, 0, this);
316fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
317efa8b4f3SAxel Dörfler 
318905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Show caption in full screen mode"),
319905c8c8cSMatt Madia 		MSG_SHOW_CAPTION, 0, 0, this);
320fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
321efa8b4f3SAxel Dörfler 
322fd952aefSRyan Leavengood 	_MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
323*6db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, fImageView->ShrinksToBounds());
324*6db01936SAxel Dörfler 	_MarkMenuItem(menu, MSG_STRETCH_TO_WINDOW, fImageView->StretchesToBounds());
325a60adbf9SAxel Dörfler 
326d9f6762dSMichael Pfeiffer 	if (popupMenu) {
327a60adbf9SAxel Dörfler 		menu->AddSeparatorItem();
328905c8c8cSMatt Madia 		_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
3291ed4535fSStephan Aßmus 			MSG_DESKTOP_BACKGROUND, 0, 0, this);
330d9f6762dSMichael Pfeiffer 	}
331da87390fSMichael Pfeiffer }
332da87390fSMichael Pfeiffer 
333efa8b4f3SAxel Dörfler 
334da87390fSMichael Pfeiffer void
335efa8b4f3SAxel Dörfler ShowImageWindow::AddMenus(BMenuBar* bar)
33613afa642SPhil Greenway {
337905c8c8cSMatt Madia 	BMenu* menu = new BMenu(B_TRANSLATE("File"));
338905c8c8cSMatt Madia 	fOpenMenu = new RecentDocumentsMenu(B_TRANSLATE("Open"));
339efa8b4f3SAxel Dörfler 	menu->AddItem(fOpenMenu);
340d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTrigger('O');
341d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
342d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTarget(be_app);
343d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetShortcut('O', 0);
344efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
345*6db01936SAxel Dörfler 	BMenu* menuSaveAs = new BMenu(B_TRANSLATE("Save as" B_UTF8_ELLIPSIS),
3461ed4535fSStephan Aßmus 		B_ITEMS_IN_COLUMN);
347*6db01936SAxel Dörfler 	BTranslationUtils::AddTranslationItems(menuSaveAs, B_TRANSLATOR_BITMAP);
348fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
349fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
350*6db01936SAxel Dörfler 	menu->AddItem(menuSaveAs);
351905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Close"), B_QUIT_REQUESTED, 'W', 0, this);
352efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
353905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS),
3541ed4535fSStephan Aßmus 		MSG_PAGE_SETUP, 0, 0, this);
355905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Print" B_UTF8_ELLIPSIS),
3561ed4535fSStephan Aßmus 		MSG_PREPARE_PRINT, 'P', 0, this);
357efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
358905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("About ShowImage" B_UTF8_ELLIPSIS),
3591ed4535fSStephan Aßmus 		B_ABOUT_REQUESTED, 0, 0, be_app);
360efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
361905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q', 0, be_app);
362efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
36313afa642SPhil Greenway 
364905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Edit"));
365905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Undo"), B_UNDO, 'Z', 0, this, false);
366efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
367905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Copy"), B_COPY, 'C', 0, this, false);
368efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
369*6db01936SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Selection Mode"), MSG_SELECTION_MODE, 0, 0,
370*6db01936SAxel Dörfler 		this);
37132c22143SAxel Dörfler 	_AddItemMenu(menu, B_TRANSLATE("Clear selection"),
37232c22143SAxel Dörfler 		MSG_CLEAR_SELECT, 0, 0, this, false);
373905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Select all"),
374905c8c8cSMatt Madia 		MSG_SELECT_ALL, 'A', 0, this);
375efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
37613afa642SPhil Greenway 
377905c8c8cSMatt Madia 	menu = fBrowseMenu = new BMenu(B_TRANSLATE("Browse"));
378905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("First page"),
3791ed4535fSStephan Aßmus 		MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, this);
380905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Last page"),
3811ed4535fSStephan Aßmus 		MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, this);
382905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous page"),
383905c8c8cSMatt Madia 		MSG_PAGE_PREV, B_LEFT_ARROW, 0, this);
384905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next page"),
385905c8c8cSMatt Madia 		MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, this);
386905c8c8cSMatt Madia 	fGoToPageMenu = new BMenu(B_TRANSLATE("Go to page"));
3875e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
388efa8b4f3SAxel Dörfler 	menu->AddItem(fGoToPageMenu);
389efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
390905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Previous file"),
391905c8c8cSMatt Madia 		MSG_FILE_PREV, B_UP_ARROW, 0, this);
392905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Next file"),
393905c8c8cSMatt Madia 		MSG_FILE_NEXT, B_DOWN_ARROW, 0, this);
394efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
39503839579SMatthew Wilber 
396905c8c8cSMatt Madia 	menu = new BMenu(B_TRANSLATE("Image"));
397905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate clockwise"),
398905c8c8cSMatt Madia 		MSG_ROTATE_90, 'R', 0, this);
399905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Rotate counterclockwise"),
4001ed4535fSStephan Aßmus 		MSG_ROTATE_270, 'R', B_SHIFT_KEY, this);
401efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
402905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip left to right"),
4031ed4535fSStephan Aßmus 		MSG_FLIP_LEFT_TO_RIGHT, 0, 0, this);
404905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Flip top to bottom"),
4051ed4535fSStephan Aßmus 		MSG_FLIP_TOP_TO_BOTTOM, 0, 0, this);
406efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
407905c8c8cSMatt Madia 	fResizeItem = _AddItemMenu(menu, B_TRANSLATE("Resize" B_UTF8_ELLIPSIS),
4086163f333SKarsten Heimrich 		MSG_OPEN_RESIZER_WINDOW, 0, 0, this);
409efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
410d9f6762dSMichael Pfeiffer 	menu->AddSeparatorItem();
411905c8c8cSMatt Madia 	_AddItemMenu(menu, B_TRANSLATE("Use as background" B_UTF8_ELLIPSIS),
4121ed4535fSStephan Aßmus 		MSG_DESKTOP_BACKGROUND, 0, 0, this);
41313afa642SPhil Greenway }
41413afa642SPhil Greenway 
415efa8b4f3SAxel Dörfler 
416cdb89ebbSMatthew Wilber BMenuItem*
417fd952aefSRyan Leavengood ShowImageWindow::_AddItemMenu(BMenu* menu, const char* label, uint32 what,
4184fd570d3SAxel Dörfler 	char shortcut, uint32 modifier, const BHandler* target, bool enabled)
419cdb89ebbSMatthew Wilber {
4204fd570d3SAxel Dörfler 	BMenuItem* item = new BMenuItem(label, new BMessage(what), shortcut,
4214fd570d3SAxel Dörfler 		modifier);
422efa8b4f3SAxel Dörfler 	menu->AddItem(item);
423efa8b4f3SAxel Dörfler 
4246163f333SKarsten Heimrich 	item->SetTarget(target);
4256163f333SKarsten Heimrich 	item->SetEnabled(enabled);
4266163f333SKarsten Heimrich 
427efa8b4f3SAxel Dörfler 	return item;
42813afa642SPhil Greenway }
42913afa642SPhil Greenway 
430efa8b4f3SAxel Dörfler 
431ad13f387SMichael Pfeiffer BMenuItem*
432fd952aefSRyan Leavengood ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, float value)
433ad13f387SMichael Pfeiffer {
434efa8b4f3SAxel Dörfler 	BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
435efa8b4f3SAxel Dörfler 	message->AddFloat("value", value);
436ad13f387SMichael Pfeiffer 
4376163f333SKarsten Heimrich 	BMenuItem* item = new BMenuItem(label, message, 0);
438efa8b4f3SAxel Dörfler 	item->SetTarget(this);
439ad13f387SMichael Pfeiffer 
440d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
441efa8b4f3SAxel Dörfler 	if (marked)
442efa8b4f3SAxel Dörfler 		item->SetMarked(true);
443ad13f387SMichael Pfeiffer 
444efa8b4f3SAxel Dörfler 	menu->AddItem(item);
445efa8b4f3SAxel Dörfler 	return item;
446ad13f387SMichael Pfeiffer }
447ad13f387SMichael Pfeiffer 
448efa8b4f3SAxel Dörfler 
449cdb89ebbSMatthew Wilber void
4501076d97bSAxel Dörfler ShowImageWindow::WindowRedimension(BBitmap* bitmap)
45113afa642SPhil Greenway {
452d10d5947SMichael Pfeiffer 	BScreen screen;
45371a34702SAxel Dörfler 	if (!screen.IsValid())
454efa8b4f3SAxel Dörfler 		return;
455efa8b4f3SAxel Dörfler 
4561076d97bSAxel Dörfler 	// TODO: use View::GetPreferredSize() instead?
4571076d97bSAxel Dörfler 	BRect r(bitmap->Bounds());
4581076d97bSAxel Dörfler 	float width = r.Width() + B_V_SCROLL_BAR_WIDTH;
4591076d97bSAxel Dörfler 	float height = r.Height() + 1 + fBar->Frame().Height()
4601076d97bSAxel Dörfler 		+ B_H_SCROLL_BAR_HEIGHT;
461cdb89ebbSMatthew Wilber 
4626163f333SKarsten Heimrich 	BRect frame = screen.Frame();
4636163f333SKarsten Heimrich 	const float windowBorder = 5;
464d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
4656163f333SKarsten Heimrich 	float maxWidth = frame.Width() + 1 - windowBorder - Frame().left;
4666163f333SKarsten Heimrich 	float maxHeight = frame.Height() + 1 - windowBorder - Frame().top;
467cdb89ebbSMatthew Wilber 
468a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
469a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
470efa8b4f3SAxel Dörfler 
471fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
472a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
473efa8b4f3SAxel Dörfler 	if (maxWidth > maxW)
474efa8b4f3SAxel Dörfler 		maxWidth = maxW;
475efa8b4f3SAxel Dörfler 	if (maxHeight > maxH)
476efa8b4f3SAxel Dörfler 		maxHeight = maxH;
477efa8b4f3SAxel Dörfler 	if (width < minW)
478efa8b4f3SAxel Dörfler 		width = minW;
479efa8b4f3SAxel Dörfler 	if (height < minH)
480efa8b4f3SAxel Dörfler 		height = minH;
481a8fc7138SMichael Pfeiffer 
482efa8b4f3SAxel Dörfler 	if (width > maxWidth)
483efa8b4f3SAxel Dörfler 		width = maxWidth;
484efa8b4f3SAxel Dörfler 	if (height > maxHeight)
485efa8b4f3SAxel Dörfler 		height = maxHeight;
486d10d5947SMichael Pfeiffer 
487d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
48813afa642SPhil Greenway }
48913afa642SPhil Greenway 
490efa8b4f3SAxel Dörfler 
491cdb89ebbSMatthew Wilber void
492cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
49313afa642SPhil Greenway {
4946163f333SKarsten Heimrich 	BWindow::FrameResized(width, height);
49513afa642SPhil Greenway }
49613afa642SPhil Greenway 
497efa8b4f3SAxel Dörfler 
4987eca0987SMichael Pfeiffer bool
499fd952aefSRyan Leavengood ShowImageWindow::_ToggleMenuItem(uint32 what)
5007eca0987SMichael Pfeiffer {
5017eca0987SMichael Pfeiffer 	bool marked = false;
5026163f333SKarsten Heimrich 	BMenuItem* item = fBar->FindItem(what);
5037eca0987SMichael Pfeiffer 	if (item != NULL) {
5047eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
5057eca0987SMichael Pfeiffer 		item->SetMarked(marked);
5067eca0987SMichael Pfeiffer 	}
5077eca0987SMichael Pfeiffer 	return marked;
5087eca0987SMichael Pfeiffer }
5097eca0987SMichael Pfeiffer 
510efa8b4f3SAxel Dörfler 
511cdb89ebbSMatthew Wilber void
512fd952aefSRyan Leavengood ShowImageWindow::_EnableMenuItem(BMenu* menu, uint32 what, bool enable)
513e6a50d9cSMichael Pfeiffer {
5146163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
5156163f333SKarsten Heimrich 	if (item && item->IsEnabled() != enable)
516e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
517e6a50d9cSMichael Pfeiffer }
518e6a50d9cSMichael Pfeiffer 
519efa8b4f3SAxel Dörfler 
520e6a50d9cSMichael Pfeiffer void
521fd952aefSRyan Leavengood ShowImageWindow::_MarkMenuItem(BMenu* menu, uint32 what, bool marked)
522e6a50d9cSMichael Pfeiffer {
5236163f333SKarsten Heimrich 	BMenuItem* item = menu->FindItem(what);
5246163f333SKarsten Heimrich 	if (item && item->IsMarked() != marked)
525e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
526e6a50d9cSMichael Pfeiffer }
527e6a50d9cSMichael Pfeiffer 
528efa8b4f3SAxel Dörfler 
529da87390fSMichael Pfeiffer void
530fd952aefSRyan Leavengood ShowImageWindow::_MarkSlideShowDelay(float value)
531da87390fSMichael Pfeiffer {
532d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
533da87390fSMichael Pfeiffer 	float v;
534da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
535d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
536da87390fSMichael Pfeiffer 		if (item) {
537da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
5386163f333SKarsten Heimrich 				if (!item->IsMarked())
539da87390fSMichael Pfeiffer 					item->SetMarked(true);
540da87390fSMichael Pfeiffer 				return;
541da87390fSMichael Pfeiffer 			}
542da87390fSMichael Pfeiffer 		}
543da87390fSMichael Pfeiffer 	}
544da87390fSMichael Pfeiffer }
545e6a50d9cSMichael Pfeiffer 
54619c76de4SMichael Pfeiffer 
54719c76de4SMichael Pfeiffer void
548fd952aefSRyan Leavengood ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what)
54919c76de4SMichael Pfeiffer {
550fd952aefSRyan Leavengood 	bool enabled = _ToggleMenuItem(what);
5516163f333SKarsten Heimrich 	if (shrink)
552d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
5536163f333SKarsten Heimrich 	else
5544fd570d3SAxel Dörfler 		fImageView->SetStretchToBounds(enabled);
55519c76de4SMichael Pfeiffer }
55619c76de4SMichael Pfeiffer 
557efa8b4f3SAxel Dörfler 
558e6a50d9cSMichael Pfeiffer void
559efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage* message)
56013afa642SPhil Greenway {
561efa8b4f3SAxel Dörfler 	switch (message->what) {
562ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
563ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
564ee7b4f39SMatthew Wilber 			fModified = true;
565ee7b4f39SMatthew Wilber 			break;
566ee7b4f39SMatthew Wilber 
567fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
568fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
569d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
570cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
571fd952aefSRyan Leavengood 				_SaveAs(message);
57213afa642SPhil Greenway 			break;
573fc0a275bSMatthew Wilber 
574fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
575fc0a275bSMatthew Wilber 			// User specified where to save the output image
576fd952aefSRyan Leavengood 			_SaveToFile(message);
57707caaa8eSMatthew Wilber 			break;
57807caaa8eSMatthew Wilber 
579cdb89ebbSMatthew Wilber 		case B_CANCEL:
580d3046f7dSMichael Pfeiffer 			delete fSavePanel;
581d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
582cdb89ebbSMatthew Wilber 			break;
583cdb89ebbSMatthew Wilber 
584*6db01936SAxel Dörfler 		case MSG_UPDATE_STATUS:
585*6db01936SAxel Dörfler 		{
5866163f333SKarsten Heimrich 			int32 pages = fImageView->PageCount();
5876163f333SKarsten Heimrich 			int32 curPage = fImageView->CurrentPage();
5886c305411SMatthew Wilber 
58936c17651SRyan Leavengood 			bool enable = (pages > 1) ? true : false;
59036c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_FIRST, enable);
59136c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_LAST, enable);
59236c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_NEXT, enable);
59336c17651SRyan Leavengood 			_EnableMenuItem(fBar, MSG_PAGE_PREV, enable);
59436c17651SRyan Leavengood 			fGoToPageMenu->SetEnabled(enable);
5951d592070SMatthew Wilber 
596fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_FILE_NEXT, fImageView->HasNextFile());
597fd952aefSRyan Leavengood 			_EnableMenuItem(fBar, MSG_FILE_PREV, fImageView->HasPrevFile());
598134d6076SMichael Pfeiffer 
599d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
6006c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
6016c305411SMatthew Wilber 				// pages is different
6026c305411SMatthew Wilber 
603d3046f7dSMichael Pfeiffer 				while (fGoToPageMenu->CountItems() > 0)
6046c305411SMatthew Wilber 					// Remove all page numbers
605d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
6066c305411SMatthew Wilber 
607780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
6086c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
6096163f333SKarsten Heimrich 					BMessage* pgomsg = new BMessage(MSG_GOTO_PAGE);
6106c305411SMatthew Wilber 					pgomsg->AddInt32("page", i);
6116163f333SKarsten Heimrich 
6126163f333SKarsten Heimrich 					char shortcut = 0;
613780d8a62SMichael Pfeiffer 					if (i < 10) {
614780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
615780d8a62SMichael Pfeiffer 					} else if (i == 10) {
616780d8a62SMichael Pfeiffer 						shortcut = '0';
617780d8a62SMichael Pfeiffer 					}
6186163f333SKarsten Heimrich 
6196163f333SKarsten Heimrich 					BString strCaption;
6206163f333SKarsten Heimrich 					strCaption << i;
6216163f333SKarsten Heimrich 
6226163f333SKarsten Heimrich 					BMenuItem* item = new BMenuItem(strCaption.String(), pgomsg,
6236163f333SKarsten Heimrich 						shortcut);
6246c305411SMatthew Wilber 					if (curPage == i)
625efa8b4f3SAxel Dörfler 						item->SetMarked(true);
626efa8b4f3SAxel Dörfler 					fGoToPageMenu->AddItem(item);
6276c305411SMatthew Wilber 				}
6286c305411SMatthew Wilber 			} else {
6296c305411SMatthew Wilber 				// Make sure the correct page is marked
6306c305411SMatthew Wilber 				BMenuItem *pcurItem;
631d3046f7dSMichael Pfeiffer 				pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
6326c305411SMatthew Wilber 				if (!pcurItem->IsMarked()) {
6336c305411SMatthew Wilber 					pcurItem->SetMarked(true);
6346c305411SMatthew Wilber 				}
6356c305411SMatthew Wilber 			}
6366c305411SMatthew Wilber 
6370cd4ecd8SStephan Aßmus 			BString status;
638d9f6762dSMichael Pfeiffer 			bool messageProvidesSize = false;
6398f5fd23fSRyan Leavengood 			if (message->FindInt32("width", &fWidth) >= B_OK
6408f5fd23fSRyan Leavengood 				&& message->FindInt32("height", &fHeight) >= B_OK) {
6418f5fd23fSRyan Leavengood 				status << fWidth << "x" << fHeight;
642d9f6762dSMichael Pfeiffer 				messageProvidesSize = true;
6430cd4ecd8SStephan Aßmus 			}
6440cd4ecd8SStephan Aßmus 
64503839579SMatthew Wilber 			BString str;
6460acb8cc4SMichael Pfeiffer 			if (message->FindString("status", &str) == B_OK && str.Length() > 0) {
6470acb8cc4SMichael Pfeiffer 				if (status.Length() > 0)
6480acb8cc4SMichael Pfeiffer 					status << ", ";
6490cd4ecd8SStephan Aßmus 				status << str;
6505eb50e46SMichael Pfeiffer 			}
6510cd4ecd8SStephan Aßmus 
652d9f6762dSMichael Pfeiffer 			if (messageProvidesSize) {
653fd952aefSRyan Leavengood 				_UpdateResizerWindow(fWidth, fHeight);
654*6db01936SAxel Dörfler 				if (!fImageView->StretchesToBounds()
655*6db01936SAxel Dörfler 					&& !fImageView->ShrinksToBounds()
656f75975a9SPhilippe Saint-Pierre 					&& !fFullScreen)
65729c4d5a9SPhilippe Saint-Pierre 					WindowRedimension(fImageView->GetBitmap());
658d9f6762dSMichael Pfeiffer 			}
659d9f6762dSMichael Pfeiffer 
6600cd4ecd8SStephan Aßmus 			fStatusView->SetText(status);
6617eca0987SMichael Pfeiffer 
6627eca0987SMichael Pfeiffer 			UpdateTitle();
663*6db01936SAxel Dörfler 			break;
664*6db01936SAxel Dörfler 		}
66503839579SMatthew Wilber 
666*6db01936SAxel Dörfler 		case MSG_UPDATE_STATUS_TEXT:
667*6db01936SAxel Dörfler 		{
6688f5fd23fSRyan Leavengood 			BString status;
6698f5fd23fSRyan Leavengood 			status << fWidth << "x" << fHeight;
6708f5fd23fSRyan Leavengood 			BString str;
6718f5fd23fSRyan Leavengood 			if (message->FindString("status", &str) == B_OK && str.Length() > 0) {
6728f5fd23fSRyan Leavengood 				status << ", " << str;
6738f5fd23fSRyan Leavengood 				fStatusView->SetText(status);
6748f5fd23fSRyan Leavengood 			}
675*6db01936SAxel Dörfler 			break;
676*6db01936SAxel Dörfler 		}
6778f5fd23fSRyan Leavengood 
678*6db01936SAxel Dörfler 		case MSG_SELECTION:
679*6db01936SAxel Dörfler 		{
6808ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
6818ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
6828ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
683*6db01936SAxel Dörfler 			bool enable;
684*6db01936SAxel Dörfler 			if (message->FindBool("has_selection", &enable) == B_OK) {
685*6db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_COPY, enable);
686*6db01936SAxel Dörfler 				_EnableMenuItem(fBar, MSG_CLEAR_SELECT, enable);
6878ad30bcfSMatthew Wilber 			}
688*6db01936SAxel Dörfler 			break;
689*6db01936SAxel Dörfler 		}
6908ad30bcfSMatthew Wilber 
691*6db01936SAxel Dörfler 		case MSG_UNDO_STATE:
692*6db01936SAxel Dörfler 		{
693*6db01936SAxel Dörfler 			bool enable;
694*6db01936SAxel Dörfler 			if (message->FindBool("can_undo", &enable) == B_OK)
695*6db01936SAxel Dörfler 				_EnableMenuItem(fBar, B_UNDO, enable);
696*6db01936SAxel Dörfler 			break;
697*6db01936SAxel Dörfler 		}
698402c09e5SMatthew Wilber 
69913afa642SPhil Greenway 		case B_UNDO:
7007598450eSMatthew Wilber 			fImageView->Undo();
70113afa642SPhil Greenway 			break;
7026163f333SKarsten Heimrich 
70313afa642SPhil Greenway 		case B_COPY:
704d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
70513afa642SPhil Greenway 			break;
7066163f333SKarsten Heimrich 
707*6db01936SAxel Dörfler 		case MSG_SELECTION_MODE:
708*6db01936SAxel Dörfler 			fImageView->SetSelectionMode(_ToggleMenuItem(MSG_SELECTION_MODE));
709*6db01936SAxel Dörfler 			break;
710*6db01936SAxel Dörfler 
71113afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
712d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
71313afa642SPhil Greenway 			break;
7146163f333SKarsten Heimrich 
71513afa642SPhil Greenway 		case MSG_SELECT_ALL:
716d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
71713afa642SPhil Greenway 			break;
71813afa642SPhil Greenway 
71903839579SMatthew Wilber 		case MSG_PAGE_FIRST:
720fd952aefSRyan Leavengood 			if (_ClosePrompt())
721d3046f7dSMichael Pfeiffer 				fImageView->FirstPage();
72203839579SMatthew Wilber 			break;
72303839579SMatthew Wilber 
72403839579SMatthew Wilber 		case MSG_PAGE_LAST:
725fd952aefSRyan Leavengood 			if (_ClosePrompt())
726d3046f7dSMichael Pfeiffer 				fImageView->LastPage();
72703839579SMatthew Wilber 			break;
72803839579SMatthew Wilber 
72903839579SMatthew Wilber 		case MSG_PAGE_NEXT:
730fd952aefSRyan Leavengood 			if (_ClosePrompt())
731d3046f7dSMichael Pfeiffer 				fImageView->NextPage();
73203839579SMatthew Wilber 			break;
73303839579SMatthew Wilber 
73403839579SMatthew Wilber 		case MSG_PAGE_PREV:
735fd952aefSRyan Leavengood 			if (_ClosePrompt())
736d3046f7dSMichael Pfeiffer 				fImageView->PrevPage();
73703839579SMatthew Wilber 			break;
73803839579SMatthew Wilber 
7396163f333SKarsten Heimrich 		case MSG_GOTO_PAGE: {
740fd952aefSRyan Leavengood 			if (!_ClosePrompt())
741ee7b4f39SMatthew Wilber 				break;
742ee7b4f39SMatthew Wilber 
7436163f333SKarsten Heimrich 			int32 newPage;
7446163f333SKarsten Heimrich 			if (message->FindInt32("page", &newPage) != B_OK)
7456163f333SKarsten Heimrich 				break;
7466163f333SKarsten Heimrich 
7476163f333SKarsten Heimrich 			int32 curPage = fImageView->CurrentPage();
7486163f333SKarsten Heimrich 			int32 pages = fImageView->PageCount();
7496c305411SMatthew Wilber 
7506c305411SMatthew Wilber 			if (newPage > 0 && newPage <= pages) {
7516163f333SKarsten Heimrich 				BMenuItem* pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
7526163f333SKarsten Heimrich 				BMenuItem* pnewItem = fGoToPageMenu->ItemAt(newPage - 1);
7536163f333SKarsten Heimrich 				if (pcurItem && pnewItem) {
7546c305411SMatthew Wilber 					pcurItem->SetMarked(false);
7556c305411SMatthew Wilber 					pnewItem->SetMarked(true);
756d3046f7dSMichael Pfeiffer 					fImageView->GoToPage(newPage);
7576c305411SMatthew Wilber 				}
7586c305411SMatthew Wilber 			}
7596163f333SKarsten Heimrich 		}	break;
7606c305411SMatthew Wilber 
76119c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
762fd952aefSRyan Leavengood 			_ResizeToWindow(true, message->what);
76319c76de4SMichael Pfeiffer 			break;
7646163f333SKarsten Heimrich 
7654fd570d3SAxel Dörfler 		case MSG_STRETCH_TO_WINDOW:
766fd952aefSRyan Leavengood 			_ResizeToWindow(false, message->what);
7677eca0987SMichael Pfeiffer 			break;
7687eca0987SMichael Pfeiffer 
7697eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
770fd952aefSRyan Leavengood 			if (_ClosePrompt())
771d3046f7dSMichael Pfeiffer 				fImageView->PrevFile();
7727eca0987SMichael Pfeiffer 			break;
7737eca0987SMichael Pfeiffer 
7747eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
775fd952aefSRyan Leavengood 			if (_ClosePrompt())
776d3046f7dSMichael Pfeiffer 				fImageView->NextFile();
77713afa642SPhil Greenway 			break;
77813afa642SPhil Greenway 
779bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
780d3046f7dSMichael Pfeiffer 			fImageView->Rotate(90);
781ad13f387SMichael Pfeiffer 			break;
7826163f333SKarsten Heimrich 
783bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
784d3046f7dSMichael Pfeiffer 			fImageView->Rotate(270);
785ad13f387SMichael Pfeiffer 			break;
7866163f333SKarsten Heimrich 
78769eee339SRyan Leavengood 		case MSG_FLIP_LEFT_TO_RIGHT:
78861ddc257SRyan Leavengood 			fImageView->Flip(true);
789ad13f387SMichael Pfeiffer 			break;
7906163f333SKarsten Heimrich 
79169eee339SRyan Leavengood 		case MSG_FLIP_TOP_TO_BOTTOM:
79261ddc257SRyan Leavengood 			fImageView->Flip(false);
793ad13f387SMichael Pfeiffer 			break;
7946163f333SKarsten Heimrich 
7951076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW:
7961076d97bSAxel Dörfler 		{
7976163f333SKarsten Heimrich 			BMenuItem* item = fBar->FindItem(message->what);
798ee7b4f39SMatthew Wilber 			if (!item)
799ee7b4f39SMatthew Wilber 				break;
800ee7b4f39SMatthew Wilber 			if (item->IsMarked()) {
801ee7b4f39SMatthew Wilber 				item->SetMarked(false);
802ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(true);
803d3046f7dSMichael Pfeiffer 				fImageView->StopSlideShow();
804fd952aefSRyan Leavengood 			} else if (_ClosePrompt()) {
805ee7b4f39SMatthew Wilber 				item->SetMarked(true);
806ebaed939SRyan Leavengood 				fResizeItem->SetEnabled(false);
807ee7b4f39SMatthew Wilber 				fImageView->StartSlideShow();
808ad13f387SMichael Pfeiffer 			}
8091076d97bSAxel Dörfler 			break;
8101076d97bSAxel Dörfler 		}
811ee7b4f39SMatthew Wilber 
8121076d97bSAxel Dörfler 		case MSG_SLIDE_SHOW_DELAY:
8131076d97bSAxel Dörfler 		{
814ad13f387SMichael Pfeiffer 			float value;
815efa8b4f3SAxel Dörfler 			if (message->FindFloat("value", &value) == B_OK) {
816d3046f7dSMichael Pfeiffer 				fImageView->SetSlideShowDelay(value);
817da87390fSMichael Pfeiffer 				// in case message is sent from popup menu
818fd952aefSRyan Leavengood 				_MarkSlideShowDelay(value);
819ad13f387SMichael Pfeiffer 			}
8201076d97bSAxel Dörfler 			break;
8211076d97bSAxel Dörfler 		}
822ad13f387SMichael Pfeiffer 
823ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
824fd952aefSRyan Leavengood 			_ToggleFullScreen();
825ad13f387SMichael Pfeiffer 			break;
8266163f333SKarsten Heimrich 
827fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
828fc5ca95dSStephan Aßmus 			if (fFullScreen)
829fd952aefSRyan Leavengood 				_ToggleFullScreen();
830fc5ca95dSStephan Aßmus 			break;
8316163f333SKarsten Heimrich 
8326163f333SKarsten Heimrich 		case MSG_SHOW_CAPTION: {
833fd952aefSRyan Leavengood 			fShowCaption = _ToggleMenuItem(message->what);
834efa8b4f3SAxel Dörfler 			ShowImageSettings* settings = my_app->Settings();
835efa8b4f3SAxel Dörfler 
836d3046f7dSMichael Pfeiffer 			if (settings->Lock()) {
837d3046f7dSMichael Pfeiffer 				settings->SetBool("ShowCaption", fShowCaption);
838d3046f7dSMichael Pfeiffer 				settings->Unlock();
839d3046f7dSMichael Pfeiffer 			}
840efa8b4f3SAxel Dörfler 			if (fFullScreen)
841d3046f7dSMichael Pfeiffer 				fImageView->SetShowCaption(fShowCaption);
8426163f333SKarsten Heimrich 		}	break;
843ad13f387SMichael Pfeiffer 
844780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
845fd952aefSRyan Leavengood 			_PageSetup();
846780d8a62SMichael Pfeiffer 			break;
8476163f333SKarsten Heimrich 
848780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
849fd952aefSRyan Leavengood 			_PrepareForPrint();
850780d8a62SMichael Pfeiffer 			break;
8516163f333SKarsten Heimrich 
852780d8a62SMichael Pfeiffer 		case MSG_PRINT:
853fd952aefSRyan Leavengood 			_Print(message);
854780d8a62SMichael Pfeiffer 			break;
855780d8a62SMichael Pfeiffer 
856780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
857d3046f7dSMichael Pfeiffer 			fImageView->ZoomIn();
858780d8a62SMichael Pfeiffer 			break;
8596163f333SKarsten Heimrich 
860780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
861d3046f7dSMichael Pfeiffer 			fImageView->ZoomOut();
862780d8a62SMichael Pfeiffer 			break;
8636163f333SKarsten Heimrich 
864780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
8654fd570d3SAxel Dörfler 			fImageView->SetZoom(1.0);
866780d8a62SMichael Pfeiffer 			break;
8676163f333SKarsten Heimrich 
86881b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
869fd952aefSRyan Leavengood 			fImageView->SetScaleBilinear(_ToggleMenuItem(message->what));
87081b9c776SMichael Pfeiffer 			break;
871780d8a62SMichael Pfeiffer 
8726163f333SKarsten Heimrich 		case MSG_OPEN_RESIZER_WINDOW: {
8736163f333SKarsten Heimrich 			if (fImageView->GetBitmap() != NULL) {
874d9f6762dSMichael Pfeiffer 				BRect rect = fImageView->GetBitmap()->Bounds();
875fd952aefSRyan Leavengood 				_OpenResizerWindow(rect.IntegerWidth()+1, rect.IntegerHeight()+1);
876d9f6762dSMichael Pfeiffer 			}
8776163f333SKarsten Heimrich 		}	break;
8786163f333SKarsten Heimrich 
8796163f333SKarsten Heimrich 		case MSG_RESIZE: {
880d9f6762dSMichael Pfeiffer 			int w = message->FindInt32("w");
881d9f6762dSMichael Pfeiffer 			int h = message->FindInt32("h");
882d9f6762dSMichael Pfeiffer 			fImageView->ResizeImage(w, h);
8836163f333SKarsten Heimrich 		} break;
8846163f333SKarsten Heimrich 
885880be331SRyan Leavengood 		case MSG_RESIZER_WINDOW_QUIT:
8866163f333SKarsten Heimrich 			delete fResizerWindowMessenger;
887d9f6762dSMichael Pfeiffer 			fResizerWindowMessenger = NULL;
888d9f6762dSMichael Pfeiffer 			break;
889d9f6762dSMichael Pfeiffer 
8906163f333SKarsten Heimrich 		case MSG_DESKTOP_BACKGROUND: {
8910a74004cSRyan Leavengood 			BMessage message(B_REFS_RECEIVED);
8920a74004cSRyan Leavengood 			message.AddRef("refs", fImageView->Image());
8930a74004cSRyan Leavengood 			// This is used in the Backgrounds code for scaled placement
8940a74004cSRyan Leavengood 			message.AddInt32("placement", 'scpl');
8950a74004cSRyan Leavengood 			be_roster->Launch("application/x-vnd.haiku-backgrounds", &message);
8966163f333SKarsten Heimrich 		}	break;
897a60adbf9SAxel Dörfler 
89813afa642SPhil Greenway 		default:
899efa8b4f3SAxel Dörfler 			BWindow::MessageReceived(message);
90013afa642SPhil Greenway 			break;
90113afa642SPhil Greenway 	}
90213afa642SPhil Greenway }
903fc0a275bSMatthew Wilber 
904efa8b4f3SAxel Dörfler 
905fc0a275bSMatthew Wilber void
906fd952aefSRyan Leavengood ShowImageWindow::_SaveAs(BMessage* message)
907fc0a275bSMatthew Wilber {
908cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
909cdb89ebbSMatthew Wilber 	translator_id outTranslator;
910cdb89ebbSMatthew Wilber 	uint32 outType;
9116163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
912efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9136163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
914cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
915fc0a275bSMatthew Wilber 		return;
916fc0a275bSMatthew Wilber 
917cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
918cdb89ebbSMatthew Wilber 	// message that the save panel will send back
919c1a10c14SKarsten Heimrich 	BMessage panelMsg(MSG_SAVE_PANEL);
920c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTranslatorField, outTranslator);
921c1a10c14SKarsten Heimrich 	panelMsg.AddInt32(kTypeField, outType);
922cdb89ebbSMatthew Wilber 
923cdb89ebbSMatthew Wilber 	// Create save panel and show it
9246163f333SKarsten Heimrich 	BMessenger target(this);
925efa8b4f3SAxel Dörfler 	fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
926c1a10c14SKarsten Heimrich 		&target, NULL, 0, false, &panelMsg);
927d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
928fc0a275bSMatthew Wilber 		return;
929a60adbf9SAxel Dörfler 
930d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
931d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
932fc0a275bSMatthew Wilber }
933fc0a275bSMatthew Wilber 
934efa8b4f3SAxel Dörfler 
935fc0a275bSMatthew Wilber void
936fd952aefSRyan Leavengood ShowImageWindow::_SaveToFile(BMessage* message)
937fc0a275bSMatthew Wilber {
938cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
939efa8b4f3SAxel Dörfler 	entry_ref dirRef;
940efa8b4f3SAxel Dörfler 	if (message->FindRef("directory", &dirRef) != B_OK)
941fc0a275bSMatthew Wilber 		return;
942efa8b4f3SAxel Dörfler 
943fc0a275bSMatthew Wilber 	const char* filename;
944efa8b4f3SAxel Dörfler 	if (message->FindString("name", &filename) != B_OK)
945fc0a275bSMatthew Wilber 		return;
946fc0a275bSMatthew Wilber 
947cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
948cdb89ebbSMatthew Wilber 	// to save the output image
949cdb89ebbSMatthew Wilber 	translator_id outTranslator;
950cdb89ebbSMatthew Wilber 	uint32 outType;
9516163f333SKarsten Heimrich 	if (message->FindInt32(kTranslatorField,
952efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
9536163f333SKarsten Heimrich 		|| message->FindInt32(kTypeField,
954cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
955cdb89ebbSMatthew Wilber 		return;
956cdb89ebbSMatthew Wilber 
957a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
958a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
959a7e78e3bSMatthew Wilber 	BTranslatorRoster* roster = BTranslatorRoster::Default();
960efa8b4f3SAxel Dörfler 	const translation_format* outFormat = NULL;
961efa8b4f3SAxel Dörfler 	int32 outCount = 0;
962efa8b4f3SAxel Dörfler 	if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
963efa8b4f3SAxel Dörfler 		|| outCount < 1)
964a7e78e3bSMatthew Wilber 		return;
965efa8b4f3SAxel Dörfler 
966a7e78e3bSMatthew Wilber 	int32 i;
967efa8b4f3SAxel Dörfler 	for (i = 0; i < outCount; i++) {
968efa8b4f3SAxel Dörfler 		if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
969a7e78e3bSMatthew Wilber 			break;
970a7e78e3bSMatthew Wilber 	}
971efa8b4f3SAxel Dörfler 	if (i == outCount)
972fc0a275bSMatthew Wilber 		return;
973fc0a275bSMatthew Wilber 
974a7e78e3bSMatthew Wilber 	// Write out the image file
975efa8b4f3SAxel Dörfler 	BDirectory dir(&dirRef);
976efa8b4f3SAxel Dörfler 	fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
977fc0a275bSMatthew Wilber }
978fc0a275bSMatthew Wilber 
979efa8b4f3SAxel Dörfler 
9801ed4535fSStephan Aßmus // This is temporary solution for building BString with printf like format.
9811ed4535fSStephan Aßmus // will be removed in the future.
9821ed4535fSStephan Aßmus static void
9831ed4535fSStephan Aßmus bs_printf(BString* string, const char* format, ...)
9841ed4535fSStephan Aßmus {
9851ed4535fSStephan Aßmus 	va_list ap;
9861ed4535fSStephan Aßmus 	char* buf;
9871ed4535fSStephan Aßmus 
9881ed4535fSStephan Aßmus 	va_start(ap, format);
9891ed4535fSStephan Aßmus 	vasprintf(&buf, format, ap);
9901ed4535fSStephan Aßmus 	string->SetTo(buf);
9911ed4535fSStephan Aßmus 	free(buf);
9921ed4535fSStephan Aßmus 	va_end(ap);
9931ed4535fSStephan Aßmus }
9941ed4535fSStephan Aßmus 
9951ed4535fSStephan Aßmus 
9964eb0cbb0SMatt Madia #undef B_TRANSLATE_CONTEXT
9974eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "ClosePrompt"
9981ed4535fSStephan Aßmus 
999cdb89ebbSMatthew Wilber bool
1000fd952aefSRyan Leavengood ShowImageWindow::_ClosePrompt()
1001ee7b4f39SMatthew Wilber {
1002ee7b4f39SMatthew Wilber 	if (!fModified)
1003ee7b4f39SMatthew Wilber 		return true;
1004efa8b4f3SAxel Dörfler 
1005ee7b4f39SMatthew Wilber 	int32 page, count;
1006ee7b4f39SMatthew Wilber 	count = fImageView->PageCount();
1007ee7b4f39SMatthew Wilber 	page = fImageView->CurrentPage();
1008ee7b4f39SMatthew Wilber 	BString prompt, name;
1009ee7b4f39SMatthew Wilber 	fImageView->GetName(&name);
1010efa8b4f3SAxel Dörfler 
10111ed4535fSStephan Aßmus 	if (count > 1) {
10121ed4535fSStephan Aßmus 		bs_printf(&prompt,
1013905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' (page %d) has been changed. Do you "
1014905c8c8cSMatt Madia 				"want to close the document?"),
10151ed4535fSStephan Aßmus 			name.String(), page);
10161ed4535fSStephan Aßmus 	} else {
10171ed4535fSStephan Aßmus 		bs_printf(&prompt,
1018905c8c8cSMatt Madia 			B_TRANSLATE("The document '%s' has been changed. Do you want to "
1019905c8c8cSMatt Madia 				"close the document?"),
10201ed4535fSStephan Aßmus 			name.String());
10211ed4535fSStephan Aßmus 	}
10221ed4535fSStephan Aßmus 
1023905c8c8cSMatt Madia 	BAlert* pAlert = new BAlert(B_TRANSLATE("Close document"), prompt.String(),
1024905c8c8cSMatt Madia 		B_TRANSLATE("Cancel"), B_TRANSLATE("Close"));
1025efa8b4f3SAxel Dörfler 	if (pAlert->Go() == 0) {
1026ee7b4f39SMatthew Wilber 		// Cancel
1027ee7b4f39SMatthew Wilber 		return false;
1028efa8b4f3SAxel Dörfler 	} else {
1029ee7b4f39SMatthew Wilber 		// Close
1030187f0b8aSMatthew Wilber 		fModified = false;
1031ee7b4f39SMatthew Wilber 		return true;
1032ee7b4f39SMatthew Wilber 	}
1033ee7b4f39SMatthew Wilber }
1034ee7b4f39SMatthew Wilber 
1035cdb89ebbSMatthew Wilber 
1036ad13f387SMichael Pfeiffer void
1037fd952aefSRyan Leavengood ShowImageWindow::_ToggleFullScreen()
1038ad13f387SMichael Pfeiffer {
1039ad13f387SMichael Pfeiffer 	BRect frame;
1040ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
1041ad13f387SMichael Pfeiffer 	if (fFullScreen) {
1042ad13f387SMichael Pfeiffer 		BScreen screen;
1043ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
1044ad13f387SMichael Pfeiffer 		frame = screen.Frame();
1045d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
1046ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
1047ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
1048ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
1049ad13f387SMichael Pfeiffer 
1050ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
1051c0b16687SAxel Dörfler 
1052c0b16687SAxel Dörfler 		Activate();
1053c0b16687SAxel Dörfler 			// make the window frontmost
1054ad13f387SMichael Pfeiffer 	} else {
1055ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
1056ad13f387SMichael Pfeiffer 
1057ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
1058ad13f387SMichael Pfeiffer 	}
1059efa8b4f3SAxel Dörfler 
106076d115d8SRyan Leavengood 	fImageView->SetFullScreen(fFullScreen);
1061d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
1062ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
1063ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
1064ad13f387SMichael Pfeiffer }
1065ad13f387SMichael Pfeiffer 
1066efa8b4f3SAxel Dörfler 
1067d3046f7dSMichael Pfeiffer void
1068fd952aefSRyan Leavengood ShowImageWindow::_LoadSettings()
1069d3046f7dSMichael Pfeiffer {
1070efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1071efa8b4f3SAxel Dörfler 
1072d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1073d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
1074d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
1075d3046f7dSMichael Pfeiffer 
1076efa8b4f3SAxel Dörfler 		int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option());
1077d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
1078d3046f7dSMichael Pfeiffer 
1079efa8b4f3SAxel Dörfler 		float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1080d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
1081d3046f7dSMichael Pfeiffer 
1082d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
1083d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
1084d3046f7dSMichael Pfeiffer 
1085d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
1086d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
1087d3046f7dSMichael Pfeiffer 
1088d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
1089d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
1090d3046f7dSMichael Pfeiffer 
1091d3046f7dSMichael Pfeiffer 		settings->Unlock();
1092d3046f7dSMichael Pfeiffer 	}
1093d3046f7dSMichael Pfeiffer }
1094d3046f7dSMichael Pfeiffer 
1095efa8b4f3SAxel Dörfler 
1096d3046f7dSMichael Pfeiffer void
1097fd952aefSRyan Leavengood ShowImageWindow::_SavePrintOptions()
1098d3046f7dSMichael Pfeiffer {
1099efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
1100efa8b4f3SAxel Dörfler 
1101d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
1102d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
1103d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
1104d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1105d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
1106d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
1107d3046f7dSMichael Pfeiffer 		settings->Unlock();
1108d3046f7dSMichael Pfeiffer 	}
1109d3046f7dSMichael Pfeiffer }
1110d3046f7dSMichael Pfeiffer 
1111efa8b4f3SAxel Dörfler 
1112cdb89ebbSMatthew Wilber bool
1113fd952aefSRyan Leavengood ShowImageWindow::_PageSetup()
1114780d8a62SMichael Pfeiffer {
1115780d8a62SMichael Pfeiffer 	BString name;
1116d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
1117780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
1118efa8b4f3SAxel Dörfler 	if (fPrintSettings != NULL)
1119780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
1120efa8b4f3SAxel Dörfler 
11216163f333SKarsten Heimrich 	status_t status = printJob.ConfigPage();
11226163f333SKarsten Heimrich 	if (status == B_OK) {
1123780d8a62SMichael Pfeiffer 		delete fPrintSettings;
1124780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
1125780d8a62SMichael Pfeiffer 	}
1126efa8b4f3SAxel Dörfler 
11276163f333SKarsten Heimrich 	return status == B_OK;
1128780d8a62SMichael Pfeiffer }
1129780d8a62SMichael Pfeiffer 
1130efa8b4f3SAxel Dörfler 
1131780d8a62SMichael Pfeiffer void
1132fd952aefSRyan Leavengood ShowImageWindow::_PrepareForPrint()
1133780d8a62SMichael Pfeiffer {
11346163f333SKarsten Heimrich 	if (fPrintSettings == NULL) {
11356163f333SKarsten Heimrich 		BString name;
11366163f333SKarsten Heimrich 		fImageView->GetName(&name);
11376163f333SKarsten Heimrich 
11386163f333SKarsten Heimrich 		BPrintJob printJob("");
11396163f333SKarsten Heimrich 		if (printJob.ConfigJob() == B_OK)
11406163f333SKarsten Heimrich 			fPrintSettings = printJob.Settings();
11416163f333SKarsten Heimrich 	}
1142780d8a62SMichael Pfeiffer 
1143d3046f7dSMichael Pfeiffer 	fPrintOptions.SetBounds(fImageView->GetBitmap()->Bounds());
1144d3046f7dSMichael Pfeiffer 	fPrintOptions.SetWidth(fImageView->GetBitmap()->Bounds().Width() + 1);
1145780d8a62SMichael Pfeiffer 
1146efa8b4f3SAxel Dörfler 	new PrintOptionsWindow(BPoint(Frame().left + 30, Frame().top + 50),
1147efa8b4f3SAxel Dörfler 		&fPrintOptions, this);
1148780d8a62SMichael Pfeiffer }
1149780d8a62SMichael Pfeiffer 
1150efa8b4f3SAxel Dörfler 
1151780d8a62SMichael Pfeiffer void
1152fd952aefSRyan Leavengood ShowImageWindow::_Print(BMessage* msg)
1153780d8a62SMichael Pfeiffer {
1154780d8a62SMichael Pfeiffer 	status_t st;
1155efa8b4f3SAxel Dörfler 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1156780d8a62SMichael Pfeiffer 		return;
1157780d8a62SMichael Pfeiffer 
1158fd952aefSRyan Leavengood 	_SavePrintOptions();
1159d3046f7dSMichael Pfeiffer 
1160780d8a62SMichael Pfeiffer 	BString name;
1161d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
11626163f333SKarsten Heimrich 
1163780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
11646163f333SKarsten Heimrich 	if (fPrintSettings)
1165780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
11666163f333SKarsten Heimrich 
1167780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
11686163f333SKarsten Heimrich 		delete fPrintSettings;
11696163f333SKarsten Heimrich 		fPrintSettings = printJob.Settings();
1170780d8a62SMichael Pfeiffer 
1171780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
11723177ae77SStefano Ceccherini 		int32 firstPage = printJob.FirstPage();
11733177ae77SStefano Ceccherini 		int32 lastPage = printJob.LastPage();
11746163f333SKarsten Heimrich 		BRect printableRect = printJob.PrintableRect();
11756163f333SKarsten Heimrich 
1176efa8b4f3SAxel Dörfler 		if (firstPage < 1)
1177780d8a62SMichael Pfeiffer 			firstPage = 1;
1178efa8b4f3SAxel Dörfler 		if (lastPage < firstPage)
1179780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1180780d8a62SMichael Pfeiffer 
11813177ae77SStefano Ceccherini 		BBitmap* bitmap = fImageView->GetBitmap();
11823177ae77SStefano Ceccherini 		float imageWidth = bitmap->Bounds().Width() + 1.0;
11833177ae77SStefano Ceccherini 		float imageHeight = bitmap->Bounds().Height() + 1.0;
1184780d8a62SMichael Pfeiffer 
11856163f333SKarsten Heimrich 		float width;
1186780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
11876163f333SKarsten Heimrich 			case PrintOptions::kFitToPage: {
11886163f333SKarsten Heimrich 				float w1 = printableRect.Width()+1;
11896163f333SKarsten Heimrich 				float w2 = imageWidth * (printableRect.Height() + 1) / imageHeight;
1190efa8b4f3SAxel Dörfler 				if (w2 < w1)
1191780d8a62SMichael Pfeiffer 					width = w2;
1192efa8b4f3SAxel Dörfler 				else
1193780d8a62SMichael Pfeiffer 					width = w1;
11946163f333SKarsten Heimrich 			}	break;
1195780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1196780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1197780d8a62SMichael Pfeiffer 				break;
1198780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1199780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1200780d8a62SMichael Pfeiffer 				break;
1201780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1202780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1203780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1204780d8a62SMichael Pfeiffer 				break;
1205efa8b4f3SAxel Dörfler 
1206780d8a62SMichael Pfeiffer 			default:
1207780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1208780d8a62SMichael Pfeiffer 				width = imageWidth;
1209780d8a62SMichael Pfeiffer 		}
1210780d8a62SMichael Pfeiffer 
1211efa8b4f3SAxel Dörfler 		// TODO: eventually print large images on several pages
1212780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1213d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
12145eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
12155eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
12165eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1217d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1218780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1219780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1220780d8a62SMichael Pfeiffer 	}
1221780d8a62SMichael Pfeiffer }
1222780d8a62SMichael Pfeiffer 
122356b0c7b9SKarsten Heimrich 
1224d9f6762dSMichael Pfeiffer void
1225fd952aefSRyan Leavengood ShowImageWindow::_OpenResizerWindow(int32 width, int32 height)
1226d9f6762dSMichael Pfeiffer {
1227d9f6762dSMichael Pfeiffer 	if (fResizerWindowMessenger == NULL) {
1228d9f6762dSMichael Pfeiffer 		// open window if it is not already opened
1229d9f6762dSMichael Pfeiffer 		BWindow* window = new ResizerWindow(this, width, height);
1230d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger = new BMessenger(window);
1231d9f6762dSMichael Pfeiffer 		window->Show();
12326163f333SKarsten Heimrich 	} else {
1233d9f6762dSMichael Pfeiffer 		fResizerWindowMessenger->SendMessage(ResizerWindow::kActivateMsg);
1234d9f6762dSMichael Pfeiffer 	}
12356163f333SKarsten Heimrich }
1236d9f6762dSMichael Pfeiffer 
123756b0c7b9SKarsten Heimrich 
1238d9f6762dSMichael Pfeiffer void
1239fd952aefSRyan Leavengood ShowImageWindow::_UpdateResizerWindow(int32 width, int32 height)
1240d9f6762dSMichael Pfeiffer {
12416163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1242d9f6762dSMichael Pfeiffer 		return;
1243d9f6762dSMichael Pfeiffer 
1244d9f6762dSMichael Pfeiffer 	BMessage updateMsg(ResizerWindow::kUpdateMsg);
12450acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("width", width);
12460acb8cc4SMichael Pfeiffer 	updateMsg.AddInt32("height", height);
1247d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(&updateMsg);
1248d9f6762dSMichael Pfeiffer }
1249d9f6762dSMichael Pfeiffer 
125056b0c7b9SKarsten Heimrich 
1251d9f6762dSMichael Pfeiffer void
1252fd952aefSRyan Leavengood ShowImageWindow::_CloseResizerWindow()
1253d9f6762dSMichael Pfeiffer {
12546163f333SKarsten Heimrich 	if (fResizerWindowMessenger == NULL)
1255d9f6762dSMichael Pfeiffer 		return;
12566163f333SKarsten Heimrich 
1257d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger->SendMessage(B_QUIT_REQUESTED);
12586163f333SKarsten Heimrich 	delete fResizerWindowMessenger;
1259d9f6762dSMichael Pfeiffer 	fResizerWindowMessenger = NULL;
1260d9f6762dSMichael Pfeiffer }
1261efa8b4f3SAxel Dörfler 
126256b0c7b9SKarsten Heimrich 
1263780d8a62SMichael Pfeiffer bool
1264cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1265cdb89ebbSMatthew Wilber {
1266efa8b4f3SAxel Dörfler 	if (fSavePanel) {
1267efa8b4f3SAxel Dörfler 		// Don't allow this window to be closed if a save panel is open
1268efa8b4f3SAxel Dörfler 		return false;
1269cdb89ebbSMatthew Wilber 	}
1270cdb89ebbSMatthew Wilber 
1271fd952aefSRyan Leavengood 	bool quit = _ClosePrompt();
1272efa8b4f3SAxel Dörfler 
1273efa8b4f3SAxel Dörfler 	if (quit) {
1274fd952aefSRyan Leavengood 		_CloseResizerWindow();
1275d9f6762dSMichael Pfeiffer 
127607caaa8eSMatthew Wilber 		// tell the app to forget about this window
127707caaa8eSMatthew Wilber 		be_app->PostMessage(MSG_WINDOW_QUIT);
127807caaa8eSMatthew Wilber 	}
1279fc0a275bSMatthew Wilber 
1280efa8b4f3SAxel Dörfler 	return quit;
1281efa8b4f3SAxel Dörfler }
1282