#include "GPBinding.h"
#include <list>
#include <set>
#include <string>
#include <gutenprint/gutenprint.h>
#include "GPCapabilityExtractor.h"
using namespace std;
static const char* kManufacturerId = "id";
static const char* kManufacturerDisplayName = "name";
static const char* kModelDisplayName = "model";
static const char* kModelDriver = "driver";
GPBinding::GPBinding()
:
fInitialized(false),
fOutputStream(NULL)
{
}
GPBinding::~GPBinding()
{
DeleteBands();
}
status_t
GPBinding::GetPrinterManufacturers(BMessage& manufacturers)
{
InitGutenprint();
list<string> ids;
set<string> manufacturerSet;
for (int i = 0; i < stp_printer_model_count(); i ++) {
const stp_printer_t* printer = stp_get_printer_by_index(i);
string manufacturer = stp_printer_get_manufacturer(printer);
if (manufacturer == "")
continue;
if (manufacturerSet.find(manufacturer) != manufacturerSet.end())
continue;
manufacturerSet.insert(manufacturer);
ids.push_back(manufacturer);
}
ids.sort();
list<string>::iterator it = ids.begin();
for (; it != ids.end(); it ++) {
string manufacturer = *it;
const char* id = manufacturer.c_str();
const char* name = manufacturer.c_str();
AddManufacturer(manufacturers, id, name);
}
return B_OK;
}
bool
GPBinding::ExtractManufacturer(const BMessage& manufacturers, int32 index,
BString& id, BString& displayName)
{
if (manufacturers.FindString(kManufacturerId, index, &id) != B_OK)
return false;
if (manufacturers.FindString(kManufacturerDisplayName, index, &displayName)
!= B_OK)
return false;
return true;
}
void
GPBinding::AddManufacturer(BMessage& manufacturers, const char* id,
const char* displayName)
{
manufacturers.AddString(kManufacturerId, id);
manufacturers.AddString(kManufacturerDisplayName, displayName);
}
status_t
GPBinding::GetPrinterModels(const char* manufacturer, BMessage& models)
{
for (int i = 0; i < stp_printer_model_count(); i ++) {
const stp_printer_t* printer = stp_get_printer_by_index(i);
if (strcmp(manufacturer, stp_printer_get_manufacturer(printer)) != 0)
continue;
const char* displayName = stp_printer_get_long_name(printer);
const char* driver = stp_printer_get_driver(printer);
AddModel(models, displayName, driver);
}
return B_OK;
}
bool
GPBinding::ExtractModel(const BMessage& models, int32 index, BString& displayName,
BString& driver)
{
if (models.FindString(kModelDisplayName, index, &displayName) != B_OK)
return false;
if (models.FindString(kModelDriver, index, &driver) != B_OK)
return false;
return true;
}
void
GPBinding::AddModel(BMessage& models, const char* displayName, const char* driver)
{
models.AddString(kModelDisplayName, displayName);
models.AddString(kModelDriver, driver);
}
status_t
GPBinding::GetCapabilities(const char* driver, GPCapabilities* capabilities)
{
InitGutenprint();
const stp_printer_t* printer = stp_get_printer_by_driver(driver);
if (printer == NULL)
return B_ERROR;
GPCapabilityExtractor extractor(capabilities);
extractor.Visit(printer);
return B_OK;
}
status_t
GPBinding::BeginJob(GPJobConfiguration* configuration,
OutputStream* outputStream)
{
fOutputStream = outputStream;
fJob.SetApplicationName("Gutenprint");
fJob.SetConfiguration(configuration);
fJob.SetOutputStream(outputStream);
return fJob.Begin();
}
void
GPBinding::EndJob()
{
fJob.End();
fOutputStream = NULL;
}
void
GPBinding::BeginPage()
{
}
void
GPBinding::EndPage()
{
status_t status = fJob.PrintPage(fBands);
DeleteBands();
if (status == B_IO_ERROR)
throw TransportException("I/O Error");
if (status == B_ERROR) {
BString message;
fJob.GetErrorMessage(message);
throw TransportException(message.String());
}
}
status_t
GPBinding::AddBitmapToPage(BBitmap* bitmap, BRect validRect, BPoint where)
{
GPBand* band = new(nothrow) GPBand(bitmap, validRect, where);
if (band == NULL) {
return B_NO_MEMORY;
}
fBands.push_back(band);
return B_OK;
}
void
GPBinding::InitGutenprint()
{
if (fInitialized)
return;
fInitialized = true;
stp_init();
stp_set_output_codeset("UTF-8");
}
void
GPBinding::DeleteBands()
{
list<GPBand*>::iterator it = fBands.begin();
for (; it != fBands.end(); it ++) {
GPBand* band = *it;
delete band;
}
fBands.clear();
}