WebPrint UserLib (OSX x86)

Mac OSX specific forum
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

WebPrint UserLib (OSX x86)

Post by wilbert »

I converted a method to print web / html content I posted in another thread into a userlib.

Link to userlib : http://www.w73.nl/pb/libPBWebPrint.zip

Example code

Code: Select all

If OpenWindow(0, 0, 0, 200, 100, "WebPrint Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 10, 100, 20, "Print")

  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_Gadget
      Select EventGadget()
          
        Case 0
          
          WebPrint_SetPaperSize(420, 595); A5 paper
          WebPrint_SetOrientation(1); 0 = portrait, 1 = landscape
          WebPrint_SetMargins(70.9, 56.7, 56.7, 56.7)
          WebPrint_SetCentered(#False, #False)
          
          ; output url to pdf
          
          WebPrint_ToPDF("pbtest.pdf")
          WebPrint_SetPrintBackgrounds(#True)
          WebPrint_PrintURL("http://www.purebasic.com")
          
          ; show printer dialog and output 2 copies of a html text to the printer
                    
          WebPrint_ToPrinter()
          WebPrint_SetShowDialog(#True)
          WebPrint_SetCopies(2)
          WebPrint_SetOrientation(0)
          WebPrint_PrintHTML("<font face='Helvetica'>Testing<hr>HTML printing</font>")
          
      EndSelect
    EndIf      
  Until EventID = #PB_Event_CloseWindow
  
EndIf
Last edited by wilbert on Wed May 31, 2017 3:14 pm, edited 1 time in total.
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: WebPrint UserLib (OSX x86)

Post by jesperbrannmark »

Isn't there any "Like" button here like there is on facebook ;-)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: WebPrint UserLib (OSX x86)

Post by wilbert »

I don't think so but I'm glad you like it :D

It seems that it's also possible using html to insert page breaks.

Code: Select all

PageBreak.s = "<div style='page-break-after:always'>&nbsp;</div>"

If OpenWindow(0, 0, 0, 200, 100, "WebPrint Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 10, 100, 20, "Print")

  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_Gadget
      Select EventGadget()
          
        Case 0
          
          WebPrint_SetShowDialog(#True)

          WebPrint_SetPaperSize(595, 842); A4 paper
          WebPrint_SetOrientation(0); 0 = portrait, 1 = landscape
          WebPrint_SetMargins(70.9, 56.7, 56.7, 56.7); margins in points
          WebPrint_SetCentered(#False, #False)
          
          H.s = "<font face='Helvetica'>"
          H+ "Testing<hr>HTML printing"
          H+ PageBreak
          H+ "Page 2"
          H+ PageBreak
          H+ "Page 3"
          H+ "</font>"

          WebPrint_PrintHTML(H)
          
      EndSelect
    EndIf      
  Until EventID = #PB_Event_CloseWindow
  
EndIf
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: WebPrint UserLib (OSX x86)

Post by jesperbrannmark »

In a lot of cases it doesnt load images. Try this:
Disconnect printer
Run code
Click on printer and then click on the printouts to preview them.
I get about 20% of them without the Purebasic logotype...
Is there a timeout that can be changed?

Code: Select all

If OpenWindow(0, 0, 0, 200, 100, "WebPrint Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 10, 100, 20, "Print")
  
  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_Gadget
      Select EventGadget()
          
        Case 0
          
          WebPrint_SetPrintBackgrounds(#True)
          
          For i=1 To 10 ;- do the same thing 10 times
            WebPrint_ToPrinter()
            WebPrint_SetShowDialog(#False)
            WebPrint_SetOrientation(0)
            WebPrint_PrintURL("http://www.purebasic.com")
          Next
      EndSelect
    EndIf      
  Until EventID = #PB_Event_CloseWindow
  
EndIf
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: WebPrint UserLib (OSX x86)

Post by wilbert »

jesperbrannmark wrote:Is there a timeout that can be changed?
Currently the way it works is by using the didFinishLoadForFrame method of the WebFrameLoadDelegate protocol.
https://developer.apple.com/library/mac ... rence.html
The reference states
This method is invoked when a location request for frame has completed; that is, when all the resources are done loading.
So it should wait I guess.
Can it a problem with the connection ?
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: WebPrint UserLib (OSX x86)

Post by jesperbrannmark »

No this I have tried from several computers. One has a webserver right next to it. Also tried from my home 3G modem and the result is about the same. So I am getting the same problem with both OS X 10.7.x and 10.6.x and different connections.
I would think (since if you look at the popups from printing they are multiple at the same time) that if it would be possible to freeze program until printing is done instead of doing it in background - this would solve the problem.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: WebPrint UserLib (OSX x86)

Post by wilbert »

Freezing shouldn't make a difference since printing starts when everything is loaded.

The following code should print the web view itself (not the whole content).
Does that show images or also not ?

Code: Select all

EnableExplicit

; *** import the required C functions ***

ImportC ""
  
  HIWebViewGetWebView(inView)
  
  oClassAddMethod(class, selector, imp, types.p-ascii) As "_class_addMethod"
  oClass(name.p-ascii) As "_objc_lookUpClass"
  oCreateClass(superclass, name.p-ascii, extraBytes = 0) As "_objc_allocateClassPair"
  oInstance(class, extraBytes = 0) As "_class_createInstance"
  CocoaMessageSend(receiver, selector, arg1 = #Null, arg2 = #Null, arg3 = #Null) As "_objc_msgSend"
  oRegisterClass(class) As "_objc_registerClassPair"
  oSel(name.p-ascii) As "_sel_registerName"
  
EndImport

; *** selectors that are used a lot ***

Global SEL_absoluteString = oSel("absoluteString")
Global SEL_dataSource = oSel("dataSource")
Global SEL_frameView = oSel("frameView")
Global SEL_getCharacters_range_ = oSel("getCharacters:range:")
Global SEL_length = oSel("length")
Global SEL_print = oSel("print:")
Global SEL_request = oSel("request")
Global SEL_URL = oSel("URL")

; *** functions to get frame url ***

Procedure.s StringFromNSString(nsstring)
  Protected len = CocoaMessageSend(nsstring, SEL_length)
  Protected *mem = malloc_(len << 1); allocate 16 byte aligned uninitialized memory
  CocoaMessageSend(nsstring, SEL_getCharacters_range_, *mem, 0, len)
  Protected result.s = PeekS(*mem, len, #PB_Unicode)
  free_(*mem)
  ProcedureReturn result
EndProcedure

Procedure.s GetFrameURL(frame, provisional = #False)
  Protected source = CocoaMessageSend(frame, SEL_dataSource)
  Protected urlString = CocoaMessageSend(CocoaMessageSend(CocoaMessageSend(source, SEL_request), SEL_URL), SEL_absoluteString)
  ProcedureReturn StringFromNSString(urlString)
EndProcedure

; *** the functions for our delegate class ***

ProcedureC LoadComplete(obj, sel, webview, frame); load complete
  Debug "Finished loading : " + GetFrameURL(frame)
  Protected frameView = CocoaMessageSend(frame, SEL_frameView)
  CocoaMessageSend(frameView, SEL_print)
EndProcedure

; *** create the delegate class and instance ***

Define FrameLoadDelegateClass = oCreateClass(oClass("NSObject"), "PB_FrameLoadDelegate"); PB_FrameLoadDelegate class extends NSObject
oClassAddMethod(FrameLoadDelegateClass, oSel("webView:didFinishLoadForFrame:"), @LoadComplete(), "v@:@@")
oRegisterClass(FrameLoadDelegateClass)
Define FrameLoadDelegate = oInstance(FrameLoadDelegateClass)

; *** class and instance are created now ***


; test the frame load delegate

If OpenWindow(0, 0, 0, 600, 340, "WebPrint", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 10, 100, 20, "Load page")
  
  Define PBWebView = WebGadget(#PB_Any, 10, 50, 580, 280, "")
  Define WebView = HIWebViewGetWebView(GadgetID(PBWebView))
  CocoaMessageSend(WebView, oSel("setFrameLoadDelegate:"), FrameLoadDelegate)
  
  Repeat
    Define EventID = WaitWindowEvent()
    If EventID = #PB_Event_Gadget
      Select EventGadget()
          
        Case 0
          SetGadgetText(PBWebView, "http://www.purebasic.com")
          
      EndSelect
    EndIf      
  Until EventID = #PB_Event_CloseWindow
  
EndIf
Last edited by wilbert on Sun Sep 23, 2012 12:20 pm, edited 1 time in total.
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: WebPrint UserLib (OSX x86)

Post by jesperbrannmark »

On the first sample code i added

Code: Select all

            WebPrint_SetShowDialog(#True)
instead of false, and here i now get no pictures.
on the last sample you sent I do get images - but something is strange.
A while back I noted that webgadget need to be at 0 in either X or Y otherwise you had to move the mouse around to get page continue to update. This is just the issue here due to:

Code: Select all

  ButtonGadget(0, 10, 10, 100, 20, "Load page")
  
  Define PBWebView = WebGadget(#PB_Any, 10, 50, 580, 280, "")
When I change to:

Code: Select all

  ButtonGadget(0, 500, 10, 100, 20, "Load page")
  
  Define PBWebView = WebGadget(#PB_Any, 0, 0, 480, 280, "")
I still have to move mousepointer left into the area of the webgadget, so the behavour is similar to the issue with webgadget reported before about a year ago.
However, it prints pictures wonderful. Would there be any way of hide the printout properties (nr copies, printer name) etc to do some more testing here?
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: WebPrint UserLib (OSX x86)

Post by jesperbrannmark »

I have put together a test that uses all these methods. I see different people are getting different results.
My computers the only one working fully is the one using Safari - but on other computers that seem to print the wrong page from time to time. On my computers the webprint userlib seem to chop off images (most likely because they dont have time to load).
Remember a while back we were talking about the issue with Webgadget, that one coordinate needed to be 0 (x or y - or both) otherwise you would have to move the mouse in order for it to actually change anything on screen? - Could this be an artifact of this?

Code: Select all

;EnableExplicit

; *** import the required C functions ***

ImportC ""
  
  HIWebViewGetWebView(inView)
  
  oClassAddMethod(class, selector, imp, types.p-ascii) As "_class_addMethod"
  oClass(name.p-ascii) As "_objc_lookUpClass"
  oCreateClass(superclass, name.p-ascii, extraBytes = 0) As "_objc_allocateClassPair"
  oInstance(class, extraBytes = 0) As "_class_createInstance"
  CocoaMessage(receiver, selector, arg1 = #Null, arg2 = #Null, arg3 = #Null) As "_objc_msgSend"
  oRegisterClass(class) As "_objc_registerClassPair"
  oSel(name.p-ascii) As "_sel_registerName"
  
EndImport

; *** selectors that are used a lot ***

Global SEL_absoluteString = oSel("absoluteString")
Global SEL_dataSource = oSel("dataSource")
Global SEL_frameView = oSel("frameView")
Global SEL_getCharacters_range_ = oSel("getCharacters:range:")
Global SEL_length = oSel("length")
Global SEL_print = oSel("print:")
Global SEL_request = oSel("request")
Global SEL_URL = oSel("URL")

; *** functions to get frame url ***

Procedure.s StringFromNSString(nsstring)
  Protected len = CocoaMessage(nsstring, SEL_length)
  Protected *mem = malloc_(len << 1); allocate 16 byte aligned uninitialized memory
  CocoaMessage(nsstring, SEL_getCharacters_range_, *mem, 0, len)
  Protected result.s = PeekS(*mem, len, #PB_Unicode)
  free_(*mem)
  ProcedureReturn result
EndProcedure

Procedure.s GetFrameURL(frame, provisional = #False)
  Protected source = CocoaMessage(frame, SEL_dataSource)
  Protected urlString = CocoaMessage(CocoaMessage(CocoaMessage(source, SEL_request), SEL_URL), SEL_absoluteString)
  ProcedureReturn StringFromNSString(urlString)
EndProcedure

; *** the functions for our delegate class ***

ProcedureC LoadComplete(obj, sel, webview, frame); load complete
  Debug "Finished loading : " + GetFrameURL(frame)
  Protected frameView = CocoaMessage(frame, SEL_frameView)
  CocoaMessage(frameView, SEL_print)
EndProcedure

; *** create the delegate class and instance ***

Define FrameLoadDelegateClass = oCreateClass(oClass("NSObject"), "PB_FrameLoadDelegate"); PB_FrameLoadDelegate class extends NSObject
oClassAddMethod(FrameLoadDelegateClass, oSel("webView:didFinishLoadForFrame:"), @LoadComplete(), "v@:@@")
oRegisterClass(FrameLoadDelegateClass)
Define FrameLoadDelegate = oInstance(FrameLoadDelegateClass)

; *** class and instance are created now ***



OpenWindow(0,0,0,640,480,"TEST 1")
ButtonGadget(1,0,0,200,30,"TEST 1")
ButtonGadget(2,0,40,200,30,"TEST 2")
ButtonGadget(3,0,80,200,30,"TEST 3")
ButtonGadget(4,0,120,200,30,"TEST 4")

Define PBWebView = WebGadget(#PB_Any, 0, 250, 580, 280, "")
Define WebView = HIWebViewGetWebView(GadgetID(PBWebView))
CocoaMessage(WebView, oSel("setFrameLoadDelegate:"), FrameLoadDelegate)

Repeat
  a=WaitWindowEvent()
  If a=#PB_Event_Gadget And EventGadget()=1
    WebPrint_ToPrinter()
    WebPrint_SetPrintBackgrounds(#True)
    WebPrint_SetShowDialog(#True)
    WebPrint_PrintURL("http://www.purebasic.com")
  ElseIf a=#PB_Event_Gadget And EventGadget()=2
    WebPrint_ToPrinter()
    WebPrint_SetPrintBackgrounds(#True)
    WebPrint_SetShowDialog(#False)
    WebPrint_PrintURL("http://www.purebasic.com")
  ElseIf a=#PB_Event_Gadget And EventGadget()=3
    SetGadgetText(PBWebView, "http://www.purebasic.com")
  ElseIf a=#PB_Event_Gadget And EventGadget()=4
    aa.s="tell application "+Chr(34)+"Safari"+Chr(34)+#CRLF$
    aa.s+"make new document at end of documents"+#CRLF$
    aa.s+"set URL of document 1 to "+Chr(34)+"http://www.purebasic.com"+Chr(34)+#CRLF$
    aa.s+"try"+#CRLF$
    aa.s+"repeat"+#CRLF$
    aa.s+"delay 0.5"+#CRLF$
    aa.s+"tell application "+Chr(34)+"System Events"+Chr(34)+" to "
    aa.s+"tell application process "+Chr(34)+"Safari"+Chr(34)+#CRLF$
    aa.s+"if (name of static text 1 of group 1 of window 1 as text) begins with "+Chr(34)+"Contacting"+Chr(34)
    aa.s+" or (name of Static text 1 of group 1 of window 1 as text) begins with "+Chr(34)+"Loading"+Chr(34)+" then "+#CRLF$
    aa.s+"else"+#CRLF$
    aa.s+"exit repeat"+#CRLF$
    aa.s+"end if"+#CRLF$
    aa.s+"end tell"+#CRLF$
    aa.s+"end repeat"+#CRLF$
    aa.s+"on error"+#CRLF$
    aa.s+"delay 3"+#CRLF$
    aa.s+"end try"+#CRLF$
    aa.s+"tell front document"+#CRLF$
    aa.s+"print"+#CRLF$
    aa.s+"close"+#CRLF$
    aa.s+"end tell"+#CRLF$
    aa.s+"close"+#CRLF$
    aa.s+"end tell"+#CRLF$
    COCOA_AppleScript(aa.s)
    
  EndIf
  
Until a=#PB_Event_CloseWindow
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: WebPrint UserLib (OSX x86)

Post by jesperbrannmark »

ok. With PB 4.7b1 this works PERFECT! So the issues we saw were probably a Cocoa <-> Carbon thing.

Code: Select all

If OpenWindow(0, 0, 0, 200, 100, "WebPrint Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 10, 100, 20, "Print")
  
  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_Gadget
      Select EventGadget()
          
        Case 0
          
          WebPrint_SetPrintBackgrounds(#True)
          
          For i=1 To 10 ;- do the same thing 10 times
            WebPrint_ToPrinter()
            WebPrint_SetShowDialog(#False)
            WebPrint_SetOrientation(0)
            WebPrint_PrintURL("http://www.purebasic.com")
          Next
      EndSelect
    EndIf      
  Until EventID = #PB_Event_CloseWindow
  
EndIf

Running in 4.7b1 with carbon as linker subsystem gives this error (that has already been reported on other problems in the beta)
Undefined symbols for architecture i386:
"_PB_Window_GetID", referenced from:
-[PBMenuDelegate eventHandler:] in Cocoa.a(MenuDelegate.o)
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: WebPrint UserLib (OSX x86)

Post by jesperbrannmark »

Do we have something similar like WebPrint_PrintURL("http://www.purebasic.com") using CocoaMessage command?
Meaning, can we print a URL without the use of a webgadget or a window?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: WebPrint UserLib (OSX x86)

Post by wilbert »

That command still uses a WebView object internally.
It would be possible to recreate using multiple commands but not with a single cocoa message.
Have you considered using an invisible window or something like that ?
Post Reply