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