Tip of the day: Folderitem items sorted

Here are some code snippets for methods, you may want to put in a module and use in your project. They return you the items or true items in a folder sorted by name and optionally with hidden items skipped:

Function Items(extends f as FolderItem, IncludeInvisible as Boolean = true) As FolderItem() // return all items in a folder // resoloves aliases or links // optionally filters hidden files Dim items() As FolderItem Dim c As Integer = f.Count For i As Integer = 1 To c Dim item As FolderItem = f.Item(i) If item <> Nil Then If IncludeInvisible Or item.Visible Then items.Append item end if End If Next Return items End Function
Function ItemsSorted(extends f as FolderItem, IncludeInvisible as Boolean = true) As FolderItem() // return all items in a folder ordered by display name // resoloves aliases or links // optionally filters hidden files Dim items() As FolderItem dim names() As string Dim c As Integer = f.Count For i As Integer = 1 To c Dim item As FolderItem = f.Item(i) If item <> Nil Then If IncludeInvisible Or item.Visible Then items.Append item names.Append item.DisplayName end if End If Next names.SortWith items Return items End Function
Function TrueItems(extends f as FolderItem, IncludeInvisible as Boolean = true) As FolderItem() // return all true items in a folder // does not resolove aliases or links // optionally filters hidden files Dim items() As FolderItem Dim c As Integer = f.Count For i As Integer = 1 To c Dim item As FolderItem = f.TrueItem(i) if item <> nil then If IncludeInvisible Or item.Visible Then items.Append item end if end if Next Return items End Function
Function TrueItemsSorted(extends f as FolderItem, IncludeInvisible as Boolean = true) As FolderItem() // return all true items in a folder ordered by display name // does not resolove aliases or links // optionally filters hidden files Dim items() As FolderItem dim names() As string Dim c As Integer = f.Count For i As Integer = 1 To c Dim item As FolderItem = f.TrueItem(i) If item <> Nil Then If IncludeInvisible Or item.Visible Then items.Append item names.Append item.DisplayName end if End If Next names.SortWith items Return items End Function

ZUGFeRD 2.0 and Factur-X for Xojo

With the last DynaPDF update we got new support for ZUGFeRD 2.0 and Factur-X, two standards to deliver invoices as PDF files with embedded XML data. We supported ZUGFeRD 1.0 before and now upgraded code to support version 2 in addition.


So here is a little Xojo code snippet to convert an existing PDF into a ZUGFeRD 2.0 document. Before you start, please assemble the XML for the invoice and know whether it's Minimum, Basic, Comfort or Extended level. So the code here starts with a new DynaPDFMBS object and creates a new PDF environment. We set import flags to import all content and prepare for PDF/A. If needed, you could skip some content like annotations directly here.


dim pdf as new MyDynapdfMBS

dim f as FolderItem = SpecialFolder.Desktop.Child("Create PDF.pdf")

pdf.SetLicenseKey "Pro" // For this example you can use a Pro or Enterprise License

// now create PDF

call pdf.CreateNewPDF f

Dim flags As Integer

flags = Bitwise.BitOr(flags, pdf.kifImportAll)

flags = Bitwise.BitOr(flags, pdf.kifImportAsPage)

flags = Bitwise.BitOr(flags, pdf.kifPrepareForPDFA)

call pdf.SetImportFlags(flags)


Next we load an existing PDF from a container field. Of course you can also use functions to create new pages here or open an import PDF from a file on disk. The next line imports the whole PDF file we opened into our work PDF. If you repeat the open and import step, you can merge several documents here. If you need only one page, you can use DynaPDF.ImportPDFPage function.


// import PDF file

dim ImportFile as FolderItem = FindFile("invoice template.pdf")

call pdf.OpenImportFile(ImportFile)

call pdf.ImportPDFFile(1) 


Per PDF/A requirement, we add here the language setting and a structure tree:


// PDF/A requires a language set

Call pdf.SetLanguage("en-US")

// PDF/A requires a structure tree

Call pdf.CreateStructureTree


If the PDF contains colorspaces which are not backed by an ICC Profile, we get an OnReplaceICCProfile event call to provide a replacement profile to the PDF engine. So if there is a colorspace missing the profile, it will be using one of our replacement profiles for RGB, Gray or CMYK. Here is an example implementation of the event, which looks for some generic profiles to replace an existing one:


EventHandler Function OnReplaceICCProfile(Type as integer, ColorSpace as integer) As integer

// provide missing ICC Profiles to DynaPDF

// The ICC profiles which should normally be configured by the user.

Dim filename As String

Select Case type

Case Me.kictGray

filename = "Generic Gray Profile.icc"

Case Me.kictRGB

filename = "Generic RGB Profile.icc"

Case Me.kictCMYK

filename = "Generic CMYK Profile.icc"

Case Me.kictLab

// not yet needed, but maybe in future

filename = "Generic Lab Profile.icc"



Return -1 // new type we don't know?

End Select

Dim f As FolderItem = FindFile(filename)

If f = Nil Or Not f.Exists Then

// file missing?

Return -1

End If

Dim e As Integer = ReplaceICCProfile(ColorSpace, f)

If e < 0 Then

// failed


End If

// pass along success or failure

Return e

End EventHandler


There is another event for missing fonts, where you can provide a replacement font. We simply replace missing fonts with Arial


EventHandler Function OnFontNotFound(PDFFontRef as integer, FontName as string, Style as integer, StdFontIndex as integer, IsSymbolFont as boolean) As integer

// Here you could use your own mapping table.

// In this example we replace the font simply with Arial

if (WeightFromStyle(Style) < 500) then

// Only the weights 500 and 700 of Arial are installed

// by default. If you have also light variants then it is

// not required to change the style.

Style = BitwiseAnd(Style, &h0F)

Style = BitwiseOr(Style, kfsRegular)

end if

return ReplaceFont(PDFFontRef, "Arial", Style, true)

End EventHandler


Next we attach the XML invoice to the PDF. You can pass attachments as container, file or text, but please use the corresponding function. Here we pass it as text from a field, specify UTF-8 encoding and the ZUGFeRD specific file name. The attachment is associated with the main catalog as an alternative version.


// now add xml

Dim file As FolderItem = FindFile("ZUGFeRD-invoice.xml")

dim n as integer = pdf.AttachFile(file, "ZUGFeRD Rechnung", false)

if not pdf.AssociateEmbFile(pdf.kadCatalog, -1, pdf.karAlternative, n) then

Break // error

end if


Now we do the conformance check. If you licensed the PDF/A converter from us (Add-on for DynaPDF Pro), you get the PDF fixed if needed. If the PDF was already PDF/A, this should return okay and tel you which output indent is recommended. We than add the ICC Profile for RGB or CMYK to indicate how the PDF likes to be viewed.


// make sure we conform

// for perfect usage, you need PDF/A extension for DynaPDF (extra purchase)

// here we pass Basic level. Please make sure XML and level here match!

Dim retval As Integer = pdf.CheckConformance(pdf.kctZUGFeRD2_Basic, pdf.kcoDefault)

Select case retval

case 1

call pdf.AddOutputIntent(RGBProfileFile) // RGB

case 2

call pdf.AddOutputIntent(CMYKProfileFile) // CMYK

case 3

call pdf.AddOutputIntent(GrayProfileFile) // Gray

end Select


Finally we close the PDF file and let the destructor free the PDF environment.


call pdf.CloseFile 


We hope you enjoy this blog post. Please check the example databases included with MBS Xojo Plugins 19.3.

Ideas from WWDC

After a few days passed some of the details in various WWDC sessions show up.

I got a few points of interest to look into till the new releases appear in the wild and this includes:
  • Text recognition in Vision framework
  • Speech functions
  • Encryption functions
  • Asking for permissions to access user folders
  • CoreML functions
  • Enhancements for AppKit
  • Color picker
  • Sign-in with Apple button
Anything else? What are you interested in using in your solution with help of our plugins?

The release for MacOS 10.15 and iOS 13 are expected for September/October. The APIs are still in flux and the betas not yet polished. So let's wait for the public betas in July before we change applications. So maybe in August, we could show you some plugins for some new features.

Xcode 11 is working well and our projects build already with a few little changes.

MBS Xojo Plugins, version 19.3pr2

New in this prerelease of the 19.3 plugins:
  • Updated DynaPDF to version
  • Changed Create3DView in DynaPDFMBS class to now use unicode version of the function. Also keep old function as Create3DViewAnsi.
  • Added BindedValues and BindedTypes property for SQLPreparedStatements to inspect bindings.
  • Added isCatalina function for SystemInformationMBS class.
  • Added OpenDirectory classes for Xojo: ODQueryMBS, ODRecordMBS, ODNodeMBS and ODSessionMBS.
  • Added LibVersion, BarcodeMailMark, BarcodeUPNQR, BarcodeVin, FontSize and InputModeEscape to BarcodeGeneratorMBS class.
  • Added ZintRenderHexagonMBS.Height property.
  • Updated libzint to version 2.6.3.
  • Updated libiconv to version 1.16.
  • Updated libPNG to version 1.6.37.
  • Updated PCRE to version 8.43.
  • Updated libxlst to version 1.1.33.
  • Updated libxml2 to version 2.9.9.
  • Updated libcpuid to version 0.4.1.
  • Updated OpenSSL to version 1.1.1c.
  • Updated curl to version 7.65.1.
  • Added examples for ZUGFeRD 2.0 and Factur-X for DynaPDF.
  • Changed iTunesLibraryMediaEntityMBS.persistentID to Int64.
  • Added WindowsADSystemInfoMBS class to query Active Directory details for current user.
  • Deprecated ImageCaptureMBS and ImageCaptureObjectMBS classes.
  • Removed helpWindow, eventWindow and shadowWindow from NSHelpManagerMBS class.
  • Added SQLDatabaseMBS.kOptionLibraryCubeSQL and SQLConnectionMBS.kOptionLibraryCubeSQL constants.
Download: monkeybreadsoftware.com/xojo/download/plugin/Prerelease/.
Or ask us to be added to our shared Dropbox folder.

CubeSQL Library for Mac

We just built a CubeSQL client library for Mac, the cubesql.dylib. You can download it in our download area in Libs folder.

As you may know you can use SQL functions in both MBS Xojo SQL Plugin and MBS FileMaker Plugin to connect to a CubeSQL server and perform queries. Since SQLabs does not yet provide prebuilt libraries for Mac & Linux, we just made one for Mac 32 and 64 bit with OpenSSL embedded.

For Xojo, you can of course use InternalCubeSQLLibraryMBS module which has library embedded for all platforms right into our MBS Xojo SQL Plugin.

For FileMaker, please use library files. For example in your script set the library path as a connection option.

For Windows:
MBS( "SQL.SetConnectionOption"; $Connection; "CUBESQL.LIBS"; "c:\CubeSQL\cubesql.dll" )

For MacOS:
MBS( "SQL.SetConnectionOption"; $Connection; "CUBESQL.LIBS"; "/Users/cs/Desktop/cubesql.dylib" )

Of course you need different paths depending on your installation. e.g. you can put the CubeSQL library in the same folder as the plugins.

WWDC Tipps and Notes

WWDC is the yearly Apple developer conference. With over 5000 attendees and 1000 Apple engineers on site (plus security and host people from Apple), there are people everywhere. It is a great experience and after several years of trying the lottery, I had the honor to join the conference this year. Here a few notes to make live easier:
  • The keynote room is big enough to sit everyone. No need to hurry to get a seat.
  • Whether it is worth waiting 4 hours to get a spot in a front row? Next time I'd better come at 9:30, sit in the back and not so close near the screen that I need to move my head to see the other side.
  • Watching the keynote on a screen at home has a big advantage: You can press the pause button. And you can open a website in parallel with a newsfeed so you have a transcript to look back. This year the keynote was very fast and there was not enough time to read slides with a lot of text.
  • Bring a jacket. It's cold early morning outside and often the temperature in the rooms is chilly.
  • Bring a bag folded in your pocket. Over the day, you may need to stuff things there like your jacket, some purchases at the Apple store or simply food for having it later.
  • Rucksacks are not optimal as you may run into bag checks on the entry. Laptop bags are more likely to be inspected.
  • Skip the waiting lines for sessions. The sessions are in general not very full, so you can just walk into 5 minutes before the session starts and find a good spot. As you can watch all session later at home, the only benefit of going there is to get the information earlier and then ask questions at the labs. There are no questions taken in the session room.
  • Go to the labs. Before WWDC make detailed list with things to ask, sample projects to show your issues, radar numbers for the bugs, so they can follow up. And check if the bug is fixed in new beta already before (!) you ask.
  • If you need the restroom, best go there when sessions start or leave one a minute before it ends. You may even use restrooms in the session room (on the back wall) before the session starts.
  • Grab some food and drinks early when it's delivered, put it in the bag and walk to find an area where you can eat without a thousand people watching you. If you come late to the food tables, the best stuff is taken...
  • Bring extra devices to install the beta software. Don't put it on your regular machine unless it's a VM for MacOS. First betas are said to be buggy and may not even boot or cause data loss.
  • For hotel booking: Either you pick an expensive one in downtown San Jose or you stay outside. As car park is $25 in the conference center and nearby parking space, the best choice seems to pick a hotel near a train station and use those local trains here in the city. I stayed at the Courtyard hotel in Campbell which is just a few stops away and right next to a train station. The train is $5 per day for two trips.
  • A wish to Belkin and Apple: Please make USB-C Ethernet adapters which can charge the MacBook Pro via Power over Ethernet. That would be even better for sitting in the CafĂ© area.
The conference can be a great experience with thousands of developers from all over the world. I learnt a ton of things and got a few ideas for new plugins, but more in a future blog post. You can make friends, find a lot of other developers from your country (lots of German) and ask your questions directly to Apple employer. They may not answer everything, but sometimes you can read between the lines. Next year, I'll not enter the lottery to give others a chance to go there!

OpenDirectory Framework for Xojo

For next plugin version, we add OpenDirectory classes for MacOS. They allow you to query local, active directory and LDAP information for users.

We have ODSessionMBS class for a session, ODQueryMBS for synchronous or asynchronous queries. You may query for records (ODRecordMBS) on a given node (ODNodeMBS).

The existing classes allow you already to query details on the current user when logged into a Mac with Active Directory or LDAP server.

We also have LDAPMBS class for cross-platform queries to LDAP and Active Directory servers. But Apple deprecated the OpenLDAP library For MacOS, so it is not sure whether it will work in future OS versions. So far it looks like it is still included for MacOS 10.15.

You can try that soon with next prerelease. If you miss additional features, please let us know.

Plugin wishes for macOS 10.15 and iOS 13?

You may all be watching videos from WWDC and learn what's coming soon for macOS and iOS.

Now the are a lot of new APIs, but I'd like to know from you what you'd like to see in our plugins for Xojo and FileMaker.

Usually we provide lower level wrapper for Xojo to Apple's APIs for macOS with hiding all the threading issues from you and translating values from native Xojo types to the matching Foundation types. As there is currently no iOS plugin SDK for Xojo, we can't make all features available via declares.

For FileMaker we usually provide a much more higher level API to do selected things and provide plugin functions for both macOS and iOS.

If you have ideas and wishes, please email me. I'll keep a list and if we have a lot of wishes for a given API, I may give it some priority.

MBS Xojo Plugins, version 19.3pr1

New in this prerelease of the 19.3 plugins:
  • Updated DynaPDF to version
  • Added constants for DynaPDF to create ZUGFerd 2.0 and Factur-X files.
  • Fixed CSTransformMBS to better pick right alpha info for Xojo pictures.
  • Fixed QLPreviewPanel.Show to work if used with cards.
  • Fixed MKPinAnnotationViewMBS constructor.
  • Added multi line support for DynaPDFMBS graphics support with StringShape object.
  • Added trace support for graphics calls in DynaPDFMBS.
  • Fixed a problem with DynaPDFMBS ReplacePattern function and fonts missing the CID Ordering table.
  • Fixed issue with DynaPDFMBS graphics and center aligned text in reports.
  • Added OptionMaxAgeConn property for CURLSMBS class.
  • Added ZoneID property for CURLSURLMBS class.
  • Updated curl to version 7.65.0.
  • Improved automatic CURL library loading on Linux to better find the library.
  • Improved destructor for FSEventsMBS class to avoid a possible crash.
  • Improved SplitCommaSeparatedValuesMBS to better handle new lines.
Download: monkeybreadsoftware.com/xojo/download/plugin/Prerelease/.
Or ask us to be added to our shared Dropbox folder.

LLVM Bitcode

Did you know that Bitcode feature in Xcode and LLVM made it possible for Apple to recompile all 32-bit apps for the Apple Watch as 64-bit versions?

Bitcode is the representation of the app as the LLVM compiler internally uses it. The platform independent part parses code, optimizes and then passes this intermediate representation to the platform specific code generator, which then builds machine instructions for the target processor. Instead of outputting 32-bit code, Apple took the intermediate representation (the Bitcode) and let LLVM make a 64-bit version. A few tweaks may be needed like stubs to take 32-bit arguments and than call system functions with 64-bit values, but it looks like Apple figured that out.

Now if Apple goes someday with ARM processor for MacOS, the Bitcode in Mac apps (on the App Store) could allow the system to recompile the app for ARM 64-bit automatically. The developer uploaded his applications to Mac App Store and if bitcode is included, Apple could deliver them as ARM 64-bit for newer Macs automatically. Or if the bitcode is delivered with the final application, this could be done on the Mac on first-run.

I think that is a great way to make transition easier and not require an emulation at runtime like Rosetta for PPC code.

And to play with the bitcode option, I build a couple of libraries with bitcode and got a the MBS FileMaker Plugin for iOS built with Bitcode included. For a test with our MBS Xojo Plugins, I built a few of them with bitcode enabled. Maybe I can do the same for MacOS and make sure our plugin would benefit from an on device recompilation if such transition happens. But for now, we keep this as an experiment and disable bitcode again.


Jun 2019
Apr 2019
Mar 2019
Feb 2019
Jan 2019
Dec 2018
Nov 2018
Oct 2018
Sep 2018
Aug 2018
Jul 2018
Jun 2018
May 2018
Apr 2018
Mar 2018
Feb 2018
Jan 2018
Dec 2017
Nov 2017
Oct 2017
Sep 2017
Aug 2017
Jul 2017
Jun 2017
May 2017
Apr 2017
Mar 2017
Feb 2017
Jan 2017
Dec 2016
Nov 2016
Oct 2016
Sep 2016
Aug 2016
Jul 2016
Jun 2016
May 2016
Apr 2016
Mar 2016
Feb 2016
Jan 2016
Dec 2015
Nov 2015
Oct 2015
Sep 2015
Aug 2015
Jul 2015
Jun 2015
May 2015
Apr 2015
Mar 2015
Feb 2015
Jan 2015
Dec 2014
Nov 2014
Oct 2014
Sep 2014
Aug 2014
Jul 2014
Jun 2014
May 2014
Apr 2014
Mar 2014
Feb 2014
Jan 2014
Dec 2013
Nov 2013
Oct 2013
Sep 2013
Aug 2013
Jul 2013
Jun 2013
May 2013
Apr 2013
Mar 2013
Feb 2013
Jan 2013
Dec 2012
Nov 2012
Oct 2012
Sep 2012
Aug 2012
Jul 2012
Jun 2012
May 2012
Apr 2012
Mar 2012
Feb 2012
Jan 2012
Dec 2011
Nov 2011
Oct 2011
Sep 2011
Aug 2011
Jul 2011
Jun 2011
May 2011
Apr 2011
Mar 2011
Feb 2011
Jan 2011
Dec 2010
Nov 2010
Oct 2010
Sep 2010
Aug 2010
Jul 2010
Jun 2010
May 2010
Apr 2010
Mar 2010
Feb 2010
Jan 2010
Dec 2009
Nov 2009
Oct 2009
Sep 2009
Aug 2009
Jul 2009
Apr 2009
Mar 2009
Feb 2009
Dec 2008
Nov 2008
Oct 2008
Aug 2008
May 2008
Apr 2008
Mar 2008
Feb 2008