Chapter 12. Adding more features

Making possible to save the result

Ok, we want now to save the tinted image in a file. What can we do? First, we add an accesor method to CentralView that returns the tinted pixmap (the pixmap that is in m_label) :

   QPixmap *tintedPixmap() const { return m_label->pixmap(); };

In TheTinterView, we're adding a new method next to openURL(const KURL &url), can you guess the name? Right, saveURL(const KURL &url) :) . That method does :

void TheTinterView::saveURL(const KURL &url)
  QString tmpFile;
  KTempFile *temp=0;
  if (url.isLocalFile())
    temp=new KTempFile;

  m_view->tintedPixmap()->save( tmpFile, "PNG");

  if (temp)
    KIO::NetAccess::upload(tmpFile, url, this);
    delete temp;

In case the url is a local file, we just use it as the file to which we will save the tinted pixmap in PNG format. If it's not a local file, we first create a temporal local file and save the tinted image there as PNG file, then, we upload the temporal file to the url the user specified, unlink (remove) the temporal file and delete the object we created for it.

Adding Drag&Drop support

There's not much to do here, as KDevelop automatically added since the beginning the code necessary to accept uri drops (equivalent to url drops for now), and as we've used KIO to load our images, you can already drag an image from konqueror to TheTinter and it will be downloaded.

Only to develop something related to Drag&Drop, we'll add support for image drops. The difference with uri drops is that image Drag&Drop events contain the image data in the event, while url drops just contain the URL for the image.

The code we'll use is:

void TheTinter::dragEnterEvent(QDragEnterEvent *event)
      // accept uri drops only
          event->accept(QUriDrag::canDecode(event) || QImageDrag::canDecode(event));
This will be called whenever we receive a drag event entering our application. It tells the drag&drop subsystem whenever we accept or reject the drag.

void TheTinter::dropEvent(QDropEvent *event)
  // this is a very simplistic implementation of a drop event.  we
  // will only accept a dropped URL.  the Qt dnd code can do *much*
  // much more, so please read the docs there
  QStrList uri;

  // see if we can decode a URI.. if not, just ignore it
  if (QUriDrag::decode(event, uri))
    // okay, we have a URI.. process it
    QString url, target;
    url = uri.first();

    // load in the file

  QPixmap pixmap;
  if (QImageDrag::decode(event, pixmap))
This code is executed when the user actually drops whatever he was dragging in our window. First, we try to decode the event as an uri event. If it succeedes, we extract the first url from the (possible) list of uris that the event contains, and load that url.

If it wasn't an uri event, we try to decode it as an image drag event (using QImageDrag::decode). And if it suceedes, we open that pixmap. We note that TheTinterView::openPixmap doesn't exist yet, so we add that method and implement it as:

void TheTinterView::openPixmap(const QPixmap& pixmap)
    m_view->setPixmap( pixmap );

And that's s9, our final application. I hope you liked the tutorial and learned a lot with it. I'm waiting to see your KDE applications soon in the web :) .


Antonio Larrosa Jiménez <>