[rar] add a callback class for unrarlib rather than calling into guilib direct from...
authorJonathan Marshall <jmarshall@xbmc.org>
Mon, 9 Jun 2014 09:13:00 +0000 (21:13 +1200)
committerJonathan Marshall <jmarshall@xbmc.org>
Mon, 14 Jul 2014 02:21:22 +0000 (14:21 +1200)
lib/UnrarXLib/UnrarX.hpp
lib/UnrarXLib/rar.cpp
lib/UnrarXLib/rdwrfn.cpp
lib/UnrarXLib/rdwrfn.hpp
xbmc/filesystem/RarManager.cpp

index c2f7c03..716d89e 100644 (file)
@@ -34,7 +34,8 @@ typedef struct archivelist
           or NULL for all files.
   libpassword   - Password (for encrypted archives)
 \*-------------------------------------------------------------------------*/
-int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libpassword = NULL, int64_t* iOffset=NULL, bool bShowProgress=false);
+typedef bool (*progress_callback)(void*, int, const char*);
+int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libpassword = NULL, int64_t* iOffset=NULL, progress_callback progress = NULL, void *context = NULL);
 
 /*-------------------------------------------------------------------------*\
   List the files in a RAR file
index 7515f7e..a634d0e 100644 (file)
@@ -1,7 +1,6 @@
 #include "rar.hpp"
 #include "UnrarX.hpp"
 #include "guilib/GUIWindowManager.h"
-#include "dialogs/GUIDialogProgress.h"
 #include "filesystem/File.h"
 
 #include "smallfn.cpp"
@@ -142,7 +141,7 @@ int main(int argc, char *argv[])
           or NULL for all files.
   libpassword   - Password (for encrypted archives)
 \*-------------------------------------------------------------------------*/
-int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libpassword, int64_t* iOffset, bool bShowProgress)
+int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libpassword, int64_t* iOffset, progress_callback progress, void *context)
 {
   InitCRC();
   int bRes = 1;
@@ -200,16 +199,8 @@ int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libp
             pExtract->GetDataIO().TotalArcSize+=FD.Size;
           pExtract->ExtractArchiveInit(pCmd.get(),*pArc);
 
-          if (bShowProgress)
-          {
-            pExtract->GetDataIO().m_pDlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
-            if (pExtract->GetDataIO().m_pDlgProgress)
-            {
-              pExtract->GetDataIO().m_pDlgProgress->SetHeading(fileToExtract);
-              pExtract->GetDataIO().m_pDlgProgress->SetCanCancel(false);
-              pExtract->GetDataIO().m_pDlgProgress->StartModal();
-            }
-          }
+          pExtract->GetDataIO().m_progress = progress;
+          pExtract->GetDataIO().m_context = context;
 
           int64_t iOff=0;
           bool bSeeked = false;
@@ -237,8 +228,6 @@ int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libp
             
             if (pExtract->GetDataIO().bQuit) 
             {
-              if (pExtract->GetDataIO().m_pDlgProgress)
-                pExtract->GetDataIO().m_pDlgProgress->Close();
               bRes = 2;
               break;
             }
@@ -269,12 +258,7 @@ int urarlib_get(char *rarfile, char *targetPath, char *fileToExtract, char *libp
           }
 
           pExtract->GetDataIO().ProcessedArcSize+=FD.Size;         
-          if (pExtract->GetDataIO().m_pDlgProgress)
-            pExtract->GetDataIO().m_pDlgProgress->ShowProgressBar(false);
         }
-        if (bShowProgress)
-          if (pExtract->GetDataIO().m_pDlgProgress)
-            pExtract->GetDataIO().m_pDlgProgress->Close();
       }
     }
   }
index 4eae8fa..0ca2208 100644 (file)
@@ -1,6 +1,5 @@
 #include "rar.hpp"
 #include "URL.h"
-#include "dialogs/GUIDialogProgress.h"
 
 ComprDataIO::ComprDataIO()
 {
@@ -35,7 +34,8 @@ void ComprDataIO::Init()
   CurrentCommand=0;
   ProcessedArcSize=TotalArcSize=0;
   bQuit = false;
-  m_pDlgProgress = NULL;
+  m_progress = NULL;
+  m_context  = NULL;
  }
 
 int ComprDataIO::UnpRead(byte *Addr,uint Count)
@@ -143,12 +143,8 @@ int ComprDataIO::UnpRead(byte *Addr,uint Count)
         return(-1);
       }
       CurUnpStart = CurUnpRead;
-      if (m_pDlgProgress)
-      {
-        CURL url(SrcArc->FileName);
-        m_pDlgProgress->SetLine(0,url.GetWithoutUserDetails()); // update currently extracted rar file
-        m_pDlgProgress->Progress();
-      }
+      if (m_progress)
+        m_progress(m_context, -1, SrcArc->FileName);
     }
     else
       break;
@@ -241,12 +237,9 @@ void ComprDataIO::UnpWrite(byte *Addr,uint Count)
   }
   ShowUnpWrite();
   Wait();
-  if (m_pDlgProgress)
+  if (m_progress)
   {
-    m_pDlgProgress->ShowProgressBar(true);
-    m_pDlgProgress->SetPercentage(int(float(CurUnpWrite)/float(((Archive*)SrcFile)->NewLhd.FullUnpSize)*100));
-    m_pDlgProgress->Progress();
-    if (m_pDlgProgress->IsCanceled()) 
+    if (!m_progress(m_context, int(float(CurUnpWrite)/float(((Archive*)SrcFile)->NewLhd.FullUnpSize)*100), NULL))
       bQuit = true;
   }
 }
index 69d7f59..cf6691d 100644 (file)
@@ -7,7 +7,7 @@ class Unpack;
 #include "system.h"
 #include "threads/Event.h"
 
-class CGUIDialogProgress;
+typedef bool (*progress_callback)(void*, int, const char*);
 
 class ComprDataIO
 {
@@ -90,7 +90,8 @@ class ComprDataIO
     CEvent* hSeek;
     CEvent* hSeekDone;
     CEvent* hQuit;
-    CGUIDialogProgress* m_pDlgProgress;
+    progress_callback m_progress;
+    void*             m_context;
     bool bQuit;
     Int64 m_iSeekTo;
     Int64 m_iStartOfBuffer;
index 5043aeb..0415c10 100644 (file)
 #include "FileItem.h"
 #include "utils/log.h"
 #include "filesystem/File.h"
+#include "URL.h"
 
 #include "dialogs/GUIDialogYesNo.h"
+#include "dialogs/GUIDialogProgress.h"
 #include "guilib/GUIWindowManager.h"
 #include "utils/StringUtils.h"
 
@@ -64,6 +66,71 @@ CRarManager::~CRarManager()
   ClearCache(true);
 }
 
+class progress_info
+{
+public:
+  progress_info(const std::string &file) : heading(file), shown(false), showTime(200) // 200ms to show...
+  {
+  }
+  ~progress_info()
+  {
+    if (shown)
+    {
+      // close progress dialog
+      CGUIDialogProgress* dlg = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
+      if (dlg)
+        dlg->Close();
+    }
+  }
+  /*! \brief Progress callback from rar manager.
+   \return true to continue processing, false to cancel.
+   */
+  bool progress(int progress, const char *text)
+  {
+    bool cont(true);
+    if (shown || showTime.IsTimePast())
+    {
+      // grab the busy and show it
+      CGUIDialogProgress* dlg = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
+      if (dlg)
+      {
+        if (!shown)
+        {
+          dlg->SetHeading(heading);
+          dlg->StartModal();
+        }
+        if (progress >= 0)
+        {
+          dlg->ShowProgressBar(true);
+          dlg->SetPercentage(progress);
+        }
+        if (text)
+          dlg->SetLine(1, text);
+        cont = !dlg->IsCanceled();
+        shown = true;
+        // tell render loop to spin
+        dlg->Progress();
+      }
+    }
+    return cont;
+  };
+private:
+  std::string          heading;
+  bool                 shown;
+  XbmcThreads::EndTime showTime;
+};
+
+/*! \brief Rar progress callback.
+  \return false to halt progress, true to continue
+ */
+bool ProgressCallback(void *context, int progress, const char *text)
+{
+  progress_info* info = (progress_info*)context;
+  if (info)
+    return info->progress(progress, text);
+  return true;
+}
+
 bool CRarManager::CacheRarredFile(std::string& strPathInCache, const std::string& strRarPath, const std::string& strPathInRar, BYTE  bOptions, const std::string& strDir, const int64_t iSize)
 {
 #ifdef HAS_FILESYSTEM_RAR
@@ -182,8 +249,9 @@ bool CRarManager::CacheRarredFile(std::string& strPathInCache, const std::string
     URIUtils::RemoveSlashAtEnd(strDir2);
     if (!CDirectory::Exists(strDir2))
       CDirectory::Create(strDir2);
+    progress_info info(CURL(strPath).GetWithoutUserDetails());
     iRes = urarlib_get(const_cast<char*>(strRarPath.c_str()), const_cast<char*>(strDir2.c_str()),
-                       const_cast<char*>(strPath.c_str()),NULL,&iOffset,bShowProgress);
+                       const_cast<char*>(strPath.c_str()),NULL,&iOffset,bShowProgress ? ProgressCallback : NULL, &info);
   }
   if (iRes == 0)
   {