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