Showing posts with label qt. Show all posts
Showing posts with label qt. Show all posts

Saturday, February 2, 2013

Still Riding The Qt Train?

(Or: Welcome, BB10!)

On popular request, I have finally added some documentation to my OAuth library "O2". Check out the new README here: https://github.com/pipacs/o2/blob/master/README.md

Sunday, August 26, 2012

O2 Does O1, Too

Don't remember mentioning it on this blog: O2, my OAuth 2.0 library for Qt is now supporting OAuth 1.0 as well.

The library is still lacking good documentation, but it has been used with several applications already, against OAuth providers like Twitter, Dropbox, Google, Skydrive and more. Give it a try!

Tuesday, May 8, 2012

Ionic: Number Two In Nokia Store

Ionic, my e-book reader is number 2 in the Nokia Store right now, beaten only by Firefox! Thanks for all your support.

Sunday, March 18, 2012

WMware Fusion Works With Latest Nokias

The Burning Platform has got a bit more interesting recently, with the introduction of the fantastic Nokia 808 PureView. But the SDK is as stubborn as before: Windows or bust. 


For developers who made the switch to Mac ages ago, virtualization is the only option. However, the latest Nokia Connectivity Cable drivers don't work under Parallels, and didn't work under VMware Fusion either - until recently.


So the good news is that VMware has fixed the issue in the latest Fusions. Mine is version 4.1.1 (build 536016), and the USB cable drivers finally work! Tested with Nokia N8 and C7, and hopefully they will work with the new monster camera phone as well.

Sunday, March 4, 2012

Keep Accelerometer Running While The Screen Is Locked

On N9, the accelerometer is disabled while the screen is locked. In order to enable it all the time, set the "alwaysOn" property to true:


    accelerometer = new QAccelerometer(this);
    accelerometer->setProperty("alwaysOn", true);

This is a Meego-specific property, and it is only documented here.

Friday, February 10, 2012

Help! Virtual keyboard is hiding the input on Symbian

Modern GUIs often place labels, input fields and other controls on a scrollable pane - think of a Settings page for example. Implementing this in QML is easy: just lay out the controls in a Column, and place the Column in a Flickable.

For example:

Page {
  Flickable {
    anchors.fill: parent
    Column {
      Label {text: "Input 1:"}
      TextField {id: input1}
      Label {text: "Input 2:"}
      TextField {id: input2}
      // More controls
    }
  }
}


This works fine on Meego, but on Symbian it has a flaw: the virtual keyboard (VKB) can hide the input fields towards the bottom of the page. This is a serious shortcoming without a trivial solution, so I had to come up with a non-trivial one.

Basic idea: Whenever the virtual keyboard is displayed, the input field with the focus should be moved up within the Flickable, if it was originally covered by the VKB.

Here is the implementation:

Page {
  Flickable {
    id: flickable
    anchors.fill: parent
    Column {
      Label {text: "Input 1:"}
      TextField {id: input1}
      // More controls
    }

    // (1)
    Timer {
      id: adjuster
      interval: 200
      onTriggered: flickable.adjust()
    }

    // (2)
    Component.onCompleted: {
      inputContext.visibleChanged.connect(adjuster.restart)
    }

    // (3)
    function adjust() {
      if (!inputContext.visible) {
        return
      }

      var focusChild = null
      function findFocusChild(p) {
        if (p["activeFocus"] === true) {
          focusChild = p
        } else {
          for (var i = 0; i < p["children"].length; i++) {
            findFocusChild(p["children"][i])
            if (focusChild !== null) {
              break
            }
          }
        }
      }
      findFocusChild(flickable)

      if (focusChild === null) {
        return
      }
      var focusChildY = focusChild["y"]
      var focusChildHeight = focusChild["height"]
      if ((flickable.contentY + flickable.height) < (focusChildY + focusChildHeight)) {
        flickable.contentY = focusChildY + focusChildHeight - flickable.height
      }
    }
  }
}

Some explanations:

(1) We need a timer to adjust the focus item's position. We can't adjust it immediately after the virtual keyboard appears, because the the Flickable component will get resized with a nice animation, which takes time.

(2) So when the VKB gets visible, we just start a timer, that will adjust the focus item later

(3) Shifting the focus item (and all the others of course in the Flickable) happens in the adjust() function. The function tries to find a child item with active focus. If there is such an item, and it is currently hidden, the whole Flickable content will be elevated by changing it's contentY property.

Oh one more important remark: The PageStack component that owns the Page should have its platformSoftwareInputPanel property set to true. Otherwise the Page (and with it the Flickable) won't get resized when the VKB is shown.

Finally: QML is changing fast, so I'm sure one day this bug will be fixed by Nokia. The problem was found on, and the solution was written for the following environment:

  • Qt 4.7.4 on Symbian Anna or Belle
  • QtQuick 1.1
  • com.nokia.symbian 1.1

Wednesday, February 1, 2012

Count Your Steps

Steps, the open source step counter is available from Nokia Store. Besides counting steps, it can also log to Google Fusion Tables.

The Symbian version is downloadable now, Meego version is coming soon.

Sunday, January 29, 2012

Translating QML Applications: The Full Story

1. In the QML code, text should be inside qsTr(), e.g. instead of

    Label {text: "Hello"}

write

    Label {text: qsTr("Hello")

2. Make a directory containing the translations, let's call it translations. Add let's assume the QML sources are in the directory qml

3. Collect the texts to be translated into translations/<language>.ts, using the lupdate command. The following command

    lupdate qml -ts translations/hu.ts translations/es.ts

will recursively collect texts from source code in qml, into hu.ts and es.ts.

Name the translation files after the name of the target language, like es.ts (Spanish) or hu.ts (Hungarian).  Use two-letter language codes as in ISO 639-1. See http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes.

To make a country-specific translation variant, append the two-digit ISO country code after the language code, for example hu_HO.ts (the Hungarian dialect spoken in Honduras).

If lupdate is not found on the PATH, find it in the Qt SDK. I have a version in ~/QtSDK/Desktop/Qt/473/gcc/bin for example

4. Open the .ts files with the Qt translation tool Linguist. Assuming Qt SDK on Mac, it is in ~/QtSDK/Linguist.app/Contents/MacOS/Linguist

Using Linguist, set the .ts file's language and country, and translate. Make sure all texts are translated, and translations are marked "Done" (so there is a check mark in front of them)

5. When done with translating, release the translations (File → Release). "Releasing" in this context means converting the translation file to a compact binary, which has the same name as the original, but with the extension ".qm". For example, hu.ts will be released as hu.qm

6. Create a resource file translations.qrc and add it to the project

7. Add the released translations to this resource file, so it contains

    /
      translations/hu.qm
      translations/es.qm

8. Finally in main(), activate the translation corresponding to the current language:

#include <QTranslator>
#include <QLocale>

int main(int argc, char *argv[]) {
    QApplication app;
    QString locale = QLocale::system().name();
    QTranslator translator;
    if (translator.load(locale, ":/translations")) {
        app.installTranslator(&translator);
    } else {
        // Could not load translation
    }
    ...
}


Saturday, December 10, 2011

Simple OAuth 2.0 In Qt

I couldn't find any Qt-based OAuth 2.0 implementations, so I made one: https://github.com/pipacs/steps/tree/master/o2. Works with Google Docs, but far from complete.

Special thanks to Johan Paul for KQOAuth, his OAuth 1.0 library, which was inspirational for writing O2.

Sunday, November 13, 2011

Cross-Platform UI with Qt Components

Cross-platform UI development doesn't make much sense, if the platform UI paradigms are wildly different. It does however in my case: I develop Nokia Store applications targeting two very similar Nokia platforms: Meego and Symbian.

Both platforms are mobile phones with a touchscreen, and for both, Nokia provides UI toolkits (QML Components), that are similar, but full of maddening small differences. I'm sure these differences will disappear over time. In the meanwhile, I work around them using the Qt resource system.

So the idea is to wrap the platform-specific components into components providing uniform interfaces, and then put the wrappers into platform-specific resource files, with the content aliased to the same location. In my project, I have three resource files: meego.qrc, symbian.qrc, and for the common UI code, common.qrc.

This is how meego.qrc looks like:

<rcc>
 <qresource prefix="/qml">
  <file alias="MainPage.qml">qml/meego/MainWindow.qml</file>
 </qresource>
</rcc>

And this is how symbian.qrc looks like:

<rcc>
 <qresource prefix="/qml">
  <file alias="MainPage.qml">qml/symbian/MainWindow.qml</file>
 </qresource>
</rcc>


Lastly, this is in common.qml:

<rcc>
 <qresource prefix="/">
  <file>qml/main.qml</file>
 </qresource>
</rcc>

MainWindow,qml is implementing the wrapper for the platform-specific application main windows, that can be used from the platform-independent main.qml. To achieve this, both meego/MainWindow.qml and symbian/MainWindow.qml are aliased to the same resource file location (/qml/MainWindow.qml), while they physically reside in different source files (qml/meego/MainPage.qml and qml/symbian/MainPage.qml).

The project file of course only includes meego.qrc when building for Meego, and symbian.qrc when building for Symbian.

Final touches

When editing main.qml in Qt Creator, it won't find MainWindow.qml on the import path (because it doesn't exist in the current directory). To work around this, we should add the sub-directories "meego" and/or "symbian" to the import path. The final main.qml looks like this:

import symbian
import meego
import MainWindow.qml


MainWindow {
    ... (common UI code goes here)
}

Unfortunately, this is still not enough. Qt Creator is now happy, but when running main.qml from the resource file on the target platform, it will complain the directories "meego" and "symbian" do not exist.

This can be resolved by adding some dummy QML files (meego/dummy.qml and symbian/dummy.qml), and including them to the common resource file, which now looks like this:

<rcc>
 <qresource prefix="/">
  <file>qml/main.qml</file>
  <file>qml/meego/Dummy.qml</file>
  <file>qml/symbian/dummy.qml</file>
 </qresource>
</rcc>

Summary

What we have achieved with this somewhat complicated setup is simple: We can now wrap platform-specific QML components with a cross-platform API, and use them from a platform-agnostic UI code.



Tuesday, October 18, 2011

Ionic E-Book Reader

Ionic, my e-book reader for the Nokia N9 and N950 is out! Get it from the Nokia Store: http://store.ovi.com/content/212271.

Sunday, October 16, 2011

My E-book Reader: Coming Soon To The Nokia N9

The first release is done, waiting for Nokia Store approval. It's called Ionic, and it's the only EPUB reader for the Nokia N9 I know of. Stay tuned.