xref: /haiku/src/add-ons/print/transports/ipp/IppSetupDlg.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
1 // Sun, 18 Jun 2000
2 // Y.Takagi
3 
4 #include <string.h>
5 #include <strings.h>
6 
7 #include <Alert.h>
8 #include <Button.h>
9 #include <Directory.h>
10 #include <Rect.h>
11 #include <TextControl.h>
12 #include <View.h>
13 #include <Url.h>
14 
15 #include "IppContent.h"
16 #include "IppURLConnection.h"
17 #include "IppSetupDlg.h"
18 #include "IppDefs.h"
19 #include "DbgMsg.h"
20 
21 #define	DLG_WIDTH		350
22 #define DLG_HEIGHT		80
23 
24 #define BUTTON_WIDTH	70
25 #define BUTTON_HEIGHT	20
26 
27 #define URL_H			10
28 #define URL_V			10
29 #define URL_WIDTH		(DLG_WIDTH - URL_H - URL_H)
30 #define URL_HEIGHT		20
31 #define URL_TEXT		"URL"
32 
33 #define OK_H			(DLG_WIDTH  - BUTTON_WIDTH  - 11)
34 #define OK_V			(DLG_HEIGHT - BUTTON_HEIGHT - 11)
35 #define OK_TEXT			"OK"
36 
37 #define CANCEL_H		(OK_H - BUTTON_WIDTH - 12)
38 #define CANCEL_V		OK_V
39 #define CANCEL_TEXT		"Cancel"
40 
41 
42 const BRect URL_RECT(
43 	URL_H,
44 	URL_V,
45 	URL_H + URL_WIDTH,
46 	URL_V + URL_HEIGHT);
47 
48 const BRect OK_RECT(
49 	OK_H,
50 	OK_V,
51 	OK_H + BUTTON_WIDTH,
52 	OK_V + BUTTON_HEIGHT);
53 
54 const BRect CANCEL_RECT(
55 	CANCEL_H,
56 	CANCEL_V,
57 	CANCEL_H + BUTTON_WIDTH,
58 	CANCEL_V + BUTTON_HEIGHT);
59 
60 enum MSGS {
61 	M_CANCEL = 1,
62 	M_OK
63 };
64 
65 
66 class IppSetupView : public BView {
67 public:
68 	IppSetupView(BRect, BDirectory *);
69 	~IppSetupView() {}
70 	virtual void AttachedToWindow();
71 	bool UpdateViewData();
72 
73 private:
74 	BTextControl *url;
75 	BDirectory *dir;
76 };
77 
78 IppSetupView::IppSetupView(BRect frame, BDirectory *d)
79 	: BView(frame, "", B_FOLLOW_ALL, B_WILL_DRAW), dir(d)
80 {
81 	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
82 }
83 
84 void IppSetupView::AttachedToWindow()
85 {
86 	/* url box */
87 
88 	url = new BTextControl(URL_RECT, "", URL_TEXT, "", NULL);
89 	AddChild(url);
90 	url->SetDivider(StringWidth(URL_TEXT) + 10);
91 
92 	/* cancel */
93 
94 	BButton *button = new BButton(CANCEL_RECT, "", CANCEL_TEXT, new BMessage(M_CANCEL));
95 	AddChild(button);
96 
97 	/* ok */
98 
99 	button = new BButton(OK_RECT, "", OK_TEXT, new BMessage(M_OK));
100 	AddChild(button);
101 	button->MakeDefault(true);
102 }
103 
104 bool IppSetupView::UpdateViewData()
105 {
106 	string error_msg;
107 
108 	if (*url->Text()) {
109 		IppContent *request = new IppContent;
110 		request->setOperationId(IPP_GET_PRINTER_ATTRIBUTES);
111 		request->setDelimiter(IPP_OPERATION_ATTRIBUTES_TAG);
112 		request->setCharset("attributes-charset", "utf-8");
113 		request->setNaturalLanguage("attributes-natural-language", "en-us");
114 		request->setURI("printer-uri", url->Text());
115 		request->setDelimiter(IPP_END_OF_ATTRIBUTES_TAG);
116 
117 		IppURLConnection conn(BUrl(url->Text()));
118 		conn.setIppRequest(request);
119 		conn.setRequestProperty("Connection", "close");
120 
121 		HTTP_RESPONSECODE response_code = conn.getResponseCode();
122 		if (response_code == HTTP_OK) {
123 			const char *content_type = conn.getContentType();
124 			if (content_type == NULL
125 				|| strncasecmp(content_type, "application/ipp", 15) == 0) {
126 				const IppContent *ipp_response = conn.getIppResponse();
127 				if (ipp_response->good()) {
128 					dir->WriteAttr(IPP_URL, B_STRING_TYPE, 0, url->Text(),
129 						strlen(url->Text()) + 1);
130 					return true;
131 				} else {
132 					error_msg = ipp_response->getStatusMessage();
133 				}
134 			} else {
135 				error_msg = "cannot get a IPP response.";
136 			}
137 		} else if (response_code != HTTP_UNKNOWN) {
138 			error_msg = conn.getResponseMessage();
139 		} else {
140 			error_msg = "cannot connect to the IPP server.";
141 		}
142 	} else {
143 		error_msg = "please input the printer URL.";
144 	}
145 
146 	BAlert *alert = new BAlert("", error_msg.c_str(), "OK");
147 	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
148 	alert->Go();
149 	return false;
150 }
151 
152 IppSetupDlg::IppSetupDlg(BDirectory *dir)
153 	: BWindow(BRect(100, 100, 100 + DLG_WIDTH, 100 + DLG_HEIGHT),
154 		"IPP Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
155 		B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE
156 			| B_CLOSE_ON_ESCAPE)
157 {
158 	result = 0;
159 
160 	Lock();
161 	IppSetupView *view = new IppSetupView(Bounds(), dir);
162 	AddChild(view);
163 	Unlock();
164 
165 	semaphore = create_sem(0, "IppSetupSem");
166 }
167 
168 bool IppSetupDlg::QuitRequested()
169 {
170 	result = B_ERROR;
171 	release_sem(semaphore);
172 	return true;
173 }
174 
175 void IppSetupDlg::MessageReceived(BMessage *msg)
176 {
177 	bool success;
178 
179 	switch (msg->what) {
180 	case M_OK:
181 		Lock();
182 		success = ((IppSetupView *)ChildAt(0))->UpdateViewData();
183 		Unlock();
184 		if (success) {
185 			result = B_NO_ERROR;
186 			release_sem(semaphore);
187 		}
188 		break;
189 
190 	case M_CANCEL:
191 		result = B_ERROR;
192 		release_sem(semaphore);
193 		break;
194 
195 	default:
196 		BWindow::MessageReceived(msg);
197 		break;
198 	}
199 }
200 
201 int IppSetupDlg::Go()
202 {
203 	Show();
204 	acquire_sem(semaphore);
205 	delete_sem(semaphore);
206 	int value = result;
207 	Lock();
208 	Quit();
209 	return value;
210 }
211