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:
10//
11// Copyright (c) 2002 Haiku Project
12//
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:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
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/*****************************************************************************/
31
32#ifndef _JOBS_H
33#define _JOBS_H
34
35#include "BeUtils.h"
36#include "ObjectList.h"
37#include "FolderWatcher.h"
38
39#include <Directory.h>
40#include <Entry.h>
41#include <Handler.h>
42#include <Locker.h>
43#include <String.h>
44#include <StorageDefs.h>
45
46
47enum JobStatus {  // job file
48	kWaiting,     //   to be processed
49	kProcessing,  //   processed by a printer add-on
50	kFailed,      //   failed to process the job file
51	kCompleted,   //   successfully processed
52	kUnknown,     //   other
53};
54
55class Printer;
56class Folder;
57
58// Job file in printer folder
59class Job : public Object {
60private:
61	Folder* fFolder;      // the handler that watches the node of the job file
62	BString fName;        // the name of the job file
63	long fTime;           // the time encoded in the file name
64	node_ref fNode;       // the node of the job file
65	entry_ref fEntry;     // the entry of the job file
66	JobStatus fStatus;    // the status of the job file
67	bool fValid;          // is this a valid job file?
68	Printer* fPrinter;    // the printer that processes this job
69
70	void UpdateStatus(const char* status);
71	void UpdateStatusAttribute(const char* status);
72	bool HasAttribute(BNode* node, const char* name);
73	bool IsValidJobFile();
74
75public:
76	Job(const BEntry& entry, Folder* folder);
77
78	status_t InitCheck() const        { return fTime >= 0 ? B_OK : B_ERROR; }
79
80	// accessors
81	const BString& Name() const       { return fName; }
82	JobStatus Status() const          { return fStatus; }
83	bool IsValid() const              { return fValid; }
84	long Time() const                 { return fTime; }
85	const node_ref& NodeRef() const   { return fNode; }
86	const entry_ref& EntryRef() const { return fEntry; }
87	bool IsWaiting() const            { return fStatus == kWaiting; }
88	Printer* GetPrinter() const       { return fPrinter; }
89
90	// modifiers
91	void SetPrinter(Printer* p) { fPrinter = p; }
92	void SetStatus(JobStatus s, bool writeToNode = true);
93	void UpdateAttribute();
94	void Remove();
95};
96
97
98// Printer folder watches creation, deletion and attribute changes of job files
99// and notifies print_server if a job is waiting for processing
100class Folder : public FolderWatcher, public FolderListener {
101	typedef FolderWatcher inherited;
102
103private:
104	BLocker* fLocker;
105	BObjectList<Job> fJobs;
106
107	static int AscendingByTime(const Job* a, const Job* b);
108
109	bool AddJob(BEntry& entry, bool notify = true);
110	Job* Find(node_ref* node);
111
112	// FolderListener
113	void EntryCreated(node_ref* node, entry_ref* entry);
114	void EntryRemoved(node_ref* node);
115	void AttributeChanged(node_ref* node);
116
117	void SetupJobList();
118
119protected:
120	enum {
121		kJobAdded,
122		kJobRemoved,
123		kJobAttrChanged,
124	};
125	virtual void Notify(Job* job, int kind) = 0;
126
127public:
128	Folder(BLocker* fLocker, BLooper* looper, const BDirectory& spoolDir);
129	~Folder();
130
131	BDirectory* GetSpoolDir() { return inherited::Folder(); }
132
133	BLocker* Locker() const { return fLocker; }
134	bool Lock() const       { return fLocker != NULL ? fLocker->Lock() : true; }
135	void Unlock() const     { if (fLocker) fLocker->Unlock(); }
136
137	int32 CountJobs() const { return fJobs.CountItems(); }
138	Job* JobAt(int i) const { return fJobs.ItemAt(i); }
139
140		// Caller is responsible to set the status of the job appropriately
141		// and to release the object when done
142	Job* GetNextJob();
143};
144#endif
145