Home | History | Annotate | Download | only in GUI
      1 // ExtractGUI.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../Common/IntToString.h"
      6 #include "../../../Common/StringConvert.h"
      7 
      8 #include "../../../Windows/FileDir.h"
      9 #include "../../../Windows/FileFind.h"
     10 #include "../../../Windows/FileName.h"
     11 #include "../../../Windows/Thread.h"
     12 
     13 #include "../FileManager/ExtractCallback.h"
     14 #include "../FileManager/FormatUtils.h"
     15 #include "../FileManager/LangUtils.h"
     16 #include "../FileManager/resourceGui.h"
     17 #include "../FileManager/OverwriteDialogRes.h"
     18 
     19 #include "../Common/ArchiveExtractCallback.h"
     20 #include "../Common/PropIDUtils.h"
     21 
     22 #include "../Explorer/MyMessages.h"
     23 
     24 #include "resource2.h"
     25 #include "ExtractRes.h"
     26 
     27 #include "ExtractDialog.h"
     28 #include "ExtractGUI.h"
     29 #include "HashGUI.h"
     30 
     31 #include "../FileManager/PropertyNameRes.h"
     32 
     33 using namespace NWindows;
     34 using namespace NFile;
     35 using namespace NDir;
     36 
     37 static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
     38 
     39 #ifndef _SFX
     40 
     41 static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColon = true)
     42 {
     43   AddLangString(s, resourceID);
     44   if (addColon)
     45     s += L':';
     46   s.Add_Space();
     47   char sz[32];
     48   ConvertUInt64ToString(value, sz);
     49   s.AddAscii(sz);
     50   s.Add_LF();
     51 }
     52 
     53 static void AddSizePair(UString &s, UINT resourceID, UInt64 value)
     54 {
     55   wchar_t sz[32];
     56   AddLangString(s, resourceID);
     57   s += L": ";
     58   ConvertUInt64ToString(value, sz);
     59   s += MyFormatNew(IDS_FILE_SIZE, sz);
     60   // s += sz;
     61   if (value >= (1 << 20))
     62   {
     63     ConvertUInt64ToString(value >> 20, sz);
     64     s += L" (";
     65     s += sz;
     66     s += L" MB)";
     67   }
     68   s.Add_LF();
     69 }
     70 
     71 #endif
     72 
     73 class CThreadExtracting: public CProgressThreadVirt
     74 {
     75   HRESULT ProcessVirt();
     76 public:
     77   CCodecs *codecs;
     78   CExtractCallbackImp *ExtractCallbackSpec;
     79   const CObjectVector<COpenType> *FormatIndices;
     80   const CIntVector *ExcludedFormatIndices;
     81 
     82   UStringVector *ArchivePaths;
     83   UStringVector *ArchivePathsFull;
     84   const NWildcard::CCensorNode *WildcardCensor;
     85   const CExtractOptions *Options;
     86   #ifndef _SFX
     87   CHashBundle *HashBundle;
     88   #endif
     89   CMyComPtr<IExtractCallbackUI> ExtractCallback;
     90   UString Title;
     91 };
     92 
     93 HRESULT CThreadExtracting::ProcessVirt()
     94 {
     95   CDecompressStat Stat;
     96   #ifndef _SFX
     97   if (HashBundle)
     98     HashBundle->Init();
     99   #endif
    100 
    101   HRESULT res = Extract(codecs,
    102       *FormatIndices, *ExcludedFormatIndices,
    103       *ArchivePaths, *ArchivePathsFull,
    104       *WildcardCensor, *Options, ExtractCallbackSpec, ExtractCallback,
    105       #ifndef _SFX
    106         HashBundle,
    107       #endif
    108       FinalMessage.ErrorMessage.Message, Stat);
    109   #ifndef _SFX
    110   if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK())
    111   {
    112     UString s;
    113 
    114     AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
    115     AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
    116 
    117     if (!HashBundle)
    118     {
    119       if (Stat.NumFolders != 0)
    120         AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders);
    121       AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles);
    122       AddSizePair(s, IDS_PROP_SIZE, Stat.UnpackSize);
    123       if (Stat.NumAltStreams != 0)
    124       {
    125         s.Add_LF();
    126         AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams);
    127         AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize);
    128       }
    129     }
    130 
    131     if (HashBundle)
    132     {
    133       s.Add_LF();
    134       AddHashBundleRes(s, *HashBundle, UString());
    135     }
    136 
    137     s.Add_LF();
    138     AddLangString(s, IDS_MESSAGE_NO_ERRORS);
    139 
    140     FinalMessage.OkMessage.Title = Title;
    141     FinalMessage.OkMessage.Message = s;
    142   }
    143   #endif
    144   return res;
    145 }
    146 
    147 HRESULT ExtractGUI(
    148     CCodecs *codecs,
    149     const CObjectVector<COpenType> &formatIndices,
    150     const CIntVector &excludedFormatIndices,
    151     UStringVector &archivePaths,
    152     UStringVector &archivePathsFull,
    153     const NWildcard::CCensorNode &wildcardCensor,
    154     CExtractOptions &options,
    155     #ifndef _SFX
    156     CHashBundle *hb,
    157     #endif
    158     bool showDialog,
    159     bool &messageWasDisplayed,
    160     CExtractCallbackImp *extractCallback,
    161     HWND hwndParent)
    162 {
    163   messageWasDisplayed = false;
    164 
    165   CThreadExtracting extracter;
    166   extracter.codecs = codecs;
    167   extracter.FormatIndices = &formatIndices;
    168   extracter.ExcludedFormatIndices = &excludedFormatIndices;
    169 
    170   if (!options.TestMode)
    171   {
    172     FString outputDir = options.OutputDir;
    173     #ifndef UNDER_CE
    174     if (outputDir.IsEmpty())
    175       GetCurrentDir(outputDir);
    176     #endif
    177     if (showDialog)
    178     {
    179       CExtractDialog dialog;
    180       FString outputDirFull;
    181       if (!MyGetFullPathName(outputDir, outputDirFull))
    182       {
    183         ShowErrorMessage(kIncorrectOutDir);
    184         messageWasDisplayed = true;
    185         return E_FAIL;
    186       }
    187       NName::NormalizeDirPathPrefix(outputDirFull);
    188 
    189       dialog.DirPath = fs2us(outputDirFull);
    190 
    191       dialog.OverwriteMode = options.OverwriteMode;
    192       dialog.OverwriteMode_Force = options.OverwriteMode_Force;
    193       dialog.PathMode = options.PathMode;
    194       dialog.PathMode_Force = options.PathMode_Force;
    195       dialog.ElimDup = options.ElimDup;
    196 
    197       if (archivePathsFull.Size() == 1)
    198         dialog.ArcPath = archivePathsFull[0];
    199 
    200       #ifndef _SFX
    201       // dialog.AltStreams = options.NtOptions.AltStreams;
    202       dialog.NtSecurity = options.NtOptions.NtSecurity;
    203       if (extractCallback->PasswordIsDefined)
    204         dialog.Password = extractCallback->Password;
    205       #endif
    206 
    207       if (dialog.Create(hwndParent) != IDOK)
    208         return E_ABORT;
    209 
    210       outputDir = us2fs(dialog.DirPath);
    211 
    212       options.OverwriteMode = dialog.OverwriteMode;
    213       options.PathMode = dialog.PathMode;
    214       options.ElimDup = dialog.ElimDup;
    215 
    216       #ifndef _SFX
    217       // options.NtOptions.AltStreams = dialog.AltStreams;
    218       options.NtOptions.NtSecurity = dialog.NtSecurity;
    219       extractCallback->Password = dialog.Password;
    220       extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty();
    221       #endif
    222     }
    223     if (!MyGetFullPathName(outputDir, options.OutputDir))
    224     {
    225       ShowErrorMessage(kIncorrectOutDir);
    226       messageWasDisplayed = true;
    227       return E_FAIL;
    228     }
    229     NName::NormalizeDirPathPrefix(options.OutputDir);
    230 
    231     /*
    232     if (!CreateComplexDirectory(options.OutputDir))
    233     {
    234       UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
    235       UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
    236       #ifdef LANG
    237       0x02000603,
    238       #endif
    239       options.OutputDir);
    240       s2.Add_LF();
    241       s2 += s;
    242       MyMessageBox(s2);
    243       return E_FAIL;
    244     }
    245     */
    246   }
    247 
    248   UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING);
    249 
    250   extracter.Title = title;
    251   extracter.ExtractCallbackSpec = extractCallback;
    252   extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;
    253   extracter.ExtractCallback = extractCallback;
    254   extracter.ExtractCallbackSpec->Init();
    255 
    256   extracter.ProgressDialog.CompressingMode = false;
    257 
    258   extracter.ArchivePaths = &archivePaths;
    259   extracter.ArchivePathsFull = &archivePathsFull;
    260   extracter.WildcardCensor = &wildcardCensor;
    261   extracter.Options = &options;
    262   #ifndef _SFX
    263   extracter.HashBundle = hb;
    264   #endif
    265 
    266   extracter.ProgressDialog.IconID = IDI_ICON;
    267 
    268   RINOK(extracter.Create(title, hwndParent));
    269   messageWasDisplayed = extracter.ThreadFinishedOK &
    270       extracter.ProgressDialog.MessagesDisplayed;
    271   return extracter.Result;
    272 }
    273