Every now and then I get a question about the inner workings of Doppler. In this post I’ll try to take you to a small trip into the program. I’m going to limit myself to Doppler 3.0 as that is different in it’s architecture from Doppler 2.0. Be warned, this is a long post.

First, Doppler is fully written in C# and is based upon the .NET 2.0 framework and I develop it using Visual Studio 2005 Professional Edition.

I’ll discuss the various elements of the program by referring to the following screenshot.

doppleroverview.gif

The panes you see are all SplitContainers. In first (internal builds) of Doppler 3.0 which was based upon the .NET 1.1 framework I used Splitter controls, which are an absolute horror to work with. The order in which you put controls on the form and the docking properties all mattered with Splitters whereas you get much much more freedom with SplitContainers. They where lifesavers to me.

At the top you see the orange bar (1) which is a Panel control. In the first beta of Doppler 3.0 I used an image which I set as a background to the panel. That worked, but I changed it later to internal routines. I’ve overridden the ‘OnPaint’ event of the panel and I build up two rectangles which I fill with 2 gradients which give the effect as shown. The same I do for the gray gradient bar at the bottom and the blue gradient bar in the right pane.

The feeds are a list of FeedItem objects contained in a so called FeedList collection. Both custom classes I created specifically for Doppler. Every time you click on ‘Retrieve’ or select one of the retrieval options from the context menu Doppler creates a seperate threads (to offload the main gui thread) which go out and start parsing the feeds. It first checks if there is a local cache file available. If there is, it will check for a few things first on the server on which the feed resides, Last modification date and the etag. Both are included in the feed retrieval. If the server is then replying that the feed has not been changed since the last retrievel it will use the cached copy, offloading your internet connection.
For every enclosure Doppler finds in the feed it will check for 2 things: if it’s available in the history, or if not, if it already resides on the filesystem. If one of these checks returns a ‘true’, Doppler will skip the download. If it’s a new enclosure, I’m signaling back to the main gui thread using an event that there is a new download. The main gui thread than tells the ‘Downloader’ control (3) to start retrieving a download.

During the download you see a progress bar in orange. I did that by overriding the DrawSubItem event of the ListView control. Every item contains some values regarding its progress and in the code behind the event I draw a gradient rectangle that shows the progress.

After the download is finished succesfully, Doppler will add an entry to the download history. Doppler uses hashcodes based on a few properties per post to build up a unique reference to a post which it uses to find an already downloaded post in the history.

The posts pane (4) contains an overview of the Posts. The posts are shown in a ListBox control. To create multiline items I override the DrawItem event of the control. During the initialization of the posts list I simply add the RssItem objects (again internally created) to the control. The DrawItem code knows how to handle those and draws the appropriate lines in the control. Then you click on a post the content shows below the list. That is done using a WebBrowser control on which I disabled the context menus and a few more things. As many rss feeds these days contain HTML content for the post description this control easily allows me to show that HTML without building my own parser.

All the threads that run (feed check and download) are started from a ThreadPool. That allows me to control the number of active threads very easily (you can set the number of concurrent threads from the ‘advanced’ tab in the options of Doppler).

The moment you switch from the posts pane (4) to the files pane I start a FileSystemWatcher control that monitors that specific folder. Everytime a certain file property changes or a a new file is created or a file has been deleted I update the list of files in the files pane.

Wel, this was a (brief) overview of the inner workings of Doppler. It only touches the surface of the program, but hopefully it gives you an idea of whats going on behind the curtains.