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 //printf("In addDirectory cwd \"%s\" newdir \"%s\"\n", m_cwd.toUtf8().data(),
166 //newdir.toUtf8().data());
168 /* add unix '/' directory first */
169 if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
170 QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
172 item->setText(0, text.toUtf8().data());
173 //printf("Pre Inserting %s\n",text.toUtf8().data());
174 m_dirPaths.insert(text, item);
175 m_dirTreeItems.insert(item, text);
178 if (regex.indexIn(fullpath,0) == 0) {
179 /* this is a windows drive */
180 //printf("Need to do windows \"letter\":/\n");
181 fullpath.replace(0,1,"");
185 /* is it already existent ?? */
186 if (!m_dirPaths.contains(fullpath)) {
187 QTreeWidgetItem *item = NULL;
189 /* this is the base widget */
190 item = new QTreeWidgetItem(directoryWidget);
191 item->setText(0, fullpath.toUtf8().data());
193 QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
195 /* new directories to add */
196 item = new QTreeWidgetItem(parent);
197 item->setText(0, newdir.toUtf8().data());
198 directoryWidget->expandItem(parent);
201 //printf("In else of if parent cwd \"%s\" newdir \"%s\"\n",
202 //m_cwd.toUtf8().data() ,newdir.toUtf8().data());
205 /* insert into both forward and reverse hash */
207 //printf("Inserting %s\n",fullpath.toUtf8().data());
208 m_dirPaths.insert(fullpath, item);
209 m_dirTreeItems.insert(item, fullpath);
215 * Executed when the tree item in the directory pane is changed. This will
216 * allow us to populate the file pane and make this the cwd.
218 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
219 QTreeWidgetItem * /*previousitem*/)
221 QString fullpath = m_dirTreeItems.value(currentitem);
223 cwd(fullpath.toUtf8().data());
228 void restorePage::okButtonPushed()
231 m_console->write("done");
232 m_console->notify(true);
235 mainWin->resetFocus();
239 void restorePage::cancelButtonPushed()
242 m_console->write("quit");
243 m_console->displayToPrompt();
244 mainWin->set_status("Canceled");
246 m_console->notify(true);
247 mainWin->resetFocus();
250 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
253 if (column == 0) { /* mark/unmark */
254 if (item->text(0) == "*") {
255 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
256 item->setText(0, " ");
258 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
259 item->setText(0, "*");
261 m_console->write_dir(cmd);
262 if (m_console->read() > 0) {
263 strip_trailing_junk(m_console->msg());
264 statusLine->setText(m_console->msg());
266 m_console->displayToPrompt();
270 * Double clicking other than column 0 means to decend into
271 * the directory -- or nothing if it is not a directory.
273 if (item->text(1).endsWith("/")) {
274 QString fullpath = m_cwd + item->text(1);
275 /* check for fullpath = "/c:/" */
276 QRegExp regex("^/[a-z]:/");
277 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
278 fullpath.replace(0,1,"");
279 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
281 directoryWidget->setCurrentItem(item);
283 /* FIXME ***** Create an error log */
284 //printf("DoubleClick else of item column %i fullpath %s\n", column, fullpath.toUtf8().data());
290 * If up button pushed, making the parent tree widget current will call fill
293 void restorePage::upButtonPushed()
296 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
298 directoryWidget->setCurrentItem(item);
303 * Mark selected items
305 void restorePage::markButtonPushed()
307 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
308 QTreeWidgetItem *item;
310 foreach (item, treeItemList) {
311 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
312 item->setText(0, "*");
313 m_console->write_dir(cmd);
314 if (m_console->read() > 0) {
315 strip_trailing_junk(m_console->msg());
316 statusLine->setText(m_console->msg());
318 Dmsg1(100, "cmd=%s\n", cmd);
319 m_console->discardToPrompt();
324 * Unmark selected items
326 void restorePage::unmarkButtonPushed()
328 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
329 QTreeWidgetItem *item;
331 foreach (item, treeItemList) {
332 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
333 item->setText(0, " ");
334 m_console->write_dir(cmd);
335 if (m_console->read() > 0) {
336 strip_trailing_junk(m_console->msg());
337 statusLine->setText(m_console->msg());
339 Dmsg1(100, "cmd=%s\n", cmd);
340 m_console->discardToPrompt();
345 * Change current working directory
347 bool restorePage::cwd(const char *dir)
350 char cd_cmd[MAXSTRING];
352 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
353 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
354 m_console->write_dir(cd_cmd);
356 if ((stat = m_console->read()) > 0) {
357 m_cwd = m_console->msg();
358 lineEdit->insert(m_cwd);
359 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
361 Dmsg1(000, "stat=%d\n", stat);
362 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
364 m_console->discardToPrompt();
365 return true; /* ***FIXME*** return real status */
369 * Return cwd when in tree restore mode
371 char *restorePage::get_cwd()
374 m_console->write_dir(".pwd");
375 Dmsg0(100, "send: .pwd\n");
376 if ((stat = m_console->read()) > 0) {
377 m_cwd = m_console->msg();
378 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
380 Dmsg1(000, "Something went wrong read stat=%d\n", stat);
381 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
383 m_console->discardToPrompt();
384 return m_cwd.toUtf8().data();