2020-11-28 16:20:56 +00:00
# include "stdafx.h"
# include "RecoveryWindow.h"
# include "SandMan.h"
# include "../MiscHelpers/Common/Settings.h"
# include "../MiscHelpers/Common/TreeItemModel.h"
# include "../MiscHelpers/Common/Common.h"
# include <QFileIconProvider>
CRecoveryWindow : : CRecoveryWindow ( const CSandBoxPtr & pBox , QWidget * parent )
: QDialog ( parent )
{
2021-01-26 20:58:43 +00:00
Qt : : WindowFlags flags = windowFlags ( ) ;
flags | = Qt : : CustomizeWindowHint ;
//flags &= ~Qt::WindowContextHelpButtonHint;
//flags &= ~Qt::WindowSystemMenuHint;
//flags &= ~Qt::WindowMinMaxButtonsHint;
flags | = Qt : : WindowMinimizeButtonHint ;
//flags &= ~Qt::WindowCloseButtonHint;
setWindowFlags ( flags ) ;
bool bAlwaysOnTop = theConf - > GetBool ( " Options/AlwaysOnTop " , false ) ;
this - > setWindowFlag ( Qt : : WindowStaysOnTopHint , bAlwaysOnTop ) ;
2020-11-28 16:20:56 +00:00
ui . setupUi ( this ) ;
this - > setWindowTitle ( tr ( " %1 - File Recovery " ) . arg ( pBox - > GetName ( ) ) ) ;
m_pBox = pBox ;
2021-01-18 12:04:14 +00:00
m_pCounter = NULL ;
2020-11-28 16:20:56 +00:00
# ifdef WIN32
QStyle * pStyle = QStyleFactory : : create ( " windows " ) ;
ui . treeFiles - > setStyle ( pStyle ) ;
# endif
2021-01-18 12:04:14 +00:00
ui . treeFiles - > setExpandsOnDoubleClick ( false ) ;
2020-11-28 16:20:56 +00:00
ui . btnDeleteAll - > setVisible ( false ) ;
m_pFileModel = new CSimpleTreeModel ( ) ;
m_pFileModel - > SetUseIcons ( true ) ;
m_pFileModel - > AddColumn ( tr ( " File Name " ) , " FileName " ) ;
m_pFileModel - > AddColumn ( tr ( " File Size " ) , " FileSize " ) ;
m_pFileModel - > AddColumn ( tr ( " Full Path " ) , " DiskPath " ) ;
/*m_pSortProxy = new CSortFilterProxyModel(false, this);
m_pSortProxy - > setSortRole ( Qt : : EditRole ) ;
m_pSortProxy - > setSourceModel ( m_pSnapshotModel ) ;
m_pSortProxy - > setDynamicSortFilter ( true ) ; */
//ui.treeSnapshots->setItemDelegate(theGUI->GetItemDelegate());
//ui.treeSnapshots->setModel(m_pSortProxy);
ui . treeFiles - > setModel ( m_pFileModel ) ;
ui . treeFiles - > setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
//connect(ui.treeFiles, SIGNAL(clicked(const QModelIndex&)), this, SLOT(UpdateSnapshot(const QModelIndex&)));
//connect(ui.treeFiles->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(UpdateSnapshot(const QModelIndex&)));
//connect(ui.treeFiles, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(OnSelectSnapshot()));
2021-01-30 18:10:49 +00:00
connect ( ui . btnAddFolder , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnAddFolder ( ) ) ) ;
2021-01-18 12:04:14 +00:00
connect ( ui . chkShowAll , SIGNAL ( clicked ( bool ) ) , this , SLOT ( FindFiles ( ) ) ) ;
2021-01-30 18:10:49 +00:00
connect ( ui . btnRefresh , SIGNAL ( clicked ( bool ) ) , this , SLOT ( FindFiles ( ) ) ) ;
connect ( ui . btnRecover , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnRecover ( ) ) ) ;
connect ( ui . btnRecoverTo , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnRecoverTo ( ) ) ) ;
connect ( ui . btnDeleteAll , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnDeleteAll ( ) ) ) ;
connect ( ui . btnClose , SIGNAL ( clicked ( bool ) ) , this , SLOT ( close ( ) ) ) ;
2020-11-28 16:20:56 +00:00
restoreGeometry ( theConf - > GetBlob ( " RecoveryWindow/Window_Geometry " ) ) ;
QByteArray Columns = theConf - > GetBlob ( " RecoveryWindow/FileTree_Columns " ) ;
if ( ! Columns . isEmpty ( ) )
ui . treeFiles - > header ( ) - > restoreState ( Columns ) ;
for ( int i = 0 ; i < m_pFileModel - > columnCount ( ) ; i + + )
m_pFileModel - > SetColumnEnabled ( i , true ) ;
foreach ( const QString & NtFolder , m_pBox - > GetTextList ( " RecoverFolder " , true , true ) )
{
2021-06-13 17:11:04 +01:00
bool bOk ;
QString Folder = theAPI - > Nt2DosPath ( NtFolder , & bOk ) ;
if ( bOk )
m_RecoveryFolders . append ( Folder ) ;
2020-11-28 16:20:56 +00:00
}
}
CRecoveryWindow : : ~ CRecoveryWindow ( )
{
theConf - > SetBlob ( " RecoveryWindow/Window_Geometry " , saveGeometry ( ) ) ;
theConf - > SetBlob ( " RecoveryWindow/FileTree_Columns " , ui . treeFiles - > header ( ) - > saveState ( ) ) ;
}
int CRecoveryWindow : : exec ( )
{
ui . btnDeleteAll - > setVisible ( true ) ;
return QDialog : : exec ( ) ;
}
void CRecoveryWindow : : closeEvent ( QCloseEvent * e )
{
this - > deleteLater ( ) ;
}
void CRecoveryWindow : : OnAddFolder ( )
{
2020-12-22 14:50:58 +00:00
QString Folder = QFileDialog : : getExistingDirectory ( this , tr ( " Select Directory " ) ) . replace ( " / " , " \\ " ) ; ;
2020-11-28 16:20:56 +00:00
if ( Folder . isEmpty ( ) )
return ;
if ( m_RecoveryFolders . contains ( Folder ) )
return ;
2021-01-18 12:04:14 +00:00
m_RecoveryFolders . append ( Folder ) ;
2020-11-28 16:20:56 +00:00
m_pBox - > AppendText ( " RecoverFolder " , Folder ) ;
2021-01-18 12:04:14 +00:00
FindFiles ( Folder ) ;
2020-11-28 16:20:56 +00:00
m_pFileModel - > Sync ( m_FileMap ) ;
ui . treeFiles - > expandAll ( ) ;
}
void CRecoveryWindow : : OnDeleteAll ( )
{
this - > setResult ( 1 ) ;
this - > close ( ) ;
}
int CRecoveryWindow : : FindFiles ( )
{
2021-01-18 12:04:14 +00:00
if ( m_pCounter = = NULL ) {
m_pCounter = new CRecoveryCounter ( m_pBox - > GetFileRoot ( ) , this ) ;
connect ( m_pCounter , SIGNAL ( Count ( quint32 , quint32 , quint64 ) ) , this , SLOT ( OnCount ( quint32 , quint32 , quint64 ) ) ) ;
}
2020-11-28 16:20:56 +00:00
m_FileMap . clear ( ) ;
int Count = 0 ;
2021-01-18 12:04:14 +00:00
if ( ui . chkShowAll - > isChecked ( ) )
{
2021-06-13 17:11:04 +01:00
//for(char drive = 'A'; drive <= 'Z'; drive++)
QDir Dir ( m_pBox - > GetFileRoot ( ) + " \\ drive \\ " ) ;
foreach ( const QFileInfo & Info , Dir . entryInfoList ( QDir : : Dirs | QDir : : NoDotAndDotDot ) )
Count + = FindBoxFiles ( " \\ drive \\ " + Info . fileName ( ) ) ;
2021-01-18 12:04:14 +00:00
if ( m_pBox - > GetBool ( " SeparateUserFolders " , true ) ) {
Count + = FindBoxFiles ( " \\ user \\ current " ) ;
Count + = FindBoxFiles ( " \\ user \\ all " ) ;
Count + = FindBoxFiles ( " \\ user \\ public " ) ;
}
2021-06-13 17:11:04 +01:00
//Count += FindBoxFiles("\\share");
QDir DirSvr ( m_pBox - > GetFileRoot ( ) + " \\ share \\ " ) ;
foreach ( const QFileInfo & InfoSrv , DirSvr . entryInfoList ( QDir : : Dirs | QDir : : NoDotAndDotDot ) ) {
QDir DirPub ( m_pBox - > GetFileRoot ( ) + " \\ share \\ " + InfoSrv . fileName ( ) ) ;
foreach ( const QFileInfo & InfoPub , DirPub . entryInfoList ( QDir : : Dirs | QDir : : NoDotAndDotDot ) )
Count + = FindBoxFiles ( " \\ share \\ " + InfoSrv . fileName ( ) + " \\ " + InfoPub . fileName ( ) ) ;
}
2021-01-18 12:04:14 +00:00
}
else
{
foreach ( const QString & Folder , m_RecoveryFolders )
Count + = FindFiles ( Folder ) ;
}
2020-11-28 16:20:56 +00:00
m_pFileModel - > Sync ( m_FileMap ) ;
ui . treeFiles - > expandAll ( ) ;
return Count ;
}
int CRecoveryWindow : : FindFiles ( const QString & Folder )
2021-01-18 12:04:14 +00:00
{
2021-06-13 17:11:04 +01:00
//int Count = 0;
//foreach(const QString & Path, theAPI->GetBoxedPath(m_pBox, Folder))
// Count += FindFiles(Folder, Path, Folder);
//return Count;
2021-01-18 12:04:14 +00:00
return FindFiles ( Folder , theAPI - > GetBoxedPath ( m_pBox , Folder ) , Folder ) ;
}
int CRecoveryWindow : : FindBoxFiles ( const QString & Folder )
{
2021-06-13 17:11:04 +01:00
QString RealFolder = theAPI - > GetRealPath ( m_pBox , m_pBox - > GetFileRoot ( ) + Folder ) ;
if ( RealFolder . isEmpty ( ) )
return 0 ;
return FindFiles ( Folder , m_pBox - > GetFileRoot ( ) + Folder , RealFolder ) ;
2021-01-18 12:04:14 +00:00
}
int CRecoveryWindow : : FindFiles ( const QString & RecParent , const QString & BoxedFolder , const QString & RealFolder )
2020-11-28 16:20:56 +00:00
{
QFileIconProvider IconProvider ;
int Count = 0 ;
quint64 TotalSize = 0 ;
QStringList Folders ;
2021-01-18 12:04:14 +00:00
Folders . append ( BoxedFolder ) ;
2020-11-28 16:20:56 +00:00
do {
QDir Dir ( Folders . takeFirst ( ) ) ;
foreach ( const QFileInfo & Info , Dir . entryInfoList ( QDir : : AllEntries ) )
{
QString Name = Info . fileName ( ) ;
if ( Name = = " . " | | Name = = " .. " )
continue ;
QString Path = Info . filePath ( ) . replace ( " / " , " \\ " ) ;
if ( Info . isFile ( ) )
{
Count + + ;
TotalSize + = Info . size ( ) ;
2021-01-18 12:04:14 +00:00
QString RealPath = RealFolder + Path . mid ( BoxedFolder . length ( ) ) ;
2020-11-28 16:20:56 +00:00
QVariantMap RecFile ;
RecFile [ " ID " ] = RealPath ;
RecFile [ " ParentID " ] = RecParent ;
RecFile [ " FileName " ] = Name ;
RecFile [ " FileSize " ] = FormatSize ( Info . size ( ) ) ;
RecFile [ " DiskPath " ] = RealPath ;
RecFile [ " BoxPath " ] = Path ;
RecFile [ " Icon " ] = IconProvider . icon ( Info ) ;
m_FileMap . insert ( RealPath , RecFile ) ;
}
else
Folders . append ( Path ) ;
}
} while ( ! Folders . isEmpty ( ) ) ;
if ( Count > 0 )
{
QVariantMap RecFolder ;
RecFolder [ " ID " ] = RecParent ;
RecFolder [ " ParentID " ] = QVariant ( ) ;
RecFolder [ " FileName " ] = RecParent ;
RecFolder [ " FileSize " ] = FormatSize ( TotalSize ) ;
//RecFolder["DiskPath"];
//RecFolder["BoxPath"];
RecFolder [ " Icon " ] = IconProvider . icon ( QFileIconProvider : : Folder ) ;
m_FileMap . insert ( RecParent , RecFolder ) ;
}
return Count ;
}
void CRecoveryWindow : : RecoverFiles ( bool bBrowse )
{
2021-06-13 17:11:04 +01:00
//bool HasShare = false;
2020-11-28 16:20:56 +00:00
QMap < QString , QString > FileMap ;
foreach ( const QModelIndex & Index , ui . treeFiles - > selectionModel ( ) - > selectedIndexes ( ) )
{
//QModelIndex ModelIndex = m_pSortProxy->mapToSource(Index);
//QVariant ID = m_pFileModel->GetItemID(ModelIndex);
QVariant ID = m_pFileModel - > GetItemID ( Index ) ;
QVariantMap File = m_FileMap . value ( ID ) ;
if ( File . isEmpty ( ) )
continue ;
2021-06-14 20:13:25 +01:00
if ( ! File [ " ParentID " ] . isNull ( ) )
{
2021-06-13 17:11:04 +01:00
//if (File["DiskPath"].toString().indexOf("\\device\\mup", 0, Qt::CaseInsensitive) == 0)
2021-06-14 20:13:25 +01:00
// HasShare = true;
2020-11-28 16:20:56 +00:00
FileMap [ File [ " BoxPath " ] . toString ( ) ] = File [ " DiskPath " ] . toString ( ) ;
2021-01-18 12:04:14 +00:00
}
2020-11-28 16:20:56 +00:00
else
{
for ( int i = 0 ; i < m_pFileModel - > rowCount ( Index ) ; i + + )
{
QModelIndex ChildIndex = m_pFileModel - > index ( i , 0 , Index ) ;
QVariant ChildID = m_pFileModel - > GetItemID ( ChildIndex ) ;
QVariantMap File = m_FileMap . value ( ChildID ) ;
if ( File . isEmpty ( ) )
continue ;
2021-06-13 17:11:04 +01:00
//if (File["DiskPath"].toString().indexOf("\\device\\mup") == 0)
// HasShare = true;
2020-11-28 16:20:56 +00:00
FileMap [ File [ " BoxPath " ] . toString ( ) ] = File [ " DiskPath " ] . toString ( ) ;
}
}
}
2021-06-14 20:13:25 +01:00
/*if (HasShare && !bBrowse) {
QMessageBox : : warning ( this , " Sandboxie-Plus " , tr ( " One or more selected files are located on a network share, and must be recovered to a local drive, please select a folder to recover all selected files to. " ) ) ;
bBrowse = true ;
} */
QString RecoveryFolder ;
if ( bBrowse ) {
RecoveryFolder = QFileDialog : : getExistingDirectory ( this , tr ( " Select Directory " ) ) . replace ( " / " , " \\ " ) ;
2021-01-18 12:04:14 +00:00
if ( RecoveryFolder . isEmpty ( ) )
return ;
}
2020-11-28 16:20:56 +00:00
2021-01-30 18:10:49 +00:00
2020-11-28 16:20:56 +00:00
QList < QPair < QString , QString > > FileList ;
for ( QMap < QString , QString > : : const_iterator I = FileMap . begin ( ) ; I ! = FileMap . end ( ) ; + + I )
{
2021-06-14 20:13:25 +01:00
QString BoxedFilePath = I . key ( ) ;
QString RecoveryPath = I . value ( ) ;
if ( ! RecoveryFolder . isEmpty ( ) )
{
QString FileName = RecoveryPath . mid ( RecoveryPath . lastIndexOf ( " \\ " ) + 1 ) ;
RecoveryPath = RecoveryFolder + " \\ " + FileName ;
2020-11-28 16:20:56 +00:00
}
FileList . append ( qMakePair ( BoxedFilePath , RecoveryPath ) ) ;
}
2021-01-30 18:10:49 +00:00
2020-11-28 16:20:56 +00:00
SB_PROGRESS Status = theGUI - > RecoverFiles ( FileList ) ;
if ( Status . GetStatus ( ) = = OP_ASYNC )
{
connect ( Status . GetValue ( ) . data ( ) , SIGNAL ( Finished ( ) ) , this , SLOT ( FindFiles ( ) ) ) ;
theGUI - > AddAsyncOp ( Status . GetValue ( ) ) ;
}
}
2021-01-18 12:04:14 +00:00
void CRecoveryWindow : : OnCount ( quint32 fileCount , quint32 folderCount , quint64 totalSize )
{
2021-06-14 20:13:25 +01:00
ui . lblInfo - > setText ( tr ( " There are %1 files and %2 folders in the sandbox, occupying %3 of disk space. " ) . arg ( fileCount ) . arg ( folderCount ) . arg ( FormatSize ( totalSize ) ) ) ;
2021-01-18 12:04:14 +00:00
}
void CRecoveryCounter : : run ( )
{
quint32 fileCount = 0 ;
quint32 folderCount = 0 ;
quint64 totalSize = 0 ;
QStringList Folders ;
Folders . append ( m_BoxPath ) ;
do {
if ( ! m_run ) break ;
QDir Dir ( Folders . takeFirst ( ) ) ;
foreach ( const QFileInfo & Info , Dir . entryInfoList ( QDir : : AllEntries ) )
{
if ( ! m_run ) break ;
QString Name = Info . fileName ( ) ;
if ( Name = = " . " | | Name = = " .. " )
continue ;
QString Path = Info . filePath ( ) . replace ( " / " , " \\ " ) ;
if ( Info . isFile ( ) )
{
fileCount + + ;
totalSize + = Info . size ( ) ;
}
else
{
Folders . append ( Path ) ;
folderCount + + ;
}
}
emit Count ( fileCount , folderCount , totalSize ) ;
} while ( ! Folders . isEmpty ( ) ) ;
}