1
/* cdrdao - write audio CD-Rs in disc-at-once mode
3
* Copyright (C) 1998-2002 Andreas Mueller <andreas@daneb.de>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29
#include "DeviceConfDialog.h"
32
#include "guiUpdate.h"
36
#define MAX_DEVICE_TYPE_ID 2
38
static CdDevice::DeviceType ID2DEVICE_TYPE[MAX_DEVICE_TYPE_ID + 1] = {
45
DeviceConfDialog::DeviceConfDialog()
56
set_title(_("Configure Devices"));
58
// TreeView initialization
59
listModel_ = Gtk::ListStore::create(listColumns_);
60
list_.set_model(listModel_);
61
list_.append_column(_("Dev"), listColumns_.dev);
62
list_.append_column(_("Vendor"), listColumns_.vendor);
63
list_.append_column(_("Model"), listColumns_.model);
64
list_.append_column(_("Status"), listColumns_.status);
66
selectedRow_ = list_.get_selection()->get_selected();
67
list_.get_selection()->signal_changed().
68
connect(slot(*this, &DeviceConfDialog::selectionChanged));
70
Gtk::Menu *dmenu = manage(new Gtk::Menu);
73
for (i = 0; i <= CdDevice::maxDriverId(); i++) {
74
mi = manage(new Gtk::MenuItem(CdDevice::driverName(i)));
75
mi->signal_activate().connect(bind(slot(*this,
76
&DeviceConfDialog::setDriverId),
82
driverMenu_ = manage(new Gtk::OptionMenu);
83
driverMenu_->set_menu(*dmenu);
85
Gtk::Menu *tmenu = manage(new Gtk::Menu);
87
for (i = 0; i <= MAX_DEVICE_TYPE_ID; i++) {
89
Gtk::MenuItem(CdDevice::deviceType2string(ID2DEVICE_TYPE[i])));
90
mi->signal_activate().connect(bind(slot(*this,
91
&DeviceConfDialog::setDeviceType),
97
devtypeMenu_ = manage(new Gtk::OptionMenu);
98
devtypeMenu_->set_menu(*tmenu);
100
devEntry_.set_max_length(32);
101
vendorEntry_.set_max_length(8);
102
productEntry_.set_max_length(16);
104
Gtk::VBox *contents = manage(new Gtk::VBox);
105
contents->set_spacing(5);
106
contents->set_border_width(7);
108
// ---------------------------- Device list
109
Gtk::VBox *listBox = manage(new Gtk::VBox);
110
listBox->set_spacing(5);
111
listBox->set_border_width(5);
113
hbox = manage(new Gtk::HBox);
115
hbox->pack_start(list_, Gtk::PACK_EXPAND_WIDGET);
117
Gtk::Adjustment *adjust = manage(new Gtk::Adjustment(0.0, 0.0, 0.0));
118
Gtk::VScrollbar *scrollBar = manage(new Gtk::VScrollbar(*adjust));
119
hbox->pack_start(*scrollBar, Gtk::PACK_SHRINK);
121
list_.set_vadjustment(*adjust);
123
listBox->pack_start(*hbox, Gtk::PACK_EXPAND_WIDGET);
125
Gtk::ButtonBox *bbox = manage(new Gtk::HButtonBox(Gtk::BUTTONBOX_SPREAD));
127
button = manage(new Gtk::Button(_("Rescan")));
128
bbox->pack_start(*button);
129
button->signal_clicked().
130
connect(SigC::slot(*this,&DeviceConfDialog::rescanAction));
132
button = manage(new Gtk::Button(Gtk::StockID(Gtk::Stock::DELETE)));
133
bbox->pack_start(*button);
134
button->signal_clicked().
135
connect(SigC::slot(*this,&DeviceConfDialog::deleteDeviceAction));
137
listBox->pack_start(*bbox, Gtk::PACK_SHRINK);
139
listFrame_.set_label(_(" Device List "));
140
listFrame_.add(*listBox);
141
contents->pack_start(listFrame_, Gtk::PACK_EXPAND_WIDGET);
143
// ---------------------------- Device settings
145
settingFrame_.set_label(_(" Device Settings "));
146
table = manage(new Gtk::Table(2, 4, FALSE));
147
table->set_row_spacings(5);
148
table->set_col_spacings(5);
149
table->set_border_width(10);
150
settingFrame_.add(*table);
152
label = manage(new Gtk::Label(_("Device Type:")));
153
table->attach(*label, 0, 1, 0, 1);
154
table->attach(*devtypeMenu_, 1, 2, 0, 1);
156
label = manage(new Gtk::Label(_("Driver:")));
157
table->attach(*label, 0, 1, 1, 2);
158
table->attach(*driverMenu_, 1, 2, 1, 2);
160
label = manage(new Gtk::Label(_("Driver Options:")));
161
table->attach(*label, 0, 1, 2, 3);
162
table->attach(driverOptionsEntry_, 1, 2, 2, 3);
164
contents->pack_start(settingFrame_, Gtk::PACK_SHRINK);
166
// -------------- Add device
168
addDeviceFrame_.set_label(_(" Add Device "));
169
Gtk::VBox *addDeviceBox = manage(new Gtk::VBox);
170
addDeviceBox->set_spacing(5);
171
addDeviceBox->set_border_width(5);
173
table = manage(new Gtk::Table(3, 2, FALSE));
174
table->set_row_spacings(5);
175
table->set_col_spacings(5);
176
addDeviceBox->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
178
label = manage(new Gtk::Label(_("Device:")));
179
table->attach(*label, 0, 1, 0, 1);
180
table->attach(devEntry_, 1, 2, 0, 1);
182
label = manage(new Gtk::Label(_("Vendor:")));
183
table->attach(*label, 0, 1, 1, 2);
184
table->attach(vendorEntry_, 1, 2, 1, 2);
186
label = manage(new Gtk::Label(_("Product:")));
187
table->attach(*label, 0, 1, 2, 3);
188
table->attach(productEntry_, 1, 2, 2, 3);
190
bbox = manage(new Gtk::HButtonBox(Gtk::BUTTONBOX_SPREAD));
191
bbox->set_spacing(5);
192
Gtk::Button* addButton =
193
manage(new Gtk::Button(Gtk::StockID(Gtk::Stock::ADD)));
194
bbox->pack_start(*addButton);
195
addButton->signal_clicked().
196
connect(slot(*this, &DeviceConfDialog::addDeviceAction));
197
addDeviceBox->pack_start(*bbox);
199
addDeviceFrame_.add(*addDeviceBox);
200
contents->pack_start(addDeviceFrame_, Gtk::PACK_SHRINK);
202
// 3 buttons at bottom of window.
204
bbox = manage(new Gtk::HButtonBox(Gtk::BUTTONBOX_SPREAD));
205
bbox->set_spacing(5);
206
hbox->set_border_width(10);
207
Gtk::Button* applyButton =
208
manage(new Gtk::Button(Gtk::StockID(Gtk::Stock::APPLY)));
209
bbox->pack_start(*applyButton);
210
applyButton->signal_clicked().connect(slot(*this,
211
&DeviceConfDialog::applyAction));
213
Gtk::Button *resetButton = manage(new Gtk::Button(_("Reset")));
214
bbox->pack_start(*resetButton);
215
resetButton->signal_clicked().connect(slot(*this,
216
&DeviceConfDialog::resetAction));
218
Gtk::Button *cancelButton =
219
manage(new Gtk::Button(Gtk::StockID(Gtk::Stock::CLOSE)));
220
bbox->pack_start(*cancelButton);
221
cancelButton->signal_clicked().connect(slot(*this,
222
&DeviceConfDialog::closeAction));
224
contents->pack_start(*bbox, Gtk::PACK_SHRINK);
229
DeviceConfDialog::~DeviceConfDialog()
234
void DeviceConfDialog::start()
242
update(UPD_CD_DEVICES);
246
void DeviceConfDialog::stop()
252
void DeviceConfDialog::update(unsigned long level)
257
if (level & UPD_CD_DEVICES)
259
else if (level & UPD_CD_DEVICE_STATUS)
263
void DeviceConfDialog::closeAction()
268
void DeviceConfDialog::resetAction()
274
void DeviceConfDialog::applyAction()
277
exportConfiguration(selectedRow_);
279
guiUpdate(UPD_CD_DEVICES);
282
void DeviceConfDialog::addDeviceAction()
291
if ((s = checkString(devEntry_.get_text())) == NULL)
295
if ((s = checkString(vendorEntry_.get_text())) == NULL)
299
if ((s = checkString(productEntry_.get_text())) == NULL)
303
if (CdDevice::find(dev.c_str()) != NULL)
306
cddev = CdDevice::add(dev.c_str(), vendor.c_str(), product.c_str());
309
cddev->manuallyConfigured(true);
310
Gtk::TreeIter new_entry = appendTableEntry(cddev);
311
list_.get_selection()->select(new_entry);
314
guiUpdate(UPD_CD_DEVICES);
317
void DeviceConfDialog::deleteDeviceAction()
324
data = (*selectedRow_)[listColumns_.data];
326
dev = CdDevice::find(data->dev.c_str());
327
if (dev == NULL || dev->status() == CdDevice::DEV_RECORDING ||
328
dev->status() == CdDevice::DEV_BLANKING) {
329
// don't remove device that is currently busy
333
CdDevice::remove(data->dev.c_str());
334
listModel_->erase(selectedRow_);
335
list_.get_selection()->unselect_all();
336
selectedRow_ = list_.get_selection()->get_selected();
339
guiUpdate(UPD_CD_DEVICES);
343
void DeviceConfDialog::rescanAction()
346
guiUpdate(UPD_CD_DEVICES);
349
Gtk::TreeIter DeviceConfDialog::appendTableEntry(CdDevice *dev)
352
const gchar *rowStr[6];
354
data = new DeviceData;
355
data->dev = dev->dev();
356
data->driverId = dev->driverId();
357
data->options = dev->driverOptions();
359
switch (dev->deviceType()) {
360
case CdDevice::CD_ROM:
361
data->deviceType = 0;
364
data->deviceType = 1;
366
case CdDevice::CD_RW:
367
data->deviceType = 2;
371
Gtk::TreeIter newiter = listModel_->append();
372
Gtk::TreeModel::Row row = *newiter;
373
row[listColumns_.dev] = data->dev;
374
row[listColumns_.vendor] = dev->vendor();
375
row[listColumns_.model] = dev->product();
376
row[listColumns_.status] = CdDevice::status2string(dev->status());
377
row[listColumns_.data] = data;
382
void DeviceConfDialog::import()
387
list_.get_selection()->unselect_all();
388
selectedRow_ = list_.get_selection()->get_selected();
392
for (drun = CdDevice::first(); drun != NULL; drun = CdDevice::next(drun)) {
393
appendTableEntry(drun);
396
if (listModel_->children().size() > 0) {
397
list_.columns_autosize();
398
list_.get_selection()->select(Gtk::TreeModel::Path((unsigned)1));
402
void DeviceConfDialog::importConfiguration(Gtk::TreeIter row)
409
data = (*selectedRow_)[listColumns_.data];
410
driverMenu_->set_sensitive(true);
411
driverMenu_->set_history(data->driverId);
412
devtypeMenu_->set_sensitive(true);
413
devtypeMenu_->set_history(data->deviceType);
414
driverOptionsEntry_.set_sensitive(true);
415
sprintf(buf, "0x%lx", data->options);
416
driverOptionsEntry_.set_text(buf);
420
driverMenu_->set_history(0);
421
driverMenu_->set_sensitive(false);
422
devtypeMenu_->set_history(0);
423
devtypeMenu_->set_sensitive(false);
424
driverOptionsEntry_.set_text("");
425
driverOptionsEntry_.set_sensitive(false);
429
void DeviceConfDialog::importStatus()
434
Gtk::TreeNodeChildren ch = listModel_->children();
435
for (int i = 0; i < ch.size(); i++) {
436
Gtk::TreeRow row = ch[i];
437
data = row[listColumns_.data];
438
if (data && (dev = CdDevice::find(data->dev.c_str()))) {
439
row[listColumns_.status] = CdDevice::status2string(dev->status());
443
list_.columns_autosize();
446
void DeviceConfDialog::exportConfiguration(Gtk::TreeIter row)
451
data = (*row)[listColumns_.data];
454
data->options = strtoul(driverOptionsEntry_.get_text().c_str(), NULL, 0);
459
void DeviceConfDialog::exportData()
465
Gtk::TreeNodeChildren ch = listModel_->children();
466
for (int i = 0; i < ch.size(); i++) {
467
Gtk::TreeRow row = ch[i];
468
data = row[listColumns_.data];
469
if (data && (dev = CdDevice::find(data->dev.c_str()))) {
471
if (dev->driverId() != data->driverId) {
472
dev->driverId(data->driverId);
473
dev->manuallyConfigured(true);
476
if (dev->deviceType() != ID2DEVICE_TYPE[data->deviceType]) {
477
dev->deviceType(ID2DEVICE_TYPE[data->deviceType]);
478
dev->manuallyConfigured(true);
481
if (dev->driverOptions() != data->options) {
482
dev->driverOptions(data->options);
483
dev->manuallyConfigured(true);
491
void DeviceConfDialog::setDriverId(int id)
495
if (selectedRow_ && id >= 0 && id <= CdDevice::maxDriverId()) {
496
data = (*selectedRow_)[listColumns_.data];
502
void DeviceConfDialog::setDeviceType(int id)
506
if (selectedRow_ && id >= 0 && id <= CdDevice::maxDriverId()) {
507
data = (*selectedRow_)[listColumns_.data];
509
data->deviceType = id;
513
void DeviceConfDialog::selectionChanged()
515
Gtk::TreeIter new_sel = list_.get_selection()->get_selected();
517
if ((bool)selectedRow_ != (bool)new_sel || selectedRow_ != new_sel) {
520
exportConfiguration(selectedRow_);
522
selectedRow_ = new_sel;
523
importConfiguration(selectedRow_);
527
const char *DeviceConfDialog::checkString(const std::string &str)
529
static char *buf = NULL;
530
static long bufLen = 0;
532
long len = strlen(str.c_str());
537
if (buf == NULL || len + 1 > bufLen) {
540
buf = new char[bufLen];
543
strcpy(buf, str.c_str());
548
while (*s != 0 && isspace(*s))
554
while (p > s && isspace(*p)) {