]> git.lyx.org Git - lyx.git/blobdiff - development/Win32/pdfview/pdfview.nsi
LaTeXConfig.lyx : Document the bibliography and citation packages (change tracking).
[lyx.git] / development / Win32 / pdfview / pdfview.nsi
index a30e9dfa84f677171964cafa2c189b211814c4b5..aab892f44ca668dbcf7f45ca14cfc24cb4f011f3 100644 (file)
@@ -1,26 +1,21 @@
 /*
 
 Windows PDF view helper
 /*
 
 Windows PDF view helper
-Author: Joost Verburg
+Author: Joost Verburg and Uwe Stöhr
 
 This will be installed as pdfview.exe.
 
 The application will launch the default PDF viewer to display the PDF file,
 
 This will be installed as pdfview.exe.
 
 The application will launch the default PDF viewer to display the PDF file,
-but works around the file locking problems of Adobe Reader.
+but works around the file locking problems of Adobe Reader and Acrobat.
 
 
-Source code of pdfopen/pdfclose is available at:
-http://magic.aladdin.cs.cmu.edu/2005/07/15/pdfopen-and-pdfclose/
+The files pdfopen/pdfclose are part of this archive:
+http://www.tex.ac.uk/tex-archive/systems/win32/w32tex/pdftex-w32.tar.xz
 
 */
 
 !include LogicLib.nsh
 !include FileFunc.nsh
 
 
 */
 
 !include LogicLib.nsh
 !include FileFunc.nsh
 
-# Functions from FileFunc.nsh
-!insertmacro GetParameters
-!insertmacro GetFileName
-!insertmacro GetParent
-
 #--------------------------------
 # Settings
 
 #--------------------------------
 # Settings
 
@@ -30,7 +25,7 @@ Icon "..\packaging\icons\lyx.ico"
 SilentInstall silent
 
 #--------------------------------
 SilentInstall silent
 
 #--------------------------------
-# Windows Vista settings
+# Windows Vista (and later) settings
 
 RequestExecutionLevel user
 
 
 RequestExecutionLevel user
 
@@ -40,7 +35,9 @@ RequestExecutionLevel user
 !define FALSE 0
 !define TRUE 1
 
 !define FALSE 0
 !define TRUE 1
 
+# see http://msdn.microsoft.com/en-us/library/windows/desktop/aa364417%28v=vs.85%29.aspx
 !define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
 !define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
+# see http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx
 !define WAIT_TIMEOUT 0x00000102
 
 #--------------------------------
 !define WAIT_TIMEOUT 0x00000102
 
 #--------------------------------
@@ -54,16 +51,14 @@ Var OriginalFileName
 Var OriginalDir
 
 Var PDFFile
 Var OriginalDir
 
 Var PDFFile
+Var ViewerFileName
 Var Viewer
 
 Var ChangeNotification
 Var WaitReturn
 Var LockedFile
 
 Var Viewer
 
 Var ChangeNotification
 Var WaitReturn
 Var LockedFile
 
-Var OriginalTimeHigh
-Var OriginalTimeLow
-Var CurrentTimeHigh
-Var CurrentTimeLow
+Var TimeDiff
 
 #--------------------------------
 # Macros
 
 #--------------------------------
 # Macros
@@ -91,6 +86,76 @@ Var CurrentTimeLow
 
 !macroend
 
 
 !macroend
 
+# all following macros and functions are from
+# http://nsis.sourceforge.net/FileTimeDiff
+!define GetFileTimeS "!insertmacro _GetFileTimeS"
+
+!macro _GetFileTimeS _Time_ _File_
+
+   Push "${_File_}"
+   Call GetFileTimeS
+   Pop ${_Time_}
+   
+!macroend
+
+Function GetFileTimeS
+       
+   Exch $0  # File / hi
+   Push $1  # lo
+   ClearErrors
+   GetFileTime "$0" $0 $1
+   IfErrors err
+   System::Call '*(i r1, i r0) i .r0'
+   System::Call '*$0(l .r0)'
+   System::Int64Op $0 / 10000000  # Conversion From '100 ns' to '1 sec' unit
+   Goto end
+   err:
+      Push ""
+      SetErrors
+      Goto +3
+   end:
+   System::Free $0
+   Exch 2
+   Pop $0
+   Pop $1
+   
+FunctionEnd
+
+!define FileTimeDiff "!insertmacro _FileTimeDiff"
+
+!macro _FileTimeDiff _RetVal_ _FileA_ _FileB_
+
+   Push "${_FileB_}"
+   Push "${_FileA_}"
+   Call FileTimeDiff
+   Pop ${_RetVal_}
+   
+!macroend
+
+Function FileTimeDiff 
+   Exch $0  # FileA
+   Exch 
+   Exch $1  # FileB
+   ${GetFileTimeS} $0 "$0"
+   IfErrors err
+   ${GetFileTimeS} $1 "$1"
+   IfErrors err
+   System::Int64Op $0 - $1
+   Goto end
+   err:
+      Push ""
+      SetErrors
+   end:
+   Exch 2
+   Pop $0
+   Pop $1
+   
+FunctionEnd
+
 #--------------------------------
 # PDF viewing
 
 #--------------------------------
 # PDF viewing
 
@@ -113,7 +178,8 @@ Section "View PDF file"
 
   GetFullPathName $OriginalFile $OriginalFile
   ${GetFileName} $OriginalFile $OriginalFileName
 
   GetFullPathName $OriginalFile $OriginalFile
   ${GetFileName} $OriginalFile $OriginalFileName
-  ${GetParent} $OriginalFile $OriginalDir
+  ${GetParent} $OriginalFile $OriginalDir # tmpbuf
+  ${GetParent} $OriginalDir $OriginalDir # tmpdir
 
   SetOutPath $TEMP # The LyX tmpbuf should not be locked
 
 
   SetOutPath $TEMP # The LyX tmpbuf should not be locked
 
@@ -121,8 +187,8 @@ Section "View PDF file"
 
   # Check whether the file will be opened with Adobe Reader or Adobe Acrobat
   !insertmacro SystemCall "shell32::FindExecutable(t '$OriginalFile', t '', t .s)"
 
   # Check whether the file will be opened with Adobe Reader or Adobe Acrobat
   !insertmacro SystemCall "shell32::FindExecutable(t '$OriginalFile', t '', t .s)"
-  Call GetFileName
-  Pop $Viewer
+  Pop $ViewerFileName
+  ${GetFileName} $ViewerFileName $Viewer
 
   ${If} $Viewer == ""
     MessageBox MB_OK|MB_ICONEXCLAMATION "No PDF viewer is installed. \
 
   ${If} $Viewer == ""
     MessageBox MB_OK|MB_ICONEXCLAMATION "No PDF viewer is installed. \
@@ -131,9 +197,17 @@ Section "View PDF file"
   ${EndIf}
 
   ${If} $Viewer == "AcroRd32.exe"
   ${EndIf}
 
   ${If} $Viewer == "AcroRd32.exe"
-    ${OrIf} $Viewer == "Acrobat.exe"
-    
-    # Using Adobe viewer
+  ${OrIf} $Viewer == "Acrobat.exe"
+  
+    # get the version of Acrobat - currenly not necessary
+    #GetDLLVersion $ViewerFileName $R0 $R1
+    #IntOp $R2 $R0 >> 16
+    #IntOp $R2 $R2 & 0x0000FFFF ; $R2 now contains major version
+    #IntOp $R3 $R0 & 0x0000FFFF ; $R3 now contains minor version
+    #IntOp $R4 $R1 >> 16
+    #IntOp $R4 $R4 & 0x0000FFFF ; $R4 now contains release
+    #IntOp $R5 $R1 & 0x0000FFFF ; $R5 now contains build
+    #StrCpy $ViewerVersion "$R2"
     
     # Close existing view
     ${If} ${FileExists} $PDFFile
     
     # Close existing view
     ${If} ${FileExists} $PDFFile
@@ -144,31 +218,22 @@ Section "View PDF file"
     CopyFiles /SILENT $OriginalFile $PDFFile
     
     # Open a new view
     CopyFiles /SILENT $OriginalFile $PDFFile
     
     # Open a new view
-    !insertmacro HideConsole '"$EXEDIR\pdfopen.exe" --back --file "$PDFFile"'
-    
-    # Monitor for updates of the original file
-    GetFileTime $OriginalFile $OriginalTimeHigh $OriginalTimeLow
+    !insertmacro HideConsole '"$EXEDIR\pdfopen.exe" --file "$PDFFile"'
+        
+    # check if a file in LyX's temp folder has been changed
     !insertmacro SystemCall "kernel32::FindFirstChangeNotification(t '$OriginalDir', \
     !insertmacro SystemCall "kernel32::FindFirstChangeNotification(t '$OriginalDir', \
-      i 0, i ${FILE_NOTIFY_CHANGE_LAST_WRITE}) i.s"
+      i 1, i ${FILE_NOTIFY_CHANGE_LAST_WRITE}) i.s"
     Pop $ChangeNotification
     
     ${Do}
     
     Pop $ChangeNotification
     
     ${Do}
     
+      # wait until the folder is not changed anymore, if so a "0" is returned
+      # otherwise a "258" (0x00000102) is returned
       !insertmacro SystemCall "kernel32::WaitForSingleObject(i $ChangeNotification, i 10000) i.s"
       Pop $WaitReturn
       
       !insertmacro SystemCall "kernel32::WaitForSingleObject(i $ChangeNotification, i 10000) i.s"
       Pop $WaitReturn
       
-      # Check whether the PDF still exists (if not, LyX is being closed)
-      
-      ${IfNot} ${FileExists} $LockedFile
-        # Quit this application
-        !insertmacro SystemCall "kernel32::FindCloseChangeNotification(i $ChangeNotification)"
-        Quit
-      ${EndIf}
-      
-      # Check whether the lock is still active (if not, Adobe Reader being closed)
-      
+      # Check whether the lock of the PDF file is still active (if not, Adobe Reader is closed)
       FileOpen $LockedFile $PDFFile a
       FileOpen $LockedFile $PDFFile a
-      
       ${If} $LockedFile != ""
         # Quit this application
         FileClose $LockedFile
       ${If} $LockedFile != ""
         # Quit this application
         FileClose $LockedFile
@@ -177,28 +242,40 @@ Section "View PDF file"
         Quit
       ${EndIf}
       
         Quit
       ${EndIf}
       
+      # if the folder is (for now) not changed anymore
       ${IfNot} $WaitReturn = ${WAIT_TIMEOUT}
       ${IfNot} $WaitReturn = ${WAIT_TIMEOUT}
-        # The LyX tmpbuf has been updated
-        # Check whether it's the PDF file that has been updated
-          
-        GetFileTime $OriginalFile $CurrentTimeHigh $CurrentTimeLow
+      
+        # check if the PDF-file in our temp directory is older than the one
+        # in LyX's temp folder because then it has been changed by LaTeX
+        ${FileTimeDiff} $TimeDiff "$PDFFile" "$OriginalFile"
         
         
-        ${if} $OriginalTimeHigh != $CurrentTimeHigh
-          ${orif} $OriginalTimeLow != $CurrentTimeLow
-          # PDF has been modified, update view
+        # if the file is older than 1 second
+        ${If} $TimeDiff < -1
+          # close the PDF
           !insertmacro HideConsole '"$EXEDIR\pdfclose.exe" --file "$PDFFile"'
           !insertmacro HideConsole '"$EXEDIR\pdfclose.exe" --file "$PDFFile"'
-          CopyFiles /SILENT $OriginalFile $PDFFile
-          !insertmacro HideConsole '"$EXEDIR\pdfopen.exe" --back --file "$PDFFile"'
           
           
-          # Time of new file
-          StrCpy $OriginalTimeHigh $CurrentTimeHigh
-          StrCpy $OriginalTimeLow  $CurrentTimeLow
+          # The problem is now that LaTeX might need several runs and therefore the PDF can
+          # also be rewritten consecutively several times.
+          # If we would directly open the file we will get in troubles as the PDF can be
+          # unreadable. We also don't know the time of a LaTeX run.
+          # (As example take UserGuide.lyx, view it, then remove a letter in a section heading
+          # and finally update the view.)
+          # We therefore loop until the PDF is no longer changed and wait some time in each loop.
+          ${Do}
+           CopyFiles /SILENT $OriginalFile $PDFFile
+           # wait 1.666 seconds (is empirically enough time that the PDF can be changed)
+           Sleep 1666
+           ${FileTimeDiff} $TimeDiff "$PDFFile" "$OriginalFile"
+          ${LoopUntil} $TimeDiff = 0
+          
+          # open the new file
+          !insertmacro HideConsole '"$EXEDIR\pdfopen.exe" --file "$PDFFile"'
         ${EndIf}
         
         #Monitor again
         !insertmacro SystemCall "kernel32::FindNextChangeNotification(i $ChangeNotification)"
         
         ${EndIf}
         
         #Monitor again
         !insertmacro SystemCall "kernel32::FindNextChangeNotification(i $ChangeNotification)"
         
-      ${EndIf}
+      ${EndIf} # end ifnot
     
     ${Loop}
     
     
     ${Loop}