00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "backuprestore.h"
00030 #include "errordialog.h"
00031
00032
00033 #include <opie2/odebug.h>
00034 #include <opie2/odevice.h>
00035 #include <opie2/ostorageinfo.h>
00036 #include <opie2/ofiledialog.h>
00037 #include <opie2/oresource.h>
00038 #include <opie2/owait.h>
00039
00040 #include <qpe/qpeapplication.h>
00041 #include <qpe/config.h>
00042
00043 using namespace Opie::Core;
00044 using namespace Opie::Ui;
00045
00046
00047 #include <qapplication.h>
00048 #include <qmultilineedit.h>
00049 #include <qdir.h>
00050 #include <qfile.h>
00051 #include <qfileinfo.h>
00052 #include <qlistview.h>
00053 #include <qpushbutton.h>
00054 #include <qradiobutton.h>
00055 #include <qheader.h>
00056 #include <qmessagebox.h>
00057 #include <qcombobox.h>
00058 #include <qlist.h>
00059 #include <qregexp.h>
00060 #include <qtextstream.h>
00061 #include <qtextview.h>
00062 #include <qlineedit.h>
00063 #include <qstringlist.h>
00064
00065
00066 #include <errno.h>
00067 #include <stdlib.h>
00068 #include <unistd.h>
00069 #include <sys/stat.h>
00070 #include <dirent.h>
00071
00072 #define HEADER_NAME 0
00073 #define HEADER_BACKUP 1
00074 #define BACKUP_LOCATION 2
00075
00076 #define EXTENSION ".bck"
00077
00078 const QString tempFileName = "/tmp/backup.err";
00079
00080 BackupAndRestore::BackupAndRestore( QWidget* parent, const char* name, WFlags fl)
00081 : BackupAndRestoreBase(parent, name, fl)
00082 {
00083 backupList->header()->hide();
00084 restoreList->header()->hide();
00085 locationList->header()->hide();
00086 connect( backupButton, SIGNAL( clicked() ), this, SLOT( backup() ) );
00087 connect( restoreButton, SIGNAL( clicked() ), this, SLOT( restore() ) );
00088 connect( backupList, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( selectItem( QListViewItem* ) ) );
00089 connect( restoreSource, SIGNAL( activated( int ) ), this, SLOT( sourceDirChanged( int ) ) );
00090 connect( addLocationButton, SIGNAL( clicked() ), this, SLOT( addLocation() ) );
00091 connect( removeLocationButton, SIGNAL( clicked() ), this, SLOT( removeLocation() ) );
00092 connect( selectLocationButton, SIGNAL( clicked() ), this, SLOT( selectLocation() ) );
00093
00094
00095 applicationSettings = new QListViewItem(backupList, "Application Settings", "", "Settings/");
00096 selectItem(applicationSettings);
00097 applicationSettings = new QListViewItem(backupList, "Application Data", "", "Applications/");
00098 selectItem(applicationSettings);
00099 documents= new QListViewItem(backupList, "Documents", "", "Documents/");
00100 selectItem(documents);
00101
00102 scanForApplicationSettings();
00103 refreshLocations();
00104 refreshBackupLocations();
00105 sourceDirChanged(restoreSource->currentItem());
00106
00107
00108 QList<QString> dontBackupList;
00109 dontBackupList.setAutoDelete(true);
00110 Config config("BackupAndRestore");
00111 config.setGroup("DontBackup");
00112 int total = config.readNumEntry("Total", 0);
00113 for(int i = 0; i < total; i++)
00114 {
00115 dontBackupList.append(new QString(config.readEntry(QString("%1").arg(i), "")));
00116 }
00117
00118 QList<QListViewItem> list;
00119 getAllItems(backupList->firstChild(), list);
00120
00121 for(uint i = 0; i < list.count(); i++)
00122 {
00123 QString text = list.at(i)->text(HEADER_NAME);
00124 for(uint i2 = 0; i2 < dontBackupList.count(); i2++)
00125 {
00126 if(*dontBackupList.at(i2) == text)
00127 {
00128 selectItem(list.at(i));
00129 break;
00130 }
00131 }
00132 }
00133 QPEApplication::showWidget( this );
00134 }
00135
00136 BackupAndRestore::~BackupAndRestore()
00137 {
00138 QList<QListViewItem> list;
00139 getAllItems(backupList->firstChild(), list);
00140
00141 Config config("BackupAndRestore");
00142 config.setGroup("DontBackup");
00143 config.clearGroup();
00144
00145 int count = 0;
00146 for(uint i = 0; i < list.count(); i++)
00147 {
00148 if(list.at(i)->text(HEADER_BACKUP) == "")
00149 {
00150 config.writeEntry(QString("%1").arg(count), list.at(i)->text(HEADER_NAME));
00151 count++;
00152 }
00153 }
00154 config.writeEntry("Total", count);
00155
00156
00157 if ( QFile::exists( tempFileName ) )
00158 QFile::remove( tempFileName );
00159 }
00160
00161 void BackupAndRestore::refreshBackupLocations()
00162 {
00163 backupLocations.clear();
00164
00165 Opie::Core::OStorageInfo storage;
00166 backupLocations.insert( "Documents", QDir::homeDirPath() + "/Documents" );
00167 if ( storage.hasCf() )
00168 {
00169 backupLocations.insert( "CF", storage.cfPath() );
00170 odebug << "Cf Path: " + storage.cfPath() << oendl;
00171 }
00172 if ( storage.hasSd() )
00173 {
00174 backupLocations.insert( "SD", storage.sdPath() );
00175 odebug << " Sd Path: " + storage.sdPath() << oendl;
00176 }
00177 if ( storage.hasMmc() )
00178 {
00179 backupLocations.insert( "MMC", storage.mmcPath() );
00180 odebug << "Mmc Path: " + storage.mmcPath() << oendl;
00181 }
00182
00183 for ( QListViewItemIterator it( locationList ); it.current(); ++it )
00184 {
00185 backupLocations.insert( it.current()->text( 0 ), it.current()->text( 0 ) );
00186 }
00187
00188
00189 storeToLocation->clear();
00190 restoreSource->clear();
00191
00192
00193 Config config("BackupAndRestore");
00194 config.setGroup("LastLocation");
00195 QString lastStoreLocation = config.readEntry( "LastStoreLocation", "" );
00196 QString lastRestoreLocation = config.readEntry( "LastRestoreLocation", "" );
00197 int locationIndex = 0;
00198
00199
00200 QMap<QString, QString>::Iterator it;
00201 for( it = backupLocations.begin(); it != backupLocations.end(); ++it )
00202 {
00203 storeToLocation->insertItem(it.key());
00204 restoreSource->insertItem(it.key());
00205
00206
00207 if ( it.key() == lastStoreLocation )
00208 storeToLocation->setCurrentItem( locationIndex );
00209 if ( it.key() == lastRestoreLocation )
00210 restoreSource->setCurrentItem( locationIndex );
00211 locationIndex++;
00212 }
00213 }
00214
00215 QList<QListViewItem> BackupAndRestore::getAllItems(QListViewItem *item, QList<QListViewItem> &list)
00216 {
00217 while(item)
00218 {
00219 if(item->childCount() > 0)
00220 getAllItems(item->firstChild(), list);
00221 list.append(item);
00222 item = item->nextSibling();
00223 }
00224 return list;
00225 }
00226
00232 void BackupAndRestore::selectItem(QListViewItem *currentItem)
00233 {
00234 if(!currentItem)
00235 return;
00236
00237 if(currentItem->text(HEADER_BACKUP) == "B")
00238 {
00239 currentItem->setPixmap(HEADER_NAME, Opie::Core::OResource::loadPixmap("backup/null"));
00240 currentItem->setText(HEADER_BACKUP, "");
00241 }
00242 else
00243 {
00244 currentItem->setPixmap(HEADER_NAME, Opie::Core::OResource::loadPixmap("backup/check"));
00245 currentItem->setText(HEADER_BACKUP, "B");
00246 }
00247 }
00248
00249 void BackupAndRestore::scanForApplicationSettings()
00250 {
00251 QDir d( QDir::homeDirPath() + "/" + QString( applicationSettings->text(BACKUP_LOCATION) ) );
00252 d.setFilter( QDir::Dirs | QDir::Files | QDir::NoSymLinks );
00253 const QFileInfoList *list = d.entryInfoList();
00254 QFileInfoListIterator it( *list );
00255 QFileInfo *fi;
00256 while ( (fi=it.current()) )
00257 {
00258
00259 if ( ( fi->fileName() != "." ) && ( fi->fileName() != ".." ) )
00260 {
00261 QListViewItem *newItem = new QListViewItem(applicationSettings, fi->fileName());
00262 selectItem(newItem);
00263 }
00264 ++it;
00265 }
00266 }
00267
00274 void BackupAndRestore::backup()
00275 {
00276 backupUserData();
00277
00278
00279
00280
00281 }
00282
00283
00284 void BackupAndRestore::backupRootFs()
00285 {
00286 if ( ( ODevice::inst()->model() != Model_Zaurus_SL5000 ) && ( ODevice::inst()->model() != Model_Zaurus_SL5500 ) )
00287 {
00288 QMessageBox::critical( this, "Not yet implemented!", "<qt>Sorry, support for this model is not yet done.</qt>", "Ok" );
00289 return;
00290 }
00291
00292 if ( !QFile::exists( "/usr/bin/mkfs.jffs2" ) && !QFile::exists( "/usr/sbin/mkfs.jffs2" ) )
00293 {
00294 QMessageBox::critical( this, "Can't find utility!", "<qt>Can't find mkfs.jffs2 - Install mtd-utils.</qt>", "Ok" );
00295 return;
00296 }
00297
00298
00299 FILE* mountp = popen( "mount", "r" );
00300 QString device;
00301 QString mountpoint;
00302 {
00303 QTextStream mounto( mountp, IO_ReadOnly );
00304 QString on;
00305 QString type;
00306 QString filesystem;
00307 QString options;
00308 while ( !mounto.atEnd() )
00309 {
00310 mounto >> device >> on >> mountpoint >> type >> filesystem >> options;
00311 if ( mountpoint == "/" ) break;
00312 }
00313 odebug << device << " is formatted w/ '" << filesystem << "' and mounted on '" << mountpoint << "'" << oendl;
00314
00315 if ( !device.startsWith( "/dev/mtdblock" ) )
00316 {
00317 QMessageBox::critical( this, "Can't backup!", QString( "<qt>unsupported root device '%1' - needs to be /dev/mtdblockN</qt>").arg( device ), "Ok" );
00318 return;
00319 }
00320 }
00321 pclose( mountp );
00322
00323 #if 1
00324 int rootmtd = device.right( 1 ).toInt();
00325 #else
00326 int rootmtd = 0;
00327 #endif
00328 odebug << "root mtdblock seems to be '" << rootmtd << "'" << oendl;
00329
00330
00331 QFile procmtdf( "/proc/mtd" );
00332 if ( !procmtdf.open( IO_ReadOnly ) )
00333 {
00334 QMessageBox::critical( this, "Can't backup!", "<qt>Can't open /proc/mtd</qt>", "Ok" );
00335 return;
00336 }
00337
00338 QTextStream procmtd( &procmtdf );
00339 for ( int i = 0; i <= rootmtd; ++i ) procmtd.readLine();
00340 QString dev;
00341 QString size;
00342 QString erasesize;
00343 QString devname;
00344 procmtd >> dev >> size >> erasesize >> devname;
00345
00346 odebug << "device " << dev << " size = " << size << ", erase size = " << erasesize << ", name = " << devname << "\"" << oendl;
00347
00348
00349 QString pad = "--pad";
00350 switch ( ODevice::inst()->model() )
00351 {
00352 case Model_Zaurus_SL5000: pad = "--pad=14680064"; break;
00353 case Model_Zaurus_SL5500: pad = "--pad=14680064"; break;
00354
00355 }
00356
00357
00358 QString eraseblock = "--eraseblock=0x" + erasesize;
00359
00360
00361 QString outputFile = "--output=" + backupLocations[storeToLocation->currentText()];
00362 QDateTime datetime = QDateTime::currentDateTime();
00363 QString dateString = QString::number( datetime.date().year() ) + QString::number( datetime.date().month() ).rightJustify(2, '0') +
00364 QString::number( datetime.date().day() ).rightJustify(2, '0');
00365 outputFile += "/initrd.bin-" + dateString;
00366
00367
00368 QString cmdline = QString( "mkfs.jffs2 --faketime --root=/ %1 --little-endian %2 %3 -n" ).arg( outputFile ).arg( pad ).arg( eraseblock );
00369 cmdline.append( " --ignore=/tmp --ignore=/mnt --ignore=/var --ignore=/proc" );
00370 owarn << "Calling '" << cmdline << "'" << oendl;
00371
00372 OWait *owait = new OWait();
00373 Global::statusMessage( tr( "Backing up..." ) );
00374 owait->show();
00375 qApp->processEvents();
00376
00377 int r = ::system( cmdline );
00378
00379 owait->hide();
00380 delete owait;
00381
00382 if ( r != 0 )
00383 {
00384 perror("Error: ");
00385 QString errorMsg = QString( tr( "<qt>%1</qt>" ).arg( strerror( errno ) ) );
00386 QMessageBox::critical(this, tr( "Backup Failed!" ), errorMsg, QString( tr( "Ok" ) ) );
00387 }
00388
00389
00390 }
00391
00392 void BackupAndRestore::backupUserData()
00393 {
00394 QString backupFiles;
00395 if(getBackupFiles(backupFiles, NULL) == 0)
00396 {
00397 QMessageBox::critical(this, "Message",
00398 "No items selected.",QString("Ok") );
00399 return;
00400 }
00401
00402 OWait *owait = new OWait();
00403 Global::statusMessage( tr( "Backing up..." ) );
00404 owait->show();
00405 qApp->processEvents();
00406
00407 QString outputFile = backupLocations[storeToLocation->currentText()];
00408
00409 QDateTime datetime = QDateTime::currentDateTime();
00410 QString dateString = QString::number( datetime.date().year() ) + QString::number( datetime.date().month() ).rightJustify(2, '0') +
00411 QString::number( datetime.date().day() ).rightJustify(2, '0');
00412
00413 outputFile += "/" + dateString;
00414
00415 QString t = outputFile;
00416 int c = 1;
00417 while(QFile::exists(outputFile + EXTENSION))
00418 {
00419 outputFile = t + QString("%1").arg(c);
00420 c++;
00421 }
00422
00423
00424
00425
00426 odebug << "Storing file: " << outputFile.latin1() << "" << oendl;
00427 outputFile += EXTENSION;
00428
00429 QString commandLine = QString( "cd %1 && (tar -X %1 -cz %2 Applications/backup/exclude -f %3 ) 2> %4" ).arg( QDir::homeDirPath() )
00430 .arg( getExcludeFile() )
00431 .arg( backupFiles )
00432 .arg( outputFile.latin1() )
00433 .arg( tempFileName.latin1() );
00434
00435 odebug << commandLine << oendl;
00436
00437 int r = system( commandLine );
00438
00439 owait->hide();
00440 delete owait;
00441
00442
00443 if(r != 0)
00444 {
00445 perror("Error: ");
00446 QString errorMsg= tr( "Error from System:\n" ) + (QString)strerror( errno );
00447
00448 switch( QMessageBox::critical(this, tr( "Message" ), tr( "Backup Failed!" ) + "\n"
00449 + errorMsg, QString( tr( "Ok" ) ), QString( tr( "Details" ) ) ) )
00450 {
00451
00452 case 1:
00453 owarn << "Details pressed !" << oendl;
00454 ErrorDialog* pErrDialog = new ErrorDialog( this, NULL, true );
00455 QFile errorFile( tempFileName );
00456 if ( errorFile.open(IO_ReadOnly) )
00457 {
00458 QTextStream t( &errorFile );
00459 QString s;
00460 while ( !t.eof() )
00461 {
00462 s += t.readLine();
00463 }
00464 errorFile.close();
00465
00466 pErrDialog->m_textarea->setText( s );
00467 }
00468 else
00469 {
00470 pErrDialog->m_textarea->setText( "Unable to open File: /tmp/backup.er" );
00471 }
00472 QPEApplication::execDialog( pErrDialog );
00473 delete pErrDialog;
00474 break;
00475 }
00476 setCaption(tr("Backup and Restore.. Failed !!"));
00477 return;
00478 }
00479 else
00480 {
00481 QMessageBox::information(this, tr( "Message" ), tr( "Backup Successful." ), QString(tr( "Ok" ) ) );
00482 }
00483
00484
00485 Config config( "BackupAndRestore" );
00486 config.setGroup( "LastLocation" );
00487 config.writeEntry( "LastStoreLocation", storeToLocation->currentText() );
00488
00489 setCaption(tr("Backup and Restore"));
00490 }
00491
00492
00493
00494
00495 int BackupAndRestore::getBackupFiles(QString &backupFiles, QListViewItem *parent)
00496 {
00497 QListViewItem * currentItem;
00498 QString currentHome;
00499 if(!parent)
00500 currentItem = backupList->firstChild();
00501 else
00502 {
00503 currentItem = parent->firstChild();
00504 currentHome = parent->text(BACKUP_LOCATION);
00505 }
00506
00507 uint count = 0;
00508 while( currentItem != 0 )
00509 {
00510 if(currentItem->text(HEADER_BACKUP) == "B" )
00511 {
00512 if(currentItem->childCount() == 0 )
00513 {
00514 if(parent == NULL)
00515 backupFiles += currentItem->text(BACKUP_LOCATION);
00516 else
00517 backupFiles += currentHome + currentItem->text(HEADER_NAME);
00518 backupFiles += " ";
00519 count++;
00520 }
00521 else
00522 {
00523 count += getBackupFiles(backupFiles, currentItem);
00524 }
00525 }
00526 currentItem = currentItem->nextSibling();
00527 }
00528 return count;
00529 }
00530
00531 void BackupAndRestore::sourceDirChanged(int selection)
00532 {
00533 restoreList->clear();
00534 rescanFolder(backupLocations[restoreSource->text(selection)]);
00535 }
00536
00537 void BackupAndRestore::fileListUpdate()
00538 {
00539 owarn << "void BackupAndRestore::fileListUpdate()" << oendl;
00540 restoreList->clear();
00541 rescanFolder( backupLocations[restoreSource->currentText()] );
00542 }
00543
00549 void BackupAndRestore::rescanFolder(QString directory)
00550 {
00551
00552 QDir d(directory);
00553 if(!d.exists())
00554 return;
00555
00556 d.setFilter( QDir::Files | QDir::Hidden | QDir::Dirs);
00557 const QFileInfoList *list = d.entryInfoList();
00558 QFileInfoListIterator it( *list );
00559 QFileInfo *file;
00560 while ( (file=it.current()) )
00561 {
00562
00563 if(file->isDir())
00564 {
00565 if(file->fileName() != ".." && file->fileName() != ".")
00566 {
00567 rescanFolder(directory + "/" + file->fileName());
00568 }
00569 }
00570 else
00571 {
00572
00573 if(file->fileName().contains(EXTENSION))
00574 (void)new QListViewItem(restoreList, file->fileName());
00575 }
00576 ++it;
00577 }
00578 }
00579
00584 void BackupAndRestore::restore()
00585 {
00586 QListViewItem *restoreItem = restoreList->currentItem();
00587 if(!restoreItem)
00588 {
00589 QMessageBox::critical(this, tr( "Message" ),
00590 tr( "Please select something to restore." ),QString( tr( "Ok") ) );
00591 return;
00592 }
00593
00594 if ( QMessageBox::warning( this, tr( "Restore" ),
00595 tr( "Would you really overwrite your local data?" ),
00596 tr( "Yes" ), tr( "No" ), "", 1 ) == 1 )
00597 return;
00598
00599 OWait *owait = new OWait();
00600 Global::statusMessage( tr( "Restore Backup..." ) );
00601 owait->show();
00602 qApp->processEvents();
00603
00604 QString restoreFile = backupLocations[restoreSource->currentText()];
00605
00606 restoreFile += "/" + restoreItem->text(0);
00607
00608 odebug << restoreFile << oendl;
00609
00610
00611
00612 QString commandLine = QString( "tar -tzf %1 | grep Applications/backup/exclude" ).arg( restoreFile.latin1() );
00613
00614 int r = system( commandLine );
00615
00616 QString startDir;
00617
00618 if( r != 0 )
00619 {
00620 startDir = QString( "/" );
00621 } else
00622 {
00623 startDir = QDir::homeDirPath();
00624 }
00625
00626
00627 commandLine = QString( "cd %1 && tar -zxf %2 2> %3" ).arg( startDir )
00628 .arg( restoreFile.latin1() )
00629 .arg( tempFileName.latin1() );
00630
00631 odebug << commandLine << oendl;
00632
00633 r = system( commandLine );
00634
00635 owait->hide();
00636 delete owait;
00637
00638
00639 if(r != 0)
00640 {
00641 QString errorMsg= tr( "Error from System:\n" ) + (QString)strerror( errno );
00642 switch( QMessageBox::critical(this, tr( "Message" ), tr( "Restore Failed." ) + "\n"
00643 + errorMsg, QString( tr( "Ok") ), QString( tr( "Details" ) ) ) )
00644 {
00645 case 1:
00646 owarn << "Details pressed !" << oendl;
00647 ErrorDialog* pErrDialog = new ErrorDialog( this, NULL, true );
00648 QFile errorFile( tempFileName );
00649 if ( errorFile.open(IO_ReadOnly) )
00650 {
00651 QTextStream t( &errorFile );
00652 QString s;
00653 while ( !t.eof() )
00654 {
00655 s += t.readLine();
00656 }
00657 errorFile.close();
00658
00659 pErrDialog->m_textarea->setText( s );
00660 }
00661 else
00662 {
00663 pErrDialog->m_textarea->setText( tr( "Unable to open File: %1" ).arg( "/tmp/backup.er" ) );
00664 }
00665 QPEApplication::execDialog( pErrDialog );
00666 delete pErrDialog;
00667
00668 setCaption(tr("Backup and Restore.. Failed !!"));
00669 return;
00670
00671 break;
00672
00673 }
00674 }
00675 else
00676 {
00677 QMessageBox::information(this, tr( "Message" ), tr( "Restore Successful." ), QString( tr( "Ok") ) );
00678 }
00679
00680
00681 Config config( "BackupAndRestore" );
00682 config.setGroup( "LastLocation" );
00683 config.writeEntry( "LastRestoreLocation", restoreSource->currentText() );
00684
00685 setCaption(tr("Backup and Restore"));
00686 }
00687
00695 QString BackupAndRestore::getExcludeFile()
00696 {
00697 QString excludeFileName = Global::applicationFileName( "backup", "exclude" );
00698 if ( !QFile::exists( excludeFileName ) )
00699 {
00700 QFile excludeFile( excludeFileName);
00701 if ( excludeFile.open( IO_WriteOnly ) == true )
00702 {
00703 QTextStream writeStream( &excludeFile );
00704 writeStream << "*.bck" << "\n";
00705 excludeFile.close();
00706 }
00707 else
00708 {
00709 return QString::null;
00710 }
00711 }
00712
00713 return excludeFileName;
00714 }
00715
00716 void BackupAndRestore::refreshLocations()
00717 {
00718 locationList->clear();
00719
00720
00721 Config config( "BackupAndRestore" );
00722 config.setGroup( "Locations" );
00723
00724 QStringList locations( config.readListEntry( "locations", '|' ) );
00725
00726 for ( QStringList::Iterator it = locations.begin(); it != locations.end(); ++it ) {
00727 (void) new QListViewItem( locationList, *it );
00728 }
00729 }
00730
00731 void BackupAndRestore::addLocation()
00732 {
00733 if ( ( !locationEdit->text().isEmpty() ) &&
00734 ( QDir( locationEdit->text() ).exists() ) )
00735 {
00736 (void) new QListViewItem( locationList, locationEdit->text() );
00737 locationEdit->setText( "" );
00738 saveLocations();
00739 }
00740 }
00741
00742 void BackupAndRestore::removeLocation()
00743 {
00744 if ( locationList->selectedItem() )
00745 {
00746 delete( locationList->selectedItem() );
00747 saveLocations();
00748 }
00749 }
00750
00751 void BackupAndRestore::saveLocations()
00752 {
00753 Config config("BackupAndRestore");
00754 config.setGroup("Locations");
00755
00756 QStringList locations;
00757 for ( QListViewItemIterator it( locationList ); it.current(); ++it )
00758 {
00759 locations.append( it.current()->text( 0 ) );
00760 }
00761 config.writeEntry( "locations", locations, '|' );
00762
00763 refreshBackupLocations();
00764 }
00765
00766 void BackupAndRestore::selectLocation()
00767 {
00768 QString location = OFileDialog::getDirectory( OFileSelector::DIRECTORYSELECTOR );
00769 if ( !location.isEmpty() )
00770 {
00771 locationEdit->setText( location );
00772 }
00773 }
00774
00775
00776