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\"\n"))
192 Pmsg0(000, msg.toUtf8().data());
195 /* add unix '/' directory first */
196 if (m_dirPaths.empty() && !isWin32Path(fullpath)) {
197 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
198 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
201 item->setText(0, text.toUtf8().data());
202 if (mainWin->m_miscDebug) {
203 Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
205 m_dirPaths.insert(text, item);
206 m_dirTreeItems.insert(item, text);
209 if (isWin32Path(fullpath)) {
210 /* this is a windows drive */
211 if (mainWin->m_miscDebug) {
212 Pmsg0(000, "Need to do windows \"letter\":/\n");
217 /* is it already existent ?? */
218 if (!m_dirPaths.contains(fullpath)) {
219 QTreeWidgetItem *item = NULL;
221 /* this is the base widget */
222 item = new QTreeWidgetItem(directoryWidget);
223 item->setText(0, fullpath.toUtf8().data());
224 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
226 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
228 /* new directories to add */
229 item = new QTreeWidgetItem(parent);
230 item->setText(0, newdir.toUtf8().data());
231 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png")));
232 directoryWidget->expandItem(parent);
235 if (mainWin->m_miscDebug) {
236 QString msg = QString(tr("In else of if parent cwd \"%1\" newdir \"%2\"\n"))
239 Pmsg0(000, msg.toUtf8().data());
243 /* insert into both forward and reverse hash */
245 if (mainWin->m_miscDebug) {
246 Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
248 m_dirPaths.insert(fullpath, item);
249 m_dirTreeItems.insert(item, fullpath);
255 * Executed when the tree item in the directory pane is changed. This will
256 * allow us to populate the file pane and make this the cwd.
258 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
259 QTreeWidgetItem * /*previousitem*/)
261 QString fullpath = m_dirTreeItems.value(currentitem);
262 statusLine->setText("");
264 cwd(fullpath.toUtf8().data());
269 void restorePage::okButtonPushed()
271 // printf("In restorePage::okButtonPushed\n");
273 m_console->write("done");
274 m_console->notify(true);
277 mainWin->resetFocus();
281 void restorePage::cancelButtonPushed()
284 m_console->write("quit");
285 m_console->displayToPrompt();
286 mainWin->set_status(tr("Canceled"));
288 m_console->notify(true);
289 mainWin->resetFocus();
292 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
295 statusLine->setText("");
296 if (column == 0) { /* mark/unmark */
297 if (item->data(0, Qt::UserRole).toBool()) {
298 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
299 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
300 item->setData(0, Qt::UserRole, false);
302 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
303 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
304 item->setData(0, Qt::UserRole, true);
306 m_console->write_dir(cmd);
307 if (m_console->read() > 0) {
308 strip_trailing_junk(m_console->msg());
309 statusLine->setText(m_console->msg());
311 m_console->displayToPrompt();
315 * Double clicking other than column 0 means to decend into
316 * the directory -- or nothing if it is not a directory.
318 if (item->text(1).endsWith("/")) {
319 QString fullpath = m_cwd + item->text(1);
320 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
322 directoryWidget->setCurrentItem(item);
324 QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
327 Pmsg0(000, msg.toUtf8().data());
333 * If up button pushed, making the parent tree widget current will call fill
336 void restorePage::upButtonPushed()
339 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
341 directoryWidget->setCurrentItem(item);
343 statusLine->setText("");
347 * Mark selected items
349 void restorePage::markButtonPushed()
351 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
352 QTreeWidgetItem *item;
355 statusLine->setText("");
356 foreach (item, treeItemList) {
358 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
359 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
360 m_console->write_dir(cmd);
361 if (m_console->read() > 0) {
362 strip_trailing_junk(m_console->msg());
363 statusLine->setText(m_console->msg());
365 Dmsg1(100, "cmd=%s\n", cmd);
366 m_console->discardToPrompt();
369 mainWin->set_status("Nothing selected, nothing done");
370 statusLine->setText("Nothing selected, nothing done");
376 * Unmark selected items
378 void restorePage::unmarkButtonPushed()
380 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
381 QTreeWidgetItem *item;
384 statusLine->setText("");
385 foreach (item, treeItemList) {
387 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
388 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
389 m_console->write_dir(cmd);
390 if (m_console->read() > 0) {
391 strip_trailing_junk(m_console->msg());
392 statusLine->setText(m_console->msg());
394 Dmsg1(100, "cmd=%s\n", cmd);
395 m_console->discardToPrompt();
398 mainWin->set_status("Nothing selected, nothing done");
399 statusLine->setText("Nothing selected, nothing done");
405 * Change current working directory
407 bool restorePage::cwd(const char *dir)
410 char cd_cmd[MAXSTRING];
412 statusLine->setText("");
413 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
414 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
415 m_console->write_dir(cd_cmd);
417 if ((stat = m_console->read()) > 0) {
418 m_cwd = m_console->msg();
419 lineEdit->insert(m_cwd);
420 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
422 Dmsg1(000, "stat=%d\n", stat);
423 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
425 m_console->discardToPrompt();
426 return true; /* ***FIXME*** return real status */
430 * Return cwd when in tree restore mode
432 char *restorePage::get_cwd()
435 m_console->write_dir(".pwd");
436 Dmsg0(100, "send: .pwd\n");
437 if ((stat = m_console->read()) > 0) {
438 m_cwd = m_console->msg();
439 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
441 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
442 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
444 m_console->discardToPrompt();
445 return m_cwd.toUtf8().data();
449 * Save user settings associated with this page
451 void restorePage::writeSettings()
453 QSettings settings(m_console->m_dir->name(), "bat");
454 settings.beginGroup("RestorePage");
455 settings.setValue("splitterSizes", splitter->saveState());
460 * Read and restore user settings associated with this page
462 void restorePage::readSettings()
464 QSettings settings(m_console->m_dir->name(), "bat");
465 settings.beginGroup("RestorePage");
466 splitter->restoreState(settings.value("splitterSizes").toByteArray());