xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision a60adbf9b400d4f8d586c3acb7ff34034e89fb6d)
1efa8b4f3SAxel Dörfler /*
2efa8b4f3SAxel Dörfler  * Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
3efa8b4f3SAxel Dörfler  * Distributed under the terms of the MIT License.
4efa8b4f3SAxel Dörfler  *
5efa8b4f3SAxel Dörfler  * Authors:
6efa8b4f3SAxel Dörfler  *		Fernando Francisco de Oliveira
7efa8b4f3SAxel Dörfler  *		Michael Wilber
8efa8b4f3SAxel Dörfler  *		Michael Pfeiffer
9efa8b4f3SAxel Dörfler  */
1013afa642SPhil Greenway 
11efa8b4f3SAxel Dörfler 
12*a60adbf9SAxel Dörfler #include "BackgroundImage.h"
13efa8b4f3SAxel Dörfler #include "EntryMenuItem.h"
14efa8b4f3SAxel Dörfler #include "ShowImageApp.h"
15efa8b4f3SAxel Dörfler #include "ShowImageConstants.h"
16efa8b4f3SAxel Dörfler #include "ShowImageStatusView.h"
17efa8b4f3SAxel Dörfler #include "ShowImageView.h"
18efa8b4f3SAxel Dörfler #include "ShowImageWindow.h"
19efa8b4f3SAxel Dörfler 
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>
27*a60adbf9SAxel Dörfler #include <FindDirectory.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>
36efa8b4f3SAxel Dörfler #include <SupportDefs.h>
3713afa642SPhil Greenway #include <TranslationUtils.h>
3813afa642SPhil Greenway #include <TranslatorRoster.h>
3913afa642SPhil Greenway 
40efa8b4f3SAxel Dörfler #include <new>
41efa8b4f3SAxel Dörfler #include <stdio.h>
4213afa642SPhil Greenway 
43a8fc7138SMichael Pfeiffer 
44758b1d0eSIngo Weinhold RecentDocumentsMenu::RecentDocumentsMenu(const char *title, menu_layout layout)
45a8fc7138SMichael Pfeiffer 	: BMenu(title, layout)
46a8fc7138SMichael Pfeiffer {
47a8fc7138SMichael Pfeiffer }
48a8fc7138SMichael Pfeiffer 
49efa8b4f3SAxel Dörfler 
50a8fc7138SMichael Pfeiffer bool
51*a60adbf9SAxel Dörfler RecentDocumentsMenu::AddDynamicItem(add_state addState)
52a8fc7138SMichael Pfeiffer {
53*a60adbf9SAxel Dörfler 	if (addState != B_INITIAL_ADD)
54efa8b4f3SAxel Dörfler 		return false;
55a8fc7138SMichael Pfeiffer 
56a8fc7138SMichael Pfeiffer 	BMenuItem *item;
57a8fc7138SMichael Pfeiffer 	BMessage list, *msg;
58a8fc7138SMichael Pfeiffer 	entry_ref ref;
59a8fc7138SMichael Pfeiffer 	char name[B_FILE_NAME_LENGTH];
60a8fc7138SMichael Pfeiffer 
61a8fc7138SMichael Pfeiffer 	while ((item = RemoveItem((int32)0)) != NULL) {
62a8fc7138SMichael Pfeiffer 		delete item;
63a8fc7138SMichael Pfeiffer 	}
64a8fc7138SMichael Pfeiffer 
65efa8b4f3SAxel Dörfler 	be_roster->GetRecentDocuments(&list, 20, NULL, kApplicationSignature);
66a8fc7138SMichael Pfeiffer 	for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
67a8fc7138SMichael Pfeiffer 		BEntry entry(&ref);
68a8fc7138SMichael Pfeiffer 		if (entry.Exists() && entry.GetName(name) == B_OK) {
69a8fc7138SMichael Pfeiffer 			msg = new BMessage(B_REFS_RECEIVED);
70a8fc7138SMichael Pfeiffer 			msg->AddRef("refs", &ref);
71a8fc7138SMichael Pfeiffer 			item =  new EntryMenuItem(&ref, name, msg, 0, 0);
72a8fc7138SMichael Pfeiffer 			AddItem(item);
73a8fc7138SMichael Pfeiffer 			item->SetTarget(be_app, NULL);
74a8fc7138SMichael Pfeiffer 		}
75a8fc7138SMichael Pfeiffer 	}
76a8fc7138SMichael Pfeiffer 
77a8fc7138SMichael Pfeiffer 	return false;
78a8fc7138SMichael Pfeiffer }
79a8fc7138SMichael Pfeiffer 
80a8fc7138SMichael Pfeiffer 
81efa8b4f3SAxel Dörfler //	#pragma mark -
82a8fc7138SMichael Pfeiffer 
83efa8b4f3SAxel Dörfler 
84efa8b4f3SAxel Dörfler ShowImageWindow::ShowImageWindow(const entry_ref *ref,
85efa8b4f3SAxel Dörfler 		const BMessenger& trackerMessenger)
861de41298SMatthew Wilber 	: BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0)
8713afa642SPhil Greenway {
88d3046f7dSMichael Pfeiffer 	fSavePanel = NULL;
89ee7b4f39SMatthew Wilber 	fModified = false;
90ad13f387SMichael Pfeiffer 	fFullScreen = false;
91d3046f7dSMichael Pfeiffer 	fShowCaption = true;
92780d8a62SMichael Pfeiffer 	fPrintSettings = NULL;
93d3046f7dSMichael Pfeiffer 	fImageView = NULL;
94d3046f7dSMichael Pfeiffer 	fSlideShowDelay = NULL;
95d3046f7dSMichael Pfeiffer 
96d3046f7dSMichael Pfeiffer 	LoadSettings();
97fc0a275bSMatthew Wilber 
9813afa642SPhil Greenway 	// create menu bar
99e9dcd874SAxel Dörfler 	fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar");
100efa8b4f3SAxel Dörfler 	AddMenus(fBar);
101e9dcd874SAxel Dörfler 	AddChild(fBar);
10213afa642SPhil Greenway 
10313afa642SPhil Greenway 	BRect viewFrame = Bounds();
104e9dcd874SAxel Dörfler 	viewFrame.top = fBar->Bounds().Height() + 1;
10513afa642SPhil Greenway 	viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
10613afa642SPhil Greenway 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
10713afa642SPhil Greenway 
10813afa642SPhil Greenway 	// create the image view
109d3046f7dSMichael Pfeiffer 	fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
1107eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
11113afa642SPhil Greenway 	// wrap a scroll view around the view
112efa8b4f3SAxel Dörfler 	BScrollView *scrollView = new BScrollView("image_scroller", fImageView,
113cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
114efa8b4f3SAxel Dörfler 	AddChild(scrollView);
11513afa642SPhil Greenway 
11607caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
117cdb89ebbSMatthew Wilber 	BRect rect;
11813afa642SPhil Greenway 	rect = Bounds();
11913afa642SPhil Greenway 	rect.top	= viewFrame.bottom + 1;
12007caaa8eSMatthew Wilber 	rect.left 	= viewFrame.left + kstatusWidth;
1210916ab53SMatthew Wilber 	rect.right	= viewFrame.right + 1;
1220916ab53SMatthew Wilber 	rect.bottom += 1;
123efa8b4f3SAxel Dörfler 	BScrollBar *horizontalScrollBar = new BScrollBar(rect, "hscroll",
124efa8b4f3SAxel Dörfler 		fImageView, 0, 150, B_HORIZONTAL);
125efa8b4f3SAxel Dörfler 	AddChild(horizontalScrollBar);
12613afa642SPhil Greenway 
12713afa642SPhil Greenway 	rect.left = 0;
12807caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
1290cd4ecd8SStephan Aßmus 	rect.bottom -= 1;
130d3046f7dSMichael Pfeiffer 	fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
131cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
132d3046f7dSMichael Pfeiffer 	AddChild(fStatusView);
13313afa642SPhil Greenway 
13413afa642SPhil Greenway 	rect = Bounds();
1350916ab53SMatthew Wilber 	rect.top    = viewFrame.top - 1;
13613afa642SPhil Greenway 	rect.left 	= viewFrame.right + 1;
1370916ab53SMatthew Wilber 	rect.bottom	= viewFrame.bottom + 1;
1380916ab53SMatthew Wilber 	rect.right	+= 1;
139efa8b4f3SAxel Dörfler 	BScrollBar *verticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
140efa8b4f3SAxel Dörfler 		0, 150, B_VERTICAL);
141efa8b4f3SAxel Dörfler 	AddChild(verticalScrollBar);
14213afa642SPhil Greenway 
14303839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
14413afa642SPhil Greenway 
145134d6076SMichael Pfeiffer 	// finish creating the window
146efa8b4f3SAxel Dörfler 	fImageView->SetImage(ref);
147134d6076SMichael Pfeiffer 	fImageView->SetTrackerMessenger(trackerMessenger);
1487eca0987SMichael Pfeiffer 
149780d8a62SMichael Pfeiffer 	if (InitCheck() == B_OK) {
150d3046f7dSMichael Pfeiffer 		// add View menu here so it can access ShowImageView methods
151efa8b4f3SAxel Dörfler 		BMenu* menu = new BMenu("View");
152efa8b4f3SAxel Dörfler 		BuildViewMenu(menu);
153efa8b4f3SAxel Dörfler 		fBar->AddItem(menu);
154a8fc7138SMichael Pfeiffer 		MarkMenuItem(fBar, MSG_DITHER_IMAGE, fImageView->GetDither());
155780d8a62SMichael Pfeiffer 		UpdateTitle();
156780d8a62SMichael Pfeiffer 
157efa8b4f3SAxel Dörfler 		SetPulseRate(100000);
158efa8b4f3SAxel Dörfler 			// every 1/10 second; ShowImageView needs it for marching ants
15903839579SMatthew Wilber 
160d3046f7dSMichael Pfeiffer 		fImageView->FlushToLeftTop();
161d3046f7dSMichael Pfeiffer 		WindowRedimension(fImageView->GetBitmap());
162d3046f7dSMichael Pfeiffer 		fImageView->MakeFocus(true); // to receive KeyDown messages
16313afa642SPhil Greenway 		Show();
164d10d5947SMichael Pfeiffer 	} else {
165e6a50d9cSMichael Pfeiffer 		BAlert* alert;
166e6a50d9cSMichael Pfeiffer 		alert = new BAlert("ShowImage",
167e6a50d9cSMichael Pfeiffer 			"Could not load image! Either the file or an image translator for it does not exist.",
168e6a50d9cSMichael Pfeiffer 			"OK", NULL, NULL,
169e6a50d9cSMichael Pfeiffer 			B_WIDTH_AS_USUAL, B_INFO_ALERT);
170e6a50d9cSMichael Pfeiffer 		alert->Go();
171efa8b4f3SAxel Dörfler 
172d10d5947SMichael Pfeiffer 		// exit if file could not be opened
173efa8b4f3SAxel Dörfler 		PostMessage(B_QUIT_REQUESTED);
174efa8b4f3SAxel Dörfler 		return;
175d10d5947SMichael Pfeiffer 	}
176402c09e5SMatthew Wilber 
177402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
178402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
179402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
18013afa642SPhil Greenway }
18113afa642SPhil Greenway 
182efa8b4f3SAxel Dörfler 
18313afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
18413afa642SPhil Greenway {
18513afa642SPhil Greenway }
18613afa642SPhil Greenway 
187efa8b4f3SAxel Dörfler 
188cdb89ebbSMatthew Wilber status_t
189cdb89ebbSMatthew Wilber ShowImageWindow::InitCheck()
19013afa642SPhil Greenway {
191d3046f7dSMichael Pfeiffer 	if (!fImageView || fImageView->GetBitmap() == NULL)
19213afa642SPhil Greenway 		return B_ERROR;
193efa8b4f3SAxel Dörfler 
19413afa642SPhil Greenway 	return B_OK;
19513afa642SPhil Greenway }
196cdb89ebbSMatthew Wilber 
197efa8b4f3SAxel Dörfler 
198cdb89ebbSMatthew Wilber void
199cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
20013afa642SPhil Greenway {
201e6a50d9cSMichael Pfeiffer 	BString path;
202d3046f7dSMichael Pfeiffer 	fImageView->GetPath(&path);
203e6a50d9cSMichael Pfeiffer 	SetTitle(path.String());
20413afa642SPhil Greenway }
20513afa642SPhil Greenway 
206efa8b4f3SAxel Dörfler 
207cdb89ebbSMatthew Wilber void
208efa8b4f3SAxel Dörfler ShowImageWindow::BuildViewMenu(BMenu *menu)
209da87390fSMichael Pfeiffer {
210efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, 'W', true);
211efa8b4f3SAxel Dörfler 	MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
212efa8b4f3SAxel Dörfler 	BMenu* delayMenu = new BMenu("Slide Delay");
213efa8b4f3SAxel Dörfler 	if (fSlideShowDelay == NULL)
214efa8b4f3SAxel Dörfler 		fSlideShowDelay = delayMenu;
215efa8b4f3SAxel Dörfler 
216efa8b4f3SAxel Dörfler 	delayMenu->SetRadioMode(true);
217efa8b4f3SAxel Dörfler 	// Note: ShowImage loads images in window thread so it becomes unresponsive if
218da87390fSMichael Pfeiffer 	// slide show delay is too short! (Especially if loading the image takes as long as
219da87390fSMichael Pfeiffer 	// or longer than the slide show delay). Should load in background thread!
220efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Three Seconds", 3);
221efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Four Second", 4);
222efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Five Seconds", 5);
223efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Six Seconds", 6);
224efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Seven Seconds", 7);
225efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Eight Seconds", 8);
226efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Nine Seconds", 9);
227efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Ten Seconds", 10);
228efa8b4f3SAxel Dörfler 	AddDelayItem(delayMenu, "Twenty Seconds", 20);
229efa8b4f3SAxel Dörfler 	menu->AddItem(delayMenu);
23030060f17SMatthew Wilber 
231efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
232efa8b4f3SAxel Dörfler 
233efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Original Size", MSG_ORIGINAL_SIZE, 0, 0, 'W', true);
234efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Zoom In", MSG_ZOOM_IN, '+', 0, 'W', true);
235efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Zoom Out", MSG_ZOOM_OUT, '-', 0, 'W', true);
236efa8b4f3SAxel Dörfler 
237efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
238efa8b4f3SAxel Dörfler 
239efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Scale Bilinear", MSG_SCALE_BILINEAR, 0, 0, 'W', true);
240efa8b4f3SAxel Dörfler 
241efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
242efa8b4f3SAxel Dörfler 
243efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Shrink to Window", MSG_SHRINK_TO_WINDOW, 0, 0, 'W', true);
244efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Zoom to Window", MSG_ZOOM_TO_WINDOW, 0, 0, 'W', true);
245efa8b4f3SAxel Dörfler 
246efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
247efa8b4f3SAxel Dörfler 
248efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Full Screen", MSG_FULL_SCREEN, 'F', 0, 'W', true);
249efa8b4f3SAxel Dörfler 	MarkMenuItem(menu, MSG_FULL_SCREEN, fFullScreen);
250efa8b4f3SAxel Dörfler 
251efa8b4f3SAxel Dörfler 	AddShortcut(B_ENTER, 0, new BMessage(MSG_FULL_SCREEN));
252efa8b4f3SAxel Dörfler 
253efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Show Caption in Full Screen Mode", MSG_SHOW_CAPTION, 0, 0, 'W', true);
254efa8b4f3SAxel Dörfler 	MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
255efa8b4f3SAxel Dörfler 
256efa8b4f3SAxel Dörfler 	MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
257da87390fSMichael Pfeiffer 
25819c76de4SMichael Pfeiffer 	bool shrink, zoom, enabled;
259efa8b4f3SAxel Dörfler 
260d3046f7dSMichael Pfeiffer 	shrink = fImageView->GetShrinkToBounds();
261d3046f7dSMichael Pfeiffer 	zoom = fImageView->GetZoomToBounds();
262efa8b4f3SAxel Dörfler 	MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, shrink);
263efa8b4f3SAxel Dörfler 	MarkMenuItem(menu, MSG_ZOOM_TO_WINDOW, zoom);
264efa8b4f3SAxel Dörfler 
26519c76de4SMichael Pfeiffer  	enabled = !(shrink || zoom);
266efa8b4f3SAxel Dörfler 	EnableMenuItem(menu, MSG_ORIGINAL_SIZE, enabled);
267efa8b4f3SAxel Dörfler 	EnableMenuItem(menu, MSG_ZOOM_IN, enabled);
268efa8b4f3SAxel Dörfler 	EnableMenuItem(menu, MSG_ZOOM_OUT, enabled);
269*a60adbf9SAxel Dörfler 
270*a60adbf9SAxel Dörfler 	menu->AddSeparatorItem();
271*a60adbf9SAxel Dörfler 
272*a60adbf9SAxel Dörfler 	AddItemMenu(menu, "As Desktop Background", MSG_DESKTOP_BACKGROUND, 0, 0, 'W',
273*a60adbf9SAxel Dörfler 		true);
274da87390fSMichael Pfeiffer }
275da87390fSMichael Pfeiffer 
276efa8b4f3SAxel Dörfler 
277da87390fSMichael Pfeiffer void
278efa8b4f3SAxel Dörfler ShowImageWindow::AddMenus(BMenuBar *bar)
27913afa642SPhil Greenway {
280efa8b4f3SAxel Dörfler 	BMenu *menu = new BMenu("File");
281a8fc7138SMichael Pfeiffer 	fOpenMenu = new RecentDocumentsMenu("Open");
282efa8b4f3SAxel Dörfler 	menu->AddItem(fOpenMenu);
283d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTrigger('O');
284d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
285d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTarget(be_app);
286d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetShortcut('O', 0);
287efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
288780d8a62SMichael Pfeiffer 	BMenu *pmenuSaveAs = new BMenu("Save As" B_UTF8_ELLIPSIS, B_ITEMS_IN_COLUMN);
289cdb89ebbSMatthew Wilber 	BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP);
290fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
291fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
292efa8b4f3SAxel Dörfler 	menu->AddItem(pmenuSaveAs);
293efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Close", B_QUIT_REQUESTED, 'W', 0, 'W', true);
294efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
295efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Page Setup" B_UTF8_ELLIPSIS, MSG_PAGE_SETUP, 0, 0, 'W', true);
296efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Print" B_UTF8_ELLIPSIS, MSG_PREPARE_PRINT, 0, 0, 'W', true);
297efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
298efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "About ShowImage" B_UTF8_ELLIPSIS, B_ABOUT_REQUESTED, 0, 0, 'A', true);
299efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
300efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Quit", B_QUIT_REQUESTED, 'Q', 0, 'A', true);
301efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
30213afa642SPhil Greenway 
303efa8b4f3SAxel Dörfler 	menu = new BMenu("Edit");
304efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Undo", B_UNDO, 'Z', 0, 'W', false);
305efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
306efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Cut", B_CUT, 'X', 0, 'W', false);
307efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Copy", B_COPY, 'C', 0, 'W', false);
308efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Paste", B_PASTE, 'V', 0, 'W', false);
309efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', false);
310efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
311efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
312efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
31313afa642SPhil Greenway 
314efa8b4f3SAxel Dörfler 	menu = fBrowseMenu = new BMenu("Browse");
315efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "First Page", MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, 'W', true);
316efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Last Page", MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, 'W', true);
317efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Previous Page", MSG_PAGE_PREV, B_LEFT_ARROW, 0, 'W', true);
318efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Next Page", MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, 'W', true);
319d3046f7dSMichael Pfeiffer 	fGoToPageMenu = new BMenu("Go To Page");
3205e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
321efa8b4f3SAxel Dörfler 	menu->AddItem(fGoToPageMenu);
322efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
323efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Previous File", MSG_FILE_PREV, B_UP_ARROW, 0, 'W', true);
324efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Next File", MSG_FILE_NEXT, B_DOWN_ARROW, 0, 'W', true);
325efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
32603839579SMatthew Wilber 
327efa8b4f3SAxel Dörfler 	menu = new BMenu("Image");
328efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Dither Image", MSG_DITHER_IMAGE, 0, 0, 'W', true);
329efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
330efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Rotate -90°", MSG_ROTATE_270, '[', 0, 'W', true);
331efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Rotate +90°", MSG_ROTATE_90, ']', 0, 'W', true);
332efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
333efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Mirror Vertical", MSG_MIRROR_VERTICAL, 0, 0, 'W', true);
334efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Mirror Horizontal", MSG_MIRROR_HORIZONTAL, 0, 0, 'W', true);
335efa8b4f3SAxel Dörfler 	menu->AddSeparatorItem();
336efa8b4f3SAxel Dörfler 	AddItemMenu(menu, "Invert", MSG_INVERT, 0, 0, 'W', true);
337efa8b4f3SAxel Dörfler 	bar->AddItem(menu);
33813afa642SPhil Greenway }
33913afa642SPhil Greenway 
340efa8b4f3SAxel Dörfler 
341cdb89ebbSMatthew Wilber BMenuItem *
342*a60adbf9SAxel Dörfler ShowImageWindow::AddItemMenu(BMenu *menu, char *caption, uint32 command,
343efa8b4f3SAxel Dörfler 	char shortcut, uint32 modifier, char target, bool enabled)
344cdb89ebbSMatthew Wilber {
345*a60adbf9SAxel Dörfler 	BMenuItem* item = new BMenuItem(caption, new BMessage(command), shortcut, modifier);
34613afa642SPhil Greenway 
34713afa642SPhil Greenway 	if (target == 'A')
348efa8b4f3SAxel Dörfler 		item->SetTarget(be_app);
349da87390fSMichael Pfeiffer 	else
350efa8b4f3SAxel Dörfler 		item->SetTarget(this);
35113afa642SPhil Greenway 
352efa8b4f3SAxel Dörfler 	item->SetEnabled(enabled);
353efa8b4f3SAxel Dörfler 	menu->AddItem(item);
354efa8b4f3SAxel Dörfler 
355efa8b4f3SAxel Dörfler 	return item;
35613afa642SPhil Greenway }
35713afa642SPhil Greenway 
358efa8b4f3SAxel Dörfler 
359ad13f387SMichael Pfeiffer BMenuItem*
360efa8b4f3SAxel Dörfler ShowImageWindow::AddDelayItem(BMenu *menu, char *caption, float value)
361ad13f387SMichael Pfeiffer {
362efa8b4f3SAxel Dörfler 	BMessage* message = new BMessage(MSG_SLIDE_SHOW_DELAY);
363efa8b4f3SAxel Dörfler 	message->AddFloat("value", value);
364ad13f387SMichael Pfeiffer 
365efa8b4f3SAxel Dörfler 	BMenuItem* item = new BMenuItem(caption, message, 0);
366efa8b4f3SAxel Dörfler 	item->SetTarget(this);
367ad13f387SMichael Pfeiffer 
368d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
369efa8b4f3SAxel Dörfler 	if (marked)
370efa8b4f3SAxel Dörfler 		item->SetMarked(true);
371ad13f387SMichael Pfeiffer 
372efa8b4f3SAxel Dörfler 	menu->AddItem(item);
373efa8b4f3SAxel Dörfler 	return item;
374ad13f387SMichael Pfeiffer }
375ad13f387SMichael Pfeiffer 
376efa8b4f3SAxel Dörfler 
377cdb89ebbSMatthew Wilber void
378cdb89ebbSMatthew Wilber ShowImageWindow::WindowRedimension(BBitmap *pbitmap)
37913afa642SPhil Greenway {
380d10d5947SMichael Pfeiffer 	BScreen screen;
381efa8b4f3SAxel Dörfler 	if (screen.IsValid())
382efa8b4f3SAxel Dörfler 		return;
383efa8b4f3SAxel Dörfler 
384d10d5947SMichael Pfeiffer 	BRect r(pbitmap->Bounds());
385d10d5947SMichael Pfeiffer 	const float windowBorderWidth = 5;
386d10d5947SMichael Pfeiffer 	const float windowBorderHeight = 5;
38713afa642SPhil Greenway 
388fc5ca95dSStephan Aßmus 	float width = r.Width() + 2 * PEN_SIZE + B_V_SCROLL_BAR_WIDTH;
389fc5ca95dSStephan Aßmus 	float height = r.Height() + 2 * PEN_SIZE + 1 + fBar->Frame().Height() + B_H_SCROLL_BAR_HEIGHT;
390cdb89ebbSMatthew Wilber 
391d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
392fc5ca95dSStephan Aßmus 	float maxWidth = screen.Frame().Width() + 1 - windowBorderWidth - Frame().left;
393fc5ca95dSStephan Aßmus 	float maxHeight = screen.Frame().Height() + 1 - windowBorderHeight - Frame().top;
394cdb89ebbSMatthew Wilber 
395a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
396a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
397efa8b4f3SAxel Dörfler 
398fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
399a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
400efa8b4f3SAxel Dörfler 	if (maxWidth > maxW)
401efa8b4f3SAxel Dörfler 		maxWidth = maxW;
402efa8b4f3SAxel Dörfler 	if (maxHeight > maxH)
403efa8b4f3SAxel Dörfler 		maxHeight = maxH;
404efa8b4f3SAxel Dörfler 	if (width < minW)
405efa8b4f3SAxel Dörfler 		width = minW;
406efa8b4f3SAxel Dörfler 	if (height < minH)
407efa8b4f3SAxel Dörfler 		height = minH;
408a8fc7138SMichael Pfeiffer 
409efa8b4f3SAxel Dörfler 	if (width > maxWidth)
410efa8b4f3SAxel Dörfler 		width = maxWidth;
411efa8b4f3SAxel Dörfler 	if (height > maxHeight)
412efa8b4f3SAxel Dörfler 		height = maxHeight;
413d10d5947SMichael Pfeiffer 
414d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
41513afa642SPhil Greenway }
41613afa642SPhil Greenway 
417efa8b4f3SAxel Dörfler 
418cdb89ebbSMatthew Wilber void
419cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
42013afa642SPhil Greenway {
42113afa642SPhil Greenway }
42213afa642SPhil Greenway 
423efa8b4f3SAxel Dörfler 
4247eca0987SMichael Pfeiffer bool
4257eca0987SMichael Pfeiffer ShowImageWindow::ToggleMenuItem(uint32 what)
4267eca0987SMichael Pfeiffer {
4277eca0987SMichael Pfeiffer 	BMenuItem *item;
4287eca0987SMichael Pfeiffer 	bool marked = false;
429d3046f7dSMichael Pfeiffer 	item = fBar->FindItem(what);
4307eca0987SMichael Pfeiffer 	if (item != NULL) {
4317eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
4327eca0987SMichael Pfeiffer 		item->SetMarked(marked);
4337eca0987SMichael Pfeiffer 	}
4347eca0987SMichael Pfeiffer 	return marked;
4357eca0987SMichael Pfeiffer }
4367eca0987SMichael Pfeiffer 
437efa8b4f3SAxel Dörfler 
438cdb89ebbSMatthew Wilber void
439da87390fSMichael Pfeiffer ShowImageWindow::EnableMenuItem(BMenu *menu, uint32 what, bool enable)
440e6a50d9cSMichael Pfeiffer {
441e6a50d9cSMichael Pfeiffer 	BMenuItem* item;
442da87390fSMichael Pfeiffer 	item = menu->FindItem(what);
443e6a50d9cSMichael Pfeiffer 	if (item && item->IsEnabled() != enable) {
444e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
445e6a50d9cSMichael Pfeiffer 	}
446e6a50d9cSMichael Pfeiffer }
447e6a50d9cSMichael Pfeiffer 
448efa8b4f3SAxel Dörfler 
449e6a50d9cSMichael Pfeiffer void
450da87390fSMichael Pfeiffer ShowImageWindow::MarkMenuItem(BMenu *menu, uint32 what, bool marked)
451e6a50d9cSMichael Pfeiffer {
452e6a50d9cSMichael Pfeiffer 	BMenuItem* item;
453da87390fSMichael Pfeiffer 	item = menu->FindItem(what);
454e6a50d9cSMichael Pfeiffer 	if (item && item->IsMarked() != marked) {
455e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
456e6a50d9cSMichael Pfeiffer 	}
457e6a50d9cSMichael Pfeiffer }
458e6a50d9cSMichael Pfeiffer 
459efa8b4f3SAxel Dörfler 
460da87390fSMichael Pfeiffer void
461da87390fSMichael Pfeiffer ShowImageWindow::MarkSlideShowDelay(float value)
462da87390fSMichael Pfeiffer {
463d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
464da87390fSMichael Pfeiffer 	float v;
465da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
466d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
467da87390fSMichael Pfeiffer 		if (item) {
468da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
469da87390fSMichael Pfeiffer 				if (!item->IsMarked()) {
470da87390fSMichael Pfeiffer 					item->SetMarked(true);
471da87390fSMichael Pfeiffer 				}
472da87390fSMichael Pfeiffer 				return;
473da87390fSMichael Pfeiffer 			}
474da87390fSMichael Pfeiffer 		}
475da87390fSMichael Pfeiffer 	}
476da87390fSMichael Pfeiffer }
477e6a50d9cSMichael Pfeiffer 
47819c76de4SMichael Pfeiffer 
47919c76de4SMichael Pfeiffer void
48019c76de4SMichael Pfeiffer ShowImageWindow::ResizeToWindow(bool shrink, uint32 what)
48119c76de4SMichael Pfeiffer {
48219c76de4SMichael Pfeiffer 	bool enabled;
48319c76de4SMichael Pfeiffer 	enabled = ToggleMenuItem(what);
48419c76de4SMichael Pfeiffer 	if (shrink) {
485d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
48619c76de4SMichael Pfeiffer 	} else {
487d3046f7dSMichael Pfeiffer 		fImageView->SetZoomToBounds(enabled);
48819c76de4SMichael Pfeiffer 	}
489d3046f7dSMichael Pfeiffer 	enabled = !(fImageView->GetShrinkToBounds() || fImageView->GetZoomToBounds());
490d3046f7dSMichael Pfeiffer 	EnableMenuItem(fBar, MSG_ORIGINAL_SIZE, enabled);
491d3046f7dSMichael Pfeiffer 	EnableMenuItem(fBar, MSG_ZOOM_IN, enabled);
492d3046f7dSMichael Pfeiffer 	EnableMenuItem(fBar, MSG_ZOOM_OUT, enabled);
49319c76de4SMichael Pfeiffer }
49419c76de4SMichael Pfeiffer 
495efa8b4f3SAxel Dörfler 
496e6a50d9cSMichael Pfeiffer void
497efa8b4f3SAxel Dörfler ShowImageWindow::MessageReceived(BMessage *message)
49813afa642SPhil Greenway {
499efa8b4f3SAxel Dörfler 	switch (message->what) {
500ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
501ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
502ee7b4f39SMatthew Wilber 			fModified = true;
503ee7b4f39SMatthew Wilber 			break;
504ee7b4f39SMatthew Wilber 
505fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
506fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
507d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
508cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
509efa8b4f3SAxel Dörfler 				SaveAs(message);
51013afa642SPhil Greenway 			break;
511fc0a275bSMatthew Wilber 
512fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
513fc0a275bSMatthew Wilber 			// User specified where to save the output image
514efa8b4f3SAxel Dörfler 			SaveToFile(message);
51507caaa8eSMatthew Wilber 			break;
51607caaa8eSMatthew Wilber 
517cdb89ebbSMatthew Wilber 		case B_CANCEL:
518d3046f7dSMichael Pfeiffer 			delete fSavePanel;
519d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
520cdb89ebbSMatthew Wilber 			break;
521cdb89ebbSMatthew Wilber 
52203839579SMatthew Wilber 		case MSG_UPDATE_STATUS:
52303839579SMatthew Wilber 		{
5246c305411SMatthew Wilber 			int32 pages, curPage;
525d3046f7dSMichael Pfeiffer 			pages = fImageView->PageCount();
526d3046f7dSMichael Pfeiffer 			curPage = fImageView->CurrentPage();
5276c305411SMatthew Wilber 
5286c305411SMatthew Wilber 			bool benable = (pages > 1) ? true : false;
529d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_FIRST, benable);
530d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_LAST, benable);
531d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_NEXT, benable);
532d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_PREV, benable);
5331d592070SMatthew Wilber 
534134d6076SMichael Pfeiffer 			EnableMenuItem(fBar, MSG_FILE_NEXT, fImageView->HasNextFile());
535134d6076SMichael Pfeiffer 			EnableMenuItem(fBar, MSG_FILE_PREV, fImageView->HasPrevFile());
536134d6076SMichael Pfeiffer 
537d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
5386c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
5396c305411SMatthew Wilber 				// pages is different
5406c305411SMatthew Wilber 
541d3046f7dSMichael Pfeiffer 				while (fGoToPageMenu->CountItems() > 0)
5426c305411SMatthew Wilber 					// Remove all page numbers
543d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
5446c305411SMatthew Wilber 
545780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
5466c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
5476c305411SMatthew Wilber 					BMessage *pgomsg;
548780d8a62SMichael Pfeiffer 					char shortcut = 0;
5496c305411SMatthew Wilber 					pgomsg = new BMessage(MSG_GOTO_PAGE);
5506c305411SMatthew Wilber 					pgomsg->AddInt32("page", i);
5516c305411SMatthew Wilber 					BString strCaption;
5526c305411SMatthew Wilber 					strCaption << i;
553efa8b4f3SAxel Dörfler 					BMenuItem *item;
554780d8a62SMichael Pfeiffer 					if (i < 10) {
555780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
556780d8a62SMichael Pfeiffer 					} else if (i == 10) {
557780d8a62SMichael Pfeiffer 						shortcut = '0';
558780d8a62SMichael Pfeiffer 					}
559efa8b4f3SAxel Dörfler 					item = new BMenuItem(strCaption.String(), pgomsg, shortcut);
5606c305411SMatthew Wilber 					if (curPage == i)
561efa8b4f3SAxel Dörfler 						item->SetMarked(true);
562efa8b4f3SAxel Dörfler 					fGoToPageMenu->AddItem(item);
5636c305411SMatthew Wilber 				}
5646c305411SMatthew Wilber 			} else {
5656c305411SMatthew Wilber 				// Make sure the correct page is marked
5666c305411SMatthew Wilber 				BMenuItem *pcurItem;
567d3046f7dSMichael Pfeiffer 				pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
5686c305411SMatthew Wilber 				if (!pcurItem->IsMarked()) {
5696c305411SMatthew Wilber 					pcurItem->SetMarked(true);
5706c305411SMatthew Wilber 				}
5716c305411SMatthew Wilber 			}
5726c305411SMatthew Wilber 
57316b663b7SMatthew Wilber 			// Disable the Invert menu item if the bitmap color space
57416b663b7SMatthew Wilber 			// is B_CMAP8. (B_CMAP8 is currently unsupported by the
57516b663b7SMatthew Wilber 			// invert algorithm)
57616b663b7SMatthew Wilber 			color_space colors = B_NO_COLOR_SPACE;
577efa8b4f3SAxel Dörfler 			message->FindInt32("colors", reinterpret_cast<int32 *>(&colors));
57816b663b7SMatthew Wilber 			EnableMenuItem(fBar, MSG_INVERT, (colors != B_CMAP8));
57916b663b7SMatthew Wilber 
5800cd4ecd8SStephan Aßmus 			BString status;
5810cd4ecd8SStephan Aßmus 			int32 width, height;
582efa8b4f3SAxel Dörfler 			if (message->FindInt32("width", &width) >= B_OK
583efa8b4f3SAxel Dörfler 				&& message->FindInt32("height", &height) >= B_OK) {
5840cd4ecd8SStephan Aßmus 				status << width << "x" << height << ", ";
5850cd4ecd8SStephan Aßmus 			}
5860cd4ecd8SStephan Aßmus 
58703839579SMatthew Wilber 			BString str;
588efa8b4f3SAxel Dörfler 			if (message->FindString("status", &str) == B_OK) {
5890cd4ecd8SStephan Aßmus 				status << str;
5905eb50e46SMichael Pfeiffer 			}
5910cd4ecd8SStephan Aßmus 
5920cd4ecd8SStephan Aßmus 			fStatusView->SetText(status);
5937eca0987SMichael Pfeiffer 
5947eca0987SMichael Pfeiffer 			UpdateTitle();
59503839579SMatthew Wilber 			break;
59603839579SMatthew Wilber 		}
59703839579SMatthew Wilber 
5988ad30bcfSMatthew Wilber 		case MSG_SELECTION:
5998ad30bcfSMatthew Wilber 		{
6008ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
6018ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
6028ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
6038ad30bcfSMatthew Wilber 			bool benable;
604efa8b4f3SAxel Dörfler 			if (message->FindBool("has_selection", &benable) == B_OK) {
605d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, B_CUT, benable);
606d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, B_COPY, benable);
607d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, MSG_CLEAR_SELECT, benable);
6088ad30bcfSMatthew Wilber 			}
6098ad30bcfSMatthew Wilber 			break;
6108ad30bcfSMatthew Wilber 		}
6118ad30bcfSMatthew Wilber 
6127598450eSMatthew Wilber 		case MSG_UNDO_STATE:
6137598450eSMatthew Wilber 		{
6147598450eSMatthew Wilber 			bool benable;
615efa8b4f3SAxel Dörfler 			if (message->FindBool("can_undo", &benable) == B_OK)
6167598450eSMatthew Wilber 				EnableMenuItem(fBar, B_UNDO, benable);
6177598450eSMatthew Wilber 			break;
6187598450eSMatthew Wilber 		}
6197598450eSMatthew Wilber 
620402c09e5SMatthew Wilber 		case MSG_CLIPBOARD_CHANGED:
621402c09e5SMatthew Wilber 		{
622402c09e5SMatthew Wilber 			// The app sends this message after it examines
623402c09e5SMatthew Wilber 			// the clipboard in response to a B_CLIPBOARD_CHANGED
624402c09e5SMatthew Wilber 			// message
625402c09e5SMatthew Wilber 			bool bdata;
626efa8b4f3SAxel Dörfler 			if (message->FindBool("data_available", &bdata) == B_OK)
627d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, B_PASTE, bdata);
628402c09e5SMatthew Wilber 			break;
629402c09e5SMatthew Wilber 		}
630402c09e5SMatthew Wilber 
63113afa642SPhil Greenway 		case B_UNDO:
6327598450eSMatthew Wilber 			fImageView->Undo();
63313afa642SPhil Greenway 			break;
63413afa642SPhil Greenway 		case B_CUT:
635d3046f7dSMichael Pfeiffer 			fImageView->Cut();
63613afa642SPhil Greenway 			break;
63713afa642SPhil Greenway 		case B_COPY:
638d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
63913afa642SPhil Greenway 			break;
64013afa642SPhil Greenway 		case B_PASTE:
641d3046f7dSMichael Pfeiffer 			fImageView->Paste();
64213afa642SPhil Greenway 			break;
64313afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
644d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
64513afa642SPhil Greenway 			break;
64613afa642SPhil Greenway 		case MSG_SELECT_ALL:
647d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
64813afa642SPhil Greenway 			break;
64913afa642SPhil Greenway 
65003839579SMatthew Wilber 		case MSG_PAGE_FIRST:
651ee7b4f39SMatthew Wilber 			if (ClosePrompt())
652d3046f7dSMichael Pfeiffer 				fImageView->FirstPage();
65303839579SMatthew Wilber 			break;
65403839579SMatthew Wilber 
65503839579SMatthew Wilber 		case MSG_PAGE_LAST:
656ee7b4f39SMatthew Wilber 			if (ClosePrompt())
657d3046f7dSMichael Pfeiffer 				fImageView->LastPage();
65803839579SMatthew Wilber 			break;
65903839579SMatthew Wilber 
66003839579SMatthew Wilber 		case MSG_PAGE_NEXT:
661ee7b4f39SMatthew Wilber 			if (ClosePrompt())
662d3046f7dSMichael Pfeiffer 				fImageView->NextPage();
66303839579SMatthew Wilber 			break;
66403839579SMatthew Wilber 
66503839579SMatthew Wilber 		case MSG_PAGE_PREV:
666ee7b4f39SMatthew Wilber 			if (ClosePrompt())
667d3046f7dSMichael Pfeiffer 				fImageView->PrevPage();
66803839579SMatthew Wilber 			break;
66903839579SMatthew Wilber 
6706c305411SMatthew Wilber 		case MSG_GOTO_PAGE:
6716c305411SMatthew Wilber 		{
672ee7b4f39SMatthew Wilber 			if (!ClosePrompt())
673ee7b4f39SMatthew Wilber 				break;
674ee7b4f39SMatthew Wilber 
6756c305411SMatthew Wilber 			int32 curPage, newPage, pages;
676efa8b4f3SAxel Dörfler 			if (message->FindInt32("page", &newPage) == B_OK) {
677d3046f7dSMichael Pfeiffer 				curPage = fImageView->CurrentPage();
678d3046f7dSMichael Pfeiffer 				pages = fImageView->PageCount();
6796c305411SMatthew Wilber 
6806c305411SMatthew Wilber 				if (newPage > 0 && newPage <= pages) {
6816c305411SMatthew Wilber 					BMenuItem *pcurItem, *pnewItem;
682d3046f7dSMichael Pfeiffer 					pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
683d3046f7dSMichael Pfeiffer 					pnewItem = fGoToPageMenu->ItemAt(newPage - 1);
6846c305411SMatthew Wilber 					if (!pcurItem || !pnewItem)
6856c305411SMatthew Wilber 						break;
6866c305411SMatthew Wilber 					pcurItem->SetMarked(false);
6876c305411SMatthew Wilber 					pnewItem->SetMarked(true);
688d3046f7dSMichael Pfeiffer 					fImageView->GoToPage(newPage);
6896c305411SMatthew Wilber 				}
6906c305411SMatthew Wilber 			}
6916c305411SMatthew Wilber 			break;
692efa8b4f3SAxel Dörfler 		}
6936c305411SMatthew Wilber 
694cdb89ebbSMatthew Wilber 		case MSG_DITHER_IMAGE:
695efa8b4f3SAxel Dörfler 			fImageView->SetDither(ToggleMenuItem(message->what));
6967eca0987SMichael Pfeiffer 			break;
6977eca0987SMichael Pfeiffer 
69819c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
699efa8b4f3SAxel Dörfler 			ResizeToWindow(true, message->what);
70019c76de4SMichael Pfeiffer 			break;
70119c76de4SMichael Pfeiffer 		case MSG_ZOOM_TO_WINDOW:
702efa8b4f3SAxel Dörfler 			ResizeToWindow(false, message->what);
7037eca0987SMichael Pfeiffer 			break;
7047eca0987SMichael Pfeiffer 
7057eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
706ee7b4f39SMatthew Wilber 			if (ClosePrompt())
707d3046f7dSMichael Pfeiffer 				fImageView->PrevFile();
7087eca0987SMichael Pfeiffer 			break;
7097eca0987SMichael Pfeiffer 
7107eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
711ee7b4f39SMatthew Wilber 			if (ClosePrompt())
712d3046f7dSMichael Pfeiffer 				fImageView->NextFile();
71313afa642SPhil Greenway 			break;
71413afa642SPhil Greenway 
715bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
716d3046f7dSMichael Pfeiffer 			fImageView->Rotate(90);
717ad13f387SMichael Pfeiffer 			break;
718bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
719d3046f7dSMichael Pfeiffer 			fImageView->Rotate(270);
720ad13f387SMichael Pfeiffer 			break;
721ad13f387SMichael Pfeiffer 		case MSG_MIRROR_VERTICAL:
722d3046f7dSMichael Pfeiffer 			fImageView->Mirror(true);
723ad13f387SMichael Pfeiffer 			break;
724ad13f387SMichael Pfeiffer 		case MSG_MIRROR_HORIZONTAL:
725d3046f7dSMichael Pfeiffer 			fImageView->Mirror(false);
726ad13f387SMichael Pfeiffer 			break;
727ad13f387SMichael Pfeiffer 		case MSG_INVERT:
728d3046f7dSMichael Pfeiffer 			fImageView->Invert();
729ad13f387SMichael Pfeiffer 			break;
730e6a50d9cSMichael Pfeiffer 		case MSG_SLIDE_SHOW:
731ee7b4f39SMatthew Wilber 		{
732ee7b4f39SMatthew Wilber 			BMenuItem *item;
733efa8b4f3SAxel Dörfler 			item = fBar->FindItem(message->what);
734ee7b4f39SMatthew Wilber 			if (!item)
735ee7b4f39SMatthew Wilber 				break;
736ee7b4f39SMatthew Wilber 			if (item->IsMarked()) {
737ee7b4f39SMatthew Wilber 				item->SetMarked(false);
738d3046f7dSMichael Pfeiffer 				fImageView->StopSlideShow();
739ee7b4f39SMatthew Wilber 			} else if (ClosePrompt()) {
740ee7b4f39SMatthew Wilber 				item->SetMarked(true);
741ee7b4f39SMatthew Wilber 				fImageView->StartSlideShow();
742ad13f387SMichael Pfeiffer 			}
743ee7b4f39SMatthew Wilber 			break;
744efa8b4f3SAxel Dörfler 		}
745ee7b4f39SMatthew Wilber 
746e6a50d9cSMichael Pfeiffer 		case MSG_SLIDE_SHOW_DELAY:
747ad13f387SMichael Pfeiffer 		{
748ad13f387SMichael Pfeiffer 			float value;
749efa8b4f3SAxel Dörfler 			if (message->FindFloat("value", &value) == B_OK) {
750d3046f7dSMichael Pfeiffer 				fImageView->SetSlideShowDelay(value);
751da87390fSMichael Pfeiffer 				// in case message is sent from popup menu
752da87390fSMichael Pfeiffer 				MarkSlideShowDelay(value);
753ad13f387SMichael Pfeiffer 			}
754ad13f387SMichael Pfeiffer 			break;
755efa8b4f3SAxel Dörfler 		}
756ad13f387SMichael Pfeiffer 
757ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
758ad13f387SMichael Pfeiffer 			ToggleFullScreen();
759ad13f387SMichael Pfeiffer 			break;
760fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
761fc5ca95dSStephan Aßmus 			if (fFullScreen)
762fc5ca95dSStephan Aßmus 				ToggleFullScreen();
763fc5ca95dSStephan Aßmus 			break;
764e6a50d9cSMichael Pfeiffer 		case MSG_SHOW_CAPTION:
765efa8b4f3SAxel Dörfler 		{
766efa8b4f3SAxel Dörfler 			fShowCaption = ToggleMenuItem(message->what);
767efa8b4f3SAxel Dörfler 			ShowImageSettings* settings = my_app->Settings();
768efa8b4f3SAxel Dörfler 
769d3046f7dSMichael Pfeiffer 			if (settings->Lock()) {
770d3046f7dSMichael Pfeiffer 				settings->SetBool("ShowCaption", fShowCaption);
771d3046f7dSMichael Pfeiffer 				settings->Unlock();
772d3046f7dSMichael Pfeiffer 			}
773efa8b4f3SAxel Dörfler 			if (fFullScreen)
774d3046f7dSMichael Pfeiffer 				fImageView->SetShowCaption(fShowCaption);
775e6a50d9cSMichael Pfeiffer 			break;
776efa8b4f3SAxel Dörfler 		}
777ad13f387SMichael Pfeiffer 
778780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
779780d8a62SMichael Pfeiffer 			PageSetup();
780780d8a62SMichael Pfeiffer 			break;
781780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
782780d8a62SMichael Pfeiffer 			PrepareForPrint();
783780d8a62SMichael Pfeiffer 			break;
784780d8a62SMichael Pfeiffer 		case MSG_PRINT:
785efa8b4f3SAxel Dörfler 			Print(message);
786780d8a62SMichael Pfeiffer 			break;
787780d8a62SMichael Pfeiffer 
788780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
789d3046f7dSMichael Pfeiffer 			fImageView->ZoomIn();
790780d8a62SMichael Pfeiffer 			break;
791780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
792d3046f7dSMichael Pfeiffer 			fImageView->ZoomOut();
793780d8a62SMichael Pfeiffer 			break;
794780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
795d3046f7dSMichael Pfeiffer 			fImageView->SetZoom(1.0);
796780d8a62SMichael Pfeiffer 			break;
79781b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
798efa8b4f3SAxel Dörfler 			fImageView->SetScaleBilinear(ToggleMenuItem(message->what));
79981b9c776SMichael Pfeiffer 			break;
800780d8a62SMichael Pfeiffer 
801*a60adbf9SAxel Dörfler 		case MSG_DESKTOP_BACKGROUND:
802*a60adbf9SAxel Dörfler 		{
803*a60adbf9SAxel Dörfler 			BPath path;
804*a60adbf9SAxel Dörfler 			if (find_directory(B_DESKTOP_DIRECTORY, &path) == B_OK) {
805*a60adbf9SAxel Dörfler 				BDirectory directory(path.Path());
806*a60adbf9SAxel Dörfler 				if (directory.InitCheck() == B_OK) {
807*a60adbf9SAxel Dörfler 					if (path.SetTo(fImageView->Image()) == B_OK) {
808*a60adbf9SAxel Dörfler 						BackgroundImage::SetDesktopImage(directory, B_CURRENT_WORKSPACE,
809*a60adbf9SAxel Dörfler 							path.Path(), BackgroundImage::kScaledToFit, BPoint(0, 0),
810*a60adbf9SAxel Dörfler 							false);
811*a60adbf9SAxel Dörfler 					}
812*a60adbf9SAxel Dörfler 				}
813*a60adbf9SAxel Dörfler 			}
814*a60adbf9SAxel Dörfler 			break;
815*a60adbf9SAxel Dörfler 		}
816*a60adbf9SAxel Dörfler 
81713afa642SPhil Greenway 		default:
818efa8b4f3SAxel Dörfler 			BWindow::MessageReceived(message);
81913afa642SPhil Greenway 			break;
82013afa642SPhil Greenway 	}
82113afa642SPhil Greenway }
822fc0a275bSMatthew Wilber 
823efa8b4f3SAxel Dörfler 
824fc0a275bSMatthew Wilber void
825efa8b4f3SAxel Dörfler ShowImageWindow::SaveAs(BMessage *message)
826fc0a275bSMatthew Wilber {
827cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
828cdb89ebbSMatthew Wilber 	translator_id outTranslator;
829cdb89ebbSMatthew Wilber 	uint32 outType;
830efa8b4f3SAxel Dörfler 	if (message->FindInt32(TRANSLATOR_FLD,
831efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
832efa8b4f3SAxel Dörfler 		|| message->FindInt32(TYPE_FLD,
833cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
834fc0a275bSMatthew Wilber 		return;
835fc0a275bSMatthew Wilber 
836cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
837cdb89ebbSMatthew Wilber 	// message that the save panel will send back
838*a60adbf9SAxel Dörfler 	BMessage *panelMsg = new BMessage(MSG_SAVE_PANEL);
839*a60adbf9SAxel Dörfler 	panelMsg->AddInt32(TRANSLATOR_FLD, outTranslator);
840*a60adbf9SAxel Dörfler 	panelMsg->AddInt32(TYPE_FLD, outType);
841cdb89ebbSMatthew Wilber 
842cdb89ebbSMatthew Wilber 	// Create save panel and show it
843efa8b4f3SAxel Dörfler 	fSavePanel = new (std::nothrow) BFilePanel(B_SAVE_PANEL,
844*a60adbf9SAxel Dörfler 		new BMessenger(this), NULL, 0, false, panelMsg);
845d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
846fc0a275bSMatthew Wilber 		return;
847*a60adbf9SAxel Dörfler 
848d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
849d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
850fc0a275bSMatthew Wilber }
851fc0a275bSMatthew Wilber 
852efa8b4f3SAxel Dörfler 
853fc0a275bSMatthew Wilber void
854efa8b4f3SAxel Dörfler ShowImageWindow::SaveToFile(BMessage *message)
855fc0a275bSMatthew Wilber {
856cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
857efa8b4f3SAxel Dörfler 	entry_ref dirRef;
858efa8b4f3SAxel Dörfler 	if (message->FindRef("directory", &dirRef) != B_OK)
859fc0a275bSMatthew Wilber 		return;
860efa8b4f3SAxel Dörfler 
861fc0a275bSMatthew Wilber 	const char *filename;
862efa8b4f3SAxel Dörfler 	if (message->FindString("name", &filename) != B_OK)
863fc0a275bSMatthew Wilber 		return;
864fc0a275bSMatthew Wilber 
865cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
866cdb89ebbSMatthew Wilber 	// to save the output image
867cdb89ebbSMatthew Wilber 	translator_id outTranslator;
868cdb89ebbSMatthew Wilber 	uint32 outType;
869efa8b4f3SAxel Dörfler 	if (message->FindInt32(TRANSLATOR_FLD,
870efa8b4f3SAxel Dörfler 			reinterpret_cast<int32 *>(&outTranslator)) != B_OK
871efa8b4f3SAxel Dörfler 		|| message->FindInt32(TYPE_FLD,
872cdb89ebbSMatthew Wilber 			reinterpret_cast<int32 *>(&outType)) != B_OK)
873cdb89ebbSMatthew Wilber 		return;
874cdb89ebbSMatthew Wilber 
875a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
876a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
877a7e78e3bSMatthew Wilber 	BTranslatorRoster *roster = BTranslatorRoster::Default();
878efa8b4f3SAxel Dörfler 	const translation_format *outFormat = NULL;
879efa8b4f3SAxel Dörfler 	int32 outCount = 0;
880efa8b4f3SAxel Dörfler 	if (roster->GetOutputFormats(outTranslator, &outFormat, &outCount) != B_OK
881efa8b4f3SAxel Dörfler 		|| outCount < 1)
882a7e78e3bSMatthew Wilber 		return;
883efa8b4f3SAxel Dörfler 
884a7e78e3bSMatthew Wilber 	int32 i;
885efa8b4f3SAxel Dörfler 	for (i = 0; i < outCount; i++) {
886efa8b4f3SAxel Dörfler 		if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
887a7e78e3bSMatthew Wilber 			break;
888a7e78e3bSMatthew Wilber 	}
889efa8b4f3SAxel Dörfler 	if (i == outCount)
890fc0a275bSMatthew Wilber 		return;
891fc0a275bSMatthew Wilber 
892a7e78e3bSMatthew Wilber 	// Write out the image file
893efa8b4f3SAxel Dörfler 	BDirectory dir(&dirRef);
894efa8b4f3SAxel Dörfler 	fImageView->SaveToFile(&dir, filename, NULL, &outFormat[i]);
895fc0a275bSMatthew Wilber }
896fc0a275bSMatthew Wilber 
897efa8b4f3SAxel Dörfler 
898cdb89ebbSMatthew Wilber bool
899ee7b4f39SMatthew Wilber ShowImageWindow::ClosePrompt()
900ee7b4f39SMatthew Wilber {
901ee7b4f39SMatthew Wilber 	if (!fModified)
902ee7b4f39SMatthew Wilber 		return true;
903efa8b4f3SAxel Dörfler 
904ee7b4f39SMatthew Wilber 	int32 page, count;
905ee7b4f39SMatthew Wilber 	count = fImageView->PageCount();
906ee7b4f39SMatthew Wilber 	page = fImageView->CurrentPage();
907ee7b4f39SMatthew Wilber 	BString prompt, name;
908ee7b4f39SMatthew Wilber 	fImageView->GetName(&name);
909ee7b4f39SMatthew Wilber 	prompt << "The document '" << name << "'";
910ee7b4f39SMatthew Wilber 	if (count > 1)
911ee7b4f39SMatthew Wilber 		prompt << " (page " << page << ")";
912efa8b4f3SAxel Dörfler 
913ee7b4f39SMatthew Wilber 	prompt << " has been changed. "
914ee7b4f39SMatthew Wilber 	       << "Do you want to close the document?";
915ee7b4f39SMatthew Wilber 	BAlert *pAlert = new BAlert("Close document", prompt.String(),
916ee7b4f39SMatthew Wilber 		"Cancel", "Close");
917efa8b4f3SAxel Dörfler 	if (pAlert->Go() == 0) {
918ee7b4f39SMatthew Wilber 		// Cancel
919ee7b4f39SMatthew Wilber 		return false;
920efa8b4f3SAxel Dörfler 	} else {
921ee7b4f39SMatthew Wilber 		// Close
922187f0b8aSMatthew Wilber 		fModified = false;
923ee7b4f39SMatthew Wilber 		return true;
924ee7b4f39SMatthew Wilber 	}
925ee7b4f39SMatthew Wilber }
926ee7b4f39SMatthew Wilber 
927cdb89ebbSMatthew Wilber 
928ad13f387SMichael Pfeiffer void
929ad13f387SMichael Pfeiffer ShowImageWindow::ToggleFullScreen()
930ad13f387SMichael Pfeiffer {
931ad13f387SMichael Pfeiffer 	BRect frame;
932ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
933ad13f387SMichael Pfeiffer 	if (fFullScreen) {
934ad13f387SMichael Pfeiffer 		BScreen screen;
935ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
936ad13f387SMichael Pfeiffer 		frame = screen.Frame();
937d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
938ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
939ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
940ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
941ad13f387SMichael Pfeiffer 
942ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
943d3046f7dSMichael Pfeiffer 		fImageView->SetAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE);
944ad13f387SMichael Pfeiffer 	} else {
945ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
946ad13f387SMichael Pfeiffer 
947ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
948fc5ca95dSStephan Aßmus // NOTE: I changed this to not use left/top alignment at all, because
949fc5ca95dSStephan Aßmus // I have no idea why it would be useful. The layouting is much more
950fc5ca95dSStephan Aßmus // predictable now. -Stephan
951fc5ca95dSStephan Aßmus //		fImageView->SetAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
952fc5ca95dSStephan Aßmus 		fImageView->SetAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE);
953ad13f387SMichael Pfeiffer 	}
954efa8b4f3SAxel Dörfler 
955d3046f7dSMichael Pfeiffer 	fImageView->SetBorder(!fFullScreen);
956d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
957ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
958ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
959ad13f387SMichael Pfeiffer }
960ad13f387SMichael Pfeiffer 
961efa8b4f3SAxel Dörfler 
962d3046f7dSMichael Pfeiffer void
963d3046f7dSMichael Pfeiffer ShowImageWindow::LoadSettings()
964d3046f7dSMichael Pfeiffer {
965efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
966efa8b4f3SAxel Dörfler 
967d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
968d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
969d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
970d3046f7dSMichael Pfeiffer 
971efa8b4f3SAxel Dörfler 		int32 op = settings->GetInt32("PO:Option", fPrintOptions.Option());
972d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
973d3046f7dSMichael Pfeiffer 
974efa8b4f3SAxel Dörfler 		float f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
975d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
976d3046f7dSMichael Pfeiffer 
977d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
978d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
979d3046f7dSMichael Pfeiffer 
980d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
981d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
982d3046f7dSMichael Pfeiffer 
983d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
984d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
985d3046f7dSMichael Pfeiffer 
986d3046f7dSMichael Pfeiffer 		settings->Unlock();
987d3046f7dSMichael Pfeiffer 	}
988d3046f7dSMichael Pfeiffer }
989d3046f7dSMichael Pfeiffer 
990efa8b4f3SAxel Dörfler 
991d3046f7dSMichael Pfeiffer void
992d3046f7dSMichael Pfeiffer ShowImageWindow::SavePrintOptions()
993d3046f7dSMichael Pfeiffer {
994efa8b4f3SAxel Dörfler 	ShowImageSettings* settings = my_app->Settings();
995efa8b4f3SAxel Dörfler 
996d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
997d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
998d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
999d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
1000d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
1001d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
1002d3046f7dSMichael Pfeiffer 		settings->Unlock();
1003d3046f7dSMichael Pfeiffer 	}
1004d3046f7dSMichael Pfeiffer }
1005d3046f7dSMichael Pfeiffer 
1006efa8b4f3SAxel Dörfler 
1007cdb89ebbSMatthew Wilber bool
1008780d8a62SMichael Pfeiffer ShowImageWindow::PageSetup()
1009780d8a62SMichael Pfeiffer {
1010780d8a62SMichael Pfeiffer 	status_t st;
1011780d8a62SMichael Pfeiffer 	BString name;
1012d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
1013780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
1014efa8b4f3SAxel Dörfler 	if (fPrintSettings != NULL)
1015780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
1016efa8b4f3SAxel Dörfler 
1017780d8a62SMichael Pfeiffer 	st = printJob.ConfigPage();
1018780d8a62SMichael Pfeiffer 	if (st == B_OK) {
1019780d8a62SMichael Pfeiffer 		delete fPrintSettings;
1020780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
1021780d8a62SMichael Pfeiffer 	}
1022efa8b4f3SAxel Dörfler 
1023780d8a62SMichael Pfeiffer 	return st == B_OK;
1024780d8a62SMichael Pfeiffer }
1025780d8a62SMichael Pfeiffer 
1026efa8b4f3SAxel Dörfler 
1027780d8a62SMichael Pfeiffer void
1028780d8a62SMichael Pfeiffer ShowImageWindow::PrepareForPrint()
1029780d8a62SMichael Pfeiffer {
1030efa8b4f3SAxel Dörfler 	if (fPrintSettings == NULL && !PageSetup())
1031780d8a62SMichael Pfeiffer 		return;
1032780d8a62SMichael Pfeiffer 
1033d3046f7dSMichael Pfeiffer 	fPrintOptions.SetBounds(fImageView->GetBitmap()->Bounds());
1034d3046f7dSMichael Pfeiffer 	fPrintOptions.SetWidth(fImageView->GetBitmap()->Bounds().Width()+1);
1035780d8a62SMichael Pfeiffer 
1036efa8b4f3SAxel Dörfler 	new PrintOptionsWindow(BPoint(Frame().left+30, Frame().top+50),
1037efa8b4f3SAxel Dörfler 		&fPrintOptions, this);
1038780d8a62SMichael Pfeiffer }
1039780d8a62SMichael Pfeiffer 
1040efa8b4f3SAxel Dörfler 
1041780d8a62SMichael Pfeiffer void
1042780d8a62SMichael Pfeiffer ShowImageWindow::Print(BMessage *msg)
1043780d8a62SMichael Pfeiffer {
1044780d8a62SMichael Pfeiffer 	status_t st;
1045efa8b4f3SAxel Dörfler 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK)
1046780d8a62SMichael Pfeiffer 		return;
1047780d8a62SMichael Pfeiffer 
1048d3046f7dSMichael Pfeiffer 	SavePrintOptions();
1049d3046f7dSMichael Pfeiffer 
1050780d8a62SMichael Pfeiffer 	BString name;
1051d3046f7dSMichael Pfeiffer 	fPrintOptions.SetBounds(fImageView->GetBitmap()->Bounds());
1052d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
1053780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
1054780d8a62SMichael Pfeiffer 	printJob.SetSettings(new BMessage(*fPrintSettings));
1055780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
1056780d8a62SMichael Pfeiffer 		int32 firstPage;
1057780d8a62SMichael Pfeiffer 		int32 lastPage;
1058780d8a62SMichael Pfeiffer 		BRect printableRect = printJob.PrintableRect();
1059780d8a62SMichael Pfeiffer 		float width, imageWidth, imageHeight, w1, w2;
1060780d8a62SMichael Pfeiffer 		BBitmap* bitmap;
1061780d8a62SMichael Pfeiffer 
1062780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
1063780d8a62SMichael Pfeiffer 		firstPage = printJob.FirstPage();
1064780d8a62SMichael Pfeiffer 		lastPage = printJob.LastPage();
1065efa8b4f3SAxel Dörfler 		if (firstPage < 1)
1066780d8a62SMichael Pfeiffer 			firstPage = 1;
1067efa8b4f3SAxel Dörfler 		if (lastPage < firstPage)
1068780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1069780d8a62SMichael Pfeiffer 
1070d3046f7dSMichael Pfeiffer 		bitmap = fImageView->GetBitmap();
1071780d8a62SMichael Pfeiffer 		imageWidth = bitmap->Bounds().Width() + 1.0;
1072780d8a62SMichael Pfeiffer 		imageHeight = bitmap->Bounds().Height() + 1.0;
1073780d8a62SMichael Pfeiffer 
1074780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
1075780d8a62SMichael Pfeiffer 			case PrintOptions::kFitToPage:
1076780d8a62SMichael Pfeiffer 				w1 = printableRect.Width()+1;
1077780d8a62SMichael Pfeiffer 				w2 = imageWidth * (printableRect.Height() + 1) / imageHeight;
1078efa8b4f3SAxel Dörfler 				if (w2 < w1)
1079780d8a62SMichael Pfeiffer 					width = w2;
1080efa8b4f3SAxel Dörfler 				else
1081780d8a62SMichael Pfeiffer 					width = w1;
1082780d8a62SMichael Pfeiffer 				break;
1083780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1084780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1085780d8a62SMichael Pfeiffer 				break;
1086780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1087780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1088780d8a62SMichael Pfeiffer 				break;
1089780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1090780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1091780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1092780d8a62SMichael Pfeiffer 				break;
1093efa8b4f3SAxel Dörfler 
1094780d8a62SMichael Pfeiffer 			default:
1095780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1096780d8a62SMichael Pfeiffer 				width = imageWidth;
1097780d8a62SMichael Pfeiffer 		}
1098780d8a62SMichael Pfeiffer 
1099efa8b4f3SAxel Dörfler 		// TODO: eventually print large images on several pages
1100780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1101d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
11025eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
11035eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
11045eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1105d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1106780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1107780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1108780d8a62SMichael Pfeiffer 	}
1109780d8a62SMichael Pfeiffer }
1110780d8a62SMichael Pfeiffer 
1111efa8b4f3SAxel Dörfler 
1112780d8a62SMichael Pfeiffer bool
1113cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1114cdb89ebbSMatthew Wilber {
1115efa8b4f3SAxel Dörfler 	if (fSavePanel) {
1116efa8b4f3SAxel Dörfler 		// Don't allow this window to be closed if a save panel is open
1117efa8b4f3SAxel Dörfler 		return false;
1118cdb89ebbSMatthew Wilber 	}
1119cdb89ebbSMatthew Wilber 
1120efa8b4f3SAxel Dörfler 	bool quit = ClosePrompt();
1121efa8b4f3SAxel Dörfler 
1122efa8b4f3SAxel Dörfler 	if (quit) {
112307caaa8eSMatthew Wilber 		// tell the app to forget about this window
112407caaa8eSMatthew Wilber 		be_app->PostMessage(MSG_WINDOW_QUIT);
112507caaa8eSMatthew Wilber 	}
1126fc0a275bSMatthew Wilber 
1127efa8b4f3SAxel Dörfler 	return quit;
1128efa8b4f3SAxel Dörfler }
1129efa8b4f3SAxel Dörfler 
1130efa8b4f3SAxel Dörfler 
1131fc5ca95dSStephan Aßmus void
1132fc5ca95dSStephan Aßmus ShowImageWindow::Zoom(BPoint origin, float width, float height)
1133fc5ca95dSStephan Aßmus {
1134fc5ca95dSStephan Aßmus 	// just go into fullscreen
1135fc5ca95dSStephan Aßmus 	ToggleFullScreen();
1136fc5ca95dSStephan Aßmus }
1137fc5ca95dSStephan Aßmus 
1138