Ticket #4623: 19997.sg.patch

File 19997.sg.patch, 27.3 KB (added by gnassas@…, 11 years ago)

updated for current svn

  • libs/libmyth/storagegroup.h

     
    99class MPUBLIC StorageGroup: public ConfigurationWizard
    1010{
    1111  public:
    12     StorageGroup(const QString group = "", const QString hostname = "");
     12    StorageGroup(const QString group = "",
     13                 const QString hostname = "",
     14                 bool useDefaultWhenEmpty = true);
    1315
    1416    void    Init(const QString group = "Default",
    15                  const QString hostname = "");
     17                 const QString hostname = "",
     18                 bool useDefaultWhenEmpty = true);
    1619
     20    void    Delete(void);
     21
     22    virtual void Save(void);
     23
     24    bool hasChanged(void);
     25
     26    QString AddDir(const QString directory);
     27    QString DelDir(const QString directory);
     28
    1729    QString getName(void) const
    1830        { QString tmp = m_groupname; tmp.detach(); return tmp; }
    1931
    2032    QStringList GetDirList(void) const
    2133        { QStringList tmp = m_dirlist; tmp.detach(); return tmp; }
    2234
     35    typedef QMap<QString, QStringList> FilesList;
     36
     37    FilesList GetAllFiles(bool descendIntoSubDirs = false,
     38                          bool followSymbolicLinks = true);
     39    static QStringList GetAllFiles(const QString directory,
     40                                   bool descendIntoSubDirs = false,
     41                                   bool followSymbolicLinks = true);
     42
    2343    QStringList GetFileList(QString Path);
    2444    bool FileExists(QString filename);
    2545    QStringList GetFileInfo(QString filename);
     
    2949
    3050    QString FindNextDirMostFree(void);
    3151
     52    static QStringList GetStorageGroupNames(const QString hostname = "");
     53    static QString FindStorageGroupForDir(const QString directory, const QString hostname = "");
     54
    3255    static void CheckAllStorageGroupDirs(void);
    3356
    3457    static const char *kDefaultStorageDir;
     
    4063  private:
    4164    QString      m_groupname;
    4265    QString      m_hostname;
     66    QStringList  m_originaldirs;
    4367    QStringList  m_dirlist;
     68
     69    static void GetAllFilesImpl(const QString directory,
     70                                QStringList& fileList,
     71                                bool descendIntoSubDirs = false,
     72                                bool followSymbolicLinks = true,
     73                                const QString prefix = "");
    4474};
    4575
    4676class MPUBLIC StorageGroupEditor :
     
    4979    Q_OBJECT
    5080  public:
    5181    StorageGroupEditor(QString group);
     82    virtual ~StorageGroupEditor(void);
    5283    virtual DialogCode exec(void);
    5384    virtual void Load(void);
    54     virtual void Save(void) { }
     85    virtual void Save(void);
    5586    virtual void Save(QString) { }
     87    void Delete();
     88    bool hasChanged(void);
    5689    virtual MythDialog* dialogWidget(MythMainWindow* parent,
    5790                                     const char* widgetname=0);
    5891
     92    QString getGroup(void) const
     93    {
     94        QString groupName;
     95        groupName = m_group->getName();
     96        return groupName;
     97    }
     98
    5999  protected slots:
    60100    void open(QString name);
    61101    void doDelete(void);
    62102
    63103  protected:
    64     QString         m_group;
     104    StorageGroup   *m_group;
    65105    ListBoxSetting *listbox;
    66106    QString         lastValue;
    67107};
     
    72112    Q_OBJECT
    73113  public:
    74114    StorageGroupListEditor(void);
     115    virtual ~StorageGroupListEditor(void);
    75116    virtual DialogCode exec(void);
    76117    virtual void Load(void);
    77     virtual void Save(void) { }
     118    virtual void Save(void);
    78119    virtual void Save(QString) { }
     120    bool hasChanged(void);
    79121    virtual MythDialog* dialogWidget(MythMainWindow* parent,
    80122                                     const char* widgetname=0);
    81123
     
    86128  protected:
    87129    ListBoxSetting *listbox;
    88130    QString         lastValue;
     131
     132    typedef QMap<QString, StorageGroupEditor*> StorageGroupEditors;
     133    StorageGroupEditors m_edited;
     134    StorageGroupEditors m_deleted;
    89135};
    90136
    91137#endif
  • libs/libmyth/storagegroup.cpp

     
    44
    55#include "storagegroup.h"
    66#include "mythcontext.h"
    7 #include "mythdb.h"
    8 #include "mythverbose.h"
     7#include "libmythdb/mythdb.h"
     8#include "libmythdb/mythverbose.h"
    99#include "util.h"
    1010
    1111#define LOC QString("SG(%1): ").arg(m_groupname)
     
    2828 *  \param hostname hostname where to search, blank will search all hosts'
    2929 *                  directories, but only in local directory structure.
    3030 *                  This is parameter is ignored if group is an empty string.
     31 *  \parm useDefaultWhenEmpty fall back to directories in the "Default" group
     32 *                  when no directories can be found for a given group/host
     33 *                  combination. Defaults to true. Clients doing programmatic
     34 *                  manipulation of storage groups should pass false.
    3135 */
    32 StorageGroup::StorageGroup(const QString group, const QString hostname) :
     36StorageGroup::StorageGroup(const QString group, const QString hostname,
     37                           bool useDefaultWhenEmpty) :
    3338    m_groupname(group), m_hostname(hostname)
    3439{
    3540    m_groupname.detach();
    3641    m_hostname.detach();
    3742    m_dirlist.clear();
     43    m_originaldirs.clear();
    3844
    39     Init(m_groupname, m_hostname);
     45    Init(m_groupname, m_hostname, useDefaultWhenEmpty);
    4046}
    4147
    42 void StorageGroup::Init(const QString group, const QString hostname)
     48void StorageGroup::Init(const QString group, const QString hostname,
     49                        bool useDefaultWhenEmpty)
    4350{
    4451    QString dirname;
    4552    MSqlQuery query(MSqlQuery::InitCon());
     
    7077        MythDB::DBError("StorageGroup::StorageGroup()", query);
    7178    else if (!query.next())
    7279    {
    73         if (group != "Default")
     80        if (useDefaultWhenEmpty)
    7481        {
    75             VERBOSE(VB_FILE, LOC +
    76                     QString("Unable to find storage group '%1', trying "
    77                             "'Default' group!").arg(m_groupname));
    78             Init("Default", m_hostname);
    79             return;
     82            if (group != "Default")
     83            {
     84                VERBOSE(VB_FILE, LOC +
     85                        QString("Unable to find storage group '%1', trying "
     86                                "'Default' group!").arg(m_groupname));
     87                Init("Default", m_hostname);
     88                return;
     89            }
     90            else if (!m_hostname.isEmpty())
     91            {
     92                VERBOSE(VB_FILE, LOC +
     93                        QString("Unable to find any directories for the local "
     94                                "Default storage group, trying directories in all "
     95                                "Default groups!").arg(m_groupname));
     96                Init("Default", "");
     97                return;
     98            }
    8099        }
    81         else if (!m_hostname.isEmpty())
    82         {
    83             VERBOSE(VB_FILE, LOC +
    84                     QString("Unable to find any directories for the local "
    85                             "Default storage group, trying directories in all "
    86                             "Default groups!").arg(m_groupname));
    87             Init("Default", "");
    88             return;
    89         }
    90100    }
    91101    else
    92102    {
     
    102112        while (query.next());
    103113    }
    104114
    105     if (!m_dirlist.size())
     115    m_originaldirs = m_dirlist;
     116
     117    if (!m_dirlist.size() && group == "Default")
    106118    {
    107119        QString msg = "Directory value for Default Storage Group is empty.  ";
    108120        QString tmpDir = gContext->GetSetting("RecordFilePrefix");
     
    122134    }
    123135}
    124136
     137/** \brief Remove all host-specific database entries for the Storage Group
     138 */
     139void StorageGroup::Delete(void)
     140{
     141    MSqlQuery query(MSqlQuery::InitCon());
     142    query.prepare("DELETE FROM storagegroup "
     143                  "WHERE groupname = :NAME AND hostname = :HOSTNAME;");
     144    query.bindValue(":NAME", m_groupname);
     145    query.bindValue(":HOSTNAME", m_hostname);
     146    if (!query.exec())
     147        MythDB::DBError("StorageGroup::Delete", query);
     148}
     149
     150void StorageGroup::Save(void)
     151{
     152    ConfigurationWizard::Save();
     153
     154    MSqlQuery query(MSqlQuery::InitCon());
     155
     156    // apply deletes
     157
     158    for (QStringList::iterator oldDir = m_originaldirs.begin();
     159         oldDir != m_originaldirs.end(); ++oldDir)
     160    {
     161        if (!m_dirlist.contains(*oldDir))
     162        {
     163            query.prepare("DELETE FROM storagegroup "
     164                          "WHERE groupname = :NAME "
     165                          "AND dirname = :DIRNAME "
     166                          "AND hostname = :HOSTNAME;");
     167            query.bindValue(":NAME", m_groupname);
     168            query.bindValue(":DIRNAME", (*oldDir) + "/");
     169            query.bindValue(":HOSTNAME", m_hostname);
     170            if (!query.exec())
     171                MythDB::DBError("StorageGroup::save", query);
     172        }
     173    }
     174
     175    // apply inserts
     176
     177    for (QStringList::iterator newDir = m_dirlist.begin();
     178         newDir != m_dirlist.end(); ++newDir)
     179    {
     180        if (!m_originaldirs.contains(*newDir))
     181        {
     182            query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
     183                          "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
     184            query.bindValue(":NAME", m_groupname);
     185            query.bindValue(":DIRNAME", (*newDir) + "/");
     186            query.bindValue(":HOSTNAME", m_hostname);
     187            if (!query.exec())
     188                MythDB::DBError("StorageGroup::save", query);
     189        }
     190    }
     191}
     192
     193bool StorageGroup::hasChanged(void)
     194{
     195    if (m_originaldirs.size() != m_dirlist.size())
     196        return true;
     197
     198    for (QStringList::iterator oldDir = m_originaldirs.begin();
     199         oldDir != m_originaldirs.end(); ++oldDir)
     200    {
     201        if (!m_dirlist.contains(*oldDir))
     202            return true;
     203    }
     204
     205    return false;
     206}
     207
     208/** \brief Adds a directory to a storage group.
     209 *  \param directory    directory to add.
     210 *  \param group        group to add to. defaults to "Default".
     211 *  \param hostname     host to associate with mapping.
     212 *                      Defaults to the local host name.
     213 *  \return Name of directory after adjustments or an empty string
     214 *          if the directory could not be added.
     215 */
     216QString StorageGroup::AddDir(const QString directory)
     217{
     218    QString name = directory;
     219
     220    if (name.right(1) == "/")
     221        name.remove(name.length()-1, 1);
     222
     223    if (!m_dirlist.contains(name))
     224        m_dirlist.append(name);
     225
     226    return name;
     227}
     228
     229/** \brief Deletes a directory from a storage group.
     230 *  \param directory    directory to remove.
     231 *  \param group        group to remove from. defaults to "Default".
     232 *  \param hostname     host to remove for. Defaults to the
     233 *                      local host name.
     234 *  \return Empty string if delete was successful otherwise directory
     235 *          name after adjustments.
     236 */
     237QString StorageGroup::DelDir(const QString directory)
     238{
     239    QString name = directory;
     240
     241    if (name.right(1) == "/")
     242        name.remove(name.length()-1, 1);
     243
     244    int pos = m_dirlist.indexOf(name);
     245    if (pos != -1)
     246    {
     247        m_dirlist.removeAt(pos);
     248        name.truncate(0);
     249    }
     250
     251    return name;
     252}
     253
     254/** \brief Return names of all files found in the storage group's directories.
     255 *  \param descendIntoSubDirs   traverse all subdirectories.
     256 *  \param followSymbolicLinks  include symbolically linked files in the list.
     257 *                              When descendIntoSubDirs is true then links to
     258 *                              folders will be traversed as well.
     259 *  \return A map of the storage group's directories paired with a QStringList
     260 *          of relative filenames found in that directory.
     261 */
     262StorageGroup::FilesList StorageGroup::GetAllFiles(bool descendIntoSubDirs,
     263                                                  bool followSymbolicLinks)
     264{
     265    FilesList allFiles;
     266    for (QStringList::iterator dir = m_dirlist.begin(); dir != m_dirlist.end();
     267         dir++)
     268    {
     269        QStringList files = GetAllFiles(*dir, descendIntoSubDirs, followSymbolicLinks);
     270        if (files.size() > 0)
     271        {
     272            allFiles[*dir] = files;
     273        }
     274    }
     275
     276    return allFiles;
     277}
     278
     279/** \brief Return name of all files stored within a directory.
     280 *  \param directory            directory to search.
     281 *  \param descendIntoSubDirs   traverse all subdirectories.
     282 *  \param followSymbolicLinks  include symbolically linked files in the list.
     283 *                              When descendIntoSubDirs is true then links to
     284 *                              folders will be traversed as well.
     285 *  \return A QStringList of relative filenames found in the directory.
     286 */
     287QStringList StorageGroup::GetAllFiles(const QString directory,
     288                                      bool descendIntoSubDirs,
     289                                      bool followSymbolicLinks)
     290{
     291    QStringList allFiles;
     292    StorageGroup::GetAllFilesImpl(directory,
     293                                  allFiles,
     294                                  descendIntoSubDirs,
     295                                  followSymbolicLinks,
     296                                  "");
     297    return allFiles;
     298}
     299
     300void StorageGroup::GetAllFilesImpl(const QString directory,
     301                                   QStringList& fileList,
     302                                   bool descendIntoSubDirs,
     303                                   bool followSymbolicLinks,
     304                                   const QString prefix)
     305{
     306    QDir dir(directory + prefix);
     307    if (!dir.isReadable())
     308        return;
     309
     310    dir.setSorting(QDir::Unsorted);
     311
     312    QFileInfoList files = dir.entryInfoList();
     313
     314    for (int i = 0; i < files.size(); i++)
     315    {
     316        QFileInfo fi = files.at(i);
     317
     318        QString fileName = fi.fileName();
     319
     320        if (fileName == "." || fileName == ".." ||
     321            (!descendIntoSubDirs && fi.isDir()) ||
     322            (!followSymbolicLinks && fi.isSymLink()))
     323        {
     324            continue;
     325        }
     326
     327        if (fi.isDir())
     328        {
     329            StorageGroup::GetAllFilesImpl(directory,
     330                                          fileList,
     331                                          descendIntoSubDirs,
     332                                          followSymbolicLinks,
     333                                          prefix + "/" + fileName);
     334        }
     335        else
     336        {
     337            fileList.append(prefix.mid(1) + fileName);
     338        }
     339    }
     340}
     341
    125342QStringList StorageGroup::GetFileList(QString Path)
    126343{
    127344    QStringList files;
     
    342559    return nextDir;
    343560}
    344561
     562/** \brief return list of StorageGroup names.
     563 *  \param hostname restrict list to this host, blank will search all
     564 *                  hosts' directories.
     565 */
     566QStringList StorageGroup::GetStorageGroupNames(const QString hostname)
     567{
     568    QStringList groups;
     569
     570    MSqlQuery query(MSqlQuery::InitCon());
     571    if (hostname.isEmpty())
     572    {
     573        query.prepare("SELECT DISTINCT groupname "
     574                      "FROM storagegroup "
     575                      "ORDER BY groupname;");
     576    }
     577    else
     578    {
     579        query.prepare("SELECT DISTINCT groupname "
     580                      "FROM storagegroup "
     581                      "WHERE hostname = :HOSTNAME "
     582                      "ORDER BY groupname;");
     583        query.bindValue(":HOSTNAME", hostname);
     584    }
     585
     586    if (query.exec() && query.isActive())
     587    {
     588        while (query.next())
     589            groups += query.value(0).toString();
     590    }
     591    else
     592        MythDB::DBError("StorageGroup::GetStorageGroupNames getting group names",
     593                             query);
     594
     595    return groups;
     596}
     597
     598/** \brief find name of the StorageGroup containing a given directory.
     599 *  \param directory directory to lookup.
     600 *  \param hostname restrict search to this host. Blank, the default,
     601 *                  will search all hosts' directories.
     602 *
     603 *  N.B. when two different StorageGroups contain the same directory the
     604 *  return value will be unpredictable.
     605 */
     606QString StorageGroup::FindStorageGroupForDir(const QString directory, const QString hostname)
     607{
     608    MSqlQuery query(MSqlQuery::InitCon());
     609
     610    QString searchDir(directory);
     611    if (searchDir.right(1) != "/")
     612        searchDir.append("/");
     613
     614    if (hostname.isEmpty())
     615    {
     616        query.prepare("SELECT groupname "
     617                      "FROM storagegroup "
     618                      "WHERE dirname = :DIR");
     619    }
     620    else
     621    {
     622        query.prepare("SELECT groupname "
     623                      "FROM storagegroup "
     624                      "WHERE hostname = :HOSTNAME "
     625                      "  AND dirname = :DIR");
     626        query.bindValue(":HOSTNAME", hostname);
     627    }
     628    query.bindValue(":DIR", searchDir);
     629
     630    if (!query.exec() || !query.isActive())
     631    {
     632        MythDB::DBError("StorageGroup::FindStorageGroupForDir()", query);
     633        return QString();
     634    }
     635
     636    return query.next()
     637        ? query.value(0).toString()
     638        : QString();
     639}
     640
    345641void StorageGroup::CheckAllStorageGroupDirs(void)
    346642{
    347643    QString m_groupname;
     
    505801/****************************************************************************/
    506802
    507803StorageGroupEditor::StorageGroupEditor(QString group) :
    508     m_group(group), listbox(new ListBoxSetting(this)), lastValue("")
     804    listbox(new ListBoxSetting(this)), lastValue("")
    509805{
    510806    QString dispGroup = group;
    511807
     
    514810    else if (StorageGroup::kSpecialGroups.contains(group))
    515811        dispGroup = QObject::tr(group.toLatin1().constData());
    516812
     813    m_group = new StorageGroup(group, gContext->GetHostName(), false);
     814
    517815    if (gContext->GetSetting("MasterServerIP","master") ==
    518816            gContext->GetSetting("BackendServerIP","me"))
    519817    {
     
    528826    addChild(listbox);
    529827}
    530828
     829StorageGroupEditor::~StorageGroupEditor()
     830{
     831    if (m_group)
     832        delete m_group;
     833}
     834
    531835void StorageGroupEditor::open(QString name)
    532836{
    533837    lastValue = name;
     
    546850        if (name.isEmpty())
    547851            return;
    548852
    549         if (name.right(1) != "/")
    550             name.append("/");
    551 
    552         MSqlQuery query(MSqlQuery::InitCon());
    553         query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
    554                       "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
    555         query.bindValue(":NAME", m_group);
    556         query.bindValue(":DIRNAME", name);
    557         query.bindValue(":HOSTNAME", gContext->GetHostName());
    558         if (!query.exec())
    559             MythDB::DBError("StorageGroupEditor::open", query);
    560         else
    561             lastValue = name;
     853        lastValue = m_group->AddDir(name);
    562854    } else {
    563855        SGPopupResult result = StorageGroupPopup::showPopup(
    564856            gContext->GetMainWindow(),
     
    568860        if (result == SGPopup_CANCEL)
    569861            return;
    570862
    571         if (name.right(1) != "/")
    572             name.append("/");
    573 
    574         MSqlQuery query(MSqlQuery::InitCon());
    575 
    576         query.prepare("DELETE FROM storagegroup "
    577                       "WHERE groupname = :NAME "
    578                           "AND dirname = :DIRNAME "
    579                           "AND hostname = :HOSTNAME;");
    580         query.bindValue(":NAME", m_group);
    581         query.bindValue(":DIRNAME", lastValue);
    582         query.bindValue(":HOSTNAME", gContext->GetHostName());
    583         if (!query.exec())
    584             MythDB::DBError("StorageGroupEditor::open", query);
    585 
    586         query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
    587                       "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
    588         query.bindValue(":NAME", m_group);
    589         query.bindValue(":DIRNAME", name);
    590         query.bindValue(":HOSTNAME", gContext->GetHostName());
    591         if (!query.exec())
    592             MythDB::DBError("StorageGroupEditor::open", query);
    593         else
    594             lastValue = name;
     863        lastValue = m_group->DelDir(lastValue);
     864        if (lastValue.isEmpty())
     865            lastValue = m_group->AddDir(name);
    595866    }
    596867};
    597868
     
    612883
    613884    if (kDialogCodeButton0 == value)
    614885    {
    615         MSqlQuery query(MSqlQuery::InitCon());
    616         query.prepare("DELETE FROM storagegroup "
    617                       "WHERE groupname = :NAME "
    618                           "AND dirname = :DIRNAME "
    619                           "AND hostname = :HOSTNAME;");
    620         query.bindValue(":NAME", m_group);
    621         query.bindValue(":DIRNAME", name);
    622         query.bindValue(":HOSTNAME", gContext->GetHostName());
    623         if (!query.exec())
    624             MythDB::DBError("StorageGroupEditor::doDelete", query);
    625 
    626         int lastIndex = listbox->getValueIndex(name);
    627         lastValue = "";
    628         Load();
    629         listbox->setValue(lastIndex);
     886        if (m_group->DelDir(name).isEmpty())
     887        {
     888            int lastIndex = listbox->getValueIndex(name);
     889            lastValue = "";
     890            Load();
     891            listbox->setValue(lastIndex);
     892        }
    630893    }
    631894
    632895    listbox->setFocus();
     
    636899{
    637900    listbox->clearSelections();
    638901
    639     MSqlQuery query(MSqlQuery::InitCon());
    640     query.prepare("SELECT dirname, id FROM storagegroup "
    641                   "WHERE groupname = :NAME AND hostname = :HOSTNAME "
    642                   "ORDER BY id;");
    643     query.bindValue(":NAME", m_group);
    644     query.bindValue(":HOSTNAME", gContext->GetHostName());
    645     if (!query.exec() || !query.isActive())
    646         MythDB::DBError("StorageGroupEditor::doDelete", query);
    647     else
     902    QStringList dirs = m_group->GetDirList();
     903
     904    bool first = true;
     905    for (QStringList::iterator dir = dirs.begin(); dir != dirs.end(); ++dir)
    648906    {
    649         bool first = true;
    650         while (query.next())
     907        if (first)
    651908        {
    652             if (first)
    653             {
    654                 lastValue = query.value(0).toString();
    655                 first = false;
    656             }
    657             listbox->addSelection(query.value(0).toString());
     909            lastValue = *dir;
     910            first = false;
    658911        }
     912        listbox->addSelection(*dir);
    659913    }
    660914
    661915    listbox->addSelection(tr("(Add New Directory)"),
     
    664918    listbox->setValue(lastValue);
    665919}
    666920
     921void StorageGroupEditor::Save(void)
     922{
     923    if (m_group)
     924        m_group->Save();
     925}
     926
     927void StorageGroupEditor::Delete(void)
     928{
     929    if (m_group)
     930        m_group->Delete();
     931}
     932
     933bool StorageGroupEditor::hasChanged(void)
     934{
     935    return m_group && m_group->hasChanged();
     936}
     937
    667938DialogCode StorageGroupEditor::exec(void)
    668939{
    669     while (ConfigurationDialog::exec() == kDialogCodeAccepted)
     940    while (ConfigurationDialog::exec(false) == kDialogCodeAccepted)
    670941        open(listbox->getValue());
    671942
    672943    return kDialogCodeRejected;
     
    697968    addChild(listbox);
    698969}
    699970
     971StorageGroupListEditor::~StorageGroupListEditor(void)
     972{
     973    for (StorageGroupEditors::Iterator sge = m_deleted.begin(); sge != m_deleted.end(); ++sge)
     974    {
     975        delete *sge;
     976    }
     977
     978    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
     979    {
     980        delete *sge;
     981    }
     982}
     983
    700984void StorageGroupListEditor::open(QString name)
    701985{
    702986    lastValue = name;
     
    7221006
    7231007    if (!name.isEmpty())
    7241008    {
    725         StorageGroupEditor sgEditor(name);
    726         sgEditor.exec();
     1009        StorageGroupEditor *sgEditor;
     1010
     1011        StorageGroupEditors::iterator
     1012            editor = m_edited.find(name);
     1013
     1014        if (editor == m_edited.end())
     1015        {
     1016            sgEditor = new StorageGroupEditor(name);
     1017            m_edited[name] = sgEditor;
     1018        }
     1019        else
     1020            sgEditor = *editor;
     1021
     1022        sgEditor->exec();
     1023        Load();
    7271024    }
    7281025};
    7291026
     
    7541051
    7551052    if (kDialogCodeButton0 == value)
    7561053    {
    757         MSqlQuery query(MSqlQuery::InitCon());
    758         query.prepare("DELETE FROM storagegroup "
    759                       "WHERE groupname = :NAME AND hostname = :HOSTNAME;");
    760         query.bindValue(":NAME", name);
    761         query.bindValue(":HOSTNAME", gContext->GetHostName());
    762         if (!query.exec())
    763             MythDB::DBError("StorageGroupListEditor::doDelete", query);
     1054        StorageGroupEditors::Iterator
     1055            edited = m_edited.find(name);
    7641056
     1057        // N.B. this will leak if user deletes/adds/deletes
     1058        // the same name. Too bad.
     1059        if (edited == m_edited.end())
     1060            m_deleted[name] = new StorageGroupEditor(name);
     1061        else
     1062        {
     1063            m_deleted[name] = *edited;
     1064            m_edited.erase(edited);
     1065        }
     1066
    7651067        int lastIndex = listbox->getValueIndex(name);
    7661068        lastValue = "";
    7671069        Load();
     
    7801082    bool isMaster = (gContext->GetSetting("MasterServerIP","master") ==
    7811083                     gContext->GetSetting("BackendServerIP","me"));
    7821084
    783     MSqlQuery query(MSqlQuery::InitCon());
    784     query.prepare("SELECT distinct groupname "
    785                   "FROM storagegroup "
    786                   "WHERE hostname = :HOSTNAME "
    787                   "ORDER BY groupname;");
    788     query.bindValue(":HOSTNAME", gContext->GetHostName());
    789     if (!query.exec())
    790         MythDB::DBError("StorageGroup::Load getting local group names",
    791                              query);
    792     else
     1085    QStringList localGroups =
     1086        StorageGroup::GetStorageGroupNames(gContext->GetHostName());
     1087
     1088    for (QStringList::Iterator sg = localGroups.begin(); sg != localGroups.end(); ++sg)
    7931089    {
    794         while (query.next())
    795             names << query.value(0).toString();
     1090        bool isDeleted =
     1091            m_deleted.contains(*sg) && ! m_edited.contains(*sg);
     1092
     1093        if (!isDeleted)
     1094            names << *sg;
    7961095    }
    7971096
    798     query.prepare("SELECT distinct groupname "
    799                   "FROM storagegroup "
    800                   "ORDER BY groupname;");
    801     if (!query.exec())
    802         MythDB::DBError("StorageGroup::Load getting all group names",
    803                              query);
    804     else
     1097    // groups added in this editor session won't appear in
     1098    // localGroups which pulls from the database
     1099    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
    8051100    {
    806         while (query.next())
    807             masterNames << query.value(0).toString();
     1101        if (!names.contains(sge.key()))
     1102            names << sge.key();
    8081103    }
    8091104
     1105    QStringList allGroups =
     1106        StorageGroup::GetStorageGroupNames();
     1107
     1108    for (QStringList::Iterator sg = allGroups.begin(); sg != allGroups.end(); ++sg)
     1109    {
     1110        masterNames << *sg;
     1111    }
     1112
    8101113    listbox->clearSelections();
    8111114
    8121115    if (isMaster || names.contains("Default"))
     
    8801183    listbox->setValue(lastValue);
    8811184}
    8821185
     1186void StorageGroupListEditor::Save(void)
     1187{
     1188    for (StorageGroupEditors::Iterator sge = m_deleted.begin(); sge != m_deleted.end(); ++sge)
     1189    {
     1190        (*sge)->Delete();
     1191    }
     1192
     1193    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
     1194    {
     1195        (*sge)->Save();
     1196    }
     1197}
     1198
     1199bool StorageGroupListEditor::hasChanged(void)
     1200{
     1201    if (!m_deleted.empty())
     1202        return true;
     1203
     1204    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
     1205        if ((*sge)->hasChanged())
     1206            return true;
     1207
     1208    return false;
     1209}
     1210
    8831211DialogCode StorageGroupListEditor::exec(void)
    8841212{
    885     while (ConfigurationDialog::exec() == kDialogCodeAccepted)
     1213    while (ConfigurationDialog::exec(false) == kDialogCodeAccepted)
    8861214        open(listbox->getValue());
    8871215
    8881216    return kDialogCodeRejected;
  • programs/mythtv-setup/main.cpp

     
    6666    {
    6767        StorageGroupListEditor sge;
    6868        sge.exec();
     69        if (sge.hasChanged())
     70            sge.Save();
    6971    }
    7072    else if (sel == "exiting_app")
    7173    {