Code This

std::cout <<me.ramble() <<std::endl;

Archive for the ‘Code’ Category

A Spinner Control For Android With Multi-Select Support

with 21 comments

I recently had a feature request for Checkout Tracker to allow the user to select multiple order states and multiple items when filtering the order list. I thought to myself, no problem, I can probably bang that out in a half hour or less, right? All I need is to do is add support for multiple states & items in the filter restrictions, and turn on a setting that allows the user to select multiple items in the Spinner controls used in the interface. Wrong. The Android Spinner control does not support multiple selection. This seems like a fairly obvious, and fairly common, use case. Unfortunately many such use cases are not covered currently by the Android libraries. Such is the curse of working with a young framework. No matter, I set out to create my own version of this control.

This took me about a day, after which I was able to bang out the feature request in under a half hour. Here are some screens:

 

I have made this control available for all the world to use, on github. Hopefully I have saved you a day’s worth of work.

Feel free to leave feedback about the API or functionality, or request changes.

Advertisements

Written by Kris Wong

June 17, 2012 at 11:49 am

Using QThread Without Subclassing

with 28 comments

The source code for this blog post can be found here. You do not need a Pro account to download the file, click No if you are prompted to upgrade.

Having been developing with C++ and Qt for around 6 years, and being a regular on #qt on freenode, a thought occurred to me. Hey, why not use that experience for a blog post? So, I thought I would start with one of the least understood classes in the Qt API, and that is QThread. This class is inherently difficult to use, because threading is difficult. Threading can turn a perfectly deterministic system into something non-deterministic. A threading issue is typically going to be much more difficult to diagnose and correct than other issues. Don’t get me wrong, threading is very useful, and serves a very important purpose (imagine using a web browser that didn’t use threads to fetch and render the content). But you should be familiar with both the positives and the negatives of the tools you are using to develop applications.

The first thing you need to know about using QThread is, a QThread object is not a thread. QThread is a class used for managing a thread; it is not itself a thread. The only method on QThread that runs on a separate thread is “run”. The second thing you need to know about using QThread is, as with all QObject subclasses, a QThread object has affinity to the thread in which it is instantiated. If you subclass QThread and add your own slots, you may be surprised to learn that these slots will actually run on the main thread. This also means you cannot use the QThread object as the parent of a QObject instance that has affinity to the thread (i.e., one created within “run”). And lastly, you need to know that only the main (GUI) thread can access GUI elements (QWidgets). The method of communicating between the thread and the GUI is signals and slots. If you don’t know, by default an object’s slots are run on the thread to which the object has affinity. This is done using the event loop.

Unfortunately, until Qt 4.4, QThread was an abstract class. The “run” method was pure virtual. And, even though this is no longer the case, the documentation still shows an example of using QThread by subclassing. While this is not wrong, or bad, it is not necessary. It also lends itself to using the class in ways it was not designed to be used. QThread is now able to be used without being subclassed. Attached is a small example application that creates a QTreeWidget and a button. Clicking the button will lead to the tree widget being populated with the contents of the user’s home direcrtory. Reading the contents of the file system is done on a separate thread. For this reason, you will see that you can still interact with the GUI while this is being done. There is a “sleep” call added, and tree widget items are expanded and collapsed while this is happening, so you are able see what is happening while the application runs.

So let’s jump into some code. This is the declaration of the FSReader class, the class that reads from the file system:

#ifndef FSREADER_H
#define FSREADER_H

#include <QObject>

class FSReader : public QObject
{
   Q_OBJECT

public:
   FSReader(QObject* parent = 0);
   ~FSReader();

public Q_SLOTS:
   void start();

Q_SIGNALS:
   void pathFound(const QString& path);
   void finished();
};

#endif // FSREADER_H

A pretty typical QObject subclass. As we will see later, the start slot will be executed when the thread begins to run, and the finished signal is emit’d when the object has completed its task. The pathFound signal is used to communicate with the GUI. The following is the implementation of the class:

#include "FSReader.h"
#include <QDirIterator>
#include <QDesktopServices>

#if defined(Q_OS_WIN32)
#include <windows.h>
#define SLEEP(msecs) Sleep(msecs)
#else
#define SLEEP(msecs) usleep(msecs * 1000)
#endif

FSReader::FSReader(QObject* parent)
   : QObject(parent)
{
}

FSReader::~FSReader()
{
}

void FSReader::start()
{
   QDirIterator it(QDesktopServices::storageLocation(QDesktopServices::HomeLocation), 
      QDirIterator::Subdirectories);
   while (it.hasNext()) {
      emit pathFound(it.next());
      SLEEP(1);
   }
   emit finished();
}

As you can see, the implementation of this class is quite simple. It only uses QDirIterator to iterate the files and directories in the user’s home directory, and emits a signal for each one found. As mentioned previously, the SLEEP call is simply to slow the program down a bit so you can see what is happening while it runs. It should not be used in a “real” application.

The last code snippet is also the most relevant, as it includes the use of QThread:

void Widget::onBtnClicked()
{
   QThread* thread = new QThread;
   FSReader* reader = new FSReader;

   reader->moveToThread(thread);

   connect(thread, SIGNAL(started()), reader, SLOT(start()));
   connect(reader, SIGNAL(pathFound(QString)), this, SLOT(onPathFound(QString)));
   connect(reader, SIGNAL(finished()), thread, SLOT(quit()));
   connect(reader, SIGNAL(finished()), reader, SLOT(deleteLater()));
   connect(reader, SIGNAL(finished()), thread, SLOT(deleteLater()));

   thread->start();
}

This is the button click handler of the Widget class. You can see here we instantiate both a QThread and FSReader instance, each without a parent. We then change the affinity of the “reader” to this new thread using the method “moveToThread”. This method can be used to change the thread affinity of any QObject.

Lets look at each connection that follows. The first is what starts the reader object after the thread has started. This method is run on the thread. The second connect links the reader object to the GUI. The “onPathFound” slot is run on the main thread. The next connect causes the thread’s event loop to exit once the reader has finished. The default implementation of QThread::run simply starts the thread’s event loop. The last 2 connects handle cleanup, since our objects were created without parents. The “deleteLater” method causes the objects to be deleted once there are no more pending events in the event loop. The reader is deleted on the thread, and the thread itself is actually deleted on the main thread. This “deleteLater” call works for the reader, even though the thread’s event loop would have already exited, because QThread does one final loop to handle all deferred deletetion events once its event loop has exited. QApplication does the same.

The rest of the Widget class, and the main, is included in the linked source, and is not particularly relevant to this post. That’s all you have to do to use QThread without subclassing it. Happy threading!

Written by Kris Wong

April 4, 2011 at 12:22 pm

Picasa Photo Scraper Using GData

with 2 comments

I took a trip to Japan and China about a year and a half ago.  I normally don’t take pictures (I don’t even own a digital camera!), but I have a friend who took over 1000.  Of course, once we got back, I wanted them.  The problem was he had uploaded them to Picasa and then gotten rid of them.  So I was stuck trying to get over 1000 pictures from Picasa, which I obviously didn’t want to do by hand.  I wasn’t familiar with the software, but I assumed you could not just download all the pictures in an album in one shot (which I never bothered to verify).  Instead, a friend had informed me about the Google Data APIs (GData), which he was using to display photos from Picasa on another website.  This sounded like exactly what I was looking for.  You can actually use GData to interface with all of the different data hosting services Google provides; it’s very handy.  The homepage for the project has the relevant downloads, as well as some documentation.  You can use GData from within a variety of languages, including .NET.  C# just happens to be my “quick ‘n dirty” language of choice, so I was all set.

At first it was difficult finding a good quick start guide, or something to get me up and running.  Modeling the URLs correctly to get the data you want isn’t exactly intuitive.  This situation may have improved since I wrote this little application, which was over a year ago.  I’m going to go through the code I wrote to scrape the pictures out of Picasa.  I will assume you have knowledge of C#.  This app was intended to be written quickly for a specific purpose. All data is hard coded. My knowledge of GData is limited to what is contained in this app, since I haven’t had a need for it since.  In order to get started, you need to download and install GData from the project page mentioned above.

Here is the code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using Google.GData.Client;
using Google.GData.Photos;

namespace PicasaPhotoFetcher
{
   class Program
   {
      // Modify the following data according to your needs.
      // This array contains the folder names that will be created for each album.
      private static readonly string[] Albums = {
         "Your album name here"
      };
      // This array contains the URLs for the data feed for each album.
      private static readonly string[] Urls = {
         "http://picasaweb.google.com/data/feed/api/user/[USER]/album/[ALBUM]?kind=photo"
      };
      // This is the absolute path to the folder where the albums will be stored.
      private static readonly string DownloadPath = "C:\\My Picasa Photos\\";

      // You shouldn't need to modify beyond this point.
      static void Main(string[] args)
      {
         PicasaService photoService = new PicasaService("Picasa");

         for (int i = 0; i < Albums.Length; i++) {
            FeedQuery photosQuery = new FeedQuery(Urls[i]);
            PicasaFeed albumFeed = photoService.Query(photosQuery) as PicasaFeed;
            DownloadAllPhotos(Albums[i], albumFeed.Entries);
            Console.WriteLine();
         }
      }

      static void DownloadAllPhotos(string albumName, AtomEntryCollection photoList)
      {
         DirectoryInfo dirInfo = Directory.CreateDirectory(DownloadPath + albumName);

         int photoNum = 1;
         foreach (AtomEntry photo in photoList) {
            Console.SetCursorPosition(0, Console.CursorTop);
            Console.Write("Fetching image {0} of {1}...", photoNum, photoList.Count);

            HttpWebRequest photoRequest = WebRequest.Create(photo.Content.AbsoluteUri +
               "?imgmax=800") as HttpWebRequest;
            HttpWebResponse photoResponse = photoRequest.GetResponse() as
               HttpWebResponse;

            BufferedStream bufferedStream = new BufferedStream(
               photoResponse.GetResponseStream(), 1024);
            BinaryReader reader = new BinaryReader(bufferedStream);

            FileStream imgOut = File.Create(dirInfo.FullName + "\\image" +
               photoNum++ + ".jpg");
            BinaryWriter writer = new BinaryWriter(imgOut);

            int bytesRead = 1;
            byte[] buffer = new byte[1024];
            while (bytesRead > 0) {
               bytesRead = reader.Read(buffer, 0, buffer.Length);
               writer.Write(buffer, 0, bytesRead);
            }
         }
      }
   }
}

 
In order to build this code, you will have to add references to the “Google Data API Core Library” and the “Google Data API Picasa Library” to your project.

As you can see, the class starts out with 3 data members that contain all of the configuration data required by the application.  You can add as many albums as you want to the string arrays.  Each index in the first array corresponds to the equivalent index in the second array (the arrays should have the same # of indexes).  The first array contains the name of the folders that will be created on the disk for each album.  The second array contains the actual URL sent to Google to get the album contents.  There are a few things to note here.  Obviously, the [USER] and [ALBUM] markers should be replaced with your username and album.  Also, if the album is private but has an auth key, you can add the key to url as a parameter:

&authkey=[KEY]

Where [KEY] is your auth key.  I believe you can also pass your username and password in the URL, but I am not sure of the parameter names for that off hand.

There is nothing too fancy going on here.  We are essentially reading the data of each image in 1024 byte chunks and dumping those chunks to the image file.  One additional thing to note is that we are appending the parameter:

&imgmax=800

To the photo URL.  This limits the maximum dimension of the image to 800 pixels.  The aspect ratio is maintained when the image is scaled.  If you do not want to scale your images automatically, then you can simply remove this piece of the code.

My colleague Johnathan has written a post discussing how to retrieve Picassa content with PHP and has also written a WordPress plugin for this purpose. Check them out.

Written by Kris Wong

November 18, 2008 at 10:20 am

Automatic Deallocation With AutoPtr

with one comment

One of the major concepts in C++ that makes it so powerful, and therefore so difficult, is memory management.  Even experienced programmers sometimes struggle with allocating and deallocating memory correctly and effectively.  However, if done correctly (which is, of course, rather subjective), C++ will always be more efficient than any garbage collected language will ever be.

I recently ran into a memory management issue.  I was employing a partial caching strategy, so in certain scenarios I wanted to return a pointer to memory stored in cache, and in other scenarios I needed to allocated new memory to return because the data did not exist in cache.  This left me with two options: copy the data, or try to deal with deallocating the memory in the latter case.  I chose to deal with deallocating the memory.

Initially, I considered std::auto_ptr.  Why reinvent the wheel for no good reason?  However, std::auto_ptr did not provide facilities for specifying that the auto_ptr did not own the memory upon construction, which is something I needed to be able to specify.  For this reason, and simply for the learning opportunity, I wrote my own version of an auto_ptr class with the functionality I needed (I realize I could have simply inherited std::auto_ptr to provide this functionality, but how fun would that have been).  Here is the source code for this class:

template<typename _T>
class AutoPtr
{
   template<typename _T1>
   friend class AutoPtr;

public:
   //------------------------------------------------------------------------------------------------------
   // Function: Constructor
   //
   // Parameters:
   //   ptr - the allocated pointer managed by this class
   //   owned - whether the memory should be deleted upon destruction
   //------------------------------------------------------------------------------------------------------
   explicit AutoPtr(_T* ptr = 0, bool owned = true)
      : m_owned(owned),
        m_ptr(ptr) { }
   //------------------------------------------------------------------------------------------------------
   // Function: Copy constructor
   //
   // Parameters:
   //   other - object to copy (will be disaccosiated from the managed pointer)
   //------------------------------------------------------------------------------------------------------
   AutoPtr(AutoPtr<_T>& other)
      : m_owned(false),
        m_ptr(0) {
      // Can't use the initializer list here because some compilers initialize from the bottom
      // up, which incorrectly sets m_owned to false.
      m_owned = other.m_owned;
      m_ptr = other.Detach();
   }
   //------------------------------------------------------------------------------------------------------
   // Function: Copy constructor
   //   Similar to above copy constructor, but works for types that are convertible to _T.
   //
   // Parameters:
   //   other - object to copy (will be dissociated from the managed pointer)
   //------------------------------------------------------------------------------------------------------
   template<typename _T1>
   AutoPtr(AutoPt<_T1>& other)
      : m_owned(false),
        m_ptr(0) {
      // Can't use the initializer list here because some compilers initialize from the bottom
      // up, which incorrectly sets m_owned to false.
      m_owned = other.m_owned;
      m_ptr = other.Detach();
   }
   //------------------------------------------------------------------------------------------------------
   // Function: Destructor
   //------------------------------------------------------------------------------------------------------
   ~AutoPtr() {
      if (m_owned) delete m_ptr;
   }

   _T* operator->() { return m_ptr; }
   _T& operator*() { return *m_ptr; }
   operator _T*() { return m_ptr; }
   const _T* operator->() const { return m_ptr; }
   const _T& operator*() const { return *m_ptr; }
   operator const _T*() const { return m_ptr; }

   //------------------------------------------------------------------------------------------------------
   // Function: operator=
   //
   // Parameters:
   //   lhs - object to copy (will be disaccosiated from the managed pointer)
   //------------------------------------------------------------------------------------------------------
   AutoPt& operator=(AutoPtr& lhs) {
      bool owned = lhs.m_owned;
      Reset(lhs.Detach(), owned);
      return *this;
   }
   //------------------------------------------------------------------------------------------------------
   // Function: operator=
   //   Similar to above operator=, but works for types that are convertable to _T.
   //
   // Parameters:
   //   other - object to copy (will be disaccosiated from the managed pointer)
   //------------------------------------------------------------------------------------------------------
   template<typename _T1>
   AutoPtr& operator=(AutoPtr<_T1>& lhs) {
      bool owned = lhs.m_owned;
      Reset(lhs.Detach(), owned);
      return *this;
   }

   //------------------------------------------------------------------------------------------------------
   // Function: Detach
   //   Disassociates the managed pointer from this instance.
   //
   // Parameters:
   //   None
   //
   // Returns:
   //   _T*
   //------------------------------------------------------------------------------------------------------
   _T* Detach() {
      _T* t = m_ptr;
      m_ptr = 0;
      m_owned = false;
     return t;
   }
   //------------------------------------------------------------------------------------------------------
   // Function: Reset
   //   Updates this instance to manage a new allocated pointer. Will free any previously owned pointer.
   //
   // Parameters:
   //   ptr - the allocated pointer managed by this class
   //   owned - whether the memory should be deleted upon destruction
   //
   // Returns:
   //   None
   //------------------------------------------------------------------------------------------------------
   void Reset(_T* ptr = 0, bool owned = true) {
      if (m_owned) delete m_ptr;
      m_owned = owned;
      m_ptr = ptr;
   }

protected:
   // variable: m_owned (protected)
   //   Whether or not we own the memory (and should therefore deallocate it).
   bool m_owned;

   // variable: m_ptr (protected)
   //   The pointer.
   _T* m_ptr;

protected:
   // The following is a helper class and supporting methods that allow AutoPtr to
   // support reference semantics. They are not intended to be consumed publically.
   struct PtrWrapper
   {
      bool m_owned;
      _T* m_ptr;

      explicit PtrWrapper(bool owned, _T* ptr)
         : m_owned(owned),
           m_ptr(ptr) { }
   };

public:
   AutoPtr(PtrWrapper wrapper)
      : m_owned(wrapper.m_owned),
        m_ptr(wrapper.m_ptr) { }
   AutoPt& operator=(PtrWrapper lhs) {
      Reset(lhs.m_ptr, lhs.m_owned);
      return *this;
   }

   operator PtrWrapper() {
      bool owned = m_owned;
      return PtrWrapper(owned, Detach());
   }
};

Now, this type of thing has been done a thousand times in the past, but that’s OK. I’ll take the opportunity to walk through the code anyway. I’ll assume you have at least some basic template knowledge.

We start with a basic constructor and copy constructor, easy enough.  Next is something slightly more interesting:

template<typename _T1>
AutoPtr(AutoPtr<_T1>& other);

This is a copy constructor that allows us to copy from an AutoPtr of a convertible type.  i.e., An AutoPtr of a child class type being passed to the constructor of an AutoPtr of it’s parent class type.  We then have some simple operators that give the class pointer semantics.  These operators are what allow us to treat the AutoPtr class just like a real pointer.  We then have 2 operator=’s, which are exactly like the 2 copy constructors.

Next we have:

_T* detach();

This method explicitly takes ownership of the managed memory from the AutoPtr instance. It is, of course, used in the copy constructors and operator=’s.  And:

void reset(_T* ptr = 0, bool owned = true);

Which instructs the AutoPtr instance to manage new memory, first destroying any previously managed memory.

The ReferenceHelper type is also interesting.  This simple struct gives AutoPtr reference semantics:

AutoPtr<MyClass> getMyClass()
{
   return AutoPtr<MyClass>(new MyClass);
}

int main()
{
   AutoPtr ptr = getMyClass();
}

Without this struct, we would not be able to properly manage the new’d instance of MyClass when returning from getMyClass.  What actually happens here is:

AutoPtr is implicitly converted to ReferenceHelper

ReferenceHelper is implicitly converted to AutoPtr.

This allows us to correctly remember whether or not we own the allocated memory, while not destructing it when returning from getMyClass.

This class is especially useful in complex methods that “save” data, where errors can essentially happen at any point.  If memory is allocated and managed with AutoPtr, we do not have to worry about cleaning up the allocated memory on various different code branches.

Written by Kris Wong

October 6, 2008 at 9:25 am