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