haiku/src/apps/showimage/PrintOptionsWindow.cpp

286 lines
6.3 KiB
C++

/*
* Copyright 2003-2009, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Pfeiffer, laplace@haiku-os.org
*/
#include "PrintOptionsWindow.h"
#include <stdio.h> // for sprintf
#include <stdlib.h> // for atof
#include <Box.h>
#include <Button.h>
#include <Catalog.h>
#include <ControlLook.h>
#include <GridLayoutBuilder.h>
#include <GroupLayoutBuilder.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <String.h>
#include "ShowImageConstants.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "PrintOptionsWindow"
PrintOptions::PrintOptions()
:
fOption(kFitToPage),
fZoomFactor(1.0),
fDPI(72.0),
fWidth(1024 / 72.0),
fHeight(768 / 72.0)
{
}
void
PrintOptions::SetBounds(BRect rect)
{
fBounds = rect;
}
void
PrintOptions::SetZoomFactor(float f)
{
fZoomFactor = f;
fDPI = 72.0 / fZoomFactor;
}
void
PrintOptions::SetDPI(float dpi)
{
fDPI = dpi;
fZoomFactor = 72.0 / dpi;
}
void
PrintOptions::SetWidth(float w)
{
fWidth = w;
fHeight = (fBounds.Height() + 1) * w / (fBounds.Width() + 1);
}
void
PrintOptions::SetHeight(float h)
{
fWidth = (fBounds.Width() + 1) * h / (fBounds.Height() + 1);
fHeight = h;
}
PrintOptionsWindow::PrintOptionsWindow(BPoint at, PrintOptions* options,
BWindow* listener)
:
BWindow(BRect(at.x, at.y, at.x + 300, at.y + 200),
B_TRANSLATE("Print options"),
B_TITLED_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS),
fPrintOptions(options),
fCurrentOptions(*options),
fListener(listener),
fStatus(B_ERROR)
{
AddToSubset(listener);
Setup();
Show();
}
PrintOptionsWindow::~PrintOptionsWindow()
{
BMessage msg(MSG_PRINT);
msg.AddInt32("status", fStatus);
fListener.SendMessage(&msg);
}
BRadioButton*
PrintOptionsWindow::AddRadioButton(const char* name,
const char* label, uint32 what, bool selected)
{
BRadioButton* button;
button = new BRadioButton(name, label, new BMessage(what));
button->SetValue(selected ? B_CONTROL_ON : B_CONTROL_OFF);
return button;
}
BTextControl*
PrintOptionsWindow::AddTextControl(const char* name,
const char* label, float value, uint32 what)
{
BTextControl* text;
text = new BTextControl(name, label, "", new BMessage(what));
text->SetModificationMessage(new BMessage(what));
SetValue(text, value);
return text;
}
void
PrintOptionsWindow::Setup()
{
BString value;
enum PrintOptions::Option op = fCurrentOptions.Option();
BRadioButton* rbFit;
BRadioButton* rbZoom;
BRadioButton* rbDpi;
BRadioButton* rbResize;
BBox* line;
BButton* button;
rbFit = AddRadioButton("fit_to_page", B_TRANSLATE("Fit image to page"),
kMsgFitToPageSelected, op == PrintOptions::kFitToPage);
rbZoom = AddRadioButton("zoom_factor", B_TRANSLATE("Zoom factor in %:"),
kMsgZoomFactorSelected, op == PrintOptions::kZoomFactor);
fZoomFactor = AddTextControl("zoom_factor_text", "",
fCurrentOptions.ZoomFactor() * 100, kMsgZoomFactorChanged);
rbDpi = AddRadioButton("dpi", B_TRANSLATE("DPI:"), kMsgDPISelected,
op == PrintOptions::kDPI);
fDPI = AddTextControl("dpi_text", "", fCurrentOptions.DPI(),
kMsgDPIChanged);
rbResize = AddRadioButton("width_and_height",
B_TRANSLATE("Resize to (in 1/72 inches):"), kMsgWidthAndHeightSelected,
op == PrintOptions::kWidth || op == PrintOptions::kHeight);
fWidth = AddTextControl("width", B_TRANSLATE("Width:"),
fCurrentOptions.Width(), kMsgWidthChanged);
fHeight = AddTextControl("height", B_TRANSLATE("Height: "),
fCurrentOptions.Height(), kMsgHeightChanged);
line = new BBox(B_EMPTY_STRING, B_WILL_DRAW | B_FRAME_EVENTS,
B_FANCY_BORDER);
line->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1));
button = new BButton("job setup", B_TRANSLATE("Job setup"),
new BMessage(kMsgJobSetup));
SetDefaultButton(button);
const float spacing = be_control_look->DefaultItemSpacing();
SetLayout(new BGroupLayout(B_HORIZONTAL));
AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
.Add(BGridLayoutBuilder()
.Add(rbFit, 0, 0)
.Add(rbZoom, 0, 1)
.Add(fZoomFactor, 1, 1)
.Add(rbDpi, 0, 2)
.Add(fDPI, 1, 2)
.Add(rbResize, 0, 3)
)
.AddGroup(B_HORIZONTAL, spacing)
.Add(fWidth)
.Add(fHeight)
.AddGlue()
.SetInsets(22, 0, 0, 0)
.End()
.Add(line)
.AddGroup(B_HORIZONTAL, 0)
.Add(button)
.End()
.SetInsets(spacing, spacing, spacing, spacing)
);
}
enum PrintOptions::Option
PrintOptionsWindow::MsgToOption(uint32 what)
{
switch (what) {
case kMsgFitToPageSelected: return PrintOptions::kFitToPage;
case kMsgZoomFactorSelected: return PrintOptions::kZoomFactor;
case kMsgDPISelected: return PrintOptions::kDPI;
case kMsgWidthAndHeightSelected: return PrintOptions::kWidth;
}
return PrintOptions::kFitToPage;
}
bool
PrintOptionsWindow::GetValue(BTextControl* text, float* value)
{
*value = atof(text->Text());
return true;
}
void
PrintOptionsWindow::SetValue(BTextControl* text, float value)
{
BMessage* msg;
char s[80];
snprintf(s, sizeof(s), "%0.0f", value);
// prevent sending a notification when text is set
msg = new BMessage(*text->ModificationMessage());
text->SetModificationMessage(NULL);
text->SetText(s);
text->SetModificationMessage(msg);
}
void
PrintOptionsWindow::MessageReceived(BMessage* msg)
{
float value;
switch (msg->what) {
case kMsgFitToPageSelected:
case kMsgZoomFactorSelected:
case kMsgDPISelected:
case kMsgWidthAndHeightSelected:
fCurrentOptions.SetOption(MsgToOption(msg->what));
break;
case kMsgZoomFactorChanged:
if (GetValue(fZoomFactor, &value)
&& fCurrentOptions.ZoomFactor() != value) {
fCurrentOptions.SetZoomFactor(value / 100);
SetValue(fDPI, fCurrentOptions.DPI());
}
break;
case kMsgDPIChanged:
if (GetValue(fDPI, &value) && fCurrentOptions.DPI() != value) {
fCurrentOptions.SetDPI(value);
SetValue(fZoomFactor, 100 * fCurrentOptions.ZoomFactor());
}
break;
case kMsgWidthChanged:
if (GetValue(fWidth, &value) && fCurrentOptions.Width() != value) {
fCurrentOptions.SetWidth(value);
SetValue(fHeight, fCurrentOptions.Height());
}
break;
case kMsgHeightChanged:
if (GetValue(fHeight, &value) && fCurrentOptions.Height() != value) {
fCurrentOptions.SetHeight(value);
SetValue(fWidth, fCurrentOptions.Width());
}
break;
case kMsgJobSetup:
*fPrintOptions = fCurrentOptions;
fStatus = B_OK;
PostMessage(B_QUIT_REQUESTED);
break;
default:
BWindow::MessageReceived(msg);
}
}