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(Console *console)
46 QTreeWidgetItem *parent = mainWin->getFromHash(console);
48 /* Make this a user configurable stdout msg *** FIXME ****/
49 printf("Error retrieving tree widget.");
54 m_console->notify(false); /* this should already be off */
57 connect(fileWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
58 this, SLOT(fileDoubleClicked(QTreeWidgetItem *, int)));
59 connect(directoryWidget, SIGNAL(
60 currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
61 this, SLOT(directoryItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
62 connect(upButton, SIGNAL(pressed()), this, SLOT(upButtonPushed()));
63 connect(markButton, SIGNAL(pressed()), this, SLOT(markButtonPushed()));
64 connect(unmarkButton, SIGNAL(pressed()), this, SLOT(unmarkButtonPushed()));
65 connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed()));
66 connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed()));
67 setFont(m_console->get_font());
68 m_console->displayToPrompt();
70 titles << "Mark" << "File" << "Mode" << "User" << "Group" << "Size" << "Date";
71 fileWidget->setHeaderLabels(titles);
84 * Fill the fileWidget box with the contents of the current directory
86 void restorePage::fillDirectory()
88 char modes[20], user[20], group[20], size[20], date[30];
91 POOLMEM *file = get_pool_memory(PM_FNAME);
92 POOLMEM *path = get_pool_memory(PM_FNAME);
95 m_console->write_dir("dir");
96 QList<QTreeWidgetItem *> treeItemList;
98 while (m_console->read() > 0) {
99 char *p = m_console->msg();
101 strip_trailing_junk(p);
102 if (*p == '$' || !*p) {
106 skip_nonspaces(&p); /* permissions */
108 bstrncpy(modes, l, sizeof(modes));
110 skip_nonspaces(&p); /* link count */
114 skip_nonspaces(&p); /* user */
117 bstrncpy(user, l, sizeof(user));
119 skip_nonspaces(&p); /* group */
121 bstrncpy(group, l, sizeof(group));
124 skip_nonspaces(&p); /* size */
126 bstrncpy(size, l, sizeof(size));
129 skip_nonspaces(&p); /* date/time */
133 bstrncpy(date, l, sizeof(date));
136 bstrncpy(marked, "*", sizeof(marked));
139 bstrncpy(marked, " ", sizeof(marked));
141 split_path_and_filename(p, &path, &pnl, &file, &fnl);
143 item << marked << file << modes << user << group << size << date;
144 if (item[1].endsWith("/")) {
145 addDirectory(item[1]);
147 QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
148 ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
149 treeItemList.append(ti);
152 fileWidget->insertTopLevelItems(0, treeItemList);
153 for (int i=0; i<7; i++) {
154 fileWidget->resizeColumnToContents(i);
157 free_pool_memory(file);
158 free_pool_memory(path);
162 * Function called from fill directory when a directory is found to see if this
163 * directory exists in the directory pane and then add it to the directory pane
165 void restorePage::addDirectory(QString &newdirr)
167 QString newdir = newdirr;
168 QString fullpath = m_cwd + newdirr;
169 QRegExp regex("^/[a-z]:/$");
172 //printf("In addDirectory cwd \"%s\" newdir \"%s\"\n", m_cwd.toUtf8().data(),
173 //newdir.toUtf8().data());
175 /* add unix '/' directory first */
176 if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
177 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
179 item->setText(0, text.toUtf8().data());
180 //printf("Pre Inserting %s\n",text.toUtf8().data());
181 m_dirPaths.insert(text, item);
182 m_dirTreeItems.insert(item, text);
185 if (regex.indexIn(fullpath,0) == 0) {
186 /* this is a windows drive */
187 //printf("Need to do windows c:/\n");
188 fullpath.replace(0,1,"");
191 /* is it already existent ?? */
192 if (!m_dirPaths.contains(fullpath)) {
193 QTreeWidgetItem *item = NULL;
194 if (m_dirPaths.empty()) {
195 /* this is the base widget */
196 item = new QTreeWidgetItem(directoryWidget);
197 item->setText(0, fullpath.toUtf8().data());
199 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
201 /* new directories to add */
202 item = new QTreeWidgetItem(parent);
203 item->setText(0, newdir.toUtf8().data());
204 directoryWidget->expandItem(parent);
207 //printf("In else of if parent cwd \"%s\" newdir \"%s\"\n",
208 //m_cwd.toUtf8().data() ,newdir.toUtf8().data());
211 /* insert into both forward and reverse hash */
213 //printf("Inserting %s\n",fullpath.toUtf8().data());
214 m_dirPaths.insert(fullpath, item);
215 m_dirTreeItems.insert(item, fullpath);
221 * Executed when the tree item in the directory pane is changed. This will
222 * allow us to populate the file pane and make this the cwd.
224 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
225 QTreeWidgetItem * /*previousitem*/)
227 QString fullpath = m_dirTreeItems.value(currentitem);
229 cwd(fullpath.toUtf8().data());
234 void restorePage::okButtonPushed()
237 m_console->write("done");
238 m_console->notify(true);
240 mainWin->resetFocus();
244 void restorePage::cancelButtonPushed()
247 m_console->write("quit");
248 mainWin->set_status("Canceled");
250 m_console->notify(true);
251 mainWin->resetFocus();
254 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
257 if (column == 0) { /* mark/unmark */
258 if (item->text(0) == "*") {
259 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
260 item->setText(0, " ");
262 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
263 item->setText(0, "*");
265 m_console->write_dir(cmd);
266 if (m_console->read() > 0) {
267 strip_trailing_junk(m_console->msg());
268 statusLine->setText(m_console->msg());
270 m_console->displayToPrompt();
274 * Double clicking other than column 0 means to decend into
275 * the directory -- or nothing if it is not a directory.
277 if (item->text(1).endsWith("/")) {
278 QString fullpath = m_cwd + item->text(1);
279 /* check for fullpath = "/c:/" */
280 QRegExp regex("^/[a-z]:/");
281 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
282 fullpath.replace(0,1,"");
283 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
285 directoryWidget->setCurrentItem(item);
287 /* FIXME ***** Create an error log */
288 //printf("DoubleClick else of item column %i fullpath %s\n", column, fullpath.toUtf8().data());
294 * If up button pushed, making the parent tree widget current will call fill
297 void restorePage::upButtonPushed()
300 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
302 directoryWidget->setCurrentItem(item);
307 * Mark selected items
309 void restorePage::markButtonPushed()
311 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
312 QTreeWidgetItem *item;
314 foreach (item, treeItemList) {
315 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
316 item->setText(0, "*");
317 m_console->write_dir(cmd);
318 if (m_console->read() > 0) {
319 strip_trailing_junk(m_console->msg());
320 statusLine->setText(m_console->msg());
322 Dmsg1(100, "cmd=%s\n", cmd);
323 m_console->discardToPrompt();
328 * Unmark selected items
330 void restorePage::unmarkButtonPushed()
332 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
333 QTreeWidgetItem *item;
335 foreach (item, treeItemList) {
336 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
337 item->setText(0, " ");
338 m_console->write_dir(cmd);
339 if (m_console->read() > 0) {
340 strip_trailing_junk(m_console->msg());
341 statusLine->setText(m_console->msg());
343 Dmsg1(100, "cmd=%s\n", cmd);
344 m_console->discardToPrompt();
349 * Change current working directory
351 bool restorePage::cwd(const char *dir)
354 char cd_cmd[MAXSTRING];
356 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
357 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
358 m_console->write_dir(cd_cmd);
360 if ((stat = m_console->read()) > 0) {
361 m_cwd = m_console->msg();
362 lineEdit->insert(m_cwd);
363 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
365 Dmsg1(000, "stat=%d\n", stat);
366 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
368 m_console->discardToPrompt();
369 return true; /* ***FIXME*** return real status */
373 * Return cwd when in tree restore mode
375 char *restorePage::get_cwd()
378 m_console->write_dir(".pwd");
379 Dmsg0(100, "send: .pwd\n");
380 if ((stat = m_console->read()) > 0) {
381 m_cwd = m_console->msg();
382 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
384 Dmsg1(000, "stat=%d\n", stat);
385 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
386 Dmsg1(000, "stat=%d\n", stat);
388 m_console->discardToPrompt();
389 return m_cwd.toUtf8().data();