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