Assorted whitespace cleanup and typo fixes.
[haiku.git] / src / kits / print / Jobs.cpp
blobaa60807040020ae976d616747170077853fab65d
1 /*****************************************************************************/
2 // Jobs
3 //
4 // Author
5 // Michael Pfeiffer
6 //
7 // This application and all source files used in its construction, except
8 // where noted, are licensed under the MIT License, and have been written
9 // and are:
11 // Copyright (c) 2002 OpenBeOS Project
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 /*****************************************************************************/
33 #include "pr_server.h"
34 #include "Jobs.h"
35 // #include "PrintServerApp.h"
37 // posix
38 #include <stdlib.h>
39 #include <string.h>
41 // BeOS
42 #include <kernel/fs_attr.h>
43 #include <Application.h>
44 #include <Node.h>
45 #include <NodeInfo.h>
46 #include <NodeMonitor.h>
49 // Implementation of Job
51 Job::Job(const BEntry& job, Folder* folder)
52 : fFolder(folder)
53 , fTime(-1)
54 , fStatus(kUnknown)
55 , fValid(false)
56 , fPrinter(NULL)
58 // store light weight versions of BEntry and BNode
59 job.GetRef(&fEntry);
60 job.GetNodeRef(&fNode);
62 fValid = IsValidJobFile();
64 BNode node(&job);
65 if (node.InitCheck() != B_OK) return;
67 BString status;
68 // read status attribute
69 if (node.ReadAttrString(PSRV_SPOOL_ATTR_STATUS, &status) != B_OK) {
70 status = "";
72 UpdateStatus(status.String());
74 // Now get file name and creation time from file name
75 fTime = 0;
76 BEntry entry(job);
77 char name[B_FILE_NAME_LENGTH];
78 if (entry.InitCheck() == B_OK && entry.GetName(name) == B_OK) {
79 fName = name;
80 // search for last '@' in file name
81 char* p = NULL, *c = name;
82 while ((c = strchr(c, '@')) != NULL) {
83 p = c; c ++;
85 // and get time from file name
86 if (p) fTime = atoi(p+1);
90 // conversion from string representation of status to JobStatus constant
91 void Job::UpdateStatus(const char* status) {
92 if (strcmp(status, PSRV_JOB_STATUS_WAITING) == 0) fStatus = kWaiting;
93 else if (strcmp(status, PSRV_JOB_STATUS_PROCESSING) == 0) fStatus = kProcessing;
94 else if (strcmp(status, PSRV_JOB_STATUS_FAILED) == 0) fStatus = kFailed;
95 else if (strcmp(status, PSRV_JOB_STATUS_COMPLETED) == 0) fStatus = kCompleted;
96 else fStatus = kUnknown;
99 // Write to status attribute of node
100 void Job::UpdateStatusAttribute(const char* status) {
101 BNode node(&fEntry);
102 if (node.InitCheck() == B_OK) {
103 node.WriteAttr(PSRV_SPOOL_ATTR_STATUS, B_STRING_TYPE, 0, status, strlen(status)+1);
108 bool Job::HasAttribute(BNode* n, const char* name) {
109 attr_info info;
110 return n->GetAttrInfo(name, &info) == B_OK;
114 bool Job::IsValidJobFile() {
115 BNode node(&fEntry);
116 if (node.InitCheck() != B_OK) return false;
118 BNodeInfo info(&node);
119 char mimeType[256];
121 // Is job a spool file?
122 return (info.InitCheck() == B_OK &&
123 info.GetType(mimeType) == B_OK &&
124 strcmp(mimeType, PSRV_SPOOL_FILETYPE) == 0) &&
125 HasAttribute(&node, PSRV_SPOOL_ATTR_MIMETYPE) &&
126 HasAttribute(&node, PSRV_SPOOL_ATTR_PAGECOUNT) &&
127 HasAttribute(&node, PSRV_SPOOL_ATTR_DESCRIPTION) &&
128 HasAttribute(&node, PSRV_SPOOL_ATTR_PRINTER) &&
129 HasAttribute(&node, PSRV_SPOOL_ATTR_STATUS);
133 // Set status of object and optionally write to attribute of node
134 void Job::SetStatus(JobStatus s, bool writeToNode) {
135 fStatus = s;
136 if (!writeToNode) return;
137 switch (s) {
138 case kWaiting: UpdateStatusAttribute(PSRV_JOB_STATUS_WAITING); break;
139 case kProcessing: UpdateStatusAttribute(PSRV_JOB_STATUS_PROCESSING); break;
140 case kFailed: UpdateStatusAttribute(PSRV_JOB_STATUS_FAILED); break;
141 case kCompleted: UpdateStatusAttribute(PSRV_JOB_STATUS_COMPLETED); break;
142 default: break;
146 // Synchronize file attribute with member variable
147 void Job::UpdateAttribute() {
148 fValid = fValid || IsValidJobFile();
149 BNode node(&fEntry);
150 BString status;
151 if (node.InitCheck() == B_OK &&
152 node.ReadAttrString(PSRV_SPOOL_ATTR_STATUS, &status) == B_OK) {
153 UpdateStatus(status.String());
157 void Job::Remove() {
158 BEntry entry(&fEntry);
159 if (entry.InitCheck() == B_OK) entry.Remove();
162 // Implementation of Folder
164 // BObjectList CompareFunction
165 int Folder::AscendingByTime(const Job* a, const Job* b) {
166 return a->Time() - b->Time();
169 bool Folder::AddJob(BEntry& entry, bool notify) {
170 Job* job = new Job(entry, this);
171 if (job->InitCheck() == B_OK) {
172 fJobs.AddItem(job);
173 if (notify) Notify(job, kJobAdded);
174 return true;
175 } else {
176 job->Release();
177 return false;
181 // simplified assumption that ino_t identifies job file
182 // will probabely not work in all cases with link to a file on another volume???
183 Job* Folder::Find(node_ref* node) {
184 for (int i = 0; i < fJobs.CountItems(); i ++) {
185 Job* job = fJobs.ItemAt(i);
186 if (job->NodeRef() == *node) return job;
188 return NULL;
191 void Folder::EntryCreated(node_ref* node, entry_ref* entry) {
192 BEntry job(entry);
193 if (job.InitCheck() == B_OK && Lock()) {
194 if (AddJob(job)) {
195 fJobs.SortItems(AscendingByTime);
197 Unlock();
201 void Folder::EntryRemoved(node_ref* node) {
202 Job* job = Find(node);
203 if (job && Lock()) {
204 fJobs.RemoveItem(job);
205 Notify(job, kJobRemoved);
206 job->Release();
207 Unlock();
211 void Folder::AttributeChanged(node_ref* node) {
212 Job* job = Find(node);
213 if (job && Lock()) {
214 job->UpdateAttribute();
215 Notify(job, kJobAttrChanged);
216 Unlock();
220 // initial setup of job list
221 void Folder::SetupJobList() {
222 if (inherited::Folder()->InitCheck() == B_OK) {
223 inherited::Folder()->Rewind();
225 BEntry entry;
226 while (inherited::Folder()->GetNextEntry(&entry) == B_OK) {
227 AddJob(entry, false);
229 fJobs.SortItems(AscendingByTime);
233 Folder::Folder(BLocker* locker, BLooper* looper, const BDirectory& spoolDir)
234 : FolderWatcher(looper, spoolDir, true)
235 , fLocker(locker)
236 , fJobs()
238 SetListener(this);
239 if (Lock()) {
240 SetupJobList();
241 Unlock();
246 Folder::~Folder() {
247 if (!Lock()) return;
248 // release jobs
249 for (int i = 0; i < fJobs.CountItems(); i ++) {
250 Job* job = fJobs.ItemAt(i);
251 job->Release();
253 Unlock();
256 Job* Folder::GetNextJob() {
257 for (int i = 0; i < fJobs.CountItems(); i ++) {
258 Job* job = fJobs.ItemAt(i);
259 if (job->IsValid() && job->IsWaiting()) {
260 job->Acquire(); return job;
263 return NULL;