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
41const BRect URL_RECT(
42	URL_H,
43	URL_V,
44	URL_H + URL_WIDTH,
45	URL_V + URL_HEIGHT);
46
47const BRect OK_RECT(
48	OK_H,
49	OK_V,
50	OK_H + BUTTON_WIDTH,
51	OK_V + BUTTON_HEIGHT);
52
53const BRect CANCEL_RECT(
54	CANCEL_H,
55	CANCEL_V,
56	CANCEL_H + BUTTON_WIDTH,
57	CANCEL_V + BUTTON_HEIGHT);
58
59enum MSGS {
60	M_CANCEL = 1,
61	M_OK
62};
63
64
65class IppSetupView : public BView {
66public:
67	IppSetupView(BRect, BDirectory *);
68	~IppSetupView() {}
69	virtual void AttachedToWindow();
70	bool UpdateViewData();
71
72private:
73	BTextControl *url;
74	BDirectory *dir;
75};
76
77IppSetupView::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
83void 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
103bool 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
149IppSetupDlg::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
165bool IppSetupDlg::QuitRequested()
166{
167	result = B_ERROR;
168	release_sem(semaphore);
169	return true;
170}
171
172void 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
198int 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