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 mainWin->set_status("Canceled");
242 m_console->notify(true);
243 mainWin->resetFocus();
246 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
249 if (column == 0) { /* mark/unmark */
250 if (item->text(0) == "*") {
251 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
252 item->setText(0, " ");
254 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
255 item->setText(0, "*");
257 m_console->write_dir(cmd);
258 if (m_console->read() > 0) {
259 strip_trailing_junk(m_console->msg());
260 statusLine->setText(m_console->msg());
262 m_console->displayToPrompt();
266 * Double clicking other than column 0 means to decend into
267 * the directory -- or nothing if it is not a directory.
269 if (item->text(1).endsWith("/")) {
270 QString fullpath = m_cwd + item->text(1);
271 /* check for fullpath = "/c:/" */
272 QRegExp regex("^/[a-z]:/");
273 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
274 fullpath.replace(0,1,"");
275 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
277 directoryWidget->setCurrentItem(item);
279 /* FIXME ***** Create an error log */
280 //printf("DoubleClick else of item column %i fullpath %s\n", column, fullpath.toUtf8().data());
286 * If up button pushed, making the parent tree widget current will call fill
289 void restorePage::upButtonPushed()
292 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
294 directoryWidget->setCurrentItem(item);
299 * Mark selected items
301 void restorePage::markButtonPushed()
303 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
304 QTreeWidgetItem *item;
306 foreach (item, treeItemList) {
307 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
308 item->setText(0, "*");
309 m_console->write_dir(cmd);
310 if (m_console->read() > 0) {
311 strip_trailing_junk(m_console->msg());
312 statusLine->setText(m_console->msg());
314 Dmsg1(100, "cmd=%s\n", cmd);
315 m_console->discardToPrompt();
320 * Unmark selected items
322 void restorePage::unmarkButtonPushed()
324 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
325 QTreeWidgetItem *item;
327 foreach (item, treeItemList) {
328 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
329 item->setText(0, " ");
330 m_console->write_dir(cmd);
331 if (m_console->read() > 0) {
332 strip_trailing_junk(m_console->msg());
333 statusLine->setText(m_console->msg());
335 Dmsg1(100, "cmd=%s\n", cmd);
336 m_console->discardToPrompt();
341 * Change current working directory
343 bool restorePage::cwd(const char *dir)
346 char cd_cmd[MAXSTRING];
348 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
349 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
350 m_console->write_dir(cd_cmd);
352 if ((stat = m_console->read()) > 0) {
353 m_cwd = m_console->msg();
354 lineEdit->insert(m_cwd);
355 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
357 Dmsg1(000, "stat=%d\n", stat);
358 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
360 m_console->discardToPrompt();
361 return true; /* ***FIXME*** return real status */
365 * Return cwd when in tree restore mode
367 char *restorePage::get_cwd()
370 m_console->write_dir(".pwd");
371 Dmsg0(100, "send: .pwd\n");
372 if ((stat = m_console->read()) > 0) {
373 m_cwd = m_console->msg();
374 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
376 Dmsg1(000, "stat=%d\n", stat);
377 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
378 Dmsg1(000, "stat=%d\n", stat);
380 m_console->discardToPrompt();
381 return m_cwd.toUtf8().data();