status_t PrinterDriver::PrintJob ( BFile *jobFile, // spool file BNode *printerNode, // printer node, used by OpenTransport() to find & load transport add-on BMessage *jobMsg // job message ) { print_file_header pfh; status_t status; BMessage *msg; int32 page; uint32 copy; uint32 copies; const int32 passes = 2; fJobFile = jobFile; fPrinterNode = printerNode; fJobMsg = jobMsg; if (!fJobFile || !fPrinterNode) return B_ERROR; if (fPrintTransport.Open(fPrinterNode) != B_OK) { return B_ERROR; } if (fPrintTransport.IsPrintToFileCanceled()) { return B_OK; } // read print file header fJobFile->Seek(0, SEEK_SET); fJobFile->Read(&pfh, sizeof(pfh)); // read job message fJobMsg = msg = new BMessage(); msg->Unflatten(fJobFile); // We have to load the settings here for Dano/Zeta because they don't store // all fields from the message returned by config_job in the job file! PrinterSettings::Read(printerNode, msg, PrinterSettings::kJobSettings); if (msg->HasInt32("copies")) { copies = msg->FindInt32("copies"); } else { copies = 1; } // force creation of Report object Report::Instance(); // show status window StatusWindow* statusWindow = new StatusWindow(passes, pfh.page_count, this); status = BeginJob(); fPrinting = true; for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) { for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++) { for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) { statusWindow->NextPage(); status = PrintPage(page, pfh.page_count); } // re-read job message for next page fJobFile->Seek(sizeof(pfh), SEEK_SET); msg->Unflatten(fJobFile); } } status_t s = EndJob(); if (status == B_OK) status = s; delete fJobMsg; // close status window if (Report::Instance()->CountItems() != 0) { statusWindow->WaitForClose(); } if (statusWindow->Lock()) { statusWindow->Quit(); } // delete Report object Report::Instance()->Free(); return status; }