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]:/$");
164 //printf("In addDirectory cwd \"%s\" newdir \"%s\"\n", m_cwd.toUtf8().data(),
165 //newdir.toUtf8().data());
167 /* add unix '/' directory first */
168 if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
169 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
171 item->setText(0, text.toUtf8().data());
172 //printf("Pre Inserting %s\n",text.toUtf8().data());
173 m_dirPaths.insert(text, item);
174 m_dirTreeItems.insert(item, text);
177 if (regex.indexIn(fullpath,0) == 0) {
178 /* this is a windows drive */
179 //printf("Need to do windows c:/\n");
180 fullpath.replace(0,1,"");
183 /* is it already existent ?? */
184 if (!m_dirPaths.contains(fullpath)) {
185 QTreeWidgetItem *item = NULL;
186 if (m_dirPaths.empty()) {
187 /* this is the base widget */
188 item = new QTreeWidgetItem(directoryWidget);
189 item->setText(0, fullpath.toUtf8().data());
191 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
193 /* new directories to add */
194 item = new QTreeWidgetItem(parent);
195 item->setText(0, newdir.toUtf8().data());
196 directoryWidget->expandItem(parent);
199 //printf("In else of if parent cwd \"%s\" newdir \"%s\"\n",
200 //m_cwd.toUtf8().data() ,newdir.toUtf8().data());
203 /* insert into both forward and reverse hash */
205 //printf("Inserting %s\n",fullpath.toUtf8().data());
206 m_dirPaths.insert(fullpath, item);
207 m_dirTreeItems.insert(item, fullpath);
213 * Executed when the tree item in the directory pane is changed. This will
214 * allow us to populate the file pane and make this the cwd.
216 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
217 QTreeWidgetItem * /*previousitem*/)
219 QString fullpath = m_dirTreeItems.value(currentitem);
221 cwd(fullpath.toUtf8().data());
226 void restorePage::okButtonPushed()
229 m_console->write("done");
230 m_console->notify(true);
232 mainWin->resetFocus();
236 void restorePage::cancelButtonPushed()
239 m_console->write("quit");
240 m_console->displayToPrompt();
241 mainWin->set_status("Canceled");
243 m_console->notify(true);
244 mainWin->resetFocus();
247 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
250 if (column == 0) { /* mark/unmark */
251 if (item->text(0) == "*") {
252 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
253 item->setText(0, " ");
255 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
256 item->setText(0, "*");
258 m_console->write_dir(cmd);
259 if (m_console->read() > 0) {
260 strip_trailing_junk(m_console->msg());
261 statusLine->setText(m_console->msg());
263 m_console->displayToPrompt();
267 * Double clicking other than column 0 means to decend into
268 * the directory -- or nothing if it is not a directory.
270 if (item->text(1).endsWith("/")) {
271 QString fullpath = m_cwd + item->text(1);
272 /* check for fullpath = "/c:/" */
273 QRegExp regex("^/[a-z]:/");
274 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
275 fullpath.replace(0,1,"");
276 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
278 directoryWidget->setCurrentItem(item);
280 /* FIXME ***** Create an error log */
281 //printf("DoubleClick else of item column %i fullpath %s\n", column, fullpath.toUtf8().data());
287 * If up button pushed, making the parent tree widget current will call fill
290 void restorePage::upButtonPushed()
293 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
295 directoryWidget->setCurrentItem(item);
300 * Mark selected items
302 void restorePage::markButtonPushed()
304 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
305 QTreeWidgetItem *item;
307 foreach (item, treeItemList) {
308 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
309 item->setText(0, "*");
310 m_console->write_dir(cmd);
311 if (m_console->read() > 0) {
312 strip_trailing_junk(m_console->msg());
313 statusLine->setText(m_console->msg());
315 Dmsg1(100, "cmd=%s\n", cmd);
316 m_console->discardToPrompt();
321 * Unmark selected items
323 void restorePage::unmarkButtonPushed()
325 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
326 QTreeWidgetItem *item;
328 foreach (item, treeItemList) {
329 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
330 item->setText(0, " ");
331 m_console->write_dir(cmd);
332 if (m_console->read() > 0) {
333 strip_trailing_junk(m_console->msg());
334 statusLine->setText(m_console->msg());
336 Dmsg1(100, "cmd=%s\n", cmd);
337 m_console->discardToPrompt();
342 * Change current working directory
344 bool restorePage::cwd(const char *dir)
347 char cd_cmd[MAXSTRING];
349 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
350 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
351 m_console->write_dir(cd_cmd);
353 if ((stat = m_console->read()) > 0) {
354 m_cwd = m_console->msg();
355 lineEdit->insert(m_cwd);
356 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
358 Dmsg1(000, "stat=%d\n", stat);
359 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
361 m_console->discardToPrompt();
362 return true; /* ***FIXME*** return real status */
366 * Return cwd when in tree restore mode
368 char *restorePage::get_cwd()
371 m_console->write_dir(".pwd");
372 Dmsg0(100, "send: .pwd\n");
373 if ((stat = m_console->read()) > 0) {
374 m_cwd = m_console->msg();
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", ".pwd command failed", QMessageBox::Ok);
379 Dmsg1(000, "stat=%d\n", stat);
381 m_console->discardToPrompt();
382 return m_cwd.toUtf8().data();