1 /* 2 * Copyright 2008, Haiku. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Michael Pfeiffer <laplace@users.sourceforge.net> 7 */ 8 9 #include "PrinterSelection.h" 10 #include "PPDParser.h" 11 #include "StatementListVisitor.h" 12 #include "UIUtils.h" 13 14 #include <Directory.h> 15 #include <Entry.h> 16 #include <Path.h> 17 18 #include <ScrollView.h> 19 #include <StringView.h> 20 21 // margin 22 const float kLeftMargin = 3.0; 23 const float kRightMargin = 3.0; 24 const float kTopMargin = 3.0; 25 const float kBottomMargin = 3.0; 26 27 // space between views 28 const float kHorizontalSpace = 8.0; 29 const float kVerticalSpace = 8.0; 30 31 #include <stdio.h> 32 33 PrinterSelectionView::PrinterSelectionView(BRect bounds, const char *name, uint32 resizeMask, uint32 flags) 34 : BView(bounds, name, resizeMask, flags) 35 { 36 // add vendor list view 37 bounds.OffsetTo(0, 0); 38 BRect listBounds(bounds.left + kLeftMargin, bounds.top + kTopMargin, 39 bounds.right / 3.0 - kHorizontalSpace / 2, bounds.bottom - kBottomMargin); 40 listBounds.right -= B_V_SCROLL_BAR_WIDTH; 41 listBounds.bottom -= B_H_SCROLL_BAR_HEIGHT; 42 43 BStringView* label = new BStringView(listBounds, "vendors-label", "Vendors:"); 44 AddChild(label); 45 label->ResizeToPreferred(); 46 47 listBounds.top += label->Bounds().bottom + 5; 48 49 fVendors = new BListView(listBounds, "vendors", B_SINGLE_SELECTION_LIST, 50 B_FOLLOW_ALL); 51 FillVendors(); 52 53 BScrollView* scrollView = new BScrollView("vendors-scroll-view", 54 fVendors, B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, 0, true, true); 55 56 AddChild(scrollView); 57 58 // add details view 59 BRect printerBounds(listBounds); 60 printerBounds.left = B_V_SCROLL_BAR_WIDTH + printerBounds.right + kHorizontalSpace; 61 printerBounds.right = bounds.right - kRightMargin - B_V_SCROLL_BAR_WIDTH; 62 printerBounds.top = bounds.top + kTopMargin; 63 label = new BStringView(printerBounds, "printers-label", "Printers:"); 64 AddChild(label); 65 label->ResizeToPreferred(); 66 67 BRect detailBounds(listBounds); 68 detailBounds.left = B_V_SCROLL_BAR_WIDTH + detailBounds.right + kHorizontalSpace; 69 detailBounds.right = bounds.right - kRightMargin - B_V_SCROLL_BAR_WIDTH; 70 fPrinters = new BListView(detailBounds, "printers", B_SINGLE_SELECTION_LIST, 71 B_FOLLOW_ALL); 72 73 scrollView = new BScrollView("printers-scroll-view", 74 fPrinters, B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, 0, true, true); 75 76 AddChild(scrollView); 77 } 78 79 void PrinterSelectionView::AttachedToWindow() 80 { 81 fVendors->SetSelectionMessage(new BMessage('sel')); 82 fVendors->SetTarget(this); 83 84 fPrinters->SetSelectionMessage(new BMessage('prnt')); 85 fPrinters->SetTarget(this); 86 } 87 88 89 void PrinterSelectionView::FillVendors() 90 { 91 BDirectory directory("/boot/beos/etc/ppd"); 92 BEntry entry; 93 while (directory.GetNextEntry(&entry) == B_OK) { 94 char name[B_FILE_NAME_LENGTH]; 95 entry.GetName(name); 96 BPath path; 97 entry.GetPath(&path); 98 fVendors->AddItem(new FileItem(name, path.Path())); 99 } 100 } 101 102 void PrinterSelectionView::FillPrinters(const char* vendor) 103 { 104 MakeEmpty(fPrinters); 105 106 BList printers; 107 BDirectory directory(vendor); 108 BEntry entry; 109 while (directory.GetNextEntry(&entry) == B_OK) { 110 char name[B_FILE_NAME_LENGTH]; 111 entry.GetName(name); 112 BPath path; 113 entry.GetPath(&path); 114 115 PPDParser parser(path.Path()); 116 PPD* ppd = parser.ParseHeader(); 117 if (parser.HasWarning()) { 118 fprintf(stderr, "Warning(s): %s", parser.GetWarningMessage()); 119 } 120 121 if (ppd != NULL) { 122 123 BString label; 124 const char* s; 125 s = ppd->GetValue("ModelName"); 126 if (s != NULL) { 127 label << s; 128 } 129 s = ppd->GetValue("PCFileName"); 130 if (s != NULL) { 131 label << " [" << s << "]"; 132 } 133 s = ppd->GetValue("Manufacturer"); 134 if (s != NULL) { 135 label << " (" << s << ")"; 136 } 137 printers.AddItem(new FileItem(label.String(), path.Path())); 138 delete ppd; 139 } else { 140 fprintf(stderr, "Parsing error (%s)\n%s\n", path.Path(), 141 parser.GetErrorMessage()); 142 } 143 } 144 145 fPrinters->AddList(&printers); 146 } 147 148 void PrinterSelectionView::MessageReceived(BMessage* msg) 149 { 150 int32 index; 151 switch (msg->what) { 152 case 'sel': 153 if (msg->FindInt32("index", &index) == B_OK) { 154 FileItem* file = (FileItem*)fVendors->ItemAt(index); 155 if (file != NULL) { 156 FillPrinters(file->GetFile()); 157 } 158 } 159 break; 160 case 'prnt': 161 if (msg->FindInt32("index", &index) == B_OK) { 162 FileItem* file = (FileItem*)fPrinters->ItemAt(index); 163 if (file != NULL) { 164 BMessage copy(*Message()); 165 copy.AddString("file", file->GetFile()); 166 InvokeNotify(©); 167 } 168 } 169 break; 170 } 171 BView::MessageReceived(msg); 172 } 173