]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/restore/restore.cpp
This commit puts prefences for debuggin output and prefences for the joblist
[bacula/bacula] / bacula / src / qt-console / restore / restore.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
5
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.
12
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.
17
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
21    02110-1301, USA.
22
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.
27 */
28  
29 /*
30  *   Version $Id$
31  *
32  *  Restore Class 
33  *
34  *   Kern Sibbald, February MMVII
35  *
36  */ 
37
38 #include "bat.h"
39 #include "restore.h"
40
41 restorePage::restorePage()
42 {
43    QStringList titles;
44
45    setupUi(this);
46    m_name = "Restore Select";
47    pgInitialize();
48    m_console->notify(false);          /* this should already be off */
49    m_closeable = true;
50
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();
63
64    titles << "Mark" << "File" << "Mode" << "User" << "Group" << "Size" << "Date";
65    fileWidget->setHeaderLabels(titles);
66
67    get_cwd();
68
69    fillDirectory();
70    dockPage();
71    setCurrent();
72    this->show();
73 }
74
75 /*
76  * Fill the fileWidget box with the contents of the current directory
77  */
78 void restorePage::fillDirectory()
79 {
80    char modes[20], user[20], group[20], size[20], date[30];
81    char marked[10];
82    int pnl, fnl;
83    POOLMEM *file = get_pool_memory(PM_FNAME);
84    POOLMEM *path = get_pool_memory(PM_FNAME);
85
86    fileWidget->clear();
87    m_console->write_dir("dir");
88    QList<QTreeWidgetItem *> treeItemList;
89    QStringList item;
90    while (m_console->read() > 0) {
91       char *p = m_console->msg();
92       char *l;
93       strip_trailing_junk(p);
94       if (*p == '$' || !*p) {
95          continue;
96       }
97       l = p;
98       skip_nonspaces(&p);             /* permissions */
99       *p++ = 0;
100       bstrncpy(modes, l, sizeof(modes));
101       skip_spaces(&p);
102       skip_nonspaces(&p);             /* link count */
103       *p++ = 0;
104       skip_spaces(&p);
105       l = p;
106       skip_nonspaces(&p);             /* user */
107       *p++ = 0;
108       skip_spaces(&p);
109       bstrncpy(user, l, sizeof(user));
110       l = p;
111       skip_nonspaces(&p);             /* group */
112       *p++ = 0;
113       bstrncpy(group, l, sizeof(group));
114       skip_spaces(&p);
115       l = p;
116       skip_nonspaces(&p);             /* size */
117       *p++ = 0;
118       bstrncpy(size, l, sizeof(size));
119       skip_spaces(&p);
120       l = p;
121       skip_nonspaces(&p);             /* date/time */
122       skip_spaces(&p);
123       skip_nonspaces(&p);
124       *p++ = 0;
125       bstrncpy(date, l, sizeof(date));
126       skip_spaces(&p);
127       if (*p == '*') {
128          bstrncpy(marked, "*", sizeof(marked));
129          p++;
130       } else {
131          bstrncpy(marked, " ", sizeof(marked));
132       }
133       split_path_and_filename(p, &path, &pnl, &file, &fnl);
134       item.clear();
135       item << marked << file << modes << user << group << size << date;
136       if (item[1].endsWith("/")) {
137          addDirectory(item[1]);
138        }
139       QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
140       ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
141       treeItemList.append(ti);
142    }
143    fileWidget->clear();
144    fileWidget->insertTopLevelItems(0, treeItemList);
145    for (int i=0; i<7; i++) {
146       fileWidget->resizeColumnToContents(i);
147    }
148
149    free_pool_memory(file);
150    free_pool_memory(path);
151 }
152
153 /*
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
156  */
157 void restorePage::addDirectory(QString &newdirr)
158 {
159    QString newdir = newdirr;
160    QString fullpath = m_cwd + newdirr;
161    QRegExp regex("^/[a-z]:/$");
162    bool ok = true;
163    bool windrive = false;
164
165    if (mainWin->m_miscDebug) {
166       QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
167                     .arg(m_cwd)
168                     .arg(newdir);
169       Pmsg0(000, msg.toUtf8().data());
170    }
171
172    /* add unix '/' directory first */
173    if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
174       QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
175       QString text("/");
176       item->setText(0, text.toUtf8().data());
177       if (mainWin->m_miscDebug) {
178          Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
179       }
180       m_dirPaths.insert(text, item);
181       m_dirTreeItems.insert(item, text);
182    }
183
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");
188       }
189       fullpath.replace(0,1,"");
190       windrive = true;
191    }
192  
193    /* is it already existent ?? */
194    if (!m_dirPaths.contains(fullpath)) {
195       QTreeWidgetItem *item = NULL;
196       if (windrive) {
197          /* this is the base widget */
198          item = new QTreeWidgetItem(directoryWidget);
199          item->setText(0, fullpath.toUtf8().data());
200       } else {
201          QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
202          if (parent) {
203             /* new directories to add */
204             item = new QTreeWidgetItem(parent);
205             item->setText(0, newdir.toUtf8().data());
206             directoryWidget->expandItem(parent);
207          } else {
208             ok = false;
209             if (mainWin->m_miscDebug) {
210                QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
211                     .arg(m_cwd)
212                     .arg(newdir);
213                Pmsg0(000, msg.toUtf8().data());
214             }
215          }
216       }
217       /* insert into both forward and reverse hash */
218       if (ok) {
219          if (mainWin->m_miscDebug) {
220             Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
221          }
222          m_dirPaths.insert(fullpath, item);
223          m_dirTreeItems.insert(item, fullpath);
224       }
225    }
226 }
227
228 /*
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.
231  */
232 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
233                                          QTreeWidgetItem * /*previousitem*/)
234 {
235    QString fullpath = m_dirTreeItems.value(currentitem);
236    if (fullpath != ""){
237       cwd(fullpath.toUtf8().data());
238       fillDirectory();
239    }
240 }
241
242 void restorePage::okButtonPushed()
243 {
244    this->hide();
245    m_console->write("done");
246    m_console->notify(true);
247    setConsoleCurrent();
248    closeStackPage();
249    mainWin->resetFocus();
250 }
251
252
253 void restorePage::cancelButtonPushed()
254 {
255    this->hide();
256    m_console->write("quit");
257    m_console->displayToPrompt();
258    mainWin->set_status("Canceled");
259    closeStackPage();
260    m_console->notify(true);
261    mainWin->resetFocus();
262 }
263
264 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
265 {
266    char cmd[1000];
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, " ");
271       } else {
272          bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
273          item->setText(0, "*");
274       }
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());
279       }
280       m_console->displayToPrompt();
281       return;
282    }    
283    /* 
284     * Double clicking other than column 0 means to decend into
285     *  the directory -- or nothing if it is not a directory.
286     */
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);
294       if (item) {
295          directoryWidget->setCurrentItem(item);
296       } else {
297          QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
298               .arg(column,10)
299               .arg(fullpath);
300          Pmsg0(000, msg.toUtf8().data());
301       }
302    }
303 }
304
305 /*
306  * If up button pushed, making the parent tree widget current will call fill
307  * directory.
308  */
309 void restorePage::upButtonPushed()
310 {
311    cwd("..");
312    QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
313    if (item) {
314       directoryWidget->setCurrentItem(item);
315    }
316 }
317
318 /*
319  * Mark selected items
320  */
321 void restorePage::markButtonPushed()
322 {
323    QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
324    QTreeWidgetItem *item;
325    char cmd[1000];
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());
333       }
334       Dmsg1(100, "cmd=%s\n", cmd);
335       m_console->discardToPrompt();
336    }
337 }
338
339 /*
340  * Unmark selected items
341  */
342 void restorePage::unmarkButtonPushed()
343 {
344    QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
345    QTreeWidgetItem *item;
346    char cmd[1000];
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());
354       }
355       Dmsg1(100, "cmd=%s\n", cmd);
356       m_console->discardToPrompt();
357    }
358 }
359
360 /*
361  * Change current working directory 
362  */
363 bool restorePage::cwd(const char *dir)
364 {
365    int stat;
366    char cd_cmd[MAXSTRING];
367
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);
371    lineEdit->clear();
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());
376    } else {
377       Dmsg1(000, "stat=%d\n", stat);
378       QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
379    }
380    m_console->discardToPrompt();
381    return true;  /* ***FIXME*** return real status */
382 }
383
384 /*
385  * Return cwd when in tree restore mode 
386  */
387 char *restorePage::get_cwd()
388 {
389    int stat;
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());
395    } else {
396       Dmsg1(000, "Something went wrong read stat=%d\n", stat);
397       QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
398    }
399    m_console->discardToPrompt(); 
400    return m_cwd.toUtf8().data();
401 }