many others, a complete list can be found in the file AUTHORS.
This program is Free Software; you can redistribute it and/or
modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation plus additions
- that are listed in the file LICENSE.
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
*/
/*
- * Version $Id: medialist.cpp 4230 2007-02-21 20:07:37Z kerns $
+ * Version $Id$
*
* MediaList Class
*
#include "medialist.h"
#include "mediaedit/mediaedit.h"
#include "joblist/joblist.h"
+#include "relabel/relabel.h"
+#include "run/run.h"
-MediaList::MediaList(QStackedWidget *parent, Console *console, QTreeWidgetItem *treeItem, int indexseq)
+MediaList::MediaList()
{
- SetPassedValues(parent, treeItem, indexseq );
setupUi(this);
+ m_name = "Media";
+ pgInitialize();
+ QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
+ thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge.png")));
/* mp_treeWidget, Storage Tree Tree Widget inherited from ui_medialist.h */
- mp_console = console;
- createConnections();
m_populated = false;
m_checkcurwidget = true;
+ m_closeable = false;
+ /* add context sensitive menu items specific to this classto the page
+ * selector tree. m_contextActions is QList of QActions */
+ m_contextActions.append(actionRefreshMediaList);
+ dockPage();
}
MediaList::~MediaList()
void MediaList::populateTree()
{
QTreeWidgetItem *mediatreeitem, *pooltreeitem, *topItem;
- QString currentpool("");
- QString resultline;
- QStringList results;
- const char *query =
- "SELECT p.Name,m.VolumeName,m.MediaId,m.VolStatus,m.Enabled,m.VolBytes,"
- "m.VolFiles,m.VolRetention,m.MediaType,m.LastWritten"
- " FROM Media m,Pool p"
- " WHERE m.PoolId=p.PoolId"
- " ORDER BY p.Name";
+
+ if (!m_console->preventInUseConnect())
+ return;
+
QStringList headerlist = (QStringList()
- << "Pool Name" << "Volume Name" << "Media Id" << "Volume Status" << "Enabled"
- << "Volume Bytes" << "Volume Files" << "Volume Retention"
- << "Media Type" << "Last Written");
+ << "Volume Name" << "Id" << "Status" << "Enabled" << "Bytes" << "Files"
+ << "Jobs" << "Retention" << "Media Type" << "Slot" << "Use Duration"
+ << "Max Jobs" << "Max Files" << "Max Bytes" << "Recycle" << "Enabled"
+ << "RecyclePool" << "Last Written");
+ int statusIndex = headerlist.indexOf("Status");
m_checkcurwidget = false;
mp_treeWidget->clear();
m_checkcurwidget = true;
- mp_treeWidget->setColumnCount(9);
+ mp_treeWidget->setColumnCount(headerlist.count());
topItem = new QTreeWidgetItem(mp_treeWidget);
topItem->setText(0, "Pools");
topItem->setData(0, Qt::UserRole, 0);
- topItem->setExpanded( true );
+ topItem->setExpanded(true);
+
+ mp_treeWidget->setHeaderLabels(headerlist);
-#ifdef xxx
-#include <QSize>
-***** FIXME *****
-//how to get the size of a column to be larger
-//topItem->setSizeHint(0,QSize(1050,50));
-#endif
+ QString query;
- mp_treeWidget->setHeaderLabels(headerlist);
+ foreach (QString pool_listItem, m_console->pool_list) {
+ pooltreeitem = new QTreeWidgetItem(topItem);
+ pooltreeitem->setText(0, pool_listItem);
+ pooltreeitem->setData(0, Qt::UserRole, 1);
+ pooltreeitem->setExpanded(true);
- /*
- * Setup a context menu
- */
- QAction *editAction = new QAction("Edit Properties", mp_treeWidget);
- QAction *listAction = new QAction("List Jobs On Media", mp_treeWidget);
- mp_treeWidget->addAction(editAction);
- mp_treeWidget->addAction(listAction);
- connect(editAction, SIGNAL(triggered()), this, SLOT(editMedia()));
- connect(listAction, SIGNAL(triggered()), this, SLOT(showJobs()));
- mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
- connect(mp_treeWidget, SIGNAL(
- currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
- this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
+ query = "SELECT Media.VolumeName AS Media, "
+ " Media.MediaId AS Id, Media.VolStatus AS VolStatus,"
+ " Media.Enabled AS Enabled, Media.VolBytes AS Bytes,"
+ " Media.VolFiles AS FileCount, Media.VolJobs AS JobCount,"
+ " Media.VolRetention AS VolumeRetention, Media.MediaType AS MediaType,"
+ " Media.Slot AS Slot, Media.VolUseDuration AS UseDuration,"
+ " Media.MaxVolJobs AS MaxJobs, Media.MaxVolFiles AS MaxFiles,"
+ " Media.MaxVolBytes AS MaxBytes, Media.Recycle AS Recycle,"
+ " Media.Enabled AS enabled, Pol.Name AS RecyclePool,"
+ " Media.LastWritten AS LastWritten"
+ " FROM Media"
+ " LEFT OUTER JOIN Pool ON (Media.PoolId=Pool.PoolId)"
+ " LEFT OUTER JOIN Pool AS Pol ON (Media.recyclepoolid=Pol.PoolId)"
+ " WHERE";
+ query += " Pool.Name='" + pool_listItem + "'";
+ query += " ORDER BY Media";
+
+ if (mainWin->m_sqlDebug) {
+ Pmsg1(000, "MediaList query cmd : %s\n",query.toUtf8().data());
+ }
+ QStringList results;
+ if (m_console->sql_cmd(query, results)) {
+ QString field;
+ QStringList fieldlist;
- if (mp_console->sql_cmd(query, results)) {
- QString field;
- QStringList fieldlist;
-
- foreach (resultline, results) {
- fieldlist = resultline.split("\t");
- int index = 0;
- /* Iterate through fields in the record */
- foreach (field, fieldlist) {
- field = field.trimmed(); /* strip leading & trailing spaces */
- if (field != "") {
- /* The first field is the pool name */
- if (index == 0) {
- /* If new pool name, create new Pool item */
- if (currentpool != field) {
- currentpool = field;
- pooltreeitem = new QTreeWidgetItem(topItem);
- pooltreeitem->setText(0, field);
- pooltreeitem->setData(0, Qt::UserRole, 1);
- pooltreeitem->setExpanded(true);
- }
- mediatreeitem = new QTreeWidgetItem(pooltreeitem);
+ /* Iterate through the lines of results. */
+ foreach (QString resultline, results) {
+ fieldlist = resultline.split("\t");
+ int index = 0;
+ mediatreeitem = new QTreeWidgetItem(pooltreeitem);
+
+ /* Iterate through fields in the record */
+ foreach (field, fieldlist) {
+ field = field.trimmed(); /* strip leading & trailing spaces */
+ if (field != "") {
mediatreeitem->setData(index, Qt::UserRole, 2);
- } else {
- /* Put media fields under the pool tree item */
mediatreeitem->setData(index, Qt::UserRole, 2);
mediatreeitem->setText(index, field);
+ if (index == statusIndex) {
+ setStatusColor(mediatreeitem, field, index);
+ }
}
- }
- index++;
- }
- }
+ index++;
+ } /* foreach field */
+ } /* foreach resultline */
+ } /* if results from query */
+ } /* foreach pool_listItem */
+ /* Resize the columns */
+ for(int cnter=0; cnter<headerlist.count(); cnter++) {
+ mp_treeWidget->resizeColumnToContents(cnter);
+ }
+}
+
+void MediaList::setStatusColor(QTreeWidgetItem *item, QString &field, int &index)
+{
+ if (field == "Append" ) {
+ item->setBackground(index, Qt::green);
+ } else if (field == "Error") {
+ item->setBackground(index, Qt::red);
+ } else if ((field == "Used") || ("Full")){
+ item->setBackground(index, Qt::yellow);
}
}
/*
- * Not being used currently, Should this be kept for possible future use.
+ * Called from the signal of the context sensitive menu!
*/
-void MediaList::createConnections()
+void MediaList::editVolume()
{
- connect(mp_treeWidget, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this,
- SLOT(treeItemClicked(QTreeWidgetItem *, int)));
- connect(mp_treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this,
- SLOT(treeItemDoubleClicked(QTreeWidgetItem *, int)));
+ MediaEdit* edit = new MediaEdit(mainWin->getFromHash(this), m_currentVolumeId);
+ connect(edit, SIGNAL(destroyed()), this, SLOT(populateTree()));
}
/*
- * Not being used currently, Should this be kept for possible future use.
+ * Called from the signal of the context sensitive menu!
*/
-void MediaList::treeItemClicked(QTreeWidgetItem * /*item*/, int /*column*/)
+void MediaList::showJobs()
{
+ QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
+ mainWin->createPageJobList(m_currentVolumeName, "", "", "", parentItem);
}
/*
- * Not being used currently, Should this be kept for possible future use.
+ * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
+ * The tree has been populated.
*/
-void MediaList::treeItemDoubleClicked(QTreeWidgetItem * /*item*/, int /*column*/)
+void MediaList::PgSeltreeWidgetClicked()
{
+ if (!m_populated) {
+ populateTree();
+ createContextMenu();
+ m_populated=true;
+ }
}
/*
- * Called from the signal of the context sensitive menu!
+ * Added to set the context menu policy based on currently active treeWidgetItem
+ * signaled by currentItemChanged
*/
-void MediaList::editMedia()
+void MediaList::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetItem *previouswidgetitem )
{
- MediaEdit* edit = new MediaEdit(mp_console, m_currentlyselected);
- edit->show();
+ /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */
+ if (m_checkcurwidget) {
+ /* The Previous item */
+ if (previouswidgetitem) { /* avoid a segfault if first time */
+ foreach(QAction* mediaAction, mp_treeWidget->actions()) {
+ mp_treeWidget->removeAction(mediaAction);
+ }
+ }
+
+ int treedepth = currentwidgetitem->data(0, Qt::UserRole).toInt();
+ m_currentVolumeName=currentwidgetitem->text(0);
+ mp_treeWidget->addAction(actionRefreshMediaList);
+ if (treedepth == 2){
+ m_currentVolumeId=currentwidgetitem->text(1);
+ mp_treeWidget->addAction(actionEditVolume);
+ mp_treeWidget->addAction(actionListJobsOnVolume);
+ mp_treeWidget->addAction(actionDeleteVolume);
+ mp_treeWidget->addAction(actionPruneVolume);
+ mp_treeWidget->addAction(actionPurgeVolume);
+ mp_treeWidget->addAction(actionRelabelVolume);
+ mp_treeWidget->addAction(actionVolumeFromPool);
+ } else if (treedepth == 1) {
+ mp_treeWidget->addAction(actionAllVolumesFromPool);
+ }
+ }
}
-/*
- * Called from the signal of the context sensitive menu!
+/*
+ * Setup a context menu
+ * Made separate from populate so that it would not create context menu over and
+ * over as the tree is repopulated.
*/
-void MediaList::showJobs()
+void MediaList::createContextMenu()
{
- JobList* joblist = new JobList(mp_console, m_currentlyselected);
- joblist->show();
+ mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
+ connect(actionEditVolume, SIGNAL(triggered()), this, SLOT(editVolume()));
+ connect(actionListJobsOnVolume, SIGNAL(triggered()), this, SLOT(showJobs()));
+ connect(actionDeleteVolume, SIGNAL(triggered()), this, SLOT(deleteVolume()));
+ connect(actionPurgeVolume, SIGNAL(triggered()), this, SLOT(purgeVolume()));
+ connect(actionPruneVolume, SIGNAL(triggered()), this, SLOT(pruneVolume()));
+ connect(actionRelabelVolume, SIGNAL(triggered()), this, SLOT(relabelVolume()));
+ connect(mp_treeWidget, SIGNAL(
+ currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
+ this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
+ /* connect to the action specific to this pages class */
+ connect(actionRefreshMediaList, SIGNAL(triggered()), this,
+ SLOT(populateTree()));
+ connect(actionAllVolumesFromPool, SIGNAL(triggered()), this, SLOT(allVolumesFromPool()));
+ connect(actionVolumeFromPool, SIGNAL(triggered()), this, SLOT(volumeFromPool()));
}
/*
- * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
- * The tree has been populated.
+ * Virtual function which is called when this page is visible on the stack
*/
-void MediaList::PgSeltreeWidgetClicked()
+void MediaList::currentStackItem()
{
if(!m_populated) {
populateTree();
+ /* Create the context menu for the medialist tree */
+ createContextMenu();
m_populated=true;
}
}
/*
- * When the treeWidgetItem in the page selector tree is doubleclicked, Use that
- * As a signal to repopulate from a query of the database.
- * Should this be from a context sensitive menu in either or both of the page selector
- * or This widnow ???
+ * Called from the signal of the context sensitive menu to delete a volume!
*/
-void MediaList::PgSeltreeWidgetDoubleClicked()
+void MediaList::deleteVolume()
{
+ if (QMessageBox::warning(this, tr("Bat"),
+ tr("Are you sure you want to delete?? !!!.\n"
+"This delete command is used to delete a Volume record and all associated catalog"
+" records that were created. This command operates only on the Catalog"
+" database and has no effect on the actual data written to a Volume. This"
+" command can be dangerous and we strongly recommend that you do not use"
+" it unless you know what you are doing. All Jobs and all associated"
+" records (File and JobMedia) will be deleted from the catalog."
+ "Press OK to proceed with delete operation.?"),
+ QMessageBox::Ok | QMessageBox::Cancel)
+ == QMessageBox::Cancel) { return; }
+
+ QString cmd("delete volume=");
+ cmd += m_currentVolumeName;
+ consoleCommand(cmd);
+}
+
+/*
+ * Called from the signal of the context sensitive menu to purge!
+ */
+void MediaList::purgeVolume()
+{
+ if (QMessageBox::warning(this, tr("Bat"),
+ tr("Are you sure you want to purge ?? !!!.\n"
+"The Purge command will delete associated Catalog database records from Jobs and"
+" Volumes without considering the retention period. Purge works only on the"
+" Catalog database and does not affect data written to Volumes. This command can"
+" be dangerous because you can delete catalog records associated with current"
+" backups of files, and we recommend that you do not use it unless you know what"
+" you are doing.\n"
+ "Press OK to proceed with the purge operation?"),
+ QMessageBox::Ok | QMessageBox::Cancel)
+ == QMessageBox::Cancel) { return; }
+
+ QString cmd("purge volume=");
+ cmd += m_currentVolumeName;
+ consoleCommand(cmd);
populateTree();
}
/*
- * Added to set the context menu policy based on currently active treeWidgetItem
- * signaled by currentItemChanged
+ * Called from the signal of the context sensitive menu to prune!
*/
-void MediaList::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetItem *) /*previouswidgetitem*/
+void MediaList::pruneVolume()
{
- if ( m_checkcurwidget ) {
- int treedepth = currentwidgetitem->data(0, Qt::UserRole).toInt();
- if (treedepth == 2){
- mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
- m_currentlyselected=currentwidgetitem->text(1);
- } else {
- mp_treeWidget->setContextMenuPolicy(Qt::NoContextMenu);
- }
- }
+ new prunePage(m_currentVolumeName, "");
+}
+
+/*
+ * Called from the signal of the context sensitive menu to relabel!
+ */
+void MediaList::relabelVolume()
+{
+ setConsoleCurrent();
+ new relabelDialog(m_console, m_currentVolumeName);
+}
+
+/*
+ * Called from the signal of the context sensitive menu to purge!
+ */
+void MediaList::allVolumesFromPool()
+{
+ QString cmd = "update volume AllFromPool=" + m_currentVolumeName;
+ consoleCommand(cmd);
+ populateTree();
+}
+
+/*
+ * Called from the signal of the context sensitive menu to purge!
+ */
+void MediaList::volumeFromPool()
+{
+ QTreeWidgetItem *currentItem = mp_treeWidget->currentItem();
+ QTreeWidgetItem *parent = currentItem->parent();
+ QString pool = parent->text(0);
+ QString cmd;
+ cmd = "update volume=" + m_currentVolumeName + " frompool=" + pool;
+ consoleCommand(cmd);
+ populateTree();
}