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