xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision 758b1d0e05fe1042cce6e00d194a147802d4f9be)
1cdb89ebbSMatthew Wilber /*****************************************************************************/
2cdb89ebbSMatthew Wilber // ShowImageWindow
3ad13f387SMichael Pfeiffer // Written by Fernando Francisco de Oliveira, Michael Wilber, Michael Pfeiffer
4cdb89ebbSMatthew Wilber //
5cdb89ebbSMatthew Wilber // ShowImageWindow.cpp
6cdb89ebbSMatthew Wilber //
7cdb89ebbSMatthew Wilber //
8cdb89ebbSMatthew Wilber // Copyright (c) 2003 OpenBeOS Project
9cdb89ebbSMatthew Wilber //
10cdb89ebbSMatthew Wilber // Permission is hereby granted, free of charge, to any person obtaining a
11cdb89ebbSMatthew Wilber // copy of this software and associated documentation files (the "Software"),
12cdb89ebbSMatthew Wilber // to deal in the Software without restriction, including without limitation
13cdb89ebbSMatthew Wilber // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14cdb89ebbSMatthew Wilber // and/or sell copies of the Software, and to permit persons to whom the
15cdb89ebbSMatthew Wilber // Software is furnished to do so, subject to the following conditions:
16cdb89ebbSMatthew Wilber //
17cdb89ebbSMatthew Wilber // The above copyright notice and this permission notice shall be included
18cdb89ebbSMatthew Wilber // in all copies or substantial portions of the Software.
19cdb89ebbSMatthew Wilber //
20cdb89ebbSMatthew Wilber // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21cdb89ebbSMatthew Wilber // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22cdb89ebbSMatthew Wilber // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23cdb89ebbSMatthew Wilber // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24cdb89ebbSMatthew Wilber // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25cdb89ebbSMatthew Wilber // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26cdb89ebbSMatthew Wilber // DEALINGS IN THE SOFTWARE.
27cdb89ebbSMatthew Wilber /*****************************************************************************/
2813afa642SPhil Greenway 
2907caaa8eSMatthew Wilber #include <stdio.h>
3013afa642SPhil Greenway #include <Application.h>
3113afa642SPhil Greenway #include <Bitmap.h>
32fc0a275bSMatthew Wilber #include <BitmapStream.h>
3313afa642SPhil Greenway #include <Entry.h>
34fc0a275bSMatthew Wilber #include <File.h>
3513afa642SPhil Greenway #include <Menu.h>
3613afa642SPhil Greenway #include <MenuBar.h>
3713afa642SPhil Greenway #include <MenuItem.h>
3813afa642SPhil Greenway #include <Path.h>
3913afa642SPhil Greenway #include <ScrollView.h>
4013afa642SPhil Greenway #include <TranslationUtils.h>
4113afa642SPhil Greenway #include <TranslatorRoster.h>
4213afa642SPhil Greenway #include <Alert.h>
4307caaa8eSMatthew Wilber #include <SupportDefs.h>
44ad13f387SMichael Pfeiffer #include <Screen.h>
45d10d5947SMichael Pfeiffer #include <Roster.h>
46780d8a62SMichael Pfeiffer #include <PrintJob.h>
47c60a8d8cSPhilippe Houdoin #include <Clipboard.h>
4813afa642SPhil Greenway 
49d3046f7dSMichael Pfeiffer #include "ShowImageApp.h"
5013afa642SPhil Greenway #include "ShowImageConstants.h"
5113afa642SPhil Greenway #include "ShowImageWindow.h"
5213afa642SPhil Greenway #include "ShowImageView.h"
5313afa642SPhil Greenway #include "ShowImageStatusView.h"
547c0bc4a2SMichael Pfeiffer #include "EntryMenuItem.h"
5513afa642SPhil Greenway 
56a8fc7138SMichael Pfeiffer 
57a8fc7138SMichael Pfeiffer // Implementation of RecentDocumentsMenu
58a8fc7138SMichael Pfeiffer 
59*758b1d0eSIngo Weinhold RecentDocumentsMenu::RecentDocumentsMenu(const char *title, menu_layout layout)
60a8fc7138SMichael Pfeiffer 	: BMenu(title, layout)
61a8fc7138SMichael Pfeiffer {
62a8fc7138SMichael Pfeiffer }
63a8fc7138SMichael Pfeiffer 
64a8fc7138SMichael Pfeiffer bool
65a8fc7138SMichael Pfeiffer RecentDocumentsMenu::AddDynamicItem(add_state s)
66a8fc7138SMichael Pfeiffer {
67a8fc7138SMichael Pfeiffer 	if (s != B_INITIAL_ADD) return false;
68a8fc7138SMichael Pfeiffer 
69a8fc7138SMichael Pfeiffer 	BMenuItem *item;
70a8fc7138SMichael Pfeiffer 	BMessage list, *msg;
71a8fc7138SMichael Pfeiffer 	entry_ref ref;
72a8fc7138SMichael Pfeiffer 	char name[B_FILE_NAME_LENGTH];
73a8fc7138SMichael Pfeiffer 
74a8fc7138SMichael Pfeiffer 	while ((item = RemoveItem((int32)0)) != NULL) {
75a8fc7138SMichael Pfeiffer 		delete item;
76a8fc7138SMichael Pfeiffer 	}
77a8fc7138SMichael Pfeiffer 
78a8fc7138SMichael Pfeiffer 	be_roster->GetRecentDocuments(&list, 20, NULL, APP_SIG);
79a8fc7138SMichael Pfeiffer 	for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
80a8fc7138SMichael Pfeiffer 		BEntry entry(&ref);
81a8fc7138SMichael Pfeiffer 		if (entry.Exists() && entry.GetName(name) == B_OK) {
82a8fc7138SMichael Pfeiffer 			msg = new BMessage(B_REFS_RECEIVED);
83a8fc7138SMichael Pfeiffer 			msg->AddRef("refs", &ref);
84a8fc7138SMichael Pfeiffer 			item =  new EntryMenuItem(&ref, name, msg, 0, 0);
85a8fc7138SMichael Pfeiffer 			AddItem(item);
86a8fc7138SMichael Pfeiffer 			item->SetTarget(be_app, NULL);
87a8fc7138SMichael Pfeiffer 		}
88a8fc7138SMichael Pfeiffer 	}
89a8fc7138SMichael Pfeiffer 
90a8fc7138SMichael Pfeiffer 	return false;
91a8fc7138SMichael Pfeiffer }
92a8fc7138SMichael Pfeiffer 
93a8fc7138SMichael Pfeiffer 
94a8fc7138SMichael Pfeiffer // Implementation of ShowImageWindow
95a8fc7138SMichael Pfeiffer 
96134d6076SMichael Pfeiffer ShowImageWindow::ShowImageWindow(const entry_ref *pref, const BMessenger& trackerMessenger)
971de41298SMatthew Wilber 	: BWindow(BRect(5, 24, 250, 100), "", B_DOCUMENT_WINDOW, 0)
9813afa642SPhil Greenway {
99d3046f7dSMichael Pfeiffer 	fSavePanel = NULL;
100ee7b4f39SMatthew Wilber 	fModified = false;
101ad13f387SMichael Pfeiffer 	fFullScreen = false;
102d3046f7dSMichael Pfeiffer 	fShowCaption = true;
103780d8a62SMichael Pfeiffer 	fPrintSettings = NULL;
104d3046f7dSMichael Pfeiffer 	fImageView = NULL;
105d3046f7dSMichael Pfeiffer 	fSlideShowDelay = NULL;
106d3046f7dSMichael Pfeiffer 
107d3046f7dSMichael Pfeiffer 	LoadSettings();
108fc0a275bSMatthew Wilber 
10913afa642SPhil Greenway 	// create menu bar
110e9dcd874SAxel Dörfler 	fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar");
111d3046f7dSMichael Pfeiffer 	LoadMenus(fBar);
112e9dcd874SAxel Dörfler 	AddChild(fBar);
11313afa642SPhil Greenway 
11413afa642SPhil Greenway 	BRect viewFrame = Bounds();
115e9dcd874SAxel Dörfler 	viewFrame.top = fBar->Bounds().Height() + 1;
11613afa642SPhil Greenway 	viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
11713afa642SPhil Greenway 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
11813afa642SPhil Greenway 
11913afa642SPhil Greenway 	// create the image view
120d3046f7dSMichael Pfeiffer 	fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
1217eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
12213afa642SPhil Greenway 	// wrap a scroll view around the view
123d3046f7dSMichael Pfeiffer 	BScrollView *pscrollView = new BScrollView("image_scroller", fImageView,
124cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
125cdb89ebbSMatthew Wilber 	AddChild(pscrollView);
12613afa642SPhil Greenway 
12707caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
128cdb89ebbSMatthew Wilber 	BRect rect;
12913afa642SPhil Greenway 	rect = Bounds();
13013afa642SPhil Greenway 	rect.top	= viewFrame.bottom + 1;
13107caaa8eSMatthew Wilber 	rect.left 	= viewFrame.left + kstatusWidth;
1320916ab53SMatthew Wilber 	rect.right	= viewFrame.right + 1;
1330916ab53SMatthew Wilber 	rect.bottom += 1;
134cdb89ebbSMatthew Wilber 	BScrollBar *phscroll;
135d3046f7dSMichael Pfeiffer 	phscroll = new BScrollBar(rect, "hscroll", fImageView, 0, 150,
136cdb89ebbSMatthew Wilber 		B_HORIZONTAL);
137cdb89ebbSMatthew Wilber 	AddChild(phscroll);
13813afa642SPhil Greenway 
13913afa642SPhil Greenway 	rect.left = 0;
14007caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
1410cd4ecd8SStephan Aßmus 	rect.bottom -= 1;
142d3046f7dSMichael Pfeiffer 	fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
143cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
144d3046f7dSMichael Pfeiffer 	AddChild(fStatusView);
14513afa642SPhil Greenway 
14613afa642SPhil Greenway 	rect = Bounds();
1470916ab53SMatthew Wilber 	rect.top    = viewFrame.top - 1;
14813afa642SPhil Greenway 	rect.left 	= viewFrame.right + 1;
1490916ab53SMatthew Wilber 	rect.bottom	= viewFrame.bottom + 1;
1500916ab53SMatthew Wilber 	rect.right	+= 1;
151cdb89ebbSMatthew Wilber 	BScrollBar *pvscroll;
152d3046f7dSMichael Pfeiffer 	pvscroll = new BScrollBar(rect, "vscroll", fImageView, 0, 150, B_VERTICAL);
153cdb89ebbSMatthew Wilber 	AddChild(pvscroll);
15413afa642SPhil Greenway 
15503839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
15613afa642SPhil Greenway 
157134d6076SMichael Pfeiffer 	// finish creating the window
158d3046f7dSMichael Pfeiffer 	fImageView->SetImage(pref);
159134d6076SMichael Pfeiffer 	fImageView->SetTrackerMessenger(trackerMessenger);
1607eca0987SMichael Pfeiffer 
161780d8a62SMichael Pfeiffer 	if (InitCheck() == B_OK) {
162d3046f7dSMichael Pfeiffer 		// add View menu here so it can access ShowImageView methods
163d3046f7dSMichael Pfeiffer 		BMenu* pmenu = new BMenu("View");
164d3046f7dSMichael Pfeiffer 		BuildViewMenu(pmenu);
165d3046f7dSMichael Pfeiffer 		fBar->AddItem(pmenu);
166a8fc7138SMichael Pfeiffer 		MarkMenuItem(fBar, MSG_DITHER_IMAGE, fImageView->GetDither());
167780d8a62SMichael Pfeiffer 		UpdateTitle();
168780d8a62SMichael Pfeiffer 
1697eca0987SMichael Pfeiffer 		SetPulseRate(100000); // every 1/10 second; ShowImageView needs it for marching ants
17003839579SMatthew Wilber 
171d3046f7dSMichael Pfeiffer 		fImageView->FlushToLeftTop();
172d3046f7dSMichael Pfeiffer 		WindowRedimension(fImageView->GetBitmap());
173d3046f7dSMichael Pfeiffer 		fImageView->MakeFocus(true); // to receive KeyDown messages
17413afa642SPhil Greenway 		Show();
175d10d5947SMichael Pfeiffer 	} else {
176e6a50d9cSMichael Pfeiffer 		BAlert* alert;
177e6a50d9cSMichael Pfeiffer 		alert = new BAlert("ShowImage",
178e6a50d9cSMichael Pfeiffer 			"Could not load image! Either the file or an image translator for it does not exist.",
179e6a50d9cSMichael Pfeiffer 			"OK", NULL, NULL,
180e6a50d9cSMichael Pfeiffer 			B_WIDTH_AS_USUAL, B_INFO_ALERT);
181e6a50d9cSMichael Pfeiffer 		alert->Go();
182d10d5947SMichael Pfeiffer 		// exit if file could not be opened
183d10d5947SMichael Pfeiffer 		Quit();
184d10d5947SMichael Pfeiffer 	}
185402c09e5SMatthew Wilber 
186402c09e5SMatthew Wilber 	// Tell application object to query the clipboard
187402c09e5SMatthew Wilber 	// and tell this window if it contains interesting data or not
188402c09e5SMatthew Wilber 	be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
18913afa642SPhil Greenway }
19013afa642SPhil Greenway 
19113afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
19213afa642SPhil Greenway {
19313afa642SPhil Greenway }
19413afa642SPhil Greenway 
195cdb89ebbSMatthew Wilber status_t
196cdb89ebbSMatthew Wilber ShowImageWindow::InitCheck()
19713afa642SPhil Greenway {
198d3046f7dSMichael Pfeiffer 	if (!fImageView || fImageView->GetBitmap() == NULL)
19913afa642SPhil Greenway 		return B_ERROR;
200cdb89ebbSMatthew Wilber 	else
20113afa642SPhil Greenway 		return B_OK;
20213afa642SPhil Greenway }
203cdb89ebbSMatthew Wilber 
204cdb89ebbSMatthew Wilber void
205cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
20613afa642SPhil Greenway {
207e6a50d9cSMichael Pfeiffer 	BString path;
208d3046f7dSMichael Pfeiffer 	fImageView->GetPath(&path);
209e6a50d9cSMichael Pfeiffer 	SetTitle(path.String());
21013afa642SPhil Greenway }
21113afa642SPhil Greenway 
212cdb89ebbSMatthew Wilber void
213da87390fSMichael Pfeiffer ShowImageWindow::BuildViewMenu(BMenu *pmenu)
214da87390fSMichael Pfeiffer {
215da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, 'W', true);
216d3046f7dSMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
217da87390fSMichael Pfeiffer 	BMenu* pDelay = new BMenu("Slide Delay");
218d3046f7dSMichael Pfeiffer 	if (fSlideShowDelay == NULL) {
219d3046f7dSMichael Pfeiffer 		fSlideShowDelay = pDelay;
220da87390fSMichael Pfeiffer 	}
221da87390fSMichael Pfeiffer 	pDelay->SetRadioMode(true);
222da87390fSMichael Pfeiffer 	// Note: ShowImage loades images in window thread so it becomes unresponsive if
223da87390fSMichael Pfeiffer 	// slide show delay is too short! (Especially if loading the image takes as long as
224da87390fSMichael Pfeiffer 	// or longer than the slide show delay). Should load in background thread!
225d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Three Seconds", 3);
226d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Four Second", 4);
227d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Five Seconds", 5);
228d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Six Seconds", 6);
229d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Seven Seconds", 7);
230d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Eight Seconds", 8);
231d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Nine Seconds", 9);
232d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Ten Seconds", 10);
233d3046f7dSMichael Pfeiffer 	AddDelayItem(pDelay, "Twenty Seconds", 20);
234da87390fSMichael Pfeiffer 	pmenu->AddItem(pDelay);
235da87390fSMichael Pfeiffer 	pmenu->AddSeparatorItem();
236da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Original Size", MSG_ORIGINAL_SIZE, 0, 0, 'W', true);
237da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Zoom In", MSG_ZOOM_IN, '+', 0, 'W', true);
238da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Zoom Out", MSG_ZOOM_OUT, '-', 0, 'W', true);
239d3046f7dSMichael Pfeiffer 	pmenu->AddSeparatorItem();
24081b9c776SMichael Pfeiffer 	AddItemMenu(pmenu, "Scale Bilinear", MSG_SCALE_BILINEAR, 0, 0, 'W', true);
241da87390fSMichael Pfeiffer 	pmenu->AddSeparatorItem();
24219c76de4SMichael Pfeiffer 	AddItemMenu(pmenu, "Shrink to Window", MSG_SHRINK_TO_WINDOW, 0, 0, 'W', true);
24319c76de4SMichael Pfeiffer 	AddItemMenu(pmenu, "Zoom to Window", MSG_ZOOM_TO_WINDOW, 0, 0, 'W', true);
244d3046f7dSMichael Pfeiffer 	pmenu->AddSeparatorItem();
24530060f17SMatthew Wilber 	AddItemMenu(pmenu, "Full Screen", MSG_FULL_SCREEN, 'F', 0, 'W', true);
24681b9c776SMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_FULL_SCREEN, fFullScreen);
24730060f17SMatthew Wilber 	BMessage *pFullScreen = new BMessage(MSG_FULL_SCREEN);
24830060f17SMatthew Wilber 	AddShortcut(B_ENTER, 0, pFullScreen);
24930060f17SMatthew Wilber 
250da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Show Caption in Full Screen Mode", MSG_SHOW_CAPTION, 0, 0, 'W', true);
251da87390fSMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_SHOW_CAPTION, fShowCaption);
252da87390fSMichael Pfeiffer 
25319c76de4SMichael Pfeiffer 	bool shrink, zoom, enabled;
254d3046f7dSMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear());
255d3046f7dSMichael Pfeiffer 	shrink = fImageView->GetShrinkToBounds();
256d3046f7dSMichael Pfeiffer 	zoom = fImageView->GetZoomToBounds();
25719c76de4SMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_SHRINK_TO_WINDOW, shrink);
25819c76de4SMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_ZOOM_TO_WINDOW, zoom);
25919c76de4SMichael Pfeiffer  	enabled = !(shrink || zoom);
26019c76de4SMichael Pfeiffer 	EnableMenuItem(pmenu, MSG_ORIGINAL_SIZE, enabled);
26119c76de4SMichael Pfeiffer 	EnableMenuItem(pmenu, MSG_ZOOM_IN, enabled);
26219c76de4SMichael Pfeiffer 	EnableMenuItem(pmenu, MSG_ZOOM_OUT, enabled);
263da87390fSMichael Pfeiffer }
264da87390fSMichael Pfeiffer 
265da87390fSMichael Pfeiffer void
266cdb89ebbSMatthew Wilber ShowImageWindow::LoadMenus(BMenuBar *pbar)
26713afa642SPhil Greenway {
268cdb89ebbSMatthew Wilber 	BMenu *pmenu = new BMenu("File");
269a8fc7138SMichael Pfeiffer 	fOpenMenu = new RecentDocumentsMenu("Open");
270d3046f7dSMichael Pfeiffer 	pmenu->AddItem(fOpenMenu);
271d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTrigger('O');
272d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
273d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetTarget(be_app);
274d3046f7dSMichael Pfeiffer 	fOpenMenu->Superitem()->SetShortcut('O', 0);
275cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
276780d8a62SMichael Pfeiffer 	BMenu *pmenuSaveAs = new BMenu("Save As" B_UTF8_ELLIPSIS, B_ITEMS_IN_COLUMN);
277cdb89ebbSMatthew Wilber 	BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP);
278fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
279fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
280cdb89ebbSMatthew Wilber 	pmenu->AddItem(pmenuSaveAs);
281cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Close", MSG_CLOSE, 'W', 0, 'W', true);
282cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
283780d8a62SMichael Pfeiffer 	AddItemMenu(pmenu, "Page Setup" B_UTF8_ELLIPSIS, MSG_PAGE_SETUP, 0, 0, 'W', true);
284780d8a62SMichael Pfeiffer 	AddItemMenu(pmenu, "Print" B_UTF8_ELLIPSIS, MSG_PREPARE_PRINT, 0, 0, 'W', true);
285780d8a62SMichael Pfeiffer 	pmenu->AddSeparatorItem();
286780d8a62SMichael Pfeiffer 	AddItemMenu(pmenu, "About ShowImage" B_UTF8_ELLIPSIS, B_ABOUT_REQUESTED, 0, 0, 'A', true);
287cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
288cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Quit", B_QUIT_REQUESTED, 'Q', 0, 'A', true);
289cdb89ebbSMatthew Wilber 	pbar->AddItem(pmenu);
29013afa642SPhil Greenway 
291cdb89ebbSMatthew Wilber 	pmenu = new BMenu("Edit");
292cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Undo", B_UNDO, 'Z', 0, 'W', false);
293cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
294cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Cut", B_CUT, 'X', 0, 'W', false);
2958ad30bcfSMatthew Wilber 	AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', false);
296cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Paste", B_PASTE, 'V', 0, 'W', false);
297da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', false);
298cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
299d10d5947SMichael Pfeiffer 	AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
300cdb89ebbSMatthew Wilber 	pbar->AddItem(pmenu);
30113afa642SPhil Greenway 
302d3046f7dSMichael Pfeiffer 	pmenu = fBrowseMenu = new BMenu("Browse");
3032cb9af89SMatthew Wilber 	AddItemMenu(pmenu, "First Page", MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, 'W', true);
3042cb9af89SMatthew Wilber 	AddItemMenu(pmenu, "Last Page", MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, 'W', true);
3052cb9af89SMatthew Wilber 	AddItemMenu(pmenu, "Previous Page", MSG_PAGE_PREV, B_LEFT_ARROW, 0, 'W', true);
306fc5ca95dSStephan Aßmus 	AddItemMenu(pmenu, "Next Page", MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, 'W', true);
307d3046f7dSMichael Pfeiffer 	fGoToPageMenu = new BMenu("Go To Page");
3085e427b6aSMichael Pfeiffer 	fGoToPageMenu->SetRadioMode(true);
309d3046f7dSMichael Pfeiffer 	pmenu->AddItem(fGoToPageMenu);
310e6a50d9cSMichael Pfeiffer 	pmenu->AddSeparatorItem();
311e6a50d9cSMichael Pfeiffer 	AddItemMenu(pmenu, "Previous File", MSG_FILE_PREV, B_UP_ARROW, 0, 'W', true);
312fc5ca95dSStephan Aßmus 	AddItemMenu(pmenu, "Next File", MSG_FILE_NEXT, B_DOWN_ARROW, 0, 'W', true);
31303839579SMatthew Wilber 	pbar->AddItem(pmenu);
31403839579SMatthew Wilber 
315cdb89ebbSMatthew Wilber 	pmenu = new BMenu("Image");
316cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Dither Image", MSG_DITHER_IMAGE, 0, 0, 'W', true);
317ad13f387SMichael Pfeiffer 	pmenu->AddSeparatorItem();
318d2adcceaSAxel Dörfler 	AddItemMenu(pmenu, "Rotate -90°", MSG_ROTATE_270, '[', 0, 'W', true);
319fc5ca95dSStephan Aßmus 	AddItemMenu(pmenu, "Rotate +90°", MSG_ROTATE_90, ']', 0, 'W', true);
320ad13f387SMichael Pfeiffer 	pmenu->AddSeparatorItem();
321ad13f387SMichael Pfeiffer 	AddItemMenu(pmenu, "Mirror Vertical", MSG_MIRROR_VERTICAL, 0, 0, 'W', true);
322ad13f387SMichael Pfeiffer 	AddItemMenu(pmenu, "Mirror Horizontal", MSG_MIRROR_HORIZONTAL, 0, 0, 'W', true);
323ad13f387SMichael Pfeiffer 	pmenu->AddSeparatorItem();
324ad13f387SMichael Pfeiffer 	AddItemMenu(pmenu, "Invert", MSG_INVERT, 0, 0, 'W', true);
325ad13f387SMichael Pfeiffer 	pbar->AddItem(pmenu);
32613afa642SPhil Greenway }
32713afa642SPhil Greenway 
328cdb89ebbSMatthew Wilber BMenuItem *
329cdb89ebbSMatthew Wilber ShowImageWindow::AddItemMenu(BMenu *pmenu, char *caption, long unsigned int msg,
330cdb89ebbSMatthew Wilber 	char shortcut, uint32 modifier, char target, bool benabled)
331cdb89ebbSMatthew Wilber {
332cdb89ebbSMatthew Wilber 	BMenuItem* pitem;
3332cb9af89SMatthew Wilber 	pitem = new BMenuItem(caption, new BMessage(msg), shortcut, modifier);
33413afa642SPhil Greenway 
33513afa642SPhil Greenway 	if (target == 'A')
336cdb89ebbSMatthew Wilber 		pitem->SetTarget(be_app);
337da87390fSMichael Pfeiffer 	else
338da87390fSMichael Pfeiffer 		pitem->SetTarget(this);
339cdb89ebbSMatthew Wilber 	pitem->SetEnabled(benabled);
340cdb89ebbSMatthew Wilber 	pmenu->AddItem(pitem);
34113afa642SPhil Greenway 
342cdb89ebbSMatthew Wilber 	return pitem;
34313afa642SPhil Greenway }
34413afa642SPhil Greenway 
345ad13f387SMichael Pfeiffer BMenuItem*
346d3046f7dSMichael Pfeiffer ShowImageWindow::AddDelayItem(BMenu *pmenu, char *caption, float value)
347ad13f387SMichael Pfeiffer {
348ad13f387SMichael Pfeiffer 	BMenuItem* pitem;
349ad13f387SMichael Pfeiffer 	BMessage* pmsg;
350e6a50d9cSMichael Pfeiffer 	pmsg = new BMessage(MSG_SLIDE_SHOW_DELAY);
351ad13f387SMichael Pfeiffer 	pmsg->AddFloat("value", value);
352ad13f387SMichael Pfeiffer 
353ad13f387SMichael Pfeiffer 	pitem = new BMenuItem(caption, pmsg, 0);
354da87390fSMichael Pfeiffer 	pitem->SetTarget(this);
355ad13f387SMichael Pfeiffer 
356d3046f7dSMichael Pfeiffer 	bool marked = fImageView->GetSlideShowDelay() == value;
357ad13f387SMichael Pfeiffer 	if (marked) pitem->SetMarked(true);
358ad13f387SMichael Pfeiffer 	pmenu->AddItem(pitem);
359ad13f387SMichael Pfeiffer 
360ad13f387SMichael Pfeiffer 	return pitem;
361ad13f387SMichael Pfeiffer }
362ad13f387SMichael Pfeiffer 
363cdb89ebbSMatthew Wilber void
364cdb89ebbSMatthew Wilber ShowImageWindow::WindowRedimension(BBitmap *pbitmap)
36513afa642SPhil Greenway {
366d10d5947SMichael Pfeiffer 	BScreen screen;
367d10d5947SMichael Pfeiffer 	BRect r(pbitmap->Bounds());
368d10d5947SMichael Pfeiffer 	const float windowBorderWidth = 5;
369d10d5947SMichael Pfeiffer 	const float windowBorderHeight = 5;
37013afa642SPhil Greenway 
371d10d5947SMichael Pfeiffer 	if (screen.Frame().right == 0.0) {
372d10d5947SMichael Pfeiffer 		return; // invalid screen object
373d10d5947SMichael Pfeiffer 	}
374cdb89ebbSMatthew Wilber 
375fc5ca95dSStephan Aßmus 	float width = r.Width() + 2 * PEN_SIZE + B_V_SCROLL_BAR_WIDTH;
376fc5ca95dSStephan Aßmus 	float height = r.Height() + 2 * PEN_SIZE + 1 + fBar->Frame().Height() + B_H_SCROLL_BAR_HEIGHT;
377cdb89ebbSMatthew Wilber 
378d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
379fc5ca95dSStephan Aßmus 	float maxWidth = screen.Frame().Width() + 1 - windowBorderWidth - Frame().left;
380fc5ca95dSStephan Aßmus 	float maxHeight = screen.Frame().Height() + 1 - windowBorderHeight - Frame().top;
381cdb89ebbSMatthew Wilber 
382a8fc7138SMichael Pfeiffer 	// We have to check size limits manually, otherwise
383a8fc7138SMichael Pfeiffer 	// menu bar will be too short for small images.
384fc5ca95dSStephan Aßmus 	float minW, maxW, minH, maxH;
385a8fc7138SMichael Pfeiffer 	GetSizeLimits(&minW, &maxW, &minH, &maxH);
386a8fc7138SMichael Pfeiffer 	if (maxWidth > maxW) maxWidth = maxW;
387a8fc7138SMichael Pfeiffer 	if (maxHeight > maxH) maxHeight = maxH;
388a8fc7138SMichael Pfeiffer 	if (width < minW) width = minW;
389a8fc7138SMichael Pfeiffer 	if (height < minH) height = minH;
390a8fc7138SMichael Pfeiffer 
391d10d5947SMichael Pfeiffer 	if (width > maxWidth) width = maxWidth;
392d10d5947SMichael Pfeiffer 	if (height > maxHeight) height = maxHeight;
393d10d5947SMichael Pfeiffer 
394d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
39513afa642SPhil Greenway }
39613afa642SPhil Greenway 
397cdb89ebbSMatthew Wilber void
398cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
39913afa642SPhil Greenway {
40013afa642SPhil Greenway }
40113afa642SPhil Greenway 
4027eca0987SMichael Pfeiffer bool
4037eca0987SMichael Pfeiffer ShowImageWindow::ToggleMenuItem(uint32 what)
4047eca0987SMichael Pfeiffer {
4057eca0987SMichael Pfeiffer 	BMenuItem *item;
4067eca0987SMichael Pfeiffer 	bool marked = false;
407d3046f7dSMichael Pfeiffer 	item = fBar->FindItem(what);
4087eca0987SMichael Pfeiffer 	if (item != NULL) {
4097eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
4107eca0987SMichael Pfeiffer 		item->SetMarked(marked);
4117eca0987SMichael Pfeiffer 	}
4127eca0987SMichael Pfeiffer 	return marked;
4137eca0987SMichael Pfeiffer }
4147eca0987SMichael Pfeiffer 
415cdb89ebbSMatthew Wilber void
416da87390fSMichael Pfeiffer ShowImageWindow::EnableMenuItem(BMenu *menu, uint32 what, bool enable)
417e6a50d9cSMichael Pfeiffer {
418e6a50d9cSMichael Pfeiffer 	BMenuItem* item;
419da87390fSMichael Pfeiffer 	item = menu->FindItem(what);
420e6a50d9cSMichael Pfeiffer 	if (item && item->IsEnabled() != enable) {
421e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
422e6a50d9cSMichael Pfeiffer 	}
423e6a50d9cSMichael Pfeiffer }
424e6a50d9cSMichael Pfeiffer 
425e6a50d9cSMichael Pfeiffer void
426da87390fSMichael Pfeiffer ShowImageWindow::MarkMenuItem(BMenu *menu, uint32 what, bool marked)
427e6a50d9cSMichael Pfeiffer {
428e6a50d9cSMichael Pfeiffer 	BMenuItem* item;
429da87390fSMichael Pfeiffer 	item = menu->FindItem(what);
430e6a50d9cSMichael Pfeiffer 	if (item && item->IsMarked() != marked) {
431e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
432e6a50d9cSMichael Pfeiffer 	}
433e6a50d9cSMichael Pfeiffer }
434e6a50d9cSMichael Pfeiffer 
435da87390fSMichael Pfeiffer void
436da87390fSMichael Pfeiffer ShowImageWindow::MarkSlideShowDelay(float value)
437da87390fSMichael Pfeiffer {
438d3046f7dSMichael Pfeiffer 	const int32 n = fSlideShowDelay->CountItems();
439da87390fSMichael Pfeiffer 	float v;
440da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
441d3046f7dSMichael Pfeiffer 		BMenuItem* item = fSlideShowDelay->ItemAt(i);
442da87390fSMichael Pfeiffer 		if (item) {
443da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
444da87390fSMichael Pfeiffer 				if (!item->IsMarked()) {
445da87390fSMichael Pfeiffer 					item->SetMarked(true);
446da87390fSMichael Pfeiffer 				}
447da87390fSMichael Pfeiffer 				return;
448da87390fSMichael Pfeiffer 			}
449da87390fSMichael Pfeiffer 		}
450da87390fSMichael Pfeiffer 	}
451da87390fSMichael Pfeiffer }
452e6a50d9cSMichael Pfeiffer 
45319c76de4SMichael Pfeiffer 
45419c76de4SMichael Pfeiffer void
45519c76de4SMichael Pfeiffer ShowImageWindow::ResizeToWindow(bool shrink, uint32 what)
45619c76de4SMichael Pfeiffer {
45719c76de4SMichael Pfeiffer 	bool enabled;
45819c76de4SMichael Pfeiffer 	enabled = ToggleMenuItem(what);
45919c76de4SMichael Pfeiffer 	if (shrink) {
460d3046f7dSMichael Pfeiffer 		fImageView->SetShrinkToBounds(enabled);
46119c76de4SMichael Pfeiffer 	} else {
462d3046f7dSMichael Pfeiffer 		fImageView->SetZoomToBounds(enabled);
46319c76de4SMichael Pfeiffer 	}
464d3046f7dSMichael Pfeiffer 	enabled = !(fImageView->GetShrinkToBounds() || fImageView->GetZoomToBounds());
465d3046f7dSMichael Pfeiffer 	EnableMenuItem(fBar, MSG_ORIGINAL_SIZE, enabled);
466d3046f7dSMichael Pfeiffer 	EnableMenuItem(fBar, MSG_ZOOM_IN, enabled);
467d3046f7dSMichael Pfeiffer 	EnableMenuItem(fBar, MSG_ZOOM_OUT, enabled);
46819c76de4SMichael Pfeiffer }
46919c76de4SMichael Pfeiffer 
470e6a50d9cSMichael Pfeiffer void
471cdb89ebbSMatthew Wilber ShowImageWindow::MessageReceived(BMessage *pmsg)
47213afa642SPhil Greenway {
473d3046f7dSMichael Pfeiffer 	ShowImageSettings* settings;
474cdb89ebbSMatthew Wilber 	switch (pmsg->what) {
475ee7b4f39SMatthew Wilber 		case MSG_MODIFIED:
476ee7b4f39SMatthew Wilber 			// If image has been modified due to a Cut or Paste
477ee7b4f39SMatthew Wilber 			fModified = true;
478ee7b4f39SMatthew Wilber 			break;
479ee7b4f39SMatthew Wilber 
480fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
481fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
482d3046f7dSMichael Pfeiffer 			if (!fSavePanel)
483cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
484cdb89ebbSMatthew Wilber 				SaveAs(pmsg);
48513afa642SPhil Greenway 			break;
486fc0a275bSMatthew Wilber 
487fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
488fc0a275bSMatthew Wilber 			// User specified where to save the output image
489cdb89ebbSMatthew Wilber 			SaveToFile(pmsg);
490fc0a275bSMatthew Wilber 			break;
491fc0a275bSMatthew Wilber 
49207caaa8eSMatthew Wilber 		case MSG_CLOSE:
493cdb89ebbSMatthew Wilber 			if (CanQuit())
49407caaa8eSMatthew Wilber 				Quit();
49507caaa8eSMatthew Wilber 			break;
49607caaa8eSMatthew Wilber 
497cdb89ebbSMatthew Wilber 		case B_CANCEL:
498d3046f7dSMichael Pfeiffer 			delete fSavePanel;
499d3046f7dSMichael Pfeiffer 			fSavePanel = NULL;
500cdb89ebbSMatthew Wilber 			break;
501cdb89ebbSMatthew Wilber 
50203839579SMatthew Wilber 		case MSG_UPDATE_STATUS:
50303839579SMatthew Wilber 		{
5046c305411SMatthew Wilber 			int32 pages, curPage;
505d3046f7dSMichael Pfeiffer 			pages = fImageView->PageCount();
506d3046f7dSMichael Pfeiffer 			curPage = fImageView->CurrentPage();
5076c305411SMatthew Wilber 
5086c305411SMatthew Wilber 			bool benable = (pages > 1) ? true : false;
509d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_FIRST, benable);
510d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_LAST, benable);
511d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_NEXT, benable);
512d3046f7dSMichael Pfeiffer 			EnableMenuItem(fBar, MSG_PAGE_PREV, benable);
5131d592070SMatthew Wilber 
514134d6076SMichael Pfeiffer 			EnableMenuItem(fBar, MSG_FILE_NEXT, fImageView->HasNextFile());
515134d6076SMichael Pfeiffer 			EnableMenuItem(fBar, MSG_FILE_PREV, fImageView->HasPrevFile());
516134d6076SMichael Pfeiffer 
517d3046f7dSMichael Pfeiffer 			if (fGoToPageMenu->CountItems() != pages) {
5186c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
5196c305411SMatthew Wilber 				// pages is different
5206c305411SMatthew Wilber 
521d3046f7dSMichael Pfeiffer 				while (fGoToPageMenu->CountItems() > 0)
5226c305411SMatthew Wilber 					// Remove all page numbers
523d3046f7dSMichael Pfeiffer 					delete fGoToPageMenu->RemoveItem(0L);
5246c305411SMatthew Wilber 
525780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
5266c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
5276c305411SMatthew Wilber 					BMessage *pgomsg;
528780d8a62SMichael Pfeiffer 					char shortcut = 0;
5296c305411SMatthew Wilber 					pgomsg = new BMessage(MSG_GOTO_PAGE);
5306c305411SMatthew Wilber 					pgomsg->AddInt32("page", i);
5316c305411SMatthew Wilber 					BString strCaption;
5326c305411SMatthew Wilber 					strCaption << i;
5336c305411SMatthew Wilber 					BMenuItem *pitem;
534780d8a62SMichael Pfeiffer 					if (i < 10) {
535780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
536780d8a62SMichael Pfeiffer 					} else if (i == 10) {
537780d8a62SMichael Pfeiffer 						shortcut = '0';
538780d8a62SMichael Pfeiffer 					}
539780d8a62SMichael Pfeiffer 					pitem = new BMenuItem(strCaption.String(), pgomsg, shortcut);
5406c305411SMatthew Wilber 					if (curPage == i)
5416c305411SMatthew Wilber 						pitem->SetMarked(true);
542d3046f7dSMichael Pfeiffer 					fGoToPageMenu->AddItem(pitem);
5436c305411SMatthew Wilber 				}
5446c305411SMatthew Wilber 			} else {
5456c305411SMatthew Wilber 				// Make sure the correct page is marked
5466c305411SMatthew Wilber 				BMenuItem *pcurItem;
547d3046f7dSMichael Pfeiffer 				pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
5486c305411SMatthew Wilber 				if (!pcurItem->IsMarked()) {
5496c305411SMatthew Wilber 					pcurItem->SetMarked(true);
5506c305411SMatthew Wilber 				}
5516c305411SMatthew Wilber 			}
5526c305411SMatthew Wilber 
55316b663b7SMatthew Wilber 			// Disable the Invert menu item if the bitmap color space
55416b663b7SMatthew Wilber 			// is B_CMAP8. (B_CMAP8 is currently unsupported by the
55516b663b7SMatthew Wilber 			// invert algorithm)
55616b663b7SMatthew Wilber 			color_space colors = B_NO_COLOR_SPACE;
55716b663b7SMatthew Wilber 			pmsg->FindInt32("colors", reinterpret_cast<int32 *>(&colors));
55816b663b7SMatthew Wilber 			EnableMenuItem(fBar, MSG_INVERT, (colors != B_CMAP8));
55916b663b7SMatthew Wilber 
5600cd4ecd8SStephan Aßmus 			BString status;
5610cd4ecd8SStephan Aßmus 			int32 width, height;
5620cd4ecd8SStephan Aßmus 			if (pmsg->FindInt32("width", &width) >= B_OK
5630cd4ecd8SStephan Aßmus 				&& pmsg->FindInt32("height", &height) >= B_OK) {
5640cd4ecd8SStephan Aßmus 				status << width << "x" << height << ", ";
5650cd4ecd8SStephan Aßmus 			}
5660cd4ecd8SStephan Aßmus 
56703839579SMatthew Wilber 			BString str;
5685eb50e46SMichael Pfeiffer 			if (pmsg->FindString("status", &str) == B_OK) {
5690cd4ecd8SStephan Aßmus 				status << str;
5705eb50e46SMichael Pfeiffer 			}
5710cd4ecd8SStephan Aßmus 
5720cd4ecd8SStephan Aßmus 			fStatusView->SetText(status);
5737eca0987SMichael Pfeiffer 
5747eca0987SMichael Pfeiffer 			UpdateTitle();
57503839579SMatthew Wilber 			break;
57603839579SMatthew Wilber 		}
57703839579SMatthew Wilber 
5788ad30bcfSMatthew Wilber 		case MSG_SELECTION:
5798ad30bcfSMatthew Wilber 		{
5808ad30bcfSMatthew Wilber 			// The view sends this message when a selection is
5818ad30bcfSMatthew Wilber 			// made or the selection is cleared so that the window
5828ad30bcfSMatthew Wilber 			// can update the state of the appropriate menu items
5838ad30bcfSMatthew Wilber 			bool benable;
5848ad30bcfSMatthew Wilber 			if (pmsg->FindBool("has_selection", &benable) == B_OK) {
585d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, B_CUT, benable);
586d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, B_COPY, benable);
587d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, MSG_CLEAR_SELECT, benable);
5888ad30bcfSMatthew Wilber 			}
5898ad30bcfSMatthew Wilber 			break;
5908ad30bcfSMatthew Wilber 		}
5918ad30bcfSMatthew Wilber 
5927598450eSMatthew Wilber 		case MSG_UNDO_STATE:
5937598450eSMatthew Wilber 		{
5947598450eSMatthew Wilber 			bool benable;
5957598450eSMatthew Wilber 			if (pmsg->FindBool("can_undo", &benable) == B_OK)
5967598450eSMatthew Wilber 				EnableMenuItem(fBar, B_UNDO, benable);
5977598450eSMatthew Wilber 			break;
5987598450eSMatthew Wilber 		}
5997598450eSMatthew Wilber 
600402c09e5SMatthew Wilber 		case MSG_CLIPBOARD_CHANGED:
601402c09e5SMatthew Wilber 		{
602402c09e5SMatthew Wilber 			// The app sends this message after it examines
603402c09e5SMatthew Wilber 			// the clipboard in response to a B_CLIPBOARD_CHANGED
604402c09e5SMatthew Wilber 			// message
605402c09e5SMatthew Wilber 			bool bdata;
606402c09e5SMatthew Wilber 			if (pmsg->FindBool("data_available", &bdata) == B_OK)
607d3046f7dSMichael Pfeiffer 				EnableMenuItem(fBar, B_PASTE, bdata);
608402c09e5SMatthew Wilber 			break;
609402c09e5SMatthew Wilber 		}
610402c09e5SMatthew Wilber 
61113afa642SPhil Greenway 		case B_UNDO:
6127598450eSMatthew Wilber 			fImageView->Undo();
61313afa642SPhil Greenway 			break;
61413afa642SPhil Greenway 		case B_CUT:
615d3046f7dSMichael Pfeiffer 			fImageView->Cut();
61613afa642SPhil Greenway 			break;
61713afa642SPhil Greenway 		case B_COPY:
618d3046f7dSMichael Pfeiffer 			fImageView->CopySelectionToClipboard();
61913afa642SPhil Greenway 			break;
62013afa642SPhil Greenway 		case B_PASTE:
621d3046f7dSMichael Pfeiffer 			fImageView->Paste();
62213afa642SPhil Greenway 			break;
62313afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
624d3046f7dSMichael Pfeiffer 			fImageView->ClearSelection();
62513afa642SPhil Greenway 			break;
62613afa642SPhil Greenway 		case MSG_SELECT_ALL:
627d3046f7dSMichael Pfeiffer 			fImageView->SelectAll();
62813afa642SPhil Greenway 			break;
62913afa642SPhil Greenway 
63003839579SMatthew Wilber 		case MSG_PAGE_FIRST:
631ee7b4f39SMatthew Wilber 			if (ClosePrompt())
632d3046f7dSMichael Pfeiffer 				fImageView->FirstPage();
63303839579SMatthew Wilber 			break;
63403839579SMatthew Wilber 
63503839579SMatthew Wilber 		case MSG_PAGE_LAST:
636ee7b4f39SMatthew Wilber 			if (ClosePrompt())
637d3046f7dSMichael Pfeiffer 				fImageView->LastPage();
63803839579SMatthew Wilber 			break;
63903839579SMatthew Wilber 
64003839579SMatthew Wilber 		case MSG_PAGE_NEXT:
641ee7b4f39SMatthew Wilber 			if (ClosePrompt())
642d3046f7dSMichael Pfeiffer 				fImageView->NextPage();
64303839579SMatthew Wilber 			break;
64403839579SMatthew Wilber 
64503839579SMatthew Wilber 		case MSG_PAGE_PREV:
646ee7b4f39SMatthew Wilber 			if (ClosePrompt())
647d3046f7dSMichael Pfeiffer 				fImageView->PrevPage();
64803839579SMatthew Wilber 			break;
64903839579SMatthew Wilber 
6506c305411SMatthew Wilber 		case MSG_GOTO_PAGE:
6516c305411SMatthew Wilber 			{
652ee7b4f39SMatthew Wilber 				if (!ClosePrompt())
653ee7b4f39SMatthew Wilber 					break;
654ee7b4f39SMatthew Wilber 
6556c305411SMatthew Wilber 				int32 curPage, newPage, pages;
6566c305411SMatthew Wilber 				if (pmsg->FindInt32("page", &newPage) == B_OK) {
657d3046f7dSMichael Pfeiffer 					curPage = fImageView->CurrentPage();
658d3046f7dSMichael Pfeiffer 					pages = fImageView->PageCount();
6596c305411SMatthew Wilber 
6606c305411SMatthew Wilber 					if (newPage > 0 && newPage <= pages) {
6616c305411SMatthew Wilber 						BMenuItem *pcurItem, *pnewItem;
662d3046f7dSMichael Pfeiffer 						pcurItem = fGoToPageMenu->ItemAt(curPage - 1);
663d3046f7dSMichael Pfeiffer 						pnewItem = fGoToPageMenu->ItemAt(newPage - 1);
6646c305411SMatthew Wilber 						if (!pcurItem || !pnewItem)
6656c305411SMatthew Wilber 							break;
6666c305411SMatthew Wilber 						pcurItem->SetMarked(false);
6676c305411SMatthew Wilber 						pnewItem->SetMarked(true);
668d3046f7dSMichael Pfeiffer 						fImageView->GoToPage(newPage);
6696c305411SMatthew Wilber 					}
6706c305411SMatthew Wilber 				}
6716c305411SMatthew Wilber 			}
6726c305411SMatthew Wilber 			break;
6736c305411SMatthew Wilber 
674cdb89ebbSMatthew Wilber 		case MSG_DITHER_IMAGE:
675a8fc7138SMichael Pfeiffer 			fImageView->SetDither(ToggleMenuItem(pmsg->what));
6767eca0987SMichael Pfeiffer 			break;
6777eca0987SMichael Pfeiffer 
67819c76de4SMichael Pfeiffer 		case MSG_SHRINK_TO_WINDOW:
67919c76de4SMichael Pfeiffer 			ResizeToWindow(true, pmsg->what);
68019c76de4SMichael Pfeiffer 			break;
68119c76de4SMichael Pfeiffer 		case MSG_ZOOM_TO_WINDOW:
68219c76de4SMichael Pfeiffer 			ResizeToWindow(false, pmsg->what);
6837eca0987SMichael Pfeiffer 			break;
6847eca0987SMichael Pfeiffer 
6857eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
686ee7b4f39SMatthew Wilber 			if (ClosePrompt())
687d3046f7dSMichael Pfeiffer 				fImageView->PrevFile();
6887eca0987SMichael Pfeiffer 			break;
6897eca0987SMichael Pfeiffer 
6907eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
691ee7b4f39SMatthew Wilber 			if (ClosePrompt())
692d3046f7dSMichael Pfeiffer 				fImageView->NextFile();
69313afa642SPhil Greenway 			break;
69413afa642SPhil Greenway 
695bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
696d3046f7dSMichael Pfeiffer 			fImageView->Rotate(90);
697ad13f387SMichael Pfeiffer 			break;
698bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
699d3046f7dSMichael Pfeiffer 			fImageView->Rotate(270);
700ad13f387SMichael Pfeiffer 			break;
701ad13f387SMichael Pfeiffer 		case MSG_MIRROR_VERTICAL:
702d3046f7dSMichael Pfeiffer 			fImageView->Mirror(true);
703ad13f387SMichael Pfeiffer 			break;
704ad13f387SMichael Pfeiffer 		case MSG_MIRROR_HORIZONTAL:
705d3046f7dSMichael Pfeiffer 			fImageView->Mirror(false);
706ad13f387SMichael Pfeiffer 			break;
707ad13f387SMichael Pfeiffer 		case MSG_INVERT:
708d3046f7dSMichael Pfeiffer 			fImageView->Invert();
709ad13f387SMichael Pfeiffer 			break;
710e6a50d9cSMichael Pfeiffer 		case MSG_SLIDE_SHOW:
711ee7b4f39SMatthew Wilber 			{
712ee7b4f39SMatthew Wilber 				BMenuItem *item;
713ee7b4f39SMatthew Wilber 				item = fBar->FindItem(pmsg->what);
714ee7b4f39SMatthew Wilber 				if (!item)
715ee7b4f39SMatthew Wilber 					break;
716ee7b4f39SMatthew Wilber 				if (item->IsMarked()) {
717ee7b4f39SMatthew Wilber 					item->SetMarked(false);
718d3046f7dSMichael Pfeiffer 					fImageView->StopSlideShow();
719ee7b4f39SMatthew Wilber 				} else if (ClosePrompt()) {
720ee7b4f39SMatthew Wilber 					item->SetMarked(true);
721ee7b4f39SMatthew Wilber 					fImageView->StartSlideShow();
722ad13f387SMichael Pfeiffer 				}
723ee7b4f39SMatthew Wilber 			}
724ee7b4f39SMatthew Wilber 			break;
725ee7b4f39SMatthew Wilber 
726e6a50d9cSMichael Pfeiffer 		case MSG_SLIDE_SHOW_DELAY:
727ad13f387SMichael Pfeiffer 			{
728ad13f387SMichael Pfeiffer 				float value;
729ad13f387SMichael Pfeiffer 				if (pmsg->FindFloat("value", &value) == B_OK) {
730d3046f7dSMichael Pfeiffer 					fImageView->SetSlideShowDelay(value);
731da87390fSMichael Pfeiffer 					// in case message is sent from popup menu
732da87390fSMichael Pfeiffer 					MarkSlideShowDelay(value);
733ad13f387SMichael Pfeiffer 				}
734ad13f387SMichael Pfeiffer 			}
735ad13f387SMichael Pfeiffer 			break;
736ad13f387SMichael Pfeiffer 
737ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
738ad13f387SMichael Pfeiffer 			ToggleFullScreen();
739ad13f387SMichael Pfeiffer 			break;
740fc5ca95dSStephan Aßmus 		case MSG_EXIT_FULL_SCREEN:
741fc5ca95dSStephan Aßmus 			if (fFullScreen)
742fc5ca95dSStephan Aßmus 				ToggleFullScreen();
743fc5ca95dSStephan Aßmus 			break;
744e6a50d9cSMichael Pfeiffer 		case MSG_SHOW_CAPTION:
745e6a50d9cSMichael Pfeiffer 			fShowCaption = ToggleMenuItem(pmsg->what);
746d3046f7dSMichael Pfeiffer 			settings = my_app->Settings();
747d3046f7dSMichael Pfeiffer 			if (settings->Lock()) {
748d3046f7dSMichael Pfeiffer 				settings->SetBool("ShowCaption", fShowCaption);
749d3046f7dSMichael Pfeiffer 				settings->Unlock();
750d3046f7dSMichael Pfeiffer 			}
751e6a50d9cSMichael Pfeiffer 			if (fFullScreen) {
752d3046f7dSMichael Pfeiffer 				fImageView->SetShowCaption(fShowCaption);
753e6a50d9cSMichael Pfeiffer 			}
754e6a50d9cSMichael Pfeiffer 			break;
755ad13f387SMichael Pfeiffer 
756780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
757780d8a62SMichael Pfeiffer 			PageSetup();
758780d8a62SMichael Pfeiffer 			break;
759780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
760780d8a62SMichael Pfeiffer 			PrepareForPrint();
761780d8a62SMichael Pfeiffer 			break;
762780d8a62SMichael Pfeiffer 		case MSG_PRINT:
763780d8a62SMichael Pfeiffer 			Print(pmsg);
764780d8a62SMichael Pfeiffer 			break;
765780d8a62SMichael Pfeiffer 
766780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
767d3046f7dSMichael Pfeiffer 			fImageView->ZoomIn();
768780d8a62SMichael Pfeiffer 			break;
769780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
770d3046f7dSMichael Pfeiffer 			fImageView->ZoomOut();
771780d8a62SMichael Pfeiffer 			break;
772780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
773d3046f7dSMichael Pfeiffer 			fImageView->SetZoom(1.0);
774780d8a62SMichael Pfeiffer 			break;
77581b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
776d3046f7dSMichael Pfeiffer 			fImageView->SetScaleBilinear(ToggleMenuItem(pmsg->what));
77781b9c776SMichael Pfeiffer 			break;
778780d8a62SMichael Pfeiffer 
77913afa642SPhil Greenway 		default:
780cdb89ebbSMatthew Wilber 			BWindow::MessageReceived(pmsg);
78113afa642SPhil Greenway 			break;
78213afa642SPhil Greenway 	}
78313afa642SPhil Greenway }
784fc0a275bSMatthew Wilber 
785fc0a275bSMatthew Wilber void
786fc0a275bSMatthew Wilber ShowImageWindow::SaveAs(BMessage *pmsg)
787fc0a275bSMatthew Wilber {
788cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
789cdb89ebbSMatthew Wilber 	translator_id outTranslator;
790cdb89ebbSMatthew Wilber 	uint32 outType;
791cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TRANSLATOR_FLD,
792cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outTranslator)) != B_OK)
793fc0a275bSMatthew Wilber 		return;
794cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TYPE_FLD,
795cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outType)) != B_OK)
796fc0a275bSMatthew Wilber 		return;
797fc0a275bSMatthew Wilber 
798cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
799cdb89ebbSMatthew Wilber 	// message that the save panel will send back
800cdb89ebbSMatthew Wilber 	BMessage *ppanelMsg = new BMessage(MSG_SAVE_PANEL);
801cdb89ebbSMatthew Wilber 	ppanelMsg->AddInt32(TRANSLATOR_FLD, outTranslator);
802cdb89ebbSMatthew Wilber 	ppanelMsg->AddInt32(TYPE_FLD, outType);
803cdb89ebbSMatthew Wilber 
804cdb89ebbSMatthew Wilber 	// Create save panel and show it
805d3046f7dSMichael Pfeiffer 	fSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), NULL, 0,
806cdb89ebbSMatthew Wilber 		false, ppanelMsg);
807d3046f7dSMichael Pfeiffer 	if (!fSavePanel)
808fc0a275bSMatthew Wilber 		return;
809d3046f7dSMichael Pfeiffer 	fSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
810d3046f7dSMichael Pfeiffer 	fSavePanel->Show();
811fc0a275bSMatthew Wilber }
812fc0a275bSMatthew Wilber 
813fc0a275bSMatthew Wilber void
814fc0a275bSMatthew Wilber ShowImageWindow::SaveToFile(BMessage *pmsg)
815fc0a275bSMatthew Wilber {
816cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
817fc0a275bSMatthew Wilber 	entry_ref dirref;
818fc0a275bSMatthew Wilber 	if (pmsg->FindRef("directory", &dirref) != B_OK)
819fc0a275bSMatthew Wilber 		return;
820fc0a275bSMatthew Wilber 	const char *filename;
821fc0a275bSMatthew Wilber 	if (pmsg->FindString("name", &filename) != B_OK)
822fc0a275bSMatthew Wilber 		return;
823fc0a275bSMatthew Wilber 
824cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
825cdb89ebbSMatthew Wilber 	// to save the output image
826cdb89ebbSMatthew Wilber 	translator_id outTranslator;
827cdb89ebbSMatthew Wilber 	uint32 outType;
828cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TRANSLATOR_FLD,
829cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outTranslator)) != B_OK)
830cdb89ebbSMatthew Wilber 		return;
831cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TYPE_FLD,
832cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outType)) != B_OK)
833cdb89ebbSMatthew Wilber 		return;
834cdb89ebbSMatthew Wilber 
835a7e78e3bSMatthew Wilber 	// Find the translator_format information needed to
836a7e78e3bSMatthew Wilber 	// write a MIME attribute for the image file
837a7e78e3bSMatthew Wilber 	BTranslatorRoster *roster = BTranslatorRoster::Default();
838a7e78e3bSMatthew Wilber 	const translation_format *pouts = NULL;
839a7e78e3bSMatthew Wilber 	int32 outsCount = 0;
840a7e78e3bSMatthew Wilber 	if (roster->GetOutputFormats(outTranslator, &pouts, &outsCount) != B_OK)
841a7e78e3bSMatthew Wilber 		return;
842a7e78e3bSMatthew Wilber 	if (outsCount < 1)
843a7e78e3bSMatthew Wilber 		return;
844a7e78e3bSMatthew Wilber 	int32 i;
845a7e78e3bSMatthew Wilber 	for (i = 0; i < outsCount; i++) {
846a7e78e3bSMatthew Wilber 		if (pouts[i].group == B_TRANSLATOR_BITMAP && pouts[i].type == outType)
847a7e78e3bSMatthew Wilber 			break;
848a7e78e3bSMatthew Wilber 	}
849a7e78e3bSMatthew Wilber 	if (i == outsCount)
850fc0a275bSMatthew Wilber 		return;
851fc0a275bSMatthew Wilber 
852a7e78e3bSMatthew Wilber 	// Write out the image file
853a7e78e3bSMatthew Wilber 	BDirectory dir(&dirref);
854a7e78e3bSMatthew Wilber 	fImageView->SaveToFile(&dir, filename, NULL, &pouts[i]);
855fc0a275bSMatthew Wilber }
856fc0a275bSMatthew Wilber 
857cdb89ebbSMatthew Wilber bool
858ee7b4f39SMatthew Wilber ShowImageWindow::ClosePrompt()
859ee7b4f39SMatthew Wilber {
860ee7b4f39SMatthew Wilber 	if (!fModified)
861ee7b4f39SMatthew Wilber 		return true;
862ee7b4f39SMatthew Wilber 	else {
863ee7b4f39SMatthew Wilber 		int32 page, count;
864ee7b4f39SMatthew Wilber 		count = fImageView->PageCount();
865ee7b4f39SMatthew Wilber 		page = fImageView->CurrentPage();
866ee7b4f39SMatthew Wilber 		BString prompt, name;
867ee7b4f39SMatthew Wilber 		fImageView->GetName(&name);
868ee7b4f39SMatthew Wilber 		prompt << "The document '" << name << "'";
869ee7b4f39SMatthew Wilber 		if (count > 1)
870ee7b4f39SMatthew Wilber 			prompt << " (page " << page << ")";
871ee7b4f39SMatthew Wilber 		prompt << " has been changed. "
872ee7b4f39SMatthew Wilber 		       << "Do you want to close the document?";
873ee7b4f39SMatthew Wilber 		BAlert *pAlert = new BAlert("Close document", prompt.String(),
874ee7b4f39SMatthew Wilber 			"Cancel", "Close");
875ee7b4f39SMatthew Wilber 		if (pAlert->Go() == 0)
876ee7b4f39SMatthew Wilber 			// Cancel
877ee7b4f39SMatthew Wilber 			return false;
878187f0b8aSMatthew Wilber 		else {
879ee7b4f39SMatthew Wilber 			// Close
880187f0b8aSMatthew Wilber 			fModified = false;
881ee7b4f39SMatthew Wilber 			return true;
882ee7b4f39SMatthew Wilber 		}
883ee7b4f39SMatthew Wilber 	}
884187f0b8aSMatthew Wilber }
885ee7b4f39SMatthew Wilber 
886ee7b4f39SMatthew Wilber bool
887cdb89ebbSMatthew Wilber ShowImageWindow::CanQuit()
888cdb89ebbSMatthew Wilber {
889d3046f7dSMichael Pfeiffer 	if (fSavePanel)
890cdb89ebbSMatthew Wilber 		// Don't allow this window to be closed if a save panel is open
891cdb89ebbSMatthew Wilber 		return false;
892cdb89ebbSMatthew Wilber 	else
893ee7b4f39SMatthew Wilber 		return ClosePrompt();
894cdb89ebbSMatthew Wilber }
895cdb89ebbSMatthew Wilber 
896ad13f387SMichael Pfeiffer void
897ad13f387SMichael Pfeiffer ShowImageWindow::ToggleFullScreen()
898ad13f387SMichael Pfeiffer {
899ad13f387SMichael Pfeiffer 	BRect frame;
900ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
901ad13f387SMichael Pfeiffer 	if (fFullScreen) {
902ad13f387SMichael Pfeiffer 		BScreen screen;
903ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
904ad13f387SMichael Pfeiffer 		frame = screen.Frame();
905d3046f7dSMichael Pfeiffer 		frame.top -= fBar->Bounds().Height()+1;
906ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
907ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
908ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
909ad13f387SMichael Pfeiffer 
910ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
911d3046f7dSMichael Pfeiffer 		fImageView->SetAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE);
912ad13f387SMichael Pfeiffer 	} else {
913ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
914ad13f387SMichael Pfeiffer 
915ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
916fc5ca95dSStephan Aßmus // NOTE: I changed this to not use left/top alignment at all, because
917fc5ca95dSStephan Aßmus // I have no idea why it would be useful. The layouting is much more
918fc5ca95dSStephan Aßmus // predictable now. -Stephan
919fc5ca95dSStephan Aßmus //		fImageView->SetAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
920fc5ca95dSStephan Aßmus 		fImageView->SetAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE);
921ad13f387SMichael Pfeiffer 	}
922d3046f7dSMichael Pfeiffer 	fImageView->SetBorder(!fFullScreen);
923d3046f7dSMichael Pfeiffer 	fImageView->SetShowCaption(fFullScreen && fShowCaption);
924ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
925ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
926ad13f387SMichael Pfeiffer }
927ad13f387SMichael Pfeiffer 
928d3046f7dSMichael Pfeiffer void
929d3046f7dSMichael Pfeiffer ShowImageWindow::LoadSettings()
930d3046f7dSMichael Pfeiffer {
931d3046f7dSMichael Pfeiffer 	ShowImageSettings* settings;
932d3046f7dSMichael Pfeiffer 	settings = my_app->Settings();
933d3046f7dSMichael Pfeiffer 	int32 op;
934d3046f7dSMichael Pfeiffer 	float f;
935d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
936d3046f7dSMichael Pfeiffer 		fShowCaption = settings->GetBool("ShowCaption", fShowCaption);
937d3046f7dSMichael Pfeiffer 		fPrintOptions.SetBounds(BRect(0, 0, 1023, 767));
938d3046f7dSMichael Pfeiffer 
939d3046f7dSMichael Pfeiffer 		op = settings->GetInt32("PO:Option", fPrintOptions.Option());
940d3046f7dSMichael Pfeiffer 		fPrintOptions.SetOption((enum PrintOptions::Option)op);
941d3046f7dSMichael Pfeiffer 
942d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
943d3046f7dSMichael Pfeiffer 		fPrintOptions.SetZoomFactor(f);
944d3046f7dSMichael Pfeiffer 
945d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:DPI", fPrintOptions.DPI());
946d3046f7dSMichael Pfeiffer 		fPrintOptions.SetDPI(f);
947d3046f7dSMichael Pfeiffer 
948d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Width", fPrintOptions.Width());
949d3046f7dSMichael Pfeiffer 		fPrintOptions.SetWidth(f);
950d3046f7dSMichael Pfeiffer 
951d3046f7dSMichael Pfeiffer 		f = settings->GetFloat("PO:Height", fPrintOptions.Height());
952d3046f7dSMichael Pfeiffer 		fPrintOptions.SetHeight(f);
953d3046f7dSMichael Pfeiffer 
954d3046f7dSMichael Pfeiffer 		settings->Unlock();
955d3046f7dSMichael Pfeiffer 	}
956d3046f7dSMichael Pfeiffer }
957d3046f7dSMichael Pfeiffer 
958d3046f7dSMichael Pfeiffer void
959d3046f7dSMichael Pfeiffer ShowImageWindow::SavePrintOptions()
960d3046f7dSMichael Pfeiffer {
961d3046f7dSMichael Pfeiffer 	ShowImageSettings* settings;
962d3046f7dSMichael Pfeiffer 	settings = my_app->Settings();
963d3046f7dSMichael Pfeiffer 	if (settings->Lock()) {
964d3046f7dSMichael Pfeiffer 		settings->SetInt32("PO:Option", fPrintOptions.Option());
965d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:ZoomFactor", fPrintOptions.ZoomFactor());
966d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:DPI", fPrintOptions.DPI());
967d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Width", fPrintOptions.Width());
968d3046f7dSMichael Pfeiffer 		settings->SetFloat("PO:Height", fPrintOptions.Height());
969d3046f7dSMichael Pfeiffer 		settings->Unlock();
970d3046f7dSMichael Pfeiffer 	}
971d3046f7dSMichael Pfeiffer }
972d3046f7dSMichael Pfeiffer 
973cdb89ebbSMatthew Wilber bool
974780d8a62SMichael Pfeiffer ShowImageWindow::PageSetup()
975780d8a62SMichael Pfeiffer {
976780d8a62SMichael Pfeiffer 	status_t st;
977780d8a62SMichael Pfeiffer 	BString name;
978d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
979780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
980780d8a62SMichael Pfeiffer 	if (fPrintSettings != NULL) {
981780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
982780d8a62SMichael Pfeiffer 	}
983780d8a62SMichael Pfeiffer 	st = printJob.ConfigPage();
984780d8a62SMichael Pfeiffer 	if (st == B_OK) {
985780d8a62SMichael Pfeiffer 		delete fPrintSettings;
986780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
987780d8a62SMichael Pfeiffer 	}
988780d8a62SMichael Pfeiffer 	return st == B_OK;
989780d8a62SMichael Pfeiffer }
990780d8a62SMichael Pfeiffer 
991780d8a62SMichael Pfeiffer void
992780d8a62SMichael Pfeiffer ShowImageWindow::PrepareForPrint()
993780d8a62SMichael Pfeiffer {
994780d8a62SMichael Pfeiffer 	if (fPrintSettings == NULL && !PageSetup()) {
995780d8a62SMichael Pfeiffer 		return;
996780d8a62SMichael Pfeiffer 	}
997780d8a62SMichael Pfeiffer 
998d3046f7dSMichael Pfeiffer 	fPrintOptions.SetBounds(fImageView->GetBitmap()->Bounds());
999d3046f7dSMichael Pfeiffer 	fPrintOptions.SetWidth(fImageView->GetBitmap()->Bounds().Width()+1);
1000780d8a62SMichael Pfeiffer 
1001780d8a62SMichael Pfeiffer 	new PrintOptionsWindow(BPoint(Frame().left+30, Frame().top+50), &fPrintOptions, this);
1002780d8a62SMichael Pfeiffer }
1003780d8a62SMichael Pfeiffer 
1004780d8a62SMichael Pfeiffer void
1005780d8a62SMichael Pfeiffer ShowImageWindow::Print(BMessage *msg)
1006780d8a62SMichael Pfeiffer {
1007780d8a62SMichael Pfeiffer 	status_t st;
1008780d8a62SMichael Pfeiffer 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK) {
1009780d8a62SMichael Pfeiffer 		return;
1010780d8a62SMichael Pfeiffer 	}
1011780d8a62SMichael Pfeiffer 
1012d3046f7dSMichael Pfeiffer 	SavePrintOptions();
1013d3046f7dSMichael Pfeiffer 
1014780d8a62SMichael Pfeiffer 	BString name;
1015d3046f7dSMichael Pfeiffer 	fPrintOptions.SetBounds(fImageView->GetBitmap()->Bounds());
1016d3046f7dSMichael Pfeiffer 	fImageView->GetName(&name);
1017780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
1018780d8a62SMichael Pfeiffer 	printJob.SetSettings(new BMessage(*fPrintSettings));
1019780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
1020780d8a62SMichael Pfeiffer 		int32  firstPage;
1021780d8a62SMichael Pfeiffer 		int32  lastPage;
1022780d8a62SMichael Pfeiffer 		BRect  printableRect = printJob.PrintableRect();
1023780d8a62SMichael Pfeiffer 		float width, imageWidth, imageHeight, w1, w2;
1024780d8a62SMichael Pfeiffer 		BBitmap* bitmap;
1025780d8a62SMichael Pfeiffer 
1026780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
1027780d8a62SMichael Pfeiffer 		firstPage = printJob.FirstPage();
1028780d8a62SMichael Pfeiffer 		lastPage = printJob.LastPage();
1029780d8a62SMichael Pfeiffer 		if (firstPage < 1) {
1030780d8a62SMichael Pfeiffer 			firstPage = 1;
1031780d8a62SMichael Pfeiffer 		}
1032780d8a62SMichael Pfeiffer 		if (lastPage < firstPage) {
1033780d8a62SMichael Pfeiffer 			lastPage = firstPage;
1034780d8a62SMichael Pfeiffer 		}
1035780d8a62SMichael Pfeiffer 
1036d3046f7dSMichael Pfeiffer 		bitmap = fImageView->GetBitmap();
1037780d8a62SMichael Pfeiffer 		imageWidth = bitmap->Bounds().Width() + 1.0;
1038780d8a62SMichael Pfeiffer 		imageHeight = bitmap->Bounds().Height() + 1.0;
1039780d8a62SMichael Pfeiffer 
1040780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
1041780d8a62SMichael Pfeiffer 			case PrintOptions::kFitToPage:
1042780d8a62SMichael Pfeiffer 				w1 = printableRect.Width()+1;
1043780d8a62SMichael Pfeiffer 				w2 = imageWidth * (printableRect.Height() + 1) / imageHeight;
1044780d8a62SMichael Pfeiffer 				if (w2 < w1) {
1045780d8a62SMichael Pfeiffer 					width = w2;
1046780d8a62SMichael Pfeiffer 				} else {
1047780d8a62SMichael Pfeiffer 					width = w1;
1048780d8a62SMichael Pfeiffer 				}
1049780d8a62SMichael Pfeiffer 				break;
1050780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
1051780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
1052780d8a62SMichael Pfeiffer 				break;
1053780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
1054780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
1055780d8a62SMichael Pfeiffer 				break;
1056780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
1057780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
1058780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
1059780d8a62SMichael Pfeiffer 				break;
1060780d8a62SMichael Pfeiffer 			default:
1061780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
1062780d8a62SMichael Pfeiffer 				width = imageWidth;
1063780d8a62SMichael Pfeiffer 		}
1064780d8a62SMichael Pfeiffer 
1065780d8a62SMichael Pfeiffer 		// XXX: eventually print large images on several pages
1066780d8a62SMichael Pfeiffer 		printJob.BeginJob();
1067d3046f7dSMichael Pfeiffer 		fImageView->SetScale(width / imageWidth);
10685eb50e46SMichael Pfeiffer 		// coordinates are relative to printable rectangle
10695eb50e46SMichael Pfeiffer 		BRect bounds(bitmap->Bounds());
10705eb50e46SMichael Pfeiffer 		printJob.DrawView(fImageView, bounds, BPoint(0, 0));
1071d3046f7dSMichael Pfeiffer 		fImageView->SetScale(1.0);
1072780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
1073780d8a62SMichael Pfeiffer 		printJob.CommitJob();
1074780d8a62SMichael Pfeiffer 	}
1075780d8a62SMichael Pfeiffer }
1076780d8a62SMichael Pfeiffer 
1077780d8a62SMichael Pfeiffer bool
1078cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
1079cdb89ebbSMatthew Wilber {
1080cdb89ebbSMatthew Wilber 	return CanQuit();
1081cdb89ebbSMatthew Wilber }
1082cdb89ebbSMatthew Wilber 
108307caaa8eSMatthew Wilber void
108407caaa8eSMatthew Wilber ShowImageWindow::Quit()
108507caaa8eSMatthew Wilber {
108607caaa8eSMatthew Wilber 	// tell the app to forget about this window
108707caaa8eSMatthew Wilber 	be_app->PostMessage(MSG_WINDOW_QUIT);
108807caaa8eSMatthew Wilber 	BWindow::Quit();
108907caaa8eSMatthew Wilber }
1090fc0a275bSMatthew Wilber 
1091fc5ca95dSStephan Aßmus void
1092fc5ca95dSStephan Aßmus ShowImageWindow::Zoom(BPoint origin, float width, float height)
1093fc5ca95dSStephan Aßmus {
1094fc5ca95dSStephan Aßmus 	// just go into fullscreen
1095fc5ca95dSStephan Aßmus 	ToggleFullScreen();
1096fc5ca95dSStephan Aßmus }
1097fc5ca95dSStephan Aßmus 
1098