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 = tr("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 << tr("Mark") << tr("File") << tr("Mode") << tr("User")
75 << tr("Group") << tr("Size") << tr("Date");
76 fileWidget->setHeaderLabels(titles);
87 restorePage::~restorePage()
93 * Fill the fileWidget box with the contents of the current directory
95 void restorePage::fillDirectory()
97 char modes[20], user[20], group[20], size[20], date[30];
100 POOLMEM *file = get_pool_memory(PM_FNAME);
101 POOLMEM *path = get_pool_memory(PM_FNAME);
104 m_console->write_dir("dir");
105 QList<QTreeWidgetItem *> treeItemList;
107 while (m_console->read() > 0) {
108 char *p = m_console->msg();
110 strip_trailing_junk(p);
111 if (*p == '$' || !*p) {
115 skip_nonspaces(&p); /* permissions */
117 bstrncpy(modes, l, sizeof(modes));
119 skip_nonspaces(&p); /* link count */
123 skip_nonspaces(&p); /* user */
126 bstrncpy(user, l, sizeof(user));
128 skip_nonspaces(&p); /* group */
130 bstrncpy(group, l, sizeof(group));
133 skip_nonspaces(&p); /* size */
135 bstrncpy(size, l, sizeof(size));
138 skip_nonspaces(&p); /* date/time */
142 bstrncpy(date, l, sizeof(date));
145 bstrncpy(marked, "*", sizeof(marked));
148 bstrncpy(marked, " ", sizeof(marked));
150 split_path_and_filename(p, &path, &pnl, &file, &fnl);
152 item << "" << file << modes << user << group << size << date;
153 if (item[1].endsWith("/")) {
154 addDirectory(item[1]);
156 QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
157 ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
158 if (strcmp(marked, "*") == 0) {
159 ti->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
160 ti->setData(0, Qt::UserRole, true);
162 ti->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
163 ti->setData(0, Qt::UserRole, false);
165 treeItemList.append(ti);
168 fileWidget->insertTopLevelItems(0, treeItemList);
169 for (int i=0; i<7; i++) {
170 fileWidget->resizeColumnToContents(i);
173 free_pool_memory(file);
174 free_pool_memory(path);
178 * Function called from fill directory when a directory is found to see if this
179 * directory exists in the directory pane and then add it to the directory pane
181 void restorePage::addDirectory(QString &newdirr)
183 QString newdir = newdirr;
184 QString fullpath = m_cwd + newdirr;
186 bool windrive = false;
188 if (mainWin->m_miscDebug) {
189 QString msg = QString(tr("In addDirectory cwd \"%1\" newdir \"%2\" fullpath \"%3\"\n"))
193 Pmsg0(000, msg.toUtf8().data());
196 /* add unix '/' directory first */
197 if (m_dirPaths.empty()) {
198 if (isWin32Path(newdir)) {
199 /* this is a windows drive */
200 if (mainWin->m_miscDebug) {
201 Pmsg0(000, "Need to do windows \"letter\":/\n");
203 fullpath.replace(0,1,"");
206 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
207 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
210 item->setText(0, text.toUtf8().data());
211 if (mainWin->m_miscDebug) {
212 Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
214 m_dirPaths.insert(text, item);
215 m_dirTreeItems.insert(item, text);
220 /* is it already existent ?? */
221 if (!m_dirPaths.contains(fullpath)) {
222 QTreeWidgetItem *item = NULL;
224 /* this is the base widget */
225 item = new QTreeWidgetItem(directoryWidget);
226 item->setText(0, fullpath.toUtf8().data());
227 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
229 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
231 /* new directories to add */
232 item = new QTreeWidgetItem(parent);
233 item->setText(0, newdir.toUtf8().data());
234 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
235 directoryWidget->expandItem(parent);
238 if (mainWin->m_miscDebug) {
239 QString msg = QString(tr("In else of if parent cwd \"%1\" newdir \"%2\"\n"))
242 Pmsg0(000, msg.toUtf8().data());
246 /* insert into both forward and reverse hash */
248 if (mainWin->m_miscDebug) {
249 Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
251 m_dirPaths.insert(fullpath, item);
252 m_dirTreeItems.insert(item, fullpath);
258 * Executed when the tree item in the directory pane is changed. This will
259 * allow us to populate the file pane and make this the cwd.
261 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
262 QTreeWidgetItem * /*previousitem*/)
264 QString fullpath = m_dirTreeItems.value(currentitem);
265 statusLine->setText("");
267 cwd(fullpath.toUtf8().data());
272 void restorePage::okButtonPushed()
274 // printf("In restorePage::okButtonPushed\n");
276 m_console->write("done");
277 m_console->notify(true);
280 mainWin->resetFocus();
284 void restorePage::cancelButtonPushed()
287 m_console->write("quit");
288 m_console->displayToPrompt();
289 mainWin->set_status(tr("Canceled"));
291 m_console->notify(true);
292 mainWin->resetFocus();
295 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
298 statusLine->setText("");
299 if (column == 0) { /* mark/unmark */
300 if (item->data(0, Qt::UserRole).toBool()) {
301 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
302 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
303 item->setData(0, Qt::UserRole, false);
305 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
306 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
307 item->setData(0, Qt::UserRole, true);
309 m_console->write_dir(cmd);
310 if (m_console->read() > 0) {
311 strip_trailing_junk(m_console->msg());
312 statusLine->setText(m_console->msg());
314 m_console->displayToPrompt();
318 * Double clicking other than column 0 means to decend into
319 * the directory -- or nothing if it is not a directory.
321 if (item->text(1).endsWith("/")) {
322 QString fullpath = m_cwd + item->text(1);
323 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
325 directoryWidget->setCurrentItem(item);
327 QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
330 Pmsg0(000, msg.toUtf8().data());
336 * If up button pushed, making the parent tree widget current will call fill
339 void restorePage::upButtonPushed()
342 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
344 directoryWidget->setCurrentItem(item);
346 statusLine->setText("");
350 * Mark selected items
352 void restorePage::markButtonPushed()
354 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
355 QTreeWidgetItem *item;
358 statusLine->setText("");
359 foreach (item, treeItemList) {
361 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
362 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
363 m_console->write_dir(cmd);
364 if (m_console->read() > 0) {
365 strip_trailing_junk(m_console->msg());
366 statusLine->setText(m_console->msg());
368 Dmsg1(100, "cmd=%s\n", cmd);
369 m_console->discardToPrompt();
372 mainWin->set_status("Nothing selected, nothing done");
373 statusLine->setText("Nothing selected, nothing done");
379 * Unmark selected items
381 void restorePage::unmarkButtonPushed()
383 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
384 QTreeWidgetItem *item;
387 statusLine->setText("");
388 foreach (item, treeItemList) {
390 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
391 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
392 m_console->write_dir(cmd);
393 if (m_console->read() > 0) {
394 strip_trailing_junk(m_console->msg());
395 statusLine->setText(m_console->msg());
397 Dmsg1(100, "cmd=%s\n", cmd);
398 m_console->discardToPrompt();
401 mainWin->set_status(tr("Nothing selected, nothing done"));
402 statusLine->setText(tr("Nothing selected, nothing done"));
408 * Change current working directory
410 bool restorePage::cwd(const char *dir)
413 char cd_cmd[MAXSTRING];
415 statusLine->setText("");
416 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
417 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
418 m_console->write_dir(cd_cmd);
420 if ((stat = m_console->read()) > 0) {
421 m_cwd = m_console->msg();
422 lineEdit->insert(m_cwd);
423 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
425 Dmsg1(000, "stat=%d\n", stat);
426 QMessageBox::critical(this, "Error", tr("cd command failed"), QMessageBox::Ok);
428 m_console->discardToPrompt();
429 return true; /* ***FIXME*** return real status */
433 * Return cwd when in tree restore mode
435 char *restorePage::get_cwd()
438 m_console->write_dir(".pwd");
439 Dmsg0(100, "send: .pwd\n");
440 if ((stat = m_console->read()) > 0) {
441 m_cwd = m_console->msg();
442 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
444 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
445 QMessageBox::critical(this, "Error", tr(".pwd command failed"), QMessageBox::Ok);
447 m_console->discardToPrompt();
448 return m_cwd.toUtf8().data();
452 * Save user settings associated with this page
454 void restorePage::writeSettings()
456 QSettings settings(m_console->m_dir->name(), "bat");
457 settings.beginGroup("RestorePage");
458 settings.setValue("splitterSizes", splitter->saveState());
463 * Read and restore user settings associated with this page
465 void restorePage::readSettings()
467 QSettings settings(m_console->m_dir->name(), "bat");
468 settings.beginGroup("RestorePage");
469 splitter->restoreState(settings.value("splitterSizes").toByteArray());