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