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")));
146 ti->setData(0, Qt::UserRole, true);
148 ti->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
149 ti->setData(0, Qt::UserRole, false);
151 treeItemList.append(ti);
154 fileWidget->insertTopLevelItems(0, treeItemList);
155 for (int i=0; i<7; i++) {
156 fileWidget->resizeColumnToContents(i);
159 free_pool_memory(file);
160 free_pool_memory(path);
164 * Function called from fill directory when a directory is found to see if this
165 * directory exists in the directory pane and then add it to the directory pane
167 void restorePage::addDirectory(QString &newdirr)
169 QString newdir = newdirr;
170 QString fullpath = m_cwd + newdirr;
171 QRegExp regex("^/[a-z]:/$");
173 bool windrive = false;
175 if (mainWin->m_miscDebug) {
176 QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
179 Pmsg0(000, msg.toUtf8().data());
182 /* add unix '/' directory first */
183 if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
184 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
185 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.svg")));
188 item->setText(0, text.toUtf8().data());
189 if (mainWin->m_miscDebug) {
190 Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
192 m_dirPaths.insert(text, item);
193 m_dirTreeItems.insert(item, text);
196 if (regex.indexIn(fullpath,0) == 0) {
197 /* this is a windows drive */
198 if (mainWin->m_miscDebug) {
199 Pmsg0(000, "Need to do windows \"letter\":/\n");
201 fullpath.replace(0,1,"");
205 /* is it already existent ?? */
206 if (!m_dirPaths.contains(fullpath)) {
207 QTreeWidgetItem *item = NULL;
209 /* this is the base widget */
210 item = new QTreeWidgetItem(directoryWidget);
211 item->setText(0, fullpath.toUtf8().data());
212 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.svg")));
214 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
216 /* new directories to add */
217 item = new QTreeWidgetItem(parent);
218 item->setText(0, newdir.toUtf8().data());
219 item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.svg")));
220 directoryWidget->expandItem(parent);
223 if (mainWin->m_miscDebug) {
224 QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
227 Pmsg0(000, msg.toUtf8().data());
231 /* insert into both forward and reverse hash */
233 if (mainWin->m_miscDebug) {
234 Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
236 m_dirPaths.insert(fullpath, item);
237 m_dirTreeItems.insert(item, fullpath);
243 * Executed when the tree item in the directory pane is changed. This will
244 * allow us to populate the file pane and make this the cwd.
246 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
247 QTreeWidgetItem * /*previousitem*/)
249 QString fullpath = m_dirTreeItems.value(currentitem);
251 cwd(fullpath.toUtf8().data());
256 void restorePage::okButtonPushed()
259 m_console->write("done");
260 m_console->notify(true);
263 mainWin->resetFocus();
267 void restorePage::cancelButtonPushed()
270 m_console->write("quit");
271 m_console->displayToPrompt();
272 mainWin->set_status("Canceled");
274 m_console->notify(true);
275 mainWin->resetFocus();
278 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
281 if (column == 0) { /* mark/unmark */
282 if (item->data(0, Qt::UserRole).toBool()) {
283 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
284 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
285 item->setData(0, Qt::UserRole, false);
287 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
288 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
289 item->setData(0, Qt::UserRole, true);
291 m_console->write_dir(cmd);
292 if (m_console->read() > 0) {
293 strip_trailing_junk(m_console->msg());
294 statusLine->setText(m_console->msg());
296 m_console->displayToPrompt();
300 * Double clicking other than column 0 means to decend into
301 * the directory -- or nothing if it is not a directory.
303 if (item->text(1).endsWith("/")) {
304 QString fullpath = m_cwd + item->text(1);
305 /* check for fullpath = "/c:/" */
306 QRegExp regex("^/[a-z]:/");
307 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
308 fullpath.replace(0,1,"");
309 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
311 directoryWidget->setCurrentItem(item);
313 QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
316 Pmsg0(000, msg.toUtf8().data());
322 * If up button pushed, making the parent tree widget current will call fill
325 void restorePage::upButtonPushed()
328 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
330 directoryWidget->setCurrentItem(item);
335 * Mark selected items
337 void restorePage::markButtonPushed()
339 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
340 QTreeWidgetItem *item;
342 foreach (item, treeItemList) {
343 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
344 item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
345 m_console->write_dir(cmd);
346 if (m_console->read() > 0) {
347 strip_trailing_junk(m_console->msg());
348 statusLine->setText(m_console->msg());
350 Dmsg1(100, "cmd=%s\n", cmd);
351 m_console->discardToPrompt();
356 * Unmark selected items
358 void restorePage::unmarkButtonPushed()
360 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
361 QTreeWidgetItem *item;
363 foreach (item, treeItemList) {
364 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
365 item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
366 m_console->write_dir(cmd);
367 if (m_console->read() > 0) {
368 strip_trailing_junk(m_console->msg());
369 statusLine->setText(m_console->msg());
371 Dmsg1(100, "cmd=%s\n", cmd);
372 m_console->discardToPrompt();
377 * Change current working directory
379 bool restorePage::cwd(const char *dir)
382 char cd_cmd[MAXSTRING];
384 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
385 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
386 m_console->write_dir(cd_cmd);
388 if ((stat = m_console->read()) > 0) {
389 m_cwd = m_console->msg();
390 lineEdit->insert(m_cwd);
391 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
393 Dmsg1(000, "stat=%d\n", stat);
394 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
396 m_console->discardToPrompt();
397 return true; /* ***FIXME*** return real status */
401 * Return cwd when in tree restore mode
403 char *restorePage::get_cwd()
406 m_console->write_dir(".pwd");
407 Dmsg0(100, "send: .pwd\n");
408 if ((stat = m_console->read()) > 0) {
409 m_cwd = m_console->msg();
410 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
412 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
413 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
415 m_console->discardToPrompt();
416 return m_cwd.toUtf8().data();