PopTrayU Progress: Unread Message Filtering

There was a user requested feature for PopTrayU to add filtering based on read/unread status. This is something that is only technically feasible for IMAP since POP servers don’t store read/unread status. Anyway, I started working on implementing this feature, and decided that if you are only showing unread messages, you might need a mechanism to change the read/unread status–especially if previewing automatically marks the message read on the server.

So whip up some code for this…go to test it…and…nothing. No change to the message status.  Turn on some logging of server communication, and something looks off about the command set to the server…and the server response? Yeah, pretty sure that’s not what’s supposed to happen either.

Sent: C4 UID STORE 1264  (\Seen)<EOL>
Recv: C4 BAD Error in IMAP command UID STORE: Invalid STORE modifiers.<EOL>

This may not be so apparent in a non-monospaced font, but there’s a double space between 1264 and (\Seen) like a token got left out. But not being intimately aquainted with every nuance of the IMAP spec, I had to lookup the section on setting flags in the IMAP RFC for IMAP to be sure I even knew what the command was supposed to look like. It’s supposed to have a +FLAGS.SILENT in that missing token.

So, long story short, I had to update my copy of Indy from SVN to make sure the bug still existed on top of trunk, then I had to debug a variable type that disappeared in the new version of indy (it got replaced with something else), after retesting and trying a couple variants to see if it only exhibited this behavior when certain parameters were used, I filed a bug report to let the Indy team know about this issue, and left my code using a workaround with the better code commented out in the meantime. Remy and the Indy team are pretty responsive to fixing actual bugs, especially ones that are probably pretty trivial to fix like this (now incredibly useful but difficult to implement enhancements on the other hand, like IMAP IDLE I’m not about to hold my breath over…).

Aside from this particular sub-feature, there’s still quite a bit that needs to be done to make “unread only” mode happen. Like, the main window needs a whole new paradigm of basing the read/unread status off of the server for IMAP and off internal tracking for POP. And the message list needs to be using UIDs instead of relative message numbers for a bunch of different commands including but not limited to preview and delete.

And while I’m at changing it to download by UIDs, this would be a good time to evaluate whether it should be downloading only the “message envelope” (a limited set of headers that basically are the headers you see in your email client message list) instead of the “full headers” (including all the headers you usually don’t read like spam checker versions and hosts that redirected the email and so on that could be useful for rules) the way it does now. If you’re not making rules that use the extended headers, this could cut data transfer in about half, which could be a significant time saver on large inboxes, so it’s worth looking into, even though I’d probably still have to also support having the existing modes to support users who use those headers to create complex rules. And while I’m doing that…and so on and so forth it goes 😉

Log4D Basic FileLogger Example

Since there is lacking on “getting started” documentation for Log4D, I thought a basic example might be helpful to others who might be intimidated about getting started with logging to a file in Delphi. Log4D is very simple, and similar to other Log4J related logging packages but lacks basic “getting started” documentation.

I used XE4 Starter for this. At the time of this writing, I and others have submitted some patches to fix the compile errors in Log4D affecting XE4, but they have not been merged in yet. For the quick fix to make it compile in whatever recent version of Delphi you have, see my previous post, my previous post.

First, create a project. I created a VCL application project for this example, because I’m not writing console applications so it’d be easier to copy and paste from 😉

Open the .dproj file (right click on the .exe name in the Project Manager and select “view source”) and add the highlighted lines:

<pre>
program Log4DbasicExample;</code>

uses
Vcl.Forms,
Log4D,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var
Logger : TLogLogger;
begin

TLogBasicConfigurator.Configure;
TLogLogger.GetRootLogger.Level := All;
Logger := TLogLogger.GetLogger('myLogger');
Logger.addAppender(TLogFileAppender.Create('filelogger','log4d.log'));

Logger.Debug('initializing logging example program');

Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
</pre>

When you run this application, it will create a log file called log4d.log in the directory the .exe file is in. Good enough for quick logging and debugging. Not adequate for production code.

Anywhere else in the project you need to log something, now it’s easy. I added one button to my VCL form, and double clicked the button to add an onClick handler, and then updated my VCL form unit as follows:

unit Unit1;

interface

uses
  Log4D, 
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  TLogLogger.GetLogger('myLogger').Debug('Button 1 clicked!');
end;

end.

If you’re doing a bunch of logging in one part of your code, you probably don’t want to use the chaining syntax because calling GetLogger repeatedly is unnecessary overhead. Instead store the Logger in a variable:

procedure TForm1.Button2Click(Sender: TObject);
var
  Logger : TLogLogger;
begin
  Logger := TLogLogger.GetLogger('myLogger');
  Logger.Debug('Button 2 clicked!');
end;

Well, there you have it. Basic, just enough to get started example. Because next time I want to add logging to a different project, I’m sure I will have completely forgotten how to do it and what and where I added my code.

File-Logging in Delphi

I wanted to do some quick logging to help me understand some code flow in Delphi. But having the Starter Edition of Delphi was crimping my style! Starter Edition doesn’t include the Event Log Viewer to see the output from OutputDebugString() while running in the debugger.

So I kept coming back to “I really just need to get over the learning curve and set up a ‘proper’ logging tool like Log4J”, a tool I’d used for Java projects in times long past. StackOverflow suggested Log4D and Log4Delphi as good possible candidates.

After reviewing both packages, I decided to go with Log4D.

Log4D seemed a bit simpler in that everything you need for basic logging is in one .pas file and one .inc file. I can see advantages both ways as a developer, but for just get me some logging quick, only having to add two files rather than a handful, and only needing one new unit in the uses statement simplifies some things.

Neither one had been updated in the last few years, so when you’re talking about “make this compile in a current version of Delphi” it looked like similar level of work.

Log4Delphi claims to be “loosely based on” Log4J. Log4D claims to be a direct port of Log4J.

Log4Delphi appears to be fairly well documented, whereas Log4D has almost no documentation. And while usually I prefer to go with the well-documented version, I felt like the simplicity of one file would make it worth seeing if I could muddle through the lacking documentation to make Log4D work. A few Delphi experts on StackOverflow swear by Log4D.

There were two compile errors I had to fix to make Log4D compile on XE4:

The IFDEF around Contnrs is missed by newer versions of Delphi, so you need to add {$DEFINE DELPHI5_UP} to the end of the .inc file (or in the .pas file works too). And ShortDateFormat needed to change to FormatSettings.ShortDateFormat

That’s the bare minimum fix, a better fix that maintains backwards compatibility isn’t a whole lot harder See my StackOverflow Discussion here about fixing the IFDEF so “and above”. And the ShortDateFormat issue, just needs another IFDEF around the FormatSettings for XE+.

The only basic “how to get this up and running” example of Log4D I could find online was this one blog entry. It needed a couple changes to compile (“Trace” wasn’t one of the log levels in the downloaded Log4D package). And then a little more puzzling together from the code and documentation for Log4Delphi and Log4J to make a file logger. I’ll write more about those changes in my next post ;-).

Indy 10 & Security Enhancements in PopTrayU

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.text.TextOrientationType” however, the descriptions reveal that option is for changing the orientation of the text, not the chart.

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.

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.

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

A few articles about porting to Indy10:
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.