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->Go(); 145 return false; 146 } 147 148 IppSetupDlg::IppSetupDlg(BDirectory *dir) 149 : BWindow(BRect(100, 100, 100 + DLG_WIDTH, 100 + DLG_HEIGHT), 150 "IPP Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, 151 B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE) 152 { 153 result = 0; 154 155 Lock(); 156 IppSetupView *view = new IppSetupView(Bounds(), dir); 157 AddChild(view); 158 Unlock(); 159 160 semaphore = create_sem(0, "IppSetupSem"); 161 } 162 163 bool IppSetupDlg::QuitRequested() 164 { 165 result = B_ERROR; 166 release_sem(semaphore); 167 return true; 168 } 169 170 void IppSetupDlg::MessageReceived(BMessage *msg) 171 { 172 bool success; 173 174 switch (msg->what) { 175 case M_OK: 176 Lock(); 177 success = ((IppSetupView *)ChildAt(0))->UpdateViewData(); 178 Unlock(); 179 if (success) { 180 result = B_NO_ERROR; 181 release_sem(semaphore); 182 } 183 break; 184 185 case M_CANCEL: 186 result = B_ERROR; 187 release_sem(semaphore); 188 break; 189 190 default: 191 BWindow::MessageReceived(msg); 192 break; 193 } 194 } 195 196 int IppSetupDlg::Go() 197 { 198 Show(); 199 acquire_sem(semaphore); 200 delete_sem(semaphore); 201 int value = result; 202 Lock(); 203 Quit(); 204 return value; 205 } 206