xref: /haiku/src/libs/print/libprint/JobData.cpp (revision de18d919e7c940b402a6e213f7deb21e2f187e22)
1 /*
2  * JobData.cpp
3  * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
4  */
5 
6 #include "JobData.h"
7 
8 #include <InterfaceDefs.h>
9 #include <Message.h>
10 
11 #include <sstream>
12 
13 #include "PrinterCap.h"
14 #include "DbgMsg.h"
15 
16 static const char *kJDXRes                  = "xres";
17 static const char *kJDYRes                  = "yres";
18 static const char *kJDCopies                = "copies";
19 static const char *kJDOrientation           = "orientation";
20 static const char *kJDScaling               = "scale";
21 static const char *kJDScaledPaperRect       = "paper_rect";
22 static const char *kJDScaledPrintableRect   = "printable_rect";
23 static const char *kJDFirstPage             = "first_page";
24 static const char *kJDLastPage              = "last_page";
25 
26 static const char *kJDShowPreview           = "JJJJ_showPreview";
27 static const char *kJDPaper                 = "JJJJ_paper";
28 static const char *kJDNup                   = "JJJJ_nup";
29 static const char *kJDGamma                 = "JJJJ_gamma";
30 static const char *kJDInkDensity            = "JJJJ_ink_density";
31 static const char *kJDPaperSource           = "JJJJ_paper_source";
32 static const char *kJDCollate               = "JJJJ_collate";
33 static const char *kJDReverse               = "JJJJ_reverse";
34 static const char *kJDPrintStyle            = "JJJJ_print_style";
35 static const char *kJDBindingLocation       = "JJJJ_binding_location";
36 static const char *kJDPageOrder             = "JJJJ_page_order";
37 static const char *kJDColor                 = "JJJJ_color";
38 static const char *kJDDitherType            = "JJJJ_dither_type";
39 static const char *kJDPaperRect             = "JJJJ_paper_rect";
40 static const char* kJDPrintableRect         = "JJJJ_printable_rect";
41 static const char* kJDPageSelection         = "JJJJ_page_selection";
42 static const char* kJDMarginUnit            = "JJJJ_margin_unit";
43 static const char* kJDPhysicalRect          = "JJJJ_physical_rect";
44 static const char* kJDScaledPhysicalRect    = "JJJJ_scaled_physical_rect";
45 static const char* kJDResolution            = "JJJJ_resolution";
46 static const char* kJDDriverSpecificSettings = "JJJJ_driverSpecificSettings";
47 
48 static const char* kDriverSpecificSettingsSeparator = ";";
49 
50 
51 JobData::JobData(BMessage *msg, const PrinterCap *cap, Settings settings)
52 {
53 	load(msg, cap, settings);
54 }
55 
56 
57 JobData::~JobData()
58 {
59 }
60 
61 
62 JobData::JobData(const JobData &job_data)
63 {
64 	*this = job_data;
65 }
66 
67 
68 JobData&
69 JobData::operator=(const JobData &job_data)
70 {
71 	fShowPreview           = job_data.fShowPreview;
72 	fPaper                 = job_data.fPaper;
73 	fResolutionID          = job_data.fResolutionID;
74 	fXRes                  = job_data.fXRes;
75 	fYRes                  = job_data.fYRes;
76 	fOrientation           = job_data.fOrientation;
77 	fScaling               = job_data.fScaling;
78 	fPaperRect             = job_data.fPaperRect;
79 	fScaledPaperRect       = job_data.fScaledPaperRect;
80 	fPrintableRect         = job_data.fPrintableRect;
81 	fScaledPrintableRect   = job_data.fScaledPrintableRect;
82 	fNup                   = job_data.fNup;
83 	fFirstPage             = job_data.fFirstPage;
84 	fLastPage              = job_data.fLastPage;
85 	fGamma                 = job_data.fGamma;
86 	fInkDensity            = job_data.fInkDensity;
87 	fPaperSource           = job_data.fPaperSource;
88 	fCopies                = job_data.fCopies;
89 	fCollate               = job_data.fCollate;
90 	fReverse               = job_data.fReverse;
91 	fPrintStyle            = job_data.fPrintStyle;
92 	fBindingLocation       = job_data.fBindingLocation;
93 	fPageOrder             = job_data.fPageOrder;
94 	fSettings              = job_data.fSettings;
95 	fMsg                   = job_data.fMsg;
96 	fColor                 = job_data.fColor;
97 	fDitherType            = job_data.fDitherType;
98 	fPageSelection         = job_data.fPageSelection;
99 	fMarginUnit            = job_data.fMarginUnit;
100 	fPhysicalRect          = job_data.fPhysicalRect;
101 	fScaledPhysicalRect    = job_data.fScaledPhysicalRect;
102 	fDriverSpecificSettings = job_data.fDriverSpecificSettings;
103 	return *this;
104 }
105 
106 
107 void
108 JobData::load(BMessage *msg, const PrinterCap *cap, Settings settings)
109 {
110 	fMsg = msg;
111 	fSettings = settings;
112 
113 	const PaperCap *paperCap = NULL;
114 
115  	if (msg->HasBool(kJDShowPreview))
116  		fShowPreview = msg->FindBool(kJDShowPreview);
117  	else
118  		fShowPreview = false;
119 
120 	if (msg->HasInt32(kJDPaper))
121 		fPaper = (Paper)msg->FindInt32(kJDPaper);
122 	else if (cap->isSupport(PrinterCap::kPaper)) {
123 		paperCap = (const PaperCap *)cap->getDefaultCap(PrinterCap::kPaper);
124 		fPaper = paperCap->fPaper;
125 	} else
126 		fPaper = kA4;
127 
128 	if (msg->HasInt32(kJDResolution)) {
129 		msg->FindInt32(kJDResolution, &fResolutionID);
130 	} else if (cap->isSupport(PrinterCap::kResolution)) {
131 		fResolutionID = cap->getDefaultCap(PrinterCap::kResolution)->ID();
132 	} else {
133 		// should not reach here!
134 		fResolutionID = 0;
135 	}
136 
137 	if (msg->HasInt64(kJDXRes)) {
138 		int64 xres64;
139 		msg->FindInt64(kJDXRes, &xres64);
140 		fXRes = xres64;
141 	} else if (cap->isSupport(PrinterCap::kResolution)) {
142 		fXRes = ((const ResolutionCap *)cap->getDefaultCap(
143 			PrinterCap::kResolution))->fXResolution;
144 	} else {
145 		fXRes = 300;
146 	}
147 
148 	if (msg->HasInt64(kJDYRes)) {
149 		int64 yres64;
150 		msg->FindInt64(kJDYRes, &yres64);
151 		fYRes = yres64;
152 	} else if (cap->isSupport(PrinterCap::kResolution)) {
153 		fYRes = ((const ResolutionCap *)cap->getDefaultCap(
154 			PrinterCap::kResolution))->fYResolution;
155 	} else {
156 		fYRes = 300;
157 	}
158 
159 	if (msg->HasInt32(kJDOrientation))
160 		fOrientation = (Orientation)msg->FindInt32(kJDOrientation);
161 	else if (cap->isSupport(PrinterCap::kOrientation))
162 		fOrientation = ((const OrientationCap *)cap->getDefaultCap(
163 			PrinterCap::kOrientation))->fOrientation;
164 	else
165 		fOrientation = kPortrait;
166 
167 	if (msg->HasFloat(kJDScaling))
168 		fScaling = msg->FindFloat(kJDScaling);
169 	else
170 		fScaling = 100.0f;
171 
172 	if (msg->HasRect(kJDPaperRect)) {
173 		fPaperRect = msg->FindRect(kJDPaperRect);
174 	} else if (paperCap != NULL) {
175 		fPaperRect = paperCap->fPaperRect;
176 	}
177 
178 	if (msg->HasRect(kJDScaledPaperRect)) {
179 		fScaledPaperRect = msg->FindRect(kJDScaledPaperRect);
180 	} else {
181 		fScaledPaperRect = fPaperRect;
182 	}
183 
184 	if (msg->HasRect(kJDPrintableRect)) {
185 		fPrintableRect = msg->FindRect(kJDPrintableRect);
186 	} else if (paperCap != NULL) {
187 		fPrintableRect = paperCap->fPhysicalRect;
188 	}
189 
190 	if (msg->HasRect(kJDScaledPrintableRect)) {
191 		fScaledPrintableRect = msg->FindRect(kJDScaledPrintableRect);
192 	} else {
193 		fScaledPrintableRect = fPrintableRect;
194 	}
195 
196 	if (msg->HasRect(kJDPhysicalRect)) {
197 		fPhysicalRect = msg->FindRect(kJDPhysicalRect);
198 	} else if (paperCap != NULL) {
199 		fPhysicalRect = paperCap->fPhysicalRect;
200 	}
201 
202 	if (msg->HasRect(kJDScaledPhysicalRect)) {
203 		fScaledPhysicalRect = msg->FindRect(kJDScaledPhysicalRect);
204 	} else {
205 		fScaledPhysicalRect = fPhysicalRect;
206 	}
207 
208 	if (msg->HasInt32(kJDFirstPage))
209 		fFirstPage = msg->FindInt32(kJDFirstPage);
210 	else
211 		fFirstPage = 1;
212 
213 	if (msg->HasInt32(kJDLastPage))
214 		fLastPage = msg->FindInt32(kJDLastPage);
215 	else
216 		fLastPage = -1;
217 
218 	if (msg->HasInt32(kJDNup))
219 		fNup = msg->FindInt32(kJDNup);
220 	else
221 		fNup = 1;
222 
223 	if (msg->HasFloat(kJDGamma))
224 		fGamma = fMsg->FindFloat(kJDGamma);
225 	else
226 		fGamma = 0.25f;
227 
228 	if (msg->HasFloat(kJDInkDensity))
229 		fInkDensity = fMsg->FindFloat(kJDInkDensity);
230 	else
231 		fInkDensity = 0.0f;
232 
233 	if (msg->HasInt32(kJDPaperSource))
234 		fPaperSource = (PaperSource)fMsg->FindInt32(kJDPaperSource);
235 	else if (cap->isSupport(PrinterCap::kPaperSource))
236 		fPaperSource = ((const PaperSourceCap *)cap->getDefaultCap(
237 			PrinterCap::kPaperSource))->fPaperSource;
238 	else
239 		fPaperSource = kAuto;
240 
241 	if (msg->HasInt32(kJDCopies))
242 		fCopies = msg->FindInt32(kJDCopies);
243 	else
244 		fCopies = 1;
245 
246 	if (msg->HasBool(kJDCollate))
247 		fCollate = msg->FindBool(kJDCollate);
248 	else
249 		fCollate = false;
250 
251 	if (msg->HasBool(kJDReverse))
252 		fReverse = msg->FindBool(kJDReverse);
253 	else
254 		fReverse = false;
255 
256 	if (msg->HasInt32(kJDPrintStyle))
257 		fPrintStyle = (PrintStyle)msg->FindInt32(kJDPrintStyle);
258 	else if (cap->isSupport(PrinterCap::kPrintStyle))
259 		fPrintStyle = ((const PrintStyleCap *)cap->getDefaultCap(
260 			PrinterCap::kPrintStyle))->fPrintStyle;
261 	else
262 		fPrintStyle = kSimplex;
263 
264 	if (msg->HasInt32(kJDBindingLocation))
265 		fBindingLocation = (BindingLocation)msg->FindInt32(kJDBindingLocation);
266 	else if (cap->isSupport(PrinterCap::kBindingLocation))
267 		fBindingLocation = ((const BindingLocationCap *)cap->getDefaultCap(
268 			PrinterCap::kBindingLocation))->fBindingLocation;
269 	else
270 		fBindingLocation = kLongEdgeLeft;
271 
272 	if (msg->HasInt32(kJDPageOrder))
273 		fPageOrder = (PageOrder)msg->FindInt32(kJDPageOrder);
274 	else
275 		fPageOrder = kAcrossFromLeft;
276 
277 	if (msg->HasInt32(kJDColor))
278 		fColor = (Color)msg->FindInt32(kJDColor);
279 	else if (cap->isSupport(PrinterCap::kColor))
280 		fColor = ((const ColorCap *)cap->getDefaultCap(PrinterCap::kColor))
281 			->fColor;
282 	else
283 		fColor = kMonochrome;
284 
285 	if (msg->HasInt32(kJDDitherType))
286 		fDitherType = (Halftone::DitherType)msg->FindInt32(kJDDitherType);
287 	else
288 		fDitherType = Halftone::kTypeFloydSteinberg;
289 
290 	if (msg->HasInt32(kJDPageSelection))
291 		fPageSelection = (PageSelection)msg->FindInt32(kJDPageSelection);
292 	else
293 		fPageSelection = kAllPages;
294 
295 	if (msg->HasInt32(kJDMarginUnit))
296 		fMarginUnit = (MarginUnit)msg->FindInt32(kJDMarginUnit);
297 	else
298 		fMarginUnit = kUnitInch;
299 
300 	BString serializedSettings;
301 	if (msg->HasString(kJDDriverSpecificSettings))
302 		msg->FindString(kJDDriverSpecificSettings, &serializedSettings);
303 	DeserializePrinterSpecificSettings(serializedSettings);
304 }
305 
306 
307 void
308 JobData::save(BMessage *msg)
309 {
310 	if (msg == NULL) {
311 		msg = fMsg;
312 	}
313 
314 	// page settings
315 	msg->RemoveName(kJDPaper);
316 	msg->AddInt32(kJDPaper, fPaper);
317 
318 	msg->RemoveName(kJDResolution);
319 	msg->AddInt32(kJDResolution, fResolutionID);
320 
321 	msg->RemoveName(kJDXRes);
322 	msg->AddInt64(kJDXRes, fXRes);
323 
324 	msg->RemoveName(kJDYRes);
325 	msg->AddInt64(kJDYRes, fYRes);
326 
327 	msg->RemoveName(kJDOrientation);
328 	msg->AddInt32(kJDOrientation, fOrientation);
329 
330 	msg->RemoveName(kJDScaling);
331 	msg->AddFloat(kJDScaling, fScaling);
332 
333 	msg->RemoveName(kJDPaperRect);
334 	msg->AddRect(kJDPaperRect, fPaperRect);
335 
336 	msg->RemoveName(kJDScaledPaperRect);
337 	msg->AddRect(kJDScaledPaperRect, fScaledPaperRect);
338 
339 	msg->RemoveName(kJDPrintableRect);
340 	msg->AddRect(kJDPrintableRect, fPrintableRect);
341 
342 	msg->RemoveName(kJDScaledPrintableRect);
343 	msg->AddRect(kJDScaledPrintableRect, fScaledPrintableRect);
344 
345 	msg->RemoveName(kJDPhysicalRect);
346 	msg->AddRect(kJDPhysicalRect, fPhysicalRect);
347 
348 	msg->RemoveName(kJDScaledPhysicalRect);
349 	msg->AddRect(kJDScaledPhysicalRect, fScaledPhysicalRect);
350 
351 	msg->RemoveName(kJDMarginUnit);
352 	msg->AddInt32(kJDMarginUnit, fMarginUnit);
353 
354 	// page settings end here
355 
356 	// job settings
357 
358 	// make sure job settings are not present in page settings
359 	msg->RemoveName(kJDShowPreview);
360 	if (fSettings == kJobSettings)
361 		msg->AddBool(kJDShowPreview, fShowPreview);
362 
363 	msg->RemoveName(kJDNup);
364 	if (fSettings == kJobSettings)
365 		msg->AddInt32(kJDNup, fNup);
366 
367 	msg->RemoveName(kJDFirstPage);
368 	if (fSettings == kJobSettings)
369 		msg->AddInt32(kJDFirstPage, fFirstPage);
370 
371 	msg->RemoveName(kJDLastPage);
372 	if (fSettings == kJobSettings)
373 		msg->AddInt32(kJDLastPage, fLastPage);
374 
375 	msg->RemoveName(kJDGamma);
376 	if (fSettings == kJobSettings)
377 		msg->AddFloat(kJDGamma, fGamma);
378 
379 	msg->RemoveName(kJDInkDensity);
380 	if (fSettings == kJobSettings)
381 		msg->AddFloat(kJDInkDensity, fInkDensity);
382 
383 	msg->RemoveName(kJDPaperSource);
384 	if (fSettings == kJobSettings)
385 		msg->AddInt32(kJDPaperSource, fPaperSource);
386 
387 	msg->RemoveName(kJDCopies);
388 	if (fSettings == kJobSettings)
389 		msg->AddInt32(kJDCopies, fCopies);
390 
391 	msg->RemoveName(kJDCollate);
392 	if (fSettings == kJobSettings)
393 		msg->AddBool(kJDCollate, fCollate);
394 
395 	msg->RemoveName(kJDReverse);
396 	if (fSettings == kJobSettings)
397 		msg->AddBool(kJDReverse, fReverse);
398 
399 	msg->RemoveName(kJDPrintStyle);
400 	if (fSettings == kJobSettings)
401 		msg->AddInt32(kJDPrintStyle, fPrintStyle);
402 
403 	msg->RemoveName(kJDBindingLocation);
404 	if (fSettings == kJobSettings)
405 		msg->AddInt32(kJDBindingLocation, fBindingLocation);
406 
407 	msg->RemoveName(kJDPageOrder);
408 	if (fSettings == kJobSettings)
409 		msg->AddInt32(kJDPageOrder, fPageOrder);
410 
411 	msg->RemoveName(kJDColor);
412 	if (fSettings == kJobSettings)
413 		msg->AddInt32(kJDColor, fColor);
414 
415 	msg->RemoveName(kJDDitherType);
416 	if (fSettings == kJobSettings)
417 		msg->AddInt32(kJDDitherType, fDitherType);
418 
419 	msg->RemoveName(kJDPageSelection);
420 	if (fSettings == kJobSettings)
421 		msg->AddInt32(kJDPageSelection, fPageSelection);
422 
423 	msg->RemoveName(kJDDriverSpecificSettings);
424 	if (fSettings == kJobSettings)
425 	{
426 		BString serializedSettings;
427 		SerializePrinterSpecificSettings(serializedSettings);
428 		msg->AddString(kJDDriverSpecificSettings, serializedSettings);
429 	}
430 }
431 
432 
433 bool
434 JobData::HasDriverSpecificSetting(const string& category) const
435 {
436 	return fDriverSpecificSettings.find(category) !=
437 		fDriverSpecificSettings.end();
438 }
439 
440 
441 const string&
442 JobData::DriverSpecificSetting(const string& category) const
443 {
444 	return fDriverSpecificSettings.find(category)->second;
445 }
446 
447 
448 void
449 JobData::SetDriverSpecificSetting(const string& category, const string& value)
450 {
451 	fDriverSpecificSettings[category] = value;
452 }
453 
454 
455 void
456 JobData::SerializePrinterSpecificSettings(BString& serializedSettings)
457 {
458 	bool first = true;
459 	map<string, string>::iterator it = fDriverSpecificSettings.begin();
460 	for (; it != fDriverSpecificSettings.end(); it++) {
461 		if (first)
462 			first = false;
463 		else
464 			serializedSettings << kDriverSpecificSettingsSeparator;
465 
466 		serializedSettings << it->first.c_str()
467 			<< kDriverSpecificSettingsSeparator
468 			<< it->second.c_str();
469 	}
470 }
471 
472 
473 void
474 JobData::DeserializePrinterSpecificSettings(BString& serializedSettings)
475 {
476 	// Note: strtok_r terminates the string after the first token
477 	fDriverSpecificSettings.clear();
478 
479 	int length = serializedSettings.Length() + 1;
480 	char* state = NULL;
481 	char* buffer = serializedSettings.LockBuffer(length);
482 	const char* separator = kDriverSpecificSettingsSeparator;
483 	char* token = strtok_r(buffer, separator, &state);
484 	while (token != NULL) {
485 		char* key = token;
486 		token = strtok_r(NULL, separator, &state);
487 		if (token == NULL)
488 			break;
489 		char* value = token;
490 		fDriverSpecificSettings[key] = value;
491 		token = strtok_r(NULL, separator, &state);
492 	}
493 
494 	serializedSettings.UnlockBuffer(0);
495 }
496