00001 #include <qdir.h>
00002 #include <qfile.h>
00003 #include <qregexp.h>
00004
00005 #include "storagegroup.h"
00006 #include "libmyth/mythcontext.h"
00007 #include "libmyth/mythdbcon.h"
00008 #include "libmyth/util.h"
00009
00010 #define LOC QString("SG(%1): ").arg(m_groupname)
00011 #define LOC_WARN QString("SG(%1) Warning: ").arg(m_groupname)
00012 #define LOC_ERR QString("SG(%1) Error: ").arg(m_groupname)
00013
00014 const char *StorageGroup::kDefaultStorageDir = "/mnt/store";
00015
00016 const QStringList StorageGroup::kSpecialGroups = QStringList()
00017 << "LiveTV"
00018
00019 << "DB Backups"
00020 ;
00021
00022
00023
00030 StorageGroup::StorageGroup(const QString group, const QString hostname) :
00031 m_groupname(QDeepCopy<QString>(group)),
00032 m_hostname(QDeepCopy<QString>(hostname))
00033 {
00034 m_dirlist.clear();
00035
00036 Init(m_groupname, m_hostname);
00037 }
00038
00039 void StorageGroup::Init(const QString group, const QString hostname)
00040 {
00041 QString dirname;
00042 MSqlQuery query(MSqlQuery::InitCon());
00043
00044 m_groupname = QDeepCopy<QString>(group);
00045 m_hostname = QDeepCopy<QString>(hostname);
00046 m_dirlist.clear();
00047
00048 QString sql = "SELECT DISTINCT dirname "
00049 "FROM storagegroup ";
00050
00051 if (!m_groupname.isEmpty())
00052 {
00053 sql.append("WHERE groupname = :GROUP");
00054 if (!m_hostname.isEmpty())
00055 sql.append(" AND hostname = :HOSTNAME");
00056 }
00057
00058 query.prepare(sql);
00059 query.bindValue(":GROUP", m_groupname.utf8());
00060 query.bindValue(":HOSTNAME", m_hostname);
00061
00062 if (!query.exec() || !query.isActive())
00063 MythContext::DBError("StorageGroup::StorageGroup()", query);
00064 else if (!query.next())
00065 {
00066 if (group != "Default")
00067 {
00068 VERBOSE(VB_FILE, LOC +
00069 QString("Unable to find storage group '%1', trying "
00070 "'Default' group!").arg(m_groupname));
00071 Init("Default", m_hostname);
00072 return;
00073 }
00074 else if (!m_hostname.isEmpty())
00075 {
00076 VERBOSE(VB_FILE, LOC +
00077 QString("Unable to find any directories for the local "
00078 "Default storage group, trying directories in all "
00079 "Default groups!").arg(m_groupname));
00080 Init("Default", "");
00081 return;
00082 }
00083 }
00084 else
00085 {
00086 do
00087 {
00088 dirname = QString::fromUtf8(query.value(0).toString());
00089 dirname.replace(QRegExp("^\\s*"), "");
00090 dirname.replace(QRegExp("\\s*$"), "");
00091 if (dirname.right(1) == "/")
00092 dirname.remove(dirname.length() - 1, 1);
00093 m_dirlist << QDeepCopy<QString>(dirname);
00094 }
00095 while (query.next());
00096 }
00097
00098 if (!m_dirlist.size())
00099 {
00100 QString msg = "Directory value for Default Storage Group is empty. ";
00101 QString tmpDir = gContext->GetSetting("RecordFilePrefix");
00102 if (tmpDir != "")
00103 {
00104 msg += QString("Using old 'RecordFilePrefix' value of '%1'")
00105 .arg(tmpDir);
00106 }
00107 else
00108 {
00109 tmpDir = kDefaultStorageDir;
00110 msg += QString("Using hardcoded default value of '%1'")
00111 .arg(kDefaultStorageDir);
00112 }
00113 VERBOSE(VB_IMPORTANT, LOC_ERR + msg);
00114 m_dirlist << QDeepCopy<QString>(tmpDir);
00115 }
00116 }
00117
00118 QString StorageGroup::FindRecordingFile(QString filename)
00119 {
00120 VERBOSE(VB_FILE, LOC + QString("FindRecordingFile: Searching for '%1'")
00121 .arg(filename));
00122
00123 QString recDir = FindRecordingDir(filename);
00124 QString result = "";
00125
00126 if (!recDir.isEmpty())
00127 {
00128 result = recDir + "/" + filename;
00129 VERBOSE(VB_FILE, LOC + QString("FindRecordingFile: Found '%1'")
00130 .arg(result));
00131 }
00132 else
00133 {
00134 VERBOSE(VB_FILE, LOC_ERR +
00135 QString("FindRecordingFile: Unable to find '%1'!")
00136 .arg(filename));
00137 }
00138
00139 return result;
00140 }
00141
00142 QString StorageGroup::FindRecordingDir(QString filename)
00143 {
00144 QString result = "";
00145 QFile checkFile("");
00146
00147 unsigned int curDir = 0;
00148 while (curDir < m_dirlist.size())
00149 {
00150 QString testFile = m_dirlist[curDir] + "/" + filename;
00151 VERBOSE(VB_FILE, LOC + QString("FindRecordingDir: Checking '%1'")
00152 .arg(m_dirlist[curDir]));
00153 checkFile.setName(testFile);
00154 if (checkFile.exists())
00155 return QDeepCopy<QString>(m_dirlist[curDir]);
00156
00157 curDir++;
00158 }
00159
00160 if (m_groupname.isEmpty())
00161 {
00162
00163 QString tmpFile =
00164 gContext->GetSetting("RecordFilePrefix") + "/" + filename;
00165 checkFile.setName(tmpFile);
00166 if (checkFile.exists())
00167 result = tmpFile;
00168 }
00169 else if (m_groupname != "Default")
00170 {
00171
00172 StorageGroup sgroup("Default");
00173 QString tmpFile = sgroup.FindRecordingDir(filename);
00174 result = (tmpFile.isEmpty()) ? result : tmpFile;
00175 }
00176 else
00177 {
00178
00179 StorageGroup sgroup;
00180 QString tmpFile = sgroup.FindRecordingDir(filename);
00181 result = (tmpFile.isEmpty()) ? result : tmpFile;
00182 }
00183
00184 return QDeepCopy<QString>(result);
00185 }
00186
00187 QString StorageGroup::FindNextDirMostFree(void)
00188 {
00189 QString nextDir = kDefaultStorageDir;
00190 long long nextDirFree = 0;
00191 long long thisDirTotal;
00192 long long thisDirUsed;
00193 long long thisDirFree;
00194
00195 VERBOSE(VB_FILE, LOC + QString("FindNextDirMostFree: Starting'"));
00196
00197 if (m_dirlist.size())
00198 nextDir = m_dirlist[0];
00199
00200 QDir checkDir("");
00201 unsigned int curDir = 0;
00202 while (curDir < m_dirlist.size())
00203 {
00204 checkDir.setPath(m_dirlist[curDir]);
00205 if (!checkDir.exists())
00206 {
00207 VERBOSE(VB_IMPORTANT, LOC_ERR +
00208 QString("FindNextDirMostFree: '%1' does not exist!")
00209 .arg(nextDir));
00210 curDir++;
00211 continue;
00212 }
00213
00214 thisDirFree = getDiskSpace(m_dirlist[curDir], thisDirTotal,
00215 thisDirUsed);
00216 VERBOSE(VB_FILE, LOC +
00217 QString("FindNextDirMostFree: '%1' has %2 KiB free")
00218 .arg(m_dirlist[curDir])
00219 .arg(longLongToString(thisDirFree)));
00220
00221 if (thisDirFree > nextDirFree)
00222 {
00223 nextDir = m_dirlist[curDir];
00224 nextDirFree = thisDirFree;
00225 }
00226 curDir++;
00227 }
00228
00229 VERBOSE(VB_FILE, LOC + QString("FindNextDirMostFree: Using '%1'")
00230 .arg(nextDir));
00231
00232 return QDeepCopy<QString>(nextDir);
00233 }
00234
00235 void StorageGroup::CheckAllStorageGroupDirs(void)
00236 {
00237 QString m_groupname;
00238 QString dirname;
00239 MSqlQuery query(MSqlQuery::InitCon());
00240
00241 query.prepare("SELECT groupname, dirname "
00242 "FROM storagegroup "
00243 "WHERE hostname = :HOSTNAME;");
00244 query.bindValue(":HOSTNAME", gContext->GetHostName());
00245 if (!query.exec() || !query.isActive())
00246 {
00247 MythContext::DBError("StorageGroup::CheckAllStorageGroupDirs()", query);
00248 return;
00249 }
00250
00251 VERBOSE(VB_FILE, LOC + "CheckAllStorageGroupDirs(): Checking All Storage "
00252 "Group directories");
00253
00254 QFile testFile("");
00255 QDir testDir("");
00256 while (query.next())
00257 {
00258 m_groupname = QString::fromUtf8(query.value(0).toString());
00259 dirname = QString::fromUtf8(query.value(1).toString());
00260
00261 dirname.replace(QRegExp("^\\s*"), "");
00262 dirname.replace(QRegExp("\\s*$"), "");
00263
00264 VERBOSE(VB_FILE, LOC +
00265 QString("Checking directory '%1' in group '%2'.")
00266 .arg(dirname).arg(m_groupname));
00267
00268 testDir.setPath(dirname);
00269 if (!testDir.exists())
00270 {
00271 VERBOSE(VB_FILE, LOC_WARN +
00272 QString("Group '%1' references directory '%2' but this "
00273 "directory does not exist. This directory "
00274 "will not be used on this server.")
00275 .arg(m_groupname).arg(dirname));
00276 }
00277 else
00278 {
00279 testFile.setName(dirname + "/.test");
00280 if (testFile.open(IO_WriteOnly))
00281 testFile.remove();
00282 else
00283 VERBOSE(VB_IMPORTANT,
00284 LOC_ERR +
00285 QString("Group '%1' wants to use directory '%2', but "
00286 "this directory is not writeable.")
00287 .arg(m_groupname).arg(dirname));
00288 }
00289 }
00290 }
00291
00292 QStringList StorageGroup::getRecordingsGroups(void)
00293 {
00294 QStringList groups;
00295
00296 MSqlQuery query(MSqlQuery::InitCon());
00297
00298 QString sql = "SELECT DISTINCT groupname "
00299 "FROM storagegroup "
00300 "WHERE groupname NOT IN (";
00301 for (QStringList::const_iterator it = StorageGroup::kSpecialGroups.begin();
00302 it != StorageGroup::kSpecialGroups.end(); ++it)
00303 sql.append(QString(" '%1',").arg(*it));
00304 sql = sql.left(sql.length() - 1);
00305 sql.append(" );");
00306
00307 query.prepare(sql);
00308 if (query.exec() && query.isActive() && query.size() > 0)
00309 while (query.next())
00310 groups += QString::fromUtf8(query.value(0).toString());
00311
00312 groups.sort();
00313
00314 return QDeepCopy<QStringList>(groups);
00315 }
00316
00317
00318 typedef enum {
00319 SGPopup_OK = 0,
00320 SGPopup_CANCEL,
00321 SGPopup_DELETE
00322 } SGPopupResult;
00323
00324 class StorageGroupPopup
00325 {
00326 public:
00327 static SGPopupResult showPopup(MythMainWindow *parent, QString title,
00328 QString message, QString& text);
00329 };
00330
00331 SGPopupResult StorageGroupPopup::showPopup(MythMainWindow *parent,
00332 QString title, QString message, QString& text)
00333 {
00334 MythPopupBox *popup = new MythPopupBox(parent, title);
00335 popup->addLabel(message);
00336
00337 MythLineEdit *textEdit = new MythLineEdit(popup, "chooseEdit");
00338 textEdit->setText(text);
00339 popup->addWidget(textEdit);
00340
00341 popup->addButton(QObject::tr("OK"), popup, SLOT(accept()));
00342 popup->addButton(QObject::tr("Cancel"), popup, SLOT(reject()));
00343
00344 textEdit->setFocus();
00345
00346 bool ok = (MythDialog::Accepted == popup->ExecPopup());
00347 if (ok)
00348 text = QDeepCopy<QString>(textEdit->text());
00349
00350 popup->hide();
00351 popup->deleteLater();
00352
00353 return (ok) ? SGPopup_OK : SGPopup_CANCEL;
00354 }
00355
00356
00357
00358 StorageGroupEditor::StorageGroupEditor(QString group) :
00359 m_group(group), listbox(new ListBoxSetting(this)), lastValue("")
00360 {
00361 QString dispGroup = group;
00362
00363 if (group == "Default")
00364 dispGroup = QObject::tr("Default");
00365 else if (StorageGroup::kSpecialGroups.contains(group))
00366 dispGroup = QObject::tr(group);
00367
00368 if (gContext->GetSetting("MasterServerIP","master") ==
00369 gContext->GetSetting("BackendServerIP","me"))
00370 {
00371 listbox->setLabel(tr("'%1' Storage Group Directories").arg(dispGroup));
00372 }
00373 else
00374 {
00375 listbox->setLabel(tr("Local '%1' Storage Group Directories")
00376 .arg(dispGroup));
00377 }
00378
00379 addChild(listbox);
00380 }
00381
00382 void StorageGroupEditor::open(QString name)
00383 {
00384 lastValue = name;
00385
00386 if (name == "__CREATE_NEW_STORAGE_DIRECTORY__")
00387 {
00388 name = "";
00389 SGPopupResult result = StorageGroupPopup::showPopup(
00390 gContext->GetMainWindow(),
00391 tr("Add Storage Group Directory"),
00392 tr("Enter directory name or press SELECT to enter text via the "
00393 "On Screen Keyboard"), name);
00394 if (result == SGPopup_CANCEL)
00395 return;
00396
00397 if (name == "")
00398 return;
00399
00400 if (name.right(1) != "/")
00401 name.append("/");
00402
00403 MSqlQuery query(MSqlQuery::InitCon());
00404 query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
00405 "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
00406 query.bindValue(":NAME", m_group.utf8());
00407 query.bindValue(":DIRNAME", name.utf8());
00408 query.bindValue(":HOSTNAME", gContext->GetHostName());
00409 if (!query.exec())
00410 MythContext::DBError("StorageGroupEditor::open", query);
00411 else
00412 lastValue = name;
00413 } else {
00414 SGPopupResult result = StorageGroupPopup::showPopup(
00415 gContext->GetMainWindow(),
00416 tr("Edit Storage Group Directory"),
00417 tr("Enter directory name or press SELECT to enter text via the "
00418 "On Screen Keyboard"), name);
00419 if (result == SGPopup_CANCEL)
00420 return;
00421
00422 if (name.right(1) != "/")
00423 name.append("/");
00424
00425 MSqlQuery query(MSqlQuery::InitCon());
00426
00427 query.prepare("DELETE FROM storagegroup "
00428 "WHERE groupname = :NAME "
00429 "AND dirname = :DIRNAME "
00430 "AND hostname = :HOSTNAME;");
00431 query.bindValue(":NAME", m_group.utf8());
00432 query.bindValue(":DIRNAME", lastValue.utf8());
00433 query.bindValue(":HOSTNAME", gContext->GetHostName());
00434 if (!query.exec())
00435 MythContext::DBError("StorageGroupEditor::open", query);
00436
00437 query.prepare("INSERT INTO storagegroup (groupname, hostname, dirname) "
00438 "VALUES (:NAME, :HOSTNAME, :DIRNAME);");
00439 query.bindValue(":NAME", m_group.utf8());
00440 query.bindValue(":DIRNAME", name.utf8());
00441 query.bindValue(":HOSTNAME", gContext->GetHostName());
00442 if (!query.exec())
00443 MythContext::DBError("StorageGroupEditor::open", query);
00444 else
00445 lastValue = name;
00446 }
00447 };
00448
00449 void StorageGroupEditor::doDelete(void)
00450 {
00451 QString name = listbox->getValue();
00452 if (name == "__CREATE_NEW_STORAGE_DIRECTORY__")
00453 return;
00454
00455 QString message =
00456 tr("Remove '%1'\nDirectory From Storage Group?").arg(name);
00457
00458 DialogCode value = MythPopupBox::Show2ButtonPopup(
00459 gContext->GetMainWindow(), "", message,
00460 tr("Yes, remove directory"),
00461 tr("No, Don't remove directory"),
00462 kDialogCodeButton1);
00463
00464 if (kDialogCodeButton0 == value)
00465 {
00466 MSqlQuery query(MSqlQuery::InitCon());
00467 query.prepare("DELETE FROM storagegroup "
00468 "WHERE groupname = :NAME "
00469 "AND dirname = :DIRNAME "
00470 "AND hostname = :HOSTNAME;");
00471 query.bindValue(":NAME", m_group.utf8());
00472 query.bindValue(":DIRNAME", name.utf8());
00473 query.bindValue(":HOSTNAME", gContext->GetHostName());
00474 if (!query.exec())
00475 MythContext::DBError("StorageGroupEditor::doDelete", query);
00476
00477 int lastIndex = listbox->getValueIndex(name);
00478 lastValue = "";
00479 load();
00480 listbox->setValue(lastIndex);
00481 }
00482
00483 listbox->setFocus();
00484 }
00485
00486 void StorageGroupEditor::load(void) {
00487 listbox->clearSelections();
00488
00489 MSqlQuery query(MSqlQuery::InitCon());
00490 query.prepare("SELECT dirname, id FROM storagegroup "
00491 "WHERE groupname = :NAME AND hostname = :HOSTNAME "
00492 "ORDER BY id;");
00493 query.bindValue(":NAME", m_group.utf8());
00494 query.bindValue(":HOSTNAME", gContext->GetHostName());
00495 if (!query.exec() || !query.isActive())
00496 MythContext::DBError("StorageGroupEditor::doDelete", query);
00497 else
00498 {
00499 bool first = true;
00500 while (query.next())
00501 {
00502 if (first)
00503 {
00504 lastValue = query.value(0).toString();
00505 first = false;
00506 }
00507 listbox->addSelection(query.value(0).toString());
00508 }
00509 }
00510
00511 listbox->addSelection(tr("(Add New Directory)"),
00512 "__CREATE_NEW_STORAGE_DIRECTORY__");
00513
00514 listbox->setValue(lastValue);
00515 }
00516
00517 DialogCode StorageGroupEditor::exec(void)
00518 {
00519 while (ConfigurationDialog::exec() == kDialogCodeAccepted)
00520 open(listbox->getValue());
00521
00522 return kDialogCodeRejected;
00523 }
00524
00525 MythDialog* StorageGroupEditor::dialogWidget(MythMainWindow* parent,
00526 const char* widgetName)
00527 {
00528 dialog = ConfigurationDialog::dialogWidget(parent, widgetName);
00529 connect(dialog, SIGNAL(menuButtonPressed()), this, SLOT(doDelete()));
00530 connect(dialog, SIGNAL(deleteButtonPressed()), this, SLOT(doDelete()));
00531 return dialog;
00532 }
00533
00534
00535
00536 StorageGroupListEditor::StorageGroupListEditor(void) :
00537 listbox(new ListBoxSetting(this)), lastValue("")
00538 {
00539 if (gContext->GetSetting("MasterServerIP","master") ==
00540 gContext->GetSetting("BackendServerIP","me"))
00541 listbox->setLabel(
00542 tr("Storage Groups (directories for new recordings)"));
00543 else
00544 listbox->setLabel(
00545 tr("Local Storage Groups (directories for new recordings)"));
00546
00547 addChild(listbox);
00548 }
00549
00550 void StorageGroupListEditor::open(QString name)
00551 {
00552 lastValue = name;
00553
00554 if (name.left(28) == "__CREATE_NEW_STORAGE_GROUP__")
00555 {
00556 if (name.length() > 28)
00557 {
00558 name = name.mid(28);
00559 }
00560 else
00561 {
00562 name = "";
00563 SGPopupResult result = StorageGroupPopup::showPopup(
00564 gContext->GetMainWindow(),
00565 tr("Create New Storage Group"),
00566 tr("Enter group name or press SELECT to enter text via the "
00567 "On Screen Keyboard"), name);
00568 if (result == SGPopup_CANCEL)
00569 return;
00570 }
00571 }
00572
00573 if (!name.isEmpty())
00574 {
00575 StorageGroupEditor sgEditor(name);
00576 sgEditor.exec();
00577 }
00578 };
00579
00580 void StorageGroupListEditor::doDelete(void)
00581 {
00582 QString name = listbox->getValue();
00583 if (name.left(28) == "__CREATE_NEW_STORAGE_GROUP__")
00584 return;
00585
00586 if ((gContext->GetSetting("MasterServerIP","master") ==
00587 gContext->GetSetting("BackendServerIP","me")) &&
00588 (name == "Default"))
00589 return;
00590
00591 QString dispGroup = name;
00592 if (name == "Default")
00593 dispGroup = QObject::tr("Default");
00594 else if (StorageGroup::kSpecialGroups.contains(name))
00595 dispGroup = QObject::tr(name);
00596
00597 QString message = tr("Delete '%1' Storage Group?").arg(dispGroup);
00598
00599 DialogCode value = MythPopupBox::Show2ButtonPopup(
00600 gContext->GetMainWindow(),
00601 "", message,
00602 tr("Yes, delete group"),
00603 tr("No, Don't delete group"), kDialogCodeButton1);
00604
00605 if (kDialogCodeButton0 == value)
00606 {
00607 MSqlQuery query(MSqlQuery::InitCon());
00608 query.prepare("DELETE FROM storagegroup "
00609 "WHERE groupname = :NAME AND hostname = :HOSTNAME;");
00610 query.bindValue(":NAME", name.utf8());
00611 query.bindValue(":HOSTNAME", gContext->GetHostName());
00612 if (!query.exec())
00613 MythContext::DBError("StorageGroupListEditor::doDelete", query);
00614
00615 int lastIndex = listbox->getValueIndex(name);
00616 lastValue = "";
00617 load();
00618 listbox->setValue(lastIndex);
00619 }
00620
00621 listbox->setFocus();
00622 }
00623
00624 void StorageGroupListEditor::load(void)
00625 {
00626 QStringList names;
00627 QStringList masterNames;
00628 bool createAddDefaultButton = false;
00629 bool createAddSpecialGroupButton[StorageGroup::kSpecialGroups.size()];
00630 bool isMaster = (gContext->GetSetting("MasterServerIP","master") ==
00631 gContext->GetSetting("BackendServerIP","me"));
00632
00633 MSqlQuery query(MSqlQuery::InitCon());
00634 query.prepare("SELECT distinct groupname "
00635 "FROM storagegroup "
00636 "WHERE hostname = :HOSTNAME "
00637 "ORDER BY groupname;");
00638 query.bindValue(":HOSTNAME", gContext->GetHostName());
00639 if (!query.exec())
00640 MythContext::DBError("StorageGroup::load getting local group names",
00641 query);
00642 else
00643 {
00644 while (query.next())
00645 names << QString::fromUtf8(query.value(0).toString());
00646 }
00647
00648 query.prepare("SELECT distinct groupname "
00649 "FROM storagegroup "
00650 "ORDER BY groupname;");
00651 if (!query.exec())
00652 MythContext::DBError("StorageGroup::load getting all group names",
00653 query);
00654 else
00655 {
00656 while (query.next())
00657 masterNames << QString::fromUtf8(query.value(0).toString());
00658 }
00659
00660 listbox->clearSelections();
00661
00662 if (isMaster || names.contains("Default"))
00663 {
00664 listbox->addSelection(QObject::tr("Default"), "Default");
00665 lastValue = "Default";
00666 }
00667 else
00668 createAddDefaultButton = true;
00669
00670 unsigned int curGroup = 0;
00671 QString groupName;
00672 while (curGroup < StorageGroup::kSpecialGroups.size())
00673 {
00674 groupName = StorageGroup::kSpecialGroups[curGroup];
00675 if (names.contains(groupName))
00676 {
00677 listbox->addSelection(QObject::tr(groupName), groupName);
00678 createAddSpecialGroupButton[curGroup] = false;
00679 }
00680 else
00681 createAddSpecialGroupButton[curGroup] = true;
00682 curGroup++;
00683 }
00684
00685 unsigned int curName = 0;
00686 while (curName < names.size())
00687 {
00688 if ((names[curName] != "Default") &&
00689 (!StorageGroup::kSpecialGroups.contains(names[curName])))
00690 listbox->addSelection(names[curName]);
00691 curName++;
00692 }
00693
00694 if (createAddDefaultButton)
00695 {
00696 listbox->addSelection(tr("(Create %1 group)").arg("Default"),
00697 "Default");
00698 lastValue = "Default";
00699 }
00700
00701 curGroup = 0;
00702 while (curGroup < StorageGroup::kSpecialGroups.size())
00703 {
00704 groupName = StorageGroup::kSpecialGroups[curGroup];
00705 if (createAddSpecialGroupButton[curGroup])
00706 listbox->addSelection(tr("(Create %1 group)").arg(groupName),
00707 QString("__CREATE_NEW_STORAGE_GROUP__%1").arg(groupName));
00708 curGroup++;
00709 }
00710
00711 if (isMaster)
00712 listbox->addSelection(tr("(Create %1 group)").arg("new"),
00713 "__CREATE_NEW_STORAGE_GROUP__");
00714 else
00715 {
00716 curName = 0;
00717 while (curName < masterNames.size())
00718 {
00719 if ((masterNames[curName] != "Default") &&
00720 (!StorageGroup::kSpecialGroups.contains(masterNames[curName])) &&
00721 (!names.contains(masterNames[curName])))
00722 listbox->addSelection(tr("(Create %1 group)")
00723 .arg(masterNames[curName]),
00724 "__CREATE_NEW_STORAGE_GROUP__" + masterNames[curName]);
00725 curName++;
00726 }
00727 }
00728
00729 listbox->setValue(lastValue);
00730 }
00731
00732 DialogCode StorageGroupListEditor::exec(void)
00733 {
00734 while (ConfigurationDialog::exec() == kDialogCodeAccepted)
00735 open(listbox->getValue());
00736
00737 return kDialogCodeRejected;
00738 }
00739
00740 MythDialog* StorageGroupListEditor::dialogWidget(MythMainWindow* parent,
00741 const char* widgetName)
00742 {
00743 dialog = ConfigurationDialog::dialogWidget(parent, widgetName);
00744 connect(dialog, SIGNAL(menuButtonPressed()), this, SLOT(doDelete()));
00745 connect(dialog, SIGNAL(deleteButtonPressed()), this, SLOT(doDelete()));
00746 return dialog;
00747 }
00748
00749