So to be a little more detailed from my last post about how upgrading Indy affects the protocol plugins for PopTrayU…
PopTray, historically, only included POP3 as a “core” protocol. Anything else (Pop3 with SSL, Pop3 with APOP, IMAP, IMAP with SSL, etc) had to be configured as a seperate plugin. There’s a DLL interface that the plugin has to implement (though many of the methods are optional), which can be implemented in either Delphi or C++.
PopTray had a set of “example” plugins that included the most common additional protocol needs (those mentioned above), implemented in Delphi.
The POP3 SSL plugin for PopTray (a seperate DLL) directly extended pop3.pas (one of the source files for the core executable). That class has a reference to an Indy callback object that updates the a progress meteron the UI. In Indy 10, one of the parameters was changed from Int to Int64 and changed whether it was const. So the older DLL + the newer EXE (or conversely new DLL + older EXE) just don’t quite mix well and initial testing was showing “random” crashes and such undesirable behavior.
Well, if we’re going to have to break the existing plugins for SSL and IMAP, now would be the time to make any other changes/additions to the plugin interface, so we don’t have too many different versions of the plugin interface, wouldn’t it?
One change I’ve been contemplating for some time is including IMAP and SSL as “core” features rather than plugins. It’s becoming increasingly common for mail providers (Gmail, for example) to require SSL to even get POP access to an email account.
Another change I’d been contamplating is offering an “advanced connection options” feature. Almost every email client (even the one on my phone) has a menu or dialog where you can tinker with some various cryptic sounding settings beyond “SSL/TLS enabled”, like STARTTLS, Explicit TLS, SASL, APOP, etc. In PopTray, you had to have a lengthy list of protocols to have a seperate protocol for every permutation of feature combinations you needed, and not only does that lead to having to make the protocol support only the least common denominator of desirable settings, it made configuring options on a per account basis difficult. The plugins were set up so there was a configuration page for the plugin itself (which to be honest I’ve never seen actually used for more than an “about” dialog), but no way to configure settings differently between two different accounts that both require SSL connections, even if I put the plugin settings dialog to better use.
So I spent a bit of time researching what all these crazy-sounding advanced settings acronyms mean that other mail clients use, and then tried to create a list of which ones would be useful to support. One in particular that I was initially undecided about was APOP. Even the iPhone’s default mail app doesn’t have APOP support. In the days of SSL, does anyone really use APOP instead (APOP just uses an MD5 hash to obscure the password on a plain-text connection, which is obviously better than sending any passwords in plaintext over public wifi where there might be hackers looking for your passwords, but far less secure than SSL. But some research seemed to indicate that there is at least one major ISP (Earthlink) that, as best I can tell, flat out does not support SSL even in this day and age, but does support APOP. Well, for the sake of anyone who unfortunate enough to have such an account, I’d rather not deprecate increased security that was already available in previous versions of PopTray and PopTrayU.
And then after deciding which advanced options I’d like to support, the more difficult decision becomes how to group and arrange and label them on the UI. Should I label a checkbox “STARTTLS” or “Explicit TLS” or put slashes between alternate version of the name? They mean the same thing, but different apps label it differently. That particular option opens the connection over the standard insecure port (110 for POP) and then sends the server a command to “explicitly” enter encrypted connection mode, rather than requiring you to use a different port if you want a secure connection. Apparently, there’s some debate about which way is the better way to do things, but if you want to be flexible and accomodate the widest assortment of mail server configurations, ideally you’d support both options. and just to make things confusing, there’s also a mode called Implicit TLS. That means that you still use a TLS secure connection, but the connection doesn’t make an insecure “handshake” first, you connect over the secure port and it’s just assumed you’re going to be in secure mode because you connected on the secure port.
Anyway, I don’t want to bore you with all the details of every single email connection option I ended up learning about and what all those options mean exactly…for most users, they just want to check the box their ISP or geek friend/adviser told them to use, and not know a thing about what it means ;-)
But it suffices to say, there’s no one standard UI for setting all those advanced settings. They have different labels and groupings depending on the app and which features it supports. So one of the hardest aspects of addding all these extra advanced connection options is deciding on a usable interface for setting the options, not to mention how the plugins can interact with the options available to enable or disable options that protocol doesn’t support. So I’m taking my time with this and doing a lot of testing, and well, some of this secure stuff is tricky, and I’m still working on some of the kinks that happen if you mix and match combinations of features that just aren’t compatible and shouldn’t be available at the same time.
One of the features in particular that I’m excited to add support for is SASL authentication. SASL wasn’t even invented until 2006, so obviously, it was after PopTray’s time, and still new enough that everyone doesn’t automatically expect SASL support, let alone know what it does. The layman’s version is you don’t need to know a thing about how it works, you just need to know that that SASL + SSL can be more secure than SSL alone, so you should absolutely be using it if it’s an option available. Internally, there’s a whole bunch of different “authentication mechanisms” the app can choose from, and it will send your password using the most secure one of those mechanisms that the server supports. So it’s going to be one of those “enabled by default” kind of features that will make newer version more secure without having to be an IT professional to know what settings to pick.
The one thing I’m probably not going to do is include OpenSSL DLL’s in the base installer for PopTrayU, simply because, it’s a liability to bundle SSL abilities. The US and many other countries have all kinds of weird rules about importing and exporting software that include “strong” encryption. So some people may want the “insecure only” version, to avoid the whole issue of whether it’s legal to travel to xyz country with this software or it’s installer loaded on their PC.
Overall, I am attempting to minimizing changes to the plugin interface, and add the new features as optional methods, in hopes of breaking as few existing plugins as possible. There are poptray plugins for various webmail interfaces that I have no interest in supporting or developing, but if they continue to work as-is, I’d rather leave things that way.
Latest on my PopTrayU development
So in a slight twist of irony since my last post about working on PopTrayU, after all the trouble of getting Indy 9 set up on my current machine, I’ve decided to port PopTrayU from Indy 9 to Indy 10.
For those of you unfamiliar with Indy (which is probably pretty much everyone who is not an experienced Delphi developer), Indy is an open source networking library that is available both for .NET and Delphi platforms. It does most of the heavy lifting as far as the technical implementation of connecting to a POP3 server, downloading and parsing the email headers (though I had to override a few little pieces of that to workaround Delphi 7 international character support issues) and that sort of stuff.
Version 9 is, well, a legacy version at this point. You can’t escape being asked “why are you still using Indy 9 anyhow?” if you ask a question pertaining to it on a programming forum. Version 10 has a lot of new features, and performance improvements and so forth. But, they made a lot of changes to the interfaces, so it’s not like you can just download version 10, and your code for version 9 will just work without changes.
I’d already done the vast majority of the porting to version 10 legwork when I was working on my Lazarus port, so there were only a few holes (“todos”) here and there that needed to be fixed. It was probably more painful to actually do enough research/reading to even figure out how to get versions 9 and 10 “somewhat” concurrently installed in delphi (to the degree that’s possible), than it was to makde PopTrayU built on Indy 10 itself work.
But I’ve been holding off on releasing these changes as the next version, because aside from wanting to make sure it’s stable and not buggy, it introduces the first change to the plugin interface since branching from PopTray that will make certain older plugins no longer compatible. I’ll write more about those changes in my next post
How to use the Basic Primitives Org Chart Tool
As I mentioned in my previous post, Basic Primitives is a powerful tool for making Org Charts for your website. I thought it would be useful to document a little bit how to use the Basic Primitives Org Chart tool, because the examples weren’t quite the tutorial I was hoping to find.
So, starting with a simple example of something I needed for my project, I wanted to change the chart’s orientation from top to bottom to left to right. I started by searching the reference guide for orientation. I found it was a part of the primitives.orgdiagram.Config class.
So far, not much on how to use it though. Clicking on orientation type takes you to a more detailed explanation:
Disappointingly, that’s a pretty terse explanation. Ideally, it would explain all the different choices, where to set this property, and have a code snippet to show you the synax. Some defaults in this document are linked to their choices. This one is not.
Searching the page for OrientationType does yield promising results for what the possible values are at least:
The best looking match is:
There’s also a close sounding match “primitives.
So, now, how to use the information we’ve found from the reference guide?
If you go to the “How to Use” section, there’s a list of examples. You could really start with any of them, but I’ll pick the “First organizational chart”. On the plus sides, these examples are all editable, so you can experiment. On the down side, if you make a syntax mistake, the whole chart disappears and it doesn’t tell you where your mistake is.
So the important parts here are where the global options variable is initialized, and where they use it.
Initialization:
var options = new primitives.orgdiagram.Config();
this is given in the example. You’ll notice the variable options is of the type primitives.orgdiagram.Config, like we saw in the reference guide above. So this variable is the one you need to use to change any *global* configuration item that is in that same section of the reference guide.
Now skip down near the end of the example:
options.rootItem = rootItem;
options.hasSelectorCheckbox = primitives.common.Enabled.True;
These two lines change a couple of the global configuration options. So, to add another global option, you just need to add another line of code before or after these two lines, adding your new option.
Go back to the beginning of the reference guide, jump to the section on primatives.orgdiagram.config again, everything under the word “properties” here is a property of options that can be set:
The correct value to use is a little trickier in this particular case. The documentation showed an example of the default being primitives.orgdiagram.OrientationType.Top, however, the documentation shows the possible values for Orientation under a heading called primitives.common.OrientationType. Notice anything different about the package naming? Yeah, that’s a little confusing, and I ended up with a blank diagram a couple times because of this.
Looking at the source code for the enumeration, it appears to be a simple documentation error, that the comment was not updated when the package name was changed for whatever reasons. Here’s the definition in the source code:
/*
Enum: primitives.common.OrientationType
Defines diagram orientation type.
Top - Vertical orientation having root item at the top.
Bottom - Vertical orientation having root item at the bottom.
Left - Horizontal orientation having root item on the left.
Right - Horizontal orientation having root item on the right.
*/
primitives.orgdiagram.OrientationType =
{
Top: 0,
Bottom: 1,
Left: 2,
Right: 3
};
Yep, I’m sure you’ve all seen code like that before. Anyway, just use OrientationType defined in orgdiagram, because that’s what the code says, and what works. And if you find some other property you want to set, and it’s not working, check the package name in the source code to make sure it’s right.
So our working line of code to change the orientation becomes:
options.orientationType = primitives.orgdiagram.OrientationType.Left;
And you just have to put that with the other global options (technically, other places are ok too, but to keep things simple, leave all the options in one place.
If you go back to the orgdiagram.global properties list at the beginning of the documenation,
(there’s more than fit in this screenshot), any of these are set following the same formula. Orientation Type is not the only enumeration incorrectly documented. graphicsType isn’t defined in the documenation at all. Just search the source code for the possible enumeration values. Theres no apparent consistency about whether things are under common or orgdiagam, so just look up what’s in which spot, unless you start to notice a pattern I missed.
options.graphicsType = primitives.common.GraphicsType.Canvas;
options.pageFitMode = primitives.orgdiagram.PageFitMode.PageHeight;
and so forth.
A couple of other options I ended up changing for my diagram included:
options.connectorType = primitives.orgdiagram.ConnectorType.Squared;
options.hasSelectorCheckbox = primitives.common.Enabled.False;
options.minimalVisibility = primitives.orgdiagram.Visibility.Normal;
As a footnote, changing the template around, because we didn’t need pictures next to the roles (since we only showed names for board members on our chart) was a bit more complex and requires structural changes to the javascript. I wouldn’t recommend it for javascript/jquery beginners unless the demo one is really close to what you need. But if you’re a seasoned user of javascript, it’s quite doable.
In Search of An Org Chart
Another project I’ve been working on recently was an online org chart to show the leadership structure for my mom’s club. One of the leaders sent me a powerpoint version of the chart and said “we want this on the website”.
I was anticipating this document would change over time, as new roles are created or subdivided and old roles are retired, so I wanted to make the update process straightforward and quick, so I wasn’t too keen on using an image for the chart.
My first thought was to use Google Orgchart, as it’s super-easy to set up, and I could have the whole thing done in five minutes or so, and there initially appeared to be a section on customizations. But then when I started digging into the options, it turns out there’s no option to change the orientation to go left to right instead of top to bottom, which ended up being a deal-breaker. To illustrate why, here’s a demo of what Google Orgchart’s output looks like with a shallow but wide tree:
In reality, there are 2-5 coordinators under each director role, and a few of those have as many as 3 assisting roles beneath that, so the actual chart would have been much wider. I just wanted to show you how having horizontal labels on a wide chart without putting children far enough down to scrunch the previous level results in a hard to read chart. For a deep hierarchy with few nodes, Google Orgchart seems like a great simple tool, but for a shallow hierarchy with many nodes per level, it just wasn’t the right tool.
So I started looking into alternatives to Google Orgchart. There was absolutely nothing with the same level of simplicity. At one point I even looked into how hard would it be to just export the powerpoint chart to HTML. Oh, but it turns out Office took “export to html” out of the features list in Office 2010, so I would have had to reinstall Office 2003, or experiment with a rather complex workaround, just to evaluate whether that would be a feasible choice.
In the end I kept coming back to suggestions that Basic Primitives looked like the right tool for the job. It’s demos clearly showed it was capable of a horizontal layout, but unfortunately, their “how to use” section completely neglected to give a demo on how to change that option. The tool provides lengthy documentation on all the properties you could possibly set, however, the “reference guide” looked like a machine-generated documentation, and I felt like the “how to” section could have been a little more helpful at explaining how to use the different customization options, rather than leaving that as an exercise to the newbie who has no idea how to use this tool.
It took a a bit of time studying the examples they did provide, and trying to match up how they changed this and that to where in the reference guide that item was documented to figure out how to decipher the reference guide. But in the end, I was successful in creating the org chart I needed using this tool.
Here’s an image of what the layout ended up looking like using the basic primitives tool with custom (simplified) layouts for each role. The colors are designed to coordinate with the site
.
In my next post I’ll spell out a little more about how to use Basic Primitives because it’s a great tool, but the documentation isn’t very newbie friendly.
Installing Indy9 from Source Code
I’m finally working on getting Delphi 7 set up on my Win7 x64 machine. I think it’s been over a year since I last did this on my Vista machine or my Win7 x32 netbook, so my mind totally went blank trying to remember how to install the lastest version of Indy 9.
I already had pulled the code from Indy’s SVN server and been able to transfer that from the old machine, so I was one step ahead there.
I pulled up the “ManualInstall.txt” document in the Indy source directory and tried to follow the directions, only to find it didn’t work. At first it looked like it was a permissions issue, I needed to be running a batch file called fulld7.bat from a command line running on elevated privileges to get the script to run without errors, however, even after sorting all that out, when you get to the step of Installing the *.bpl, even after you’ve correctly remembered which one is the right menu option install such, it just doesn’t work. Complains about a missing file (that just doesn’t seem to exist in the provided repository or compiled files directory).
Well, after much fiddling and trying to figure it out on my own, since the internet had no solutions, it turns out, those directions probably are obsolete, and doing it the way that actually *worked* was much easier…just not obvious if you haven’t been working with Delphi recently.
In the Indy 9 directory from the SVN, there’s a .DPK package file for each delphi version. So, since I’m using Delphi 7, double click Indy70.DPK, it opens in Delphi with a package window visible displaying a list of all the files. At this point you’re two clicks away from a working Indy install. Click “Compile” and then “Install” on the package window, and dismiss the dialogs that confirm those steps work, and suddenly Indy is on the component toolbar without even restarting Delphi.
So there you have it. I’m thinking documenting the steps on installing this that work will be helpful, because by the next time I get around to trying to install Indy on a new machine, I almost certainly will have forgotten how you install it, since you do it once and never touch it again, and odds are good that it will need re-installing after a hiatus where I haven’t touched Delphi in a while period and can’t remember off the top of my head the difference between installing a component and installing a package, since that’s very delphi-specific terminology.
Pattern Block Designer
I’ve started a new project recently. A pattern block designer written in Java 7. Yes, in spite of all the other projects I have yet to start
.
My mom gave my son a box of mis-matched pattern blocks that were left over from her classroom. Anyway, he’s not really old enough to “get” making designs on his own yet, but I figured he loves puzzles and matching shapes and colors isn’t too hard for him, so I started looking for some designs online of concrete objects drawn in pattern blocks, like a train, for example, since he’s really into trains.
But while the first site I found a bunch of animal designs had nice high quality printable PDFs, the second site (which had some cool designs like rockets and trains) had a word document with upscaled screenshots from a java applet. It was quite low resolution (like 32 pixels per inch instead of 300 pixels per inch…and no amount of anti-aliasing is going to make up for that), and the geometry of two of the shapes was just a little bit off for the sake of convenience. It just didn’t look very good printed. And there weren’t a lot of other free or instant-download alternatives.
So I decided to redraw a couple of those designs in Corel Draw, and set out creating isometric guidelines and measuring all the real pattern blocks with a ruler and compass to make sure I had the scale correct and everything before I created shape templates. And while the finished product didn’t look bad, I kept getting frustrated with how much simpler it “ought to be” to do this, mentally designing how it ought to work.
So that’s pretty much my inspiration for deciding to start this project. And just for fun, here’s one of my corel draw animal designs as a low quality gif image…and you can see a couple of my points of frustration trying to get the geometry to line up perfectly…even with the “snap” options in corel draw.
Computer Woes
My old computer was finally giving way, starting to have blue screens at least once a week and some other erratic issues. That’s never a good sign. And when you’re talking about a 5 year old laptop that’s already had the motherboard replaced once…well, it was just time to replace, before it dies a catastrophic death.
At first I was thinking I’d just get another laptop, but when I started looking at computers, a relatively new form-factor caught my eye–the all in one flat-panel touch-screen computers. Just think of how much desk space this would free up! And a full HD screen? That doesn’t require an external monitor sitting next to it? And it’s not like I ever take that computer with me when I travel, since the netbook is a lot more portable.
I was kind of procrastinating at making a decision about the new computer, until I got a look at the new Windows 8, and decided I really just wasn’t ready to make the leap toward the experiment of their new UI, which by all accounts is great for touch-screen tablets but “may be” a step backward for desktop users, accustomed to having a start button and doing heavy multi-tasking. Two days later, I’d ordered a clearance windows-7 machine online. I would have bought in person, but I really wanted an I5 processor (that seems to be the sweet spot of performance vs price at the moment) and not an AMD processor, and definitely not an intel pentium (they still make those?!?!), and that pretty much eliminated everything I could get locally.
A week later it arrived, and luckily turned out to be as fantastic as I expected, and fit on my desk with less than an inch to spare between the monitor and the hutch on my desk. Not that there aren’t a few things I would have done differently if I were designing the computer, but nothing I can’t live with.
Around the same time as I was trying to get everything installed on the new computer, I discovered a nasty click-fraud rootkit virus on the netbook that I primarily use for web-surfing. Long story short, even after running bunch of different virus scanners and malware removers and “fixing” multiple viruses, I couldn’t get the suspicious network activity to cease, so I had to order restore disks from Toshiba and reformat. Too bad I never got around to making the restore disks *before* it was infected. I suppose I’ll have to start doing a better job of actually installing all the windows security updates and browser updates, even if the lastest firefox is giving me nothing but trouble and crashes a lot
.
So, between all that and the holidays, and working on the annual photo calendars, I haven’t had as much time to work on my usual “geek projects” as I’d like. That and every time I go to work on a particular project I find another program or two I still need to install for that task, or some important registry key or password or file that got missed when I was migrating files to the new computer that I have to track down, which can just be time consuming. But things are coming together and I’m putting the computer to good use.
Oh, and there’s a hope I might actually be able to install the free version of Visual Studio on the new machine, since the issues I was having on the old computer with it being unable to install a certain service pack required for Visual Studio is now moot.
Disabling Auto-Check
I recently finished implementing a new feature for PopTrayU, conditionally disabling automatic checking for an email account based on the time of day. This feature already existed on a global level: you could disable checking for all accounts, so that your computer would not check for email while you’re sleeping or awaken you with a loud “you have new email” notification sound. But some users, particularly users who work from home and use the same computer for both work and pleasure, were making a feature request that they’d like to be able to turn off notifications for their work email outside of normal working hours.
The part of the implementation that was most difficult, of course, was the requirements analysis and the detailed design. On the surface, this feature seemed pretty straight-forward, but as I started to dive into actually implementing it, a lot of nuances come up where it isn’t exactly clear how this feature should work, and the design has to be hashed out in more detail, and the requirements clarified.
Each account has a status icon indicating whether the account is disabled or has new email or no new email. (For the sake of clarify, lets call this new per-account no-auto-check feature “sleeping”.) Should the visual appearance of an account that is “sleeping” appear like a normal account or a disabled account? Something else? What should the status-bar for the account say when an auto-check happens, but a single account is skipped because of the time? If the user presses “Check All Accounts” manually, should that skip or include accounts that are sleeping? What if they press “Check” for a single “sleeping” account?
Once I nailed down the design, implementation was pretty simple. Because the feature existed on a global level, most of the implementation was quite similar to the logic and UI of how it was done for the global level.
As far as how I decided to resolve some of those issues:
An account that is disabled is represented by an envelope with a red minus symbol on it, like this:
Previously, this was the only reason a specific account would be skipped when an auto-check occurred. Now we have two reasons an account might be skipped. It could, for some users, be handy to be able to differentiate the reason the account is not automatically checking, especially should they be troubleshooting settings gone awry. I experimented with making a new symbol that resembled sleeping, like something with zzz’s or a moon, but given the limited amount of space in a 16×16 image, trying to make an image that is clear and recognizable is difficult, so I decided to use the same symbol as a disabled account, but use a contrastingly different color to differentiate the different status.
As far as when to check/not-check:
- Automatic timer-interval checking, pretty straightforward, sleeping accounts should be skipped.
- Manually pressing the “check all” button: more ambiguous, it’s not really an ”auto-check”, but it behaves a lot like one. In the end I decided “check all” should replicate the behavior of auto-check, but on-demand, so accounts that are not in a state allowing automatic checking should be excluded, so it should behave like a disabled account.
- Manually pressing the “Check” (this account) button: this one seemed pretty straightforward, even a disabled account will check when pressing this button, so a sleeping account should definitely check in this case.
Upgrading from Indy9 to Indy10
Translating the source code to Indy10 only took about an hour. It would be nice if there were a more comprehensive upgrade guide, rather than having to google one piece after another to figure things out, and pulling up grep to search the source code to figure out what include is needed now.
Here’s a summary of a few of the changes I encountered needing (hope this helps someone save some time!)
- POP3.MaxLineLength becomes Pop.IOHandler.MaxLineLength (watch out for IOHandler being null though)
- wsOK moved, add uses IdIMap4
- Pop3.Connect(Timeout) breaks into two commands, Pop3.ConnectTimeout := TimeOut; Pop3.Connect()
- StoredPathName not found. Change TIdAttachment to TIdAttachmentFile
- POP.Capture(Dest); moved to POP.IOHandler.Capture(Dest);
- Signatures of OnWork and OnProcessWork changed. Change const Integer param to Int64 (not const)
- EIDSocketError not found. Import/uses IdStack
- CommaSeperatedToStringList not found. Add import/uses IdGlobalProtocols
- TIdText not found. Add import IdText
http://conferences.embarcadero.com/article/32160
http://www.indyproject.org/docsite/html/MigratingIndy10.html
http://www.indyproject.org/docsite/html/ChangesObjectHierarchy.html
But when all was said and done, that didn’t fix my disconnect problem. Looking a little more into why it was crashing disconnecting, I changed closing the connection from being conditional on the correct response to unconditional, and instantly, things start working and I have email showing up in my client! Yay.
PopTrayU to Lazarus/Free Pascal Porting Update
Well, I’ve gotten a lot of the “cosmetic” stuff fixed. Here are updated screenshots, that you can compare to the ones my last update about this project:
First, here’s the options screen.
You’ll notice it looks pretty much about right. I had to use a third-party time control (ZVDateTimeControls) to get the time picker working. Lazarus doesn’t have an equivalent of TDateTimePicker. They have a TDateEdit, but that only does calendar and not time only. But the third party one seems to work fine, though I’m not in love with the arrows on it, I’d rather see it using the native windows picker control under the hood, since cross-platform compatibility is not a primary concern of mine at the moment. But at least it’s functional for now.
Here’s the main window at the moment:
You’ll notice the main screen now looks “almost” like the real thing now. The toolbar is there, but the labels are in the wrong spot. I stumbled almost on accident onto the solution for how you do the labels on the right. Apparently you have to use TSpeedButton(s) on a TBevel instead of using a TToolbar to get labels on the right. Sounds pretty doable, but is lower priority than some of the other issues I’m dealing with.
Those tabs also don’t appear totally “right”. You’ll notice there’s some weirdness about the borders for them. The tabs are a TTabControl because they don’t have individual content, it’s really just an array of accounts it’s representing. But there’s a key difference in Lazarus from Delphi that the TTabControl is not designed to have child components, so it’s resizing it wrong to make room for the components that should be nested on the tab. This might actually be kind of involved to fix. One guy supposedly submitted a patch at one time that made it work more like Delphi, but it got rejected because it didn’t work “right” for all the different platforms Lazarus supports. So looks like I could try to track down that patch and make it into a third party control, or I could change the TTabControl to a TTabSheet, and replicate the buttons onto every tab, but that would lead to a lot more UI overhead. But either way, it’s not worth fixing unless I find a way to fix the blocking issue that could be a showstopper.
Right now the blocker issue is Indy 9. In 2005, Marco van de Voort ported Indy9 to Free Pascal, at least for 32 bit architecture, not 64 bit. But then he decided to upgrade to Indy10 so it wasn’t maintained. So, showstopper issue, Indy9 isn’t working right. I’m focusing on the “test account” button right now since that’s about the simplest network-operation the app does. Connect to the Pop3 server, login, and disconnect. Login is actually working. The problem is disconnecting. It’s reading garbage instead of “+OK” for the disconnect message, so it fails to disconnect and throws an exception that causes other problems, like skipping actually closing the connection. The problem is, using Wireshark to sniff what’s actually going on in the network, the server is actually sending the correct response back. But what PopTrayU is seeing when I step through the debugger is half of the account’s domain name, ”bear.net” Stepping through the routines where it moves pointers around to find the response, it looks like it’s reading the wrong place in memory, it’s skipping right over where it should be reading, and reading from some random spot a little bit farther out that presumably contains memory that was previously used for something else. Tricky right? The code doing this is totally obscure, and has very few comments, so it might take a while to understand it well enough to figure out *why* it’s reading the wrong address when it goes to disconnect. The warnings in Lazarus that it’s doing Pointer to Integer conversions could be a hint though. Theoretically that shouldn’t mess it up on 32 bit, but you never know, seems to be doing some bad pointer math somewhere.
Interestingly, poking through the Indy10 codebase, they appear to have reworked the whole “managed buffer” that’s giving me issues and eliminated this weird pointer math. And Indy10 is officially supported in Free Pascal, so I may have to bite the bullet and upgrade. Apparently there were some non-trivial issues when Renier tried to port to Indy10 once long ago, but perhaps they would be less nasty to resolve than buffer overrun issues.
Oh, and unrelated to all of that, I also have the tray icon partly working now. The right click menu is working, but changing the icon images is not. The rules and about screens are also on the todo list if I can resolve blocker issues. The about screen lost all the strings in the tables, because they’re encoded in binary in Delphi, so I have to retype them. And the rules stuff was using some components that have to be manually ported/fixed.

