xref: /haiku/src/tests/add-ons/print/ppd/ui/PrinterSelection.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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(&copy);
167 				}
168 			}
169 			break;
170 	}
171 	BView::MessageReceived(msg);
172 }
173