1 /* 2 * Copyright 2010, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar R. Adema <ithamar.adema@team-embedded.nl> 7 */ 8 9 10 #include "SelectPPDDlg.h" 11 12 #include <GroupLayout.h> 13 #include <GroupLayoutBuilder.h> 14 15 #include <Button.h> 16 #include <Directory.h> 17 #include <Entry.h> 18 #include <ListView.h> 19 #include <Message.h> 20 #include <Path.h> 21 #include <ScrollBar.h> 22 #include <ScrollView.h> 23 #include <String.h> 24 #include <StringItem.h> 25 26 #include "PPDParser.h" 27 28 enum { 29 kMsgCancel = 'stop', 30 kMsgOK = 'okok', 31 32 kMsgManuSelected = 'msel', 33 kMsgPrinterSelected = 'psel', 34 }; 35 36 37 class PPDStringItem : public BStringItem { 38 public: 39 PPDStringItem(const BString& text, const BString& path) 40 : 41 BStringItem(text.String()), 42 fPPDPath(path) 43 { 44 } 45 46 BString fPPDPath; 47 }; 48 49 50 SelectPPDDlg::SelectPPDDlg(PSData* data) 51 : DialogWindow(BRect(10, 10, 400, 400), 52 "Select PPD", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, 53 B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS 54 | B_CLOSE_ON_ESCAPE), 55 fPSData(data) 56 { 57 SetResult(B_ERROR); 58 59 BButton* ok; 60 BButton* cancel; 61 62 ok = new BButton("btn:ok", "OK", new BMessage(kMsgOK)); 63 ok->MakeDefault(true); 64 ok->SetEnabled(false); 65 fOKButton = ok; 66 67 cancel = new BButton("btn:cancel", "Cancel", new BMessage(kMsgCancel)); 68 69 BScrollView* manuScroller, *printerScroller; 70 fManufacturersListView = new BListView("olv:manufacturers"); 71 manuScroller = new BScrollView("scr:manufacturers", fManufacturersListView, 72 0, false, true); 73 fPrintersListView = new BListView("olv:printers"); 74 printerScroller = new BScrollView("scr:printers", fPrintersListView, 0, 75 false, true); 76 77 fPrintersListView->SetSelectionMessage(new BMessage(kMsgPrinterSelected)); 78 fManufacturersListView->SetSelectionMessage(new BMessage(kMsgManuSelected)); 79 PopulateManufacturers(B_SYSTEM_DATA_DIRECTORY); 80 81 // Build the layout 82 SetLayout(new BGroupLayout(B_VERTICAL)); 83 84 AddChild(BGroupLayoutBuilder(B_VERTICAL, 10) 85 .AddGroup(B_HORIZONTAL, 5) 86 .Add(manuScroller) 87 .Add(printerScroller) 88 .End() 89 .AddGroup(B_HORIZONTAL, 5) 90 .AddGlue() 91 .Add(cancel) 92 .Add(ok) 93 .End() 94 .SetInsets(10, 10, 10, 10) 95 ); 96 } 97 98 99 void 100 SelectPPDDlg::PopulateManufacturers(directory_which data_dir) 101 { 102 char name[1024]; 103 BDirectory dir; 104 BEntry entry; 105 BPath path; 106 107 if (find_directory(data_dir, &path) == B_OK 108 && path.Append("ppd") == B_OK 109 && dir.SetTo(path.Path()) == B_OK) { 110 // Got the directory, now scan it 111 while (dir.GetNextEntry(&entry) == B_OK) 112 if (entry.IsDirectory() 113 && entry.GetName(name) == B_OK) 114 fManufacturersListView->AddItem(new BStringItem(name)); 115 } 116 } 117 118 119 void 120 SelectPPDDlg::PopulatePrinters(directory_which data_dir) 121 { 122 int32 idx = fManufacturersListView->CurrentSelection(); 123 char name[1024]; 124 BDirectory dir; 125 BString manu; 126 BEntry entry; 127 BPath path; 128 129 // Bail out if no manufacturer is selected 130 if (idx < 0) 131 return; 132 133 manu = ((BStringItem*)fManufacturersListView->ItemAt(idx))->Text(); 134 135 if (find_directory(data_dir, &path) == B_OK 136 && path.Append("ppd") == B_OK 137 && path.Append(manu) == B_OK 138 && dir.SetTo(path.Path()) == B_OK) { 139 // Found manufacturer PPD directory, now fill our printer list 140 while (dir.GetNextEntry(&entry) == B_OK) 141 if (entry.GetName(name) == B_OK) { 142 PPDParser parser(dir, name); 143 if (parser.InitCheck() == B_OK) { 144 BString modelName = parser.GetParameter("ModelName"); 145 BPath ppdPath = path; 146 ppdPath.Append(name); 147 fPrintersListView->AddItem(new PPDStringItem(modelName, 148 ppdPath.Path())); 149 } 150 } 151 } 152 } 153 154 155 void 156 SelectPPDDlg::PrinterSelected() 157 { 158 int32 idx = fPrintersListView->CurrentSelection(); 159 fOKButton->SetEnabled(idx >= 0); 160 } 161 162 163 void 164 SelectPPDDlg::Save() 165 { 166 BString ppdPath; 167 int32 idx; 168 169 idx = fPrintersListView->CurrentSelection(); 170 if (idx >= 0) 171 ppdPath = dynamic_cast<PPDStringItem*> 172 (fPrintersListView->ItemAt(idx))->fPPDPath; 173 174 fPSData->fPPD = ppdPath; 175 fPSData->Save(); 176 } 177 178 179 void 180 SelectPPDDlg::MessageReceived(BMessage* msg) 181 { 182 switch (msg->what) { 183 case kMsgManuSelected: 184 fPrintersListView->MakeEmpty(); 185 PopulatePrinters(B_SYSTEM_DATA_DIRECTORY); 186 break; 187 case kMsgPrinterSelected: 188 PrinterSelected(); 189 break; 190 case kMsgOK: 191 Save(); 192 SetResult(B_NO_ERROR); 193 PostMessage(B_QUIT_REQUESTED); 194 break; 195 case kMsgCancel: 196 PostMessage(B_QUIT_REQUESTED); 197 break; 198 default: 199 DialogWindow::MessageReceived(msg); 200 break; 201 } 202 } 203