Goldenseal Pro Progress- Lists #2 (Jun 23)

When Apple launched OS X in 2001, they provided two different ways for developers to write apps.  One was called Carbon. It was an extended version of OS 9, accessed with the C++ programming language. The other was Cocoa. It was first developed for the Next computer, using a different language (Objective-C).  Software developers could use parts from both, but usually it made more sense to stick with one or the other.

TurtleSoft released Goldenseal accounting software for OS 9 in late 2000. It only took a few months to rewrite it so it would run on OS X, using Carbon. When Apple switched to Intel chips, it took another few months to rewrite the Goldenseal code for that.

Apple plans to release OS 10.14 (Mohave) this coming Fall. It will be the last version that supports 32-bit code. Unfortunately, Apple did not update Carbon from 32-bit to 64-bit, and does not plan to. Many Macintosh apps will need to either rewrite to Cocoa, or fade away after Fall 2019.

TurtleSoft started work on the conversion to Cocoa in September 2016. It soon became clear that this update would take more than a few months. All of the interface code needs to be rewritten completely in a new programming language. The only good news is that is has also been a chance to update and improve the way Goldenseal runs.

In Fall 2016, one of the first things we worked on was the list interface. It’s what you see when you edit categories, sales tax rates, billing rates, and other minor setup details. It’s relatively simple, so it was a good place to start.

The list window has a table that shows a list of list items. You can then select one, and edit it in a separate window. There are also buttons to add and delete items.

Back then, our staff was brand-new to Cocoa programming. We were working through tutorials and programming books to learn Objective-C and Cocoa. For lists, we adapted one of the sample projects from The Big Nerd Ranch. Unfortunately, the official Cocoa way to handle tables is complex. Miss one step and it won’t work. We ended up making a 20-step checklist to use for tables, since it was so easy to miss something.

Since then, we have built a half-dozen other types of tables. The official system ended up being just too complicated. We abandoned it, and wrote them more simply. It’s more like 4 or 5 steps now, instead of 20.

Last week we started to fix a few flaws in the list interface. Revisiting the original system was a return to nightmare. Our staff soon gave up, and rewrote the list tables completely. Now, they are similar to our other tables. They still look great, but are much easier to maintain. Still a few things to fiddle with, but we will soon be moving on to other interface details.

Dennis Kolva
Programming Director

Goldenseal Pro Progress- Lists (Jun 13)

Our new Goldenseal Pro accounting software is moving into the home stretch. Everything big is done, but there are still plenty of medium and small things to finish.

Right now, our staff is working on lists. Goldenseal includes about 70 of them. They handle all sorts of little details: job cost categories, payroll tax tables, sales tax rates, etc.

In general, lists are simpler than regular business records. Some are  just a name, and the others have only a few fields. Because of their simplicity, lists were the first things we worked on, back in 2016 when we first started the conversion to Cocoa (on Macintosh) and MFC (on Windows). Since then, the rest of the software interface has gotten ahead of the lists, so it’s time to catch up.

The current version of Goldenseal has lists scattered all over the place. Most are in submenus, under 12 different menu commands. It’s not always easy to find them. Originally, we planned to just duplicate the interface in our current accounting and estimating software. However, both Windows and Mac are moving away from top-bar menus, and putting controls inside the window instead. So, Goldenseal Pro still does the same stuff, but in just one window rather than many.

Goldenseal Pro already uses an outline view for navigation (similar to how you can organize your desktop files). With it, you can find accounts and business transactions more easily. We just put the lists there too. Now they are located near the business transactions that use them.

Back in 2016, the database code was still primitive. The list interface we wrote back then could show list records, but it didn’t make new ones, or save changes. Now that works, also. All that’s left are a few list quirks that need special treatment.

Dennis Kolva
Programming Director



Goldenseal Pro Progress (June 1)

There is a decades-old programmer’s joke that goes:

There are two hard things in computer programming: cache invalidation, naming things, and off-by-one errors.

This week the database code for our new accounting software finally started to work properly for very large files. It took almost a month, or twice as long as expected. Along the way we faced both of those three types of problems.

A cache is data in temporary storage, so it’s quicker to access.  Invalidation is just programmer talk for keeping the cache synchronized with the original data. Basically, the cache determines how long we keep accounting records stored in RAM, and when we save back to disk.

Our staff wrote the caching system for Goldenseal Pro almost 2 years ago. It worked great with small files. Then we started testing with our own company file, which is big enough to require six ‘sector managers’ to manage record locations. Anything put into the extras would eventually give errors. After dozens of debugger runs, it narrowed down to the cache system. Changes weren’t being saved.

Meanwhile, naming things is a chronic issue for all computer programmers. Poor naming is the main reason why code becomes impossible-to-understand ‘black boxes’. Good code tells a story, and explains exactly what it’s doing at every step. Getting it that way takes time and effort.

It wasn’t obvious why the cache system wasn’t saving sectors. Stepping through it, everything seemed OK. After a couple frustrating days of debugging, our staff rewrote the whole thing.  Same basic approach and almost identical code, but with names that made more sense.  Renaming everything was a good way to see how the cache interacted with other parts of the software. Finally, it became clear that sectors were indexed differently from everything else. After changing one line of code, it worked fine again. One minute to fix it, and three days to find it.

Then there are the off by one errors, sometimes called ‘off by on’. For anything involving numbers, it’s easy to get close but no cigar. It doesn’t help that there are math quirks. For example, the end of a record is at start+length-1, not start+length. It’s easy to forget that. Even worse, libraries written by true programmer nerds start counting at zero, while those written by mortals start at one. NeoAccess considered the file end to be the last byte of data, while C++ libraries put ‘end of file’ at one after the last byte. Etcetera.

Earlier this week, our TurtleSoft file was converting OK, but the file size was over 43 gigabytes. Obviously, a gap-finding problem. It took most of a day to track it down to code that called ResetToEnd on a list, thinking that it selected the last item. Nope, it was one past the last item. That name makes sense if you want to add something at the end, but not if you want to access the item at the end. Off by one.

Adding a ResetToLastItem function solved the problem, and file size dropped instantly by 800x.

Anyhow, we’re back to interface programming.

Dennis Kolva
Programming Director