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