Ticket #4623: pluginSGs.patch

File pluginSGs.patch, 28.1 KB (added by George Nassas <gnassas@…>, 12 years ago)
  • libs/libmyth/storagegroup.cpp

     
    2626 *  \param hostname hostname where to search, blank will search all hosts'
    2727 *                  directories, but only in local directory structure.
    2828 *                  This is parameter is ignored if group is an empty string.
     29 *  \parm useDefaultWhenEmpty fall back to directories in the "Default" group
     30 *                  when no directories can be found for a given group/host
     31 *                  combination. Defaults to true. Clients doing programmatic
     32 *                  manipulation of storage groups should pass false.
    2933 */
    30 StorageGroup::StorageGroup(const QString group, const QString hostname) :
     34StorageGroup::StorageGroup(const QString group, const QString hostname,
     35                           bool useDefaultWhenEmpty) :
    3136    m_groupname(QDeepCopy<QString>(group)),
    3237    m_hostname(QDeepCopy<QString>(hostname))
    3338{
    3439    m_dirlist.clear();
     40    m_originaldirs.clear();
    3541
    36     Init(m_groupname, m_hostname);
     42    Init(m_groupname, m_hostname, useDefaultWhenEmpty);
    3743}
    3844
    39 void StorageGroup::Init(const QString group, const QString hostname)
     45void StorageGroup::Init(const QString group, const QString hostname,
     46                        bool useDefaultWhenEmpty)
    4047{
    4148    QString dirname;
    4249    MSqlQuery query(MSqlQuery::InitCon());
     
    6370        MythContext::DBError("StorageGroup::StorageGroup()", query);
    6471    else if (!query.next())
    6572    {
    66         if (group != "Default")
     73        if (useDefaultWhenEmpty)
    6774        {
    68             VERBOSE(VB_FILE, LOC +
    69                     QString("Unable to find storage group '%1', trying "
    70                             "'Default' group!").arg(m_groupname));
    71             Init("Default", m_hostname);
    72             return;
     75            if (group != "Default")
     76            {
     77                VERBOSE(VB_FILE, LOC +
     78                        QString("Unable to find storage group '%1', trying "
     79                                "'Default' group!").arg(m_groupname));
     80                Init("Default", m_hostname);
     81                return;
     82            }
     83            else if (!m_hostname.isEmpty())
     84            {
     85                VERBOSE(VB_FILE, LOC +
     86                        QString("Unable to find any directories for the local "
     87                                "Default storage group, trying directories in all "
     88                                "Default groups!").arg(m_groupname));
     89                Init("Default", "");
     90                return;
     91            }
    7392        }
    74         else if (!m_hostname.isEmpty())
    75         {
    76             VERBOSE(VB_FILE, LOC +
    77                     QString("Unable to find any directories for the local "
    78                             "Default storage group, trying directories in all "
    79                             "Default groups!").arg(m_groupname));
    80             Init("Default", "");
    81             return;
    82         }
    8393    }
    8494    else
    8595    {
     
    95105        while (query.next());
    96106    }
    97107
    98     if (!m_dirlist.size())
     108    m_originaldirs = m_dirlist;
     109
     110    if (!m_dirlist.size() && group == "Default")
    99111    {
    100112        QString msg = "Directory value for Default Storage Group is empty.  ";
    101113        QString tmpDir = gContext->GetSetting("RecordFilePrefix");
     
    115127    }
    116128}
    117129
     130/** \brief Remove all host-specific database entries for the Storage Group
     131 */
     132void StorageGroup::Delete(void)
     133{
     134    MSqlQuery query(MSqlQuery::InitCon());
     135    query.prepare("DELETE FROM storagegroup "
     136                  "WHERE groupname = :NAME AND hostname = :HOSTNAME;");
     137    query.bindValue(":NAME", m_groupname.utf8());
     138    query.bindValue(":HOSTNAME", m_hostname);
     139    if (!query.exec())
     140        MythContext::DBError("StorageGroup::Delete", query);
     141}
     142
     143void StorageGroup::save(void)
     144{
     145    ConfigurationWizard::save();
     146
     147    MSqlQuery query(MSqlQuery::InitCon());
     148
     149    // apply deletes
     150
     151    for (QStringList::iterator oldDir = m_originaldirs.begin();
     152         oldDir != m_originaldirs.end(); ++oldDir)
     153    {
     154        QStringList::iterator
     155            newpos = m_dirlist.find(*oldDir);
     156        if (newpos == m_dirlist.end())
     157        {
     158            query.prepare("DELETE FROM storagegroup "
     159                          "WHERE groupname = :NAME "
     160                          "AND dirname = :DIRNAME "
     161                          "AND hostname = :HOSTNAME;");
     162            query.bindValue(":NAME", m_groupname.utf8());
     163            query.bindValue(":DIRNAME", (*oldDir).utf8() + "/");
     164            query.bindValue(":HOSTNAME", m_hostname.utf8());
     165            if (!query.exec())
     166                MythContext::DBError("StorageGroup::save", query);
     167        }
     168    }
     169
     170    // apply inserts
     171
     172    for (QStringList::iterator newDir = m_dirlist.begin();
     173         newDir != m_dirlist.end(); ++newDir)
     174    {
     175        QStringList::iterator
     176            oldpos = m_originaldirs.find(*newDir);
     177        if (oldpos == m_originaldirs.end())
     178        {
     179            query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
     180                          "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
     181            query.bindValue(":NAME", m_groupname.utf8());
     182            query.bindValue(":DIRNAME", (*newDir).utf8() + "/");
     183            query.bindValue(":HOSTNAME", m_hostname.utf8());
     184            if (!query.exec())
     185                MythContext::DBError("StorageGroup::save", query);
     186        }
     187    }
     188}
     189
     190bool StorageGroup::hasChanged(void)
     191{
     192    if (m_originaldirs.size() != m_dirlist.size())
     193        return true;
     194
     195    for (QStringList::iterator oldDir = m_originaldirs.begin();
     196         oldDir != m_originaldirs.end(); ++oldDir)
     197    {
     198        if (m_dirlist.find(*oldDir) == m_dirlist.end())
     199            return true;
     200    }
     201
     202    return false;
     203}
     204
     205/** \brief Adds a directory to a storage group.
     206 *  \param directory    directory to add.
     207 *  \param group        group to add to. defaults to "Default".
     208 *  \param hostname     host to associate with mapping.
     209 *                      Defaults to the local host name.
     210 *  \return Name of directory after adjustments or an empty string
     211 *          if the directory could not be added.
     212 */
     213QString StorageGroup::AddDir(const QString directory)
     214{
     215    QString name = directory;
     216
     217    if (name.right(1) == "/")
     218        name.remove(name.length()-1, 1);
     219
     220    if (m_dirlist.find(name) == m_dirlist.end())
     221        m_dirlist.append(name);
     222
     223    return name;
     224}
     225
     226/** \brief Deletes a directory from a storage group.
     227 *  \param directory    directory to remove.
     228 *  \param group        group to remove from. defaults to "Default".
     229 *  \param hostname     host to remove for. Defaults to the
     230 *                      local host name.
     231 *  \return Empty string if delete was successful otherwise directory
     232 *          name after adjustments.
     233 */
     234QString StorageGroup::DelDir(const QString directory)
     235{
     236    QString name = directory;
     237
     238    if (name.right(1) == "/")
     239        name.remove(name.length()-1, 1);
     240
     241    QStringList::iterator entry = m_dirlist.find(name);
     242    if (entry != m_dirlist.end())
     243    {
     244        m_dirlist.remove(entry);
     245        name.truncate(0);
     246    }
     247
     248    return name;
     249}
     250
     251/** \brief Return names of all files found in the storage group's directories.
     252 *  \param descendIntoSubDirs   traverse all subdirectories.
     253 *  \param followSymbolicLinks  include symbolically linked files in the list.
     254 *                              When descendIntoSubDirs is true then links to
     255 *                              folders will be traversed as well.
     256 *  \return A map of the storage group's directories paired with a QStringList
     257 *          of relative filenames found in that directory.
     258 */
     259StorageGroup::FilesList StorageGroup::GetAllFiles(bool descendIntoSubDirs,
     260                                                  bool followSymbolicLinks)
     261{
     262    FilesList allFiles;
     263    for (QStringList::iterator dir = m_dirlist.begin(); dir != m_dirlist.end();
     264         dir++)
     265    {
     266        QStringList files = GetAllFiles(*dir, descendIntoSubDirs, followSymbolicLinks);
     267        if (files.size() > 0)
     268        {
     269            allFiles[*dir] = files;
     270        }
     271    }
     272
     273    return allFiles;
     274}
     275
     276/** \brief Return name of all files stored within a directory.
     277 *  \param directory            directory to search.
     278 *  \param descendIntoSubDirs   traverse all subdirectories.
     279 *  \param followSymbolicLinks  include symbolically linked files in the list.
     280 *                              When descendIntoSubDirs is true then links to
     281 *                              folders will be traversed as well.
     282 *  \return A QStringList of relative filenames found in the directory.
     283 */
     284QStringList StorageGroup::GetAllFiles(const QString directory,
     285                                      bool descendIntoSubDirs,
     286                                      bool followSymbolicLinks)
     287{
     288    QStringList allFiles;
     289    StorageGroup::GetAllFilesImpl(directory,
     290                                  allFiles,
     291                                  descendIntoSubDirs,
     292                                  followSymbolicLinks,
     293                                  "");
     294    return allFiles;
     295}
     296
     297void StorageGroup::GetAllFilesImpl(const QString directory,
     298                                   QStringList fileList,
     299                                   bool descendIntoSubDirs,
     300                                   bool followSymbolicLinks,
     301                                   const QString prefix)
     302{
     303    QDir dir(directory + prefix);
     304    if (!dir.isReadable())
     305        return;
     306
     307    dir.setSorting(QDir::Unsorted);
     308
     309    const QFileInfoList *files = dir.entryInfoList();
     310    if (!files)
     311        return;
     312
     313    QFileInfoListIterator it(*files);
     314    QFileInfo *fi;
     315
     316    for (; (fi=it.current()) != 0; ++it)
     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 + fileName);
     338        }
     339    }
     340}
     341
    118342QString StorageGroup::FindRecordingFile(QString filename)
    119343{
    120344    VERBOSE(VB_FILE, LOC + QString("FindRecordingFile: Searching for '%1'")
     
    232456    return QDeepCopy<QString>(nextDir);
    233457}
    234458
     459/** \brief return list of StorageGroup names.
     460 *  \param hostname restrict list to this host, blank will search all
     461 *                  hosts' directories.
     462 */
     463QStringList StorageGroup::GetStorageGroupNames(const QString hostname)
     464{
     465    QStringList groups;
     466
     467    MSqlQuery query(MSqlQuery::InitCon());
     468    if (hostname.isEmpty())
     469    {
     470        query.prepare("SELECT DISTINCT groupname "
     471                      "FROM storagegroup "
     472                      "ORDER BY groupname;");
     473    }
     474    else
     475    {
     476        query.prepare("SELECT DISTINCT groupname "
     477                      "FROM storagegroup "
     478                      "WHERE hostname = :HOSTNAME "
     479                      "ORDER BY groupname;");
     480        query.bindValue(":HOSTNAME", hostname);
     481    }
     482
     483    if (query.exec() && query.isActive())
     484    {
     485        while (query.next())
     486            groups += QString::fromUtf8(query.value(0).toString());
     487    }
     488    else
     489        MythContext::DBError("StorageGroup::GetStorageGroupNames getting group names",
     490                             query);
     491
     492    return groups;
     493}
     494
     495/** \brief find name of the StorageGroup containing a given directory.
     496 *  \param directory directory to lookup.
     497 *  \param hostname restrict search to this host. Blank, the default,
     498 *                  will search all hosts' directories.
     499 *
     500 *  N.B. when two different StorageGroups contain the same directory the
     501 *  return value will be unpredictable.
     502 */
     503QString StorageGroup::FindStorageGroupForDir(const QString directory, const QString hostname)
     504{
     505    MSqlQuery query(MSqlQuery::InitCon());
     506
     507    QString searchDir(directory);
     508    if (searchDir.right(1) != "/")
     509        searchDir.append("/");
     510
     511    if (hostname.isEmpty())
     512    {
     513        query.prepare("SELECT groupname "
     514                      "FROM storagegroup "
     515                      "WHERE dirname = :DIR");
     516    }
     517    else
     518    {
     519        query.prepare("SELECT groupname "
     520                      "FROM storagegroup "
     521                      "WHERE hostname = :HOSTNAME "
     522                      "  AND dirname = :DIR");
     523        query.bindValue(":HOSTNAME", hostname);
     524    }
     525    query.bindValue(":DIR", searchDir);
     526
     527    if (!query.exec() || !query.isActive())
     528    {
     529        MythContext::DBError("StorageGroup::FindStorageGroupForDir()", query);
     530        return QString();
     531    }
     532
     533    return query.next()
     534        ? query.value(0).toString()
     535        : QString();
     536}
     537
    235538void StorageGroup::CheckAllStorageGroupDirs(void)
    236539{
    237540    QString m_groupname;
     
    356659/****************************************************************************/
    357660
    358661StorageGroupEditor::StorageGroupEditor(QString group) :
    359     m_group(group), listbox(new ListBoxSetting(this)), lastValue("")
     662    listbox(new ListBoxSetting(this)), lastValue("")
    360663{
    361664    QString dispGroup = group;
    362665
     
    365668    else if (StorageGroup::kSpecialGroups.contains(group))
    366669        dispGroup = QObject::tr(group);
    367670
     671    m_group = new StorageGroup(group, gContext->GetHostName(), false);
     672
    368673    if (gContext->GetSetting("MasterServerIP","master") ==
    369674            gContext->GetSetting("BackendServerIP","me"))
    370675    {
     
    379684    addChild(listbox);
    380685}
    381686
     687StorageGroupEditor::~StorageGroupEditor()
     688{
     689    if (m_group)
     690        delete m_group;
     691}
     692
    382693void StorageGroupEditor::open(QString name)
    383694{
    384695    lastValue = name;
     
    394705        if (result == SGPopup_CANCEL)
    395706            return;
    396707
    397         if (name.right(1) != "/")
    398             name.append("/");
    399 
    400         MSqlQuery query(MSqlQuery::InitCon());
    401         query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
    402                       "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
    403         query.bindValue(":NAME", m_group.utf8());
    404         query.bindValue(":DIRNAME", name.utf8());
    405         query.bindValue(":HOSTNAME", gContext->GetHostName());
    406         if (!query.exec())
    407             MythContext::DBError("StorageGroupEditor::open", query);
    408         else
    409             lastValue = name;
     708        lastValue = m_group->AddDir(name);
    410709    } else {
    411710        SGPopupResult result = StorageGroupPopup::showPopup(
    412711            gContext->GetMainWindow(),
     
    416715        if (result == SGPopup_CANCEL)
    417716            return;
    418717
    419         if (name.right(1) != "/")
    420             name.append("/");
    421 
    422         MSqlQuery query(MSqlQuery::InitCon());
    423 
    424         query.prepare("DELETE FROM storagegroup "
    425                       "WHERE groupname = :NAME "
    426                           "AND dirname = :DIRNAME "
    427                           "AND hostname = :HOSTNAME;");
    428         query.bindValue(":NAME", m_group.utf8());
    429         query.bindValue(":DIRNAME", lastValue.utf8());
    430         query.bindValue(":HOSTNAME", gContext->GetHostName());
    431         if (!query.exec())
    432             MythContext::DBError("StorageGroupEditor::open", query);
    433 
    434         query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
    435                       "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
    436         query.bindValue(":NAME", m_group.utf8());
    437         query.bindValue(":DIRNAME", name.utf8());
    438         query.bindValue(":HOSTNAME", gContext->GetHostName());
    439         if (!query.exec())
    440             MythContext::DBError("StorageGroupEditor::open", query);
    441         else
    442             lastValue = name;
     718        lastValue = m_group->DelDir(lastValue);
     719        if (lastValue.isEmpty())
     720            lastValue = m_group->AddDir(name);
    443721    }
    444722};
    445723
     
    460738
    461739    if (kDialogCodeButton0 == value)
    462740    {
    463         MSqlQuery query(MSqlQuery::InitCon());
    464         query.prepare("DELETE FROM storagegroup "
    465                       "WHERE groupname = :NAME "
    466                           "AND dirname = :DIRNAME "
    467                           "AND hostname = :HOSTNAME;");
    468         query.bindValue(":NAME", m_group.utf8());
    469         query.bindValue(":DIRNAME", name.utf8());
    470         query.bindValue(":HOSTNAME", gContext->GetHostName());
    471         if (!query.exec())
    472             MythContext::DBError("StorageGroupEditor::doDelete", query);
    473 
    474         int lastIndex = listbox->getValueIndex(name);
    475         lastValue = "";
    476         load();
    477         listbox->setValue(lastIndex);
     741        if (m_group->DelDir(name.utf8()).isEmpty())
     742        {
     743            int lastIndex = listbox->getValueIndex(name);
     744            lastValue = "";
     745            load();
     746            listbox->setValue(lastIndex);
     747        }
    478748    }
    479749
    480750    listbox->setFocus();
    481751}
    482752
    483 void StorageGroupEditor::load(void) {
     753void StorageGroupEditor::load(void)
     754{
    484755    listbox->clearSelections();
    485756
    486     MSqlQuery query(MSqlQuery::InitCon());
    487     query.prepare("SELECT dirname, id FROM storagegroup "
    488                   "WHERE groupname = :NAME AND hostname = :HOSTNAME "
    489                   "ORDER BY id;");
    490     query.bindValue(":NAME", m_group.utf8());
    491     query.bindValue(":HOSTNAME", gContext->GetHostName());
    492     if (!query.exec() || !query.isActive())
    493         MythContext::DBError("StorageGroupEditor::doDelete", query);
    494     else
     757    QStringList dirs = m_group->GetDirList();
     758
     759    bool first = true;
     760    for (QStringList::iterator dir = dirs.begin(); dir != dirs.end(); ++dir)
    495761    {
    496         bool first = true;
    497         while (query.next())
     762        if (first)
    498763        {
    499             if (first)
    500             {
    501                 lastValue = query.value(0).toString();
    502                 first = false;
    503             }
    504             listbox->addSelection(query.value(0).toString());
     764            lastValue = *dir;
     765            first = false;
    505766        }
     767        listbox->addSelection(*dir);
    506768    }
    507769
    508770    listbox->addSelection(tr("(Add New Directory)"),
     
    511773    listbox->setValue(lastValue);
    512774}
    513775
     776void StorageGroupEditor::save(void)
     777{
     778    if (m_group)
     779        m_group->save();
     780}
     781
     782void StorageGroupEditor::Delete(void)
     783{
     784    if (m_group)
     785        m_group->Delete();
     786}
     787
     788bool StorageGroupEditor::hasChanged(void)
     789{
     790    return m_group && m_group->hasChanged();
     791}
     792
    514793DialogCode StorageGroupEditor::exec(void)
    515794{
    516     while (ConfigurationDialog::exec() == kDialogCodeAccepted)
     795    while (ConfigurationDialog::exec(false) == kDialogCodeAccepted)
    517796        open(listbox->getValue());
    518797
    519798    return kDialogCodeRejected;
     
    544823    addChild(listbox);
    545824}
    546825
     826StorageGroupListEditor::~StorageGroupListEditor(void)
     827{
     828    for (StorageGroupEditors::Iterator sge = m_deleted.begin(); sge != m_deleted.end(); ++sge)
     829    {
     830        delete *sge;
     831    }
     832
     833    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
     834    {
     835        delete *sge;
     836    }
     837}
     838
    547839void StorageGroupListEditor::open(QString name)
    548840{
    549841    lastValue = name;
     
    569861
    570862    if (!name.isEmpty())
    571863    {
    572         StorageGroupEditor sgEditor(name);
    573         sgEditor.exec();
     864        StorageGroupEditor *sgEditor;
     865
     866        StorageGroupEditors::iterator
     867            editor = m_edited.find(name);
     868
     869        if (editor == m_edited.end())
     870        {
     871            sgEditor = new StorageGroupEditor(name);
     872            m_edited[name] = sgEditor;
     873        }
     874        else
     875            sgEditor = *editor;
     876
     877        sgEditor->exec();
     878        load();
    574879    }
    575880};
    576881
     
    601906
    602907    if (kDialogCodeButton0 == value)
    603908    {
    604         MSqlQuery query(MSqlQuery::InitCon());
    605         query.prepare("DELETE FROM storagegroup "
    606                       "WHERE groupname = :NAME AND hostname = :HOSTNAME;");
    607         query.bindValue(":NAME", name.utf8());
    608         query.bindValue(":HOSTNAME", gContext->GetHostName());
    609         if (!query.exec())
    610             MythContext::DBError("StorageGroupListEditor::doDelete", query);
     909        StorageGroupEditors::Iterator
     910            edited = m_edited.find(name);
    611911
     912        // N.B. this will leak if user deletes/adds/deletes
     913        // the same name. Too bad.
     914        if (edited == m_edited.end())
     915            m_deleted[name] = new StorageGroupEditor(name);
     916        else
     917        {
     918            m_deleted[name] = *edited;
     919            m_edited.remove(edited);
     920        }
     921
    612922        int lastIndex = listbox->getValueIndex(name);
    613923        lastValue = "";
    614924        load();
     
    627937    bool isMaster = (gContext->GetSetting("MasterServerIP","master") ==
    628938                     gContext->GetSetting("BackendServerIP","me"));
    629939
    630     MSqlQuery query(MSqlQuery::InitCon());
    631     query.prepare("SELECT distinct groupname "
    632                   "FROM storagegroup "
    633                   "WHERE hostname = :HOSTNAME "
    634                   "ORDER BY groupname;");
    635     query.bindValue(":HOSTNAME", gContext->GetHostName());
    636     if (!query.exec())
    637         MythContext::DBError("StorageGroup::load getting local group names",
    638                              query);
    639     else
     940    QStringList localGroups =
     941        StorageGroup::GetStorageGroupNames(gContext->GetHostName());
     942
     943    for (QStringList::Iterator sg = localGroups.begin(); sg != localGroups.end(); ++sg)
    640944    {
    641         while (query.next())
    642             names << QString::fromUtf8(query.value(0).toString());
     945        bool isDeleted =
     946            m_deleted.find(*sg) != m_deleted.end() &&
     947            m_edited.find(*sg) == m_edited.end();
     948
     949        if (!isDeleted)
     950            names << *sg;
    643951    }
    644952
    645     query.prepare("SELECT distinct groupname "
    646                   "FROM storagegroup "
    647                   "ORDER BY groupname;");
    648     if (!query.exec())
    649         MythContext::DBError("StorageGroup::load getting all group names",
    650                              query);
    651     else
     953    // groups added in this editor session won't appear in
     954    // localGroups which pulls from the database
     955    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
    652956    {
    653         while (query.next())
    654             masterNames << QString::fromUtf8(query.value(0).toString());
     957        if (names.find(sge.key()) == names.end())
     958            names << sge.key();
    655959    }
    656960
     961    QStringList allGroups =
     962        StorageGroup::GetStorageGroupNames();
     963
     964    for (QStringList::Iterator sg = allGroups.begin(); sg != allGroups.end(); ++sg)
     965    {
     966        masterNames << *sg;
     967    }
     968
    657969    listbox->clearSelections();
    658970
    659971    if (isMaster || names.contains("Default"))
     
    7261038    listbox->setValue(lastValue);
    7271039}
    7281040
     1041void StorageGroupListEditor::save(void)
     1042{
     1043    for (StorageGroupEditors::Iterator sge = m_deleted.begin(); sge != m_deleted.end(); ++sge)
     1044    {
     1045        (*sge)->Delete();
     1046    }
     1047
     1048    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
     1049    {
     1050        (*sge)->save();
     1051    }
     1052}
     1053
     1054bool StorageGroupListEditor::hasChanged(void)
     1055{
     1056    if (!m_deleted.empty())
     1057        return true;
     1058
     1059    for (StorageGroupEditors::Iterator sge = m_edited.begin(); sge != m_edited.end(); ++sge)
     1060        if ((*sge)->hasChanged())
     1061            return true;
     1062
     1063    return false;
     1064}
     1065
    7291066DialogCode StorageGroupListEditor::exec(void)
    7301067{
    731     while (ConfigurationDialog::exec() == kDialogCodeAccepted)
     1068    while (ConfigurationDialog::exec(false) == kDialogCodeAccepted)
    7321069        open(listbox->getValue());
    7331070
    7341071    return kDialogCodeRejected;
  • libs/libmyth/storagegroup.h

     
    1010class MPUBLIC StorageGroup: public ConfigurationWizard
    1111{
    1212  public:
    13     StorageGroup(const QString group = "", const QString hostname = "");
     13    StorageGroup(const QString group = "",
     14                 const QString hostname = "",
     15                 bool useDefaultWhenEmpty = true);
    1416
    1517    void    Init(const QString group = "Default",
    16                  const QString hostname = "");
     18                 const QString hostname = "",
     19                 bool useDefaultWhenEmpty = true);
    1720
     21    void    Delete(void);
     22
     23    virtual void save(void);
     24
     25    bool hasChanged(void);
     26
     27    QString AddDir(const QString directory);
     28    QString DelDir(const QString directory);
     29
    1830    QString getName(void) const
    1931        { return QDeepCopy<QString>(m_groupname); }
    2032
    2133    QStringList GetDirList(void) const
    2234        { return QDeepCopy<QStringList>(m_dirlist); }
    2335
     36    typedef QMap<QString, QStringList> FilesList;
     37
     38    FilesList GetAllFiles(bool descendIntoSubDirs = false,
     39                          bool followSymbolicLinks = true);
     40    static QStringList GetAllFiles(const QString directory,
     41                                   bool descendIntoSubDirs = false,
     42                                   bool followSymbolicLinks = true);
     43
    2444    QString FindRecordingFile(QString filename);
    2545    QString FindRecordingDir(QString filename);
    2646
    2747    QString FindNextDirMostFree(void);
    2848
     49    static QStringList GetStorageGroupNames(const QString hostname = "");
     50    static QString FindStorageGroupForDir(const QString directory, const QString hostname = "");
     51
    2952    static void CheckAllStorageGroupDirs(void);
    3053
    3154    static const char *kDefaultStorageDir;
     
    3659  private:
    3760    QString      m_groupname;
    3861    QString      m_hostname;
     62    QStringList  m_originaldirs;
    3963    QStringList  m_dirlist;
     64
     65    static void GetAllFilesImpl(const QString directory,
     66                                QStringList fileList,
     67                                bool descendIntoSubDirs = false,
     68                                bool followSymbolicLinks = true,
     69                                const QString prefix = "");
    4070};
    4171
    4272class MPUBLIC StorageGroupEditor :
     
    4575    Q_OBJECT
    4676  public:
    4777    StorageGroupEditor(QString group);
     78    virtual ~StorageGroupEditor(void);
    4879    virtual DialogCode exec(void);
    4980    virtual void load(void);
    50     virtual void save(void) { };
     81    virtual void save(void);
    5182    virtual void save(QString) { };
     83    void Delete();
     84    bool hasChanged(void);
    5285    virtual MythDialog* dialogWidget(MythMainWindow* parent,
    5386                                     const char* widgetname=0);
    5487
     88    QString getGroup(void) const
     89    {
     90        QString groupName;
     91        if (m_group)
     92            groupName = m_group->getName();
     93        return groupName;
     94    }
     95
    5596  protected slots:
    5697    void open(QString name);
    5798    void doDelete(void);
    5899
    59100  protected:
    60     QString         m_group;
     101    StorageGroup   *m_group;
    61102    ListBoxSetting *listbox;
    62103    QString         lastValue;
    63104};
     
    68109    Q_OBJECT
    69110  public:
    70111    StorageGroupListEditor(void);
     112    virtual ~StorageGroupListEditor(void);
    71113    virtual DialogCode exec(void);
    72114    virtual void load(void);
    73     virtual void save(void) { };
     115    virtual void save(void);
    74116    virtual void save(QString) { };
     117    bool hasChanged(void);
    75118    virtual MythDialog* dialogWidget(MythMainWindow* parent,
    76119                                     const char* widgetname=0);
    77120
     
    82125  protected:
    83126    ListBoxSetting *listbox;
    84127    QString         lastValue;
     128
     129    typedef QMap<QString, StorageGroupEditor*> StorageGroupEditors;
     130    StorageGroupEditors m_edited;
     131    StorageGroupEditors m_deleted;
    85132};
    86133
    87134#endif
  • programs/mythtv-setup/main.cpp

     
    7070    else if ( sel == "storage groups" )
    7171    {
    7272        StorageGroupListEditor sge;
     73
    7374        sge.exec();
     75
     76        if (sge.hasChanged())
     77        {
     78            QString message = QObject::tr("Save changes?");
     79
     80            DialogCode value = MythPopupBox::Show2ButtonPopup(
     81                gContext->GetMainWindow(),
     82                "", message,
     83                QObject::tr("Yes"),
     84                QObject::tr("No"),
     85                kDialogCodeButton1);
     86
     87            if (kDialogCodeButton0 == value)
     88                sge.save();
     89        }
    7490    }
    7591}
    7692