Unicode (Sep 2)

On a whim, our staff pasted some emojis into the new accounting software last week. It worked! The text saved fine to the database, and displayed properly. Much easier than expected. It’s all thanks to Qt’s robust support for UniCode.

Unicode is the standard format for all kinds of text, these days. It includes Ελληνικά (Greek), Українські (Ukranian), 한국어 (Korean), and any other language on this planet. Plus ♔♕♖♗♘♙, 😝🍑🏈🔥💩 and more.

This is one area where it really paid for us to procrastinate. Computer text has had some difficult times, but we missed most of the pain.

A typical English-language typewriter or keyboard has 47 printable keys, give or take a few. With shift and space bar: 95 characters. ASCII is a 7-bit system (128 choices) that’s big enough to handle it. Leftover slots are used for line feeds, tabs and the like.

Apple expanded ASCII to 8 bits. That’s what Goldenseal uses. The extra 128 characters include diacritics (ßàæçñòóôõö etc), Greek letters, extra currency symbols, and fancier punctuation. Other companies also expanded ASCII, but everyone used different setups. It’s why you’ll sometimes get emails with weird symbols.

8 bits is sufficient to cover most European languages. But move east, and there are whole new alphabets. Too much for just one byte.

For a while in the 90s and early Aughts, the solution was wchar_t. It’s 16-bit text, with 65,536 possible characters. That’s enough to hold alphabets for Britain, Thailand, and all points between. Wide characters support العربية (Arabic), کوردی (Kurdish), हिंदी (Hindi) etc.

That era was not fun. Some things still needed ASCII, some needed wchar_t. Use the wrong one and you’d get gibberish or worse.

Microsoft created a special hell, with LPSTR, LPCSTR, LPWSTR, LPCWSTR, LPTSTR, LPTCSTR, CStringA, CStringW, bstr_t, CComBSTR, WCHAR and TCHAR, all for different types of 8 or 16-bit text. There were equally obscure ways to convert between them: CW2A, C2AEX, etc. Use the wrong one and code would crash: sometimes suddenly, sometimes randomly later.

Move on to East Asia and wchar_t had another problem. China/Japan/Korea use ideographs: a different symbol for each word. Many thousands of them in each dialect. 2-byte text lacked space for them, so it wasn’t good enough for global use. It also was twice as bulky for regular Latin-language text.

Unicode fixed all that. It’s a clever system that mixes characters of different sizes: anything from 1-byte Latin to 4-byte 𒁎 (Ancient Sumerian). With over 4 billion possible glyphs, there’s room for every human language, current or extinct. Plus music notation. Emojis. Dingbats. Weird math symbols. And plenty more.

Even better, Unicode converts easily to UTF-8. That’s an 8-bit format that programmers can use to treat Unicode just like simple Latin text. Thanks to UTF-8, text-handling code inside our new accounting software accepts Unicode with no need to rewrite anything.

The new accounting app will have a few problems with Unicode, but nothing serious. Find works OK with special characters or emojis, but sorting won’t know what to do with non-Latin text. You’ll need to be careful with fonts: none support the entire gamut of Unicode, and some may be Latin-only. Other quirks may arise.

The next thing for us to test is rich text: with multiple fonts and formats inside. The Qt class we use for multi-line fields supports it. If we’re lucky, that also will be easy.

Dennis Kolva
Programming Director
TurtleSoft.com

Pictures & Links (Aug 28)

Custom Layouts is almost complete in our new accounting software. The biggest item still on the to-do list is pictures.

Goldenseal stores pix as binary data inside the company file. It uses Apple’s PICT format: once the most popular way to store bitmaps and vector images, but now obsolete.

Qt supports BMP, JPEG, PNG and a few less common graphic formats. But it can’t read PICT. We also couldn’t find any C++ code to do that. Sadly, when you convert your company file from Goldenseal to the new accounting app, any pictures will be left behind. Screen shots are the easiest way to salvage them.

The new business software stores all pictures as external files. You can put them in the TurtleSoft folder inside Pictures, or anywhere else that you choose. The database just has some text: a path to the folder location and file name.

There are trade-offs to the new system. On the plus side, it makes the company file smaller: no huge chunks of binary amongst the accounting and estimate data. Editing pictures is easier. There’s no need to export/import, just open them with any graphics app.

On the minus side: backups are more complicated. Switching to a new computer means moving more than just the app and company file.

File paths are good for more than just graphic images. They also can link to PDF documents, Excel spreadsheets, or anything else. Those files won’t display inside the accounting software window. Instead, they’ll launch the app that created them, and open in a separate window. Links also can use an Internet URL: those will open a browser page.

Goldenseal didn’t start out storing pictures inside records. We added them piecemeal to a few classes: first Cost Items, then Estimates, then a few more. In the new accounting app, any record class can store a picture, file link or website URL. The coding is easier that way.

I think pictures and links will be useful in many new places.

Dennis Kolva
Programming Director
TurtleSoft.com

 

 

 

Drawing Lines (Aug 20)

Our staff spent far too much time on line drawing this past week. We need them for printing and data forms in the new accounting software. Here’s a microscope view of one small bit of programmer sweat.

To print a line on screen or paper, it takes four numbers: x and y values for the start point, then x and y for the end. The same four numbers can also make a rectangle: one point for upper left, one for lower right. Qt specs it another way: upper left point, width, height. Both end up the same.

Every GUI uses lots of rectangles. Fields have visible boxes. Text has an invisible one. Ovals and rounded rectangles draw curves inside a box. Many apps have a drawing interface to modify shapes: it’s in all CAD software, MS Excel or Word, OpenOffice, Goldenseal’s Custom Layouts, and many others.

The standard used to be four handle boxes at the corners: drag on them to change size and shape. Drag the middle to move the whole thing. Goldenseal has code to do that in Custom Layouts. Newer software adds handles at the midpoints so you can pull in just one dimension. We now do that too.

Handle-dragging has a possible problem: what happens when you shrink to zero and keep going? Dealing with it is a programmer decision.

Goldenseal flips the numbers, turns the rectangle into a positive, and keeps going. That needed lots of complex code that isn’t easy to duplicate. The new accounting software simply stops before the edge. In fact, it won’t even go to zero, avoiding an itsy rectangle that’s hard to work with. After testing, the new approach seems fine.

Lines are less common, and totally different. In Goldenseal, you click on the handle at either end, and drag that point anywhere. A click in the middle drags the whole line. That code is buggy: some drags leave screen garbage. Getting pure verticals and horizontals isn’t easy.

Our staff tried to make end-dragging work the same way for lines in the new accounting software, but it was just too hard. Every attempt went bonkers. We finally decided to have separate commands for three types of lines: horizontal, vertical, diagonal. They’re now just rectangles that draw a line inside.

That still left one issue: diagonals can go up or down. Goldenseal stores the line slope to figure that: another design flaw. The easy answer was two commands for diagonal lines. Not like you see a lot of diagonals on business forms, anyhow.

Something trivial needed many attempts and much quandary. Multiply that by a few thousand, and it’s the history of TurtleSoft.

Dennis Kolva
Programming Director
TurtleSoft.com

Versions (Aug 13)

TurtleSoft released Goldenseal accounting/estimating software in 2000. It wasn’t long before we wanted to change it. New apps are never perfect in version 1.0. Heck, automobiles have been around for 138 years and they’re still getting big rewrites.

There’s a problem when we add new data fields. Users may already have records with the old setup, so the new code must accept two different arrangements. The solution is to use a file version number. When you read from disk, the code branches, depending on the version. Some data classes have changed many times: the current maximum is 9.

Layouts for data entry screens, reports and printed forms also need a version system. For example, we added help text to data fields in late 2000, then to buttons in 2001, then to breakdown tables in 2002. Each change added more data to read, so layouts also need different versions. The current max is 14.

For users, versions are invisible. For programmers, they are a PITA. Branches are easy to screw up. They clutter up the code base, and cause hard-to-find bugs.

Our new accounting software is a chance to start fresh. Once you convert your Goldenseal accounting file into the new app format, it bypasses all the old version branches. Some day we can delete them.

Likewise, new layouts are stored as text, not binary. Some day we can clear out the complicated code that reads Goldenseal layouts. In fact we won’t need many versions from now on, since text is less fussy than binary. We can add stuff at the end of a line and just continue if it’s not there.

Versions are one reason our staff has taken so long for the 64-bit replacement. We want to make all the big changes before the first release. Getting it right at the start avoids headaches later.

Meanwhile, our staff is still working on Custom Layouts. It’s now possible to add new fields and graphics. Colors can be partly transparent. Circles and ovals finally draw right, after much frustration. Lines are still a challenge. You’d think they’d be simpler than rectangles, but they’re not.

Dennis Kolva
Programming Director
TurtleSoft.com

Layouts & Screens (Aug 6)

Goldenseal accounting/estimating software is 24 years old. It was designed for the smaller screens of the 90s and early 00s, with pixels at 72 dots per inch. Since then, screens grew bigger and pixels shrank. Expectations of what an app should look like also changed to suit the bigger space.

Our new accounting software needs to fudge Goldenseal’s layouts to make them look OK on modern hardware. It has code for most problems: text expands from 9 points to 12, fields get bigger. The approach is similar to the Magnify feature in Goldenseal, added in version 4.3 to solve the same issue.

Even with adjustments, layouts still looked cluttered. So we added code to shift the right column over by 10 pixels. Plus a few other tweaks. Sometimes Mac and Windows need different treatments.

The code hacks makes most screens look better, but some are still ugly. We’ll need to adjust those individually, using Custom Layouts. Our staff spent the past couple weeks improving it: the work is nearly complete. You now can export layouts to a text file or import them back. Most of the nifty tools are working.

Editing a text file looks like a decent way to tweak layouts. Every value has a label, and most make sense. We also made a few changes to improve the new text-based system.

About the only thing left unfinished is pictures and logos. We did most of the work for those last year, but it’s time to make a final version. I’ll talk more about that in a future post.

Dennis Kolva
Programming Director
TurtleSoft.com

 

Printing & Formats (July 26)

When printing, the new accounting software currently puts everything onto paper or PDF, but it looks ugly. Right now our staff is working to make their appearance as close as possible to Goldenseal’s. It means another deep dive into Custom Layouts, the user interface that lets you change the appearance of just about anything in the app.

One update is in date formats. Goldenseal uses this dialog:

It’s complicated for users. Complicated to program. In fact, the sample date at the bottom sometimes won’t update properly: a very old bug that we just noticed.

The new software uses the Qt method, which is similar to Microsoft Excel. Just some text: M/d/yy = 7/26/24 and MMM d, yyyy = July 26, 2024, etc. It’s easier for users, and simple to program. No need to futz with radio buttons.

There are other details still unfinished in Custom Layouts: money and number formats, table setup, fancy font details. Some of those would take weeks or months of work to look like Goldenseal. For example, it has this complex dialog to set up report tables:

The new accounting software saves layouts as text, internally. We plan to avoid a ton of interface work by exporting and importing those. Then users (and our staff) can make fancy changes in a word processor or spreadsheet app.

We just need to figure out how to make the process as obvious as possible. Or at least less scary than that report table dialog. It was a monster to program, and not easy to use.

Dennis Kolva
Programming Director
TurtleSoft.com

 

 

 

Database Design (July 17)

We just fixed the problem of huge files in our new accounting software. It was caused by a couple stupid bugs in the code that decides where to save changed records inside the file. Zapping one got the TurtleSoft company file from 11 gigabytes down to 1.5 gigs. The second fix shrank it to 85 megabytes: bigger than the current 64 megs in Goldenseal, but that’s expected. We added a few things.

Our staff is back to using the new accounting software for our own business, in parallel with Goldenseal. As soon as there’s a month without serious bugs, it’ll be time for a first release.

Why did TurtleSoft write its own database code? Well, if we were just starting now, we’d use something free and open-source, for sure. Let someone else write the code to manage data on disk.

That was the original plan for Goldenseal in the late 80s, also. Our first estimating & accounting templates hit the limits of MS Excel, so we needed to switch to a real app. Open source software didn’t exist back then, so it needed to build atop something commercial.

First, we tried a dozen different databases and other development platforms: FileMaker, FoxBase, Omnis, etc. All had fatal flaws (usually lack of spreadsheet-like breakdowns for estimates).

We finally decided to write the interface in C++, and license an object database called NeoAccess to manage files. Neo was popular at the time, especially on Macintosh. It worked pretty well, up until we started to test with real data. Uh oh, there were crashes, corrupted files, and weird error messages deep in NeoAccess code. Emails to their tech support went unanswered. Soon the company disappeared.

Searching the early Internet showed internal emails from AOL, Netscape and others also searching for solutions, and/or making plans to give up on Neo. We were in too deep, and had no better options. So our staff spent a year rewriting NeoAccess to be more sturdy.

Most of the work was just making the code readable, so we could figure what it did. Several definite bugs turned up. We probably fixed others accidentally. That made it good enough for the 1.0 release. A couple years later, there were more updates to Goldenseal’s database code. Those fixed the last of the leftover bugs.

Our new accounting software inherits the good parts from the original NeoAccess design. Plus the good parts of what we changed and added for Goldenseal. Plus a few improvements, based on 20+ years of experience afterwards.

One thing that’s different now is gap tracking. It helps keeps files compact, even though records change size and need to move elsewhere.

Neo used CNeoFreeList to track empty spaces. Actually, many of them, scattered within the file. We replaced them with a single DB_GapManager, doing the same things but easier to debug. We also added a DB_FileManager, a list of where each record was in the file. It made double-sure that records would not write on top of something else. Later, it also allowed recovery of data that was lost when a NeoAccess index became corrupted.

Tracking gaps is complicated. Removing a record may leave a gap of the same size, or it may widen a gap that it touches. Remove a record with gaps on either side, and three gaps must merge into one. The system worked, but it was too complicated.

For the new accounting software, DB_GapManager is gone. Computers are fast enough now that we just zip through lists of record locations and sizes, and compute gaps between them. Simpler and more reliable, once the stupid logic bugs are fixed.

DB_FileManager is also replaced. Goldenseal sometimes ran out of memory because the manager was so big, so we now divide the file into bite-size sectors. DB_SectorManagers each handle disk space for 16,000+ records. Our company file has 13 sectors. There’s room for 16,000+ more, enough to manage 256 million records. There’s a way it can go beyond that, if ever needed.

BTW Google still shows a few hits for CNeoFreeList, 20+ years after its death. It’s mostly users back in the Aughties, trying to fix error messages and crashes in various apps.

NeoAccess caused pain for many Mac software developers, big and small. Other people’s code is not always the best answer.

Dennis Kolva
Programming Director
TurtleSoft.com

 

File Size (July 10)

Well, we finally fixed the mystery crashing error in our new accounting software. It took a week of testing and debugging. At least we fixed a few other potential problems along the way.

The good news is, the bug was simple. Our company file grew bigger than 4 gigabytes during the conversion from Goldenseal, but one old line of code still used 32-bit file marks. It truncated the 64-bit address, tried to save a record into the wrong part of the file, and chaos ensued. One small change made it OK.

The bad news is, our company file should not be that big. It already took up 3 gigabytes, then grew to 11 gigs in June. Goldenseal only needs 64 megs for TurtleSoft’s data. The new accounting app will have bigger files, but not by that much.

In theory, the new database has a good system to keep the file small, similar to what’s in Goldenseal. When saving a record, it looks for the first gap that’s a snug fit, and puts it there. If no tight fits, it then looks for large gaps with enough space left over to hold another record. If none of those, then it tries gaps that waste a little space (currently 24 bytes, but we may tweak it later). Any of those keep the file size unchanged. If no suitable gaps at all, the record tacks onto the end. That makes the file bigger.

If we’re lucky, there’s a stupid error in the gap-tracking code. Fix that, and files will shrink to a reasonable size.

If not lucky, we’ll need to fix a subtle design problem. One that can affect any database.

The conversion from Goldenseal to the new app does something potentially nasty. It loops through each bank transaction, and adds the ID to its bank account. That makes the account record 4 bytes bigger.

New files start out tightly packed, with zero gaps. When we save the account, it’s slightly too big for its old space, so it adds to the end. Next save it’s even bigger, so to the end again. Repeat for 25,000 bank records and the file gets huge, with 25,000 gaps that gradually increase in size.

If that’s the case, something clever needs to happen during the conversion to keep things compact. There are a few options, but we’ll worry about that only if it’s needed.

Luckily, the gap-finding system rarely fails in normal daily use. Records come in all sizes, so most of them will find a gap that’s snug. There always will be some wasted space within the file, but not much.

When our staff wrote the database code back in 2016-2018, we also added reports to help debug what’s inside the file. Right now, we’re tweaking those to be more useful and accessible. It will help track down whatever it is that makes files too big. Also any future problems.

Dennis Kolva
Programming Director
TurtleSoft.com

 

 

Data Conversions & Corruption (July 2)

Thanks to rain and hot weather, our staff has fixed many problems in breakdown tables and elsewhere. It’s time to test on our own business again. Except, we can’t. Converting TurtleSoft’s company file to the new format crashes part way through.

It’s something that has happened before. In the past we fixed things by tweaking how often changes are saved to disk. Sadly, that wasn’t enough, this time. All it did was change where the crash occurs.

Conversion is a complex process. First it reads from the Goldenseal file, using NeoAccess database code. Then it writes to the new file, using the new database setup. Some data gets tweaked along the way. For example, breakdowns change from two types to one. Bank accounts and transactions change from seven types to three. Other small fixes and improvements happen.

Once all data is moved over, there’s a second round of tweaks. Breakdowns and banking records may have new ID numbers, so anything that links to them needs to change. That process happens entirely within the new code, and the crash happens there. The Sample file and other test files always sail through, but not our data.

The most likely culprit was memory use. Our file has 20+ years of data, so it’s big. Many things need to stay in RAM during the conversion.  However, Activity Monitor only shows 65 megs max, which is tiny compared to some other apps. It stays about the same, so no big memory leaks.

We tried saving changes much more frequently. That made the conversion run very slowly, but it went to completion. Yippee! Sadly, when we opened the file, it gave warnings for bad data and crashed in an entirely different place.

That is very bad news. Corrupted data usually happens when data writes onto the wrong place in RAM or on disk, and zaps something else. Corruption is hard to diagnose, because errors show up long after the bad write that caused them.

We stepped through the code many times, and found a few suspects: things that might screw up saves in rare cases. Fixing those made the software generally more reliable, but it didn’t stop the crashes or bad data.

Early versions of Goldenseal had corruption bugs. To fix them, we first added tons of sanity-checking code, to give error messages for anything suspicious. We also added menu commands to work with raw data inside the file. Verify File is the most useful, but there are others in the View–Security menu. Those helped track down each bug, one by one. The last happened if text was too long in one of the Preferences fields, caught in 2005.

The new accounting software still has the same sanity-checking code, but not the diagnostic tools. Looks like we need to hook them up again, to see what’s going on inside. It may be something funky with our data, or something rare that we just happen to hit sometimes.

If any Goldenseal users want to be data guinea pigs, send us a compressed copy of your company file. We’ll check how well it survives the conversion process. Maybe having more examples will narrow down the cause of this problem. Eventually we’ll stumble upon it, but sooner is better.

Dennis Kolva
Programming Director
TurtleSoft.com

 

 

Exponentials & Climate (June 20)

When Covid-19 first appeared, I wrote about exponential growth. It’s why pandemics happen. Conditions change faster than anyone expects, so they get out of control.

All exponential growth tapers off, eventually. Sometimes it plateaus, sometimes it goes down to small or zero. Sometimes there are hills and valleys. Covid is doing that now.

TurtleSoft also began exponentially. Sales of our estimating software tripled annually over the first few years. Then it flattened for a few years, then shrank by 50% a couple times after Apple Computer almost died. Goldenseal created another spurt of exponential up, followed by a second slow ebb.

When this blog started, we expected to quickly update our accounting software to 64-bit, and see a third spurt of exponential growth. Maybe even bigger than the first two. After ten years of struggle, now we just want to finally finish the project. Then see whatever happens.

Meanwhile, the series of hottest-ever months continues. Last winter it was bad news for TurtleSoft users: great weather for outdoor work, so the usual spurt of stuck-indoors programming didn’t happen. Now it’s good news. AC + Computer > Sweat + Heat Stroke + Garden.

For me, the scariest part of climate change is the chance it also goes exponential. That happens when there’s positive feedback. For example, extra heat causes wildfires, vegetation loss and melting of permafrost, which increases CO2 and methane and heat. Repeat and multiply.

From ice cores and sediments, there’s evidence of large, rapid climate changes in the past: some in just a single decade. Life will be very interesting if we’re headed into one of those now.

Dennis Kolva
Programming Director
TurtleSoft.com