~ubuntu-branches/ubuntu/utopic/cdrdao/utopic

« back to all changes in this revision

Viewing changes to xdao/DeviceConfDialog.cc

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Suffield
  • Date: 2004-06-24 22:33:16 UTC
  • Revision ID: james.westby@ubuntu.com-20040624223316-534onzugaeeyq61j
Tags: upstream-1.1.9
ImportĀ upstreamĀ versionĀ 1.1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  cdrdao - write audio CD-Rs in disc-at-once mode
 
2
 *
 
3
 *  Copyright (C) 1998-2002  Andreas Mueller <andreas@daneb.de>
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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.
 
18
 */
 
19
 
 
20
#include <stdio.h>
 
21
#include <limits.h>
 
22
#include <math.h>
 
23
#include <assert.h>
 
24
#include <ctype.h>
 
25
 
 
26
#include <gtkmm.h>
 
27
#include <gnome.h>
 
28
 
 
29
#include "DeviceConfDialog.h"
 
30
 
 
31
#include "CdDevice.h"
 
32
#include "guiUpdate.h"
 
33
 
 
34
#include "util.h"
 
35
 
 
36
#define MAX_DEVICE_TYPE_ID 2
 
37
 
 
38
static CdDevice::DeviceType ID2DEVICE_TYPE[MAX_DEVICE_TYPE_ID + 1] = {
 
39
  CdDevice::CD_ROM,
 
40
  CdDevice::CD_R,
 
41
  CdDevice::CD_RW
 
42
};
 
43
    
 
44
 
 
45
DeviceConfDialog::DeviceConfDialog()
 
46
{
 
47
  int i;
 
48
  Gtk::Label *label;
 
49
  Gtk::Table *table;
 
50
  Gtk::HBox *hbox;
 
51
  Gtk::VBox *vbox;
 
52
  Gtk::Button *button;
 
53
 
 
54
  active_ = false;
 
55
 
 
56
  set_title(_("Configure Devices"));
 
57
 
 
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);
 
65
 
 
66
  selectedRow_ = list_.get_selection()->get_selected();
 
67
  list_.get_selection()->signal_changed().
 
68
      connect(slot(*this, &DeviceConfDialog::selectionChanged));
 
69
 
 
70
  Gtk::Menu *dmenu = manage(new Gtk::Menu);
 
71
  Gtk::MenuItem *mi;
 
72
 
 
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),
 
77
                                       i));
 
78
    mi->show();
 
79
    dmenu->append(*mi);
 
80
  }
 
81
 
 
82
  driverMenu_ = manage(new Gtk::OptionMenu);
 
83
  driverMenu_->set_menu(*dmenu);
 
84
 
 
85
  Gtk::Menu *tmenu = manage(new Gtk::Menu);
 
86
 
 
87
  for (i = 0; i <= MAX_DEVICE_TYPE_ID; i++) {
 
88
    mi = manage(new
 
89
                Gtk::MenuItem(CdDevice::deviceType2string(ID2DEVICE_TYPE[i])));
 
90
    mi->signal_activate().connect(bind(slot(*this,
 
91
                                            &DeviceConfDialog::setDeviceType),
 
92
                                       i));
 
93
    mi->show();
 
94
    tmenu->append(*mi);
 
95
  }
 
96
 
 
97
  devtypeMenu_ = manage(new Gtk::OptionMenu);
 
98
  devtypeMenu_->set_menu(*tmenu);
 
99
 
 
100
  devEntry_.set_max_length(32);
 
101
  vendorEntry_.set_max_length(8);
 
102
  productEntry_.set_max_length(16);
 
103
 
 
104
  Gtk::VBox *contents = manage(new Gtk::VBox);
 
105
  contents->set_spacing(5);
 
106
  contents->set_border_width(7);
 
107
 
 
108
  // ---------------------------- Device list
 
109
  Gtk::VBox *listBox = manage(new Gtk::VBox);
 
110
  listBox->set_spacing(5);
 
111
  listBox->set_border_width(5);
 
112
 
 
113
  hbox = manage(new Gtk::HBox);
 
114
 
 
115
  hbox->pack_start(list_, Gtk::PACK_EXPAND_WIDGET);
 
116
 
 
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);
 
120
 
 
121
  list_.set_vadjustment(*adjust);
 
122
 
 
123
  listBox->pack_start(*hbox, Gtk::PACK_EXPAND_WIDGET);
 
124
 
 
125
  Gtk::ButtonBox *bbox = manage(new Gtk::HButtonBox(Gtk::BUTTONBOX_SPREAD));
 
126
 
 
127
  button = manage(new Gtk::Button(_("Rescan")));
 
128
  bbox->pack_start(*button);
 
129
  button->signal_clicked().
 
130
    connect(SigC::slot(*this,&DeviceConfDialog::rescanAction));
 
131
 
 
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));
 
136
 
 
137
  listBox->pack_start(*bbox, Gtk::PACK_SHRINK);
 
138
 
 
139
  listFrame_.set_label(_(" Device List "));
 
140
  listFrame_.add(*listBox);
 
141
  contents->pack_start(listFrame_, Gtk::PACK_EXPAND_WIDGET);
 
142
 
 
143
  // ---------------------------- Device settings
 
144
 
 
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);
 
151
  
 
152
  label = manage(new Gtk::Label(_("Device Type:")));
 
153
  table->attach(*label, 0, 1, 0, 1);
 
154
  table->attach(*devtypeMenu_, 1, 2, 0, 1);
 
155
 
 
156
  label = manage(new Gtk::Label(_("Driver:")));
 
157
  table->attach(*label, 0, 1, 1, 2);
 
158
  table->attach(*driverMenu_, 1, 2, 1, 2);
 
159
 
 
160
  label = manage(new Gtk::Label(_("Driver Options:")));
 
161
  table->attach(*label, 0, 1, 2, 3);
 
162
  table->attach(driverOptionsEntry_, 1, 2, 2, 3);
 
163
 
 
164
  contents->pack_start(settingFrame_, Gtk::PACK_SHRINK);
 
165
 
 
166
  // -------------- Add device
 
167
 
 
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);
 
172
 
 
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);
 
177
 
 
178
  label = manage(new Gtk::Label(_("Device:")));
 
179
  table->attach(*label, 0, 1, 0, 1);
 
180
  table->attach(devEntry_, 1, 2, 0, 1);
 
181
 
 
182
  label = manage(new Gtk::Label(_("Vendor:")));
 
183
  table->attach(*label, 0, 1, 1, 2);
 
184
  table->attach(vendorEntry_, 1, 2, 1, 2);
 
185
 
 
186
  label = manage(new Gtk::Label(_("Product:")));
 
187
  table->attach(*label, 0, 1, 2, 3);
 
188
  table->attach(productEntry_, 1, 2, 2, 3);
 
189
 
 
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);
 
198
 
 
199
  addDeviceFrame_.add(*addDeviceBox);
 
200
  contents->pack_start(addDeviceFrame_, Gtk::PACK_SHRINK);
 
201
 
 
202
  // 3 buttons at bottom of window.
 
203
 
 
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));
 
212
  
 
213
  Gtk::Button *resetButton = manage(new Gtk::Button(_("Reset")));
 
214
  bbox->pack_start(*resetButton);
 
215
  resetButton->signal_clicked().connect(slot(*this,
 
216
                                             &DeviceConfDialog::resetAction));
 
217
 
 
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));
 
223
 
 
224
  contents->pack_start(*bbox, Gtk::PACK_SHRINK);
 
225
 
 
226
  add(*contents);
 
227
}
 
228
 
 
229
DeviceConfDialog::~DeviceConfDialog()
 
230
{
 
231
}
 
232
 
 
233
 
 
234
void DeviceConfDialog::start()
 
235
{
 
236
  if (active_) {
 
237
    present();
 
238
    return;
 
239
  }
 
240
 
 
241
  active_ = true;
 
242
  update(UPD_CD_DEVICES);
 
243
  show_all();
 
244
}
 
245
 
 
246
void DeviceConfDialog::stop()
 
247
{
 
248
  hide();
 
249
  active_ = false;
 
250
}
 
251
 
 
252
void DeviceConfDialog::update(unsigned long level)
 
253
{
 
254
  if (!active_)
 
255
    return;
 
256
 
 
257
  if (level & UPD_CD_DEVICES)
 
258
    import();
 
259
  else if (level & UPD_CD_DEVICE_STATUS)
 
260
    importStatus();
 
261
}
 
262
 
 
263
void DeviceConfDialog::closeAction()
 
264
{
 
265
  stop();
 
266
}
 
267
 
 
268
void DeviceConfDialog::resetAction()
 
269
{
 
270
  import();
 
271
}
 
272
 
 
273
 
 
274
void DeviceConfDialog::applyAction()
 
275
{
 
276
  if (selectedRow_)
 
277
    exportConfiguration(selectedRow_);
 
278
  exportData();
 
279
  guiUpdate(UPD_CD_DEVICES);
 
280
}
 
281
 
 
282
void DeviceConfDialog::addDeviceAction()
 
283
{
 
284
  const char *s;
 
285
 
 
286
  std::string dev;
 
287
  std::string vendor;
 
288
  std::string product;
 
289
  CdDevice *cddev;
 
290
 
 
291
  if ((s = checkString(devEntry_.get_text())) == NULL)
 
292
    return;
 
293
  dev = s;
 
294
 
 
295
  if ((s = checkString(vendorEntry_.get_text())) == NULL)
 
296
    return;
 
297
  vendor = s;
 
298
 
 
299
  if ((s = checkString(productEntry_.get_text())) == NULL)
 
300
    return;
 
301
  product = s;
 
302
 
 
303
  if (CdDevice::find(dev.c_str()) != NULL) 
 
304
    return;
 
305
 
 
306
  cddev = CdDevice::add(dev.c_str(), vendor.c_str(), product.c_str());
 
307
 
 
308
  if (cddev) {
 
309
      cddev->manuallyConfigured(true);
 
310
      Gtk::TreeIter new_entry = appendTableEntry(cddev);
 
311
      list_.get_selection()->select(new_entry);
 
312
  }
 
313
 
 
314
  guiUpdate(UPD_CD_DEVICES);
 
315
}
 
316
 
 
317
void DeviceConfDialog::deleteDeviceAction()
 
318
{
 
319
  DeviceData *data;
 
320
  CdDevice *dev;
 
321
 
 
322
  if (selectedRow_) {
 
323
 
 
324
    data = (*selectedRow_)[listColumns_.data];
 
325
 
 
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
 
330
      return;
 
331
    }
 
332
 
 
333
    CdDevice::remove(data->dev.c_str());
 
334
    listModel_->erase(selectedRow_);
 
335
    list_.get_selection()->unselect_all();
 
336
    selectedRow_ = list_.get_selection()->get_selected();
 
337
    delete data;
 
338
 
 
339
    guiUpdate(UPD_CD_DEVICES);
 
340
  }
 
341
}
 
342
 
 
343
void DeviceConfDialog::rescanAction()
 
344
{
 
345
  CdDevice::scan();
 
346
  guiUpdate(UPD_CD_DEVICES);
 
347
}
 
348
 
 
349
Gtk::TreeIter DeviceConfDialog::appendTableEntry(CdDevice *dev)
 
350
{
 
351
  DeviceData *data;
 
352
  const gchar *rowStr[6];
 
353
 
 
354
  data = new DeviceData;
 
355
  data->dev = dev->dev();
 
356
  data->driverId = dev->driverId();
 
357
  data->options = dev->driverOptions();
 
358
 
 
359
  switch (dev->deviceType()) {
 
360
  case CdDevice::CD_ROM:
 
361
    data->deviceType = 0;
 
362
    break;
 
363
  case CdDevice::CD_R:
 
364
    data->deviceType = 1;
 
365
    break;
 
366
  case CdDevice::CD_RW:
 
367
    data->deviceType = 2;
 
368
    break;
 
369
  }
 
370
 
 
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;
 
378
 
 
379
  return newiter;
 
380
}
 
381
 
 
382
void DeviceConfDialog::import()
 
383
{
 
384
  CdDevice *drun;
 
385
  DeviceData *data;
 
386
 
 
387
  list_.get_selection()->unselect_all();
 
388
  selectedRow_ = list_.get_selection()->get_selected();
 
389
 
 
390
  listModel_->clear();
 
391
 
 
392
  for (drun = CdDevice::first(); drun != NULL; drun = CdDevice::next(drun)) {
 
393
    appendTableEntry(drun);
 
394
  }
 
395
 
 
396
  if (listModel_->children().size() > 0) {
 
397
    list_.columns_autosize();
 
398
    list_.get_selection()->select(Gtk::TreeModel::Path((unsigned)1));
 
399
  }
 
400
}
 
401
 
 
402
void DeviceConfDialog::importConfiguration(Gtk::TreeIter row)
 
403
{
 
404
  char buf[50];
 
405
  DeviceData *data;
 
406
 
 
407
  if (selectedRow_) {
 
408
 
 
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);
 
417
 
 
418
  } else {
 
419
 
 
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);
 
426
  }
 
427
}
 
428
 
 
429
void DeviceConfDialog::importStatus()
 
430
{
 
431
  DeviceData *data;
 
432
  CdDevice *dev;
 
433
 
 
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());
 
440
    }
 
441
  }
 
442
 
 
443
  list_.columns_autosize();
 
444
}
 
445
 
 
446
void DeviceConfDialog::exportConfiguration(Gtk::TreeIter row)
 
447
{
 
448
  DeviceData *data;
 
449
 
 
450
  if (row) {
 
451
    data = (*row)[listColumns_.data];
 
452
 
 
453
    if (data) {
 
454
      data->options = strtoul(driverOptionsEntry_.get_text().c_str(), NULL, 0);
 
455
    }
 
456
  }
 
457
}
 
458
 
 
459
void DeviceConfDialog::exportData()
 
460
{
 
461
  DeviceData *data;
 
462
  CdDevice *dev;
 
463
  std::string s;
 
464
 
 
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()))) {
 
470
 
 
471
      if (dev->driverId() != data->driverId) {
 
472
        dev->driverId(data->driverId);
 
473
        dev->manuallyConfigured(true);
 
474
      }
 
475
 
 
476
      if (dev->deviceType() != ID2DEVICE_TYPE[data->deviceType]) {
 
477
        dev->deviceType(ID2DEVICE_TYPE[data->deviceType]);
 
478
        dev->manuallyConfigured(true);
 
479
      }
 
480
 
 
481
      if (dev->driverOptions() != data->options) {
 
482
        dev->driverOptions(data->options);
 
483
        dev->manuallyConfigured(true);
 
484
      }
 
485
    }
 
486
  }
 
487
}
 
488
 
 
489
 
 
490
 
 
491
void DeviceConfDialog::setDriverId(int id)
 
492
{
 
493
  DeviceData *data;
 
494
 
 
495
  if (selectedRow_ && id >= 0 && id <= CdDevice::maxDriverId()) {
 
496
    data = (*selectedRow_)[listColumns_.data];
 
497
    if (data)
 
498
      data->driverId = id;
 
499
  }
 
500
}
 
501
 
 
502
void DeviceConfDialog::setDeviceType(int id)
 
503
{
 
504
  DeviceData *data;
 
505
 
 
506
  if (selectedRow_ && id >= 0 && id <= CdDevice::maxDriverId()) {
 
507
    data = (*selectedRow_)[listColumns_.data];
 
508
    if (data)
 
509
      data->deviceType = id;
 
510
  }
 
511
}
 
512
 
 
513
void DeviceConfDialog::selectionChanged()
 
514
{
 
515
  Gtk::TreeIter new_sel = list_.get_selection()->get_selected();
 
516
 
 
517
  if ((bool)selectedRow_ != (bool)new_sel || selectedRow_ != new_sel) {
 
518
 
 
519
    if (selectedRow_)
 
520
      exportConfiguration(selectedRow_);
 
521
 
 
522
    selectedRow_ = new_sel;
 
523
    importConfiguration(selectedRow_);
 
524
  }
 
525
}
 
526
 
 
527
const char *DeviceConfDialog::checkString(const std::string &str)
 
528
{
 
529
  static char *buf = NULL;
 
530
  static long bufLen = 0;
 
531
  char *p, *s;
 
532
  long len = strlen(str.c_str());
 
533
 
 
534
  if (len == 0)
 
535
    return NULL;
 
536
 
 
537
  if (buf == NULL || len + 1 > bufLen) {
 
538
    delete[] buf;
 
539
    bufLen = len + 1;
 
540
    buf = new char[bufLen];
 
541
  }
 
542
 
 
543
  strcpy(buf, str.c_str());
 
544
 
 
545
  s = buf;
 
546
  p = buf + len - 1;
 
547
 
 
548
  while (*s != 0 && isspace(*s))
 
549
    s++;
 
550
 
 
551
  if (*s == 0)
 
552
    return NULL;
 
553
 
 
554
  while (p > s && isspace(*p)) {
 
555
    *p = 0;
 
556
    p--;
 
557
  }
 
558
  
 
559
  return s;
 
560
}