1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19
20 /*
21 * FileSet Class
22 *
23 * Dirk Bartley, March 2007
24 *
25 */
26
27 #include "bat.h"
28 #include <QAbstractEventDispatcher>
29 #include <QMenu>
30 #include "fileset/fileset.h"
31 #include "util/fmtwidgetitem.h"
32
FileSet()33 FileSet::FileSet() : Pages()
34 {
35 setupUi(this);
36 m_name = tr("FileSets");
37 pgInitialize();
38 QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
39 thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/system-file-manager.png")));
40
41 /* tableWidget, FileSet Tree Tree Widget inherited from ui_fileset.h */
42 m_populated = false;
43 m_checkcurwidget = true;
44 m_closeable = false;
45 readSettings();
46 /* add context sensitive menu items specific to this classto the page
47 * selector tree. m_contextActions is QList of QActions */
48 m_contextActions.append(actionRefreshFileSet);
49 }
50
~FileSet()51 FileSet::~FileSet()
52 {
53 writeSettings();
54 }
55
56 /*
57 * The main meat of the class!! The function that querries the director and
58 * creates the widgets with appropriate values.
59 */
populateTable()60 void FileSet::populateTable()
61 {
62
63 Freeze frz(*tableWidget); /* disable updating*/
64
65 m_checkcurwidget = false;
66 tableWidget->clear();
67 m_checkcurwidget = true;
68
69 QStringList headerlist = (QStringList() << tr("FileSet Name") << tr("FileSet Id")
70 << tr("Create Time"));
71
72 tableWidget->setColumnCount(headerlist.count());
73 tableWidget->setHorizontalHeaderLabels(headerlist);
74 tableWidget->horizontalHeader()->setHighlightSections(false);
75 tableWidget->verticalHeader()->hide();
76 tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
77 tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
78 tableWidget->setSortingEnabled(false); /* rows move on insert if sorting enabled */
79
80 QString fileset_comsep("");
81 bool first = true;
82 QStringList notFoundList = m_console->fileset_list;
83 foreach(QString filesetName, m_console->fileset_list) {
84 if (first) {
85 fileset_comsep += "'" + filesetName + "'";
86 first = false;
87 }
88 else
89 fileset_comsep += ",'" + filesetName + "'";
90 }
91
92 int row = 0;
93 tableWidget->setRowCount(m_console->fileset_list.count());
94 if (fileset_comsep != "") {
95 /* Set up query QString and header QStringList */
96 QString query("");
97 query += "SELECT FileSet AS Name, FileSetId AS Id, CreateTime"
98 " FROM FileSet"
99 " WHERE FileSetId IN (SELECT MAX(FileSetId) FROM FileSet WHERE";
100 query += " FileSet IN (" + fileset_comsep + ")";
101 query += " GROUP BY FileSet) ORDER BY FileSet";
102
103 QStringList results;
104 if (mainWin->m_sqlDebug) {
105 Pmsg1(000, "FileSet query cmd : %s\n",query.toUtf8().data());
106 }
107 if (m_console->sql_cmd(query, results)) {
108 QStringList fieldlist;
109
110 /* Iterate through the record returned from the query */
111 foreach (QString resultline, results) {
112 fieldlist = resultline.split("\t");
113 if (fieldlist.size() != 3) {
114 Pmsg1(000, "Unexpected line %s", resultline.toUtf8().data());
115 continue;
116 }
117
118 /* remove this fileSet from notFoundList */
119 int indexOf = notFoundList.indexOf(fieldlist[0]);
120 if (indexOf != -1) { notFoundList.removeAt(indexOf); }
121
122 TableItemFormatter item(*tableWidget, row);
123
124 /* Iterate through fields in the record */
125 QStringListIterator fld(fieldlist);
126 int col = 0;
127
128 /* name */
129 item.setTextFld(col++, fld.next());
130
131 /* id */
132 item.setNumericFld(col++, fld.next());
133
134 /* creation time */
135 item.setTextFld(col++, fld.next());
136
137 row++;
138 }
139 }
140 }
141 foreach(QString filesetName, notFoundList) {
142 TableItemFormatter item(*tableWidget, row);
143 item.setTextFld(0, filesetName);
144 row++;
145 }
146
147 /* set default sorting */
148 tableWidget->sortByColumn(headerlist.indexOf(tr("FileSet Name")), Qt::AscendingOrder);
149 tableWidget->setSortingEnabled(true);
150
151 /* Resize rows and columns */
152 tableWidget->resizeColumnsToContents();
153 tableWidget->resizeRowsToContents();
154
155 /* make read only */
156 int rcnt = tableWidget->rowCount();
157 int ccnt = tableWidget->columnCount();
158 for(int r=0; r < rcnt; r++) {
159 for(int c=0; c < ccnt; c++) {
160 QTableWidgetItem* item = tableWidget->item(r, c);
161 if (item) {
162 item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable)));
163 }
164 }
165 }
166 m_populated = true;
167 }
168
169 /*
170 * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
171 * The tree has been populated.
172 */
PgSeltreeWidgetClicked()173 void FileSet::PgSeltreeWidgetClicked()
174 {
175 if (!m_populated) {
176 populateTable();
177 createContextMenu();
178 }
179 if (!isOnceDocked()) {
180 dockPage();
181 }
182 }
183
184 /*
185 * Added to set the context menu policy based on currently active treeWidgetItem
186 * signaled by currentItemChanged
187 */
tableItemChanged(QTableWidgetItem * currentwidgetitem,QTableWidgetItem * previouswidgetitem)188 void FileSet::tableItemChanged(QTableWidgetItem *currentwidgetitem, QTableWidgetItem *previouswidgetitem)
189 {
190 /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */
191 if (m_checkcurwidget && currentwidgetitem) {
192 int currentRow = currentwidgetitem->row();
193 QTableWidgetItem *currentrowzeroitem = tableWidget->item(currentRow, 0);
194 m_currentlyselected = currentrowzeroitem->text();
195
196 /* The Previous item */
197 if (previouswidgetitem) { /* avoid a segfault if first time */
198 tableWidget->removeAction(actionStatusFileSetInConsole);
199 tableWidget->removeAction(actionShowJobs);
200 }
201
202 if (m_currentlyselected.length() != 0) {
203 /* set a hold variable to the fileset name in case the context sensitive
204 * menu is used */
205 tableWidget->addAction(actionStatusFileSetInConsole);
206 tableWidget->addAction(actionShowJobs);
207 }
208 }
209 }
210
211 /*
212 * Setup a context menu
213 * Made separate from populate so that it would not create context menu over and
214 * over as the tree is repopulated.
215 */
createContextMenu()216 void FileSet::createContextMenu()
217 {
218 tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
219 tableWidget->addAction(actionRefreshFileSet);
220 connect(tableWidget, SIGNAL(
221 currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)),
222 this, SLOT(tableItemChanged(QTableWidgetItem *, QTableWidgetItem *)));
223 /* connect to the action specific to this pages class */
224 connect(actionRefreshFileSet, SIGNAL(triggered()), this,
225 SLOT(populateTable()));
226 connect(actionStatusFileSetInConsole, SIGNAL(triggered()), this,
227 SLOT(consoleShowFileSet()));
228 connect(actionShowJobs, SIGNAL(triggered()), this,
229 SLOT(showJobs()));
230 }
231
232 /*
233 * Function responding to actionListJobsofFileSet which calls mainwin function
234 * to create a window of a list of jobs of this fileset.
235 */
consoleShowFileSet()236 void FileSet::consoleShowFileSet()
237 {
238 QString cmd("show fileset=\"");
239 cmd += m_currentlyselected + "\"";
240 consoleCommand(cmd);
241 }
242
243 /*
244 * Virtual function which is called when this page is visible on the stack
245 */
currentStackItem()246 void FileSet::currentStackItem()
247 {
248 if (!m_populated) {
249 populateTable();
250 /* Create the context menu for the fileset table */
251 createContextMenu();
252 }
253 }
254
255 /*
256 * Save user settings associated with this page
257 */
writeSettings()258 void FileSet::writeSettings()
259 {
260 QSettings settings(m_console->m_dir->name(), "bat");
261 settings.beginGroup("FileSet");
262 settings.setValue("geometry", saveGeometry());
263 settings.endGroup();
264 }
265
266 /*
267 * Read and restore user settings associated with this page
268 */
readSettings()269 void FileSet::readSettings()
270 {
271 QSettings settings(m_console->m_dir->name(), "bat");
272 settings.beginGroup("FileSet");
273 restoreGeometry(settings.value("geometry").toByteArray());
274 settings.endGroup();
275 }
276
277 /*
278 * Create a JobList object pre-populating a fileset
279 */
showJobs()280 void FileSet::showJobs()
281 {
282 QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
283 mainWin->createPageJobList("", "", "", m_currentlyselected, parentItem);
284 }
285