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);
233 mainWin->resetFocus();
237 void restorePage::cancelButtonPushed()
240 m_console->write("quit");
241 m_console->displayToPrompt();
242 mainWin->set_status("Canceled");
244 m_console->notify(true);
245 mainWin->resetFocus();
248 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
251 if (column == 0) { /* mark/unmark */
252 if (item->text(0) == "*") {
253 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
254 item->setText(0, " ");
256 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
257 item->setText(0, "*");
259 m_console->write_dir(cmd);
260 if (m_console->read() > 0) {
261 strip_trailing_junk(m_console->msg());
262 statusLine->setText(m_console->msg());
264 m_console->displayToPrompt();
268 * Double clicking other than column 0 means to decend into
269 * the directory -- or nothing if it is not a directory.
271 if (item->text(1).endsWith("/")) {
272 QString fullpath = m_cwd + item->text(1);
273 /* check for fullpath = "/c:/" */
274 QRegExp regex("^/[a-z]:/");
275 if (regex.indexIn(fullpath,0) == 0) /* remove leading '/' */
276 fullpath.replace(0,1,"");
277 QTreeWidgetItem *item = m_dirPaths.value(fullpath);
279 directoryWidget->setCurrentItem(item);
281 /* FIXME ***** Create an error log */
282 //printf("DoubleClick else of item column %i fullpath %s\n", column, fullpath.toUtf8().data());
288 * If up button pushed, making the parent tree widget current will call fill
291 void restorePage::upButtonPushed()
294 QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
296 directoryWidget->setCurrentItem(item);
301 * Mark selected items
303 void restorePage::markButtonPushed()
305 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
306 QTreeWidgetItem *item;
308 foreach (item, treeItemList) {
309 bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
310 item->setText(0, "*");
311 m_console->write_dir(cmd);
312 if (m_console->read() > 0) {
313 strip_trailing_junk(m_console->msg());
314 statusLine->setText(m_console->msg());
316 Dmsg1(100, "cmd=%s\n", cmd);
317 m_console->discardToPrompt();
322 * Unmark selected items
324 void restorePage::unmarkButtonPushed()
326 QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
327 QTreeWidgetItem *item;
329 foreach (item, treeItemList) {
330 bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
331 item->setText(0, " ");
332 m_console->write_dir(cmd);
333 if (m_console->read() > 0) {
334 strip_trailing_junk(m_console->msg());
335 statusLine->setText(m_console->msg());
337 Dmsg1(100, "cmd=%s\n", cmd);
338 m_console->discardToPrompt();
343 * Change current working directory
345 bool restorePage::cwd(const char *dir)
348 char cd_cmd[MAXSTRING];
350 bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
351 Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
352 m_console->write_dir(cd_cmd);
354 if ((stat = m_console->read()) > 0) {
355 m_cwd = m_console->msg();
356 lineEdit->insert(m_cwd);
357 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
359 Dmsg1(000, "stat=%d\n", stat);
360 QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
362 m_console->discardToPrompt();
363 return true; /* ***FIXME*** return real status */
367 * Return cwd when in tree restore mode
369 char *restorePage::get_cwd()
372 m_console->write_dir(".pwd");
373 Dmsg0(100, "send: .pwd\n");
374 if ((stat = m_console->read()) > 0) {
375 m_cwd = m_console->msg();
376 Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
378 Dmsg1(000, "stat=%d\n", stat);
379 QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
380 Dmsg1(000, "stat=%d\n", stat);
382 m_console->discardToPrompt();
383 return m_cwd.toUtf8().data();