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 31PrintOptions::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 42void 43PrintOptions::SetBounds(BRect rect) 44{ 45 fBounds = rect; 46} 47 48 49void 50PrintOptions::SetZoomFactor(float f) 51{ 52 fZoomFactor = f; 53 fDPI = 72.0 / fZoomFactor; 54} 55 56 57void 58PrintOptions::SetDPI(float dpi) 59{ 60 fDPI = dpi; 61 fZoomFactor = 72.0 / dpi; 62} 63 64 65void 66PrintOptions::SetWidth(float w) 67{ 68 fWidth = w; 69 fHeight = (fBounds.Height() + 1) * w / (fBounds.Width() + 1); 70} 71 72 73void 74PrintOptions::SetHeight(float h) 75{ 76 fWidth = (fBounds.Width() + 1) * h / (fBounds.Height() + 1); 77 fHeight = h; 78} 79 80 81PrintOptionsWindow::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 99PrintOptionsWindow::~PrintOptionsWindow() 100{ 101 BMessage msg(MSG_PRINT); 102 msg.AddInt32("status", fStatus); 103 fListener.SendMessage(&msg); 104} 105 106 107BRadioButton* 108PrintOptionsWindow::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 118BTextControl* 119PrintOptionsWindow::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 130void 131PrintOptionsWindow::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 202enum PrintOptions::Option 203PrintOptionsWindow::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 215bool 216PrintOptionsWindow::GetValue(BTextControl* text, float* value) 217{ 218 *value = atof(text->Text()); 219 return true; 220} 221 222 223void 224PrintOptionsWindow::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 237void 238PrintOptionsWindow::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