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 *);
~IppSetupView()69 ~IppSetupView() {}
70 virtual void AttachedToWindow();
71 bool UpdateViewData();
72
73 private:
74 BTextControl *url;
75 BDirectory *dir;
76 };
77
IppSetupView(BRect frame,BDirectory * d)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
AttachedToWindow()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
UpdateViewData()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
IppSetupDlg(BDirectory * dir)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
QuitRequested()168 bool IppSetupDlg::QuitRequested()
169 {
170 result = B_ERROR;
171 release_sem(semaphore);
172 return true;
173 }
174
MessageReceived(BMessage * msg)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
Go()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