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