<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Eddie&#039;s Electronics &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/eddies-electronics/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 14 Feb 2023 21:24:56 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>PDFTable from a RowSet</title>
		<link>https://blog.xojo.com/2023/01/17/pdftable-from-a-rowset/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 17 Jan 2023 16:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Eddie&#039;s Electronics]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tables]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11146</guid>

					<description><![CDATA[Xojo recently introduced the ability to add (aka draw) tables in PDFDocument using the PDFTable class and the PDFTableDataSource class interface together. Perhaps you already know how to use it, but what if you want to add a table using data from a RowSet? Continue reading and I will show you a technique that will have you doing just that!]]></description>
										<content:encoded><![CDATA[
<p>Xojo recently introduced the ability to add (aka draw) tables in <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument">PDFDocument</a> using the <a href="https://documentation.xojo.com/api/pdf/pdftable.html#pdftable">PDFTable</a> class and the <a href="https://documentation.xojo.com/api/pdf/pdftabledatasource.html#pdftabledatasource">PDFTableDataSource</a> class interface together. Perhaps you already know how to use it, but what if you want to add a table using data from a <a href="https://documentation.xojo.com/api/databases/rowset.html#rowset">RowSet</a>? Continue reading and I will show you a technique that will have you doing just that!</p>



<span id="more-11146"></span>



<p>But before we dive into the code,&nbsp;this example project requires the &#8220;EddiesElectronics.sqlite&#8221; SQLite database file. You can find the Eddie&#8217;s Electronics example, along with the other example projects provided with Xojo, in the Examples section of the Project Chooser. Because I am such a kind person, you can also <a href="https://drive.google.com/file/d/1zts_ZL2ZQujW7fWD1m2qr_XpQGq3dbHD/view?usp=share_link">download it directly from this link</a>.</p>



<p>And, if you want, it is also possible to download the resulting <a href="https://drive.google.com/file/d/1Z5Eurwxm7UXlCLU_aj270SNKnlDmpT7Z/view?usp=share_link">Xojo Project file (for Desktop) from this link</a>.</p>



<p>I&#8217;m pretty sure you will be able to adapt the example project so it works for you with other databases too!</p>



<figure class="wp-block-image is-style-default"><img fetchpriority="high" decoding="async" width="809" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-809x1024.png" alt="" class="wp-image-11149" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-809x1024.png 809w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-237x300.png 237w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-768x972.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-1214x1536.png 1214w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF.png 1342w" sizes="(max-width: 809px) 100vw, 809px" /></figure>



<h3 class="wp-block-heading">Helper class to the rescue!</h3>



<p>All the work of drawing the table in the PDF document will be done by a helper class. That is, a class that we are going to use to &#8220;delegate&#8221; the work. With Xojo open and a new Desktop project created, the first thing we are going to do is add a new Class to the project (Insert &gt; Class).</p>



<p>With the added Class selected in the Navigator, go to the associated Inspector Panel and use the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> PDFRenderer</li>



<li><strong>Interfaces:</strong> Click on the &#8220;Choose&#8221; button and select the PDFTableDataSource class interface</li>
</ul>



<p>The just added Class will be populated with all the methods defined by the PDFTableDataSource class interface. Do not worry about them now.</p>



<p>Next, let&#8217;s add a few properties to our PDFRenderer class:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> data</li>



<li><strong>Type:</strong> RowSet</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<ul class="wp-block-list">
<li><strong>Name:</strong> document</li>



<li><strong>Type:</strong> PDFDocument</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<ul class="wp-block-list">
<li><strong>Name:</strong> DrawingFromRowSet</li>



<li><strong>Type:</strong> Boolean</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<ul class="wp-block-list">
<li><strong>Name:</strong> Headers()</li>



<li><span style="font-size: revert;"><strong>Type:</strong> String</span></li>



<li><span style="font-size: revert;"><strong>Scope:</strong> Protected</span></li>
</ul>



<p>We are going to use the DrawingFromRowSet as a flag, so the PDFRenderer knows when the table is going to be created from a RowSet. You could use any other data source, you are limited to RowSet. That&#8217;s just something you will need to implement yourself! Take it as an exercise.</p>



<p>Next, add a new Method to the PDFRenderer class (while still selected in the Navigator) using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> Constructor</li>



<li><strong>Parameters:</strong> document As PDFDocument</li>



<li><strong>Scope:</strong> Public</li>
</ul>



<p>And type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted xojo"><code>Self.Document = document</code></pre>



<p>Yep, it is truly that simple. Assign the received PDFDocument object to the &#8220;Document&#8221; property of the object created from the PDFRenderer class.</p>



<p>Add a second method using the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> DrawTable</li>



<li><strong>Parameters:</strong> rs As RowSet, headers() As String</li>



<li><strong>Scope:</strong> Public</li>
</ul>



<p>And type the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>// This is the method we call on the Class to draw
// a table on a PDFDocument based on a RowSet

If document &lt;&gt; Nil And rs &lt;&gt; Nil Then

  // Assign the received RowSet to the "Data" property
  Self.data = rs

  // Assign the received headers to the "Headers" property
  Self.Headers = Headers

  // Hey! We are going to create a table from a RowSet
  // so we use a Boolean property as a flag for that
  // (Yeah, we can do it using other techniques, but this
  // is easy enough for this purpose…&nbsp;while leave this
  // helper class "open" enough for drawing tables based on other
  // data sources).
  Self.DrawingFromRowSet = True

  // How many columns are we going to draw?
  // Well… as many as columns in the RowSet.
  Var totalColumns As Integer = rs.ColumnCount

  // This is going to be the "drawable area" on the page
  // for the table = total page width less the left and right margins
  Var totalWidth As Double = document.Graphics.Width - 40 // 40 = 20 points left/right margins

  // Creating the PDFTable object here!
  Var table As New PDFTable

  // We want to repeat the headers on every page
  table.HasRepeatingHeader = True

  // Setting the column count for the table
  table.ColumnCount = totalColumns

  // …and the width for every column.
  table.ColumnWidths = CalculateColumnWidths(TotalWidth, totalColumns)

  // The object from this class will be the responsible
  // for handling all the methods associated with the
  // PDFTableDataSouce Class Interface
  table.DataSource = Self

  // Setting the Top and Bottom margins for the drawing
  // of the table on every PDF page
  table.TopMargin = 20
  table.BottomMargin = 20

  // …and finally we instruct the PDFDocument object
  // to draw the table!
  document.AddTable(table, 20, 0)

  // Lastly, clearing the flag
  Self.DrawingFromRowSet = False

End If</code></pre>



<p>As you can see here, we are calling the &#8220;CalculateColumnWidths&#8221; method in order to get the expected string for the column widths for the PDFTable.ColumnWidths property; so add a new method to the PDFRenderer class using the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> CalculateColumnWidths</li>



<li><strong>Parameters:</strong> TotalWidth As Double, NumberOfColumns As Double</li>



<li><strong>Return Type:</strong> String</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<p>And type the following snippet of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>Var ColumnWidth As Integer = TotalWidth / NumberOfColumns
Var s() As String

For n As Integer = 0 To NumberOfColumns-1
  s.Add(Str(ColumnWidth))
Next

Return String.FromArray(s, ",")</code></pre>



<h3 class="wp-block-heading">PDFTableDataSource Methods with RowSet data!</h3>



<p>Let&#8217;s fill the required methods from the PDFTableDataSource class interface so they work in combination with the received RowSet.</p>



<h4 class="wp-block-heading">AddNewRow Method</h4>



<p>Add this snippet of code for the &#8220;AddNewRow&#8221; method:</p>



<pre class="wp-block-preformatted"><code>If DrawingFromRowSet And data &lt;&gt; Nil Then

  // We are going to draw as many rows as rows are in the
  // "data" rowset
  Return rowCount &lt;&gt; data.RowCount

End If</code></pre>



<p>As you can see, that fragment of code will only run when both conditions are meet. That is, when the &#8220;DrawingFromRowSet&#8221; is set to True and the &#8220;data&#8221; property is set to a not niled RowSet. If this is the case, we then instruct our PDFTable to set the number of rows to be drawn to the same number of rows in the RowSet.</p>



<h4 class="wp-block-heading">Completed Method</h4>



<p>This is the method that will be called once the drawing of the PDFTable has been completed. We will use it to draw the page numbers at the bottom of every page in the PDFDocument. As you probably already know, it is really easy to change the active graphic context to a given page of the PDF document using the CurrentPage property, so we will use that to iterate every one of our PDF document pages, adding the page number to it as a footer.</p>



<p>This is the snippet of code responsible for doing just that:</p>



<pre class="wp-block-preformatted"><code>// This method is called once the table has been drawn
// so let's "print" the page number on every page
// of the PDF Document

Static pageNumber As String = "Page: "

If document &lt;&gt; Nil Then
  Var g As Graphics = document.Graphics

  For n As Integer = 1 To document.PageCount
    document.CurrentPage = n
    g.DrawText(pageNumber + Str(n), g.Width - g.TextWidth(pageNumber+Str(n))-20, g.Height-g.FontAscent)
  Next

End If</code></pre>



<h4 class="wp-block-heading">HeaderHeight Method</h4>



<p>This is the method called so we can set the PDFTable the desired height for the drawing of the Header. In this case we are going to use a fixed value: 20 points. The code for that method is:</p>



<pre class="wp-block-preformatted"><code>// Fixed header height
Return 20</code></pre>



<h4 class="wp-block-heading">PaintCell Method</h4>



<p>This is the method responsible for drawing every cell of the PDFTable. It receives as parameters the Graphic context for a particular cell (so its origin is at 0,0) and the row and column values corresponding for such cell.</p>



<p>In this case, draw the outline of a rectangle for the cell plus the text itself retrieved from the RowSet based on the received Column value. The text will be draw vertically centered in the cell:</p>



<pre class="wp-block-preformatted"><code>If DrawingFromRowSet And data &lt;&gt; Nil Then
  // Drawing the outer rectangle for the cell
  g.DrawRectangle(0, 0, g.Width, g.Height)

  // retrieving the text to be drawn from the RowSet,
  // using the column parameter for that.
  Var s As String = data.ColumnAt(column)

  // Centering vertically the text on the table cell
  // while the X offset is fixed at 5 points.
  g.DrawText(s, 5, g.Height / 2 + g.FontAscent / 2)

  // Have we drawn all the columns for this row?
  If column = data.ColumnCount - 1 Then

    // if that is the case, then move to the next row
    // in the RowSet!
    data.MoveToNextRow
  End If

End If</code></pre>



<h4 class="wp-block-heading">PaintHeaderContent Method</h4>



<p>This is the method called in order to draw the Header of the table itself. It is a more simple version of the previous method. In this case, the text will be centered both vertically and horizontally on every header cell:</p>



<pre class="wp-block-preformatted"><code>If column &lt;= Self.Headers.LastIndex Then

  Var s As String = headers(column)
  g.DrawingColor = Color.Black
  g.FillRectangle(0, 0, g.Width, g.Height)
  g.DrawingColor = Color.White
  g.DrawText(s, g.Width / 2 - g.TextWidth(headers(column)) / 2, g.Height / 2 + g.FontAscent / 2)

End If</code></pre>



<h4 class="wp-block-heading">RowHeight Method</h4>



<p>As it happen with the HeaderHeight method, this is the method called to set the height for a given row. As we did for the HeaderHeight method we are going to use a fixed value of 20 points, so type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>Return 20</code></pre>



<h3 class="wp-block-heading">Testing The PDFRenderer class</h3>



<p>In order to test our PDFRenderer class in combination with a RowSet object, we need to do some additional work. First, select the Window1 window in the project Navigator and add a property using the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> db</li>



<li><strong style="font-size: revert;">Type:</strong><span style="font-size: revert;"> SQLiteDatabase</span></li>



<li><strong style="font-size: revert;">Scope:</strong><span style="font-size: revert;"> Private</span></li>
</ul>



<p>Next, click the Window1 window in the Navigator so it is displayed in the Layout Editor. Then, drag a DesktopLabel from the Library and drop it on the left/top edge of the layout observing the aligning guides so it leaves the expected margin over the left and top edges of the Window. Use the dragging handlers of the DesktopLabel on the layout to resize it to the maximum width (once again, less the expected margins). Use the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Locking:</strong> Left, Top and Right locked. Bottom, unlocked.</li>



<li><strong>Multiline:</strong> on.</li>



<li><strong>Text:</strong> This example project needs to use the EddiesElectronics.sqlite database file. Click on the button in order to select it!</li>
</ul>



<p>The layout at this point should look like this:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img decoding="async" width="1024" height="331" src="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-1024x331.png" alt="" class="wp-image-11147" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-1024x331.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-300x97.png 300w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-768x248.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36.png 1274w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>Now, drag a DesktopButton from the Library and drop it below the previous Label so it is horizontally centered, using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Caption:</strong> Select EddiesElectronics database file</li>
</ul>



<p>The finished layout should look like this:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img decoding="async" width="1024" height="747" src="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-1024x747.png" alt="" class="wp-image-11148" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-1024x747.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-300x219.png 300w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-768x561.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13.png 1422w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>Double click the button to add the &#8220;Pressed&#8221; Event Handler. Then, add the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>Try

  // Assigning SQLite object to property
  db = New SQLiteDatabase

  // Setting the database file to the SQLite object
  db.DatabaseFile = FolderItem.ShowOpenFileDialog(".sqlite")

  // Just a simple check to see if this is the expected
  // file based on the name = "EddiesElectronics.sqlite"

  If db.DatabaseFile = Nil Or db.DatabaseFile.Name &lt;&gt; "EddiesElectronics.sqlite" Then Return

  //…and "connecting" to it!
  db.Connect

  // Let's select all the rows from the Customers table
  Var rs As RowSet = db.SelectSQL("SELECT FirstName,LastName,Address FROM Customers")

  // Creating a new PDFDocument Instance
  Var d As New PDFDocument

  // Creating the PDFTable renderer helper object (we pass the PDFDocument object to it in the Constructor)
  Var PDFRender As New PDFRenderer(d)

  // These will be the headers drawn in the Table
  Var headers() As String = Array("Name", "Surname", "Address")

  // And let's instruct the PDFTable renderer helper to draw the table
  // based in the SQLite database rowset we got in the previous step
  PDFRender.DrawTable(rs, headers)

  // …and save the resulting PDF File to the Desktop
  Var f As FolderItem = SpecialFolder.Desktop.Child("TableFromRowSet.pdf")

  If f &lt;&gt; Nil Then
    d.Save(f)
    f.Open
  End If

Catch e As DatabaseException
  System.DebugLog(e.Message)
Catch e As NilObjectException
  System.DebugLog(e.Message)
End Try</code></pre>



<p>As you can see, all this does is create a new SQLiteDatabase object and assign it to the &#8220;db&#8221; property. Then, we set the &#8220;DataBaseFile&#8221; property of that object to the file selected by the user. The code will do a simple check to see if the selected file is the expected &#8220;EddiesElectronics&#8221; database file. If that is the case, then it will connect to the database, getting a RowSet from a simple query that retrieves the &#8220;name&#8221;, &#8220;surname&#8221; and &#8220;address&#8221; columns from the &#8220;Customers&#8221; database table.</p>



<p>After creating the PDFDocument instance, the code creates a new instance from our PDFRenderer class and calls the &#8220;DrawTable&#8221; method on that object passing along both the RowSet and the Headers we want to use for drawing the table.</p>



<p>Lastly, the PDFDocument will be saved to disk and opened in the by default PDF viewer app.</p>



<p>Run the app, select the &#8220;EddiesElectronics&#8221; SQLite database file&nbsp;and the resulting PDF file will be opened after a few seconds. It will display the table generated from a RowSet data source!</p>



<h3 class="wp-block-heading">In Summary</h3>



<p>It is quite possible to draw tables in a PDFDocument when the data to render comes from a RowSet. Nearly everything was done through the use of a helper class. As always, this can be improved in several ways! For example, we are using a fixed height for every row of the table, but in a more realistic scenario may be using variable heights for the table rows based in the height / amount of data to be drawn. That is something that is doable too!</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
