Ticket #1945: dvbdevtree_gui.patch

File dvbdevtree_gui.patch, 34.6 KB (added by yeasah@…, 19 years ago)

New code for device tree GUI (no integration with existing code)

  • libs/libmyth/settings.h

     
    468468    void deleteButtonPressed(int);
    469469
    470470protected slots:
    471     void setValueByLabel(const QString& label);
     471    void setValueByIndex(int index);
    472472    void addSelection(const QString& label,
    473473                      QString value=QString::null,
    474474                      bool select=false) {
  • libs/libmyth/settings.cpp

     
    11611161            this, SIGNAL(deleteButtonPressed(int)));
    11621162    connect(this, SIGNAL(valueChanged(const QString&)),
    11631163            widget, SLOT(setCurrentItem(const QString&)));
    1164     connect(widget, SIGNAL(highlighted(const QString&)),
    1165             this, SLOT(setValueByLabel(const QString&)));
     1164    connect(widget, SIGNAL(highlighted(int)),
     1165            this, SLOT(setValueByIndex(int)));
    11661166
    11671167    if (cg)
    11681168        connect(widget, SIGNAL(changeHelpText(QString)), cg,
     
    11811181       widget->setSelectionMode(selectionMode);
    11821182}
    11831183
    1184 void ListBoxSetting::setValueByLabel(const QString& label) {
    1185     for(unsigned i = 0 ; i < labels.size() ; ++i)
    1186         if (labels[i] == label) {
    1187             setValue(values[i]);
    1188             return;
    1189         }
    1190     cerr << "BUG: ListBoxSetting::setValueByLabel called for unknown label " << label << endl;
     1184void ListBoxSetting::setValueByIndex(int index) {
     1185    setValue(values[index]);
    11911186}
    11921187
    11931188void ImageSelectSetting::addImageSelection(const QString& label,
  • libs/libmythtv/dvbdevtree_cfg.h

     
     1/*
     2 * \file dvbdevtree_cfg.h
     3 * \brief DVB-S Device Tree Configuration Classes.
     4 * \author Copyright (C) 2006, Yeasah Pell
     5 */
     6
     7#ifndef DVBDEVTREE_CFG_H
     8#define DVBDEVTREE_CFG_H
     9
     10#include "dvbtypes.h"
     11#include "dvbdevtree.h"
     12#include "settings.h"
     13
     14class SwitchTypeSetting;
     15class SwitchPortsSetting;
     16
     17class SwitchConfig : public ConfigurationWizard
     18{
     19    Q_OBJECT
     20public:
     21    SwitchConfig(DVBDevSwitch& switch_dev);
     22
     23public slots:
     24    void update();
     25
     26private:
     27    SwitchTypeSetting* m_type;
     28    SwitchPortsSetting* m_ports;
     29};
     30
     31class RotorPosMap : public ListBoxSetting
     32{
     33    Q_OBJECT
     34public:
     35    RotorPosMap(DVBDevRotor& rotor);
     36
     37    virtual void load();
     38    virtual void save();
     39
     40public slots:
     41    void edit();
     42    void del();
     43
     44protected:
     45    void PopulateList();
     46   
     47private:
     48    DVBDevRotor& m_rotor;
     49    DVBDevRotor::POSMAP m_posmap;
     50};
     51
     52class RotorConfig : public ConfigurationWizard
     53{
     54    Q_OBJECT
     55public:
     56    RotorConfig(DVBDevRotor& rotor);
     57
     58public slots:
     59    void type_changed(const QString& type);
     60    void positions();
     61
     62private:
     63    DVBDevRotor& m_rotor;
     64    TransButtonSetting* m_pos;
     65};
     66
     67class LnbTypeSetting;
     68class LnbLOFSwitchSetting;
     69class LnbLOFLowSetting;
     70class LnbLOFHighSetting;
     71
     72class LnbConfig : public ConfigurationWizard
     73{
     74    Q_OBJECT
     75public:
     76    LnbConfig(DVBDevLnb& lnb);
     77
     78public slots:
     79    void preset(const QString& value);
     80    void update();
     81
     82private:
     83    LnbTypeSetting* m_type;
     84    LnbLOFSwitchSetting* m_lof_switch;
     85    LnbLOFLowSetting* m_lof_lo;
     86    LnbLOFHighSetting* m_lof_hi;
     87};
     88
     89class DeviceTree : public ListBoxSetting
     90{
     91    Q_OBJECT
     92public:
     93    DeviceTree(DVBDevTree& tree);
     94
     95    virtual void load();
     96    virtual void save();
     97
     98protected:
     99    bool editNode(int node_id);
     100    void newRootNode();
     101    void newNode(int parent_id, unsigned int child_num);
     102
     103    bool chooseType(dvbdev_t& type);
     104    void PopulateTree();
     105    void PopulateTree(DVBDevDevice* node,
     106                      DVBDevDevice* parent = NULL,
     107                      unsigned int childnum = 0,
     108                      unsigned int depth = 0);
     109
     110public slots:
     111    void edit();
     112    void del();
     113   
     114private:
     115    DVBDevTree& m_tree;
     116};
     117
     118class DTVDeviceTreeWizard : public VerticalConfigurationGroup,
     119                            public ConfigurationDialog
     120{
     121    Q_OBJECT
     122public:
     123    DTVDeviceTreeWizard(DVBDevTree& tree);
     124
     125    virtual int exec();
     126};
     127
     128bool DTVDeviceNeedsConfiguration(unsigned int input_id);
     129   
     130class DTVDeviceConfigWizard : public ConfigurationWizard
     131{
     132    Q_OBJECT
     133public:
     134    DTVDeviceConfigWizard(DVBDevSettings& settings, unsigned int card_id);
     135    ~DTVDeviceConfigWizard();
     136   
     137public slots:
     138    void SelectNodes();
     139 
     140protected:
     141    void AddNodes(ConfigurationGroup& group, DVBDevDevice* node);
     142   
     143private:
     144    DVBDevTree m_tree;
     145    DVBDevSettings& m_settings;
     146
     147    typedef std::map<unsigned int, Setting*> DEVS;
     148    DEVS m_devs;
     149};
     150
     151#endif // DVBDVBTREE_CFG_H
  • libs/libmythtv/dvbdevtree_cfg.cpp

     
     1/*
     2 * \file dvbdevtree_cfg.cpp
     3 * \brief DVB-S Device Tree Configuration Classes.
     4 * \author Copyright (C) 2006, Yeasah Pell
     5 */
     6
     7#include "mythcontext.h"
     8#include "mythdbcon.h"
     9#include "settings.h"
     10#include "dvbdevtree_cfg.h"
     11#include "dvbdevtree.h"
     12#include <set>
     13#include <cmath>
     14
     15/* Lat/Long items relocated from videosource.cpp */
     16
     17static GlobalLineEdit *DiSEqCLatitude()
     18{
     19    GlobalLineEdit *gc = new GlobalLineEdit("latitude");
     20    gc->setLabel("Latitude");
     21    gc->setHelpText(
     22        QObject::tr("The Cartesian latitude for your location.") + " " +
     23        QObject::tr("Use negative numbers for southern "
     24                    "and western coordinates."));
     25    return gc;
     26}
     27
     28static GlobalLineEdit *DiSEqCLongitude()
     29{
     30    GlobalLineEdit *gc = new GlobalLineEdit("longitude");
     31    gc->setLabel("Longitude");
     32    gc->setHelpText(
     33        QObject::tr("The Cartesian longitude for your location.") + " " +
     34        QObject::tr("Use negative numbers for southern "
     35                    "and western coordinates."));
     36    return gc;
     37}
     38
     39//////////////////////////////////////// DeviceTypeSetting
     40
     41class DeviceTypeSetting : public ComboBoxSetting
     42{
     43public:
     44    DeviceTypeSetting(DVBDevDevice& device) : m_device(device)
     45    {
     46        setLabel(QObject::tr("Device Type"));
     47        addSelection("Switch", QString::number((uint)DVBDEV_SWITCH));
     48        addSelection("Rotor",  QString::number((uint)DVBDEV_ROTOR));
     49        addSelection("LNB", QString::number((uint)DVBDEV_LNB));
     50    }
     51
     52    virtual void load()
     53    {
     54        setValue(getValueIndex(QString::number((uint)m_device.GetDeviceType())));
     55    }
     56
     57    virtual void save()
     58    {
     59        m_device.SetDeviceType((dvbdev_t)getValue().toUInt());
     60    }
     61
     62private:   
     63    DVBDevDevice& m_device;
     64};
     65
     66//////////////////////////////////////// DeviceDescrSetting
     67
     68class DeviceDescrSetting : public LineEditSetting
     69{
     70public:
     71    DeviceDescrSetting(DVBDevDevice& device) : m_device(device)
     72    {
     73        setLabel(QObject::tr("Description"));
     74        setHelpText(QObject::tr("Optional descriptive name for this "
     75                                "device, to make it easier to configure "
     76                                "settings later."));
     77    }
     78   
     79    virtual void load()
     80    {
     81        setValue(m_device.GetDescription());
     82    }
     83
     84    virtual void save()
     85    {
     86        m_device.SetDescription(getValue());
     87    }
     88
     89private:
     90    DVBDevDevice& m_device;
     91};
     92
     93//////////////////////////////////////// SwitchTypeSetting
     94
     95class SwitchTypeSetting : public ComboBoxSetting
     96{
     97public:
     98    SwitchTypeSetting(DVBDevSwitch& switch_dev) : m_switch(switch_dev)
     99    {
     100        setLabel(QObject::tr("Switch Type"));
     101        setHelpText(QObject::tr("Select the type of switch from the list."));
     102
     103        addSelection("Tone", QString::number((uint)SWITCH_TONE));
     104        addSelection("DiSEqC", QString::number((uint)SWITCH_DISEQC_COMMITTED));
     105        addSelection("DiSEqC (Uncommitted)",  QString::number((uint)SWITCH_DISEQC_UNCOMMITTED));
     106        addSelection("Legacy SW21", QString::number((uint)SWITCH_LEGACY_SW21));
     107        addSelection("Legacy SW42", QString::number((uint)SWITCH_LEGACY_SW42));
     108        addSelection("Legacy SW64", QString::number((uint)SWITCH_LEGACY_SW64));
     109    }
     110
     111    virtual void load()
     112    {
     113        setValue(getValueIndex(QString::number((uint)m_switch.GetType())));
     114    }
     115
     116    virtual void save()
     117    {
     118        m_switch.SetType((dvbdev_switch_t)getValue().toUInt());
     119    }
     120
     121private:   
     122    DVBDevSwitch& m_switch;
     123};
     124
     125//////////////////////////////////////// SwitchPortsSetting
     126
     127class SwitchPortsSetting : public LineEditSetting
     128{
     129public:
     130    SwitchPortsSetting(DVBDevSwitch& switch_dev) : m_switch(switch_dev)
     131    {
     132        setLabel(QObject::tr("Number of ports"));
     133        setHelpText(QObject::tr("The number of ports this switch has."));
     134    }
     135
     136    virtual void load()
     137    {
     138        setValue(QString::number(m_switch.GetNumPorts()));
     139    }
     140
     141    virtual void save()
     142    {
     143        m_switch.SetNumPorts(getValue().toUInt());
     144    }
     145
     146private:   
     147    DVBDevSwitch& m_switch;
     148};
     149
     150//////////////////////////////////////// SwitchConfig
     151
     152SwitchConfig::SwitchConfig(DVBDevSwitch& switch_dev)
     153{
     154    ConfigurationGroup* group =
     155        new VerticalConfigurationGroup(false, false);
     156    group->setLabel(QObject::tr("Switch Configuration"));
     157   
     158    group->addChild(new DeviceDescrSetting(switch_dev));
     159    m_type = new SwitchTypeSetting(switch_dev);
     160    group->addChild(m_type);
     161    m_ports = new SwitchPortsSetting(switch_dev);
     162    group->addChild(m_ports);
     163   
     164    connect(m_type, SIGNAL(valueChanged(const QString&)), this, SLOT(update()));
     165   
     166    addChild(group);
     167}
     168
     169void SwitchConfig::update()
     170{
     171    switch((dvbdev_switch_t)m_type->getValue().toUInt())
     172    {
     173    case SWITCH_TONE:
     174    case SWITCH_LEGACY_SW21:
     175    case SWITCH_LEGACY_SW42:
     176        m_ports->setValue("2");
     177        m_ports->setEnabled(false);
     178        break;
     179    case SWITCH_LEGACY_SW64:
     180        m_ports->setValue("3");
     181        m_ports->setEnabled(false);
     182        break;
     183    case SWITCH_DISEQC_COMMITTED:
     184    case SWITCH_DISEQC_UNCOMMITTED:
     185        m_ports->setEnabled(true);
     186        break;
     187    }
     188}
     189
     190//////////////////////////////////////// RotorTypeSetting
     191
     192class RotorTypeSetting : public ComboBoxSetting
     193{
     194public:
     195    RotorTypeSetting(DVBDevRotor& rotor) : m_rotor(rotor)
     196    {
     197        setLabel(QObject::tr("Rotor Type"));
     198        setHelpText(QObject::tr("Select the type of rotor from the list."));
     199        addSelection("DiSEqC 1.2", QString::number((uint)ROTOR_DISEQC_1_2));
     200        addSelection("DiSEqC 1.3 (GotoX/USALS)", QString::number((uint)ROTOR_DISEQC_1_3));
     201    }
     202
     203    virtual void load()
     204    {
     205        setValue(getValueIndex(QString::number((uint)m_rotor.GetType())));
     206    }
     207
     208    virtual void save()
     209    {
     210        m_rotor.SetType((dvbdev_rotor_t)getValue().toUInt());
     211    }
     212
     213private:   
     214    DVBDevRotor& m_rotor;
     215};
     216
     217//////////////////////////////////////// RotorLoSpeedSetting
     218
     219class RotorLoSpeedSetting : public LineEditSetting
     220{
     221public:
     222    RotorLoSpeedSetting(DVBDevRotor& rotor) : m_rotor(rotor)
     223    {
     224        setLabel(QObject::tr("Rotor Low Speed (deg/sec)"));
     225        setHelpText(QObject::tr("To allow the approximate monitoring of "
     226                                "rotor movement, enter the rated angular "
     227                                "speed of the rotor when powered at 13V."));
     228    }
     229
     230    virtual void load()
     231    {
     232        setValue(QString::number(m_rotor.GetLoSpeed()));
     233    }
     234
     235    virtual void save()
     236    {
     237        m_rotor.SetLoSpeed(getValue().toDouble());
     238    }
     239
     240private:   
     241    DVBDevRotor& m_rotor;
     242};
     243
     244//////////////////////////////////////// RotorHiSpeedSetting
     245
     246class RotorHiSpeedSetting : public LineEditSetting
     247{
     248public:
     249    RotorHiSpeedSetting(DVBDevRotor& rotor) : m_rotor(rotor)
     250    {
     251        setLabel(QObject::tr("Rotor High Speed (deg/sec)"));
     252        setHelpText(QObject::tr("To allow the approximate monitoring of "
     253                                "rotor movement, enter the rated angular "
     254                                "speed of the rotor when powered at 18V."));
     255    }
     256   
     257    virtual void load()
     258    {
     259        setValue(QString::number(m_rotor.GetHiSpeed()));
     260    }
     261   
     262    virtual void save()
     263    {
     264        m_rotor.SetHiSpeed(getValue().toDouble());
     265    }
     266   
     267private:   
     268    DVBDevRotor& m_rotor;
     269};
     270
     271//////////////////////////////////////// RotorPosMap
     272
     273static QString AngleToString(double angle)
     274{
     275    QString str;
     276    if(angle >= 0.0)
     277        str = QString::number(angle) + "E";
     278    else if(angle < 0.0)
     279        str = QString::number(-angle) + "W";
     280    return str;
     281}
     282
     283static double AngleToFloat(const QString& angle)
     284{
     285    double pos;
     286    QChar postfix = angle.at(angle.length()-1);
     287    if(postfix.isLetter())
     288    {
     289        pos = angle.left(angle.length()-1).toDouble();
     290        if(postfix == 'W' || postfix == 'w')
     291            pos = -pos;
     292    }
     293    else
     294        pos = angle.toDouble();
     295   
     296    return pos;
     297}
     298
     299RotorPosMap::RotorPosMap(DVBDevRotor& rotor) : m_rotor(rotor)
     300{
     301    connect(this, SIGNAL(editButtonPressed(int)), SLOT(edit()));
     302    connect(this, SIGNAL(deleteButtonPressed(int)), SLOT(del()));
     303    connect(this, SIGNAL(accepted(int)), SLOT(edit()));
     304}
     305
     306void RotorPosMap::load()
     307{
     308    m_posmap = m_rotor.GetPosMap();
     309    PopulateList();
     310}
     311
     312void RotorPosMap::save()
     313{
     314    m_rotor.SetPosMap(m_posmap);
     315}
     316
     317void RotorPosMap::edit()
     318{
     319    unsigned int id = getValue().toUInt();
     320
     321    QString angle;
     322    if(MythPopupBox::showGetTextPopup(gContext->GetMainWindow(),
     323                                      QString("Position Index %1").arg(id),
     324                                      "Orbital Position",
     325                                      angle))
     326    {
     327        m_posmap[id] = AngleToFloat(angle);
     328        PopulateList();
     329    }
     330}
     331
     332void RotorPosMap::del()
     333{
     334    unsigned int id = getValue().toUInt();
     335    m_posmap.erase(id);
     336    PopulateList();
     337}
     338
     339void RotorPosMap::PopulateList()
     340{
     341    int old_sel = getValueIndex(getValue());
     342    clearSelections();
     343    uint num_pos = 64;
     344    for(uint pos = 1; pos < num_pos; pos++)
     345    {
     346        DVBDevRotor::POSMAP::const_iterator p = m_posmap.find(pos);
     347        QString posval;
     348        if(p == m_posmap.end())
     349            posval = "None";
     350        else
     351            posval = AngleToString(p->second);
     352
     353        addSelection(QString("Position #%1 (%2)")
     354                     .arg(pos)
     355                     .arg(posval),
     356                     QString::number(pos));
     357    }
     358    setCurrentItem(old_sel);
     359}
     360
     361//////////////////////////////////////// RotorPosConfig
     362
     363class RotorPosConfig : public VerticalConfigurationGroup,
     364                       public ConfigurationDialog
     365{
     366public:
     367    RotorPosConfig(DVBDevRotor& rotor)
     368    {
     369        setLabel(QObject::tr("Rotor Position Map"));
     370        setUseLabel(true);
     371        addChild(new RotorPosMap(rotor));
     372    }
     373
     374    virtual int exec()
     375    {
     376        while (ConfigurationDialog::exec() == QDialog::Accepted) {}
     377        return QDialog::Rejected;
     378    }
     379};
     380   
     381//////////////////////////////////////// RotorConfig
     382
     383RotorConfig::RotorConfig(DVBDevRotor& rotor) : m_rotor(rotor)
     384{
     385    ConfigurationGroup* group =
     386        new VerticalConfigurationGroup(false, false);
     387    group->setLabel(QObject::tr("Rotor Configuration"));
     388   
     389    group->addChild(new DeviceDescrSetting(rotor));
     390   
     391    ConfigurationGroup* tgroup =
     392        new HorizontalConfigurationGroup(false, false, true, true);
     393
     394    RotorTypeSetting* rtype = new RotorTypeSetting(rotor);
     395    connect(rtype, SIGNAL(valueChanged(const QString&)),
     396            SLOT(type_changed(const QString&)));
     397    tgroup->addChild(rtype);
     398   
     399    m_pos = new TransButtonSetting();
     400    m_pos->setLabel(QObject::tr("Positions"));
     401    m_pos->setHelpText(QObject::tr("Rotor position setup."));
     402    m_pos->setEnabled(rotor.GetType() == ROTOR_DISEQC_1_2);
     403    connect(m_pos, SIGNAL(pressed()), SLOT(positions()));
     404    tgroup->addChild(m_pos);
     405
     406    group->addChild(tgroup);
     407    group->addChild(new RotorLoSpeedSetting(rotor));
     408    group->addChild(new RotorHiSpeedSetting(rotor));
     409    group->addChild(DiSEqCLatitude());
     410    group->addChild(DiSEqCLongitude());
     411   
     412    addChild(group);
     413}
     414
     415void RotorConfig::type_changed(const QString& type)
     416{
     417    dvbdev_rotor_t rtype = (dvbdev_rotor_t)type.toUInt();
     418    m_pos->setEnabled(rtype == ROTOR_DISEQC_1_2);
     419}
     420
     421void RotorConfig::positions()
     422{
     423    RotorPosConfig config(m_rotor);
     424    config.exec();
     425    config.save();
     426}
     427   
     428//////////////////////////////////////// LnbPresetSetting
     429
     430struct lnb_preset
     431{
     432    const char* name;
     433    dvbdev_lnb_t type;
     434    unsigned int lof_sw;
     435    unsigned int lof_lo;
     436    unsigned int lof_hi;
     437};
     438
     439static lnb_preset lnb_presets[] =
     440{
     441    /* description, type, LOF switch, LOF low, LOF high */
     442    { "Single (Europe)", LNB_VOLTAGE, 0, 9750000, 0 },
     443    { "Universal (Europe)", LNB_VOLTAGE_TONE, 11700000, 9750000, 10600000 },
     444    { "Circular (N. America)", LNB_VOLTAGE, 0, 11250000, 0 },
     445    { "Linear (N. America)", LNB_VOLTAGE, 0, 10750000, 0 },
     446    { "C Band", LNB_VOLTAGE, 0, 5150000, 0 },
     447    { NULL, LNB_VOLTAGE, 0, 0, 0 }
     448};
     449
     450unsigned int FindPreset(const DVBDevLnb& lnb)
     451{
     452    unsigned int i;
     453    for(i=0; lnb_presets[i].name != NULL; i++)
     454    {
     455        if(lnb_presets[i].type == lnb.GetType() &&
     456           lnb_presets[i].lof_sw == lnb.GetLOFSwitch() &&
     457           lnb_presets[i].lof_lo == lnb.GetLOFLow() &&
     458           lnb_presets[i].lof_hi == lnb.GetLOFHigh())
     459            break;
     460    }
     461    return i;
     462}
     463
     464class LnbPresetSetting : public ComboBoxSetting
     465{
     466public:
     467    LnbPresetSetting(DVBDevLnb& lnb) : m_lnb(lnb)
     468    {
     469        setLabel(QObject::tr("LNB Preset"));
     470        setHelpText(QObject::tr("Select the LNB preset from the list, or "
     471                                "choose Custom and change the advanced "
     472                                "settings below."));
     473       
     474        unsigned int i;
     475        for(i=0; lnb_presets[i].name != NULL; i++)
     476            addSelection(lnb_presets[i].name, QString::number(i));
     477        addSelection(QObject::tr("Custom"), QString::number(i));
     478    }
     479
     480    virtual void load()
     481    {
     482        setValue(FindPreset(m_lnb));
     483    }
     484
     485    virtual void save()
     486    {
     487    }
     488
     489private:   
     490    DVBDevLnb& m_lnb;
     491};
     492
     493//////////////////////////////////////// LnbTypeSetting
     494
     495class LnbTypeSetting : public ComboBoxSetting
     496{
     497public:
     498    LnbTypeSetting(DVBDevLnb& lnb) : m_lnb(lnb)
     499    {
     500        setLabel(QObject::tr("LNB Type"));
     501        setHelpText(QObject::tr("Select the type of LNB from the list."));
     502        addSelection("Legacy (Fixed)", QString::number((uint)LNB_FIXED));
     503        addSelection("Standard (Voltage)", QString::number((uint)LNB_VOLTAGE));
     504        addSelection("Universal (Voltage+Tone)", QString::number((uint)LNB_VOLTAGE_TONE));
     505    }
     506
     507    virtual void load()
     508    {
     509        setValue(getValueIndex(QString::number((uint)m_lnb.GetType())));
     510    }
     511
     512    virtual void save()
     513    {
     514        m_lnb.SetType((dvbdev_lnb_t)getValue().toUInt());
     515    }
     516
     517private:   
     518    DVBDevLnb& m_lnb;
     519};
     520
     521//////////////////////////////////////// LnbLOFSwitchSetting
     522
     523class LnbLOFSwitchSetting : public LineEditSetting
     524{
     525public:
     526    LnbLOFSwitchSetting(DVBDevLnb& lnb) : m_lnb(lnb)
     527    {
     528        setLabel(QObject::tr("LNB LOF Switch (MHz)"));
     529        setHelpText(QObject::tr("This defines at what frequency "
     530                                "the LNB will do a switch from high to low "
     531                                "setting, and vice versa."));
     532    }
     533
     534    virtual void load()
     535    {
     536        setValue(QString::number(m_lnb.GetLOFSwitch() / 1000));
     537    }
     538
     539    virtual void save()
     540    {
     541        m_lnb.SetLOFSwitch(getValue().toUInt() * 1000);
     542    }
     543
     544private:   
     545    DVBDevLnb& m_lnb;
     546};
     547
     548//////////////////////////////////////// LnbLOFLowSetting
     549
     550class LnbLOFLowSetting : public LineEditSetting
     551{
     552public:
     553    LnbLOFLowSetting(DVBDevLnb& lnb) : m_lnb(lnb)
     554    {
     555        setLabel(QObject::tr("LNB LOF Low (MHz)"));
     556        setHelpText(QObject::tr("This defines the offset the "
     557                                "frequency coming from the LNB will be "
     558                                "in low setting."));
     559    }
     560
     561    virtual void load()
     562    {
     563        setValue(QString::number(m_lnb.GetLOFLow() / 1000));
     564    }
     565
     566    virtual void save()
     567    {
     568        m_lnb.SetLOFLow(getValue().toUInt() * 1000);
     569    }
     570
     571private:   
     572    DVBDevLnb& m_lnb;
     573};
     574
     575//////////////////////////////////////// LnbLOFHighSetting
     576
     577class LnbLOFHighSetting : public LineEditSetting
     578{
     579public:
     580    LnbLOFHighSetting(DVBDevLnb& lnb) : m_lnb(lnb)
     581    {
     582        setLabel(QObject::tr("LNB LOF High (MHz)"));
     583        setHelpText(QObject::tr("This defines the offset the "
     584                                "frequency coming from the LNB will be "
     585                                "in high setting."));
     586    }
     587
     588    virtual void load()
     589    {
     590        setValue(QString::number(m_lnb.GetLOFHigh() / 1000));
     591    }
     592
     593    virtual void save()
     594    {
     595        m_lnb.SetLOFHigh(getValue().toUInt() * 1000);
     596    }
     597   
     598private:   
     599    DVBDevLnb& m_lnb;
     600};
     601
     602//////////////////////////////////////// LnbConfig
     603
     604LnbConfig::LnbConfig(DVBDevLnb& lnb)
     605{
     606    ConfigurationGroup* group =
     607        new VerticalConfigurationGroup(false, false);
     608    group->setLabel(QObject::tr("LNB Configuration"));
     609
     610    group->addChild(new DeviceDescrSetting(lnb));
     611    LnbPresetSetting* preset = new LnbPresetSetting(lnb);
     612    group->addChild(preset);
     613    m_type = new LnbTypeSetting(lnb);
     614    group->addChild(m_type);
     615    m_lof_switch = new LnbLOFSwitchSetting(lnb);
     616    group->addChild(m_lof_switch);
     617    m_lof_lo = new LnbLOFLowSetting(lnb);
     618    group->addChild(m_lof_lo);
     619    m_lof_hi = new LnbLOFHighSetting(lnb);
     620    group->addChild(m_lof_hi);
     621    connect(m_type, SIGNAL(valueChanged(const QString&)), this, SLOT(update()));
     622    connect(preset, SIGNAL(valueChanged(const QString&)), this, SLOT(preset(const QString&)));
     623    addChild(group);
     624}
     625   
     626void LnbConfig::preset(const QString& value)
     627{
     628    unsigned int index = value.toUInt();
     629    if(index >= (sizeof(lnb_presets) / sizeof(lnb_preset)))
     630        return;
     631   
     632    lnb_preset& preset = lnb_presets[index];
     633    if(preset.name == NULL)
     634    {
     635        m_type->setEnabled(true);
     636        update();
     637    }
     638    else
     639    {
     640        m_type->setValue(m_type->getValueIndex(QString::number((uint)preset.type)));
     641        m_lof_switch->setValue(QString::number(preset.lof_sw / 1000));
     642        m_lof_lo->setValue(QString::number(preset.lof_lo / 1000));
     643        m_lof_hi->setValue(QString::number(preset.lof_hi / 1000));
     644        m_type->setEnabled(false);
     645        m_lof_switch->setEnabled(false);
     646        m_lof_hi->setEnabled(false);
     647        m_lof_lo->setEnabled(false);
     648    }
     649}
     650   
     651void LnbConfig::update()
     652{
     653    if(m_type->isEnabled())
     654    {
     655        switch((dvbdev_switch_t)m_type->getValue().toUInt())
     656        {
     657        case LNB_FIXED:
     658        case LNB_VOLTAGE:
     659            m_lof_switch->setEnabled(false);
     660            m_lof_hi->setEnabled(false);
     661            m_lof_lo->setEnabled(true);
     662            break;
     663        case LNB_VOLTAGE_TONE:
     664            m_lof_switch->setEnabled(true);
     665            m_lof_hi->setEnabled(true);
     666            m_lof_lo->setEnabled(true);
     667            break;
     668        }
     669    }
     670}
     671
     672//////////////////////////////////////// DeviceTree
     673
     674
     675DeviceTree::DeviceTree(DVBDevTree& tree) : m_tree(tree)
     676{
     677    connect(this, SIGNAL(editButtonPressed(int)), SLOT(edit()));
     678    connect(this, SIGNAL(deleteButtonPressed(int)), SLOT(del()));
     679    connect(this, SIGNAL(accepted(int)), SLOT(edit()));
     680}
     681
     682void DeviceTree::load()
     683{
     684    PopulateTree();
     685}
     686
     687void DeviceTree::save()
     688{
     689}
     690
     691bool DeviceTree::editNode(int node_id)
     692{
     693    DVBDevDevice* dev = m_tree.FindDevice(node_id);
     694    bool changed = false;
     695    if(dev)
     696    {
     697        switch(dev->GetDeviceType())
     698        {
     699        case DVBDEV_SWITCH:
     700        {
     701            DVBDevSwitch* sw = dynamic_cast<DVBDevSwitch*>(dev);
     702            if(sw)
     703            {
     704                SwitchConfig config(*sw);
     705                changed = (config.exec() == MythDialog::Accepted);
     706            }
     707        }
     708        break;
     709        case DVBDEV_ROTOR:
     710        {
     711            DVBDevRotor* rotor = dynamic_cast<DVBDevRotor*>(dev);
     712            if(rotor)
     713            {
     714                RotorConfig config(*rotor);
     715                changed = (config.exec() == MythDialog::Accepted);
     716            }
     717        }
     718        break;
     719        case DVBDEV_LNB:
     720        {
     721            DVBDevLnb* lnb = dynamic_cast<DVBDevLnb*>(dev);
     722            if(lnb)
     723            {
     724                LnbConfig config(*lnb);
     725                changed = (config.exec() == MythDialog::Accepted);
     726            }
     727        }
     728        break;
     729        default:
     730            break;
     731        }
     732    }
     733
     734    if(changed)
     735        PopulateTree();
     736    return changed;
     737}
     738
     739bool DeviceTree::chooseType(dvbdev_t& type)
     740{
     741    MythPopupBox* popup = new MythPopupBox(gContext->GetMainWindow(), "");
     742    popup->addLabel(tr("Select Type of Device"));
     743
     744    MythListBox* list = new MythListBox(popup);
     745    list->setScrollBar(false);
     746    list->setBottomScrollBar(false);
     747    list->insertItem("Switch");
     748    list->insertItem("Rotor");
     749    list->insertItem("LNB");
     750    list->setCurrentItem(0);
     751
     752    popup->addWidget(list);
     753    connect(list, SIGNAL(accepted(int)), popup, SLOT(done(int)));
     754    list->setFocus();
     755
     756    int res = popup->ExecPopup();
     757    type = (dvbdev_t)list->currentItem();
     758    delete popup;
     759
     760    return res >= 0;
     761}
     762
     763void DeviceTree::newRootNode()
     764{
     765    dvbdev_t type;
     766    if(chooseType(type))
     767    {
     768        DVBDevDevice* dev = DVBDevDevice::CreateByType(m_tree, type);
     769        if(dev)
     770        {
     771            m_tree.SetRoot(dev);
     772            if(!editNode(dev->DeviceID()))
     773                m_tree.SetRoot(NULL);
     774            PopulateTree();
     775        }
     776    }
     777}
     778
     779void DeviceTree::newNode(int parent_id, unsigned int child_num)
     780{
     781    DVBDevDevice* parent = m_tree.FindDevice(parent_id);
     782    if(parent)
     783    {
     784        dvbdev_t type;
     785        if(chooseType(type))
     786        {
     787            DVBDevDevice* dev = DVBDevDevice::CreateByType(m_tree, type);
     788            if(dev)
     789            {
     790                if(parent->SetChild(child_num, dev))
     791                {
     792                    if(!editNode(dev->DeviceID()))
     793                        parent->SetChild(child_num, NULL);
     794                    PopulateTree();
     795                }
     796                else
     797                    delete dev;
     798            }
     799        }
     800    }
     801}
     802
     803void DeviceTree::edit()
     804{
     805    QString id = getValue();
     806    if(id.find(':') == -1)
     807        editNode(id.toInt());
     808    else
     809    {
     810        QStringList vals = QStringList::split(':', id, true);
     811        if(vals[0].isEmpty())
     812            newRootNode();
     813        else
     814            newNode(vals[0].toInt(), vals[1].toUInt());
     815    }
     816    setFocus();
     817}
     818
     819void DeviceTree::del()
     820{
     821    QString id = getValue();
     822    if(id.find(':') == -1)
     823    {
     824        int node_id = id.toInt();
     825        DVBDevDevice* dev = m_tree.FindDevice(node_id);
     826        if(dev)
     827        {
     828            DVBDevDevice* parent = dev->GetParent();
     829            if(parent)
     830                parent->SetChild(dev->GetOrdinal(), NULL);
     831            else
     832                m_tree.SetRoot(NULL);
     833           
     834            PopulateTree();
     835        }
     836    }
     837    setFocus();
     838}
     839
     840void DeviceTree::PopulateTree()
     841{
     842    int old_sel = getValueIndex(getValue());
     843    clearSelections();
     844    PopulateTree(m_tree.Root());
     845    setCurrentItem(old_sel);
     846}
     847   
     848void DeviceTree::PopulateTree(DVBDevDevice* node,
     849                              DVBDevDevice* parent,
     850                              unsigned int childnum,
     851                              unsigned int depth)
     852{
     853    QString indent;
     854    indent.fill('\t', depth);
     855    if(node)
     856    {
     857        QString id = QString::number(node->DeviceID());
     858        addSelection(indent + node->GetDescription(), id);
     859        unsigned int num_ch = node->NumChildren();
     860        for(unsigned int ch = 0; ch < num_ch; ch++)
     861            PopulateTree(node->GetChild(ch), node, ch, depth+1);
     862    }
     863    else
     864    {
     865        QString id;
     866        if(parent)
     867            id = QString::number(parent->DeviceID());
     868        id += ":" + QString::number(childnum);
     869       
     870        addSelection(indent + "(Unconnected)", id);
     871    }
     872}
     873
     874//////////////////////////////////////// DTVDeviceTreeWizard
     875
     876DTVDeviceTreeWizard::DTVDeviceTreeWizard(DVBDevTree& tree)
     877    : ConfigurationGroup(false, true, false, false),
     878      VerticalConfigurationGroup(false, true, false, false)
     879{
     880    setLabel(QObject::tr("DVB-S Device Tree"));
     881    setUseLabel(true);
     882    addChild(new DeviceTree(tree));
     883}
     884
     885int DTVDeviceTreeWizard::exec()
     886{
     887    while (ConfigurationDialog::exec() == QDialog::Accepted) {}
     888    return QDialog::Rejected;
     889}
     890
     891//////////////////////////////////////// SwitchSetting
     892
     893class SwitchSetting : public ComboBoxSetting
     894{
     895public:
     896    SwitchSetting(DVBDevDevice& node, DVBDevSettings& settings)
     897        : m_node(node), m_settings(settings)
     898    {
     899        setLabel(node.GetDescription());
     900        setHelpText(QObject::tr("Choose a port to use for this switch."));
     901
     902        unsigned int num_children = node.NumChildren();
     903        for(unsigned int ch = 0; ch < num_children; ch++)
     904        {
     905            QString val = QString("%1").arg(ch);
     906            QString descr = QString("Port %1").arg(ch+1);
     907            DVBDevDevice* child = node.GetChild(ch);
     908            if(child)
     909                descr += QString(" (%2)").arg(child->GetDescription());
     910            addSelection(descr, val);
     911        }
     912    }
     913
     914    virtual void load()
     915    {
     916        double value = m_settings.GetValue(m_node.DeviceID());
     917        setValue((unsigned int)value);
     918    }
     919
     920    virtual void save()
     921    {
     922        m_settings.SetValue(m_node.DeviceID(), getValue().toDouble());
     923    }
     924
     925private:
     926    DVBDevDevice& m_node;
     927    DVBDevSettings& m_settings;
     928};
     929
     930//////////////////////////////////////// RotorSetting
     931
     932class RotorSetting : public ComboBoxSetting
     933{
     934public:
     935    RotorSetting(DVBDevDevice& node, DVBDevSettings& settings)
     936        : m_node(node), m_settings(settings)
     937    {
     938        setLabel(node.GetDescription());
     939        setHelpText(QObject::tr("Choose a satellite position."));
     940
     941        DVBDevRotor* rotor = dynamic_cast<DVBDevRotor*>(&m_node);
     942        if(rotor)
     943            m_posmap = rotor->GetPosMap();
     944    }
     945
     946    virtual void load()
     947    {
     948        clearSelections();
     949        DVBDevRotor::POSMAP::iterator p;
     950        for(p = m_posmap.begin(); p != m_posmap.end(); p++)
     951            addSelection(AngleToString(p->second), QString::number(p->second));
     952        double angle = m_settings.GetValue(m_node.DeviceID());
     953        setValue(getValueIndex(QString::number(angle)));
     954    }
     955
     956    virtual void save()
     957    {
     958        m_settings.SetValue(m_node.DeviceID(), getValue().toDouble());
     959    }
     960
     961private:
     962    DVBDevDevice& m_node;
     963    DVBDevSettings& m_settings;
     964    DVBDevRotor::POSMAP m_posmap;
     965};
     966
     967//////////////////////////////////////// USALSRotorSetting
     968
     969class USALSRotorSetting : public LineEditSetting
     970{
     971public:
     972    USALSRotorSetting(DVBDevDevice& node, DVBDevSettings& settings)
     973        : m_node(node), m_settings(settings)
     974    {
     975        setLabel(node.GetDescription());
     976        setHelpText(QObject::tr("The longitude of the satellite "
     977                                "you are aiming at.  For western hemisphere "
     978                                "use a 'W' suffix.  Value is in decimal."));
     979    }
     980
     981    virtual void load()
     982    {
     983        setValue(AngleToString(m_settings.GetValue(m_node.DeviceID())));
     984    }
     985
     986    virtual void save()
     987    {
     988        m_settings.SetValue(m_node.DeviceID(), AngleToFloat(getValue()));
     989    }
     990
     991private:
     992    DVBDevDevice& m_node;
     993    DVBDevSettings& m_settings;
     994};
     995
     996//////////////////////////////////////// DTVDeviceNeedsConfiguration
     997
     998bool DTVDeviceNeedsConfiguration(unsigned int card_id)
     999{
     1000    bool needs_conf = false;
     1001    MSqlQuery query(MSqlQuery::InitCon());
     1002    query.prepare("SELECT dtv_dev_type"
     1003                  " FROM dtv_device_tree, capturecard"
     1004                  " WHERE capturecard.dtv_dev_id = dtv_device_tree.dtv_dev_id"
     1005                  " AND capturecard.cardid = :CARDID");
     1006    query.bindValue(":CARDID", card_id);
     1007    if(query.exec() && query.isActive() && query.next())
     1008        needs_conf = (query.value(0).toString() != "lnb");
     1009    return needs_conf;
     1010}
     1011
     1012//////////////////////////////////////// DTVDeviceConfigWizard
     1013
     1014DTVDeviceConfigWizard::DTVDeviceConfigWizard(DVBDevSettings& settings,
     1015                                             unsigned int card_id)
     1016    : m_settings(settings)
     1017{
     1018    ConfigurationGroup* group =
     1019        new VerticalConfigurationGroup(false, false);
     1020    group->setLabel(QObject::tr("DTV Device Configuration"));
     1021
     1022    // load
     1023    m_tree.Load(card_id);
     1024
     1025    // initial UI setup
     1026    AddNodes(*group, m_tree.Root());
     1027    SelectNodes();
     1028
     1029    addChild(group);
     1030}
     1031
     1032DTVDeviceConfigWizard::~DTVDeviceConfigWizard()
     1033{
     1034}
     1035
     1036void DTVDeviceConfigWizard::AddNodes(ConfigurationGroup& group,
     1037                                     DVBDevDevice* node)
     1038{
     1039    if(node)
     1040    {
     1041        Setting* setting = NULL;
     1042        switch(node->GetDeviceType())
     1043        {
     1044        case DVBDEV_SWITCH:
     1045            setting = new SwitchSetting(*node, m_settings);
     1046            connect(setting, SIGNAL(valueChanged(const QString&)),
     1047                    SLOT(SelectNodes()));
     1048            break;
     1049        case DVBDEV_ROTOR:
     1050        {
     1051            DVBDevRotor* rotor = dynamic_cast<DVBDevRotor*>(node);
     1052            if(rotor && rotor->GetType() == ROTOR_DISEQC_1_2)
     1053                setting = new RotorSetting(*node, m_settings);
     1054            else
     1055                setting = new USALSRotorSetting(*node, m_settings);
     1056            break;
     1057        }
     1058        default:
     1059            break;
     1060        }
     1061
     1062        if(setting)
     1063        {
     1064            // add this node
     1065            m_devs[node->DeviceID()] = setting;
     1066            group.addChild(setting);
     1067        }
     1068
     1069        // add children
     1070        unsigned int num_ch = node->NumChildren();
     1071        for(unsigned int ch = 0; ch < num_ch; ch++)
     1072            AddNodes(group, node->GetChild(ch));
     1073    }
     1074}
     1075
     1076void DTVDeviceConfigWizard::SelectNodes()
     1077{
     1078    save();
     1079
     1080    std::set<unsigned int> active;
     1081    DVBDevDevice* node = m_tree.Root();
     1082    while(node)
     1083    {
     1084        active.insert(node->DeviceID());
     1085        node = node->SelectedChild(m_settings);
     1086    }
     1087
     1088    for(DEVS::iterator i = m_devs.begin(); i != m_devs.end(); i++)
     1089    {
     1090        bool visible = active.find(i->first) != active.end();
     1091        i->second->setEnabled(visible);
     1092    }
     1093}