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()));
64 setFont(m_console->get_font());
65 m_console->displayToPrompt();
67 titles << "Mark" << "File" << "Mode" << "User" << "Group" << "Size" << "Date";
68 fileWidget->setHeaderLabels(titles);
79 * Fill the fileWidget box with the contents of the current directory
81 void restorePage::fillDirectory()
83 char modes[20], user[20], group[20], size[20], date[30];
86 POOLMEM *file = get_pool_memory(PM_FNAME);
87 POOLMEM *path = get_pool_memory(PM_FNAME);
90 m_console->write_dir("dir");
91 QList<QTreeWidgetItem *> treeItemList;
93 while (m_console->read() > 0) {
94 char *p = m_console->msg();
96 strip_trailing_junk(p);
97 if (*p == '$' || !*p) {
101 skip_nonspaces(&p); /* permissions */
103 bstrncpy(modes, l, sizeof(modes));
105 skip_nonspaces(&p); /* link count */
109 skip_nonspaces(&p); /* user */
112 bstrncpy(user, l, sizeof(user));
114 skip_nonspaces(&p); /* group */
116 bstrncpy(group, l, sizeof(group));
119 skip_nonspaces(&p); /* size */
121 bstrncpy(size, l, sizeof(size));
124 skip_nonspaces(&p); /* date/time */
128 bstrncpy(date, l, sizeof(date));
131 bstrncpy(marked, "*", sizeof(marked));
134 bstrncpy(marked, " ", sizeof(marked));
136 split_path_and_filename(p, &path, &pnl, &file, &fnl);
138 item << "" << file << modes << user << group << size << date;
139 if (item[1].endsWith("/")) {
140 addDirectory(item[1]);
142 QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
143 ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
144 if (strcmp(marked, "*") == 0) {
145 ti->setIcon(0,QIcon(QString::fromUtf8(":images/check.png")));
147 ti->setIcon(0,QIcon(QString::fromUtf8(":images/unchecked.png")));
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]:/$");
171 bool windrive = false;
173 if (mainWin->m_miscDebug) {
174 QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
177 Pmsg0(000, msg.toUtf8().data());
180 /* add unix '/' directory first */
181 if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
182 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
184 item->setText(0, text.toUtf8().data());
185 if (mainWin->m_miscDebug) {
186 Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
188 m_dirPaths.insert(text, item);
189 m_dirTreeItems.insert(item, text);
192 if (regex.indexIn(fullpath,0) == 0) {
193 /* this is a windows drive */
194 if (mainWin->m_miscDebug) {
195 printf("Need to do windows \"letter\":/\n");
197 fullpath.replace(0,1,"");
201 /* is it already existent ?? */
202 if (!m_dirPaths.contains(fullpath)) {
203 QTreeWidgetItem *item = NULL;
205 /* this is the base widget */
206 item = new QTreeWidgetItem(directoryWidget);
207 item->setText(0, fullpath.toUtf8().data());
209 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
211 /* new directories to add */
212 item = new QTreeWidgetItem(parent);
213 item->setText(0, newdir.toUtf8().data());
214 directoryWidget->expandItem(parent);
217 if (mainWin->m_miscDebug) {
218 QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
221 Pmsg0(000, msg.toUtf8().data());
225 /* insert into both forward and reverse hash */
227 if (mainWin->m_miscDebug) {
228 Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
230 m_dirPaths.insert(fullpath, item);
231 m_dirTreeItems.insert(item, fullpath);
237 * Executed when the tree item in the directory pane is changed. This will
238 * allow us to populate the file pane and make this the cwd.
240 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
241 QTreeWidgetItem * /*previousitem*/)
243 QString fullpath = m_dirTreeItems.value(currentitem);
245 cwd(fullpath.toUtf8().data());
250 void restorePage::okButtonPushed()
253 m_console->write("done");
254 m_console->notify(true);
257 mainWin->resetFocus();
261 void restorePage::cancelButtonPushed()
264 m_console->write("quit");
265 m_console->displayToPrompt();
266 mainWin->set_status("Canceled");
268 m_console->notify(true);
269 mainWin->resetFocus();
272 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
275 if (column == 0) { /* mark/unmark */
276 if (item->text(0) == "*") {
277 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
278 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
280 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
281 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
283 m_console->write_dir(cmd);
284 if (m_console->read() > 0) {
285 strip_trailing_junk(m_console->msg());
286 statusLine->setText(m_console->msg());
288 m_console->displayToPrompt();
292 * Double clicking other than column 0 means to decend into
293 * the directory -- or nothing if it is not a directory.
295 if (item->text(1).endsWith("/")) {
296 QString fullpath = m_cwd + item->text(1);
297 /* check for fullpath = "/c:/" */
298 QRegExp regex("^/[a-z]:/");
299 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
300 fullpath.replace(0,1,"");
301 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
303 directoryWidget->setCurrentItem(item);
305 QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
308 Pmsg0(000, msg.toUtf8().data());
314 * If up button pushed, making the parent tree widget current will call fill
317 void restorePage::upButtonPushed()
320 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
322 directoryWidget->setCurrentItem(item);
327 * Mark selected items
329 void restorePage::markButtonPushed()
331 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
332 QTreeWidgetItem *item;
334 foreach (item, treeItemList) {
335 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
336 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
337 m_console->write_dir(cmd);
338 if (m_console->read() > 0) {
339 strip_trailing_junk(m_console->msg());
340 statusLine->setText(m_console->msg());
342 Dmsg1(100, "cmd=%s\n", cmd);
343 m_console->discardToPrompt();
348 * Unmark selected items
350 void restorePage::unmarkButtonPushed()
352 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
353 QTreeWidgetItem *item;
355 foreach (item, treeItemList) {
356 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
357 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
358 m_console->write_dir(cmd);
359 if (m_console->read() > 0) {
360 strip_trailing_junk(m_console->msg());
361 statusLine->setText(m_console->msg());
363 Dmsg1(100, "cmd=%s\n", cmd);
364 m_console->discardToPrompt();
369 * Change current working directory
371 bool restorePage::cwd(const char *dir)
374 char cd_cmd[MAXSTRING];
376 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
377 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
378 m_console->write_dir(cd_cmd);
380 if ((stat = m_console->read()) > 0) {
381 m_cwd = m_console->msg();
382 lineEdit->insert(m_cwd);
383 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
385 Dmsg1(000, "stat=%d\n", stat);
386 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
388 m_console->discardToPrompt();
389 return true; /* ***FIXME*** return real status */
393 * Return cwd when in tree restore mode
395 char *restorePage::get_cwd()
398 m_console->write_dir(".pwd");
399 Dmsg0(100, "send: .pwd\n");
400 if ((stat = m_console->read()) > 0) {
401 m_cwd = m_console->msg();
402 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
404 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
405 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
407 m_console->discardToPrompt();
408 return m_cwd.toUtf8().data();