2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
34 * Kern Sibbald, February MMVII
41 restorePage::restorePage()
46 m_name = "Restore Select";
48 QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
49 thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png")));
51 m_console->notify(false); /* this should already be off */
54 connect(fileWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
55 this, SLOT(fileDoubleClicked(QTreeWidgetItem *, int)));
56 connect(directoryWidget, SIGNAL(
57 currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
58 this, SLOT(directoryItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
59 connect(upButton, SIGNAL(pressed()), this, SLOT(upButtonPushed()));
60 connect(markButton, SIGNAL(pressed()), this, SLOT(markButtonPushed()));
61 connect(unmarkButton, SIGNAL(pressed()), this, SLOT(unmarkButtonPushed()));
62 connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed()));
63 connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed()));
65 fileWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
66 fileWidget->addAction(actionMark);
67 fileWidget->addAction(actionUnMark);
68 connect(actionMark, SIGNAL(triggered()), this, SLOT(markButtonPushed()));
69 connect(actionUnMark, SIGNAL(triggered()), this, SLOT(unmarkButtonPushed()));
71 setFont(m_console->get_font());
72 m_console->displayToPrompt();
74 titles << "Mark" << "File" << "Mode" << "User" << "Group" << "Size" << "Date";
75 fileWidget->setHeaderLabels(titles);
86 restorePage::~restorePage()
92 * Fill the fileWidget box with the contents of the current directory
94 void restorePage::fillDirectory()
96 char modes[20], user[20], group[20], size[20], date[30];
99 POOLMEM *file = get_pool_memory(PM_FNAME);
100 POOLMEM *path = get_pool_memory(PM_FNAME);
103 m_console->write_dir("dir");
104 QList<QTreeWidgetItem *> treeItemList;
106 while (m_console->read() > 0) {
107 char *p = m_console->msg();
109 strip_trailing_junk(p);
110 if (*p == '$' || !*p) {
114 skip_nonspaces(&p); /* permissions */
116 bstrncpy(modes, l, sizeof(modes));
118 skip_nonspaces(&p); /* link count */
122 skip_nonspaces(&p); /* user */
125 bstrncpy(user, l, sizeof(user));
127 skip_nonspaces(&p); /* group */
129 bstrncpy(group, l, sizeof(group));
132 skip_nonspaces(&p); /* size */
134 bstrncpy(size, l, sizeof(size));
137 skip_nonspaces(&p); /* date/time */
141 bstrncpy(date, l, sizeof(date));
144 bstrncpy(marked, "*", sizeof(marked));
147 bstrncpy(marked, " ", sizeof(marked));
149 split_path_and_filename(p, &path, &pnl, &file, &fnl);
151 item << "" << file << modes << user << group << size << date;
152 if (item[1].endsWith("/")) {
153 addDirectory(item[1]);
155 QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
156 ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
157 if (strcmp(marked, "*") == 0) {
158 ti->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
159 ti->setData(0, Qt::UserRole, true);
161 ti->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
162 ti->setData(0, Qt::UserRole, false);
164 treeItemList.append(ti);
167 fileWidget->insertTopLevelItems(0, treeItemList);
168 for (int i=0; i<7; i++) {
169 fileWidget->resizeColumnToContents(i);
172 free_pool_memory(file);
173 free_pool_memory(path);
177 * Function called from fill directory when a directory is found to see if this
178 * directory exists in the directory pane and then add it to the directory pane
180 void restorePage::addDirectory(QString &newdirr)
182 QString newdir = newdirr;
183 QString fullpath = m_cwd + newdirr;
185 bool windrive = false;
187 if (mainWin->m_miscDebug) {
188 QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
191 Pmsg0(000, msg.toUtf8().data());
194 /* add unix '/' directory first */
195 if (m_dirPaths.empty() && !isWin32Path(fullpath)) {
196 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
197 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
200 item->setText(0, text.toUtf8().data());
201 if (mainWin->m_miscDebug) {
202 Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
204 m_dirPaths.insert(text, item);
205 m_dirTreeItems.insert(item, text);
208 if (isWin32Path(fullpath)) {
209 /* this is a windows drive */
210 if (mainWin->m_miscDebug) {
211 Pmsg0(000, "Need to do windows \"letter\":/\n");
216 /* is it already existent ?? */
217 if (!m_dirPaths.contains(fullpath)) {
218 QTreeWidgetItem *item = NULL;
220 /* this is the base widget */
221 item = new QTreeWidgetItem(directoryWidget);
222 item->setText(0, fullpath.toUtf8().data());
223 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
225 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
227 /* new directories to add */
228 item = new QTreeWidgetItem(parent);
229 item->setText(0, newdir.toUtf8().data());
230 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
231 directoryWidget->expandItem(parent);
234 if (mainWin->m_miscDebug) {
235 QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
238 Pmsg0(000, msg.toUtf8().data());
242 /* insert into both forward and reverse hash */
244 if (mainWin->m_miscDebug) {
245 Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
247 m_dirPaths.insert(fullpath, item);
248 m_dirTreeItems.insert(item, fullpath);
254 * Executed when the tree item in the directory pane is changed. This will
255 * allow us to populate the file pane and make this the cwd.
257 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
258 QTreeWidgetItem * /*previousitem*/)
260 QString fullpath = m_dirTreeItems.value(currentitem);
261 statusLine->setText("");
263 cwd(fullpath.toUtf8().data());
268 void restorePage::okButtonPushed()
270 // printf("In restorePage::okButtonPushed\n");
272 m_console->write("done");
273 m_console->notify(true);
276 mainWin->resetFocus();
280 void restorePage::cancelButtonPushed()
283 m_console->write("quit");
284 m_console->displayToPrompt();
285 mainWin->set_status("Canceled");
287 m_console->notify(true);
288 mainWin->resetFocus();
291 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
294 statusLine->setText("");
295 if (column == 0) { /* mark/unmark */
296 if (item->data(0, Qt::UserRole).toBool()) {
297 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
298 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
299 item->setData(0, Qt::UserRole, false);
301 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
302 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
303 item->setData(0, Qt::UserRole, true);
305 m_console->write_dir(cmd);
306 if (m_console->read() > 0) {
307 strip_trailing_junk(m_console->msg());
308 statusLine->setText(m_console->msg());
310 m_console->displayToPrompt();
314 * Double clicking other than column 0 means to decend into
315 * the directory -- or nothing if it is not a directory.
317 if (item->text(1).endsWith("/")) {
318 QString fullpath = m_cwd + item->text(1);
319 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
321 directoryWidget->setCurrentItem(item);
323 QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
326 Pmsg0(000, msg.toUtf8().data());
332 * If up button pushed, making the parent tree widget current will call fill
335 void restorePage::upButtonPushed()
338 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
340 directoryWidget->setCurrentItem(item);
342 statusLine->setText("");
346 * Mark selected items
348 void restorePage::markButtonPushed()
350 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
351 QTreeWidgetItem *item;
354 statusLine->setText("");
355 foreach (item, treeItemList) {
357 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
358 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
359 m_console->write_dir(cmd);
360 if (m_console->read() > 0) {
361 strip_trailing_junk(m_console->msg());
362 statusLine->setText(m_console->msg());
364 Dmsg1(100, "cmd=%s\n", cmd);
365 m_console->discardToPrompt();
368 mainWin->set_status("Nothing selected, nothing done");
369 statusLine->setText("Nothing selected, nothing done");
375 * Unmark selected items
377 void restorePage::unmarkButtonPushed()
379 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
380 QTreeWidgetItem *item;
383 statusLine->setText("");
384 foreach (item, treeItemList) {
386 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
387 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
388 m_console->write_dir(cmd);
389 if (m_console->read() > 0) {
390 strip_trailing_junk(m_console->msg());
391 statusLine->setText(m_console->msg());
393 Dmsg1(100, "cmd=%s\n", cmd);
394 m_console->discardToPrompt();
397 mainWin->set_status("Nothing selected, nothing done");
398 statusLine->setText("Nothing selected, nothing done");
404 * Change current working directory
406 bool restorePage::cwd(const char *dir)
409 char cd_cmd[MAXSTRING];
411 statusLine->setText("");
412 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
413 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
414 m_console->write_dir(cd_cmd);
416 if ((stat = m_console->read()) > 0) {
417 m_cwd = m_console->msg();
418 lineEdit->insert(m_cwd);
419 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
421 Dmsg1(000, "stat=%d\n", stat);
422 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
424 m_console->discardToPrompt();
425 return true; /* ***FIXME*** return real status */
429 * Return cwd when in tree restore mode
431 char *restorePage::get_cwd()
434 m_console->write_dir(".pwd");
435 Dmsg0(100, "send: .pwd\n");
436 if ((stat = m_console->read()) > 0) {
437 m_cwd = m_console->msg();
438 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
440 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
441 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
443 m_console->discardToPrompt();
444 return m_cwd.toUtf8().data();
448 * Save user settings associated with this page
450 void restorePage::writeSettings()
452 QSettings settings(m_console->m_dir->name(), "bat");
453 settings.beginGroup("RestorePage");
454 settings.setValue("splitterSizes", splitter->saveState());
459 * Read and restore user settings associated with this page
461 void restorePage::readSettings()
463 QSettings settings(m_console->m_dir->name(), "bat");
464 settings.beginGroup("RestorePage");
465 splitter->restoreState(settings.value("splitterSizes").toByteArray());