xref: /haiku/src/servers/print/PrintServerApp.Scripting.cpp (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
1 /*
2  * Copyright 2001-2006, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ithamar R. Adema
7  */
8 
9 
10 #include "PrintServerApp.h"
11 
12 #include <stdio.h>
13 
14 #include <Catalog.h>
15 #include <Locale.h>
16 #include <PropertyInfo.h>
17 
18 #include "Transport.h"
19 #include "Printer.h"
20 
21 
22 #undef B_TRANSLATION_CONTEXT
23 #define B_TRANSLATION_CONTEXT "PrintServerApp Scripting"
24 
25 
26 static property_info prop_list[] = {
27 	{ "ActivePrinter", { B_GET_PROPERTY, B_SET_PROPERTY },
28 		{ B_DIRECT_SPECIFIER },
29 		B_TRANSLATE_MARK("Retrieve or select the active printer") },
30 	{ "Printer", { B_GET_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER,
31 		B_REVERSE_INDEX_SPECIFIER },
32 		B_TRANSLATE_MARK("Retrieve a specific printer") },
33 	{ "Printer", { B_CREATE_PROPERTY }, { B_DIRECT_SPECIFIER },
34 		B_TRANSLATE_MARK("Create a new printer") },
35 	{ "Printer", { B_DELETE_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER,
36 		B_REVERSE_INDEX_SPECIFIER },
37 		B_TRANSLATE_MARK("Delete a specific printer") },
38 	{ "Printers", { B_COUNT_PROPERTIES }, { B_DIRECT_SPECIFIER },
39 		B_TRANSLATE_MARK("Return the number of available printers") },
40 	{ "Transport", { B_GET_PROPERTY }, { B_INDEX_SPECIFIER, B_NAME_SPECIFIER,
41 		B_REVERSE_INDEX_SPECIFIER },
42 		B_TRANSLATE_MARK("Retrieve a specific transport") },
43 	{ "Transports", { B_COUNT_PROPERTIES }, { B_DIRECT_SPECIFIER },
44 		B_TRANSLATE_MARK("Return the number of available transports") },
45 	{ "UseConfigWindow", { B_GET_PROPERTY, B_SET_PROPERTY },
46 		{ B_DIRECT_SPECIFIER },
47 		B_TRANSLATE_MARK("Show configuration window") },
48 
49 	{ 0 } // terminate list
50 };
51 
52 
53 void
54 PrintServerApp::HandleScriptingCommand(BMessage* msg)
55 {
56 	BString propName;
57 	BMessage spec;
58 	int32 idx;
59 
60 	if (msg->GetCurrentSpecifier(&idx,&spec) == B_OK &&
61 		spec.FindString("property",&propName) == B_OK) {
62 		switch(msg->what) {
63 			case B_GET_PROPERTY:
64 				if (propName == "ActivePrinter") {
65 					BMessage reply(B_REPLY);
66 					reply.AddString("result", fDefaultPrinter
67 						? fDefaultPrinter->Name() : "");
68 					reply.AddInt32("error", B_OK);
69 					msg->SendReply(&reply);
70 				} else if (propName == "UseConfigWindow") {
71 					BMessage reply(B_REPLY);
72 					reply.AddString("result", fUseConfigWindow
73 						? "true" : "false");
74 					reply.AddInt32("error", B_OK);
75 					msg->SendReply(&reply);
76 				}
77 				break;
78 
79 			case B_SET_PROPERTY:
80 				if (propName == "ActivePrinter") {
81 					BString newActivePrinter;
82 					if (msg->FindString("data", &newActivePrinter) == B_OK) {
83 						BMessage reply(B_REPLY);
84 						reply.AddInt32("error",
85 							SelectPrinter(newActivePrinter.String()));
86 						msg->SendReply(&reply);
87 					}
88 				} else if (propName == "UseConfigWindow") {
89 					bool useConfigWindow;
90 					if (msg->FindBool("data", &useConfigWindow) == B_OK) {
91 						fUseConfigWindow = useConfigWindow;
92 						BMessage reply(B_REPLY);
93 						reply.AddInt32("error", fUseConfigWindow);
94 						msg->SendReply(&reply);
95 					}
96 				}
97 				break;
98 
99 			case B_CREATE_PROPERTY:
100 				if (propName == "Printer") {
101 					BString name, driver, transport, config;
102 
103 					if (msg->FindString("name", &name) == B_OK
104 						&& msg->FindString("driver", &driver) == B_OK
105 						&& msg->FindString("transport", &transport) == B_OK
106 						&& msg->FindString("config", &config) == B_OK) {
107 						BMessage reply(B_REPLY);
108 						reply.AddInt32("error", CreatePrinter(name.String(),
109 							driver.String(), "Local", transport.String(),
110 							config.String()));
111 						msg->SendReply(&reply);
112 					}
113 				}
114 				break;
115 
116 			case B_DELETE_PROPERTY: {
117 					Printer* printer = GetPrinterFromSpecifier(&spec);
118 					status_t rc = B_BAD_VALUE;
119 
120 					if (printer != NULL)
121 						rc=printer->Remove();
122 
123 					BMessage reply(B_REPLY);
124 					reply.AddInt32("error", rc);
125 					msg->SendReply(&reply);
126 				}
127 				break;
128 
129 			case B_COUNT_PROPERTIES:
130 				if (propName == "Printers") {
131 					BMessage reply(B_REPLY);
132 					reply.AddInt32("result", Printer::CountPrinters());
133 					reply.AddInt32("error", B_OK);
134 					msg->SendReply(&reply);
135 				} else if (propName == "Transports") {
136 					BMessage reply(B_REPLY);
137 					reply.AddInt32("result", Transport::CountTransports());
138 					reply.AddInt32("error", B_OK);
139 					msg->SendReply(&reply);
140 				}
141 				break;
142 		}
143 	}
144 }
145 
146 
147 Printer*
148 PrintServerApp::GetPrinterFromSpecifier(BMessage* msg)
149 {
150 	switch(msg->what) {
151 		case B_NAME_SPECIFIER:
152 		{
153 			BString name;
154 			if (msg->FindString("name", &name) == B_OK)
155 				return Printer::Find(name.String());
156 			break;
157 		}
158 
159 		case B_INDEX_SPECIFIER:
160 		{
161 			int32 idx;
162 			if (msg->FindInt32("index", &idx) == B_OK)
163 				return Printer::At(idx);
164 			break;
165 		}
166 
167 		case B_REVERSE_INDEX_SPECIFIER:
168 		{
169 			int32 idx;
170 			if (msg->FindInt32("index", &idx) == B_OK)
171 				return Printer::At(Printer::CountPrinters() - idx);
172 			break;
173 		}
174 	}
175 
176 	return NULL;
177 }
178 
179 
180 Transport*
181 PrintServerApp::GetTransportFromSpecifier(BMessage* msg)
182 {
183 	switch(msg->what) {
184 		case B_NAME_SPECIFIER:
185 		{
186 			BString name;
187 			if (msg->FindString("name", &name) == B_OK)
188 				return Transport::Find(name);
189 			break;
190 		}
191 
192 		case B_INDEX_SPECIFIER:
193 		{
194 			int32 idx;
195 			if (msg->FindInt32("index", &idx) == B_OK)
196 				return Transport::At(idx);
197 			break;
198 		}
199 
200 		case B_REVERSE_INDEX_SPECIFIER:
201 		{
202 			int32 idx;
203 			if (msg->FindInt32("index", &idx) == B_OK)
204 				return Transport::At(Transport::CountTransports() - idx);
205 			break;
206 		}
207 	}
208 
209 	return NULL;
210 }
211 
212 
213 BHandler*
214 PrintServerApp::ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec,
215 								int32 form, const char* prop)
216 {
217 	BPropertyInfo prop_info(prop_list);
218 	BHandler* rc = NULL;
219 
220 	int32 idx;
221 	switch( idx=prop_info.FindMatch(msg,0,spec,form,prop) ) {
222 		case B_ERROR:
223 			rc = Inherited::ResolveSpecifier(msg,index,spec,form,prop);
224 			break;
225 
226 		case 1:
227 			// GET Printer [arg]
228 			if ((rc=GetPrinterFromSpecifier(spec)) == NULL) {
229 				BMessage reply(B_REPLY);
230 				reply.AddInt32("error", B_BAD_INDEX);
231 				msg->SendReply(&reply);
232 			}
233 			else
234 				msg->PopSpecifier();
235 			break;
236 
237 		case 5:
238 			// GET Transport [arg]
239 			if ((rc=GetTransportFromSpecifier(spec)) == NULL) {
240 				BMessage reply(B_REPLY);
241 				reply.AddInt32("error", B_BAD_INDEX);
242 				msg->SendReply(&reply);
243 			}
244 			else
245 				msg->PopSpecifier();
246 			break;
247 
248 		default:
249 			rc = this;
250 	}
251 
252 	return rc;
253 }
254 
255 
256 status_t
257 PrintServerApp::GetSupportedSuites(BMessage* msg)
258 {
259 	msg->AddString("suites", "suite/vnd.OpenBeOS-printserver");
260 
261 	static bool localized = false;
262 	if (!localized) {
263 		localized = true;
264 		for (int i = 0; prop_list[i].name != NULL; i ++)
265 			prop_list[i].usage = B_TRANSLATE_NOCOLLECT(prop_list[i].usage);
266 	}
267 
268 	BPropertyInfo prop_info(prop_list);
269 	msg->AddFlat("messages", &prop_info);
270 
271 	return Inherited::GetSupportedSuites(msg);
272 }
273