2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2007 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 plus additions
11 that are listed in the file LICENSE.
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 * Fill the fileWidget box with the contents of the current directory
88 void restorePage::fillDirectory()
90 char modes[20], user[20], group[20], size[20], date[30];
93 POOLMEM *file = get_pool_memory(PM_FNAME);
94 POOLMEM *path = get_pool_memory(PM_FNAME);
97 m_console->write_dir("dir");
98 QList<QTreeWidgetItem *> treeItemList;
100 while (m_console->read() > 0) {
101 char *p = m_console->msg();
103 strip_trailing_junk(p);
104 if (*p == '$' || !*p) {
108 skip_nonspaces(&p); /* permissions */
110 bstrncpy(modes, l, sizeof(modes));
112 skip_nonspaces(&p); /* link count */
116 skip_nonspaces(&p); /* user */
119 bstrncpy(user, l, sizeof(user));
121 skip_nonspaces(&p); /* group */
123 bstrncpy(group, l, sizeof(group));
126 skip_nonspaces(&p); /* size */
128 bstrncpy(size, l, sizeof(size));
131 skip_nonspaces(&p); /* date/time */
135 bstrncpy(date, l, sizeof(date));
138 bstrncpy(marked, "*", sizeof(marked));
141 bstrncpy(marked, " ", sizeof(marked));
143 split_path_and_filename(p, &path, &pnl, &file, &fnl);
145 item << "" << file << modes << user << group << size << date;
146 if (item[1].endsWith("/")) {
147 addDirectory(item[1]);
149 QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
150 ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
151 if (strcmp(marked, "*") == 0) {
152 ti->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
153 ti->setData(0, Qt::UserRole, true);
155 ti->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
156 ti->setData(0, Qt::UserRole, false);
158 treeItemList.append(ti);
161 fileWidget->insertTopLevelItems(0, treeItemList);
162 for (int i=0; i<7; i++) {
163 fileWidget->resizeColumnToContents(i);
166 free_pool_memory(file);
167 free_pool_memory(path);
171 * Function called from fill directory when a directory is found to see if this
172 * directory exists in the directory pane and then add it to the directory pane
174 void restorePage::addDirectory(QString &newdirr)
176 QString newdir = newdirr;
177 QString fullpath = m_cwd + newdirr;
178 QRegExp regex("^/[a-z]:/$");
180 bool windrive = false;
182 if (mainWin->m_miscDebug) {
183 QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
186 Pmsg0(000, msg.toUtf8().data());
189 /* add unix '/' directory first */
190 if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
191 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
192 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.svg")));
195 item->setText(0, text.toUtf8().data());
196 if (mainWin->m_miscDebug) {
197 Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
199 m_dirPaths.insert(text, item);
200 m_dirTreeItems.insert(item, text);
203 if (regex.indexIn(fullpath,0) == 0) {
204 /* this is a windows drive */
205 if (mainWin->m_miscDebug) {
206 Pmsg0(000, "Need to do windows \"letter\":/\n");
208 fullpath.replace(0,1,"");
212 /* is it already existent ?? */
213 if (!m_dirPaths.contains(fullpath)) {
214 QTreeWidgetItem *item = NULL;
216 /* this is the base widget */
217 item = new QTreeWidgetItem(directoryWidget);
218 item->setText(0, fullpath.toUtf8().data());
219 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.svg")));
221 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
223 /* new directories to add */
224 item = new QTreeWidgetItem(parent);
225 item->setText(0, newdir.toUtf8().data());
226 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.svg")));
227 directoryWidget->expandItem(parent);
230 if (mainWin->m_miscDebug) {
231 QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
234 Pmsg0(000, msg.toUtf8().data());
238 /* insert into both forward and reverse hash */
240 if (mainWin->m_miscDebug) {
241 Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
243 m_dirPaths.insert(fullpath, item);
244 m_dirTreeItems.insert(item, fullpath);
250 * Executed when the tree item in the directory pane is changed. This will
251 * allow us to populate the file pane and make this the cwd.
253 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
254 QTreeWidgetItem * /*previousitem*/)
256 QString fullpath = m_dirTreeItems.value(currentitem);
258 cwd(fullpath.toUtf8().data());
263 void restorePage::okButtonPushed()
266 m_console->write("done");
267 m_console->notify(true);
270 mainWin->resetFocus();
274 void restorePage::cancelButtonPushed()
277 m_console->write("quit");
278 m_console->displayToPrompt();
279 mainWin->set_status("Canceled");
281 m_console->notify(true);
282 mainWin->resetFocus();
285 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
288 if (column == 0) { /* mark/unmark */
289 if (item->data(0, Qt::UserRole).toBool()) {
290 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
291 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
292 item->setData(0, Qt::UserRole, false);
294 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
295 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
296 item->setData(0, Qt::UserRole, true);
298 m_console->write_dir(cmd);
299 if (m_console->read() > 0) {
300 strip_trailing_junk(m_console->msg());
301 statusLine->setText(m_console->msg());
303 m_console->displayToPrompt();
307 * Double clicking other than column 0 means to decend into
308 * the directory -- or nothing if it is not a directory.
310 if (item->text(1).endsWith("/")) {
311 QString fullpath = m_cwd + item->text(1);
312 /* check for fullpath = "/c:/" */
313 QRegExp regex("^/[a-z]:/");
314 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
315 fullpath.replace(0,1,"");
316 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
318 directoryWidget->setCurrentItem(item);
320 QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
323 Pmsg0(000, msg.toUtf8().data());
329 * If up button pushed, making the parent tree widget current will call fill
332 void restorePage::upButtonPushed()
335 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
337 directoryWidget->setCurrentItem(item);
342 * Mark selected items
344 void restorePage::markButtonPushed()
346 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
347 QTreeWidgetItem *item;
349 foreach (item, treeItemList) {
350 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
351 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
352 m_console->write_dir(cmd);
353 if (m_console->read() > 0) {
354 strip_trailing_junk(m_console->msg());
355 statusLine->setText(m_console->msg());
357 Dmsg1(100, "cmd=%s\n", cmd);
358 m_console->discardToPrompt();
363 * Unmark selected items
365 void restorePage::unmarkButtonPushed()
367 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
368 QTreeWidgetItem *item;
370 foreach (item, treeItemList) {
371 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
372 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
373 m_console->write_dir(cmd);
374 if (m_console->read() > 0) {
375 strip_trailing_junk(m_console->msg());
376 statusLine->setText(m_console->msg());
378 Dmsg1(100, "cmd=%s\n", cmd);
379 m_console->discardToPrompt();
384 * Change current working directory
386 bool restorePage::cwd(const char *dir)
389 char cd_cmd[MAXSTRING];
391 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
392 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
393 m_console->write_dir(cd_cmd);
395 if ((stat = m_console->read()) > 0) {
396 m_cwd = m_console->msg();
397 lineEdit->insert(m_cwd);
398 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
400 Dmsg1(000, "stat=%d\n", stat);
401 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
403 m_console->discardToPrompt();
404 return true; /* ***FIXME*** return real status */
408 * Return cwd when in tree restore mode
410 char *restorePage::get_cwd()
413 m_console->write_dir(".pwd");
414 Dmsg0(100, "send: .pwd\n");
415 if ((stat = m_console->read()) > 0) {
416 m_cwd = m_console->msg();
417 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
419 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
420 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
422 m_console->discardToPrompt();
423 return m_cwd.toUtf8().data();