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