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 fPSData(data) 55 { 56 SetResult(B_ERROR); 57 58 BButton* ok; 59 BButton* cancel; 60 61 ok = new BButton("btn:ok", "OK", new BMessage(kMsgOK)); 62 ok->MakeDefault(true); 63 ok->SetEnabled(false); 64 fOKButton = ok; 65 66 cancel = new BButton("btn:cancel", "Cancel", new BMessage(kMsgCancel)); 67 68 BScrollView* manuScroller, *printerScroller; 69 fManufacturersListView = new BListView("olv:manufacturers"); 70 manuScroller = new BScrollView("scr:manufacturers", fManufacturersListView, 71 0, false, true); 72 fPrintersListView = new BListView("olv:printers"); 73 printerScroller = new BScrollView("scr:printers", fPrintersListView, 0, 74 false, true); 75 76 fPrintersListView->SetSelectionMessage(new BMessage(kMsgPrinterSelected)); 77 fManufacturersListView->SetSelectionMessage(new BMessage(kMsgManuSelected)); 78 PopulateManufacturers(B_SYSTEM_DATA_DIRECTORY); 79 80 // Build the layout 81 SetLayout(new BGroupLayout(B_VERTICAL)); 82 83 AddChild(BGroupLayoutBuilder(B_VERTICAL, 10) 84 .AddGroup(B_HORIZONTAL, 5) 85 .Add(manuScroller) 86 .Add(printerScroller) 87 .End() 88 .AddGroup(B_HORIZONTAL, 5) 89 .AddGlue() 90 .Add(cancel) 91 .Add(ok) 92 .End() 93 .SetInsets(10, 10, 10, 10) 94 ); 95 } 96 97 98 void 99 SelectPPDDlg::PopulateManufacturers(directory_which data_dir) 100 { 101 char name[1024]; 102 BDirectory dir; 103 BEntry entry; 104 BPath path; 105 106 if (find_directory(data_dir, &path) == B_OK 107 && path.Append("ppd") == B_OK 108 && dir.SetTo(path.Path()) == B_OK) { 109 // Got the directory, now scan it 110 while (dir.GetNextEntry(&entry) == B_OK) 111 if (entry.IsDirectory() 112 && entry.GetName(name) == B_OK) 113 fManufacturersListView->AddItem(new BStringItem(name)); 114 } 115 } 116 117 118 void 119 SelectPPDDlg::PopulatePrinters(directory_which data_dir) 120 { 121 int32 idx = fManufacturersListView->CurrentSelection(); 122 char name[1024]; 123 BDirectory dir; 124 BString manu; 125 BEntry entry; 126 BPath path; 127 128 // Bail out if no manufacturer is selected 129 if (idx < 0) 130 return; 131 132 manu = ((BStringItem*)fManufacturersListView->ItemAt(idx))->Text(); 133 134 if (find_directory(data_dir, &path) == B_OK 135 && path.Append("ppd") == B_OK 136 && path.Append(manu) == B_OK 137 && dir.SetTo(path.Path()) == B_OK) { 138 // Found manufacturer PPD directory, now fill our printer list 139 while (dir.GetNextEntry(&entry) == B_OK) 140 if (entry.GetName(name) == B_OK) { 141 PPDParser parser(dir, name); 142 if (parser.InitCheck() == B_OK) { 143 BString modelName = parser.GetParameter("ModelName"); 144 BPath ppdPath = path; 145 ppdPath.Append(name); 146 fPrintersListView->AddItem(new PPDStringItem(modelName, 147 ppdPath.Path())); 148 } 149 } 150 } 151 } 152 153 154 void 155 SelectPPDDlg::PrinterSelected() 156 { 157 int32 idx = fPrintersListView->CurrentSelection(); 158 fOKButton->SetEnabled(idx >= 0); 159 } 160 161 162 void 163 SelectPPDDlg::Save() 164 { 165 BString ppdPath; 166 int32 idx; 167 168 idx = fPrintersListView->CurrentSelection(); 169 if (idx >= 0) 170 ppdPath = dynamic_cast<PPDStringItem*> 171 (fPrintersListView->ItemAt(idx))->fPPDPath; 172 173 fPSData->fPPD = ppdPath; 174 fPSData->save(); 175 } 176 177 178 void 179 SelectPPDDlg::MessageReceived(BMessage* msg) 180 { 181 switch (msg->what) { 182 case kMsgManuSelected: 183 fPrintersListView->MakeEmpty(); 184 PopulatePrinters(B_SYSTEM_DATA_DIRECTORY); 185 break; 186 case kMsgPrinterSelected: 187 PrinterSelected(); 188 break; 189 case kMsgOK: 190 Save(); 191 SetResult(B_NO_ERROR); 192 PostMessage(B_QUIT_REQUESTED); 193 break; 194 case kMsgCancel: 195 PostMessage(B_QUIT_REQUESTED); 196 break; 197 default: 198 DialogWindow::MessageReceived(msg); 199 break; 200 } 201 } 202