]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/restore/restore.cpp
Lots of icon work. Attempting using .svg files directory. It works in my
[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    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
49    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png")));
50
51    m_console->notify(false);          /* this should already be off */
52    m_closeable = true;
53
54    connect(fileWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), 
55            this, SLOT(fileDoubleClicked(QTreeWidgetItem *, int)));
56    connect(directoryWidget, SIGNAL(
57            currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
58            this, SLOT(directoryItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
59    connect(upButton, SIGNAL(pressed()), this, SLOT(upButtonPushed()));
60    connect(markButton, SIGNAL(pressed()), this, SLOT(markButtonPushed()));
61    connect(unmarkButton, SIGNAL(pressed()), this, SLOT(unmarkButtonPushed()));
62    connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed()));
63    connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed()));
64    setFont(m_console->get_font());
65    m_console->displayToPrompt();
66
67    titles << "Mark" << "File" << "Mode" << "User" << "Group" << "Size" << "Date";
68    fileWidget->setHeaderLabels(titles);
69
70    get_cwd();
71
72    fillDirectory();
73    dockPage();
74    setCurrent();
75    this->show();
76 }
77
78 /*
79  * Fill the fileWidget box with the contents of the current directory
80  */
81 void restorePage::fillDirectory()
82 {
83    char modes[20], user[20], group[20], size[20], date[30];
84    char marked[10];
85    int pnl, fnl;
86    POOLMEM *file = get_pool_memory(PM_FNAME);
87    POOLMEM *path = get_pool_memory(PM_FNAME);
88
89    fileWidget->clear();
90    m_console->write_dir("dir");
91    QList<QTreeWidgetItem *> treeItemList;
92    QStringList item;
93    while (m_console->read() > 0) {
94       char *p = m_console->msg();
95       char *l;
96       strip_trailing_junk(p);
97       if (*p == '$' || !*p) {
98          continue;
99       }
100       l = p;
101       skip_nonspaces(&p);             /* permissions */
102       *p++ = 0;
103       bstrncpy(modes, l, sizeof(modes));
104       skip_spaces(&p);
105       skip_nonspaces(&p);             /* link count */
106       *p++ = 0;
107       skip_spaces(&p);
108       l = p;
109       skip_nonspaces(&p);             /* user */
110       *p++ = 0;
111       skip_spaces(&p);
112       bstrncpy(user, l, sizeof(user));
113       l = p;
114       skip_nonspaces(&p);             /* group */
115       *p++ = 0;
116       bstrncpy(group, l, sizeof(group));
117       skip_spaces(&p);
118       l = p;
119       skip_nonspaces(&p);             /* size */
120       *p++ = 0;
121       bstrncpy(size, l, sizeof(size));
122       skip_spaces(&p);
123       l = p;
124       skip_nonspaces(&p);             /* date/time */
125       skip_spaces(&p);
126       skip_nonspaces(&p);
127       *p++ = 0;
128       bstrncpy(date, l, sizeof(date));
129       skip_spaces(&p);
130       if (*p == '*') {
131          bstrncpy(marked, "*", sizeof(marked));
132          p++;
133       } else {
134          bstrncpy(marked, " ", sizeof(marked));
135       }
136       split_path_and_filename(p, &path, &pnl, &file, &fnl);
137       item.clear();
138       item << "" << file << modes << user << group << size << date;
139       if (item[1].endsWith("/")) {
140          addDirectory(item[1]);
141       }
142       QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
143       ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
144       if (strcmp(marked, "*") == 0) {
145          ti->setIcon(0,QIcon(QString::fromUtf8(":images/check.png")));
146       } else {
147          ti->setIcon(0,QIcon(QString::fromUtf8(":images/unchecked.png")));
148       }
149       treeItemList.append(ti);
150    }
151    fileWidget->clear();
152    fileWidget->insertTopLevelItems(0, treeItemList);
153    for (int i=0; i<7; i++) {
154       fileWidget->resizeColumnToContents(i);
155    }
156
157    free_pool_memory(file);
158    free_pool_memory(path);
159 }
160
161 /*
162  * Function called from fill directory when a directory is found to see if this
163  * directory exists in the directory pane and then add it to the directory pane
164  */
165 void restorePage::addDirectory(QString &newdirr)
166 {
167    QString newdir = newdirr;
168    QString fullpath = m_cwd + newdirr;
169    QRegExp regex("^/[a-z]:/$");
170    bool ok = true;
171    bool windrive = false;
172
173    if (mainWin->m_miscDebug) {
174       QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
175                     .arg(m_cwd)
176                     .arg(newdir);
177       Pmsg0(000, msg.toUtf8().data());
178    }
179
180    /* add unix '/' directory first */
181    if (m_dirPaths.empty() && (regex.indexIn(fullpath,0) == -1)) {
182       QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget);
183       QString text("/");
184       item->setText(0, text.toUtf8().data());
185       if (mainWin->m_miscDebug) {
186          Pmsg1(000, "Pre Inserting %s\n",text.toUtf8().data());
187       }
188       m_dirPaths.insert(text, item);
189       m_dirTreeItems.insert(item, text);
190    }
191
192    if (regex.indexIn(fullpath,0) == 0) {
193       /* this is a windows drive */
194       if (mainWin->m_miscDebug) {
195          printf("Need to do windows \"letter\":/\n");
196       }
197       fullpath.replace(0,1,"");
198       windrive = true;
199    }
200  
201    /* is it already existent ?? */
202    if (!m_dirPaths.contains(fullpath)) {
203       QTreeWidgetItem *item = NULL;
204       if (windrive) {
205          /* this is the base widget */
206          item = new QTreeWidgetItem(directoryWidget);
207          item->setText(0, fullpath.toUtf8().data());
208       } else {
209          QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
210          if (parent) {
211             /* new directories to add */
212             item = new QTreeWidgetItem(parent);
213             item->setText(0, newdir.toUtf8().data());
214             directoryWidget->expandItem(parent);
215          } else {
216             ok = false;
217             if (mainWin->m_miscDebug) {
218                QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
219                     .arg(m_cwd)
220                     .arg(newdir);
221                Pmsg0(000, msg.toUtf8().data());
222             }
223          }
224       }
225       /* insert into both forward and reverse hash */
226       if (ok) {
227          if (mainWin->m_miscDebug) {
228             Pmsg1(000, "Inserting %s\n",fullpath.toUtf8().data());
229          }
230          m_dirPaths.insert(fullpath, item);
231          m_dirTreeItems.insert(item, fullpath);
232       }
233    }
234 }
235
236 /*
237  * Executed when the tree item in the directory pane is changed.  This will
238  * allow us to populate the file pane and make this the cwd.
239  */
240 void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem,
241                                          QTreeWidgetItem * /*previousitem*/)
242 {
243    QString fullpath = m_dirTreeItems.value(currentitem);
244    if (fullpath != ""){
245       cwd(fullpath.toUtf8().data());
246       fillDirectory();
247    }
248 }
249
250 void restorePage::okButtonPushed()
251 {
252    this->hide();
253    m_console->write("done");
254    m_console->notify(true);
255    setConsoleCurrent();
256    closeStackPage();
257    mainWin->resetFocus();
258 }
259
260
261 void restorePage::cancelButtonPushed()
262 {
263    this->hide();
264    m_console->write("quit");
265    m_console->displayToPrompt();
266    mainWin->set_status("Canceled");
267    closeStackPage();
268    m_console->notify(true);
269    mainWin->resetFocus();
270 }
271
272 void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column)
273 {
274    char cmd[1000];
275    if (column == 0) {                 /* mark/unmark */
276       if (item->text(0) == "*") {
277          bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
278          item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
279       } else {
280          bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
281          item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
282       }
283       m_console->write_dir(cmd);
284       if (m_console->read() > 0) {
285          strip_trailing_junk(m_console->msg());
286          statusLine->setText(m_console->msg());
287       }
288       m_console->displayToPrompt();
289       return;
290    }    
291    /* 
292     * Double clicking other than column 0 means to decend into
293     *  the directory -- or nothing if it is not a directory.
294     */
295    if (item->text(1).endsWith("/")) {
296       QString fullpath = m_cwd + item->text(1);
297       /* check for fullpath = "/c:/" */
298       QRegExp regex("^/[a-z]:/");
299       if (regex.indexIn(fullpath,0) == 0)  /* remove leading '/' */
300          fullpath.replace(0,1,"");
301       QTreeWidgetItem *item = m_dirPaths.value(fullpath);
302       if (item) {
303          directoryWidget->setCurrentItem(item);
304       } else {
305          QString msg = QString("DoubleClick else of item column %1 fullpath %2\n")
306               .arg(column,10)
307               .arg(fullpath);
308          Pmsg0(000, msg.toUtf8().data());
309       }
310    }
311 }
312
313 /*
314  * If up button pushed, making the parent tree widget current will call fill
315  * directory.
316  */
317 void restorePage::upButtonPushed()
318 {
319    cwd("..");
320    QTreeWidgetItem *item = m_dirPaths.value(m_cwd);
321    if (item) {
322       directoryWidget->setCurrentItem(item);
323    }
324 }
325
326 /*
327  * Mark selected items
328  */
329 void restorePage::markButtonPushed()
330 {
331    QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
332    QTreeWidgetItem *item;
333    char cmd[1000];
334    foreach (item, treeItemList) {
335       bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
336       item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png")));
337       m_console->write_dir(cmd);
338       if (m_console->read() > 0) {
339          strip_trailing_junk(m_console->msg());
340          statusLine->setText(m_console->msg());
341       }
342       Dmsg1(100, "cmd=%s\n", cmd);
343       m_console->discardToPrompt();
344    }
345 }
346
347 /*
348  * Unmark selected items
349  */
350 void restorePage::unmarkButtonPushed()
351 {
352    QList<QTreeWidgetItem *> treeItemList = fileWidget->selectedItems();
353    QTreeWidgetItem *item;
354    char cmd[1000];
355    foreach (item, treeItemList) {
356       bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
357       item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png")));
358       m_console->write_dir(cmd);
359       if (m_console->read() > 0) {
360          strip_trailing_junk(m_console->msg());
361          statusLine->setText(m_console->msg());
362       }
363       Dmsg1(100, "cmd=%s\n", cmd);
364       m_console->discardToPrompt();
365    }
366 }
367
368 /*
369  * Change current working directory 
370  */
371 bool restorePage::cwd(const char *dir)
372 {
373    int stat;
374    char cd_cmd[MAXSTRING];
375
376    bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
377    Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
378    m_console->write_dir(cd_cmd);
379    lineEdit->clear();
380    if ((stat = m_console->read()) > 0) {
381       m_cwd = m_console->msg();
382       lineEdit->insert(m_cwd);
383       Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
384    } else {
385       Dmsg1(000, "stat=%d\n", stat);
386       QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
387    }
388    m_console->discardToPrompt();
389    return true;  /* ***FIXME*** return real status */
390 }
391
392 /*
393  * Return cwd when in tree restore mode 
394  */
395 char *restorePage::get_cwd()
396 {
397    int stat;
398    m_console->write_dir(".pwd");
399    Dmsg0(100, "send: .pwd\n");
400    if ((stat = m_console->read()) > 0) {
401       m_cwd = m_console->msg();
402       Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
403    } else {
404       Dmsg1(000, "Something went wrong read stat=%d\n", stat);
405       QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
406    }
407    m_console->discardToPrompt(); 
408    return m_cwd.toUtf8().data();
409 }