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
PrinterSelectionView(BRect bounds,const char * name,uint32 resizeMask,uint32 flags)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
AttachedToWindow()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
FillVendors()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
FillPrinters(const char * vendor)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
MessageReceived(BMessage * msg)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