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 m_console->notify(false); /* this should already be off */
51 connect(fileWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
52 this, SLOT(fileDoubleClicked(QTreeWidgetItem *, int)));
53 connect(directoryWidget, SIGNAL(
54 currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
55 this, SLOT(directoryItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
56 connect(upButton, SIGNAL(pressed()), this, SLOT(upButtonPushed()));
57 connect(markButton, SIGNAL(pressed()), this, SLOT(markButtonPushed()));
58 connect(unmarkButton, SIGNAL(pressed()), this, SLOT(unmarkButtonPushed()));
59 connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed()));
60 connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed()));
61 setFont(m_console->get_font());
62 m_console->displayToPrompt();
64 titles << "Mark" << "File" << "Mode" << "User" << "Group" << "Size" << "Date";
65 fileWidget->setHeaderLabels(titles);
76 * Fill the fileWidget box with the contents of the current directory
78 void restorePage::fillDirectory()
80 char modes[20], user[20], group[20], size[20], date[30];
83 POOLMEM *file = get_pool_memory(PM_FNAME);
84 POOLMEM *path = get_pool_memory(PM_FNAME);
87 m_console->write_dir("dir");
88 QList<QTreeWidgetItem *> treeItemList;
90 while (m_console->read() > 0) {
91 char *p = m_console->msg();
93 strip_trailing_junk(p);
94 if (*p == '$' || !*p) {
98 skip_nonspaces(&p); /* permissions */
100 bstrncpy(modes, l, sizeof(modes));
102 skip_nonspaces(&p); /* link count */
106 skip_nonspaces(&p); /* user */
109 bstrncpy(user, l, sizeof(user));
111 skip_nonspaces(&p); /* group */
113 bstrncpy(group, l, sizeof(group));
116 skip_nonspaces(&p); /* size */
118 bstrncpy(size, l, sizeof(size));
121 skip_nonspaces(&p); /* date/time */
125 bstrncpy(date, l, sizeof(date));
128 bstrncpy(marked, "*", sizeof(marked));
131 bstrncpy(marked, " ", sizeof(marked));
133 split_path_and_filename(p, &path, &pnl, &file, &fnl);
135 item << marked << file << modes << user << group << size << date;
136 if (item[1].endsWith("/")) {
137 addDirectory(item[1]);
139 QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
140 ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
141 treeItemList.append(ti);
144 fileWidget->insertTopLevelItems(0, treeItemList);
145 for (int i=0; i<7; i++) {
146 fileWidget->resizeColumnToContents(i);
149 free_pool_memory(file);
150 free_pool_memory(path);
154 * Function called from fill directory when a directory is found to see if this
155 * directory exists in the directory pane and then add it to the directory pane
157 void restorePage::addDirectory(QString &newdirr)
159 QString newdir = newdirr;
160 QString fullpath = m_cwd + newdirr;
161 QRegExp regex("^/[a-z]:/$");
163 bool windrive = false;
165 if (mainWin->m_miscDebug) {
166 QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
169 Pmsg0(000, msg.toUtf8().data());
172 /* add unix '/' directory first */
173 if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
174 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
176 item->setText(0, text.toUtf8().data());
177 if (mainWin->m_miscDebug) {
178 Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
180 m_dirPaths.insert(text, item);
181 m_dirTreeItems.insert(item, text);
184 if (regex.indexIn(fullpath,0) == 0) {
185 /* this is a windows drive */
186 if (mainWin->m_miscDebug) {
187 printf("Need to do windows \"letter\":/\n");
189 fullpath.replace(0,1,"");
193 /* is it already existent ?? */
194 if (!m_dirPaths.contains(fullpath)) {
195 QTreeWidgetItem *item = NULL;
197 /* this is the base widget */
198 item = new QTreeWidgetItem(directoryWidget);
199 item->setText(0, fullpath.toUtf8().data());
201 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
203 /* new directories to add */
204 item = new QTreeWidgetItem(parent);
205 item->setText(0, newdir.toUtf8().data());
206 directoryWidget->expandItem(parent);
209 if (mainWin->m_miscDebug) {
210 QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
213 Pmsg0(000, msg.toUtf8().data());
217 /* insert into both forward and reverse hash */
219 if (mainWin->m_miscDebug) {
220 Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
222 m_dirPaths.insert(fullpath, item);
223 m_dirTreeItems.insert(item, fullpath);
229 * Executed when the tree item in the directory pane is changed. This will
230 * allow us to populate the file pane and make this the cwd.
232 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
233 QTreeWidgetItem * /*previousitem*/)
235 QString fullpath = m_dirTreeItems.value(currentitem);
237 cwd(fullpath.toUtf8().data());
242 void restorePage::okButtonPushed()
245 m_console->write("done");
246 m_console->notify(true);
249 mainWin->resetFocus();
253 void restorePage::cancelButtonPushed()
256 m_console->write("quit");
257 m_console->displayToPrompt();
258 mainWin->set_status("Canceled");
260 m_console->notify(true);
261 mainWin->resetFocus();
264 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
267 if (column == 0) { /* mark/unmark */
268 if (item->text(0) == "*") {
269 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
270 item->setText(0, " ");
272 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
273 item->setText(0, "*");
275 m_console->write_dir(cmd);
276 if (m_console->read() > 0) {
277 strip_trailing_junk(m_console->msg());
278 statusLine->setText(m_console->msg());
280 m_console->displayToPrompt();
284 * Double clicking other than column 0 means to decend into
285 * the directory -- or nothing if it is not a directory.
287 if (item->text(1).endsWith("/")) {
288 QString fullpath = m_cwd + item->text(1);
289 /* check for fullpath = "/c:/" */
290 QRegExp regex("^/[a-z]:/");
291 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
292 fullpath.replace(0,1,"");
293 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
295 directoryWidget->setCurrentItem(item);
297 QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
300 Pmsg0(000, msg.toUtf8().data());
306 * If up button pushed, making the parent tree widget current will call fill
309 void restorePage::upButtonPushed()
312 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
314 directoryWidget->setCurrentItem(item);
319 * Mark selected items
321 void restorePage::markButtonPushed()
323 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
324 QTreeWidgetItem *item;
326 foreach (item, treeItemList) {
327 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
328 item->setText(0, "*");
329 m_console->write_dir(cmd);
330 if (m_console->read() > 0) {
331 strip_trailing_junk(m_console->msg());
332 statusLine->setText(m_console->msg());
334 Dmsg1(100, "cmd=%s\n", cmd);
335 m_console->discardToPrompt();
340 * Unmark selected items
342 void restorePage::unmarkButtonPushed()
344 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
345 QTreeWidgetItem *item;
347 foreach (item, treeItemList) {
348 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
349 item->setText(0, " ");
350 m_console->write_dir(cmd);
351 if (m_console->read() > 0) {
352 strip_trailing_junk(m_console->msg());
353 statusLine->setText(m_console->msg());
355 Dmsg1(100, "cmd=%s\n", cmd);
356 m_console->discardToPrompt();
361 * Change current working directory
363 bool restorePage::cwd(const char *dir)
366 char cd_cmd[MAXSTRING];
368 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
369 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
370 m_console->write_dir(cd_cmd);
372 if ((stat = m_console->read()) > 0) {
373 m_cwd = m_console->msg();
374 lineEdit->insert(m_cwd);
375 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
377 Dmsg1(000, "stat=%d\n", stat);
378 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
380 m_console->discardToPrompt();
381 return true; /* ***FIXME*** return real status */
385 * Return cwd when in tree restore mode
387 char *restorePage::get_cwd()
390 m_console->write_dir(".pwd");
391 Dmsg0(100, "send: .pwd\n");
392 if ((stat = m_console->read()) > 0) {
393 m_cwd = m_console->msg();
394 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
396 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
397 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
399 m_console->discardToPrompt();
400 return m_cwd.toUtf8().data();