summaryrefslogtreecommitdiff
authordrw <drw>2005-02-23 17:35:32 (UTC)
committer drw <drw>2005-02-23 17:35:32 (UTC)
commit9e2e6d962e1e2d3e5c17641d9a9b21a5906bd262 (patch) (unidiff)
treea0fc4cdf1afdb5a75377a61f738286da0ac27594
parent62010b750741307bf56d4db289dcf22f4a6eeb0d (diff)
downloadopie-9e2e6d962e1e2d3e5c17641d9a9b21a5906bd262.zip
opie-9e2e6d962e1e2d3e5c17641d9a9b21a5906bd262.tar.gz
opie-9e2e6d962e1e2d3e5c17641d9a9b21a5906bd262.tar.bz2
Disable full backup option for Opie 1.2, since it might not work correctly due to memory constraints
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/backup/backuprestore.cpp51
-rw-r--r--noncore/settings/backup/backuprestorebase.ui53
2 files changed, 26 insertions, 78 deletions
diff --git a/noncore/settings/backup/backuprestore.cpp b/noncore/settings/backup/backuprestore.cpp
index 180980a..5a4e284 100644
--- a/noncore/settings/backup/backuprestore.cpp
+++ b/noncore/settings/backup/backuprestore.cpp
@@ -1,119 +1,119 @@
1/* 1/*
2                This file is part of the Opie Project 2 This file is part of the Opie Project
3 =. 3 =.
4             .=l. Copyright (c) 2002-2004 The Opie Team <opie-devel@handhelds.org> 4 .=l. Copyright (c) 2002-2004 The Opie Team <opie-devel@handhelds.org>
5           .>+-= 5 .>+-=
6 _;:,     .>    :=|. This file is free software; you can 6_;:, .> :=|. This file is free software; you can
7.> <`_,   >  .   <= redistribute it and/or modify it under 7.> <`_, > . <= redistribute it and/or modify it under
8:`=1 )Y*s>-.--   : the terms of the GNU General Public 8:`=1 )Y*s>-.-- : the terms of the GNU General Public
9.="- .-=="i,     .._ License as published by the Free Software 9.="- .-=="i, .._ License as published by the Free Software
10 - .   .-<_>     .<> Foundation; either version 2 of the License, 10- . .-<_> .<> Foundation; either version 2 of the License,
11     ._= =}       : or (at your option) any later version. 11 ._= =} : or (at your option) any later version.
12    .%`+i>       _;_. 12 .%`+i> _;_.
13    .i_,=:_.      -<s. This file is distributed in the hope that 13 .i_,=:_. -<s. This file is distributed in the hope that
14     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 14 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
15    : ..    .:,     . . . without even the implied warranty of 15 : .. .:, . . . without even the implied warranty of
16    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 16 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
17  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General 17 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General
18..}^=.=       =       ; Public License for more details. 18..}^=.= = ; Public License for more details.
19++=   -.     .`     .: 19++= -. .` .:
20 :     =  ...= . :.=- You should have received a copy of the GNU 20: = ...= . :.=- You should have received a copy of the GNU
21 -.   .:....=;==+<; General Public License along with this file; 21-. .:....=;==+<; General Public License along with this file;
22  -_. . .   )=.  = see the file COPYING. If not, write to the 22 -_. . . )=. = see the file COPYING. If not, write to the
23    --        :-=` Free Software Foundation, Inc., 23 -- :-=` Free Software Foundation, Inc.,
24 59 Temple Place - Suite 330, 24 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA. 25 Boston, MA 02111-1307, USA.
26 26
27*/ 27*/
28 28
29#include "backuprestore.h" 29#include "backuprestore.h"
30#include "errordialog.h" 30#include "errordialog.h"
31 31
32/* OPIE */ 32/* OPIE */
33#include <qpe/qpeapplication.h> 33#include <qpe/qpeapplication.h>
34#include <qpe/resource.h> 34#include <qpe/resource.h>
35#include <qpe/config.h> 35#include <qpe/config.h>
36#include <opie2/odebug.h> 36#include <opie2/odebug.h>
37#include <opie2/odevice.h> 37#include <opie2/odevice.h>
38#include <opie2/ostorageinfo.h> 38#include <opie2/ostorageinfo.h>
39#include <opie2/ofiledialog.h> 39#include <opie2/ofiledialog.h>
40#include <opie2/owait.h> 40#include <opie2/owait.h>
41using namespace Opie::Core; 41using namespace Opie::Core;
42using namespace Opie::Ui; 42using namespace Opie::Ui;
43 43
44/* QT */ 44/* QT */
45#include <qapplication.h> 45#include <qapplication.h>
46#include <qmultilineedit.h> 46#include <qmultilineedit.h>
47#include <qdir.h> 47#include <qdir.h>
48#include <qfile.h> 48#include <qfile.h>
49#include <qfileinfo.h> 49#include <qfileinfo.h>
50#include <qlistview.h> 50#include <qlistview.h>
51#include <qpushbutton.h> 51#include <qpushbutton.h>
52#include <qradiobutton.h> 52#include <qradiobutton.h>
53#include <qheader.h> 53#include <qheader.h>
54#include <qmessagebox.h> 54#include <qmessagebox.h>
55#include <qcombobox.h> 55#include <qcombobox.h>
56#include <qlist.h> 56#include <qlist.h>
57#include <qregexp.h> 57#include <qregexp.h>
58#include <qtextstream.h> 58#include <qtextstream.h>
59#include <qtextview.h> 59#include <qtextview.h>
60#include <qlineedit.h> 60#include <qlineedit.h>
61#include <qstringlist.h> 61#include <qstringlist.h>
62 62
63/* STD */ 63/* STD */
64#include <errno.h> 64#include <errno.h>
65#include <stdlib.h> 65#include <stdlib.h>
66#include <unistd.h> 66#include <unistd.h>
67#include <sys/stat.h> 67#include <sys/stat.h>
68#include <dirent.h> 68#include <dirent.h>
69 69
70#define HEADER_NAME 0 70#define HEADER_NAME 0
71#define HEADER_BACKUP 1 71#define HEADER_BACKUP 1
72#define BACKUP_LOCATION 2 72#define BACKUP_LOCATION 2
73 73
74#define EXTENSION ".bck" 74#define EXTENSION ".bck"
75 75
76const QString tempFileName = "/tmp/backup.err"; 76const QString tempFileName = "/tmp/backup.err";
77 77
78BackupAndRestore::BackupAndRestore( QWidget* parent, const char* name, WFlags fl) 78BackupAndRestore::BackupAndRestore( QWidget* parent, const char* name, WFlags fl)
79 : BackupAndRestoreBase(parent, name, fl) 79 : BackupAndRestoreBase(parent, name, fl)
80{ 80{
81 backupList->header()->hide(); 81 backupList->header()->hide();
82 restoreList->header()->hide(); 82 restoreList->header()->hide();
83 locationList->header()->hide(); 83 locationList->header()->hide();
84 connect( backupButton, SIGNAL( clicked() ), this, SLOT( backup() ) ); 84 connect( backupButton, SIGNAL( clicked() ), this, SLOT( backup() ) );
85 connect( restoreButton, SIGNAL( clicked() ), this, SLOT( restore() ) ); 85 connect( restoreButton, SIGNAL( clicked() ), this, SLOT( restore() ) );
86 connect( backupList, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( selectItem( QListViewItem* ) ) ); 86 connect( backupList, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( selectItem( QListViewItem* ) ) );
87 connect( restoreSource, SIGNAL( activated( int ) ), this, SLOT( sourceDirChanged( int ) ) ); 87 connect( restoreSource, SIGNAL( activated( int ) ), this, SLOT( sourceDirChanged( int ) ) );
88 connect( addLocationButton, SIGNAL( clicked() ), this, SLOT( addLocation() ) ); 88 connect( addLocationButton, SIGNAL( clicked() ), this, SLOT( addLocation() ) );
89 connect( removeLocationButton, SIGNAL( clicked() ), this, SLOT( removeLocation() ) ); 89 connect( removeLocationButton, SIGNAL( clicked() ), this, SLOT( removeLocation() ) );
90 connect( selectLocationButton, SIGNAL( clicked() ), this, SLOT( selectLocation() ) ); 90 connect( selectLocationButton, SIGNAL( clicked() ), this, SLOT( selectLocation() ) );
91 91
92 //add directorys for backing up 92 //add directorys for backing up
93 applicationSettings = new QListViewItem(backupList, "Application Settings", "", "Settings/"); 93 applicationSettings = new QListViewItem(backupList, "Application Settings", "", "Settings/");
94 selectItem(applicationSettings); 94 selectItem(applicationSettings);
95 applicationSettings = new QListViewItem(backupList, "Application Data", "", "Applications/"); 95 applicationSettings = new QListViewItem(backupList, "Application Data", "", "Applications/");
96 selectItem(applicationSettings); 96 selectItem(applicationSettings);
97 documents= new QListViewItem(backupList, "Documents", "", "Documents/"); 97 documents= new QListViewItem(backupList, "Documents", "", "Documents/");
98 selectItem(documents); 98 selectItem(documents);
99 99
100 scanForApplicationSettings(); 100 scanForApplicationSettings();
101 refreshLocations(); 101 refreshLocations();
102 refreshBackupLocations(); 102 refreshBackupLocations();
103 103
104 // Read the list of items to ignore. 104 // Read the list of items to ignore.
105 QList<QString> dontBackupList; 105 QList<QString> dontBackupList;
106 dontBackupList.setAutoDelete(true); 106 dontBackupList.setAutoDelete(true);
107 Config config("BackupAndRestore"); 107 Config config("BackupAndRestore");
108 config.setGroup("DontBackup"); 108 config.setGroup("DontBackup");
109 int total = config.readNumEntry("Total", 0); 109 int total = config.readNumEntry("Total", 0);
110 for(int i = 0; i < total; i++) 110 for(int i = 0; i < total; i++)
111 { 111 {
112 dontBackupList.append(new QString(config.readEntry(QString("%1").arg(i), ""))); 112 dontBackupList.append(new QString(config.readEntry(QString("%1").arg(i), "")));
113 } 113 }
114 114
115 QList<QListViewItem> list; 115 QList<QListViewItem> list;
116 getAllItems(backupList->firstChild(), list); 116 getAllItems(backupList->firstChild(), list);
117 117
118 for(uint i = 0; i < list.count(); i++) 118 for(uint i = 0; i < list.count(); i++)
119 { 119 {
@@ -177,196 +177,197 @@ void BackupAndRestore::refreshBackupLocations()
177 odebug << "Mmc Path: " + storage.mmcPath() << oendl; 177 odebug << "Mmc Path: " + storage.mmcPath() << oendl;
178 } 178 }
179 179
180 for ( QListViewItemIterator it( locationList ); it.current(); ++it ) 180 for ( QListViewItemIterator it( locationList ); it.current(); ++it )
181 { 181 {
182 backupLocations.insert( it.current()->text( 0 ), it.current()->text( 0 ) ); 182 backupLocations.insert( it.current()->text( 0 ), it.current()->text( 0 ) );
183 } 183 }
184 184
185 //update QComboBox 185 //update QComboBox
186 storeToLocation->clear(); 186 storeToLocation->clear();
187 restoreSource->clear(); 187 restoreSource->clear();
188 188
189 //read last locations 189 //read last locations
190 Config config("BackupAndRestore"); 190 Config config("BackupAndRestore");
191 config.setGroup("LastLocation"); 191 config.setGroup("LastLocation");
192 QString lastStoreLocation = config.readEntry( "LastStoreLocation", "" ); 192 QString lastStoreLocation = config.readEntry( "LastStoreLocation", "" );
193 QString lastRestoreLocation = config.readEntry( "LastRestoreLocation", "" ); 193 QString lastRestoreLocation = config.readEntry( "LastRestoreLocation", "" );
194 int locationIndex = 0; 194 int locationIndex = 0;
195 195
196 //fill QComboBox 196 //fill QComboBox
197 QMap<QString, QString>::Iterator it; 197 QMap<QString, QString>::Iterator it;
198 for( it = backupLocations.begin(); it != backupLocations.end(); ++it ) 198 for( it = backupLocations.begin(); it != backupLocations.end(); ++it )
199 { 199 {
200 storeToLocation->insertItem(it.key()); 200 storeToLocation->insertItem(it.key());
201 restoreSource->insertItem(it.key()); 201 restoreSource->insertItem(it.key());
202 202
203 //check for last locations 203 //check for last locations
204 if ( it.key() == lastStoreLocation ) 204 if ( it.key() == lastStoreLocation )
205 storeToLocation->setCurrentItem( locationIndex ); 205 storeToLocation->setCurrentItem( locationIndex );
206 if ( it.key() == lastRestoreLocation ) 206 if ( it.key() == lastRestoreLocation )
207 restoreSource->setCurrentItem( locationIndex ); 207 restoreSource->setCurrentItem( locationIndex );
208 locationIndex++; 208 locationIndex++;
209 } 209 }
210} 210}
211 211
212QList<QListViewItem> BackupAndRestore::getAllItems(QListViewItem *item, QList<QListViewItem> &list) 212QList<QListViewItem> BackupAndRestore::getAllItems(QListViewItem *item, QList<QListViewItem> &list)
213{ 213{
214 while(item) 214 while(item)
215 { 215 {
216 if(item->childCount() > 0) 216 if(item->childCount() > 0)
217 getAllItems(item->firstChild(), list); 217 getAllItems(item->firstChild(), list);
218 list.append(item); 218 list.append(item);
219 item = item->nextSibling(); 219 item = item->nextSibling();
220 } 220 }
221 return list; 221 return list;
222} 222}
223 223
224/** 224/**
225 * Selects and unselects the item by setting the HEADER_BACKUP to B or !. 225 * Selects and unselects the item by setting the HEADER_BACKUP to B or !.
226 * and changing the icon to match 226 * and changing the icon to match
227 * @param currentItem the item to swich the selection choice. 227 * @param currentItem the item to swich the selection choice.
228 */ 228 */
229void BackupAndRestore::selectItem(QListViewItem *currentItem) 229void BackupAndRestore::selectItem(QListViewItem *currentItem)
230{ 230{
231 if(!currentItem) 231 if(!currentItem)
232 return; 232 return;
233 233
234 if(currentItem->text(HEADER_BACKUP) == "B") 234 if(currentItem->text(HEADER_BACKUP) == "B")
235 { 235 {
236 currentItem->setPixmap(HEADER_NAME, Resource::loadPixmap("backup/null")); 236 currentItem->setPixmap(HEADER_NAME, Resource::loadPixmap("backup/null"));
237 currentItem->setText(HEADER_BACKUP, ""); 237 currentItem->setText(HEADER_BACKUP, "");
238 } 238 }
239 else 239 else
240 { 240 {
241 currentItem->setPixmap(HEADER_NAME, Resource::loadPixmap("backup/check")); 241 currentItem->setPixmap(HEADER_NAME, Resource::loadPixmap("backup/check"));
242 currentItem->setText(HEADER_BACKUP, "B"); 242 currentItem->setText(HEADER_BACKUP, "B");
243 } 243 }
244} 244}
245 245
246void BackupAndRestore::scanForApplicationSettings() 246void BackupAndRestore::scanForApplicationSettings()
247{ 247{
248 QDir d( QDir::homeDirPath() + "/" + QString( applicationSettings->text(BACKUP_LOCATION) ) ); 248 QDir d( QDir::homeDirPath() + "/" + QString( applicationSettings->text(BACKUP_LOCATION) ) );
249 d.setFilter( QDir::Dirs | QDir::Files | QDir::NoSymLinks ); 249 d.setFilter( QDir::Dirs | QDir::Files | QDir::NoSymLinks );
250 const QFileInfoList *list = d.entryInfoList(); 250 const QFileInfoList *list = d.entryInfoList();
251 QFileInfoListIterator it( *list ); 251 QFileInfoListIterator it( *list );
252 QFileInfo *fi; 252 QFileInfo *fi;
253 while ( (fi=it.current()) ) 253 while ( (fi=it.current()) )
254 { 254 {
255 //odebug << (d.path()+"/"+fi->fileName()).latin1() << oendl; 255 //odebug << (d.path()+"/"+fi->fileName()).latin1() << oendl;
256 if ( ( fi->fileName() != "." ) && ( fi->fileName() != ".." ) ) 256 if ( ( fi->fileName() != "." ) && ( fi->fileName() != ".." ) )
257 { 257 {
258 QListViewItem *newItem = new QListViewItem(applicationSettings, fi->fileName()); 258 QListViewItem *newItem = new QListViewItem(applicationSettings, fi->fileName());
259 selectItem(newItem); 259 selectItem(newItem);
260 } 260 }
261 ++it; 261 ++it;
262 } 262 }
263} 263}
264 264
265/** 265/**
266 * The "Backup" button has been pressed. Get a list of all of the files that 266 * The "Backup" button has been pressed. Get a list of all of the files that
267 * should be backed up. If there are no files, emit and error and exit. 267 * should be backed up. If there are no files, emit and error and exit.
268 * Determine the file name to store the backup in. Backup the file(s) using 268 * Determine the file name to store the backup in. Backup the file(s) using
269 * tar and gzip --best. Report failure or success 269 * tar and gzip --best. Report failure or success
270 */ 270 */
271void BackupAndRestore::backup() 271void BackupAndRestore::backup()
272{ 272{
273 if ( cb_type_userdata->isChecked() ) 273 backupUserData();
274/* if ( cb_type_userdata->isChecked() )
274 backupUserData(); 275 backupUserData();
275 else 276 else
276 backupRootFs(); 277 backupRootFs();*/
277} 278}
278 279
279 280
280void BackupAndRestore::backupRootFs() 281void BackupAndRestore::backupRootFs()
281{ 282{
282 if ( ( ODevice::inst()->model() != Model_Zaurus_SL5000 ) && ( ODevice::inst()->model() != Model_Zaurus_SL5500 ) ) 283 if ( ( ODevice::inst()->model() != Model_Zaurus_SL5000 ) && ( ODevice::inst()->model() != Model_Zaurus_SL5500 ) )
283 { 284 {
284 QMessageBox::critical( this, "Not yet implemented!", "<qt>Sorry, support for this model is not yet done.</qt>", "Ok" ); 285 QMessageBox::critical( this, "Not yet implemented!", "<qt>Sorry, support for this model is not yet done.</qt>", "Ok" );
285 return; 286 return;
286 } 287 }
287 288
288 if ( !QFile::exists( "/usr/bin/mkfs.jffs2" ) && !QFile::exists( "/usr/sbin/mkfs.jffs2" ) ) 289 if ( !QFile::exists( "/usr/bin/mkfs.jffs2" ) && !QFile::exists( "/usr/sbin/mkfs.jffs2" ) )
289 { 290 {
290 QMessageBox::critical( this, "Can't find utility!", "<qt>Can't find mkfs.jffs2 - Install mtd-utils.</qt>", "Ok" ); 291 QMessageBox::critical( this, "Can't find utility!", "<qt>Can't find mkfs.jffs2 - Install mtd-utils.</qt>", "Ok" );
291 return; 292 return;
292 } 293 }
293 294
294 // call 'mount' and parse its output to gather the device on which the root partition is mounted 295 // call 'mount' and parse its output to gather the device on which the root partition is mounted
295 FILE* mountp = popen( "mount", "r" ); 296 FILE* mountp = popen( "mount", "r" );
296 QString device; 297 QString device;
297 QString mountpoint; 298 QString mountpoint;
298 { 299 {
299 QTextStream mounto( mountp, IO_ReadOnly ); 300 QTextStream mounto( mountp, IO_ReadOnly );
300 QString on; 301 QString on;
301 QString type; 302 QString type;
302 QString filesystem; 303 QString filesystem;
303 QString options; 304 QString options;
304 while ( !mounto.atEnd() ) 305 while ( !mounto.atEnd() )
305 { 306 {
306 mounto >> device >> on >> mountpoint >> type >> filesystem >> options; 307 mounto >> device >> on >> mountpoint >> type >> filesystem >> options;
307 if ( mountpoint == "/" ) break; 308 if ( mountpoint == "/" ) break;
308 } 309 }
309 odebug << device << " is formatted w/ '" << filesystem << "' and mounted on '" << mountpoint << "'" << oendl; 310 odebug << device << " is formatted w/ '" << filesystem << "' and mounted on '" << mountpoint << "'" << oendl;
310 311
311 if ( !device.startsWith( "/dev/mtdblock" ) ) 312 if ( !device.startsWith( "/dev/mtdblock" ) )
312 { 313 {
313 QMessageBox::critical( this, "Can't backup!", QString( "<qt>unsupported root device '%1' - needs to be /dev/mtdblockN</qt>").arg( device ), "Ok" ); 314 QMessageBox::critical( this, "Can't backup!", QString( "<qt>unsupported root device '%1' - needs to be /dev/mtdblockN</qt>").arg( device ), "Ok" );
314 return; 315 return;
315 } 316 }
316 } // at this point, the QTextStream has been destroy and we can close the FILE* 317 } // at this point, the QTextStream has been destroy and we can close the FILE*
317 pclose( mountp ); 318 pclose( mountp );
318 319
319#if 1 320#if 1
320 int rootmtd = device.right( 1 ).toInt(); 321 int rootmtd = device.right( 1 ).toInt();
321#else 322#else
322 int rootmtd = 0; 323 int rootmtd = 0;
323#endif 324#endif
324 odebug << "root mtdblock seems to be '" << rootmtd << "'" << oendl; 325 odebug << "root mtdblock seems to be '" << rootmtd << "'" << oendl;
325 326
326 // scan /proc/mtd to gather the size and erasesize of the root mtdblock 327 // scan /proc/mtd to gather the size and erasesize of the root mtdblock
327 QFile procmtdf( "/proc/mtd" ); 328 QFile procmtdf( "/proc/mtd" );
328 if ( !procmtdf.open( IO_ReadOnly ) ) 329 if ( !procmtdf.open( IO_ReadOnly ) )
329 { 330 {
330 QMessageBox::critical( this, "Can't backup!", "<qt>Can't open /proc/mtd</qt>", "Ok" ); 331 QMessageBox::critical( this, "Can't backup!", "<qt>Can't open /proc/mtd</qt>", "Ok" );
331 return; 332 return;
332 } 333 }
333 334
334 QTextStream procmtd( &procmtdf ); 335 QTextStream procmtd( &procmtdf );
335 for ( int i = 0; i <= rootmtd; ++i ) procmtd.readLine(); // skip uninteresting things 336 for ( int i = 0; i <= rootmtd; ++i ) procmtd.readLine(); // skip uninteresting things
336 QString dev; 337 QString dev;
337 QString size; 338 QString size;
338 QString erasesize; 339 QString erasesize;
339 QString devname; 340 QString devname;
340 procmtd >> dev >> size >> erasesize >> devname; 341 procmtd >> dev >> size >> erasesize >> devname;
341 342
342 odebug << "device " << dev << " size = " << size << ", erase size = " << erasesize << ", name = " << devname << "\"" << oendl; 343 odebug << "device " << dev << " size = " << size << ", erase size = " << erasesize << ", name = " << devname << "\"" << oendl;
343 344
344 // compute pad 345 // compute pad
345 QString pad = "--pad"; 346 QString pad = "--pad";
346 switch ( ODevice::inst()->model() ) 347 switch ( ODevice::inst()->model() )
347 { 348 {
348 case Model_Zaurus_SL5000: pad = "--pad=14680064"; break; 349 case Model_Zaurus_SL5000: pad = "--pad=14680064"; break;
349 case Model_Zaurus_SL5500: pad = "--pad=14680064"; break; 350 case Model_Zaurus_SL5500: pad = "--pad=14680064"; break;
350 // FIXME: Add Beagle and SIMpad 351 // FIXME: Add Beagle and SIMpad
351 } 352 }
352 353
353 // compute eraseblock 354 // compute eraseblock
354 QString eraseblock = "--eraseblock=0x" + erasesize; 355 QString eraseblock = "--eraseblock=0x" + erasesize;
355 356
356 // compute output 357 // compute output
357 QString outputFile = "--output=" + backupLocations[storeToLocation->currentText()]; 358 QString outputFile = "--output=" + backupLocations[storeToLocation->currentText()];
358 QDateTime datetime = QDateTime::currentDateTime(); 359 QDateTime datetime = QDateTime::currentDateTime();
359 QString dateString = QString::number( datetime.date().year() ) + QString::number( datetime.date().month() ).rightJustify(2, '0') + 360 QString dateString = QString::number( datetime.date().year() ) + QString::number( datetime.date().month() ).rightJustify(2, '0') +
360 QString::number( datetime.date().day() ).rightJustify(2, '0'); 361 QString::number( datetime.date().day() ).rightJustify(2, '0');
361 outputFile += "/initrd.bin-" + dateString; 362 outputFile += "/initrd.bin-" + dateString;
362 363
363 // call mkfs.jffs2 to create the backup 364 // call mkfs.jffs2 to create the backup
364 QString cmdline = QString( "mkfs.jffs2 --faketime --root=/ %1 --little-endian %2 %3 -n" ).arg( outputFile ).arg( pad ).arg( eraseblock ); 365 QString cmdline = QString( "mkfs.jffs2 --faketime --root=/ %1 --little-endian %2 %3 -n" ).arg( outputFile ).arg( pad ).arg( eraseblock );
365 cmdline.append( " --ignore=/tmp --ignore=/mnt --ignore=/var --ignore=/proc" ); 366 cmdline.append( " --ignore=/tmp --ignore=/mnt --ignore=/var --ignore=/proc" );
366 owarn << "Calling '" << cmdline << "'" << oendl; 367 owarn << "Calling '" << cmdline << "'" << oendl;
367 368
368 OWait *owait = new OWait(); 369 OWait *owait = new OWait();
369 Global::statusMessage( tr( "Backing up..." ) ); 370 Global::statusMessage( tr( "Backing up..." ) );
370 owait->show(); 371 owait->show();
371 qApp->processEvents(); 372 qApp->processEvents();
372 373
@@ -494,194 +495,194 @@ int BackupAndRestore::getBackupFiles(QString &backupFiles, QListViewItem *parent
494 QString currentHome; 495 QString currentHome;
495 if(!parent) 496 if(!parent)
496 currentItem = backupList->firstChild(); 497 currentItem = backupList->firstChild();
497 else 498 else
498 { 499 {
499 currentItem = parent->firstChild(); 500 currentItem = parent->firstChild();
500 currentHome = parent->text(BACKUP_LOCATION); 501 currentHome = parent->text(BACKUP_LOCATION);
501 } 502 }
502 503
503 uint count = 0; 504 uint count = 0;
504 while( currentItem != 0 ) 505 while( currentItem != 0 )
505 { 506 {
506 if(currentItem->text(HEADER_BACKUP) == "B" ) 507 if(currentItem->text(HEADER_BACKUP) == "B" )
507 { 508 {
508 if(currentItem->childCount() == 0 ) 509 if(currentItem->childCount() == 0 )
509 { 510 {
510 if(parent == NULL) 511 if(parent == NULL)
511 backupFiles += currentItem->text(BACKUP_LOCATION); 512 backupFiles += currentItem->text(BACKUP_LOCATION);
512 else 513 else
513 backupFiles += currentHome + currentItem->text(HEADER_NAME); 514 backupFiles += currentHome + currentItem->text(HEADER_NAME);
514 backupFiles += " "; 515 backupFiles += " ";
515 count++; 516 count++;
516 } 517 }
517 else 518 else
518 { 519 {
519 count += getBackupFiles(backupFiles, currentItem); 520 count += getBackupFiles(backupFiles, currentItem);
520 } 521 }
521 } 522 }
522 currentItem = currentItem->nextSibling(); 523 currentItem = currentItem->nextSibling();
523 } 524 }
524 return count; 525 return count;
525} 526}
526 527
527void BackupAndRestore::sourceDirChanged(int selection) 528void BackupAndRestore::sourceDirChanged(int selection)
528{ 529{
529 restoreList->clear(); 530 restoreList->clear();
530 rescanFolder(backupLocations[restoreSource->text(selection)]); 531 rescanFolder(backupLocations[restoreSource->text(selection)]);
531} 532}
532 533
533void BackupAndRestore::fileListUpdate() 534void BackupAndRestore::fileListUpdate()
534{ 535{
535 owarn << "void BackupAndRestore::fileListUpdate()" << oendl; 536 owarn << "void BackupAndRestore::fileListUpdate()" << oendl;
536 restoreList->clear(); 537 restoreList->clear();
537 rescanFolder( backupLocations[restoreSource->currentText()] ); 538 rescanFolder( backupLocations[restoreSource->currentText()] );
538} 539}
539 540
540/** 541/**
541 * Scans directory for any backup files. Will recursivly go down, 542 * Scans directory for any backup files. Will recursivly go down,
542 * but will not follow symlinks. 543 * but will not follow symlinks.
543 * @param directory - the directory to look in. 544 * @param directory - the directory to look in.
544 */ 545 */
545void BackupAndRestore::rescanFolder(QString directory) 546void BackupAndRestore::rescanFolder(QString directory)
546{ 547{
547 //odebug << QString("rescanFolder: ") + directory.latin1() << oendl; 548 //odebug << QString("rescanFolder: ") + directory.latin1() << oendl;
548 QDir d(directory); 549 QDir d(directory);
549 if(!d.exists()) 550 if(!d.exists())
550 return; 551 return;
551 552
552 d.setFilter( QDir::Files | QDir::Hidden | QDir::Dirs); 553 d.setFilter( QDir::Files | QDir::Hidden | QDir::Dirs);
553 const QFileInfoList *list = d.entryInfoList(); 554 const QFileInfoList *list = d.entryInfoList();
554 QFileInfoListIterator it( *list ); 555 QFileInfoListIterator it( *list );
555 QFileInfo *file; 556 QFileInfo *file;
556 while ( (file=it.current()) ) 557 while ( (file=it.current()) )
557 { // for each file... 558 { // for each file...
558 // If it is a dir and not .. or . then add it as a tab and go down. 559 // If it is a dir and not .. or . then add it as a tab and go down.
559 if(file->isDir()) 560 if(file->isDir())
560 { 561 {
561 if(file->fileName() != ".." && file->fileName() != ".") 562 if(file->fileName() != ".." && file->fileName() != ".")
562 { 563 {
563 rescanFolder(directory + "/" + file->fileName()); 564 rescanFolder(directory + "/" + file->fileName());
564 } 565 }
565 } 566 }
566 else 567 else
567 { 568 {
568 // If it is a backup file add to list. 569 // If it is a backup file add to list.
569 if(file->fileName().contains(EXTENSION)) 570 if(file->fileName().contains(EXTENSION))
570 (void)new QListViewItem(restoreList, file->fileName()); 571 (void)new QListViewItem(restoreList, file->fileName());
571 } 572 }
572 ++it; 573 ++it;
573 } 574 }
574} 575}
575 576
576/** 577/**
577 * Restore a backup file. 578 * Restore a backup file.
578 * Report errors or success 579 * Report errors or success
579 */ 580 */
580void BackupAndRestore::restore() 581void BackupAndRestore::restore()
581{ 582{
582 QListViewItem *restoreItem = restoreList->currentItem(); 583 QListViewItem *restoreItem = restoreList->currentItem();
583 if(!restoreItem) 584 if(!restoreItem)
584 { 585 {
585 QMessageBox::critical(this, tr( "Message" ), 586 QMessageBox::critical(this, tr( "Message" ),
586 tr( "Please select something to restore." ),QString( tr( "Ok") ) ); 587 tr( "Please select something to restore." ),QString( tr( "Ok") ) );
587 return; 588 return;
588 } 589 }
589 590
590 if ( QMessageBox::warning( this, tr( "Restore" ), 591 if ( QMessageBox::warning( this, tr( "Restore" ),
591 tr( "Would you really overwrite your local data?" ), 592 tr( "Would you really overwrite your local data?" ),
592 tr( "Yes" ), tr( "No" ), "", 1 ) == 1 ) 593 tr( "Yes" ), tr( "No" ), "", 1 ) == 1 )
593 return; 594 return;
594 595
595 OWait *owait = new OWait(); 596 OWait *owait = new OWait();
596 Global::statusMessage( tr( "Restore Backup..." ) ); 597 Global::statusMessage( tr( "Restore Backup..." ) );
597 owait->show(); 598 owait->show();
598 qApp->processEvents(); 599 qApp->processEvents();
599 600
600 QString restoreFile = backupLocations[restoreSource->currentText()]; 601 QString restoreFile = backupLocations[restoreSource->currentText()];
601 602
602 restoreFile += "/" + restoreItem->text(0); 603 restoreFile += "/" + restoreItem->text(0);
603 604
604 odebug << restoreFile << oendl; 605 odebug << restoreFile << oendl;
605 606
606 //check if backup file come from opie 1.0.x 607 //check if backup file come from opie 1.0.x
607 608
608 QString commandLine = QString( "tar -tzf %1 | grep Applications/backup/exclude" ).arg( restoreFile.latin1() ); 609 QString commandLine = QString( "tar -tzf %1 | grep Applications/backup/exclude" ).arg( restoreFile.latin1() );
609 610
610 int r = system( commandLine ); 611 int r = system( commandLine );
611 612
612 QString startDir; 613 QString startDir;
613 614
614 if( r != 0 ) //Applications/backup/exclude not found - old backup file 615 if( r != 0 ) //Applications/backup/exclude not found - old backup file
615 { 616 {
616 startDir = QString( "/" ); 617 startDir = QString( "/" );
617 } else 618 } else
618 { 619 {
619 startDir = QDir::homeDirPath(); 620 startDir = QDir::homeDirPath();
620 } 621 }
621 622
622 //unpack backup file 623 //unpack backup file
623 commandLine = QString( "cd %1 && tar -zxf %2 2> %3" ).arg( startDir ) 624 commandLine = QString( "cd %1 && tar -zxf %2 2> %3" ).arg( startDir )
624 .arg( restoreFile.latin1() ) 625 .arg( restoreFile.latin1() )
625 .arg( tempFileName.latin1() ); 626 .arg( tempFileName.latin1() );
626 627
627 odebug << commandLine << oendl; 628 odebug << commandLine << oendl;
628 629
629 r = system( commandLine ); 630 r = system( commandLine );
630 631
631 owait->hide(); 632 owait->hide();
632 delete owait; 633 delete owait;
633 634
634 //error handling 635 //error handling
635 if(r != 0) 636 if(r != 0)
636 { 637 {
637 QString errorMsg= tr( "Error from System:\n" ) + (QString)strerror( errno ); 638 QString errorMsg= tr( "Error from System:\n" ) + (QString)strerror( errno );
638 switch( QMessageBox::critical(this, tr( "Message" ), tr( "Restore Failed." ) + "\n" 639 switch( QMessageBox::critical(this, tr( "Message" ), tr( "Restore Failed." ) + "\n"
639 + errorMsg, QString( tr( "Ok") ), QString( tr( "Details" ) ) ) ) 640 + errorMsg, QString( tr( "Ok") ), QString( tr( "Details" ) ) ) )
640 { 641 {
641 case 1: 642 case 1:
642 owarn << "Details pressed !" << oendl; 643 owarn << "Details pressed !" << oendl;
643 ErrorDialog* pErrDialog = new ErrorDialog( this, NULL, true ); 644 ErrorDialog* pErrDialog = new ErrorDialog( this, NULL, true );
644 QFile errorFile( tempFileName ); 645 QFile errorFile( tempFileName );
645 if ( errorFile.open(IO_ReadOnly) ) 646 if ( errorFile.open(IO_ReadOnly) )
646 { 647 {
647 QTextStream t( &errorFile ); 648 QTextStream t( &errorFile );
648 QString s; 649 QString s;
649 while ( !t.eof() ) 650 while ( !t.eof() )
650 { // until end of file... 651 { // until end of file...
651 s += t.readLine(); // line of text excluding '\n' 652 s += t.readLine(); // line of text excluding '\n'
652 } 653 }
653 errorFile.close(); 654 errorFile.close();
654 655
655 pErrDialog->m_textarea->setText( s ); 656 pErrDialog->m_textarea->setText( s );
656 } 657 }
657 else 658 else
658 { 659 {
659 pErrDialog->m_textarea->setText( tr( "Unable to open File: %1" ).arg( "/tmp/backup.er" ) ); 660 pErrDialog->m_textarea->setText( tr( "Unable to open File: %1" ).arg( "/tmp/backup.er" ) );
660 } 661 }
661 QPEApplication::execDialog( pErrDialog ); 662 QPEApplication::execDialog( pErrDialog );
662 delete pErrDialog; 663 delete pErrDialog;
663 664
664 setCaption(tr("Backup and Restore.. Failed !!")); 665 setCaption(tr("Backup and Restore.. Failed !!"));
665 return; 666 return;
666 667
667 break; 668 break;
668 669
669 } 670 }
670 } 671 }
671 else 672 else
672 { 673 {
673 QMessageBox::information(this, tr( "Message" ), tr( "Restore Successful." ), QString( tr( "Ok") ) ); 674 QMessageBox::information(this, tr( "Message" ), tr( "Restore Successful." ), QString( tr( "Ok") ) );
674 } 675 }
675 676
676 //write restore-location 677 //write restore-location
677 Config config( "BackupAndRestore" ); 678 Config config( "BackupAndRestore" );
678 config.setGroup( "LastLocation" ); 679 config.setGroup( "LastLocation" );
679 config.writeEntry( "LastRestoreLocation", restoreSource->currentText() ); 680 config.writeEntry( "LastRestoreLocation", restoreSource->currentText() );
680 681
681 setCaption(tr("Backup and Restore")); 682 setCaption(tr("Backup and Restore"));
682} 683}
683 684
684/** 685/**
685 * Check for exclude in Applications/backup 686 * Check for exclude in Applications/backup
686 * If it does not exist, the function will create the file with *.bck as content 687 * If it does not exist, the function will create the file with *.bck as content
687 * The exclude_files is read by tar and will provide to exclude special files out from backup. 688 * The exclude_files is read by tar and will provide to exclude special files out from backup.
diff --git a/noncore/settings/backup/backuprestorebase.ui b/noncore/settings/backup/backuprestorebase.ui
index c91f292..f2b7d75 100644
--- a/noncore/settings/backup/backuprestorebase.ui
+++ b/noncore/settings/backup/backuprestorebase.ui
@@ -37,245 +37,192 @@
37 <widget row="0" column="0" > 37 <widget row="0" column="0" >
38 <class>QTabWidget</class> 38 <class>QTabWidget</class>
39 <property stdset="1"> 39 <property stdset="1">
40 <name>name</name> 40 <name>name</name>
41 <cstring>tabWidget</cstring> 41 <cstring>tabWidget</cstring>
42 </property> 42 </property>
43 <property> 43 <property>
44 <name>layoutMargin</name> 44 <name>layoutMargin</name>
45 </property> 45 </property>
46 <property> 46 <property>
47 <name>layoutSpacing</name> 47 <name>layoutSpacing</name>
48 </property> 48 </property>
49 <widget> 49 <widget>
50 <class>QWidget</class> 50 <class>QWidget</class>
51 <property stdset="1"> 51 <property stdset="1">
52 <name>name</name> 52 <name>name</name>
53 <cstring>Widget2</cstring> 53 <cstring>Widget2</cstring>
54 </property> 54 </property>
55 <attribute> 55 <attribute>
56 <name>title</name> 56 <name>title</name>
57 <string>Backup</string> 57 <string>Backup</string>
58 </attribute> 58 </attribute>
59 <grid> 59 <grid>
60 <property stdset="1"> 60 <property stdset="1">
61 <name>margin</name> 61 <name>margin</name>
62 <number>4</number> 62 <number>4</number>
63 </property> 63 </property>
64 <property stdset="1"> 64 <property stdset="1">
65 <name>spacing</name> 65 <name>spacing</name>
66 <number>2</number> 66 <number>2</number>
67 </property> 67 </property>
68 <widget row="1" column="1" > 68 <widget row="1" column="1" >
69 <class>QComboBox</class> 69 <class>QComboBox</class>
70 <property stdset="1"> 70 <property stdset="1">
71 <name>name</name> 71 <name>name</name>
72 <cstring>storeToLocation</cstring> 72 <cstring>storeToLocation</cstring>
73 </property> 73 </property>
74 <property stdset="1"> 74 <property stdset="1">
75 <name>sizePolicy</name> 75 <name>sizePolicy</name>
76 <sizepolicy> 76 <sizepolicy>
77 <hsizetype>3</hsizetype> 77 <hsizetype>3</hsizetype>
78 <vsizetype>1</vsizetype> 78 <vsizetype>1</vsizetype>
79 </sizepolicy> 79 </sizepolicy>
80 </property> 80 </property>
81 </widget> 81 </widget>
82 <widget row="1" column="0" > 82 <widget row="1" column="0" >
83 <class>QLabel</class> 83 <class>QLabel</class>
84 <property stdset="1"> 84 <property stdset="1">
85 <name>name</name> 85 <name>name</name>
86 <cstring>labelDestination</cstring> 86 <cstring>labelDestination</cstring>
87 </property> 87 </property>
88 <property stdset="1"> 88 <property stdset="1">
89 <name>text</name> 89 <name>text</name>
90 <string>Destination</string> 90 <string>Destination</string>
91 </property> 91 </property>
92 </widget> 92 </widget>
93 <widget row="3" column="0" rowspan="1" colspan="2" > 93 <widget row="3" column="0" rowspan="1" colspan="2" >
94 <class>QPushButton</class> 94 <class>QPushButton</class>
95 <property stdset="1"> 95 <property stdset="1">
96 <name>name</name> 96 <name>name</name>
97 <cstring>backupButton</cstring> 97 <cstring>backupButton</cstring>
98 </property> 98 </property>
99 <property stdset="1"> 99 <property stdset="1">
100 <name>text</name> 100 <name>text</name>
101 <string>&amp;Backup</string> 101 <string>&amp;Backup</string>
102 </property> 102 </property>
103 </widget> 103 </widget>
104 <widget row="2" column="0" rowspan="1" colspan="2" > 104 <widget row="2" column="0" rowspan="1" colspan="2" >
105 <class>QListView</class> 105 <class>QListView</class>
106 <column> 106 <column>
107 <property> 107 <property>
108 <name>text</name> 108 <name>text</name>
109 <string>Applications</string> 109 <string>Applications</string>
110 </property> 110 </property>
111 <property> 111 <property>
112 <name>clickable</name> 112 <name>clickable</name>
113 <bool>true</bool> 113 <bool>true</bool>
114 </property> 114 </property>
115 <property> 115 <property>
116 <name>resizeable</name> 116 <name>resizeable</name>
117 <bool>true</bool> 117 <bool>true</bool>
118 </property> 118 </property>
119 </column> 119 </column>
120 <property stdset="1"> 120 <property stdset="1">
121 <name>name</name> 121 <name>name</name>
122 <cstring>backupList</cstring> 122 <cstring>backupList</cstring>
123 </property> 123 </property>
124 <property stdset="1"> 124 <property stdset="1">
125 <name>allColumnsShowFocus</name> 125 <name>allColumnsShowFocus</name>
126 <bool>true</bool> 126 <bool>true</bool>
127 </property> 127 </property>
128 <property stdset="1"> 128 <property stdset="1">
129 <name>rootIsDecorated</name> 129 <name>rootIsDecorated</name>
130 <bool>true</bool> 130 <bool>true</bool>
131 </property> 131 </property>
132 </widget> 132 </widget>
133 <widget row="0" column="0" rowspan="1" colspan="2" >
134 <class>QButtonGroup</class>
135 <property stdset="1">
136 <name>name</name>
137 <cstring>frame_type</cstring>
138 </property>
139 <property stdset="1">
140 <name>title</name>
141 <string>Type</string>
142 </property>
143 <property>
144 <name>layoutMargin</name>
145 </property>
146 <property>
147 <name>layoutSpacing</name>
148 </property>
149 <grid>
150 <property stdset="1">
151 <name>margin</name>
152 <number>6</number>
153 </property>
154 <property stdset="1">
155 <name>spacing</name>
156 <number>2</number>
157 </property>
158 <widget row="1" column="0" >
159 <class>QRadioButton</class>
160 <property stdset="1">
161 <name>name</name>
162 <cstring>cb_type_fullbackup</cstring>
163 </property>
164 <property stdset="1">
165 <name>text</name>
166 <string>Full Backup (Root File System)</string>
167 </property>
168 </widget>
169 <widget row="0" column="0" >
170 <class>QRadioButton</class>
171 <property stdset="1">
172 <name>name</name>
173 <cstring>cb_type_userdata</cstring>
174 </property>
175 <property stdset="1">
176 <name>text</name>
177 <string>User Data (Configuration + PIM)</string>
178 </property>
179 <property stdset="1">
180 <name>checked</name>
181 <bool>true</bool>
182 </property>
183 </widget>
184 </grid>
185 </widget>
186 </grid> 133 </grid>
187 </widget> 134 </widget>
188 <widget> 135 <widget>
189 <class>QWidget</class> 136 <class>QWidget</class>
190 <property stdset="1"> 137 <property stdset="1">
191 <name>name</name> 138 <name>name</name>
192 <cstring>Widget3</cstring> 139 <cstring>Widget3</cstring>
193 </property> 140 </property>
194 <attribute> 141 <attribute>
195 <name>title</name> 142 <name>title</name>
196 <string>Restore</string> 143 <string>Restore</string>
197 </attribute> 144 </attribute>
198 <grid> 145 <grid>
199 <property stdset="1"> 146 <property stdset="1">
200 <name>margin</name> 147 <name>margin</name>
201 <number>4</number> 148 <number>4</number>
202 </property> 149 </property>
203 <property stdset="1"> 150 <property stdset="1">
204 <name>spacing</name> 151 <name>spacing</name>
205 <number>2</number> 152 <number>2</number>
206 </property> 153 </property>
207 <widget row="0" column="1" > 154 <widget row="0" column="1" >
208 <class>QComboBox</class> 155 <class>QComboBox</class>
209 <property stdset="1"> 156 <property stdset="1">
210 <name>name</name> 157 <name>name</name>
211 <cstring>restoreSource</cstring> 158 <cstring>restoreSource</cstring>
212 </property> 159 </property>
213 </widget> 160 </widget>
214 <widget row="2" column="0" rowspan="1" colspan="2" > 161 <widget row="2" column="0" rowspan="1" colspan="2" >
215 <class>QPushButton</class> 162 <class>QPushButton</class>
216 <property stdset="1"> 163 <property stdset="1">
217 <name>name</name> 164 <name>name</name>
218 <cstring>restoreButton</cstring> 165 <cstring>restoreButton</cstring>
219 </property> 166 </property>
220 <property stdset="1"> 167 <property stdset="1">
221 <name>text</name> 168 <name>text</name>
222 <string>&amp;Restore</string> 169 <string>&amp;Restore</string>
223 </property> 170 </property>
224 </widget> 171 </widget>
225 <widget row="0" column="0" > 172 <widget row="0" column="0" >
226 <class>QLabel</class> 173 <class>QLabel</class>
227 <property stdset="1"> 174 <property stdset="1">
228 <name>name</name> 175 <name>name</name>
229 <cstring>destinationLabel</cstring> 176 <cstring>destinationLabel</cstring>
230 </property> 177 </property>
231 <property stdset="1"> 178 <property stdset="1">
232 <name>text</name> 179 <name>text</name>
233 <string>Select Source</string> 180 <string>Select Source</string>
234 </property> 181 </property>
235 </widget> 182 </widget>
236 <widget row="1" column="0" rowspan="1" colspan="2" > 183 <widget row="1" column="0" rowspan="1" colspan="2" >
237 <class>QListView</class> 184 <class>QListView</class>
238 <column> 185 <column>
239 <property> 186 <property>
240 <name>text</name> 187 <name>text</name>
241 <string>Column 1</string> 188 <string>Column 1</string>
242 </property> 189 </property>
243 <property> 190 <property>
244 <name>clickable</name> 191 <name>clickable</name>
245 <bool>true</bool> 192 <bool>true</bool>
246 </property> 193 </property>
247 <property> 194 <property>
248 <name>resizeable</name> 195 <name>resizeable</name>
249 <bool>true</bool> 196 <bool>true</bool>
250 </property> 197 </property>
251 </column> 198 </column>
252 <property stdset="1"> 199 <property stdset="1">
253 <name>name</name> 200 <name>name</name>
254 <cstring>restoreList</cstring> 201 <cstring>restoreList</cstring>
255 </property> 202 </property>
256 <property stdset="1"> 203 <property stdset="1">
257 <name>minimumSize</name> 204 <name>minimumSize</name>
258 <size> 205 <size>
259 <width>0</width> 206 <width>0</width>
260 <height>100</height> 207 <height>100</height>
261 </size> 208 </size>
262 </property> 209 </property>
263 </widget> 210 </widget>
264 </grid> 211 </grid>
265 </widget> 212 </widget>
266 <widget> 213 <widget>
267 <class>QWidget</class> 214 <class>QWidget</class>
268 <property stdset="1"> 215 <property stdset="1">
269 <name>name</name> 216 <name>name</name>
270 <cstring>tab</cstring> 217 <cstring>tab</cstring>
271 </property> 218 </property>
272 <attribute> 219 <attribute>
273 <name>title</name> 220 <name>title</name>
274 <string>Locations</string> 221 <string>Locations</string>
275 </attribute> 222 </attribute>
276 <grid> 223 <grid>
277 <property stdset="1"> 224 <property stdset="1">
278 <name>margin</name> 225 <name>margin</name>
279 <number>4</number> 226 <number>4</number>
280 </property> 227 </property>
281 <property stdset="1"> 228 <property stdset="1">