diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 37333bf25ad9a4c538250f5af2f9f1d666362883 (patch) | |
tree | c45e8df5b9efbffe07eb3d9340df7811c7e16943 /kdat/KDatMainWindow.cpp | |
download | tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.tar.gz tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeadmin@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdat/KDatMainWindow.cpp')
-rw-r--r-- | kdat/KDatMainWindow.cpp | 1381 |
1 files changed, 1381 insertions, 0 deletions
diff --git a/kdat/KDatMainWindow.cpp b/kdat/KDatMainWindow.cpp new file mode 100644 index 0000000..925ad92 --- /dev/null +++ b/kdat/KDatMainWindow.cpp @@ -0,0 +1,1381 @@ +// KDat - a tar-based DAT archiver +// Copyright (C) 1998-2000 Sean Vyain, svyain@mail.tds.net +// Copyright (C) 2001-2002 Lawrence Widman, kdat@cardiothink.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include <assert.h> +#include <time.h> +#include <unistd.h> +#include <sys/stat.h> +#include <stdlib.h> + +#include <qdatetime.h> +#include <qdir.h> +#include <qfileinfo.h> +#include <qkeycode.h> +#include <qlayout.h> +#include <qtextstream.h> + +#include <kapplication.h> +#include <kiconloader.h> +#include <kmenubar.h> +#include <kpopupmenu.h> +#include <ktoolbar.h> +#include <kglobal.h> +#include <kconfig.h> +#include <kmessagebox.h> +#include <kstringhandler.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +#include "ArchiveInfoWidget.h" +#include "BackupDlg.h" +#include "BackupOptDlg.h" +#include "BackupProfile.h" +#include "BackupProfileInfoWidget.h" +#include "BackupProfileManager.h" +#include "FileInfoWidget.h" +#include "FormatOptDlg.h" +#include "ImageCache.h" +#include "IndexDlg.h" +#include "InfoShellWidget.h" +#include "KDatMainWindow.h" +#include "Node.h" +#include "Options.h" +#include "OptionsDlg.h" +#include "Range.h" +#include "Tape.h" +#include "TapeDrive.h" +#include "TapeFileInfoWidget.h" +#include "TapeInfoWidget.h" +#include "TapeManager.h" +#include "Util.h" +#include "VerifyDlg.h" +#include "VerifyOptDlg.h" +#include "kdat.h" +#include "ktreeview.h" +#include <klocale.h> +#include <qsplitter.h> +#include <kstatusbar.h> + +#include "KDatMainWindow.moc" + +KDatMainWindow* KDatMainWindow::_instance = 0; + +KDatMainWindow* KDatMainWindow::getInstance() +{ + if ( _instance == 0 ) { + _instance = new KDatMainWindow(); + } + return _instance; +} + +#define KDAT_HORIZONTAL_LAYOUT +KDatMainWindow::KDatMainWindow() + : KMainWindow(0), _destroyed( FALSE ) +{ +#ifdef KDAT_HORIZONTAL_LAYOUT /* 2002-01-20 LEW */ + resize( 600, 600 ); /* was 600 by 400 */ +#else + resize( 600, 600 ); +#endif /* KDAT_HORIZONTAL_LAYOUT */ + + setIconText( i18n( "KDat: <no tape>" ) ); + setCaption( i18n( "KDat: <no tape>" ) ); + + // Create object popup menus. + _tapeDriveMenu = new QPopupMenu(); + _tapeDriveMenu->insertItem( i18n( "Mount Tape" ) , this, SLOT( fileMountTape() ) ); + _tapeDriveMenu->insertItem( i18n( "Recreate Tape Index" ), this, SLOT( fileIndexTape() ) ); + _tapeDriveMenu->insertSeparator(); + _tapeDriveMenu->insertItem( i18n( "Format Tape..." ), this, SLOT( fileFormatTape() ) ); + + _archiveMenu = new QPopupMenu(); + _archiveMenu->insertItem( i18n( "Delete Archive" ), this, SLOT( fileDeleteArchive() ) ); + + _mountedArchiveMenu = new QPopupMenu(); + _mountedArchiveMenu->insertItem( i18n( "Verify..." ) , this, SLOT( fileVerify() ) ); + _mountedArchiveMenu->insertItem( i18n( "Restore..." ) , this, SLOT( fileRestore() ) ); + _mountedArchiveMenu->insertSeparator(); + _mountedArchiveMenu->insertItem( i18n( "Delete Archive" ), this, SLOT( fileDeleteArchive() ) ); + + _mountedTapeFileMenu = new QPopupMenu(); + _mountedTapeFileMenu->insertItem( i18n( "Verify..." ) , this, SLOT( fileVerify() ) ); + _mountedTapeFileMenu->insertItem( i18n( "Restore..." ), this, SLOT( fileRestore() ) ); + + _localFileMenu = new QPopupMenu(); + _localFileMenu->insertItem( i18n( "Backup..." ), this, SLOT( fileBackup() ) ); + + _tapeMenu = new QPopupMenu(); + _tapeMenu->insertItem( i18n( "Delete Tape Index" ), this, SLOT( fileDeleteIndex() ) ); + + _backupProfileRootMenu = new QPopupMenu(); + _backupProfileRootMenu->insertItem( i18n( "Create Backup Profile" ), this, SLOT( fileNewBackupProfile() ) ); + + _backupProfileMenu = new QPopupMenu(); + _backupProfileMenu->insertItem( i18n( "Backup..." ), this, SLOT( fileBackup() ) ); + _backupProfileMenu->insertSeparator(); + _backupProfileMenu->insertItem( i18n( "Delete Backup Profile" ), this, SLOT( fileDeleteBackupProfile() ) ); + + _fileMenu = new QPopupMenu; + _fileMenu->insertItem( i18n( "Backup..." ) , this, SLOT( fileBackup() ) ); + _fileMenu->insertItem( i18n( "Restore..." ) , this, SLOT( fileRestore() ) ); + _fileMenu->insertItem( i18n( "Verify..." ) , this, SLOT( fileVerify() ) ); + _fileMenu->insertItem( i18n( "Mount Tape" ) , this, SLOT( fileMountTape() ) ); + _fileMenu->insertItem( i18n( "Recreate Tape Index" ) , this, SLOT( fileIndexTape() ) ); + _fileMenu->insertItem( i18n( "Create Backup Profile" ), this, SLOT( fileNewBackupProfile() ) ); + _fileMenu->insertSeparator(); + _fileMenu->insertItem( i18n( "Delete Archive" ) , this, SLOT( fileDeleteArchive() ) ); + _fileMenu->insertItem( i18n( "Delete Index" ) , this, SLOT( fileDeleteIndex() ) ); + _fileMenu->insertItem( i18n( "Delete Backup Profile" ), this, SLOT( fileDeleteBackupProfile() ) ); + _fileMenu->insertItem( i18n( "Format Tape..." ) , this, SLOT( fileFormatTape() ) ); + _fileMenu->insertSeparator(); + _fileMenu->insertItem( SmallIcon("exit"), i18n( "&Quit" ) , this, SLOT( fileQuit() ), CTRL + Key_Q ); + + _editMenu = new QPopupMenu; + _editMenu->insertItem( SmallIcon("configure"), i18n( "Configure KDat..." ) , this, SLOT( editPreferences() ) ); + + _menu = new KMenuBar( this ); + _menu->insertItem( i18n( "&File" ), _fileMenu ); + _menu->insertItem( i18n( "&Settings" ), _editMenu ); + _menu->insertSeparator(); + QString about = i18n( "KDat Version %1\n\nKDat is a tar-based tape archiver.\n\nCopyright (c) 1998-2000 Sean Vyain\nCopyright (c) 2001-2002 Lawrence Widman\nkdat@cardiothink.com" ).arg( KDAT_VERSION ); + _menu->insertItem( i18n( "&Help" ), helpMenu( about ) ); + + _toolbar = new KToolBar( this ); + + _toolbar->insertButton( *ImageCache::instance()->getTapeUnmounted(), 0, SIGNAL( clicked( int ) ), this, SLOT( fileMountTape() ), TRUE, i18n( "Mount/unmount tape" ) ); + + _toolbar->insertSeparator(); + + _toolbar->insertButton( *ImageCache::instance()->getBackup() , 1, SIGNAL( clicked( int ) ), this, SLOT( fileBackup() ) , TRUE, i18n( "Backup" ) ); + _toolbar->setButtonIconSet( 1, BarIconSet("kdat_backup")); + _toolbar->insertButton( *ImageCache::instance()->getRestore(), 2, SIGNAL( clicked( int ) ), this, SLOT( fileRestore() ), TRUE, i18n( "Restore" ) ); + _toolbar->setButtonIconSet( 2, BarIconSet("kdat_restore")); + _toolbar->insertButton( *ImageCache::instance()->getVerify() , 3, SIGNAL( clicked( int ) ), this, SLOT( fileVerify() ) , TRUE, i18n( "Verify" ) ); + _toolbar->setButtonIconSet( 3, BarIconSet("kdat_verify")); + addToolBar( _toolbar ); + + _statusBar = new KStatusBar( this ); + _statusBar->insertItem( i18n( "Ready." ), 0 ); + +#ifdef KDAT_HORIZONTAL_LAYOUT /* 2002-01-20 LEW */ + _panner = new QSplitter( QSplitter::Horizontal, this, "panner"); +#else + _panner = new QSplitter( QSplitter::Vertical, this, "panner"); +#endif /* KDAT_HORIZONTAL_LAYOUT */ + + // Create info viewers. + InfoShellWidget* infoShell = new InfoShellWidget( _panner ); + _tapeInfo = new TapeInfoWidget( infoShell ); + _archiveInfo = new ArchiveInfoWidget( infoShell ); + _backupProfileInfo = new BackupProfileInfoWidget( infoShell ); + _tapeFileInfo = new TapeFileInfoWidget( infoShell ); + _fileInfo = new FileInfoWidget( infoShell ); + + // Now set up the tree + _tree = new KTreeView( _panner ); + _tree->setExpandButtonDrawing( TRUE ); + +#ifdef KDAT_HORIZONTAL_LAYOUT /* 2002-01-20 LEW */ + _tree->setMinimumWidth( 300 ); + _panner->moveToFirst( _tree ); +#else + _tree->setMinimumHeight( 300 ); +#endif /* KDAT_HORIZONTAL_LAYOUT */ + + connect( _tree, SIGNAL( expanding( KTreeViewItem*, bool& ) ), this, SLOT( localExpanding( KTreeViewItem*, bool& ) ) ); + connect( _tree, SIGNAL( expanded( int ) ), this, SLOT( localExpanded( int ) ) ); + connect( _tree, SIGNAL( collapsed( int ) ), this, SLOT( localCollapsed( int ) ) ); + connect( _tree, SIGNAL( selected( int ) ), this, SLOT( localSelected( int ) ) ); + connect( _tree, SIGNAL( highlighted( int ) ), this, SLOT( localHighlighted( int ) ) ); + connect( _tree, SIGNAL( popupMenu( int, const QPoint& ) ), this, SLOT( localPopupMenu( int, const QPoint& ) ) ); + + setCentralWidget( _panner ); + + _tree->insertItem( _tapeDriveNode = new TapeDriveNode() ); + _tree->insertItem( _rootNode = new RootNode() ); + _tree->insertItem( _backupProfileRootNode = new BackupProfileRootNode() ); + _tree->insertItem( new TapeIndexRootNode() ); + + connect( TapeDrive::instance(), SIGNAL( sigStatus( const QString & ) ), this, SLOT( status( const QString & ) ) ); + + setTapePresent( FALSE ); + + connect( Options::instance(), SIGNAL( sigTapeDevice() ), this, SLOT( slotTapeDevice() ) ); + + connect( TapeManager::instance(), SIGNAL( sigTapeMounted() ) , this, SLOT( slotTapeMounted() ) ); + connect( TapeManager::instance(), SIGNAL( sigTapeUnmounted() ), this, SLOT( slotTapeUnmounted() ) ); + + configureUI( 0 ); +} + +KDatMainWindow::~KDatMainWindow() +{ + _destroyed = TRUE; + + if ( Options::instance()->getLockOnMount() ) { + TapeDrive::instance()->unlock(); + } + delete _tapeDriveMenu; + delete _archiveMenu; + delete _mountedArchiveMenu; + delete _mountedTapeFileMenu; + delete _localFileMenu; + delete _tapeMenu; + delete _backupProfileRootMenu; + delete _backupProfileMenu; + +} + +void KDatMainWindow::popupTapeDriveMenu( const QPoint& p ) +{ + // Configure menu before popping up. + if ( TapeManager::instance()->getMountedTape() ) { + _tapeDriveMenu->changeItem( i18n( "Unmount Tape" ), _tapeDriveMenu->idAt( 0 ) ); + _tapeDriveMenu->setItemEnabled( _tapeDriveMenu->idAt( 1 ), TRUE ); + } else { + _tapeDriveMenu->changeItem( i18n( "Mount Tape" ), _tapeDriveMenu->idAt( 0 ) ); + _tapeDriveMenu->setItemEnabled( _tapeDriveMenu->idAt( 1 ), FALSE ); + } + + _tapeDriveMenu->popup( p ); +} + +void KDatMainWindow::popupArchiveMenu( const QPoint& p ) +{ + _archiveMenu->popup( p ); +} + +void KDatMainWindow::popupMountedArchiveMenu( const QPoint& p ) +{ + _mountedArchiveMenu->popup( p ); +} + +void KDatMainWindow::popupMountedTapeFileMenu( const QPoint& p ) +{ + _mountedTapeFileMenu->popup( p ); +} + +void KDatMainWindow::popupLocalFileMenu( const QPoint& p ) +{ + // Configure menu before popping up. + _localFileMenu->setItemEnabled( _localFileMenu->idAt( 0 ), ( TapeManager::instance()->getMountedTape() != 0 ) && ( !TapeDrive::instance()->isReadOnly() ) ); + + _localFileMenu->popup( p ); +} + +void KDatMainWindow::popupTapeMenu( const QPoint& p ) +{ + _tapeMenu->popup( p ); +} + +void KDatMainWindow::popupBackupProfileRootMenu( const QPoint& p ) +{ + _backupProfileRootMenu->popup( p ); +} + +void KDatMainWindow::popupBackupProfileMenu( const QPoint& p ) +{ + // Configure menu before popping up. + _backupProfileMenu->setItemEnabled( _backupProfileMenu->idAt( 0 ), ( TapeManager::instance()->getMountedTape() != 0 ) && ( !TapeDrive::instance()->isReadOnly() ) ); + + _backupProfileMenu->popup( p ); +} + +void KDatMainWindow::hideInfo() +{ + _archiveInfo->hide(); + _backupProfileInfo->hide(); + _tapeInfo->hide(); + _tapeFileInfo->hide(); + _fileInfo->hide(); +} + +void KDatMainWindow::showTapeInfo( Tape* tape ) +{ + assert( tape ); + + hideInfo(); + + _tapeInfo->setTape( tape ); + _tapeInfo->show(); +} + +void KDatMainWindow::showArchiveInfo( Archive* archive ) +{ + assert( archive ); + + hideInfo(); + + _archiveInfo->setArchive( archive ); + _archiveInfo->show(); +} + +void KDatMainWindow::showBackupProfileInfo( BackupProfile* backupProfile ) +{ + assert( backupProfile ); + + hideInfo(); + + _backupProfileInfo->setBackupProfile( backupProfile ); + _backupProfileInfo->show(); +} + +void KDatMainWindow::showTapeFileInfo( File* file ) +{ + assert( file ); + + hideInfo(); + + _tapeFileInfo->setFile( file ); + _tapeFileInfo->show(); +} + +void KDatMainWindow::showFileInfo( const QString & name ) +{ + assert( !name.isNull() ); + + hideInfo(); + + _fileInfo->setFile( name ); + _fileInfo->show(); +} + +void KDatMainWindow::localExpanding( KTreeViewItem* item, bool& allow ) +{ + ((Node*)item)->expanding( allow ); +} + +void KDatMainWindow::localExpanded( int index ) +{ + ((Node*)_tree->itemAt( index ))->expanded(); +} + +void KDatMainWindow::localCollapsed( int index ) +{ + ((Node*)_tree->itemAt( index ))->collapsed(); +} + +void KDatMainWindow::localSelected( int index ) +{ + Node* item = (Node*)_tree->itemAt( index ); + + /* 2002-01-30 LEW: RG and I don't like the behavior in which + the subtree expands or contracts when a directory is selected + or unselected. + so make the tree look the same when we are done.... + The goal is to redraw the icon to the left of the item. + There's gotta be a better way to do this. */ + if ( item->isExpanded() ) { + _tree->collapseItem( index ); + _tree->expandItem( index ); // 2002-01-30 LEW + } else { + _tree->expandItem( index ); + _tree->collapseItem( index ); // 2002-01-30 LEW + } + // repaint(); // this doesn't work 2002-01-30 LEW + /* 2002-01-30 LEW: RG and I don't like this behavior */ +} + +void KDatMainWindow::localHighlighted( int index ) +{ + Node* item = (Node*)_tree->itemAt( index ); + + if ( item ) { + item->selected(); + } + + configureUI( TapeManager::instance()->getMountedTape() ); +} + +void KDatMainWindow::localPopupMenu( int index, const QPoint& p ) +{ + Node* item = (Node*)_tree->itemAt( index ); + item->popupMenu( p ); +} + +void KDatMainWindow::fileBackup() +{ + BackupProfile backupProfile; + + /* 2002-01-28 LEW */ + // To the i18n translator: I apologize for this long text on the last day to submit + // i18n changes. But, the program isn't very usable without this information. Thanks. LEW + // (later today): now the program works correctly! Why? Beats me! + QString msg = i18n("KDat will dump your files properly to tape, but may not be able\n" + "to restore them. To restore your files by hand, you need to know\n" + "the name of the *non-rewinding* version of your tape device %1.\n" + ).arg(Options::instance()->getTapeDevice()); + QString msg2 = i18n("For example, if your device is /dev/st0, the non-rewinding version\n" + "is /dev/nst0. If your device name doesn't look like that, type\n" + "\"ls -l %2\" in a terminal window to see the real name of your\n" + "tape drive. Substitute that name for /dev/nst0 below.\n" + "Open a terminal window and type the following:\n" + " tar tfv /dev/nst0; tar tfv /dev/nst0\n" + " tar xfv /dev/nst0\n" + "The third call to \"tar\" will retrieve your data into your\n" + "current directory. Please let us know if this happens to you!\n" + " - KDat Maintenance Team\n" + ).arg(Options::instance()->getTapeDevice()); + msg = msg.append(msg2); + KMessageBox::sorry( this, msg); + /* 2002-01-28 LEW */ + + if ( ( _tree->getCurrentItem() ) && ( ((Node*)_tree->getCurrentItem())->isType( Node::BackupProfileNodeType ) ) ) { + BackupProfile* bp = ((BackupProfileNode*)_tree->getCurrentItem())->getBackupProfile(); + backupProfile.setArchiveName( bp->getArchiveName() ); + backupProfile.setWorkingDirectory( bp->getWorkingDirectory() ); + backupProfile.setAbsoluteFiles( bp->getAbsoluteFiles() ); + backupProfile.setOneFilesystem( bp->isOneFilesystem() ); + backupProfile.setIncremental( bp->isIncremental() ); + backupProfile.setSnapshotFile( bp->getSnapshotFile() ); + backupProfile.setRemoveSnapshot( bp->getRemoveSnapshot() ); + } else { + QString name; + name = i18n( "Archive created on %1" ).arg( KGlobal::locale()->formatDate(QDate::currentDate(), true) ); + name = name.stripWhiteSpace(); + + QStringList files; + getBackupFiles( files ); + + backupProfile.setArchiveName( name ); + backupProfile.setAbsoluteFiles( files ); + backupProfile.setOneFilesystem( TRUE ); + backupProfile.setIncremental( FALSE ); + backupProfile.setSnapshotFile( "snapshot" ); + backupProfile.setRemoveSnapshot( FALSE ); + } + + int ret = 0; + BackupOptDlg dlg( &backupProfile, this ); + if ( dlg.exec() == QDialog::Accepted ) { + // Begin backup. + status( i18n( "Performing backup..." ) ); + int size = calcBackupSize( dlg.getWorkingDirectory(), dlg.isOneFilesystem(), dlg.getRelativeFiles(), dlg.isIncremental(), dlg.getSnapshotFile(), dlg.getRemoveSnapshot() ); + + // Check to see whether user aborted the backup + if ( size < 0) { + status( i18n( "Backup canceled." ) ); + return; + } + + // Make sure the archive will fit on the tape. + int tapeSize = 1; + QPtrListIterator<Archive> i( TapeManager::instance()->getMountedTape()->getChildren() ); + if ( i.toLast() != NULL ) { + tapeSize = i.current()->getEndBlock(); + tapeSize = (int)((float)tapeSize / 1024.0 * (float)Options::instance()->getTapeBlockSize()) + 1; + } + if ( tapeSize + size >= TapeManager::instance()->getMountedTape()->getSize() ) { + // Warn user that tape is probably too short. + QString msg; + msg = i18n( "WARNING: The estimated archive size is %1 KB but " + "the tape has only %2 KB of space!\n" + "Back up anyway?" ) + .arg(KGlobal::locale()->formatNumber(size, 0)) + .arg(KGlobal::locale()->formatNumber(TapeManager::instance()->getMountedTape()->getSize() - tapeSize, 0 )); + int result = KMessageBox::warningContinueCancel( this, + msg, i18n("Backup"), i18n("Backup") ); + if ( result != KMessageBox::Continue) { + status( i18n( "Backup canceled." ) ); + return; + } + } + + if ( TapeDrive::instance()->getFile() < 0 ) { + // Rewind tape. + status( i18n( "Rewinding tape..." ) ); + if ( !TapeDrive::instance()->rewind() ) { + KMessageBox::error( this, + i18n("Cannot rewind tape.\nBackup aborted."), + i18n("Backup Error")); + status( i18n( "Backup aborted." ) ); + return; + } + } + + // Go to end of tape. + status( i18n( "Skipping to end of tape..." ) ); + if ( !TapeDrive::instance()->nextFile( TapeManager::instance()->getMountedTape()->getChildren().count() + 1 - TapeDrive::instance()->getFile() ) ) { + KMessageBox::error( this, + i18n("Cannot get to end of tape.\nBackup aborted."), + i18n("Backup Error")); + status( i18n( "Backup aborted." ) ); + return; + } + + status( i18n( "Backup in progress..." ) ); + BackupDlg backupDlg( dlg.getArchiveName(), dlg.getWorkingDirectory(), dlg.getRelativeFiles(), dlg.isOneFilesystem(), dlg.isIncremental(), dlg.getSnapshotFile(), dlg.getRemoveSnapshot(), size, TapeManager::instance()->getMountedTape(), this ); + ret = backupDlg.exec(); + +// status( i18n( "Rewinding tape..." ) ); +// TapeDrive::instance()->rewind(); +// if ( !TapeDrive::instance()->prevFile( 1 ) ) { +// status( i18n( "Rewinding tape..." ) ); +// TapeDrive::instance()->rewind(); +// } + } + + // All done. + if ( ret == QDialog::Accepted ) { + status( i18n( "Backup complete." ) ); + } else { + status( i18n( "Backup aborted." ) ); + } +} + +void KDatMainWindow::fileRestore() +{ + doVerify( TRUE ); +} + +void KDatMainWindow::fileVerify() +{ + doVerify( FALSE ); +} + +void KDatMainWindow::doVerify( bool restore ) +{ + RangeableNode* rangeableNode = 0; + MountedArchiveNode* archiveNode = 0; + QStringList files; + Archive* archive = 0; + // Check for marked files first. + for ( int i = _tapeDriveNode->childCount() - 1; i >= 0; i-- ) { + if ( ( ((SelectableNode*)_tapeDriveNode->childAt( i ))->isSelected() ) || + ( ((SelectableNode*)_tapeDriveNode->childAt( i ))->hasSelectedChildren() )) { + archiveNode = (MountedArchiveNode*)_tapeDriveNode->childAt( i ); + archive = archiveNode->getArchive(); + /* 2002-01-30 LEW */ +#ifdef DEBUG + printf("KDatMainWindow::doVerify: %d node of %s: ", i, + (SelectableNode*)_tapeDriveNode->getText().latin1() ); + if( ((SelectableNode*)_tapeDriveNode->childAt( i ))->isSelected() ){ + printf("is completely selected\n"); + } else { + printf("is partially selected\n"); + } +#endif /* DEBUG */ + /* 2002-01-30 LEW */ + break; + } + } + + if ( !archiveNode ) { + if ( ((Node*)_tree->getCurrentItem())->isType( Node::RangeableNodeType ) ) { + rangeableNode = (RangeableNode*)_tree->getCurrentItem(); + Node* parent = rangeableNode; + for ( ; !parent->isType( Node::MountedArchiveNodeType ); parent = (Node*)parent->getParent() ); + assert( parent ); + archive = ((MountedArchiveNode*)parent)->getArchive(); + } + } + + assert( archive ); + QPtrListIterator<Archive> it( archive->getTape()->getChildren() ); + int fileno; + for ( fileno = 1; ( it.current() ) && ( it.current() != archive ); ++it, fileno++ ); + + assert( archiveNode || rangeableNode ); + assert( fileno > -1 ); + + RangeList ranges; + if ( rangeableNode ) { + QPtrListIterator<Range> it( rangeableNode->getRanges() ); + for ( ; it.current(); ++it ) { + ranges.addRange( it.current()->getStart(), it.current()->getEnd() ); + } + if ( rangeableNode->isType( Node::MountedArchiveNodeType ) ) { + // Make sure the mounted archive node has populated its children. + archiveNode = (MountedArchiveNode*)rangeableNode; + if ( archiveNode->childCount() == 0 ) { + bool dummy = TRUE; + archiveNode->expanding( dummy ); + } + + for ( int i = rangeableNode->childCount() - 1; i >= 0; i-- ) { + if ( ((Node*)rangeableNode->childAt( i ))->isType( Node::MountedTapeDirectoryNodeType ) ) { + files.append( ((MountedTapeDirectoryNode*)rangeableNode->childAt( i ))->getFullPath() ); + } else if ( ((Node*)rangeableNode->childAt( i ))->isType( Node::MountedTapeFileNodeType ) ) { + files.append( ((MountedTapeFileNode*)rangeableNode->childAt( i ))->getFullPath() ); + } else { + assert( FALSE ); + } + } + } else if ( rangeableNode->isType( Node::MountedTapeDirectoryNodeType ) ) { + files.append( ((MountedTapeDirectoryNode*)rangeableNode)->getFullPath() ); + } else if ( rangeableNode->isType( Node::MountedTapeFileNodeType ) ) { + files.append( ((MountedTapeFileNode*)rangeableNode)->getFullPath() ); + } else { + assert( FALSE ); + } + } else { + // Compile a list of files to verify/restore. + QPtrStack<RangeableNode> stack; + + // Make sure the mounted archive node has populated its children. + if ( archiveNode->childCount() == 0 ) { + bool dummy = TRUE; + archiveNode->expanding( dummy ); + } + + for ( int i = archiveNode->childCount() - 1; i >= 0; i-- ) { + stack.push( (RangeableNode*)archiveNode->childAt( i ) ); + } + RangeableNode* sel = 0; + while ( stack.count() > 0 ) { + sel = stack.pop(); + if ( sel->isSelected() ) { + QPtrListIterator<Range> it( sel->getRanges() ); + for ( ; it.current(); ++it ) { + ranges.addRange( it.current()->getStart(), it.current()->getEnd() ); + } + + if ( sel->isType( Node::MountedTapeDirectoryNodeType ) ) { + files.append( ((MountedTapeDirectoryNode*)sel)->getFullPath() ); + } else if ( sel->isType( Node::MountedTapeFileNodeType ) ) { + files.append( ((MountedTapeFileNode*)sel)->getFullPath() ); + } else { + assert( FALSE ); + } + } else if ( sel->hasSelectedChildren() ) { + for ( int i = sel->childCount() - 1; i >= 0; i-- ) { + stack.push( (RangeableNode*)sel->childAt( i ) ); + } + } + } + } + + char buf[1024]; + VerifyOptDlg dlg( getcwd( buf, 1024 ), files, restore, this ); + if ( dlg.exec() == QDialog::Accepted ) { + if ( restore ) { + status( i18n( "Restore in progress..." ) ); + } else { + status( i18n( "Verify in progress..." ) ); + } + VerifyDlg verifyDlg( dlg.getWorkingDirectory(), fileno, ranges, restore, this ); + int ret = verifyDlg.exec(); + + if ( ret == QDialog::Accepted ) { + if ( restore ) { + status( i18n( "Restore complete." ) ); + } else { + status( i18n( "Verify complete." ) ); + } + } else { + if ( restore ) { + status( i18n( "Restore aborted." ) ); + } else { + status( i18n( "Verify aborted." ) ); + } + } + } +} + +void KDatMainWindow::fileMountTape() +{ + static QString msg; + + // construct helpful error message (same as in fileFormatTape()) + msg = i18n("There appears to be no tape in the drive %1. Please\n" + "check \"Edit->Preferences\" to make sure the\n" + "correct device is selected as the tape drive (e.g.\n" + "/dev/st0). If you hear the tape drive moving, wait\n" + "until it stops and then try mounting it again.") + .arg(Options::instance()->getTapeDevice()); + + if ( !TapeManager::instance()->getMountedTape() ) { + if ( Options::instance()->getLoadOnMount() ) { + if ( !TapeDrive::instance()->load() ) { + KMessageBox::sorry( this, msg); + return; + } + } + + if ( TapeDrive::instance()->isTapePresent() ) { + setTapePresent( TRUE ); + } else { + KMessageBox::sorry( this, msg); + } + } else { + setTapePresent( FALSE ); + } +} + +void KDatMainWindow::fileIndexTape() +{ + int result = KMessageBox::warningContinueCancel( this, + i18n( "The current tape index will be overwritten, continue?" ), + i18n( "Index Tape"), i18n("Overwrite")); + if ( result == KMessageBox::Continue) { + TapeManager::instance()->getMountedTape()->clear(); + IndexDlg dlg( TapeManager::instance()->getMountedTape(), this ); + if ( dlg.exec() == QDialog::Accepted ) { + QString title; + title = i18n( "KDat: %1" ).arg( TapeManager::instance()->getMountedTape()->getName() ); + setCaption( title ); + setIconText( title ); + + status( i18n( "Index complete." ) ); + } else { + status( i18n( "Index aborted." ) ); + } + } +} + +void KDatMainWindow::fileDeleteArchive() +{ + Node* sel = (Node*)_tree->getCurrentItem(); + if ( ( !sel ) || ( !sel->isType( Node::ArchiveNodeType ) && !sel->isType( Node::MountedArchiveNodeType ) ) ) { + KMessageBox::sorry( this, i18n( "No archive is selected.\n" + "In order to delete an archive, the archive to be deleted " + "must be selected in the tree first." )); + return; + } + + // Find the selected archive and see if it has any archives after it. + Archive* archive = 0; + if ( sel->isType( Node::ArchiveNodeType ) ) { + archive = ((ArchiveNode*)sel)->getArchive(); + } else if ( sel->isType( Node::MountedArchiveNodeType ) ) { + archive = ((MountedArchiveNode*)sel)->getArchive(); + } + assert( archive ); + + Tape* tape = archive->getTape(); + QPtrListIterator<Archive> i( tape->getChildren() ); + for ( ; i.current(); ++i ) { + if ( i.current() == archive ) { + break; + } + } + assert( i.current() ); + + ++i; + if ( i.current() ) { + // There are other archives after this one on the tape. + QString list; + for ( ; i.current(); ++i ) { + list.append( "\n " ); + list.append( i.current()->getName() ); + } + + QString msg = + i18n( "An archive cannot be removed from the middle of the tape. If\nthe archive '%1' is deleted then\nthe following archives will also be deleted:\n%2\n\nDelete all listed archives?" ).arg(archive->getName()).arg(list); + int result = KMessageBox::warningContinueCancel( this, + msg, i18n("Delete Archive"), i18n("Delete All")); + if (result == KMessageBox::Continue) { + tape->removeChild( archive ); + emit status( i18n( "Archives deleted." ) ); + if ( _tree->getCurrentItem() ) { + ((Node*)_tree->getCurrentItem())->selected(); + } + configureUI( TapeManager::instance()->getMountedTape() ); + } + } else { + // This is the last (known) archive on the tape. + QString msg = + i18n( "Really delete the archive '%1'?" ).arg(archive->getName()); + int result = KMessageBox::warningContinueCancel( this, + msg, i18n("Delete Archive"), i18n("Delete")); + if (result == KMessageBox::Continue) { + tape->removeChild( archive ); + emit status( i18n( "Archive deleted." ) ); + if ( _tree->getCurrentItem() ) { + ((Node*)_tree->getCurrentItem())->selected(); + } + configureUI( TapeManager::instance()->getMountedTape() ); + } + } +} + +void KDatMainWindow::fileDeleteIndex() +{ + Node* sel = (Node*)_tree->getCurrentItem(); + if ( ( !sel ) || ( !sel->isType( Node::TapeNodeType ) ) ) { + KMessageBox::sorry( this, i18n( "No tape index is selected.\n" + "In order to delete a tape index, the tape index to be deleted " + "must be selected in the tree first." )); + return; + } + + Tape* tape = ((TapeNode*)sel)->getTape(); + assert( tape ); + if ( tape == TapeManager::instance()->getMountedTape() ) { + KMessageBox::sorry( this, i18n( "Tape is still mounted. " + "The index for a mounted tape cannot be deleted.\n" + "Unmount the tape and try again." )); + return; + } + + QString msg = + i18n( "Really delete the index for '%1'?" ).arg(tape->getName()); + int result = KMessageBox::warningContinueCancel( this, + msg, i18n("Delete Tape Index"), i18n("Delete")); + if (result == KMessageBox::Continue) { + TapeManager::instance()->removeTape( tape ); + emit status( i18n( "Tape index deleted." ) ); + if ( _tree->getCurrentItem() ) { + ((Node*)_tree->getCurrentItem())->selected(); + } + configureUI( TapeManager::instance()->getMountedTape() ); + } +} + +void KDatMainWindow::fileFormatTape() +{ + static QString msg; + + // construct helpful error message (same as in fileMountTape()) + msg = i18n("There appears to be no tape in the drive %1. Please\n" + "check \"Edit->Preferences\" to make sure the\n" + "correct device is selected as the tape drive (e.g.\n" + "/dev/st0). If you hear the tape drive moving, wait\n" + "until it stops and then try mounting it again.") + .arg(Options::instance()->getTapeDevice()); + + if ( !TapeDrive::instance()->isTapePresent() ) { + KMessageBox::sorry( this, msg ); + return; + } + + if ( TapeDrive::instance()->isReadOnly() ) { + KMessageBox::sorry( this, i18n( "The tape in the drive is write protected.\nPlease disable write protection and try again." )); + return; + } + + int result = KMessageBox::warningContinueCancel( this, + i18n( "All data currently on the tape will be lost.\n" + "Are you sure you want to continue?" ), + i18n("Format Tape"), i18n("Format")); + if (result == KMessageBox::Continue ) { + QString name; + name = i18n( "Tape created on %1" ).arg( KGlobal::locale()->formatDate(QDate::currentDate(), true) ); + FormatOptDlg dlg( name.stripWhiteSpace(), this ); + if ( dlg.exec() != QDialog::Accepted ) { + return; + } + + // Delete old index file. + if ( TapeManager::instance()->getMountedTape() ) { + TapeManager::instance()->removeTape( TapeManager::instance()->getMountedTape() ); + TapeManager::instance()->unmountTape(); + } + + Tape* tape = new Tape(); + tape->setName( dlg.getName() ); + tape->setSize( dlg.getSize() ); + + status( i18n( "Formatting tape..." ) ); + tape->format(); + TapeManager::instance()->addTape( tape ); + status( i18n( "Format complete." ) ); + + setTapePresent( FALSE, FALSE ); + setTapePresent( TRUE, FALSE ); + } +} + +void KDatMainWindow::fileNewBackupProfile() +{ + BackupProfile* backupProfile = new BackupProfile(); + + // Pick a unique name. + QString name; + for ( int i = 1; ; i++ ) { + name = i18n( "Backup Profile %1").arg( i ); + QStringList list = BackupProfileManager::instance()->getBackupProfileNames(); + QStringList::Iterator it = list.begin(); + for ( ; it != list.end(); ++it ) { + if ( name == *it ) { + break; + } + } + if ( it == list.end() ) { + // Name is unique. + break; + } + } + + QStringList files; + getBackupFiles( files ); + + backupProfile->setName( name ); + backupProfile->setArchiveName( i18n( "Archive" ) ); + backupProfile->setWorkingDirectory( Util::longestCommonPath( files ) ); + if ( !backupProfile->getWorkingDirectory() ) { + backupProfile->setWorkingDirectory( "/" ); + } + backupProfile->setAbsoluteFiles( files ); + backupProfile->setOneFilesystem( TRUE ); + backupProfile->setIncremental( FALSE ); + backupProfile->setSnapshotFile( "snapshot" ); + backupProfile->setRemoveSnapshot( FALSE ); + backupProfile->save(); + + BackupProfileManager::instance()->addBackupProfile( backupProfile ); + + _backupProfileRootNode->setSelected( backupProfile ); +} + +void KDatMainWindow::fileDeleteBackupProfile() +{ + Node* sel = (Node*)_tree->getCurrentItem(); + if ( ( !sel ) || ( !sel->isType( Node::BackupProfileNodeType ) ) ) { + KMessageBox::sorry( this, i18n( "In order to delete a backup profile, the backup profile to be deleted " + "must be selected in the tree first." )); + return; + } + + BackupProfile* backupProfile = ((BackupProfileNode*)sel)->getBackupProfile(); + assert( backupProfile ); + + QString msg = + i18n("Really delete backup profile '%1'?").arg(backupProfile->getName()); + int result = KMessageBox::warningContinueCancel( this, + msg, i18n("Delete Backup Profile"), i18n("Delete")); + if (result == KMessageBox::Continue) { + BackupProfileManager::instance()->removeBackupProfile( backupProfile ); + emit status( i18n( "Backup profile deleted." ) ); + if ( _tree->getCurrentItem() ) { + ((Node*)_tree->getCurrentItem())->selected(); + } + configureUI( TapeManager::instance()->getMountedTape() ); + } +} + +void KDatMainWindow::fileQuit() +{ + KApplication::kApplication()->quit(); +} + +void KDatMainWindow::editPreferences() +{ + OptionsDlg dlg( this ); + dlg.exec(); +} + +void KDatMainWindow::help() +{ + KApplication::kApplication()->invokeHelp( ); +} + +void KDatMainWindow::setTapePresent( bool tapePresent, bool eject ) +{ + if ( TapeManager::instance()->getMountedTape() ) { + if ( !tapePresent ) { + TapeManager::instance()->unmountTape(); + + if ( ( eject ) && ( Options::instance()->getLockOnMount() ) ) { + TapeDrive::instance()->unlock(); + } + + if ( ( eject ) && ( Options::instance()->getEjectOnUnmount() ) ) { + TapeDrive::instance()->eject(); + } + + status( i18n( "Tape unmounted." ) ); + } + } else { + if ( tapePresent ) { + status( i18n( "Reading tape header..." ) ); + Tape* tape = TapeDrive::instance()->readHeader(); + + if ( tape ) { + TapeManager::instance()->mountTape( tape ); + } else { + if ( TapeDrive::instance()->isReadOnly() ) { + KMessageBox::sorry( this, i18n( "This tape has not been formatted by KDat." )); + } else { + int result = KMessageBox::questionYesNo( this, + i18n( "This tape has not been formatted by KDat.\n\nWould you like to format it now?" ), QString::null, i18n("Format"), i18n("Do Not Format")); + if (result == KMessageBox::Yes) { + fileFormatTape(); + return; + } + } + } + + if ( Options::instance()->getLockOnMount() ) { + TapeDrive::instance()->lock(); + } + + status( i18n( "Tape mounted." ) ); + } + } +} + +void KDatMainWindow::status( const QString & msg ) +{ + _statusBar->changeItem( msg, 0 ); + KApplication::kApplication()->processEvents(); +} + +void KDatMainWindow::show() +{ + KMainWindow::show(); + + hideInfo(); +} + +// 2002-01-21 LEW: returns backup size in KB, or -1 if user chose +// to abort the backup. +int KDatMainWindow::calcBackupSize( const QString& workingDir, bool local, const QStringList& files, + bool incremental, const QString& snapshot, bool removeSnapshot ) +{ + int return_value; + + chdir( QFile::encodeName(workingDir) ); + + bool useSnapshot = !snapshot.isEmpty() && !removeSnapshot; + + int tmp = 0; + if ( incremental && !removeSnapshot ) { + QFile snap( snapshot ); + if ( snap.exists() && snap.open( IO_ReadOnly ) ) { + QTextStream t( &snap ); + t >> tmp; + } else { + useSnapshot = FALSE; + } + } + QDateTime mtime; + mtime.setTime_t( tmp ); + + int size = 0; + + /* 2002-01-24 LEW: start of backup-cancel dialog */ + create_backup_dialog(); + stop_flag = FALSE; // initialize the flag that tells us whether use + // cancelled the backup via the dialog. + /* 2002-01-24 LEW: end of backup-cancel dialog */ + + QStringList filesTmp = files; + QStringList::Iterator ii = filesTmp.begin(); + for ( ; ii != filesTmp.end(); ++ii ) { + + // Is this a normal file, or a directory? + QFileInfo finfo( *ii ); + if ( !finfo.isDir() ) { + if ( ( !useSnapshot ) || ( finfo.lastModified() > mtime ) ) { + size += finfo.size() / 512; + if ( finfo.size() % 512 ) { + size++; + } + } + continue; + } + + QPtrStack<QString> dirStack; + dirStack.push( new QString( *ii ) ); + + // If stay on one file system, get device of starting directory. + dev_t device = 0; + struct stat info; + if ( local ) { + if ( lstat( QFile::encodeName(*ii), &info ) != 0 ) { + device = 0; + } else { + device = info.st_dev; + } + } + + QString msg; + // msg.truncate( 4095 ); + QDir dir; + const QFileInfoList* infoList; + while ( !dirStack.isEmpty() ) { + if( stop_flag == TRUE ) break; + QString* path = dirStack.pop(); + msg = i18n("Estimating backup size: %1, %2" ) + .arg(Util::kbytesToString( size / 2 )) + .arg(KStringHandler::csqueeze(*path, 60)); + status( msg ); + KApplication::kApplication()->processEvents(); + dir.setPath( *path ); + infoList = dir.entryInfoList( QDir::Hidden | QDir::Files | QDir::Dirs, 0 ); + if ( infoList ) { + QFileInfoListIterator i( *infoList ); + for ( ; i.current(); ++i ) { + if ( ( i.current()->fileName() != "." ) && ( i.current()->fileName() != ".." ) ) { + size++; + if ( i.current()->isSymLink() ) { + } else if ( i.current()->isDir() ) { + if ( local ) { + if ( lstat( QFile::encodeName(i.current()->absFilePath()), &info ) == 0 ) { + if ( device == info.st_dev ) { + dirStack.push( new QString( i.current()->absFilePath() ) ); + } + } + } else { + dirStack.push( new QString( i.current()->absFilePath() ) ); + } + } else if ( ( !useSnapshot ) || ( i.current()->lastModified() > mtime ) ) { + size += i.current()->size() / 512; + if ( i.current()->size() % 512 ) { + size++; + } + } + } + } + } + } + } + + delete _backupdialog; // we're done, so zap this widget + + // Convert size in tar blocks to size in kbytes. + return_value = size / 2; + + if( stop_flag == TRUE ) return_value = -1; + + return return_value; +} + +void KDatMainWindow::getBackupFiles( QStringList& files ) +{ + if ( !_rootNode->isSelected() && !_rootNode->hasSelectedChildren() ) { + // Backup the entire subtree. + if ( ( _tree->getCurrentItem() ) && ( ((Node*)_tree->getCurrentItem())->isType( Node::ArchiveableNodeType ) ) ) { + files.append( ((ArchiveableNode*)_tree->getCurrentItem())->getFullPath() ); + } + } else { + // Compile a list of files to backup. + QPtrStack<ArchiveableNode> stack; + stack.push( _rootNode ); + ArchiveableNode* sel = 0; + while ( stack.count() > 0 ) { + sel = stack.pop(); + if ( sel->isSelected() ) { + files.append( sel->getFullPath() ); + } else if ( sel->hasSelectedChildren() ) { + for ( int i = sel->childCount() - 1; i >= 0; i-- ) { + stack.push( (ArchiveableNode*)sel->childAt( i ) ); + } + } + } + } +} + +void KDatMainWindow::setBackupFiles( const QStringList& files ) +{ + _rootNode->setSelected( FALSE ); + + QString tmp; + QStringList filesTmp = files; + QStringList::Iterator it = filesTmp.begin(); + for ( ; it != filesTmp.end(); ++it ) { + ArchiveableNode* n = _rootNode; + while ( n ) { + if ( n->getFullPath() == *it ) { + n->setSelected( TRUE ); + n = 0; + } else { + if ( n->childCount() == 0 ) { + bool dummy = TRUE; + n->expanding( dummy ); + } + int i; + for ( i = n->childCount() - 1; i >=0; i-- ) { + tmp = ((ArchiveableNode*)n->childAt( i ))->getFullPath(); + if ( tmp == (*it).left( tmp.length() ) ) { + n = (ArchiveableNode*)n->childAt( i ); + break; + } + } + if ( i < 0 ) { + n = 0; + } + } + } + } +} + +void KDatMainWindow::slotTapeDevice() +{ + setTapePresent( FALSE ); +} + +void KDatMainWindow::slotTapeMounted() +{ + configureUI( TapeManager::instance()->getMountedTape() ); +} + +void KDatMainWindow::slotTapeUnmounted() +{ + configureUI( 0 ); +} + +void KDatMainWindow::configureUI( Tape* tape ) +{ + if ( _destroyed ) { + return; + } + + Node* sel = (Node*)_tree->getCurrentItem(); + + // Title bar + if ( tape ) { + QString title; + title = i18n( "KDat: %1" ).arg(tape->getName()); + setCaption( title ); + setIconText( title ); + } else { + setCaption( i18n( "KDat: <no tape>" ) ); + setIconText( i18n( "KDat: <no tape >" ) ); + } + + // Backup + bool canBackup = ( tape ) && ( !TapeDrive::instance()->isReadOnly() ) && + ( ( ( sel ) && ( sel->isType( Node::ArchiveableNodeType ) || sel->isType( Node::BackupProfileNodeType ) ) ) || + ( _rootNode->isSelected() || _rootNode->hasSelectedChildren() ) ); + _toolbar->setItemEnabled( 1, canBackup ); + _fileMenu->setItemEnabled( _fileMenu->idAt( 0 ), canBackup ); + + // Restore/verify + bool canRestore = ( tape ) && ( sel ) && sel->isType( Node::RangeableNodeType ); + if ( !canRestore ) { + for ( int i = _tapeDriveNode->childCount() - 1; i >= 0; i-- ) { + if ( ( ((SelectableNode*)_tapeDriveNode->childAt( i ))->isSelected() ) || + ( ((SelectableNode*)_tapeDriveNode->childAt( i ))->hasSelectedChildren() )) { + canRestore = TRUE; + break; + } + } + } + if ( canRestore ) { + // 2002-01-30 LEW: check Node *sel because we can have canRestore==true + // even if sel==NULL when a child is selected (see loop above). + if( sel != (Node *)0x0 ) + { + for ( Node* parent = (Node*)sel->getParent(); + ( parent ) && ( parent->getParent() ); + parent = (Node*)parent->getParent() ) { + if ( parent->isType( Node::TapeNodeType ) ) { + canRestore = FALSE; + } + } + } + // 2002-01-30 LEW: see if we ever get here... + else + { + printf("Found sel==0x0 in %s %d\n", __FILE__, __LINE__); + } + // 2002-01-30 LEW + + } + _toolbar->setItemEnabled( 2, canRestore ); + _toolbar->setItemEnabled( 3, canRestore ); + _fileMenu->setItemEnabled( _fileMenu->idAt( 1 ), canRestore ); + _fileMenu->setItemEnabled( _fileMenu->idAt( 2 ), canRestore ); + + // Mount/unmount tape + if ( tape ) { + _toolbar->setButtonPixmap( 0, *ImageCache::instance()->getTapeMounted() ); + _fileMenu->changeItem( i18n( "Unmount Tape" ), _fileMenu->idAt( 3 ) ); + } else { + _toolbar->setButtonPixmap( 0, *ImageCache::instance()->getTapeUnmounted() ); + _fileMenu->changeItem( i18n( "Mount Tape" ), _fileMenu->idAt( 3 ) ); + } + + // Index tape + _fileMenu->setItemEnabled( _fileMenu->idAt( 4 ), tape != NULL ); + + // Delete archive + _fileMenu->setItemEnabled( _fileMenu->idAt( 7 ), ( sel ) && sel->isType( Node::ArchiveNodeType ) ); + + // Delete index + _fileMenu->setItemEnabled( _fileMenu->idAt( 8 ), ( sel ) && sel->isType( Node::TapeNodeType ) ); + + // Delete backup profile + _fileMenu->setItemEnabled( _fileMenu->idAt( 9 ), ( sel ) && sel->isType( Node::BackupProfileNodeType ) ); + + // Format tape + _fileMenu->setItemEnabled( _fileMenu->idAt( 10 ), TapeManager::instance()->getMountedTape() && !TapeDrive::instance()->isReadOnly() ); +} + +void KDatMainWindow::readProperties( KConfig* config ) +{ + QValueList<int> sizes; + sizes << config->readNumEntry( "panner", 50 ); + _panner->setSizes( sizes ); +} + +void KDatMainWindow::saveProperties( KConfig* config ) +{ + config->writeEntry( "panner", _panner->sizes().first()); +} + +// Create the dialog that lets user cancel estimation of backup size +void KDatMainWindow::create_backup_dialog() +{ + /* 2002-01-24 LEW: start of backup-cancel dialog */ + static QString stop_button_text, stop_button_caption; + stop_button_text = + i18n("Click \"CANCEL\" to stop the backup process.\n" + "For example, you may quickly see that the size of\n" + "the files you selected will exceed the size of the\n" + "backup tape, and may then decide to stop and remove\n" + "some files from your list of files to backup.\n\n" + "Click \"Continue\" to remove this message while\n" + "continuing the backup."); + stop_button_caption = i18n("Stop estimating backup size"); + + // gotta put a callback in here. Probably need to create a + // dialog object 2002-01-22 LEW + _backupdialog = new KDialog( this, "backupdialog", false ); + _backupdialog->setCaption( stop_button_caption ); + // _backupdialog->resize(370,200); /* 2002-01-28 LEW */ + _backupdialog->resize(370,260); + + _lbl = new QLabel( stop_button_text, _backupdialog ); + // _lbl->setGeometry( QRect( 30, 20, 350, 140 ) ); /* 2002-01-28 LEW */ + _lbl->setGeometry( QRect( 30, 20, 350, 200 ) ); + + _cancel = new KPushButton( KStdGuiItem::cancel(), _backupdialog ); + _cancel->setFixedSize( 80, _cancel->sizeHint().height() ); + _cancel->setEnabled( TRUE ); + /* 2002-01-24 LEW: looks like we can't increase the button width + to accomodate a wider message :( */ + // _cancel->setGeometry( QRect( 50, 170, 0, 0 ) ); /* 2002-01-28 LEW */ + _cancel->setGeometry( QRect( 50, 230, 0, 0 ) ); + connect( _cancel, SIGNAL( clicked() ), this, SLOT( backupCancel() ) ); + + _continue = new KPushButton( KStdGuiItem::cont(), _backupdialog ); + _continue->setFixedSize( 80, _continue->sizeHint().height() ); + _continue->setEnabled( TRUE ); + _continue->setDefault( TRUE ); + // _continue->setGeometry( QRect( 200, 170, 0, 0 ) ); /* 2002-01-28 LEW */ + _continue->setGeometry( QRect( 200, 230, 0, 0 ) ); + connect( _continue, SIGNAL( clicked() ), this, SLOT( backupContinue() ) ); + + _backupdialog->show(); +} + +// stop calculating the backup size and hide the dialog screen +void KDatMainWindow::backupCancel() +{ + stop_flag = TRUE; + _backupdialog->hide(); +} + +// continue calculating the backup size and hide the dialog screen +void KDatMainWindow::backupContinue() +{ + _backupdialog->hide(); +} |