xref: /haiku/src/apps/showimage/PrintOptionsWindow.cpp (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
1 /*
2  * Copyright 2003-2009, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Pfeiffer, laplace@haiku-os.org
7  */
8 
9 #include "PrintOptionsWindow.h"
10 
11 #include <stdio.h> // for sprintf
12 #include <stdlib.h> // for atof
13 
14 #include <Box.h>
15 #include <Button.h>
16 #include <Catalog.h>
17 #include <ControlLook.h>
18 #include <GridLayoutBuilder.h>
19 #include <GroupLayoutBuilder.h>
20 #include <LayoutBuilder.h>
21 #include <Locale.h>
22 #include <String.h>
23 
24 #include "ShowImageConstants.h"
25 
26 
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "PrintOptionsWindow"
29 
30 
31 PrintOptions::PrintOptions()
32 	:
33 	fOption(kFitToPage),
34 	fZoomFactor(1.0),
35 	fDPI(72.0),
36 	fWidth(1024 / 72.0),
37 	fHeight(768 / 72.0)
38 {
39 }
40 
41 
42 void
43 PrintOptions::SetBounds(BRect rect)
44 {
45 	fBounds = rect;
46 }
47 
48 
49 void
50 PrintOptions::SetZoomFactor(float f)
51 {
52 	fZoomFactor = f;
53 	fDPI = 72.0 / fZoomFactor;
54 }
55 
56 
57 void
58 PrintOptions::SetDPI(float dpi)
59 {
60 	fDPI = dpi;
61 	fZoomFactor = 72.0 / dpi;
62 }
63 
64 
65 void
66 PrintOptions::SetWidth(float w)
67 {
68 	fWidth = w;
69 	fHeight = (fBounds.Height() + 1) * w / (fBounds.Width() + 1);
70 }
71 
72 
73 void
74 PrintOptions::SetHeight(float h)
75 {
76 	fWidth = (fBounds.Width() + 1) * h / (fBounds.Height() + 1);
77 	fHeight = h;
78 }
79 
80 
81 PrintOptionsWindow::PrintOptionsWindow(BPoint at, PrintOptions* options,
82 	BWindow* listener)
83 	:
84 	BWindow(BRect(at.x, at.y, at.x + 300, at.y + 200),
85 		B_TRANSLATE("Print options"),
86 		B_TITLED_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
87 		B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS),
88 	fPrintOptions(options),
89 	fCurrentOptions(*options),
90 	fListener(listener),
91 	fStatus(B_ERROR)
92 {
93 	AddToSubset(listener);
94 	Setup();
95 	Show();
96 }
97 
98 
99 PrintOptionsWindow::~PrintOptionsWindow()
100 {
101 	BMessage msg(MSG_PRINT);
102 	msg.AddInt32("status", fStatus);
103 	fListener.SendMessage(&msg);
104 }
105 
106 
107 BRadioButton*
108 PrintOptionsWindow::AddRadioButton(const char* name,
109 	const char* label, uint32 what, bool selected)
110 {
111 	BRadioButton* button;
112 	button = new BRadioButton(name, label, new BMessage(what));
113 	button->SetValue(selected ? B_CONTROL_ON : B_CONTROL_OFF);
114 	return button;
115 }
116 
117 
118 BTextControl*
119 PrintOptionsWindow::AddTextControl(const char* name,
120 	const char* label, float value, uint32 what)
121 {
122 	BTextControl* text;
123 	text = new BTextControl(name, label, "", new BMessage(what));
124 	text->SetModificationMessage(new BMessage(what));
125 	SetValue(text, value);
126 	return text;
127 }
128 
129 
130 void
131 PrintOptionsWindow::Setup()
132 {
133 	BString value;
134 	enum PrintOptions::Option op = fCurrentOptions.Option();
135 	BRadioButton* rbFit;
136 	BRadioButton* rbZoom;
137 	BRadioButton* rbDpi;
138 	BRadioButton* rbResize;
139 	BBox* line;
140 	BButton* button;
141 
142 	rbFit = AddRadioButton("fit_to_page", B_TRANSLATE("Fit image to page"),
143 		kMsgFitToPageSelected, op == PrintOptions::kFitToPage);
144 
145 	rbZoom = AddRadioButton("zoom_factor", B_TRANSLATE("Zoom factor in %:"),
146 		kMsgZoomFactorSelected, op == PrintOptions::kZoomFactor);
147 
148 	fZoomFactor = AddTextControl("zoom_factor_text", "",
149 		fCurrentOptions.ZoomFactor() * 100, kMsgZoomFactorChanged);
150 
151 	rbDpi = AddRadioButton("dpi", B_TRANSLATE("DPI:"), kMsgDPISelected,
152 		op == PrintOptions::kDPI);
153 
154 	fDPI = AddTextControl("dpi_text", "", fCurrentOptions.DPI(),
155 		kMsgDPIChanged);
156 
157 	rbResize = AddRadioButton("width_and_height",
158 		B_TRANSLATE("Resize to (in 1/72 inches):"), kMsgWidthAndHeightSelected,
159 		op == PrintOptions::kWidth || op == PrintOptions::kHeight);
160 
161 	fWidth = AddTextControl("width", B_TRANSLATE("Width:"),
162 		fCurrentOptions.Width(), kMsgWidthChanged);
163 
164 	fHeight = AddTextControl("height", B_TRANSLATE("Height: "),
165 		fCurrentOptions.Height(), kMsgHeightChanged);
166 
167 	line = new BBox(B_EMPTY_STRING, B_WILL_DRAW | B_FRAME_EVENTS,
168 		B_FANCY_BORDER);
169 	line->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1));
170 
171 	button = new BButton("job setup", B_TRANSLATE("Job setup"),
172 		new BMessage(kMsgJobSetup));
173 	SetDefaultButton(button);
174 
175 	const float spacing = be_control_look->DefaultItemSpacing();
176 
177 	SetLayout(new BGroupLayout(B_HORIZONTAL));
178 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
179 		.Add(BGridLayoutBuilder()
180 				.Add(rbFit, 0, 0)
181 				.Add(rbZoom, 0, 1)
182 				.Add(fZoomFactor, 1, 1)
183 				.Add(rbDpi, 0, 2)
184 				.Add(fDPI, 1, 2)
185 				.Add(rbResize, 0, 3)
186 				)
187 		.AddGroup(B_HORIZONTAL, spacing)
188 			.Add(fWidth)
189 			.Add(fHeight)
190 			.AddGlue()
191 			.SetInsets(22, 0, 0, 0)
192 		.End()
193 		.Add(line)
194 		.AddGroup(B_HORIZONTAL, 0)
195 			.Add(button)
196 		.End()
197 		.SetInsets(spacing, spacing, spacing, spacing)
198 	);
199 }
200 
201 
202 enum PrintOptions::Option
203 PrintOptionsWindow::MsgToOption(uint32 what)
204 {
205 	switch (what) {
206 		case kMsgFitToPageSelected: return PrintOptions::kFitToPage;
207 		case kMsgZoomFactorSelected: return PrintOptions::kZoomFactor;
208 		case kMsgDPISelected: return PrintOptions::kDPI;
209 		case kMsgWidthAndHeightSelected: return PrintOptions::kWidth;
210 	}
211 	return PrintOptions::kFitToPage;
212 }
213 
214 
215 bool
216 PrintOptionsWindow::GetValue(BTextControl* text, float* value)
217 {
218 	*value = atof(text->Text());
219 	return true;
220 }
221 
222 
223 void
224 PrintOptionsWindow::SetValue(BTextControl* text, float value)
225 {
226 	BMessage* msg;
227 	char s[80];
228 	snprintf(s, sizeof(s), "%0.0f", value);
229 	// prevent sending a notification when text is set
230 	msg = new BMessage(*text->ModificationMessage());
231 	text->SetModificationMessage(NULL);
232 	text->SetText(s);
233 	text->SetModificationMessage(msg);
234 }
235 
236 
237 void
238 PrintOptionsWindow::MessageReceived(BMessage* msg)
239 {
240 	float value;
241 	switch (msg->what) {
242 		case kMsgFitToPageSelected:
243 		case kMsgZoomFactorSelected:
244 		case kMsgDPISelected:
245 		case kMsgWidthAndHeightSelected:
246 			fCurrentOptions.SetOption(MsgToOption(msg->what));
247 			break;
248 
249 		case kMsgZoomFactorChanged:
250 			if (GetValue(fZoomFactor, &value)
251 				&& fCurrentOptions.ZoomFactor() != value) {
252 				fCurrentOptions.SetZoomFactor(value / 100);
253 				SetValue(fDPI, fCurrentOptions.DPI());
254 			}
255 			break;
256 		case kMsgDPIChanged:
257 			if (GetValue(fDPI, &value) && fCurrentOptions.DPI() != value) {
258 				fCurrentOptions.SetDPI(value);
259 				SetValue(fZoomFactor, 100 * fCurrentOptions.ZoomFactor());
260 			}
261 			break;
262 		case kMsgWidthChanged:
263 			if (GetValue(fWidth, &value) && fCurrentOptions.Width() != value) {
264 				fCurrentOptions.SetWidth(value);
265 				SetValue(fHeight, fCurrentOptions.Height());
266 			}
267 			break;
268 		case kMsgHeightChanged:
269 			if (GetValue(fHeight, &value) && fCurrentOptions.Height() != value) {
270 				fCurrentOptions.SetHeight(value);
271 				SetValue(fWidth, fCurrentOptions.Width());
272 			}
273 			break;
274 
275 		case kMsgJobSetup:
276 			*fPrintOptions = fCurrentOptions;
277 			fStatus = B_OK;
278 			PostMessage(B_QUIT_REQUESTED);
279 			break;
280 
281 		default:
282 			BWindow::MessageReceived(msg);
283 	}
284 }
285 
286