MythTV  0.26-pre
diseqcsettings.cpp
Go to the documentation of this file.
00001 /*
00002  * \file dvbdevtree_cfg.cpp
00003  * \brief DVB-S Device Tree Configuration Classes.
00004  * \author Copyright (C) 2006, Yeasah Pell
00005  */
00006 
00007 // Std C headers
00008 #include <cmath>
00009 
00010 // MythTV headers
00011 #include "mythdbcon.h"
00012 #include "mythlogging.h"
00013 #include "diseqcsettings.h"
00014 
00015 /* Lat/Long items relocated from videosource.cpp */
00016 
00017 static GlobalLineEdit *DiSEqCLatitude(void)
00018 {
00019     GlobalLineEdit *gc = new GlobalLineEdit("latitude");
00020     gc->setLabel("Latitude");
00021     gc->setHelpText(
00022         DeviceTree::tr("The Cartesian latitude for your location.") + " " +
00023         DeviceTree::tr("Use negative numbers for southern "
00024                     "and western coordinates."));
00025     return gc;
00026 }
00027 
00028 static GlobalLineEdit *DiSEqCLongitude(void)
00029 {
00030     GlobalLineEdit *gc = new GlobalLineEdit("longitude");
00031     gc->setLabel("Longitude");
00032     gc->setHelpText(
00033         DeviceTree::tr("The Cartesian longitude for your location.") + " " +
00034         DeviceTree::tr("Use negative numbers for southern "
00035                     "and western coordinates."));
00036     return gc;
00037 }
00038 
00040 
00041 class DeviceTypeSetting : public ComboBoxSetting, public Storage
00042 {
00043   public:
00044     DeviceTypeSetting(DiSEqCDevDevice &device) :
00045         ComboBoxSetting(this), m_device(device)
00046     {
00047         setLabel(DeviceTree::tr("Device Type"));
00048         addSelection(DeviceTree::tr("Switch"),
00049                      QString::number((uint) DiSEqCDevDevice::kTypeSwitch));
00050         addSelection(DeviceTree::tr("Rotor"),
00051                      QString::number((uint) DiSEqCDevDevice::kTypeRotor));
00052         addSelection(DeviceTree::tr("LNB"),
00053                      QString::number((uint) DiSEqCDevDevice::kTypeLNB));
00054     }
00055 
00056     virtual void Load(void)
00057     {
00058         QString tmp = QString::number((uint) m_device.GetDeviceType());
00059         setValue(getValueIndex(tmp));
00060     }
00061 
00062     virtual void Save(void)
00063     {
00064         m_device.SetDeviceType(
00065             (DiSEqCDevDevice::dvbdev_t) getValue().toUInt());
00066     }
00067 
00068     virtual void Save(QString /*destination*/) { }
00069 
00070   private:
00071     DiSEqCDevDevice &m_device;
00072 };
00073 
00075 
00076 class DeviceDescrSetting : public LineEditSetting, public Storage
00077 {
00078   public:
00079     DeviceDescrSetting(DiSEqCDevDevice &device) :
00080         LineEditSetting(this), m_device(device)
00081     {
00082         setLabel(DeviceTree::tr("Description"));
00083         QString help = DeviceTree::tr(
00084             "Optional descriptive name for this device, to "
00085             "make it easier to configure settings later.");
00086         setHelpText(help);
00087     }
00088 
00089     virtual void Load(void)
00090     {
00091         setValue(m_device.GetDescription());
00092     }
00093 
00094     virtual void Save(void)
00095     {
00096         m_device.SetDescription(getValue());
00097     }
00098 
00099     virtual void Save(QString /*destination*/) { }
00100 
00101   private:
00102     DiSEqCDevDevice &m_device;
00103 };
00104 
00105 
00107 
00108 class DeviceRepeatSetting : public SpinBoxSetting, public Storage
00109 {
00110   public:
00111     DeviceRepeatSetting(DiSEqCDevDevice &device) :
00112         SpinBoxSetting(this, 0, 5, 1), m_device(device)
00113     {
00114         setLabel(DeviceTree::tr("Repeat Count"));
00115         QString help = DeviceTree::tr(
00116             "Number of times to repeat DiSEqC commands sent to this device. "
00117             "Larger values may help with less reliable devices.");
00118         setHelpText(help);
00119     }
00120 
00121     virtual void Load(void)
00122     {
00123         setValue(m_device.GetRepeatCount());
00124     }
00125 
00126     virtual void Save(void)
00127     {
00128         m_device.SetRepeatCount(getValue().toUInt());
00129     }
00130 
00131     virtual void Save(QString /*destination*/) { }
00132 
00133   private:
00134     DiSEqCDevDevice &m_device;
00135 };
00136 
00138 
00139 class SwitchTypeSetting : public ComboBoxSetting, public Storage
00140 {
00141   public:
00142     SwitchTypeSetting(DiSEqCDevSwitch &switch_dev) :
00143         ComboBoxSetting(this), m_switch(switch_dev)
00144     {
00145         setLabel(DeviceTree::tr("Switch Type"));
00146         setHelpText(DeviceTree::tr("Select the type of switch from the list."));
00147 
00148         addSelection(DeviceTree::tr("Tone"),
00149                      QString::number((uint) DiSEqCDevSwitch::kTypeTone));
00150         addSelection(DeviceTree::tr("Voltage"),
00151                      QString::number((uint) DiSEqCDevSwitch::kTypeVoltage));
00152         addSelection(DeviceTree::tr("Mini DiSEqC"),
00153                      QString::number((uint) DiSEqCDevSwitch::kTypeMiniDiSEqC));
00154         addSelection(DeviceTree::tr("DiSEqC"),
00155                      QString::number((uint)
00156                                      DiSEqCDevSwitch::kTypeDiSEqCCommitted));
00157         addSelection(DeviceTree::tr("DiSEqC (Uncommitted)"),
00158                      QString::number((uint)
00159                                      DiSEqCDevSwitch::kTypeDiSEqCUncommitted));
00160         addSelection(DeviceTree::tr("Legacy SW21"),
00161                      QString::number((uint) DiSEqCDevSwitch::kTypeLegacySW21));
00162         addSelection(DeviceTree::tr("Legacy SW42"),
00163                      QString::number((uint) DiSEqCDevSwitch::kTypeLegacySW42));
00164         addSelection(DeviceTree::tr("Legacy SW64"),
00165                      QString::number((uint) DiSEqCDevSwitch::kTypeLegacySW64));
00166     }
00167 
00168     virtual void Load(void)
00169     {
00170         setValue(getValueIndex(QString::number((uint) m_switch.GetType())));
00171     }
00172 
00173     virtual void Save(void)
00174     {
00175         m_switch.SetType((DiSEqCDevSwitch::dvbdev_switch_t)
00176                          getValue().toUInt());
00177     }
00178 
00179     virtual void Save(QString /*destination*/) { }
00180 
00181   private:
00182     DiSEqCDevSwitch &m_switch;
00183 };
00184 
00186 
00187 class SwitchAddressSetting : public LineEditSetting, public Storage
00188 {
00189   public:
00190     SwitchAddressSetting(DiSEqCDevSwitch &switch_dev) :
00191            LineEditSetting(this), m_switch(switch_dev)
00192     {
00193         setLabel(DeviceTree::tr("Address of switch"));
00194         setHelpText(DeviceTree::tr("The DiSEqC address of the switch."));
00195     }
00196 
00197     virtual void Load(void)
00198     {
00199         setValue(QString("0x%1").arg(m_switch.GetAddress(), 0, 16));
00200     }
00201 
00202     virtual void Save(void)
00203     {
00204         m_switch.SetAddress(getValue().toUInt(0, 16));
00205     }
00206 
00207   private:
00208     DiSEqCDevSwitch &m_switch;
00209 };
00210 
00212 
00213 class SwitchPortsSetting : public LineEditSetting, public Storage
00214 {
00215   public:
00216     SwitchPortsSetting(DiSEqCDevSwitch &switch_dev) :
00217         LineEditSetting(this), m_switch(switch_dev)
00218     {
00219         setLabel(DeviceTree::tr("Number of ports"));
00220         setHelpText(DeviceTree::tr("The number of ports this switch has."));
00221     }
00222 
00223     virtual void Load(void)
00224     {
00225         setValue(QString::number(m_switch.GetNumPorts()));
00226     }
00227 
00228     virtual void Save(void)
00229     {
00230         m_switch.SetNumPorts(getValue().toUInt());
00231     }
00232 
00233     virtual void Save(QString /*destination*/) { }
00234 
00235   private:
00236     DiSEqCDevSwitch &m_switch;
00237 };
00238 
00240 
00241 SwitchConfig::SwitchConfig(DiSEqCDevSwitch &switch_dev)
00242 {
00243     ConfigurationGroup *group =
00244         new VerticalConfigurationGroup(false, false);
00245     group->setLabel(DeviceTree::tr("Switch Configuration"));
00246 
00247     group->addChild(new DeviceDescrSetting(switch_dev));
00248     group->addChild(new DeviceRepeatSetting(switch_dev));
00249     m_type = new SwitchTypeSetting(switch_dev);
00250     group->addChild(m_type);
00251     m_address = new SwitchAddressSetting(switch_dev);
00252     group->addChild(m_address);
00253     m_ports = new SwitchPortsSetting(switch_dev);
00254     group->addChild(m_ports);
00255 
00256     connect(m_type, SIGNAL(valueChanged(const QString&)),
00257             this,   SLOT(  update(void)));
00258 
00259     addChild(group);
00260 }
00261 
00262 void SwitchConfig::update(void)
00263 {
00264     switch ((DiSEqCDevSwitch::dvbdev_switch_t) m_type->getValue().toUInt())
00265     {
00266         case DiSEqCDevSwitch::kTypeTone:
00267         case DiSEqCDevSwitch::kTypeVoltage:
00268         case DiSEqCDevSwitch::kTypeMiniDiSEqC:
00269         case DiSEqCDevSwitch::kTypeLegacySW21:
00270         case DiSEqCDevSwitch::kTypeLegacySW42:
00271             m_address->setValue(QString("0x10"));
00272             m_address->setEnabled(false);
00273             m_ports->setValue("2");
00274             m_ports->setEnabled(false);
00275             break;
00276         case DiSEqCDevSwitch::kTypeLegacySW64:
00277             m_address->setValue(QString("0x10"));
00278             m_address->setEnabled(false);
00279             m_ports->setValue("3");
00280             m_ports->setEnabled(false);
00281             break;
00282         case DiSEqCDevSwitch::kTypeDiSEqCCommitted:
00283         case DiSEqCDevSwitch::kTypeDiSEqCUncommitted:
00284             m_address->setEnabled(true);
00285             m_ports->setEnabled(true);
00286             break;
00287     }
00288 }
00289 
00291 
00292 class RotorTypeSetting : public ComboBoxSetting, public Storage
00293 {
00294   public:
00295     RotorTypeSetting(DiSEqCDevRotor &rotor) :
00296         ComboBoxSetting(this), m_rotor(rotor)
00297     {
00298         setLabel(DeviceTree::tr("Rotor Type"));
00299         setHelpText(DeviceTree::tr("Select the type of rotor from the list."));
00300         addSelection(DeviceTree::tr("DiSEqC 1.2"),
00301                      QString::number((uint) DiSEqCDevRotor::kTypeDiSEqC_1_2));
00302         addSelection(DeviceTree::tr("DiSEqC 1.3 (GotoX/USALS)"),
00303                      QString::number((uint) DiSEqCDevRotor::kTypeDiSEqC_1_3));
00304     }
00305 
00306     virtual void Load(void)
00307     {
00308         setValue(getValueIndex(QString::number((uint)m_rotor.GetType())));
00309     }
00310 
00311     virtual void Save(void)
00312     {
00313         m_rotor.SetType((DiSEqCDevRotor::dvbdev_rotor_t)getValue().toUInt());
00314     }
00315 
00316     virtual void Save(QString /*destination*/) { }
00317 
00318   private:
00319     DiSEqCDevRotor &m_rotor;
00320 };
00321 
00323 
00324 class RotorLoSpeedSetting : public LineEditSetting, public Storage
00325 {
00326   public:
00327     RotorLoSpeedSetting(DiSEqCDevRotor &rotor) :
00328         LineEditSetting(this), m_rotor(rotor)
00329     {
00330         setLabel(DeviceTree::tr("Rotor Low Speed (deg/sec)"));
00331         QString help = DeviceTree::tr(
00332             "To allow the approximate monitoring of rotor movement, enter "
00333             "the rated angular speed of the rotor when powered at 13V.");
00334         setHelpText(help);
00335     }
00336 
00337     virtual void Load(void)
00338     {
00339         setValue(QString::number(m_rotor.GetLoSpeed()));
00340     }
00341 
00342     virtual void Save(void)
00343     {
00344         m_rotor.SetLoSpeed(getValue().toDouble());
00345     }
00346 
00347     virtual void Save(QString /*destination*/) { }
00348 
00349   private:
00350     DiSEqCDevRotor &m_rotor;
00351 };
00352 
00354 
00355 class RotorHiSpeedSetting : public LineEditSetting, public Storage
00356 {
00357   public:
00358     RotorHiSpeedSetting(DiSEqCDevRotor &rotor) :
00359         LineEditSetting(this), m_rotor(rotor)
00360     {
00361         setLabel(DeviceTree::tr("Rotor High Speed (deg/sec)"));
00362         QString help = DeviceTree::tr(
00363             "To allow the approximate monitoring of rotor movement, enter "
00364             "the rated angular speed of the rotor when powered at 18V.");
00365         setHelpText(help);
00366     }
00367 
00368     virtual void Load(void)
00369     {
00370         setValue(QString::number(m_rotor.GetHiSpeed()));
00371     }
00372 
00373     virtual void Save(void)
00374     {
00375         m_rotor.SetHiSpeed(getValue().toDouble());
00376     }
00377 
00378     virtual void Save(QString /*destination*/) { }
00379 
00380   private:
00381     DiSEqCDevRotor &m_rotor;
00382 };
00383 
00385 
00386 static QString AngleToString(double angle)
00387 {
00388     QString str = QString::null;
00389     if (angle >= 0.0)
00390         str = QString::number(angle) +
00391             DeviceTree::tr("E", "Eastern Hemisphere");
00392     else /* if (angle < 0.0) */
00393         str = QString::number(-angle) +
00394             DeviceTree::tr("W", "Western Hemisphere");
00395     return str;
00396 }
00397 
00398 static double AngleToEdit(double angle, QString &hemi)
00399 {
00400     if (angle > 0.0)
00401     {
00402         hemi = "E";
00403         return angle;
00404     }
00405 
00406     hemi = "W";
00407     return -angle;
00408 }
00409 
00410 static double AngleToFloat(const QString &angle, bool translated = true)
00411 {
00412     if (angle.length() < 2)
00413         return 0.0;
00414 
00415     double pos;
00416     QChar postfix = angle.at(angle.length() - 1);
00417     if (postfix.isLetter())
00418     {
00419         pos = angle.left(angle.length() - 1).toDouble();
00420         if ((translated &&
00421              (postfix.toUpper() ==
00422               DeviceTree::tr("W", "Western Hemisphere")[0])) ||
00423             (!translated && (postfix.toUpper() == 'W')))
00424         {
00425             pos = -pos;
00426         }
00427     }
00428     else
00429         pos = angle.toDouble();
00430 
00431     return pos;
00432 }
00433 
00434 RotorPosMap::RotorPosMap(DiSEqCDevRotor &rotor) :
00435     ListBoxSetting(this), m_rotor(rotor)
00436 {
00437     connect(this, SIGNAL(editButtonPressed(int)),   SLOT(edit(void)));
00438     connect(this, SIGNAL(deleteButtonPressed(int)), SLOT(del(void)));
00439     connect(this, SIGNAL(accepted(int)),            SLOT(edit(void)));
00440 }
00441 
00442 void RotorPosMap::Load(void)
00443 {
00444     m_posmap = m_rotor.GetPosMap();
00445     PopulateList();
00446 }
00447 
00448 void RotorPosMap::Save(void)
00449 {
00450     m_rotor.SetPosMap(m_posmap);
00451 }
00452 
00453 void RotorPosMap::edit(void)
00454 {
00455     uint id = getValue().toUInt();
00456 
00457     QString angle;
00458     if (MythPopupBox::showGetTextPopup(
00459             GetMythMainWindow(),
00460             DeviceTree::tr("Position Index %1").arg(id),
00461             DeviceTree::tr("Orbital Position"), angle))
00462     {
00463         m_posmap[id] = AngleToFloat(angle);
00464         PopulateList();
00465     }
00466 }
00467 
00468 void RotorPosMap::del(void)
00469 {
00470     uint id = getValue().toUInt();
00471     m_posmap.erase(m_posmap.find(id));
00472     PopulateList();
00473 }
00474 
00475 void RotorPosMap::PopulateList(void)
00476 {
00477     int old_sel = getValueIndex(getValue());
00478     clearSelections();
00479     uint num_pos = 64;
00480     for (uint pos = 1; pos < num_pos; pos++)
00481     {
00482         uint_to_dbl_t::const_iterator it = m_posmap.find(pos);
00483         QString posval = DeviceTree::tr("None");
00484         if (it != m_posmap.end())
00485             posval = AngleToString(*it);
00486 
00487         addSelection(DeviceTree::tr("Position #%1 (%2)").arg(pos).arg(posval),
00488                      QString::number(pos));
00489     }
00490     setCurrentItem(old_sel);
00491 }
00492 
00494 
00495 class RotorPosConfig : public ConfigurationDialog
00496 {
00497   public:
00498     RotorPosConfig(DiSEqCDevRotor &rotor)
00499     {
00500         setLabel(DeviceTree::tr("Rotor Position Map"));
00501         addChild(new RotorPosMap(rotor));
00502     }
00503 
00504     virtual DialogCode exec(void)
00505     {
00506         while (ConfigurationDialog::exec() == kDialogCodeAccepted);
00507         return kDialogCodeRejected;
00508     }
00509 };
00510 
00512 
00513 RotorConfig::RotorConfig(DiSEqCDevRotor &rotor) : m_rotor(rotor)
00514 {
00515     ConfigurationGroup *group =
00516         new VerticalConfigurationGroup(false, false);
00517     group->setLabel(DeviceTree::tr("Rotor Configuration"));
00518 
00519     group->addChild(new DeviceDescrSetting(rotor));
00520     group->addChild(new DeviceRepeatSetting(rotor));
00521 
00522     ConfigurationGroup *tgroup =
00523         new HorizontalConfigurationGroup(false, false, true, true);
00524 
00525     RotorTypeSetting *rtype = new RotorTypeSetting(rotor);
00526     connect(rtype, SIGNAL(valueChanged(const QString&)),
00527             this,  SLOT(  SetType(     const QString&)));
00528     tgroup->addChild(rtype);
00529 
00530     m_pos = new TransButtonSetting();
00531     m_pos->setLabel(DeviceTree::tr("Positions"));
00532     m_pos->setHelpText(DeviceTree::tr("Rotor position setup."));
00533     m_pos->setEnabled(rotor.GetType() == DiSEqCDevRotor::kTypeDiSEqC_1_2);
00534     connect(m_pos, SIGNAL(pressed(void)),
00535             this,  SLOT(  RunRotorPositionsDialog(void)));
00536     tgroup->addChild(m_pos);
00537 
00538     group->addChild(tgroup);
00539     group->addChild(new RotorLoSpeedSetting(rotor));
00540     group->addChild(new RotorHiSpeedSetting(rotor));
00541     group->addChild(DiSEqCLatitude());
00542     group->addChild(DiSEqCLongitude());
00543 
00544     addChild(group);
00545 }
00546 
00547 void RotorConfig::SetType(const QString &type)
00548 {
00549     DiSEqCDevRotor::dvbdev_rotor_t rtype;
00550     rtype = (DiSEqCDevRotor::dvbdev_rotor_t) type.toUInt();
00551     m_pos->setEnabled(rtype == DiSEqCDevRotor::kTypeDiSEqC_1_2);
00552 }
00553 
00554 void RotorConfig::RunRotorPositionsDialog(void)
00555 {
00556     RotorPosConfig config(m_rotor);
00557     config.exec();
00558     config.Save();
00559 }
00560 
00562 
00563 class lnb_preset
00564 {
00565   public:
00566     lnb_preset(const QString &_name, DiSEqCDevLNB::dvbdev_lnb_t _type,
00567                uint _lof_sw = 0, uint _lof_lo = 0,
00568                uint _lof_hi = 0, bool _pol_inv = false) :
00569         name(_name),     type(_type),
00570         lof_sw(_lof_sw), lof_lo(_lof_lo),
00571         lof_hi(_lof_hi), pol_inv(_pol_inv) {}
00572 
00573   public:
00574     QString                    name;
00575     DiSEqCDevLNB::dvbdev_lnb_t type;
00576     uint                       lof_sw;
00577     uint                       lof_lo;
00578     uint                       lof_hi;
00579     bool                       pol_inv;
00580 };
00581 
00582 static lnb_preset lnb_presets[] =
00583 {
00584     /* description, type, LOF switch, LOF low, LOF high, inverted polarity */
00585     lnb_preset(DeviceTree::tr("Single (Europe)"),
00586                DiSEqCDevLNB::kTypeVoltageControl,       0,  9750000),
00587     lnb_preset(DeviceTree::tr("Universal (Europe)"),
00588                DiSEqCDevLNB::kTypeVoltageAndToneControl,
00589                11700000,  9750000, 10600000),
00590     lnb_preset(DeviceTree::tr("Circular (N. America)"),
00591                DiSEqCDevLNB::kTypeVoltageControl,       0, 11250000),
00592     lnb_preset(DeviceTree::tr("Linear (N. America)"),
00593                DiSEqCDevLNB::kTypeVoltageControl,       0, 10750000),
00594     lnb_preset(DeviceTree::tr("C Band"),
00595                DiSEqCDevLNB::kTypeVoltageControl,       0,  5150000),
00596     lnb_preset(DeviceTree::tr("DishPro Bandstacked"),
00597                DiSEqCDevLNB::kTypeBandstacked,          0, 11250000, 14350000),
00598     lnb_preset(QString::null, DiSEqCDevLNB::kTypeVoltageControl),
00599 };
00600 
00601 static uint FindPreset(const DiSEqCDevLNB &lnb)
00602 {
00603     uint i;
00604     for (i = 0; !lnb_presets[i].name.isEmpty(); i++)
00605     {
00606         if (lnb_presets[i].type   == lnb.GetType()      &&
00607             lnb_presets[i].lof_sw == lnb.GetLOFSwitch() &&
00608             lnb_presets[i].lof_lo == lnb.GetLOFLow()    &&
00609             lnb_presets[i].lof_hi == lnb.GetLOFHigh()   &&
00610             lnb_presets[i].pol_inv== lnb.IsPolarityInverted())
00611         {
00612             break;
00613         }
00614     }
00615     return i;
00616 }
00617 
00618 class LNBPresetSetting : public ComboBoxSetting, public Storage
00619 {
00620   public:
00621     LNBPresetSetting(DiSEqCDevLNB &lnb) : ComboBoxSetting(this), m_lnb(lnb)
00622     {
00623         setLabel(DeviceTree::tr("LNB Preset"));
00624         QString help = DeviceTree::tr(
00625             "Select the LNB preset from the list, or choose "
00626             "'Custom' and set the advanced settings below.");
00627         setHelpText(help);
00628 
00629         uint i = 0;
00630         for (; !lnb_presets[i].name.isEmpty(); i++)
00631             addSelection(lnb_presets[i].name, QString::number(i));
00632         addSelection(DeviceTree::tr("Custom"), QString::number(i));
00633     }
00634 
00635     virtual void Load(void)
00636     {
00637         setValue(FindPreset(m_lnb));
00638     }
00639 
00640     virtual void Save(void)
00641     {
00642     }
00643 
00644     virtual void Save(QString /*destination*/)
00645     {
00646     }
00647 
00648   private:
00649     DiSEqCDevLNB &m_lnb;
00650 };
00651 
00653 
00654 class LNBTypeSetting : public ComboBoxSetting, public Storage
00655 {
00656   public:
00657     LNBTypeSetting(DiSEqCDevLNB &lnb) : ComboBoxSetting(this), m_lnb(lnb)
00658     {
00659         setLabel(DeviceTree::tr("LNB Type"));
00660         setHelpText(DeviceTree::tr("Select the type of LNB from the list."));
00661         addSelection(DeviceTree::tr("Legacy (Fixed)"),
00662                      QString::number((uint) DiSEqCDevLNB::kTypeFixed));
00663         addSelection(DeviceTree::tr("Standard (Voltage)"),
00664                      QString::number((uint) DiSEqCDevLNB::
00665                                      kTypeVoltageControl));
00666         addSelection(DeviceTree::tr("Universal (Voltage & Tone)"),
00667                      QString::number((uint) DiSEqCDevLNB::
00668                                      kTypeVoltageAndToneControl));
00669         addSelection(DeviceTree::tr("Bandstacked"),
00670                      QString::number((uint) DiSEqCDevLNB::kTypeBandstacked));
00671     }
00672 
00673     virtual void Load(void)
00674     {
00675         setValue(getValueIndex(QString::number((uint) m_lnb.GetType())));
00676     }
00677 
00678     virtual void Save(void)
00679     {
00680         m_lnb.SetType((DiSEqCDevLNB::dvbdev_lnb_t) getValue().toUInt());
00681     }
00682 
00683     virtual void Save(QString /*destination*/) { }
00684 
00685   private:
00686     DiSEqCDevLNB &m_lnb;
00687 };
00688 
00690 
00691 class LNBLOFSwitchSetting : public LineEditSetting, public Storage
00692 {
00693   public:
00694     LNBLOFSwitchSetting(DiSEqCDevLNB &lnb) : LineEditSetting(this), m_lnb(lnb)
00695     {
00696         setLabel(DeviceTree::tr("LNB LOF Switch (MHz)"));
00697         QString help = DeviceTree::tr(
00698             "This defines at what frequency the LNB will do a "
00699             "switch from high to low setting, and vice versa.");
00700         setHelpText(help);
00701     }
00702 
00703     virtual void Load(void)
00704     {
00705         setValue(QString::number(m_lnb.GetLOFSwitch() / 1000));
00706     }
00707 
00708     virtual void Save(void)
00709     {
00710         m_lnb.SetLOFSwitch(getValue().toUInt() * 1000);
00711     }
00712 
00713     virtual void Save(QString /*destination*/) { }
00714 
00715   private:
00716     DiSEqCDevLNB &m_lnb;
00717 };
00718 
00720 
00721 class LNBLOFLowSetting : public LineEditSetting, public Storage
00722 {
00723   public:
00724     LNBLOFLowSetting(DiSEqCDevLNB &lnb) : LineEditSetting(this), m_lnb(lnb)
00725     {
00726         setLabel(DeviceTree::tr("LNB LOF Low (MHz)"));
00727         QString help = DeviceTree::tr(
00728             "This defines the offset the frequency coming "
00729             "from the LNB will be in low setting. For bandstacked "
00730             "LNBs this is the vertical/right polarization band.");
00731         setHelpText(help);
00732     }
00733 
00734     virtual void Load(void)
00735     {
00736         setValue(QString::number(m_lnb.GetLOFLow() / 1000));
00737     }
00738 
00739     virtual void Save(void)
00740     {
00741         m_lnb.SetLOFLow(getValue().toUInt() * 1000);
00742     }
00743 
00744     virtual void Save(QString /*destination*/) { }
00745 
00746   private:
00747     DiSEqCDevLNB &m_lnb;
00748 };
00749 
00751 
00752 class LNBLOFHighSetting : public LineEditSetting, public Storage
00753 {
00754   public:
00755     LNBLOFHighSetting(DiSEqCDevLNB &lnb) : LineEditSetting(this), m_lnb(lnb)
00756     {
00757         setLabel(DeviceTree::tr("LNB LOF High (MHz)"));
00758         QString help = DeviceTree::tr(
00759             "This defines the offset the frequency coming from "
00760             "the LNB will be in high setting. For bandstacked "
00761             "LNBs this is the horizontal/left polarization band.");
00762         setHelpText(help);
00763     }
00764 
00765     virtual void Load(void)
00766     {
00767         setValue(QString::number(m_lnb.GetLOFHigh() / 1000));
00768     }
00769 
00770     virtual void Save(void)
00771     {
00772         m_lnb.SetLOFHigh(getValue().toUInt() * 1000);
00773     }
00774 
00775     virtual void Save(QString /*destination*/) { }
00776 
00777   private:
00778     DiSEqCDevLNB &m_lnb;
00779 };
00780 
00781 class LNBPolarityInvertedSetting : public CheckBoxSetting, public Storage
00782 {
00783   public:
00784     LNBPolarityInvertedSetting(DiSEqCDevLNB &lnb) :
00785         CheckBoxSetting(this), m_lnb(lnb)
00786     {
00787         setLabel(DeviceTree::tr("LNB Reversed"));
00788         QString help = DeviceTree::tr(
00789             "This defines whether the signal reaching the LNB "
00790             "is reversed from normal polarization. This happens "
00791             "to circular signals bouncing twice on a toroidal "
00792             "dish.");
00793         setHelpText(help);
00794     }
00795 
00796     virtual void Load(void)
00797     {
00798         setValue(m_lnb.IsPolarityInverted());
00799     }
00800 
00801     virtual void Save(void)
00802     {
00803         m_lnb.SetPolarityInverted(boolValue());
00804     }
00805 
00806     virtual void Save(QString /*destination*/) { }
00807 
00808   private:
00809     DiSEqCDevLNB &m_lnb;
00810 };
00811 
00813 
00814 LNBConfig::LNBConfig(DiSEqCDevLNB &lnb)
00815 {
00816     ConfigurationGroup *group =
00817         new VerticalConfigurationGroup(false, false);
00818     group->setLabel(DeviceTree::tr("LNB Configuration"));
00819 
00820     group->addChild(new DeviceDescrSetting(lnb));
00821     LNBPresetSetting *preset = new LNBPresetSetting(lnb);
00822     group->addChild(preset);
00823     m_type = new LNBTypeSetting(lnb);
00824     group->addChild(m_type);
00825     m_lof_switch = new LNBLOFSwitchSetting(lnb);
00826     group->addChild(m_lof_switch);
00827     m_lof_lo = new LNBLOFLowSetting(lnb);
00828     group->addChild(m_lof_lo);
00829     m_lof_hi = new LNBLOFHighSetting(lnb);
00830     group->addChild(m_lof_hi);
00831     m_pol_inv = new LNBPolarityInvertedSetting(lnb);
00832     group->addChild(m_pol_inv);
00833     connect(m_type, SIGNAL(valueChanged(const QString&)),
00834             this,   SLOT(  UpdateType(  void)));
00835     connect(preset, SIGNAL(valueChanged(const QString&)),
00836             this,   SLOT(  SetPreset(   const QString&)));
00837     addChild(group);
00838 }
00839 
00840 void LNBConfig::SetPreset(const QString &value)
00841 {
00842     uint index = value.toUInt();
00843     if (index >= (sizeof(lnb_presets) / sizeof(lnb_preset)))
00844         return;
00845 
00846     lnb_preset &preset = lnb_presets[index];
00847     if (preset.name.isEmpty())
00848     {
00849         m_type->setEnabled(true);
00850         UpdateType();
00851     }
00852     else
00853     {
00854         m_type->setValue(m_type->getValueIndex(
00855                              QString::number((uint)preset.type)));
00856         m_lof_switch->setValue(QString::number(preset.lof_sw / 1000));
00857         m_lof_lo->setValue(QString::number(preset.lof_lo / 1000));
00858         m_lof_hi->setValue(QString::number(preset.lof_hi / 1000));
00859         m_pol_inv->setValue(preset.pol_inv);
00860         m_type->setEnabled(false);
00861         m_lof_switch->setEnabled(false);
00862         m_lof_hi->setEnabled(false);
00863         m_lof_lo->setEnabled(false);
00864         m_pol_inv->setEnabled(false);
00865     }
00866 }
00867 
00868 void LNBConfig::UpdateType(void)
00869 {
00870     if (!m_type->isEnabled())
00871         return;
00872 
00873     switch ((DiSEqCDevLNB::dvbdev_lnb_t) m_type->getValue().toUInt())
00874     {
00875         case DiSEqCDevLNB::kTypeFixed:
00876         case DiSEqCDevLNB::kTypeVoltageControl:
00877             m_lof_switch->setEnabled(false);
00878             m_lof_hi->setEnabled(false);
00879             m_lof_lo->setEnabled(true);
00880             m_pol_inv->setEnabled(true);
00881             break;
00882         case DiSEqCDevLNB::kTypeVoltageAndToneControl:
00883             m_lof_switch->setEnabled(true);
00884             m_lof_hi->setEnabled(true);
00885             m_lof_lo->setEnabled(true);
00886             m_pol_inv->setEnabled(true);
00887             break;
00888         case DiSEqCDevLNB::kTypeBandstacked:
00889             m_lof_switch->setEnabled(false);
00890             m_lof_hi->setEnabled(true);
00891             m_lof_lo->setEnabled(true);
00892             m_pol_inv->setEnabled(true);
00893             break;
00894     }
00895 }
00896 
00898 
00899 DeviceTree::DeviceTree(DiSEqCDevTree &tree) :
00900     ListBoxSetting(this), m_tree(tree)
00901 {
00902     connect(this, SIGNAL(editButtonPressed(int)),   SLOT(edit(void)));
00903     connect(this, SIGNAL(deleteButtonPressed(int)), SLOT(del(void)));
00904     connect(this, SIGNAL(accepted(int)),            SLOT(edit(void)));
00905 }
00906 
00907 void DeviceTree::Load(void)
00908 {
00909     PopulateTree();
00910 }
00911 
00912 void DeviceTree::Save(void)
00913 {
00914 }
00915 
00916 bool DeviceTree::EditNodeDialog(uint nodeid)
00917 {
00918     DiSEqCDevDevice *dev = m_tree.FindDevice(nodeid);
00919     if (!dev)
00920     {
00921         LOG(VB_GENERAL, LOG_ERR, QString("DeviceTree::EditNodeDialog(%1) "
00922                                          "-- device not found").arg(nodeid));
00923         return false;
00924     }
00925 
00926     bool changed = false;
00927     switch (dev->GetDeviceType())
00928     {
00929         case DiSEqCDevDevice::kTypeSwitch:
00930         {
00931             DiSEqCDevSwitch *sw = dynamic_cast<DiSEqCDevSwitch*>(dev);
00932             if (sw)
00933             {
00934                 SwitchConfig config(*sw);
00935                 changed = (config.exec() == MythDialog::Accepted);
00936             }
00937         }
00938         break;
00939 
00940         case DiSEqCDevDevice::kTypeRotor:
00941         {
00942             DiSEqCDevRotor *rotor = dynamic_cast<DiSEqCDevRotor*>(dev);
00943             if (rotor)
00944             {
00945                 RotorConfig config(*rotor);
00946                 changed = (config.exec() == MythDialog::Accepted);
00947             }
00948         }
00949         break;
00950 
00951         case DiSEqCDevDevice::kTypeLNB:
00952         {
00953             DiSEqCDevLNB *lnb = dynamic_cast<DiSEqCDevLNB*>(dev);
00954             if (lnb)
00955             {
00956                 LNBConfig config(*lnb);
00957                 changed = (config.exec() == MythDialog::Accepted);
00958             }
00959         }
00960         break;
00961 
00962         default:
00963             break;
00964     }
00965 
00966     if (changed)
00967         PopulateTree();
00968 
00969     return changed;
00970 }
00971 
00972 bool DeviceTree::RunTypeDialog(DiSEqCDevDevice::dvbdev_t &type)
00973 {
00974     MythPopupBox *popup = new MythPopupBox(GetMythMainWindow(), "");
00975     popup->addLabel(tr("Select Type of Device"));
00976 
00977     MythListBox *list = new MythListBox(popup);
00978     list->insertItem(tr("Switch"));
00979     list->insertItem(tr("Rotor"));
00980     list->insertItem(tr("LNB"));
00981     list->setCurrentRow(0, QItemSelectionModel::Select);
00982 
00983     popup->addWidget(list);
00984     connect(list,  SIGNAL(accepted(int)),
00985             popup, SLOT(  AcceptItem(int)));
00986     list->setFocus();
00987 
00988     DialogCode res = popup->ExecPopup();
00989     type = (DiSEqCDevDevice::dvbdev_t)(list->currentRow());
00990 
00991     popup->hide();
00992     popup->deleteLater();
00993 
00994     return kDialogCodeRejected != res;
00995 }
00996 
00997 void DeviceTree::CreateRootNodeDialog(void)
00998 {
00999     DiSEqCDevDevice::dvbdev_t type;
01000     if (!RunTypeDialog(type))
01001         return;
01002 
01003     DiSEqCDevDevice *dev = DiSEqCDevDevice::CreateByType(m_tree, type);
01004     if (dev)
01005     {
01006         m_tree.SetRoot(dev);
01007 
01008         if (!EditNodeDialog(dev->GetDeviceID()))
01009             m_tree.SetRoot(NULL);
01010 
01011         PopulateTree();
01012     }
01013 }
01014 
01015 void DeviceTree::CreateNewNodeDialog(uint parentid, uint child_num)
01016 {
01017     DiSEqCDevDevice *parent = m_tree.FindDevice(parentid);
01018     if (!parent)
01019         return;
01020 
01021     DiSEqCDevDevice::dvbdev_t type;
01022     if (RunTypeDialog(type))
01023     {
01024         DiSEqCDevDevice *dev = DiSEqCDevDevice::CreateByType(m_tree, type);
01025         if (!dev)
01026             return;
01027 
01028         if (parent->SetChild(child_num, dev))
01029         {
01030             if (!EditNodeDialog(dev->GetDeviceID()))
01031                 parent->SetChild(child_num, NULL);
01032             PopulateTree();
01033         }
01034         else
01035         {
01036             delete dev;
01037         }
01038     }
01039 }
01040 
01041 void DeviceTree::edit(void)
01042 {
01043     QString id = getValue();
01044     if (id.indexOf(':') == -1)
01045     {
01046         EditNodeDialog(id.toUInt());
01047     }
01048     else
01049     {
01050         QStringList vals = id.split(':');
01051         if (vals[0].isEmpty())
01052             CreateRootNodeDialog();
01053         else
01054             CreateNewNodeDialog(vals[0].toUInt(), vals[1].toUInt());
01055     }
01056     setFocus();
01057 }
01058 
01059 void DeviceTree::del(void)
01060 {
01061     QString id = getValue();
01062 
01063     if (id.indexOf(':') == -1)
01064     {
01065         uint nodeid = id.toUInt();
01066         DiSEqCDevDevice *dev = m_tree.FindDevice(nodeid);
01067         if (dev)
01068         {
01069             DiSEqCDevDevice *parent = dev->GetParent();
01070             if (parent)
01071                 parent->SetChild(dev->GetOrdinal(), NULL);
01072             else
01073                 m_tree.SetRoot(NULL);
01074 
01075             PopulateTree();
01076         }
01077     }
01078 
01079     setFocus();
01080 }
01081 
01082 void DeviceTree::PopulateTree(void)
01083 {
01084     int old_sel = getValueIndex(getValue());
01085     clearSelections();
01086     PopulateTree(m_tree.Root());
01087     setCurrentItem(old_sel);
01088 }
01089 
01090 void DeviceTree::PopulateTree(DiSEqCDevDevice *node,
01091                               DiSEqCDevDevice *parent,
01092                               uint childnum,
01093                               uint depth)
01094 {
01095     QString indent;
01096     indent.fill(' ', 8 * depth);
01097 
01098     if (node)
01099     {
01100         QString id = QString::number(node->GetDeviceID());
01101         addSelection(indent + node->GetDescription(), id);
01102         uint num_ch = node->GetChildCount();
01103         for (uint ch = 0; ch < num_ch; ch++)
01104             PopulateTree(node->GetChild(ch), node, ch, depth+1);
01105     }
01106     else
01107     {
01108         QString id;
01109         if (parent)
01110             id = QString::number(parent->GetDeviceID());
01111         id += ":" + QString::number(childnum);
01112 
01113         addSelection(indent + "(Unconnected)", id);
01114     }
01115 }
01116 
01118 
01119 DTVDeviceTreeWizard::DTVDeviceTreeWizard(DiSEqCDevTree &tree)
01120 {
01121     setLabel(DeviceTree::tr("DiSEqC Device Tree"));
01122     addChild(new DeviceTree(tree));
01123 }
01124 
01125 DialogCode DTVDeviceTreeWizard::exec(void)
01126 {
01127     while (ConfigurationDialog::exec() == kDialogCodeAccepted);
01128     return kDialogCodeRejected;
01129 }
01130 
01132 
01133 class SwitchSetting : public ComboBoxSetting, public Storage
01134 {
01135   public:
01136     SwitchSetting(DiSEqCDevDevice &node, DiSEqCDevSettings &settings)
01137         : ComboBoxSetting(this), m_node(node), m_settings(settings)
01138     {
01139         setLabel(node.GetDescription());
01140         setHelpText(DeviceTree::tr("Choose a port to use for this switch."));
01141 
01142         uint num_children = node.GetChildCount();
01143         for (uint ch = 0; ch < num_children; ch++)
01144         {
01145             QString val = QString("%1").arg(ch);
01146             QString descr = DeviceTree::tr("Port %1").arg(ch+1);
01147             DiSEqCDevDevice *child = node.GetChild(ch);
01148             if (child)
01149                 descr += QString(" (%2)").arg(child->GetDescription());
01150             addSelection(descr, val);
01151         }
01152     }
01153 
01154     virtual void Load(void)
01155     {
01156         double value = m_settings.GetValue(m_node.GetDeviceID());
01157         setValue((uint)value);
01158     }
01159 
01160     virtual void Save(void)
01161     {
01162         m_settings.SetValue(m_node.GetDeviceID(), getValue().toDouble());
01163     }
01164 
01165     virtual void Save(QString /*destination*/) {}
01166 
01167   private:
01168     DiSEqCDevDevice   &m_node;
01169     DiSEqCDevSettings &m_settings;
01170 };
01171 
01173 
01174 class RotorSetting : public ComboBoxSetting, public Storage
01175 {
01176   public:
01177     RotorSetting(DiSEqCDevDevice &node, DiSEqCDevSettings &settings)
01178         : ComboBoxSetting(this), m_node(node), m_settings(settings)
01179     {
01180         setLabel(node.GetDescription());
01181         setHelpText(DeviceTree::tr("Choose a satellite position."));
01182 
01183         DiSEqCDevRotor *rotor = dynamic_cast<DiSEqCDevRotor*>(&m_node);
01184         if (rotor)
01185             m_posmap = rotor->GetPosMap();
01186     }
01187 
01188     virtual void Load(void)
01189     {
01190         clearSelections();
01191 
01192         uint_to_dbl_t::const_iterator it;
01193         for (it = m_posmap.begin(); it != m_posmap.end(); ++it)
01194             addSelection(AngleToString(*it), QString::number(*it));
01195 
01196         double angle = m_settings.GetValue(m_node.GetDeviceID());
01197         setValue(getValueIndex(QString::number(angle)));
01198     }
01199 
01200     virtual void Save(void)
01201     {
01202         m_settings.SetValue(m_node.GetDeviceID(), getValue().toDouble());
01203     }
01204 
01205     virtual void Save(QString /*destination*/) { }
01206 
01207   private:
01208     DiSEqCDevDevice   &m_node;
01209     DiSEqCDevSettings &m_settings;
01210     uint_to_dbl_t      m_posmap;
01211 };
01212 
01214 
01215 class USALSRotorSetting : public HorizontalConfigurationGroup
01216 {
01217   public:
01218     USALSRotorSetting(DiSEqCDevDevice &node, DiSEqCDevSettings &settings) :
01219         HorizontalConfigurationGroup(false, false, true, true),
01220         numeric(new TransLineEditSetting()),
01221         hemisphere(new TransComboBoxSetting(false)),
01222         m_node(node), m_settings(settings)
01223     {
01224         QString help =
01225             DeviceTree::tr(
01226                 "Locates the satellite you wish to point to "
01227                 "with the longitude along the Clarke Belt of "
01228                 "the satellite [-180..180] and its hemisphere.");
01229 
01230         numeric->setLabel(DeviceTree::tr("Longitude (degrees)"));
01231         numeric->setHelpText(help);
01232         hemisphere->setLabel(DeviceTree::tr("Hemisphere"));
01233         hemisphere->addSelection(DeviceTree::tr("Eastern"), "E", false);
01234         hemisphere->addSelection(DeviceTree::tr("Western"), "W", true);
01235         hemisphere->setHelpText(help);
01236 
01237         addChild(numeric);
01238         addChild(hemisphere);
01239     }
01240 
01241     virtual void Load(void)
01242     {
01243         double  val  = m_settings.GetValue(m_node.GetDeviceID());
01244         QString hemi = QString::null;
01245         double  eval = AngleToEdit(val, hemi);
01246         numeric->setValue(QString::number(eval));
01247         hemisphere->setValue(hemisphere->getValueIndex(hemi));
01248     }
01249 
01250     virtual void Save(void)
01251     {
01252         QString val = QString::number(numeric->getValue().toDouble());
01253         val += hemisphere->getValue();
01254         m_settings.SetValue(m_node.GetDeviceID(), AngleToFloat(val, false));
01255     }
01256 
01257     virtual void Save(QString /*destination*/) { }
01258 
01259   private:
01260     TransLineEditSetting *numeric;
01261     TransComboBoxSetting *hemisphere;
01262     DiSEqCDevDevice      &m_node;
01263     DiSEqCDevSettings    &m_settings;
01264 };
01265 
01267 
01268 DTVDeviceConfigGroup::DTVDeviceConfigGroup(
01269     DiSEqCDevSettings &settings, uint cardid, bool switches_enabled) :
01270     VerticalConfigurationGroup(false, false, true, true),
01271     m_settings(settings), m_switches_enabled(switches_enabled)
01272 {
01273     setLabel(DeviceTree::tr("DTV Device Configuration"));
01274 
01275     // load
01276     m_tree.Load(cardid);
01277 
01278     // initial UI setup
01279     AddNodes(this, QString::null, m_tree.Root());
01280 }
01281 
01282 DTVDeviceConfigGroup::~DTVDeviceConfigGroup(void)
01283 {
01284 }
01285 
01286 void DTVDeviceConfigGroup::AddNodes(
01287     ConfigurationGroup *group, const QString &trigger, DiSEqCDevDevice *node)
01288 {
01289     if (!node)
01290         return;
01291 
01292     Setting *setting = NULL;
01293     switch (node->GetDeviceType())
01294     {
01295         case DiSEqCDevDevice::kTypeSwitch:
01296             setting = new SwitchSetting(*node, m_settings);
01297             setting->setEnabled(m_switches_enabled);
01298             break;
01299         case DiSEqCDevDevice::kTypeRotor:
01300         {
01301             DiSEqCDevRotor *rotor = dynamic_cast<DiSEqCDevRotor*>(node);
01302             if (rotor && (rotor->GetType() == DiSEqCDevRotor::kTypeDiSEqC_1_2))
01303                 setting = new RotorSetting(*node, m_settings);
01304             else
01305                 setting = new USALSRotorSetting(*node, m_settings);
01306             break;
01307         }
01308         default:
01309             break;
01310     }
01311 
01312     if (!setting)
01313     {
01314         AddChild(group, trigger, new TransLabelSetting());
01315         return;
01316     }
01317 
01318     m_devs[node->GetDeviceID()] = setting;
01319 
01320     uint num_ch = node->GetChildCount();
01321     if (DiSEqCDevDevice::kTypeSwitch == node->GetDeviceType())
01322     {
01323         bool useframe = (node != m_tree.Root());
01324         bool zerospace = !useframe;
01325         TriggeredConfigurationGroup *cgrp = new TriggeredConfigurationGroup(
01326             false, useframe, true, true, false, false, true, zerospace);
01327 
01328         cgrp->addChild(setting);
01329         cgrp->setTrigger(setting);
01330 
01331         for (uint i = 0; i < num_ch; i++)
01332             AddNodes(cgrp, QString::number(i), node->GetChild(i));
01333 
01334         AddChild(group, trigger, cgrp);
01335         return;
01336     }
01337 
01338     if (!num_ch)
01339     {
01340         AddChild(group, trigger, setting);
01341         return;
01342     }
01343 
01344     VerticalConfigurationGroup *cgrp =
01345         new VerticalConfigurationGroup(false, false, true, true);
01346 
01347     AddChild(cgrp, QString::null, setting);
01348     for (uint i = 0; i < num_ch; i++)
01349         AddNodes(cgrp, QString::null, node->GetChild(i));
01350 
01351     AddChild(group, trigger, cgrp);
01352 }
01353 
01354 void DTVDeviceConfigGroup::AddChild(
01355     ConfigurationGroup *group, const QString &trigger, Setting *setting)
01356 {
01357     TriggeredConfigurationGroup *grp =
01358         dynamic_cast<TriggeredConfigurationGroup*>(group);
01359 
01360     if (grp && !trigger.isEmpty())
01361         grp->addTarget(trigger, setting);
01362     else
01363         group->addChild(setting);
01364 }
01365 
01367 
01368 enum OLD_DISEQC_TYPES
01369 {
01370     DISEQC_SINGLE                  = 0,
01371     DISEQC_MINI_2                  = 1,
01372     DISEQC_SWITCH_2_1_0            = 2,
01373     DISEQC_SWITCH_2_1_1            = 3,
01374     DISEQC_SWITCH_4_1_0            = 4,
01375     DISEQC_SWITCH_4_1_1            = 5,
01376     DISEQC_POSITIONER_1_2          = 6,
01377     DISEQC_POSITIONER_X            = 7,
01378     DISEQC_POSITIONER_1_2_SWITCH_2 = 8,
01379     DISEQC_POSITIONER_X_SWITCH_2   = 9,
01380     DISEQC_SW21                    = 10,
01381     DISEQC_SW64                    = 11,
01382 };
01383 
01384 // import old diseqc configuration into tree
01385 bool convert_diseqc_db(void)
01386 {
01387     MSqlQuery cquery(MSqlQuery::InitCon());
01388     cquery.prepare(
01389         "SELECT cardid, dvb_diseqc_type "
01390         "FROM capturecard"
01391         "WHERE dvb_diseqc_type IS NOT NULL AND "
01392         "      diseqcid IS NULL");
01393 
01394     // iterate through cards
01395     if (!cquery.exec())
01396         return false;
01397 
01398     MSqlQuery iquery(MSqlQuery::InitCon());
01399     iquery.prepare(
01400         "SELECT cardinputid,    diseqc_port, diseqc_pos, "
01401         "       lnb_lof_switch, lnb_lof_hi,  lnb_lof_lo  "
01402         "FROM cardinput "
01403         "WHERE cardinput.cardid = :CARDID");
01404 
01405     while (cquery.next())
01406     {
01407         uint cardid = cquery.value(0).toUInt();
01408         OLD_DISEQC_TYPES type = (OLD_DISEQC_TYPES) cquery.value(1).toUInt();
01409 
01410         DiSEqCDevTree    tree;
01411         DiSEqCDevDevice *root     = NULL;
01412         uint             add_lnbs = 0;
01413         DiSEqCDevLNB::dvbdev_lnb_t lnb_type =
01414             DiSEqCDevLNB::kTypeVoltageAndToneControl;
01415 
01416         // create root of tree
01417         switch (type)
01418         {
01419             case DISEQC_SINGLE:
01420             {
01421                 // single LNB
01422                 root = DiSEqCDevDevice::CreateByType(
01423                     tree, DiSEqCDevDevice::kTypeLNB);
01424                 break;
01425             }
01426 
01427             case DISEQC_MINI_2:
01428             {
01429                 // tone switch + 2 LNBs
01430                 root = DiSEqCDevDevice::CreateByType(
01431                     tree, DiSEqCDevDevice::kTypeSwitch);
01432                 DiSEqCDevSwitch *sw = dynamic_cast<DiSEqCDevSwitch*>(root);
01433                 if (sw)
01434                 {
01435                     sw->SetType(DiSEqCDevSwitch::kTypeTone);
01436                     sw->SetNumPorts(2);
01437                     add_lnbs = 2;
01438                 }
01439                 break;
01440             }
01441 
01442             case DISEQC_SWITCH_2_1_0:
01443             case DISEQC_SWITCH_2_1_1:
01444             {
01445                 // 2 port diseqc + 2 LNBs
01446                 root = DiSEqCDevDevice::CreateByType(
01447                     tree, DiSEqCDevDevice::kTypeSwitch);
01448                 DiSEqCDevSwitch *sw = dynamic_cast<DiSEqCDevSwitch*>(root);
01449                 if (sw)
01450                 {
01451                     sw->SetType(DiSEqCDevSwitch::kTypeDiSEqCCommitted);
01452                     sw->SetAddress(0x10);
01453                     sw->SetNumPorts(2);
01454                     add_lnbs = 2;
01455                 }
01456                 break;
01457             }
01458 
01459             case DISEQC_SWITCH_4_1_0:
01460             case DISEQC_SWITCH_4_1_1:
01461             {
01462                 // 4 port diseqc + 4 LNBs
01463                 root = DiSEqCDevDevice::CreateByType(
01464                     tree, DiSEqCDevDevice::kTypeSwitch);
01465                 DiSEqCDevSwitch *sw = dynamic_cast<DiSEqCDevSwitch*>(root);
01466                 if (sw)
01467                 {
01468                     sw->SetType(DiSEqCDevSwitch::kTypeDiSEqCCommitted);
01469                     sw->SetAddress(0x10);
01470                     sw->SetNumPorts(4);
01471                     add_lnbs = 4;
01472                 }
01473                 break;
01474             }
01475 
01476             case DISEQC_POSITIONER_1_2:
01477             {
01478                 // non-usals positioner + LNB
01479                 root = DiSEqCDevDevice::CreateByType(
01480                     tree, DiSEqCDevDevice::kTypeRotor);
01481                 DiSEqCDevRotor *rotor = dynamic_cast<DiSEqCDevRotor*>(root);
01482                 if (rotor)
01483                 {
01484                     rotor->SetType(DiSEqCDevRotor::kTypeDiSEqC_1_2);
01485                     add_lnbs = 1;
01486                 }
01487                 break;
01488             }
01489 
01490             case DISEQC_POSITIONER_X:
01491             {
01492                 // usals positioner + LNB (diseqc_pos)
01493                 root = DiSEqCDevDevice::CreateByType(
01494                     tree, DiSEqCDevDevice::kTypeRotor);
01495                 DiSEqCDevRotor *rotor = dynamic_cast<DiSEqCDevRotor*>(root);
01496                 if (rotor)
01497                 {
01498                     rotor->SetType(DiSEqCDevRotor::kTypeDiSEqC_1_3);
01499                     add_lnbs = 1;
01500                 }
01501                 break;
01502             }
01503 
01504             case DISEQC_POSITIONER_1_2_SWITCH_2:
01505             {
01506                 // 10 port uncommitted switch + 10 LNBs
01507                 root = DiSEqCDevDevice::CreateByType(
01508                     tree, DiSEqCDevDevice::kTypeSwitch);
01509                 DiSEqCDevSwitch *sw = dynamic_cast<DiSEqCDevSwitch*>(root);
01510                 if (sw)
01511                 {
01512                     sw->SetType(DiSEqCDevSwitch::kTypeDiSEqCUncommitted);
01513                     sw->SetNumPorts(10);
01514                     add_lnbs = 10;
01515                 }
01516                 break;
01517             }
01518 
01519             case DISEQC_SW21:
01520             {
01521                 // legacy SW21 + 2 fixed lnbs
01522                 root = DiSEqCDevDevice::CreateByType(
01523                     tree, DiSEqCDevDevice::kTypeSwitch);
01524                 DiSEqCDevSwitch *sw = dynamic_cast<DiSEqCDevSwitch*>(root);
01525                 if (sw)
01526                 {
01527                     sw->SetType(DiSEqCDevSwitch::kTypeLegacySW21);
01528                     sw->SetNumPorts(2);
01529                     add_lnbs = 2;
01530                     lnb_type = DiSEqCDevLNB::kTypeFixed;
01531                 }
01532                 break;
01533             }
01534 
01535             case DISEQC_SW64:
01536             {
01537                 // legacy SW64 + 3 fixed lnbs
01538                 root = DiSEqCDevDevice::CreateByType(
01539                     tree, DiSEqCDevDevice::kTypeSwitch);
01540                 DiSEqCDevSwitch *sw = dynamic_cast<DiSEqCDevSwitch*>(root);
01541                 if (sw)
01542                 {
01543                     sw->SetType(DiSEqCDevSwitch::kTypeLegacySW64);
01544                     sw->SetNumPorts(3);
01545                     add_lnbs = 3;
01546                     lnb_type = DiSEqCDevLNB::kTypeFixed;
01547                 }
01548                 break;
01549             }
01550 
01551             default:
01552             {
01553                 LOG(VB_GENERAL, LOG_ERR, "Unknown DiSEqC device type " +
01554                         QString("%1 ignoring card %2").arg(type).arg(cardid));
01555                 break;
01556             }
01557         }
01558 
01559         if (!root)
01560             continue;
01561 
01562         tree.SetRoot(root);
01563 
01564         // create LNBs
01565         for (uint i = 0; i < add_lnbs; i++)
01566         {
01567             DiSEqCDevLNB *lnb = dynamic_cast<DiSEqCDevLNB*>
01568                 (DiSEqCDevDevice::CreateByType(
01569                     tree, DiSEqCDevDevice::kTypeLNB));
01570             if (lnb)
01571             {
01572                 lnb->SetType(lnb_type);
01573                 lnb->SetDescription(QString("LNB #%1").arg(i+1));
01574                 if (!root->SetChild(i, lnb))
01575                     delete lnb;
01576             }
01577         }
01578 
01579         // save the tree to get real device ids
01580         tree.Store(cardid);
01581 
01582         // iterate inputs
01583         DiSEqCDevSettings set;
01584         iquery.bindValue(":CARDID", cardid);
01585 
01586         if (!iquery.exec())
01587             return false;
01588 
01589         while (iquery.next())
01590         {
01591             uint inputid = iquery.value(0).toUInt();
01592             uint port = iquery.value(1).toUInt();
01593             double pos = iquery.value(2).toDouble();
01594             DiSEqCDevLNB *lnb = NULL;
01595 
01596             // configure LNB and settings
01597             switch (type)
01598             {
01599                 case DISEQC_SINGLE:
01600                     lnb = dynamic_cast<DiSEqCDevLNB*>(root);
01601                     break;
01602 
01603                 case DISEQC_MINI_2:
01604                 case DISEQC_SWITCH_2_1_0:
01605                 case DISEQC_SWITCH_2_1_1:
01606                 case DISEQC_SWITCH_4_1_0:
01607                 case DISEQC_SWITCH_4_1_1:
01608                 case DISEQC_SW21:
01609                 case DISEQC_SW64:
01610                 case DISEQC_POSITIONER_1_2_SWITCH_2:
01611                     lnb = dynamic_cast<DiSEqCDevLNB*>(root->GetChild(port));
01612                     set.SetValue(root->GetDeviceID(), port);
01613                     break;
01614 
01615                 case DISEQC_POSITIONER_1_2:
01616                 case DISEQC_POSITIONER_X:
01617                     lnb = dynamic_cast<DiSEqCDevLNB*>(root->GetChild(0));
01618                     set.SetValue(root->GetDeviceID(), pos);
01619                     break;
01620 
01621                 default:
01622                     break;
01623             }
01624 
01625             // configure lnb
01626             if (lnb)
01627             {
01628                 lnb->SetLOFSwitch(iquery.value(3).toUInt());
01629                 lnb->SetLOFHigh(iquery.value(4).toUInt());
01630                 lnb->SetLOFLow(iquery.value(5).toUInt());
01631             }
01632 
01633             // save settings
01634             set.Store(inputid);
01635         }
01636 
01637         // save any LNB changes
01638         tree.Store(cardid);
01639 
01640         // invalidate cached devices
01641         DiSEqCDev trees;
01642         trees.InvalidateTrees();
01643     }
01644 
01645     return true;
01646 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends