xref: /haiku/src/apps/showimage/ShowImageWindow.cpp (revision bf461dbeb40cc5a6bdb5fa3c404d5848b3857b02)
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 
2913afa642SPhil Greenway #include <algobase.h>
3007caaa8eSMatthew Wilber #include <stdio.h>
3113afa642SPhil Greenway #include <Application.h>
3213afa642SPhil Greenway #include <Bitmap.h>
33fc0a275bSMatthew Wilber #include <BitmapStream.h>
3413afa642SPhil Greenway #include <Entry.h>
35fc0a275bSMatthew Wilber #include <File.h>
3613afa642SPhil Greenway #include <Menu.h>
3713afa642SPhil Greenway #include <MenuBar.h>
3813afa642SPhil Greenway #include <MenuItem.h>
3913afa642SPhil Greenway #include <Path.h>
4013afa642SPhil Greenway #include <ScrollView.h>
4113afa642SPhil Greenway #include <TranslationUtils.h>
4213afa642SPhil Greenway #include <TranslatorRoster.h>
4313afa642SPhil Greenway #include <Alert.h>
4407caaa8eSMatthew Wilber #include <SupportDefs.h>
45ad13f387SMichael Pfeiffer #include <Screen.h>
46d10d5947SMichael Pfeiffer #include <Roster.h>
47780d8a62SMichael Pfeiffer #include <PrintJob.h>
4813afa642SPhil Greenway 
4913afa642SPhil Greenway #include "ShowImageConstants.h"
5013afa642SPhil Greenway #include "ShowImageWindow.h"
5113afa642SPhil Greenway #include "ShowImageView.h"
5213afa642SPhil Greenway #include "ShowImageStatusView.h"
5313afa642SPhil Greenway 
5403839579SMatthew Wilber ShowImageWindow::ShowImageWindow(const entry_ref *pref)
55cdb89ebbSMatthew Wilber 	: BWindow(BRect(50, 50, 350, 250), "", B_DOCUMENT_WINDOW, 0)
5613afa642SPhil Greenway {
577eca0987SMichael Pfeiffer 	fpSavePanel = NULL;
58ad13f387SMichael Pfeiffer 	fFullScreen = false;
59e6a50d9cSMichael Pfeiffer 	fShowCaption = true; // XXX what is best for default?
60780d8a62SMichael Pfeiffer 	fPrintSettings = NULL;
61da87390fSMichael Pfeiffer 	fpImageView = NULL;
62fc0a275bSMatthew Wilber 
6313afa642SPhil Greenway 	// create menu bar
647eca0987SMichael Pfeiffer 	fpBar = new BMenuBar(BRect(0, 0, Bounds().right, 20), "menu_bar");
657eca0987SMichael Pfeiffer 	LoadMenus(fpBar);
667eca0987SMichael Pfeiffer 	AddChild(fpBar);
6713afa642SPhil Greenway 
6813afa642SPhil Greenway 	BRect viewFrame = Bounds();
697eca0987SMichael Pfeiffer 	viewFrame.top		= fpBar->Bounds().bottom + 1;
7013afa642SPhil Greenway 	viewFrame.right		-= B_V_SCROLL_BAR_WIDTH;
7113afa642SPhil Greenway 	viewFrame.bottom	-= B_H_SCROLL_BAR_HEIGHT;
7213afa642SPhil Greenway 
7313afa642SPhil Greenway 	// create the image view
747eca0987SMichael Pfeiffer 	fpImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
757eca0987SMichael Pfeiffer 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED);
7613afa642SPhil Greenway 	// wrap a scroll view around the view
777eca0987SMichael Pfeiffer 	BScrollView *pscrollView = new BScrollView("image_scroller", fpImageView,
78cdb89ebbSMatthew Wilber 		B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
79cdb89ebbSMatthew Wilber 	AddChild(pscrollView);
8013afa642SPhil Greenway 
8107caaa8eSMatthew Wilber 	const int32 kstatusWidth = 190;
82cdb89ebbSMatthew Wilber 	BRect rect;
8313afa642SPhil Greenway 	rect = Bounds();
8413afa642SPhil Greenway 	rect.top	= viewFrame.bottom + 1;
8507caaa8eSMatthew Wilber 	rect.left 	= viewFrame.left + kstatusWidth;
8613afa642SPhil Greenway 	rect.right	= viewFrame.right;
87cdb89ebbSMatthew Wilber 	BScrollBar *phscroll;
887eca0987SMichael Pfeiffer 	phscroll = new BScrollBar(rect, "hscroll", fpImageView, 0, 150,
89cdb89ebbSMatthew Wilber 		B_HORIZONTAL);
90cdb89ebbSMatthew Wilber 	AddChild(phscroll);
9113afa642SPhil Greenway 
9213afa642SPhil Greenway 	rect.left = 0;
9307caaa8eSMatthew Wilber 	rect.right = kstatusWidth - 1;
947eca0987SMichael Pfeiffer 	fpStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
95cdb89ebbSMatthew Wilber 		B_WILL_DRAW);
967eca0987SMichael Pfeiffer 	fpStatusView->SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR));
977eca0987SMichael Pfeiffer 	AddChild(fpStatusView);
9813afa642SPhil Greenway 
9913afa642SPhil Greenway 	rect = Bounds();
10013afa642SPhil Greenway 	rect.top    = viewFrame.top;
10113afa642SPhil Greenway 	rect.left 	= viewFrame.right + 1;
10213afa642SPhil Greenway 	rect.bottom	= viewFrame.bottom;
103cdb89ebbSMatthew Wilber 	BScrollBar *pvscroll;
1047eca0987SMichael Pfeiffer 	pvscroll = new BScrollBar(rect, "vscroll", fpImageView, 0, 150, B_VERTICAL);
105cdb89ebbSMatthew Wilber 	AddChild(pvscroll);
10613afa642SPhil Greenway 
10703839579SMatthew Wilber 	SetSizeLimits(250, 100000, 100, 100000);
10813afa642SPhil Greenway 
10913afa642SPhil Greenway 	// finish creating window
1107eca0987SMichael Pfeiffer 	fpImageView->SetImage(pref);
1117eca0987SMichael Pfeiffer 
112780d8a62SMichael Pfeiffer 	if (InitCheck() == B_OK) {
113780d8a62SMichael Pfeiffer 		UpdateTitle();
114780d8a62SMichael Pfeiffer 
1157eca0987SMichael Pfeiffer 		SetPulseRate(100000); // every 1/10 second; ShowImageView needs it for marching ants
11603839579SMatthew Wilber 
117d10d5947SMichael Pfeiffer 		fpImageView->FlushToLeftTop();
118d10d5947SMichael Pfeiffer 		WindowRedimension(fpImageView->GetBitmap());
119da87390fSMichael Pfeiffer 		fpImageView->MakeFocus(true); // to receive KeyDown messages
12013afa642SPhil Greenway 		Show();
121d10d5947SMichael Pfeiffer 	} else {
122e6a50d9cSMichael Pfeiffer 		BAlert* alert;
123e6a50d9cSMichael Pfeiffer 		alert = new BAlert("ShowImage",
124e6a50d9cSMichael Pfeiffer 			"Could not load image! Either the file or an image translator for it does not exist.",
125e6a50d9cSMichael Pfeiffer 			"OK", NULL, NULL,
126e6a50d9cSMichael Pfeiffer 			B_WIDTH_AS_USUAL, B_INFO_ALERT);
127e6a50d9cSMichael Pfeiffer 		alert->Go();
128d10d5947SMichael Pfeiffer 		// exit if file could not be opened
129d10d5947SMichael Pfeiffer 		Quit();
130d10d5947SMichael Pfeiffer 	}
13113afa642SPhil Greenway }
13213afa642SPhil Greenway 
13313afa642SPhil Greenway ShowImageWindow::~ShowImageWindow()
13413afa642SPhil Greenway {
13513afa642SPhil Greenway }
13613afa642SPhil Greenway 
137cdb89ebbSMatthew Wilber status_t
138cdb89ebbSMatthew Wilber ShowImageWindow::InitCheck()
13913afa642SPhil Greenway {
140e6a50d9cSMichael Pfeiffer 	if (!fpImageView || fpImageView->GetBitmap() == NULL)
14113afa642SPhil Greenway 		return B_ERROR;
142cdb89ebbSMatthew Wilber 	else
14313afa642SPhil Greenway 		return B_OK;
14413afa642SPhil Greenway }
145cdb89ebbSMatthew Wilber 
146cdb89ebbSMatthew Wilber void
147cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle()
14813afa642SPhil Greenway {
149e6a50d9cSMichael Pfeiffer 	BString path;
150e6a50d9cSMichael Pfeiffer 	fpImageView->GetPath(&path);
151e6a50d9cSMichael Pfeiffer 	SetTitle(path.String());
15213afa642SPhil Greenway }
15313afa642SPhil Greenway 
154cdb89ebbSMatthew Wilber void
155d10d5947SMichael Pfeiffer ShowImageWindow::UpdateRecentDocumentsMenu()
156d10d5947SMichael Pfeiffer {
157d10d5947SMichael Pfeiffer 	BMenuItem *item;
158d10d5947SMichael Pfeiffer 	BMessage list, *msg;
159d10d5947SMichael Pfeiffer 	entry_ref ref;
160d10d5947SMichael Pfeiffer 	char name[B_FILE_NAME_LENGTH];
161d10d5947SMichael Pfeiffer 
162d10d5947SMichael Pfeiffer 	while ((item = fpOpenMenu->RemoveItem((int32)0)) != NULL) {
163d10d5947SMichael Pfeiffer 		delete item;
164d10d5947SMichael Pfeiffer 	}
165d10d5947SMichael Pfeiffer 
166d10d5947SMichael Pfeiffer 	be_roster->GetRecentDocuments(&list, 20, NULL, APP_SIG);
167d10d5947SMichael Pfeiffer 	for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
168d10d5947SMichael Pfeiffer 		BEntry entry(&ref);
16981b9c776SMichael Pfeiffer 		if (entry.GetName(name) == B_OK) {
170d10d5947SMichael Pfeiffer 			msg = new BMessage(B_REFS_RECEIVED);
171d10d5947SMichael Pfeiffer 			msg->AddRef("refs", &ref);
172d10d5947SMichael Pfeiffer 			item =  new BMenuItem(name, msg, 0, 0);
173d10d5947SMichael Pfeiffer 			fpOpenMenu->AddItem(item);
174d10d5947SMichael Pfeiffer 			item->SetTarget(be_app, NULL);
175d10d5947SMichael Pfeiffer 		}
176d10d5947SMichael Pfeiffer 	}
17781b9c776SMichael Pfeiffer }
178d10d5947SMichael Pfeiffer 
179d10d5947SMichael Pfeiffer void
180da87390fSMichael Pfeiffer ShowImageWindow::BuildViewMenu(BMenu *pmenu)
181da87390fSMichael Pfeiffer {
182da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, 'W', true);
183da87390fSMichael Pfeiffer 	if (fpImageView) {
184da87390fSMichael Pfeiffer 		// when invoked from SlideShowView
185da87390fSMichael Pfeiffer 		MarkMenuItem(pmenu, MSG_SLIDE_SHOW, fpImageView->SlideShowStarted());
186da87390fSMichael Pfeiffer 	}
187da87390fSMichael Pfeiffer 	BMenu* pDelay = new BMenu("Slide Delay");
188da87390fSMichael Pfeiffer 	if (fpImageView == NULL) {
189da87390fSMichael Pfeiffer 		// when invoked from this window
190da87390fSMichael Pfeiffer 		fpSlideShowDelay = pDelay;
191da87390fSMichael Pfeiffer 	}
192da87390fSMichael Pfeiffer 	pDelay->SetRadioMode(true);
193da87390fSMichael Pfeiffer 	// Note: ShowImage loades images in window thread so it becomes unresponsive if
194da87390fSMichael Pfeiffer 	// slide show delay is too short! (Especially if loading the image takes as long as
195da87390fSMichael Pfeiffer 	// or longer than the slide show delay). Should load in background thread!
196da87390fSMichael Pfeiffer 	// AddDelayItem(pDelay, "Half a Second", 0.5, false);
197da87390fSMichael Pfeiffer 	// AddDelayItem(pDelay, "One Second", 1, false);
198da87390fSMichael Pfeiffer 	// AddDelayItem(pDelay, "Two Second", 2, false);
199da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Three Seconds", 3, true);
200da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Four Second", 4, false);
201da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Five Seconds", 5, false);
202da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Six Seconds", 6, false);
203da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Seven Seconds", 7, false);
204da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Eight Seconds", 8, false);
205da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Nine Seconds", 9, false);
206da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Ten Seconds", 10, false);
207da87390fSMichael Pfeiffer 	AddDelayItem(pDelay, "Twenty Seconds", 20, false);
208da87390fSMichael Pfeiffer 	pmenu->AddItem(pDelay);
209da87390fSMichael Pfeiffer 	pmenu->AddSeparatorItem();
210da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Original Size", MSG_ORIGINAL_SIZE, 0, 0, 'W', true);
211da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Zoom In", MSG_ZOOM_IN, '+', 0, 'W', true);
212da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Zoom Out", MSG_ZOOM_OUT, '-', 0, 'W', true);
21381b9c776SMichael Pfeiffer 	AddItemMenu(pmenu, "Scale Bilinear", MSG_SCALE_BILINEAR, 0, 0, 'W', true);
214da87390fSMichael Pfeiffer 	pmenu->AddSeparatorItem();
215da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Fit To Window Size", MSG_FIT_TO_WINDOW_SIZE, 0, 0, 'W', true);
216da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Full Screen", MSG_FULL_SCREEN, B_ENTER, 0, 'W', true);
21781b9c776SMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_FULL_SCREEN, fFullScreen);
218da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Show Caption in Full Screen Mode", MSG_SHOW_CAPTION, 0, 0, 'W', true);
219da87390fSMichael Pfeiffer 	MarkMenuItem(pmenu, MSG_SHOW_CAPTION, fShowCaption);
220da87390fSMichael Pfeiffer 
221da87390fSMichael Pfeiffer 	if (fpImageView) {
22281b9c776SMichael Pfeiffer 		MarkMenuItem(pmenu, MSG_SCALE_BILINEAR, fpImageView->GetScaleBilinear());
223da87390fSMichael Pfeiffer 		bool resize = fpImageView->GetResizeToViewBounds();
224da87390fSMichael Pfeiffer 		MarkMenuItem(pmenu, MSG_FIT_TO_WINDOW_SIZE, resize);
225da87390fSMichael Pfeiffer 		EnableMenuItem(pmenu, MSG_ORIGINAL_SIZE, !resize);
226da87390fSMichael Pfeiffer 		EnableMenuItem(pmenu, MSG_ZOOM_IN, !resize);
227da87390fSMichael Pfeiffer 		EnableMenuItem(pmenu, MSG_ZOOM_OUT, !resize);
228da87390fSMichael Pfeiffer 	}
229da87390fSMichael Pfeiffer }
230da87390fSMichael Pfeiffer 
231da87390fSMichael Pfeiffer void
232cdb89ebbSMatthew Wilber ShowImageWindow::LoadMenus(BMenuBar *pbar)
23313afa642SPhil Greenway {
234cdb89ebbSMatthew Wilber 	BMenu *pmenu = new BMenu("File");
235d10d5947SMichael Pfeiffer 	fpOpenMenu = new BMenu("Open");
236d10d5947SMichael Pfeiffer 	pmenu->AddItem(fpOpenMenu);
237d10d5947SMichael Pfeiffer 	fpOpenMenu->Superitem()->SetTrigger('O');
238d10d5947SMichael Pfeiffer 	fpOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
239d10d5947SMichael Pfeiffer 	fpOpenMenu->Superitem()->SetTarget(be_app);
240d10d5947SMichael Pfeiffer 	fpOpenMenu->Superitem()->SetShortcut('O', 0);
241cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
242780d8a62SMichael Pfeiffer 	BMenu *pmenuSaveAs = new BMenu("Save As" B_UTF8_ELLIPSIS, B_ITEMS_IN_COLUMN);
243cdb89ebbSMatthew Wilber 	BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP);
244fc0a275bSMatthew Wilber 		// Fill Save As submenu with all types that can be converted
245fc0a275bSMatthew Wilber 		// to from the Be bitmap image format
246cdb89ebbSMatthew Wilber 	pmenu->AddItem(pmenuSaveAs);
247cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Close", MSG_CLOSE, 'W', 0, 'W', true);
248cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
249780d8a62SMichael Pfeiffer 	AddItemMenu(pmenu, "Page Setup" B_UTF8_ELLIPSIS, MSG_PAGE_SETUP, 0, 0, 'W', true);
250780d8a62SMichael Pfeiffer 	AddItemMenu(pmenu, "Print" B_UTF8_ELLIPSIS, MSG_PREPARE_PRINT, 0, 0, 'W', true);
251780d8a62SMichael Pfeiffer 	pmenu->AddSeparatorItem();
252780d8a62SMichael Pfeiffer 	AddItemMenu(pmenu, "About ShowImage" B_UTF8_ELLIPSIS, B_ABOUT_REQUESTED, 0, 0, 'A', true);
253cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
254cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Quit", B_QUIT_REQUESTED, 'Q', 0, 'A', true);
255cdb89ebbSMatthew Wilber 	pbar->AddItem(pmenu);
25613afa642SPhil Greenway 
257cdb89ebbSMatthew Wilber 	pmenu = new BMenu("Edit");
258cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Undo", B_UNDO, 'Z', 0, 'W', false);
259cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
260cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Cut", B_CUT, 'X', 0, 'W', false);
261d10d5947SMichael Pfeiffer 	AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', true);
262cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Paste", B_PASTE, 'V', 0, 'W', false);
263da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', false);
264cdb89ebbSMatthew Wilber 	pmenu->AddSeparatorItem();
265d10d5947SMichael Pfeiffer 	AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
266da87390fSMichael Pfeiffer 	AddItemMenu(pmenu, "Select None", MSG_SELECT_NONE, 0, 0, 'W', true);
267cdb89ebbSMatthew Wilber 	pbar->AddItem(pmenu);
26813afa642SPhil Greenway 
269e6a50d9cSMichael Pfeiffer 	pmenu = fpBrowseMenu = new BMenu("Browse");
2702cb9af89SMatthew Wilber 	AddItemMenu(pmenu, "First Page", MSG_PAGE_FIRST, B_LEFT_ARROW, B_SHIFT_KEY, 'W', true);
2712cb9af89SMatthew Wilber 	AddItemMenu(pmenu, "Last Page", MSG_PAGE_LAST, B_RIGHT_ARROW, B_SHIFT_KEY, 'W', true);
2722cb9af89SMatthew Wilber 	AddItemMenu(pmenu, "Next Page", MSG_PAGE_NEXT, B_RIGHT_ARROW, 0, 'W', true);
2732cb9af89SMatthew Wilber 	AddItemMenu(pmenu, "Previous Page", MSG_PAGE_PREV, B_LEFT_ARROW, 0, 'W', true);
2746c305411SMatthew Wilber 	fpGoToPageMenu = new BMenu("Go To Page");
2756c305411SMatthew Wilber 	pmenu->AddItem(fpGoToPageMenu);
276e6a50d9cSMichael Pfeiffer 	pmenu->AddSeparatorItem();
277e6a50d9cSMichael Pfeiffer 	AddItemMenu(pmenu, "Next File", MSG_FILE_NEXT, B_DOWN_ARROW, 0, 'W', true);
278e6a50d9cSMichael Pfeiffer 	AddItemMenu(pmenu, "Previous File", MSG_FILE_PREV, B_UP_ARROW, 0, 'W', true);
27903839579SMatthew Wilber 	pbar->AddItem(pmenu);
28003839579SMatthew Wilber 
281cdb89ebbSMatthew Wilber 	pmenu = new BMenu("Image");
282cdb89ebbSMatthew Wilber 	AddItemMenu(pmenu, "Dither Image", MSG_DITHER_IMAGE, 0, 0, 'W', true);
283ad13f387SMichael Pfeiffer 	pmenu->AddSeparatorItem();
284*bf461dbeSMatthew Wilber 	AddItemMenu(pmenu, "Rotate +90", MSG_ROTATE_90, ']', 0, 'W', true);
285*bf461dbeSMatthew Wilber 	AddItemMenu(pmenu, "Rotate -90", MSG_ROTATE_270, '[', 0, 'W', true);
286ad13f387SMichael Pfeiffer 	pmenu->AddSeparatorItem();
287ad13f387SMichael Pfeiffer 	AddItemMenu(pmenu, "Mirror Vertical", MSG_MIRROR_VERTICAL, 0, 0, 'W', true);
288ad13f387SMichael Pfeiffer 	AddItemMenu(pmenu, "Mirror Horizontal", MSG_MIRROR_HORIZONTAL, 0, 0, 'W', true);
289ad13f387SMichael Pfeiffer 	pmenu->AddSeparatorItem();
290ad13f387SMichael Pfeiffer 	AddItemMenu(pmenu, "Invert", MSG_INVERT, 0, 0, 'W', true);
291ad13f387SMichael Pfeiffer 	pbar->AddItem(pmenu);
292ad13f387SMichael Pfeiffer 
293ad13f387SMichael Pfeiffer 	pmenu = new BMenu("View");
294da87390fSMichael Pfeiffer 	BuildViewMenu(pmenu);
295cdb89ebbSMatthew Wilber 	pbar->AddItem(pmenu);
296d10d5947SMichael Pfeiffer 
297d10d5947SMichael Pfeiffer 	UpdateRecentDocumentsMenu();
29813afa642SPhil Greenway }
29913afa642SPhil Greenway 
300cdb89ebbSMatthew Wilber BMenuItem *
301cdb89ebbSMatthew Wilber ShowImageWindow::AddItemMenu(BMenu *pmenu, char *caption, long unsigned int msg,
302cdb89ebbSMatthew Wilber 	char shortcut, uint32 modifier, char target, bool benabled)
303cdb89ebbSMatthew Wilber {
304cdb89ebbSMatthew Wilber 	BMenuItem* pitem;
3052cb9af89SMatthew Wilber 	pitem = new BMenuItem(caption, new BMessage(msg), shortcut, modifier);
30613afa642SPhil Greenway 
30713afa642SPhil Greenway 	if (target == 'A')
308cdb89ebbSMatthew Wilber 		pitem->SetTarget(be_app);
309da87390fSMichael Pfeiffer 	else
310da87390fSMichael Pfeiffer 		pitem->SetTarget(this);
311cdb89ebbSMatthew Wilber 	pitem->SetEnabled(benabled);
312cdb89ebbSMatthew Wilber 	pmenu->AddItem(pitem);
31313afa642SPhil Greenway 
314cdb89ebbSMatthew Wilber 	return pitem;
31513afa642SPhil Greenway }
31613afa642SPhil Greenway 
317ad13f387SMichael Pfeiffer BMenuItem*
318ad13f387SMichael Pfeiffer ShowImageWindow::AddDelayItem(BMenu *pmenu, char *caption, float value, bool marked)
319ad13f387SMichael Pfeiffer {
320ad13f387SMichael Pfeiffer 	BMenuItem* pitem;
321ad13f387SMichael Pfeiffer 	BMessage* pmsg;
322e6a50d9cSMichael Pfeiffer 	pmsg = new BMessage(MSG_SLIDE_SHOW_DELAY);
323ad13f387SMichael Pfeiffer 	pmsg->AddFloat("value", value);
324ad13f387SMichael Pfeiffer 
325ad13f387SMichael Pfeiffer 	pitem = new BMenuItem(caption, pmsg, 0);
326da87390fSMichael Pfeiffer 	pitem->SetTarget(this);
327ad13f387SMichael Pfeiffer 
328ad13f387SMichael Pfeiffer 	if (marked) pitem->SetMarked(true);
329ad13f387SMichael Pfeiffer 	pmenu->AddItem(pitem);
330ad13f387SMichael Pfeiffer 
331ad13f387SMichael Pfeiffer 	return pitem;
332ad13f387SMichael Pfeiffer }
333ad13f387SMichael Pfeiffer 
334cdb89ebbSMatthew Wilber void
335cdb89ebbSMatthew Wilber ShowImageWindow::WindowRedimension(BBitmap *pbitmap)
33613afa642SPhil Greenway {
337d10d5947SMichael Pfeiffer 	BScreen screen;
338d10d5947SMichael Pfeiffer 	BRect r(pbitmap->Bounds());
339d10d5947SMichael Pfeiffer 	float width, height;
340d10d5947SMichael Pfeiffer 	float maxWidth, maxHeight;
341d10d5947SMichael Pfeiffer 	const float windowBorderWidth = 5;
342d10d5947SMichael Pfeiffer 	const float windowBorderHeight = 5;
34313afa642SPhil Greenway 
344d10d5947SMichael Pfeiffer 	if (screen.Frame().right == 0.0) {
345d10d5947SMichael Pfeiffer 		return; // invalid screen object
346d10d5947SMichael Pfeiffer 	}
347cdb89ebbSMatthew Wilber 
348d10d5947SMichael Pfeiffer 	width = r.Width() + B_V_SCROLL_BAR_WIDTH;
349d10d5947SMichael Pfeiffer 	height = r.Height() + 1 + fpBar->Frame().Height() + B_H_SCROLL_BAR_HEIGHT;
350cdb89ebbSMatthew Wilber 
351d10d5947SMichael Pfeiffer 	// dimensions so that window does not reach outside of screen
352d10d5947SMichael Pfeiffer 	maxWidth = screen.Frame().Width() + 1 - windowBorderWidth - Frame().left;
353d10d5947SMichael Pfeiffer 	maxHeight = screen.Frame().Height() + 1 - windowBorderHeight - Frame().top;
354cdb89ebbSMatthew Wilber 
355d10d5947SMichael Pfeiffer 	if (width > maxWidth) width = maxWidth;
356d10d5947SMichael Pfeiffer 	if (height > maxHeight) height = maxHeight;
357d10d5947SMichael Pfeiffer 
358d10d5947SMichael Pfeiffer 	ResizeTo(width, height);
35913afa642SPhil Greenway }
36013afa642SPhil Greenway 
361cdb89ebbSMatthew Wilber void
362cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height)
36313afa642SPhil Greenway {
36413afa642SPhil Greenway }
36513afa642SPhil Greenway 
3667eca0987SMichael Pfeiffer bool
3677eca0987SMichael Pfeiffer ShowImageWindow::ToggleMenuItem(uint32 what)
3687eca0987SMichael Pfeiffer {
3697eca0987SMichael Pfeiffer 	BMenuItem *item;
3707eca0987SMichael Pfeiffer 	bool marked = false;
3717eca0987SMichael Pfeiffer 	item = fpBar->FindItem(what);
3727eca0987SMichael Pfeiffer 	if (item != NULL) {
3737eca0987SMichael Pfeiffer 		marked = !item->IsMarked();
3747eca0987SMichael Pfeiffer 		item->SetMarked(marked);
3757eca0987SMichael Pfeiffer 	}
3767eca0987SMichael Pfeiffer 	return marked;
3777eca0987SMichael Pfeiffer }
3787eca0987SMichael Pfeiffer 
379cdb89ebbSMatthew Wilber void
380da87390fSMichael Pfeiffer ShowImageWindow::EnableMenuItem(BMenu *menu, uint32 what, bool enable)
381e6a50d9cSMichael Pfeiffer {
382e6a50d9cSMichael Pfeiffer 	BMenuItem* item;
383da87390fSMichael Pfeiffer 	item = menu->FindItem(what);
384e6a50d9cSMichael Pfeiffer 	if (item && item->IsEnabled() != enable) {
385e6a50d9cSMichael Pfeiffer 		item->SetEnabled(enable);
386e6a50d9cSMichael Pfeiffer 	}
387e6a50d9cSMichael Pfeiffer }
388e6a50d9cSMichael Pfeiffer 
389e6a50d9cSMichael Pfeiffer void
390da87390fSMichael Pfeiffer ShowImageWindow::MarkMenuItem(BMenu *menu, uint32 what, bool marked)
391e6a50d9cSMichael Pfeiffer {
392e6a50d9cSMichael Pfeiffer 	BMenuItem* item;
393da87390fSMichael Pfeiffer 	item = menu->FindItem(what);
394e6a50d9cSMichael Pfeiffer 	if (item && item->IsMarked() != marked) {
395e6a50d9cSMichael Pfeiffer 		item->SetMarked(marked);
396e6a50d9cSMichael Pfeiffer 	}
397e6a50d9cSMichael Pfeiffer }
398e6a50d9cSMichael Pfeiffer 
399da87390fSMichael Pfeiffer void
400da87390fSMichael Pfeiffer ShowImageWindow::MarkSlideShowDelay(float value)
401da87390fSMichael Pfeiffer {
402da87390fSMichael Pfeiffer 	const int32 n = fpSlideShowDelay->CountItems();
403da87390fSMichael Pfeiffer 	float v;
404da87390fSMichael Pfeiffer 	for (int32 i = 0; i < n; i ++) {
405da87390fSMichael Pfeiffer 		BMenuItem* item = fpSlideShowDelay->ItemAt(i);
406da87390fSMichael Pfeiffer 		if (item) {
407da87390fSMichael Pfeiffer 			if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
408da87390fSMichael Pfeiffer 				if (!item->IsMarked()) {
409da87390fSMichael Pfeiffer 					item->SetMarked(true);
410da87390fSMichael Pfeiffer 				}
411da87390fSMichael Pfeiffer 				return;
412da87390fSMichael Pfeiffer 			}
413da87390fSMichael Pfeiffer 		}
414da87390fSMichael Pfeiffer 	}
415da87390fSMichael Pfeiffer }
416e6a50d9cSMichael Pfeiffer 
417e6a50d9cSMichael Pfeiffer void
418cdb89ebbSMatthew Wilber ShowImageWindow::MessageReceived(BMessage *pmsg)
41913afa642SPhil Greenway {
420cdb89ebbSMatthew Wilber 	switch (pmsg->what) {
421fc0a275bSMatthew Wilber 		case MSG_OUTPUT_TYPE:
422fc0a275bSMatthew Wilber 			// User clicked Save As then choose an output format
4237eca0987SMichael Pfeiffer 			if (!fpSavePanel)
424cdb89ebbSMatthew Wilber 				// If user doesn't already have a save panel open
425cdb89ebbSMatthew Wilber 				SaveAs(pmsg);
42613afa642SPhil Greenway 			break;
427fc0a275bSMatthew Wilber 
428fc0a275bSMatthew Wilber 		case MSG_SAVE_PANEL:
429fc0a275bSMatthew Wilber 			// User specified where to save the output image
430cdb89ebbSMatthew Wilber 			SaveToFile(pmsg);
431fc0a275bSMatthew Wilber 			break;
432fc0a275bSMatthew Wilber 
43307caaa8eSMatthew Wilber 		case MSG_CLOSE:
434cdb89ebbSMatthew Wilber 			if (CanQuit())
43507caaa8eSMatthew Wilber 				Quit();
43607caaa8eSMatthew Wilber 			break;
43707caaa8eSMatthew Wilber 
438cdb89ebbSMatthew Wilber 		case B_CANCEL:
4397eca0987SMichael Pfeiffer 			delete fpSavePanel;
4407eca0987SMichael Pfeiffer 			fpSavePanel = NULL;
441cdb89ebbSMatthew Wilber 			break;
442cdb89ebbSMatthew Wilber 
44303839579SMatthew Wilber 		case MSG_UPDATE_STATUS:
44403839579SMatthew Wilber 		{
4456c305411SMatthew Wilber 			int32 pages, curPage;
4466c305411SMatthew Wilber 			pages = fpImageView->PageCount();
4476c305411SMatthew Wilber 			curPage = fpImageView->CurrentPage();
4486c305411SMatthew Wilber 
4496c305411SMatthew Wilber 			bool benable = (pages > 1) ? true : false;
450da87390fSMichael Pfeiffer 			EnableMenuItem(fpBar, MSG_PAGE_FIRST, benable);
451da87390fSMichael Pfeiffer 			EnableMenuItem(fpBar, MSG_PAGE_LAST, benable);
452da87390fSMichael Pfeiffer 			EnableMenuItem(fpBar, MSG_PAGE_NEXT, benable);
453da87390fSMichael Pfeiffer 			EnableMenuItem(fpBar, MSG_PAGE_PREV, benable);
4541d592070SMatthew Wilber 
4556c305411SMatthew Wilber 			if (fpGoToPageMenu->CountItems() != pages) {
4566c305411SMatthew Wilber 				// Only rebuild the submenu if the number of
4576c305411SMatthew Wilber 				// pages is different
4586c305411SMatthew Wilber 
4596c305411SMatthew Wilber 				while (fpGoToPageMenu->CountItems() > 0)
4606c305411SMatthew Wilber 					// Remove all page numbers
4616c305411SMatthew Wilber 					delete fpGoToPageMenu->RemoveItem(0L);
4626c305411SMatthew Wilber 
463780d8a62SMichael Pfeiffer 				for (int32 i = 1; i <= pages; i++) {
4646c305411SMatthew Wilber 					// Fill Go To page submenu with an entry for each page
4656c305411SMatthew Wilber 					BMessage *pgomsg;
466780d8a62SMichael Pfeiffer 					char shortcut = 0;
4676c305411SMatthew Wilber 					pgomsg = new BMessage(MSG_GOTO_PAGE);
4686c305411SMatthew Wilber 					pgomsg->AddInt32("page", i);
4696c305411SMatthew Wilber 					BString strCaption;
4706c305411SMatthew Wilber 					strCaption << i;
4716c305411SMatthew Wilber 					BMenuItem *pitem;
472780d8a62SMichael Pfeiffer 					if (i < 10) {
473780d8a62SMichael Pfeiffer 						shortcut = '0' + i;
474780d8a62SMichael Pfeiffer 					} else if (i == 10) {
475780d8a62SMichael Pfeiffer 						shortcut = '0';
476780d8a62SMichael Pfeiffer 					}
477780d8a62SMichael Pfeiffer 					pitem = new BMenuItem(strCaption.String(), pgomsg, shortcut);
4786c305411SMatthew Wilber 					if (curPage == i)
4796c305411SMatthew Wilber 						pitem->SetMarked(true);
4806c305411SMatthew Wilber 					fpGoToPageMenu->AddItem(pitem);
4816c305411SMatthew Wilber 				}
4826c305411SMatthew Wilber 			} else {
4836c305411SMatthew Wilber 				// Make sure the correct page is marked
4846c305411SMatthew Wilber 				BMenuItem *pcurItem;
4856c305411SMatthew Wilber 				pcurItem = fpGoToPageMenu->ItemAt(curPage - 1);
4866c305411SMatthew Wilber 				if (!pcurItem->IsMarked()) {
4876c305411SMatthew Wilber 					// If the current page isn't marked, unmark everything
4886c305411SMatthew Wilber 					// then mark the current page
4896c305411SMatthew Wilber 					int32 items = fpGoToPageMenu->CountItems();
4906c305411SMatthew Wilber 					for (int32 i = 0; i < items; i++)
4916c305411SMatthew Wilber 						fpGoToPageMenu->ItemAt(i)->SetMarked(false);
4926c305411SMatthew Wilber 					pcurItem->SetMarked(true);
4936c305411SMatthew Wilber 				}
4946c305411SMatthew Wilber 			}
4956c305411SMatthew Wilber 
49603839579SMatthew Wilber 			BString str;
49703839579SMatthew Wilber 			if (pmsg->FindString("status", &str) == B_OK)
4987eca0987SMichael Pfeiffer 				fpStatusView->SetText(str);
4997eca0987SMichael Pfeiffer 
5007eca0987SMichael Pfeiffer 			UpdateTitle();
50103839579SMatthew Wilber 			break;
50203839579SMatthew Wilber 		}
50303839579SMatthew Wilber 
50413afa642SPhil Greenway 		case B_UNDO:
50513afa642SPhil Greenway 			break;
50613afa642SPhil Greenway 		case B_CUT:
50713afa642SPhil Greenway 			break;
50813afa642SPhil Greenway 		case B_COPY:
509d10d5947SMichael Pfeiffer 			fpImageView->CopySelectionToClipboard();
51013afa642SPhil Greenway 			break;
51113afa642SPhil Greenway 		case B_PASTE:
51213afa642SPhil Greenway 			break;
51313afa642SPhil Greenway 		case MSG_CLEAR_SELECT:
51413afa642SPhil Greenway 			break;
51513afa642SPhil Greenway 		case MSG_SELECT_ALL:
516d10d5947SMichael Pfeiffer 			fpImageView->SelectAll();
51713afa642SPhil Greenway 			break;
518da87390fSMichael Pfeiffer 		case MSG_SELECT_NONE:
519da87390fSMichael Pfeiffer 			fpImageView->Unselect();
520da87390fSMichael Pfeiffer 			break;
52113afa642SPhil Greenway 
52203839579SMatthew Wilber 		case MSG_PAGE_FIRST:
5237eca0987SMichael Pfeiffer 			fpImageView->FirstPage();
52403839579SMatthew Wilber 			break;
52503839579SMatthew Wilber 
52603839579SMatthew Wilber 		case MSG_PAGE_LAST:
5277eca0987SMichael Pfeiffer 			fpImageView->LastPage();
52803839579SMatthew Wilber 			break;
52903839579SMatthew Wilber 
53003839579SMatthew Wilber 		case MSG_PAGE_NEXT:
5317eca0987SMichael Pfeiffer 			fpImageView->NextPage();
53203839579SMatthew Wilber 			break;
53303839579SMatthew Wilber 
53403839579SMatthew Wilber 		case MSG_PAGE_PREV:
5357eca0987SMichael Pfeiffer 			fpImageView->PrevPage();
53603839579SMatthew Wilber 			break;
53703839579SMatthew Wilber 
5386c305411SMatthew Wilber 		case MSG_GOTO_PAGE:
5396c305411SMatthew Wilber 			{
5406c305411SMatthew Wilber 				int32 curPage, newPage, pages;
5416c305411SMatthew Wilber 				if (pmsg->FindInt32("page", &newPage) == B_OK) {
5426c305411SMatthew Wilber 					curPage = fpImageView->CurrentPage();
5436c305411SMatthew Wilber 					pages = fpImageView->PageCount();
5446c305411SMatthew Wilber 
5456c305411SMatthew Wilber 					if (newPage > 0 && newPage <= pages) {
5466c305411SMatthew Wilber 						BMenuItem *pcurItem, *pnewItem;
5476c305411SMatthew Wilber 						pcurItem = fpGoToPageMenu->ItemAt(curPage - 1);
5486c305411SMatthew Wilber 						pnewItem = fpGoToPageMenu->ItemAt(newPage - 1);
5496c305411SMatthew Wilber 						if (!pcurItem || !pnewItem)
5506c305411SMatthew Wilber 							break;
5516c305411SMatthew Wilber 						pcurItem->SetMarked(false);
5526c305411SMatthew Wilber 						pnewItem->SetMarked(true);
5536c305411SMatthew Wilber 						fpImageView->GoToPage(newPage);
5546c305411SMatthew Wilber 					}
5556c305411SMatthew Wilber 				}
5566c305411SMatthew Wilber 			}
5576c305411SMatthew Wilber 			break;
5586c305411SMatthew Wilber 
559cdb89ebbSMatthew Wilber 		case MSG_DITHER_IMAGE:
5607eca0987SMichael Pfeiffer 			ToggleMenuItem(pmsg->what);
5617eca0987SMichael Pfeiffer 			break;
5627eca0987SMichael Pfeiffer 
5637eca0987SMichael Pfeiffer 		case MSG_FIT_TO_WINDOW_SIZE:
5647eca0987SMichael Pfeiffer 			{
5657eca0987SMichael Pfeiffer 				bool resize;
5667eca0987SMichael Pfeiffer 				resize = ToggleMenuItem(pmsg->what);
5677eca0987SMichael Pfeiffer 				fpImageView->ResizeToViewBounds(resize);
568da87390fSMichael Pfeiffer 				EnableMenuItem(fpBar, MSG_ORIGINAL_SIZE, !resize);
569da87390fSMichael Pfeiffer 				EnableMenuItem(fpBar, MSG_ZOOM_IN, !resize);
570da87390fSMichael Pfeiffer 				EnableMenuItem(fpBar, MSG_ZOOM_OUT, !resize);
5717eca0987SMichael Pfeiffer 			}
5727eca0987SMichael Pfeiffer 			break;
5737eca0987SMichael Pfeiffer 
5747eca0987SMichael Pfeiffer 		case MSG_FILE_PREV:
5757eca0987SMichael Pfeiffer 			fpImageView->PrevFile();
5767eca0987SMichael Pfeiffer 			break;
5777eca0987SMichael Pfeiffer 
5787eca0987SMichael Pfeiffer 		case MSG_FILE_NEXT:
5797eca0987SMichael Pfeiffer 			fpImageView->NextFile();
58013afa642SPhil Greenway 			break;
58113afa642SPhil Greenway 
582*bf461dbeSMatthew Wilber 		case MSG_ROTATE_90:
583ad13f387SMichael Pfeiffer 			fpImageView->Rotate(90);
584ad13f387SMichael Pfeiffer 			break;
585*bf461dbeSMatthew Wilber 		case MSG_ROTATE_270:
586ad13f387SMichael Pfeiffer 			fpImageView->Rotate(270);
587ad13f387SMichael Pfeiffer 			break;
588ad13f387SMichael Pfeiffer 		case MSG_MIRROR_VERTICAL:
589ad13f387SMichael Pfeiffer 			fpImageView->Mirror(true);
590ad13f387SMichael Pfeiffer 			break;
591ad13f387SMichael Pfeiffer 		case MSG_MIRROR_HORIZONTAL:
592ad13f387SMichael Pfeiffer 			fpImageView->Mirror(false);
593ad13f387SMichael Pfeiffer 			break;
594ad13f387SMichael Pfeiffer 		case MSG_INVERT:
595ad13f387SMichael Pfeiffer 			fpImageView->Invert();
596ad13f387SMichael Pfeiffer 			break;
597e6a50d9cSMichael Pfeiffer 		case MSG_SLIDE_SHOW:
598ad13f387SMichael Pfeiffer 			if (ToggleMenuItem(pmsg->what)) {
599e6a50d9cSMichael Pfeiffer 				fpImageView->StartSlideShow();
600ad13f387SMichael Pfeiffer 			} else {
601e6a50d9cSMichael Pfeiffer 				fpImageView->StopSlideShow();
602ad13f387SMichael Pfeiffer 			}
603e6a50d9cSMichael Pfeiffer 		case MSG_SLIDE_SHOW_DELAY:
604ad13f387SMichael Pfeiffer 			{
605ad13f387SMichael Pfeiffer 				float value;
606ad13f387SMichael Pfeiffer 				if (pmsg->FindFloat("value", &value) == B_OK) {
607e6a50d9cSMichael Pfeiffer 					fpImageView->SetSlideShowDelay(value);
608da87390fSMichael Pfeiffer 					// in case message is sent from popup menu
609da87390fSMichael Pfeiffer 					MarkSlideShowDelay(value);
610ad13f387SMichael Pfeiffer 				}
611ad13f387SMichael Pfeiffer 			}
612ad13f387SMichael Pfeiffer 			break;
613ad13f387SMichael Pfeiffer 
614ad13f387SMichael Pfeiffer 		case MSG_FULL_SCREEN:
615ad13f387SMichael Pfeiffer 			ToggleFullScreen();
616ad13f387SMichael Pfeiffer 			break;
617e6a50d9cSMichael Pfeiffer 		case MSG_SHOW_CAPTION:
618e6a50d9cSMichael Pfeiffer 			fShowCaption = ToggleMenuItem(pmsg->what);
619e6a50d9cSMichael Pfeiffer 			if (fFullScreen) {
620e6a50d9cSMichael Pfeiffer 				fpImageView->SetShowCaption(fShowCaption);
621e6a50d9cSMichael Pfeiffer 			}
622e6a50d9cSMichael Pfeiffer 			break;
623ad13f387SMichael Pfeiffer 
624d10d5947SMichael Pfeiffer 		case MSG_UPDATE_RECENT_DOCUMENTS:
625d10d5947SMichael Pfeiffer 			UpdateRecentDocumentsMenu();
626d10d5947SMichael Pfeiffer 			break;
627d10d5947SMichael Pfeiffer 
628780d8a62SMichael Pfeiffer 		case MSG_PAGE_SETUP:
629780d8a62SMichael Pfeiffer 			PageSetup();
630780d8a62SMichael Pfeiffer 			break;
631780d8a62SMichael Pfeiffer 		case MSG_PREPARE_PRINT:
632780d8a62SMichael Pfeiffer 			PrepareForPrint();
633780d8a62SMichael Pfeiffer 			break;
634780d8a62SMichael Pfeiffer 		case MSG_PRINT:
635780d8a62SMichael Pfeiffer 			Print(pmsg);
636780d8a62SMichael Pfeiffer 			break;
637780d8a62SMichael Pfeiffer 
638780d8a62SMichael Pfeiffer 		case MSG_ZOOM_IN:
639780d8a62SMichael Pfeiffer 			fpImageView->ZoomIn();
640780d8a62SMichael Pfeiffer 			break;
641780d8a62SMichael Pfeiffer 		case MSG_ZOOM_OUT:
642780d8a62SMichael Pfeiffer 			fpImageView->ZoomOut();
643780d8a62SMichael Pfeiffer 			break;
644780d8a62SMichael Pfeiffer 		case MSG_ORIGINAL_SIZE:
645780d8a62SMichael Pfeiffer 			fpImageView->SetZoom(1.0);
646780d8a62SMichael Pfeiffer 			break;
64781b9c776SMichael Pfeiffer 		case MSG_SCALE_BILINEAR:
64881b9c776SMichael Pfeiffer 			fpImageView->SetScaleBilinear(ToggleMenuItem(pmsg->what));
64981b9c776SMichael Pfeiffer 			break;
650780d8a62SMichael Pfeiffer 
65113afa642SPhil Greenway 		default:
652cdb89ebbSMatthew Wilber 			BWindow::MessageReceived(pmsg);
65313afa642SPhil Greenway 			break;
65413afa642SPhil Greenway 	}
65513afa642SPhil Greenway }
656fc0a275bSMatthew Wilber 
657fc0a275bSMatthew Wilber void
658fc0a275bSMatthew Wilber ShowImageWindow::SaveAs(BMessage *pmsg)
659fc0a275bSMatthew Wilber {
660cdb89ebbSMatthew Wilber 	// Read the translator and output type the user chose
661cdb89ebbSMatthew Wilber 	translator_id outTranslator;
662cdb89ebbSMatthew Wilber 	uint32 outType;
663cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TRANSLATOR_FLD,
664cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outTranslator)) != B_OK)
665fc0a275bSMatthew Wilber 		return;
666cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TYPE_FLD,
667cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outType)) != B_OK)
668fc0a275bSMatthew Wilber 		return;
669fc0a275bSMatthew Wilber 
670cdb89ebbSMatthew Wilber 	// Add the chosen translator and output type to the
671cdb89ebbSMatthew Wilber 	// message that the save panel will send back
672cdb89ebbSMatthew Wilber 	BMessage *ppanelMsg = new BMessage(MSG_SAVE_PANEL);
673cdb89ebbSMatthew Wilber 	ppanelMsg->AddInt32(TRANSLATOR_FLD, outTranslator);
674cdb89ebbSMatthew Wilber 	ppanelMsg->AddInt32(TYPE_FLD, outType);
675cdb89ebbSMatthew Wilber 
676cdb89ebbSMatthew Wilber 	// Create save panel and show it
6777eca0987SMichael Pfeiffer 	fpSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), NULL, 0,
678cdb89ebbSMatthew Wilber 		false, ppanelMsg);
6797eca0987SMichael Pfeiffer 	if (!fpSavePanel)
680fc0a275bSMatthew Wilber 		return;
6817eca0987SMichael Pfeiffer 	fpSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE);
6827eca0987SMichael Pfeiffer 	fpSavePanel->Show();
683fc0a275bSMatthew Wilber }
684fc0a275bSMatthew Wilber 
685fc0a275bSMatthew Wilber void
686fc0a275bSMatthew Wilber ShowImageWindow::SaveToFile(BMessage *pmsg)
687fc0a275bSMatthew Wilber {
688cdb89ebbSMatthew Wilber 	// Read in where the file should be saved
689fc0a275bSMatthew Wilber 	entry_ref dirref;
690fc0a275bSMatthew Wilber 	if (pmsg->FindRef("directory", &dirref) != B_OK)
691fc0a275bSMatthew Wilber 		return;
692fc0a275bSMatthew Wilber 	const char *filename;
693fc0a275bSMatthew Wilber 	if (pmsg->FindString("name", &filename) != B_OK)
694fc0a275bSMatthew Wilber 		return;
695fc0a275bSMatthew Wilber 
696cdb89ebbSMatthew Wilber 	// Read in the translator and type to be used
697cdb89ebbSMatthew Wilber 	// to save the output image
698cdb89ebbSMatthew Wilber 	translator_id outTranslator;
699cdb89ebbSMatthew Wilber 	uint32 outType;
700cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TRANSLATOR_FLD,
701cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outTranslator)) != B_OK)
702cdb89ebbSMatthew Wilber 		return;
703cdb89ebbSMatthew Wilber 	if (pmsg->FindInt32(TYPE_FLD,
704cdb89ebbSMatthew Wilber 		reinterpret_cast<int32 *>(&outType)) != B_OK)
705cdb89ebbSMatthew Wilber 		return;
706cdb89ebbSMatthew Wilber 
707cdb89ebbSMatthew Wilber 	// Create the output file
708fc0a275bSMatthew Wilber 	BDirectory dir(&dirref);
709fc0a275bSMatthew Wilber 	BFile file(&dir, filename, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
710fc0a275bSMatthew Wilber 	if (file.InitCheck() != B_OK)
711fc0a275bSMatthew Wilber 		return;
712fc0a275bSMatthew Wilber 
713cdb89ebbSMatthew Wilber 	// Translate the image and write it out to the output file
7147eca0987SMichael Pfeiffer 	BBitmapStream stream(fpImageView->GetBitmap());
715fc0a275bSMatthew Wilber 	BTranslatorRoster *proster = BTranslatorRoster::Default();
716cdb89ebbSMatthew Wilber 	if (proster->Translate(outTranslator, &stream, NULL,
717cdb89ebbSMatthew Wilber 		&file, outType) != B_OK) {
718fc0a275bSMatthew Wilber 		BAlert *palert = new BAlert(NULL, "Error writing image file.", "Ok");
719fc0a275bSMatthew Wilber 		palert->Go();
720fc0a275bSMatthew Wilber 	}
721fc0a275bSMatthew Wilber 
722fc0a275bSMatthew Wilber 	BBitmap *pout = NULL;
723fc0a275bSMatthew Wilber 	stream.DetachBitmap(&pout);
724fc0a275bSMatthew Wilber 		// bitmap used by stream still belongs to the view,
725fc0a275bSMatthew Wilber 		// detach so it doesn't get deleted
726fc0a275bSMatthew Wilber }
727fc0a275bSMatthew Wilber 
728cdb89ebbSMatthew Wilber bool
729cdb89ebbSMatthew Wilber ShowImageWindow::CanQuit()
730cdb89ebbSMatthew Wilber {
7317eca0987SMichael Pfeiffer 	if (fpSavePanel)
732cdb89ebbSMatthew Wilber 		// Don't allow this window to be closed if a save panel is open
733cdb89ebbSMatthew Wilber 		return false;
734cdb89ebbSMatthew Wilber 	else
735cdb89ebbSMatthew Wilber 		return true;
736cdb89ebbSMatthew Wilber }
737cdb89ebbSMatthew Wilber 
738ad13f387SMichael Pfeiffer void
739ad13f387SMichael Pfeiffer ShowImageWindow::ToggleFullScreen()
740ad13f387SMichael Pfeiffer {
741ad13f387SMichael Pfeiffer 	BRect frame;
742ad13f387SMichael Pfeiffer 	fFullScreen = !fFullScreen;
743ad13f387SMichael Pfeiffer 	if (fFullScreen) {
744ad13f387SMichael Pfeiffer 		BScreen screen;
745ad13f387SMichael Pfeiffer 		fWindowFrame = Frame();
746ad13f387SMichael Pfeiffer 		frame = screen.Frame();
747ad13f387SMichael Pfeiffer 		frame.top -= fpBar->Bounds().Height()+1;
748ad13f387SMichael Pfeiffer 		frame.right += B_V_SCROLL_BAR_WIDTH;
749ad13f387SMichael Pfeiffer 		frame.bottom += B_H_SCROLL_BAR_HEIGHT;
750ad13f387SMichael Pfeiffer 		frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
751ad13f387SMichael Pfeiffer 
752ad13f387SMichael Pfeiffer 		SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
753da87390fSMichael Pfeiffer 		fpImageView->SetAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE);
754ad13f387SMichael Pfeiffer 	} else {
755ad13f387SMichael Pfeiffer 		frame = fWindowFrame;
756ad13f387SMichael Pfeiffer 
757ad13f387SMichael Pfeiffer 		SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
758da87390fSMichael Pfeiffer 		fpImageView->SetAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
759ad13f387SMichael Pfeiffer 	}
760e6a50d9cSMichael Pfeiffer 	fpImageView->SetShowCaption(fFullScreen && fShowCaption);
761ad13f387SMichael Pfeiffer 	MoveTo(frame.left, frame.top);
762ad13f387SMichael Pfeiffer 	ResizeTo(frame.Width(), frame.Height());
763ad13f387SMichael Pfeiffer }
764ad13f387SMichael Pfeiffer 
765cdb89ebbSMatthew Wilber bool
766780d8a62SMichael Pfeiffer ShowImageWindow::PageSetup()
767780d8a62SMichael Pfeiffer {
768780d8a62SMichael Pfeiffer 	status_t st;
769780d8a62SMichael Pfeiffer 	BString name;
770780d8a62SMichael Pfeiffer 	fpImageView->GetName(&name);
771780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
772780d8a62SMichael Pfeiffer 	if (fPrintSettings != NULL) {
773780d8a62SMichael Pfeiffer 		printJob.SetSettings(new BMessage(*fPrintSettings));
774780d8a62SMichael Pfeiffer 	}
775780d8a62SMichael Pfeiffer 	st = printJob.ConfigPage();
776780d8a62SMichael Pfeiffer 	if (st == B_OK) {
777780d8a62SMichael Pfeiffer 		delete fPrintSettings;
778780d8a62SMichael Pfeiffer 		fPrintSettings = printJob.Settings();
779780d8a62SMichael Pfeiffer 	}
780780d8a62SMichael Pfeiffer 	return st == B_OK;
781780d8a62SMichael Pfeiffer }
782780d8a62SMichael Pfeiffer 
783780d8a62SMichael Pfeiffer void
784780d8a62SMichael Pfeiffer ShowImageWindow::PrepareForPrint()
785780d8a62SMichael Pfeiffer {
786780d8a62SMichael Pfeiffer 	if (fPrintSettings == NULL && !PageSetup()) {
787780d8a62SMichael Pfeiffer 		return;
788780d8a62SMichael Pfeiffer 	}
789780d8a62SMichael Pfeiffer 
790780d8a62SMichael Pfeiffer 	fPrintOptions.SetBounds(fpImageView->GetBitmap()->Bounds());
791780d8a62SMichael Pfeiffer 	fPrintOptions.SetWidth(fpImageView->GetBitmap()->Bounds().Width()+1);
792780d8a62SMichael Pfeiffer 
793780d8a62SMichael Pfeiffer 	new PrintOptionsWindow(BPoint(Frame().left+30, Frame().top+50), &fPrintOptions, this);
794780d8a62SMichael Pfeiffer }
795780d8a62SMichael Pfeiffer 
796780d8a62SMichael Pfeiffer void
797780d8a62SMichael Pfeiffer ShowImageWindow::Print(BMessage *msg)
798780d8a62SMichael Pfeiffer {
799780d8a62SMichael Pfeiffer 	status_t st;
800780d8a62SMichael Pfeiffer 	if (msg->FindInt32("status", &st) != B_OK || st != B_OK) {
801780d8a62SMichael Pfeiffer 		return;
802780d8a62SMichael Pfeiffer 	}
803780d8a62SMichael Pfeiffer 
804780d8a62SMichael Pfeiffer 	BString name;
805780d8a62SMichael Pfeiffer 	fPrintOptions.SetBounds(fpImageView->GetBitmap()->Bounds());
806780d8a62SMichael Pfeiffer 	fpImageView->GetName(&name);
807780d8a62SMichael Pfeiffer 	BPrintJob printJob(name.String());
808780d8a62SMichael Pfeiffer 	printJob.SetSettings(new BMessage(*fPrintSettings));
809780d8a62SMichael Pfeiffer 	if (printJob.ConfigJob() == B_OK) {
810780d8a62SMichael Pfeiffer 		int32  firstPage;
811780d8a62SMichael Pfeiffer 		int32  lastPage;
812780d8a62SMichael Pfeiffer 		BRect  printableRect = printJob.PrintableRect();
813780d8a62SMichael Pfeiffer 		float width, imageWidth, imageHeight, w1, w2;
814780d8a62SMichael Pfeiffer 		BBitmap* bitmap;
815780d8a62SMichael Pfeiffer 
816780d8a62SMichael Pfeiffer 		// first/lastPage is unused for now
817780d8a62SMichael Pfeiffer 		firstPage = printJob.FirstPage();
818780d8a62SMichael Pfeiffer 		lastPage = printJob.LastPage();
819780d8a62SMichael Pfeiffer 		if (firstPage < 1) {
820780d8a62SMichael Pfeiffer 			firstPage = 1;
821780d8a62SMichael Pfeiffer 		}
822780d8a62SMichael Pfeiffer 		if (lastPage < firstPage) {
823780d8a62SMichael Pfeiffer 			lastPage = firstPage;
824780d8a62SMichael Pfeiffer 		}
825780d8a62SMichael Pfeiffer 
826780d8a62SMichael Pfeiffer 		bitmap = fpImageView->GetBitmap();
827780d8a62SMichael Pfeiffer 		imageWidth = bitmap->Bounds().Width() + 1.0;
828780d8a62SMichael Pfeiffer 		imageHeight = bitmap->Bounds().Height() + 1.0;
829780d8a62SMichael Pfeiffer 
830780d8a62SMichael Pfeiffer 		switch (fPrintOptions.Option()) {
831780d8a62SMichael Pfeiffer 			case PrintOptions::kFitToPage:
832780d8a62SMichael Pfeiffer 				w1 = printableRect.Width()+1;
833780d8a62SMichael Pfeiffer 				w2 = imageWidth * (printableRect.Height() + 1) / imageHeight;
834780d8a62SMichael Pfeiffer 				if (w2 < w1) {
835780d8a62SMichael Pfeiffer 					width = w2;
836780d8a62SMichael Pfeiffer 				} else {
837780d8a62SMichael Pfeiffer 					width = w1;
838780d8a62SMichael Pfeiffer 				}
839780d8a62SMichael Pfeiffer 				break;
840780d8a62SMichael Pfeiffer 			case PrintOptions::kZoomFactor:
841780d8a62SMichael Pfeiffer 				width = imageWidth * fPrintOptions.ZoomFactor();
842780d8a62SMichael Pfeiffer 				break;
843780d8a62SMichael Pfeiffer 			case PrintOptions::kDPI:
844780d8a62SMichael Pfeiffer 				width = imageWidth * 72.0 / fPrintOptions.DPI();
845780d8a62SMichael Pfeiffer 				break;
846780d8a62SMichael Pfeiffer 			case PrintOptions::kWidth:
847780d8a62SMichael Pfeiffer 			case PrintOptions::kHeight:
848780d8a62SMichael Pfeiffer 				width = fPrintOptions.Width();
849780d8a62SMichael Pfeiffer 				break;
850780d8a62SMichael Pfeiffer 			default:
851780d8a62SMichael Pfeiffer 				// keep compiler silent; should not reach here
852780d8a62SMichael Pfeiffer 				width = imageWidth;
853780d8a62SMichael Pfeiffer 		}
854780d8a62SMichael Pfeiffer 
855780d8a62SMichael Pfeiffer 		// XXX: eventually print large images on several pages
856780d8a62SMichael Pfeiffer 		printJob.BeginJob();
857780d8a62SMichael Pfeiffer 		fpImageView->SetScale(width / imageWidth);
858780d8a62SMichael Pfeiffer 		printJob.DrawView(fpImageView, bitmap->Bounds(), BPoint(printableRect.left, printableRect.top));
859780d8a62SMichael Pfeiffer 		fpImageView->SetScale(1.0);
860780d8a62SMichael Pfeiffer 		printJob.SpoolPage();
861780d8a62SMichael Pfeiffer 		printJob.CommitJob();
862780d8a62SMichael Pfeiffer 	}
863780d8a62SMichael Pfeiffer }
864780d8a62SMichael Pfeiffer 
865780d8a62SMichael Pfeiffer bool
866cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested()
867cdb89ebbSMatthew Wilber {
868cdb89ebbSMatthew Wilber 	return CanQuit();
869cdb89ebbSMatthew Wilber }
870cdb89ebbSMatthew Wilber 
87107caaa8eSMatthew Wilber void
87207caaa8eSMatthew Wilber ShowImageWindow::Quit()
87307caaa8eSMatthew Wilber {
87407caaa8eSMatthew Wilber 	// tell the app to forget about this window
87507caaa8eSMatthew Wilber 	be_app->PostMessage(MSG_WINDOW_QUIT);
87607caaa8eSMatthew Wilber 	BWindow::Quit();
87707caaa8eSMatthew Wilber }
878fc0a275bSMatthew Wilber 
879