20 Jan 2017

feedPlanet KDE

Building communities

As some of you might know I've been involved in the foss-gbg group for a long while (more than 3 years now). Last year I helped starting the foss-north conference, which is really about taking what foss-gbg is and turning it into something bigger. We had a great turn-up - over 100 guests and ten great speakers.

This week, I finally got time to start pushing forward with this year's edition of foss-north. It will be held on April 26 in Gothenburg and it is a great opportunity to visit Sweden and Gothenburg and mingle with the FOSS community. We've already confirmed Lydia Pintscher and Lennart Poettering as speakers. If you want to speak the call for paper has just opened and will run until March 12. Tickets sales will open shortly too, as well as the call for sponsors.

By a random chance I got involved in the organization of yet another group this week. The C++ meetup community in Gothenburg has been inactive for almost a year, so a group of people decided to pick up the ball and try to get something running. We've renamed the group to gbgcpp and the next (our first) meeting will be held January 26, and then we will take it from there. Hopefully this can turn into something fun!

20 Jan 2017 9:18am GMT

Inside QImage (with a touch of Qt Quick and OpenGL)

QImage is the most common container for image data in Qt applications.

Getting a QImage that contains the pixel data of an image loaded from a file is fairly self-explanatory:

QImage img;
img.load("some_image.png");

This can then be used with QPainter, can be passed to widgets, and can also be utilized in Qt Quick scenes via custom image provider implementations. (although the latter would obviously be a massive overkill for image data coming from a file since that's what the Image element provides out of the box anyway).

So far so good. Now, what if the image data is coming from somewhere else? For example a custom drawing made via QPainter, or an image that comes from some external engine, like a camera, scanner or computer vision framework?

The answer lies in some of the 9 constructors. The interesting ones for our purposes are the following:

QImage(int width, int height, Format format);
QImage(uchar *data, int width, int height, Format format, ...);
QImage(uchar *data, int width, int height, int bytesPerLine, Format format, …);
QImage(const uchar *data, int width, int height, ...);
QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, …);

Let's now take a look at some of the common use cases and how these constructors serve the specific needs of each case.

Case #1: Image data owned by the QImage

The common case when generating images on-the-fly, is using QPainter and its raster paint engine to draw into a QImage:

QImage img(640, 480, QImage::Format_ARGB32_Premultiplied);
img.fill(Qt::transparent);
QPainter p(&img);
p.fillRect(10, 10, 50, 50, Qt::red);
p.end();
...

Here the underlying image data is allocated and owned by img itself.

When it comes to the format for images that will be passed to Qt Quick, the basic recommendations (as of Qt 5.8) are the following:

Other formats will lead to a convertToFormat() call at some point, which is not necessarily ideal. It is better to get the format right from the start.

It is worth noting that in order to get a proper no-conversion-by-Qt-on-CPU path, the OpenGL implementation must support GL_EXT_bgra, GL_EXT_texture_format_BGRA8888, or some of the vendor-specific variants. This can be relevant on older, OpenGL ES 2.0 only systems where BGRA support is not mandated by the GLES spec. In the absence of these (A)RGB32 image data will internally need either an additional swizzle step (this is what Quick and pretty much all old Qt 4 code does) or a conversion to a byte ordered QImage format (preferred by some of the newer code in QtGui and elsewhere), because the (A)RGB32 formats are not byte ordered.

What are byte ordered however are the Format_RGB(A|X)8888[_Premultiplied] formats introduced in Qt 5.2. These are nice because when read as bytes, the order is R, G, B, A on both little and big endian systems, meaning the image data can be passed to a glTex(Sub)Image2D call using a GL_RGBA format with a GL_UNSIGNED_BYTE data type as-is.

Therefore, the older default recommendation of using Format_ARGB32_Premultiplied or Format_RGB32 is not necessarily valid always. In the context of Qt Quick however, sticking with these formats will typically still be the right choice.

Case #2: Wrapping external, read-only image data

Now, what if the image data is readily available from an external engine? The common solution here is to use the QImage constructor taking a const uchar pointer.

void *data = ...
QImage wrapper(static_cast<const uchar *>(data), 640, 480, QImage::Format_RGB32);
// 'wrapper' does not own the data.
// 'data' must stay valid until 'wrapper' is alive.

There are no memory allocations and copies made here. It is up to the application to ensure the width, height, format, and optionally the bytes per line reflect the raw image data received from the other framework or engine.

Like many other container classes in Qt, QImage is using implicit sharing. This is handy because this way a QImage can be passed or returned by value without having to worry avoid expensive copies of the actual image data.

Instances created from a const uchar * are special in the sense that any attempt to modify the QImage (via a non-const function) detaches (makes a copy) regardless of the reference count. Hence attempts to modify to original, external data are futile:

const uchar *data = ...
QImage wrapper(data, ...);
wrapper.setPixelColor(5, 5, Qt::green);
// 'wrapper' is not a wrapper anymore,
// it made a full copy and got detached

Note that while this is all nice in theory, and the zero-copy approach is great in some cases, in practice making copies of the data is often unavoidable due to the need for format conversions in order to match the needs of the various frameworks. For example when interfacing with OpenCV, the code (taken from here) to convert a CV_8UC4 image into a QImage could look like this:

QImage mat8ToImage(const cv::Mat &mat)
{
    switch (mat.type()) {
    ...
    case CV_8UC4: {
        QImage wrapper(static_cast<const uchar *>(mat.data), mat.cols, mat.rows, int(mat.step), QImage::Format_RGB32);
        return wrapper.rgbSwapped();
    }
    ...

(NB! It does not matter if we use the const or non-const pointer variant of the constructor here. A copy will be made either way due to the semantics of rgbSwapped())

Case #3: Wrapping and modifying external image data

What about the constructor taking an uchar pointer? As the non-const argument suggests, this allows modifying the external, non-owned data via a wrapping QImage, without making copies of the image data. Modification often means opening a QPainter on the QImage:

void *data = ...
QImage img(static_cast<uchar *>(data), 640, 480, QImage::Format_RGB32);
QPainter p(&img);
p.fillRect(10, 10, 50, 50, Qt::red);
p.end();
... // 'data' must stay valid as long as 'img' is alive

Here we paint a red rectangle on top of the existing content.

This is made possible by a perhaps at first confusing feature of QImage: with non-owned, non-read-only data modification attempts will not detach when the reference count is 1 (i.e. the image data is not shared between multiple QImage instances).

Compare this behavior with something like QString::fromRawData() which explicitly says: Any attempts to modify the QString or copies of it will cause it to create a deep copy of the data, ensuring that the raw data isn't modified.

There a container associated with external data always makes a copy, and does not support modifying the external data. With QImage this is not acceptable, since the ability to change the pixels of an image from an arbitrary source without making a copy is a must have.

See this little example project for a demonstration of painting into a manually allocated image. It also demonstrates one potential issue one may run into when getting started with such a QImage:

void drawStuff_Wrong(QImage image)
{
    QPainter p(&image); // oops
    p.fillRect(10, 10, 50, 50, Qt::red);
}

QImage wrapper(data, 640, 480, QImage::Format_RGB32);
drawStuff_Wrong(wrapper);

This is clearly broken. The red rectangle will not appear in the original image pointed to by 'data'. Due to passing to the function by value the image gets its refcount increased to 2, and so the modification attempt when opening the QPainter has to detach with a full copy. The solution here is to pass by pointer or reference. (or yet better do not pass at all; QImage instances referencing external data should ideally be isolated as much as possible, in order to avoid issues like the one above)

Accessing the image data

And last but not least, let's talk about accessing the bytes of a QImage.

For read access, something like QImage::pixel() clearly does not scale when having to examining a larger part of the image. Instead, use constBits() or constScanLine().

QImage img(640, 480, QImage::Format_ARGB32_Premultiplied);
const uchar *p = img.constBits();
...
// 'p' is valid as long as 'img' is alive

Read-write access is done via bits() and scanLine(). These exist in both const and non-const version. The const version are in effect same as constBits() and constScanLine(). In practice it is strongly recommended to use constBits() and constScanLine() whenever read-only access is desired, in order to avoid accidentally invoking the non-const bits() or scanLine(), and making expensive and totally unnecessary copies of the image data.

QImage img1(640, 480, QImage::Format_RGB32);
QImage img2 = img1;
const uchar *p = img1.bits();
// ouch! that's the non-const bits(). img1 detaches.
// we only wanted read access and yet wasted time with a copy.

Due to img1 not being const this should have been:

QImage img1(640, 480, QImage::Format_RGB32);
QImage img2 = img1;
const uchar *p = img1.constBits();
// no copy, img1 and img2 still share the same data

The non-const versions detach when multiple instances share the same data or when the image wraps read-only, external data (via the const uchar * constructor).

That is all for now. Hope this clears up some of the uncertainties that may arise when looking at the QImage API for the first time, and helps to avoid some of the pitfalls when working with external image data. Happy hacking with QImage!

The post Inside QImage (with a touch of Qt Quick and OpenGL) appeared first on Qt Blog.

20 Jan 2017 8:40am GMT

19 Jan 2017

feedPlanet KDE

Qt Speech (Text to Speech) is here

I'm happy that with Qt 5.8.0 we'll have Qt Speech added as a new tech preview module. It took a while to get it in shape since the poor thing sometimes did not get the attention it deserved. We had trouble with some Android builds before that backend received proper care. Luckily there's always the great Qt community to help out.
Example application show Qt Text to Speech
What's in the package? Text to speech, that's about it. The module is rather small, it abstracts away different platform backends to let you (or rather your apps) say smart things. In the screen shot you see that speech dispatcher on Linux does not care much about gender, that's platform dependent and we do our best to give you access to the different voices and information about them.

Making the common things as simple as possible with a clear API is the prime goal. How simple?
You can optionally select an engine (some platforms have several). Set a locale and voice, but by default, just create an instance of QTextToSpeech and connect a signal or two. Then call say().

m_speech = new QTextToSpeech(this);
connect(m_speech, &QTextToSpeech::stateChanged,
        this, &Window::stateChanged);
m_speech->say("Hello World!");

And that's about it. Give it a spin. It's a tech preview, so if there's feedback that the API is incomplete or we got it all wrong, let us know so we can fix it ASAP. Here's the documentation.

I'd like to thank everyone who contributed, Maurice and Richard at The Qt Company, but especially our community contributors who were there from day one. Jeremy Whiting for general improvements and encouragement along the way (I bet he almost gave up on this project). Samuel Nevala and Michael Dippold did implement most of the Android backend, finally getting things into shape. Thanks!

You may wonder about future development of Qt Speech. There are some small issues in the Text to Speech part (saving voices and the current state in general should be easier, for example). When it comes to speech recognition, I realized that that's a big project, which deserves proper focus. There are many exciting things that can and should be done, currently I feel we need proper research of all the different options. From a simple command/picker mode to dictation, from offline options and native backends to the various cloud APIs. I'd rather end up with a good API that can wrap all of these in a way that makes sense (so probably a bunch of classes, but I don't have a clear picture in my mind yet) than rushing it. I hope we'll get there eventually, because it's certainly an area that is important and becoming more and more relevant, but I assume it will take some time until we have completed the offering.

The post Qt Speech (Text to Speech) is here appeared first on Qt Blog.

19 Jan 2017 11:02pm GMT

Should you still be using QGraphicsView?

There was a time when the Qt Graphics View Framework was seen as the solution to create modern user interfaces with Qt. Now that Qt Quick 2 has matured does the Graphics View Framework still have a place in Qt?

At the Qt World Summit 2016 I gave a presentation entitled "The Curse of Choice." It gives an overview of the various GUI technologies available in Qt 5 as well as descriptions of which you should use for different use cases. I would recommend you watch the recording of the presentation, unfortunately there was a technical issue with the recording and while the talk is available for viewing online, it is incomplete. I did give the same talk in webinar format though which you can view here.

After each time giving the talk, I got many questions about the Graphics View framework, which I was quite harsh on. My conclusion was that users should avoid QGraphicsView for new applications and instead use Qt Quick. This proved to be a controversial claim because Graphics View is used in many applications shipping today. So in the interest of answering the question "Should you still be using QGraphicsView in 2017?" This post will give the longer form of the answer.

Prophetic comment on a post about Qt Scene Graph

Prophetic comment on a post about Qt Scene Graph

Does Qt Quick really replace Graphics View?

Yes and No.

Qt Quick 1 (QDeclarative* API) was built on top of Graphics View, so comparing Graphics View to Qt Quick 2 is like comparing apples to oranges.

The better question is: "Does the Qt Quick Scenegraph replace Graphics View?" The lessons learned from using Graphics View for Qt Quick 1 were applied to create its successor. An API optimized for rendering Qt Quick scenes on devices with a Graphical Processor Unit. That API is the Qt Quick Scenegraph.

Qt Quick and its Scenegraph API can do most of what Graphics View could do and much more, but there are still features that got left behind:

Graphics View enables Multiple Views of the same scene

This powerful feature was shamelessly flaunted in the 40000 Chips demo:

40000 Chips Demo

The Power of Qt Graphics View!

Because all items in Graphics View can live in a shared QGraphicsScene, it is possible to have more than one QGraphicsView widget each of which could display different views of the shared scene. This is quite difficult to replicate in Qt Quick 2 because each view would need to create its own copy of the scene.

A cool as the feature seems, in practice it was not used so much by customers. The feature was also less practical on mobile and embedded platforms where only one view would be used per screen. This proved to be an unfortunate design decision because it also limited opportunities for optimization.

It makes the code really complex and optimization hard. - Alexis Menard ( Qt DevDays 2010 )

If you need to show the same scene multiple ways when migrating to Qt Quick, then you will need to separate the data you would like to visualize from the scene defined in QML. Populate each Qt Quick scene with only the data present in the view of your logical scene. This is more complicated but does provide more flexibility in how you store the state of your shared scene. I concede that it was easier to do in QGraphicsView.

Graphics View depends on QPainter

This is both a blessing and a curse. One of the reasons that Graphics View lived on so long through Qt Quick 1 in Qt 5 is because of its use of QPainter. When Qt Quick 2 was released with Qt 5.0 it came with the requirement that it could only be rendered with OpenGL(ES) 2 or higher. This minimum requirement did not fit everyone's needs, and the solution was to keep Qt Quick 1 around for those customers.

In Qt 4 QPainter had a couple of different graphics systems (backends) that could be used. This meant that if you were rendering with QPainter you could either choose to do so in software (raster), or with the GPU (opengl). In the case of QGraphicsView if you wanted to render your scene with the OpenGL paint engine you just needed to set the viewport of QGraphicsView to be backed by a QGLWidget.

In general this would improve the rendering performance of Graphics View. However, under the hood QPainter is generating loads of state changes and rendering the scene back to front leading to a poor use of the GPU. This is a large reason why the Qt Quick Scenegraph exists. In Qt Quick the renderer can, depending on the scene's content, determine the best way to arrange the scene for rendering on the GPU.

Qt Quick as of 5.8 no longer requires the use of OpenGL 2 thanks to the Software rendering adaption.

Graphics View has collision detection

What! Are you making a game now?

Angry Birds

They use Box2D, and so should you.

Graphics View supports embedding QWidgets

This is a neat feature and became a customer favorite shortly after its debut. The intention was to enable users to reuse controls that already existed. For simple widgets like QPushButton and QSlider the cost in extra memory usage and proxying was worth it for the convenience gained. However users did not stop there and would place complex widget hierarchies into their scenes like their entire QMainWindow or QDialog.

What was convenient for customers was also problematic for performance. QWidgets can not be embedded into a Graphics View scene directly. Instead they must be proxied. Each time an item in the scene that represents a QWidget requires an update, it has to request a full update of the QWidget via QWidget::render(…). The contents of the QWidget would then be rendered and copied into Graphics View. With Graphics View there is a shared QPainter between all items which renders to a single target QPaintDevice. QWidgets however are themselves QPaintDevices which require their own QPainter instances.

The key to the high performance of Graphics View is reducing how much is painted each frame. QGraphicsWidget and QGraphicsProxyWidget together are huge performance killers because they can not be rendered in a efficient way.

If you still choose to use Graphics View today, do yourself a favor and avoid embedding QWidgets into your scene.

QGraphicsProxyWidget: Not even once

Seriously

Graphics View has Shape Items

Graphics View Items

As of Qt 5.8, Qt Quick still only has one built in shape, the Rectangle. The Rectangle Item can also be used to create circles, but that is little comfort to anyone porting Qt Graphics View shapes to Qt Quick.

You can create lines in Qt Quick with a thin and long Rectangle. Line segments become a series of Rectangles. If you wanted more exotic shapes or paths, then you have a couple of options:

Canvas Item: With the Canvas Item you can use the imperative Context2D Javascript API to render whatever shape or content you want.

QQuickPaintedItem: This is a custom C++ item that has a virtual paint method much like a custom QGraphicsViewItem. Here you can render whatever content you want but via QPainter making a very easy porting path from QGraphicsItem. Both this and the Canvas Item create an offscreen rendering surface the size of the area you want to render to. This can either be a QImage or an QOpenGLFramebufferObject.

Keep in mind that if you are drawing a large shape, there is also a large area of memory behind the scenes being used that will be the size of your shapes bounding rectangle.

Custom QSGGeometryNode: This is likely the most optimal method performance-wise, but also the most difficult. Rather than drawing the shape you desire though an imperative painting API, you would embrace the Qt Quick Scenegraph and generate custom geometry for your item. This however means turning the shape you want to render into geometrical primitives like triangles. The details of this are a bit much for this article, and likely best left to a future post. For more details check out this example.

There may be several ways to render arbitrary shapes in Qt Quick scenes, but none as convenient as QGraphicsPathItem.

Laszlo Agocs is currently researching this topic though, so as soon as Qt 5.10 there could be an easy way to use shapes and paths in Qt Quick. Stay tuned.

But I don't want to write QML or Javascript!

Time to address the gorilla in the room.

Its very easy to breeze over the detail that not everything has a public C++ API in Qt Quick. If you are porting an application using Graphics View to Qt Quick, you will very soon realize that you have to write QML code. While you can (and should) use C++ APIs as much as possible with Qt Quick as well, you will find that creating sub-classes of existing components via C++ is not possible.

Lets consider the TextEdit QML component. If you wanted to create an item that extended the existing functionality of TextEdit you would have to do so from QML. The TextEdit QML component is implemented in C++, but that class is not public API, so you can't use that class in your custom C++ item via aggregation nor composition.

Much of the Qt Quick QML APIs are like this. Even if you start with the approach of: "Code only in C++", in practice this is challenging. We hope to address this in future releases of Qt. The original reason given to keep these classes private was to keep our options open, and not lock down these APIs too soon. As we are now releasing Qt 5.8 and looking towards Qt 6, its time to reconsider this policy.

That said, QML is awesome, and in practice extending items in QML is super easy. QML stands for the Qt Meta-object Language and should be looked at as an easy way to automate the process of setting up a hierarchy of QObjects and their signal/slot connections. If you're holding out on Qt Quick because of QML, I understand, but recommend you still give it a chance. Check out the free online QML Book for more details on getting started.

Is Graphics View deprecated?

The short answer is no, not officially. The real answer is more nuanced. And it starts with the fact that Qt Quick 1 is now deprecated. This is important because it was Qt Quick 1 that drove forward the development of Graphics View. Much like the rest of the Widgets module, Graphics View is considered "done" and isn't being given new features. You can see this if you check out the commit log for those classes.

There is some maintenance, but much of those commits are from various refactoring that covers all of the QtBase module.

Because of the larger than not overlap between Qt Quick 2 and Graphics View, I would expect to see Graphics View moved into a "Compatibility" module for Qt 6.

Conclusion

I am not so naive to believe that this answers all the questions you have about the future of Graphics View. I would like to continue the discussion because if there is a reason you still can not migrate from Graphics View, then we still have work to do.

If you want me to write more articles about porting from Graphics View to Qt Quick, please let me know in the comments. Also if you recall seeing this post elsewhere, it also appeared on my own blog. In the interest of making the Dev Loop of the Qt Blog more awesome, I'll be posting all future blog articles here. So stay tuned!

The post Should you still be using QGraphicsView? appeared first on Qt Blog.

19 Jan 2017 11:00am GMT

Rahul Yadav (rahulyadav)




Google Code In ( Gcompris ) 2106-2017


Our Experience -:

This year's Google Code In was awesome as before . There were instances of tasks successfully completed by the students . Out of 12 unique tasks 11 tasks were successfully attempted . The students were enthusiastic till the very end of the program. Most of the students solved multiple tasks that provided us with varied ideas .

Some of the students bonded with the community during their tasks over the irc. All the mentors did a great job . At first the program seemed a bit monotonous but as we reached halfway through the timeline students showed their interest and made it a success.

Students seemed to be interested in contributing to opensource softwares and getting exposure to new technologies like (Qt , git). We did hit a road bump with some tasks that involved building the software or coding in general. But this was supposed to happened as we encountered very young talents.

What we learnt ( Mentors ) -:

We will try to improve the quality and type of tasks that are published for further GCI's to get more students interested in contributing to opensource softwares.


Type of tasks -:

Open Bugs -:

Blog Posts -:

  1. Https://gabrielleeblog.wordpress.com/2016/12/01/reviewing-gcompris-a-blog-post/
  2. Http://gcomprisbysunveersingh.blogspot.in
  3. Https://sangeethagci.wordpress.com/2016/12/11/about-gcompris/
  4. Http://1705mandy.blogspot.fr/2016/12/gcompris-quality-educational-software.html?m=1
  5. Http://aboutg-compris.blogspot.fr/
  6. Https://raghav5.wordpress.com/2016/12/18/google-code-in-2016/
  7. Https://ilyabizyaev.wordpress.com/2017/01/13/gcompris-review/

Videos -:



  1. https://youtu.be/cFQDWB4P5zM
  2. https://www.youtube.com/watch?v=a2hXe31vM1k&feature=youtu.be (Gtk + Version?)
  3. https://www.youtube.com/watch?v=bPVv8cXe1-E (not available)
  4. https://youtu.be/wJcakVTS3Ts
  5. https://www.youtube.com/watch?v=tcZk1-k4D3o

T-Shirts -:

  1. https://goo.gl/IYwpnW
  2. https://goo.gl/ywFhRR
  3. https://goo.gl/t3JYAa
  4. https://goo.gl/KV3Kl1
  5. https://www.spreadshirt.co.uk/create-your-own?product=146474712&view=1

Icons -: ( All the icons have been commited in the main repository )

  1. Babymatch
  2. Babyshapes
  3. details
  4. Drawletters
  5. Explore_monuments
  6. Explore_world_music
  7. Explore_world_animals
  8. Geo-country
  9. Graph-coloring
  10. Guesscount
  11. Hanoi
  12. Hanoi_real
  13. Imagename
  14. Letter-in-word
  15. Melody
  16. Missing-letter
  17. Number_sequence
  18. Paintings
  19. Photo_hunter
  20. Roman_numerals
  21. Tangram
  22. Water cycle






Code -:

  1. 2 new levels in explore_world_animals
  2. dataset update in guesscount activity


Reviews from the students :-

  • Ilya Bizyaev said -: "For me, Google Code-In was a wonderful opportunity to improve various skills, meet new friends and become part of an amazing community that shares my values."

  • Sergey said -: "GCI is an amazing adventure through the world of Opensource, allowing you not only to improve skills and meet new friends from all around the world, but also help you dive right into the development of real projects. I'd say, tagline of GCI should be "Learn by making the world a better place"."



Mentor's Review :-


  • Rahul yadav ( My Self ) :- The contest was full of energetic students. The students were active on irc as well . Students were exited to contribute to Gcompris. Some of the students work was continuously being commited to our main repository which increased their interest in the project . I had a great learning experience of being a mentor as well .

  • Johnny Jazeix said -: "really great surprises and amazing job done by some students. I though we would advance more on code tasks but the graphics have been improved a lot."

  • Pulkit Gupta

Special Thanks to :-
(they were not official GCI mentors but helped the students all along the way)
  • Timothée said -: "that was a great experience: it was cool to can share some knowledge, the students were nice and the result was helpful."

  • Wxl



19 Jan 2017 10:38am GMT

Codethink is hiring engineers.

Codethink is steadily growing for some time now. I have been working for 18 months in the company and it is about time for me to tell you that this is an outstanding place to work if you:

But above all, you are willing to learn no matter how senior you are!

Codethink is an independent consultancy company based in Manchester, UK, although it has some people like myself working remotely. Our customers are also spread around the world. We are around 75-80 people now, most of them, engineers.

Most of our work is related with Linux kernel, low level system activities, compilers, delivery of linux systems, distro and SoC work.

Let me know if you could be interested in working at Codethink or send directly your CV to jobs@codethink.co.uk

Agustin Benito Bethencourt (Toscalix) @toscalix Linkedin profile: http://linkedin.com/in/toscalix

19 Jan 2017 10:23am GMT

How to shoot yourself in the foot using only a scene graph (neat optimization trick inside)

I am trying to get into the habit of blogging more often, also about topics that may not warrant a white paper worth of text, but that may be interesting to some of you. For those of you who don't know me, I am the maintainer of the text and font code in Qt, and recently I came across a curious customer case where the optimization mechanisms in the Qt Quick scene graph ended up doing more harm than good. I thought I would share the case with you, along with the work-around I ended up giving to the customer.

Consider an application of considerable complexity: Lots of dials and lists and buttons and functionality crammed into a single screen. On this screen there are obviously also labels. Thousands of static labels, just to describe what all the complex dials and buttons do. All the labels share the same font and style.

Narrowing the example down to just the labels, here is an illustration:

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    id: window
    visible: true
    title: qsTr("Hello World")
    visibility: Window.Maximized

    Flow {
        anchors.fill: parent
        Repeater {
            model: 1000
            Text {
                text: "Hello World"
            }
        }
    }
}

Now, the way the scene graph was designed, it will make an effort to bundle together as much of a single primitive as possible, in order to minimize the number of draw calls and state changes needed to render a scene (batching). Next, it will try to keep as much as possible of the data in graphics memory between frames to avoid unnecessary uploads (retention). So if you have a set of text labels that never change and are always visible, using the same font, essentially Qt will merge them into a single list of vertices, upload this to the GPU in one go and retain the data in graphics memory for the duration of the application.

Example screenshot

Artist's impression of a complex Qt application

We can see this in action by setting the environment variable QSG_RENDERER_DEBUG=render before running the application above. In the first frame, all the data will be uploaded, but if we cause the scene graph to re-render (for instance by changing the window size), we see output like this:

Renderer::render() QSGAbstractRenderer(0x2a392d67640) "rebuild: none"
Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 1000 nodes in 1 batches...
 - 0x2a39351fcb0 [retained] [noclip] [ alpha] [  merged]  Nodes: 1000  Vertices: 40000  Indices: 60000  root: 0x0 opacity: 1
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 0

From this we can read the following: The application has one batch of alpha-blended material, containing 1000 nodes. The full 40000 vertices are retained in graphics memory between the frames, so we can repaint everything without uploading the data again.

So far so good.

But then this happens: Someone adds another label to our UI, somewhere in the depths of this complex graph of buttons, dials and labels. This label is not static, however, but shows a millisecond counter which is updated for every single frame.

While the scene graph does the correct and performant thing for most common use cases, the introduction of this single counter item in our scene breaks the preconditions. Since the counter label will be batched together with the static text, we will invalidate all the geometry in the graph every time it is changed.

To see what I mean, lets change our example and run it again.

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    id: window
    visible: true
    title: qsTr("Hello World")
    visibility: Window.Maximized
    property int number: 0

    Flow {
        anchors.fill: parent
        Repeater {
            model: 1000
            Text {
                text: index === 500 ? number : "Hello World"
            }
        }
    }

    NumberAnimation on number {
        duration: 200
        from: 0
        to: 9
        loops: Animation.Infinite
    }
}

The example looks the same, except that the 501st Text item is now a counter, looping from 0 to 9 continuously. For every render pass, we now get output like this:

Renderer::render() QSGAbstractRenderer(0x1e671914460) "rebuild: full"
Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 1000 nodes in 1 batches...
 - 0x1e672111f60 [  upload] [noclip] [ alpha] [  merged]  Nodes: 1000  Vertices: 39964  Indices: 59946  root: 0x0 opacity: 1
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/1, render: 0

As we can see, we still have a single batch with 1000 nodes, but the data is not retained, causing us to upload almost 40000 vertices per frame. In a more complex application, this may also invalidate other parts of the graph. We could even end up redoing everything for every frame if we are especially unlucky.

So, presented with this case and after analyzing what was actually going on, my first goal was to find a work-around for the customer. I needed to come up with a way to separate out the counter label into its own batch, without changing how anything looked on screen. There may be more ways of doing this, but what I ended up suggesting to the customer was to set clip to true for all the counter labels. Giving the counters a clip node parent in the graph will force them out of the main batch, and the updates will thus be isolated to the clipped part of the scene graph.

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    id: window
    visible: true
    title: qsTr("Hello World")
    visibility: Window.Maximized
    property int number: 0

    Flow {
        anchors.fill: parent
        Repeater {
            model: 1000
            Text {
                text: index === 500 ? number : "Hello World"
                clip: index === 500
            }
        }
    }

    NumberAnimation on number {
        duration: 200
        from: 0
        to: 9
        loops: Animation.Infinite
    }
}

Still the same code, except that the clip property of the 501st Text item is now set to true. If we run this updated form of the application with the same debug output, we get the following:

Renderer::render() QSGAbstractRenderer(0x143890afa10) "rebuild: partial"
Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 1000 nodes in 3 batches...
 - 0x143898ee6d0 [retained] [noclip] [ alpha] [  merged]  Nodes:  500  Vertices: 20000  Indices: 30000  root: 0x0 opacity: 1
 - 0x143898ec7e0 [  upload] [  clip] [ alpha] [  merged]  Nodes:    1  Vertices:     4  Indices:     6  root: 0x14389a3a840 opacity: 1
 - 0x143898edb90 [retained] [noclip] [ alpha] [  merged]  Nodes:  499  Vertices: 19960  Indices: 29940  root: 0x0 opacity: 1
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 0

As you can see from the output, the text is now divided into three batches instead of one. The first and last are retained between frames, causing the full upload for each frame to be an insignificant 4 vertices. Since the clip rect contains the bounding rect of the text, we will not actually clip away any pixels, so the application will still look the same as before.

So all is well that ends well: The customer was happy with the solution and their performance problems were fixed.

Also, I gained some ideas on how we can improve the Qt Quick API to make it easier for users to avoid these problems in the future. Since we want performance to be stable from the first frame, I don't think there is any way to get around the need for users to manually identify which parts of the graph should be isolated from the rest, but I would like to have a more obvious way of doing so than clipping. My current idea is to introduce a set of optimization flags to the Qt Quick Text element, one of which is Text.StaticText, sister to the QStaticText class we have for QPainter-based applications.

In the first iteration of this, the only effect of the flag will be to ensure that no label marked as StaticText will ever be batched together with non-static text. But down the road, maybe there are other optimizations we can do when we know a text label never (or rarely) changes. And this is just one of a few optimization APIs I want to add to Qt Quick Text in the near future, so stay tuned!

The post How to shoot yourself in the foot using only a scene graph (neat optimization trick inside) appeared first on Qt Blog.

19 Jan 2017 10:14am GMT

18 Jan 2017

feedPlanet KDE

“Unboxing” the Android Things Developer Preview

Android Things is Google's answer to creating an environment for IoT devices. Take a slimmed down Android build, add some sensor-specific APIs, and provide it on a number of powerful pre-integrated micro-boards and you have a ready-made platform for building a host of upcoming IoT devices. Android Things can take advantage of many existing Android libraries, toolkits, and APIs, making it easier and quicker for developers to turn ideas into product. What's not to like?

We decided to test this theory by checking out the Android Things Developer Preview on a Raspberry Pi 3. We were looking to assess the overall experience, to understand what types of products it is targeting and to try to determine how well it can support Qt.

Raspberry Pi 3 (Model B)

One of my very first observations is that Google does not provide the source, just a pre-built image. This makes it difficult to customize the image and puts us at the mercy of Google for updates to any of the contained components or packages like the kernel or SSL library. Let's hope that this will change once we're beyond the Developer Preview stage.

Once you have the image loaded onto a board, it's time to boot it and take it for a spin. This is an appropriate time to get a coffee - and you've got the time to drive to Starbucks - because booting Android Things takes a very long time. Linux builds for Yocto or Debian on the same hardware boot significantly faster than Android Things, so we can probably assume the boot process hasn't yet been fine-tuned. Without knowing the final boot speed of an Android Things product, you may want to plan use cases around a system that's always on and rarely needs a reboot, or that isn't real-time and can afford a boot process that takes minutes.

The Android Things Preview on the Raspberry Pi 3 doesn't provide OpenGL ES support or a virtual keyboard, which severely limits what type of Android Java apps will run. (Unfortunately, that also means it cannot support Qt QML either.) It's pretty safe to say that if your device plans to have a full smartphone-like display, you might not want to use Android Things anyway. Although it does support frame buffer graphics, without hardware acceleration the graphics are quite pokey. Our guess is that even if Android Things will eventually support OpenGL ES, its best application will be for a headless configuration or one where your display needs aren't too sophisticated.

Unfortunately, boot speed and graphics aren't the only things that are sluggish. Running and installing apps are quite slow: first time loads for a Java app are around 20 seconds, and for a Qt app around 25 seconds. This delay is likely due to the AOT compiler, because things speed up dramatically to a boot in just 2-3 seconds on subsequent loads. While this is a pain for developers who will suffer these load times for each new build, the AOT compiling means that customers would only notice a slow experience first time out-of-the-box.

Now for the good news. Qt developers will be happy to know that Qt Creator works very well with Android Things - running and debugging apps just works. And not only will QWidget-based applications run on Android Things, they're even faster than the platform's native Android Java widgets. This may not be saying much without GPU-accelerated graphics but any speed improvement is a bonus.

Also good news is the device's security. Android Things uses the Android security/permissions model across the board, letting you have complete security control of your IoT device access, and placing all apps in isolated containers by default. With IoT security being a primary concern, built-in security from the ground up is most welcome.

Finally, Android Things is Apache 2 licensed. People who are building an IoT device to be sold as a product will appreciate that they don't have to open up their source code to the world. It is a disadvantage to those who are tinkering but this choice (and the Google source ownership) pretty clearly point to a commercial product bias.

Conclusion

Android Things

If you're an Android fan, you'll like where Android Things is going. It's a bit on the slow side, as it's clearly designed with certain use cases in mind - like little (or no) display and infrequent reboots - but the benefits of Android development may outweigh the disadvantage of carrying around a massive Android runtime. It will definitely suffer on low-end devices but we can hope that optimizations will be made as more programmers get their hands on it. We'll certainly be keeping our eyes on it and, as running C++ can do nothing but help the overall speed, we'll be trying to make sure that it supports Qt as best as possible.

The post "Unboxing" the Android Things Developer Preview appeared first on KDAB.

18 Jan 2017 3:59pm GMT

Which OpenGL implementation is my Qt Quick app using today?

Qt Quick-based user interfaces have traditionally been requiring OpenGL, quite unsurprisingly, since the foundation of it all, the Qt Quick 2 scenegraph, is designed exclusively with OpenGL ES 2.0 (the top of the line for mobile/embedded at the time) in mind. As you may have heard, the graphics API story is a bit more inclusive in recent Qt versions, however the default OpenGL-based rendering path is, and is going to be, the number one choice for many applications and devices in the future. This raises the interesting question of OpenGL implementations.

Wait, there is more than one? Isn't there one for my graphics card, and that's it?

Kind of, but not quite.

The vendor-provided OpenGL implementation is one thing, but is is not always there to begin with (anyone who attempted to deploy Quick apps on a wide range of older machines running e.g. Windows 7 with no graphics driver installed could likely talk a lot about this…), while in some cases there are alternative options, for instance an open-source stack like Mesa. Some of these stacks can then provide multiple ways of operation (think software rasterizers like Mesa llvmpipe or Direct3D WARP).

As an example, let's take a look at Windows. The Windows-specific area of the Qt documentation describes the options pretty well. To summarize, one may be using OpenGL proper (a vendor-provided ICD behind opengl32.dll), ANGLE in D3D9 mode, ANGLE in D3D11 mode, ANGLE with the D3D11 WARP software rasterizer, an OpenGL software rasterizer provided by Mesa llvmpipe. That is no fewer than 5 options, and the choice can be made based on the built-in GPU card/driver blacklist or environment variables or hard-coded application preferences. All this is not exactly rocket science, but it does require a certain level of awareness from the developer during development, possibly when reporting bugs and support requests, and naturally also when planning deployment.

Why does this matter?

QSG_INFO=1 is your friend

When in doubt about graphics performance or before attempting to troubleshoot any sort of graphics issues, do set the QSG_INFO environment variable to 1 and rerun your Qt Quick application.

An alternative in modern Qt versions is to enable the qt.scenegraph.general logging category.

This will print something like the following either on the console or the debug output: (on Windows you can use DebugView for non-console apps when not launching from Qt Creator)

qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.95 ms
qt.scenegraph.general: texture atlas dimensions: 2048x2048
qt.scenegraph.general: R/G/B/A Buffers:    8 8 8 0
qt.scenegraph.general: Depth Buffer:       24
qt.scenegraph.general: Stencil Buffer:     8
qt.scenegraph.general: Samples:            0
qt.scenegraph.general: GL_VENDOR:          NVIDIA Corporation
qt.scenegraph.general: GL_RENDERER:        GP10B (nvgpu)/integrated
qt.scenegraph.general: GL_VERSION:         OpenGL ES 3.2 NVIDIA 367.00
qt.scenegraph.general: GL_EXTENSIONS:      ...
qt.scenegraph.general: Max Texture Size:  32768
qt.scenegraph.general: Debug context:     false

What does this tell us?

The OpenGL vendor, renderer and version strings. In the example above we see Qt Quick is using an OpenGL ES 3.2 context on some NVIDIA embedded platform, using the vendor's driver. This look good.

Now, if there happen to be references to llvmpipe, like in the below example, then that should immediately raise a flag: your application is rendering via a software rasterizer. If this is expected, fine. If not, then you should figure out why, because performance is seriously affected (you are not using the GPU at all).

GL_VENDOR: VMware, Inc.
GL_RENDERER: Gallium 0.4 on llvmpipe (LLVM 3.6, 128 bits)
GL_VERSION: 3.0 Mesa 11.2.2

Let's take another example, this time with ANGLE. Here I just forced the usage of ANGLE by setting QT_OPENGL=angle on an otherwise fully OpenGL capable system:

qt.scenegraph.general: windows render loop
qt.scenegraph.general: Using sg animation driver
t.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.scenegraph.general: texture atlas dimensions: 512x512
qt.scenegraph.general: R/G/B/A Buffers:    8 8 8 8
qt.scenegraph.general: Depth Buffer:       24
qt.scenegraph.general: Stencil Buffer:     8
qt.scenegraph.general: Samples:            0
qt.scenegraph.general: GL_VENDOR:          Google Inc.
qt.scenegraph.general: GL_RENDERER:        ANGLE (NVIDIA GeForce GTX 960 Direct3D11 vs_5_0 ps_5_0)
qt.scenegraph.general: GL_VERSION:         OpenGL ES 2.0 (ANGLE 2.1.0.8613f4946861)
qt.scenegraph.general: GL_EXTENSIONS:      ...
qt.scenegraph.general: Max Texture Size:  16384
qt.scenegraph.general: Debug context:     false

The key points are that (1) we are using ANGLE, (2) it is using its D3D11 backend, and (3) the Qt Quick scenegraph is using the (somewhat ill-named) 'windows' render loop, meaning no dedicated render thread is present. The usage of D3D9 or D3D11 WARP can be recognized from the renderer string in the same way.

Then there is the Qt Quick scenegraph's active render loop. This can be threaded, basic or windows. In recent Qt versions the scenegraph documentation describes all of these quite well, including the logic for choosing the loop to use. For experimenting or troubleshooting one can always override by setting the environment variable QSG_RENDER_LOOP to one of the three render loop names.

One common problem, mainly on embedded systems, is sometimes the bizarre speed up of animations. If you find that QML animations are running a lot faster than they should be and that the threaded render loop is in use, there is a good chance the issue is caused by the missing or incorrect vertical sync throttling. Solving this will be platform specific (e.g. in some cases one will need to force making a dedicated FBIO_WAITFORVSYNC ioctl, see QT_QPA_EGLFS_FORCEVSYNC), but armed with the logs from the application at least the root cause can be uncovered quickly and painlessly. (NB as a temporary workaround one can force the basic render loop via QSG_RENDER_LOOP=basic; this will provide more or less correct timing regardless of vsync at the expense of losing smooth animation)

Your other friends: qtdiag and contextinfo

Note that the scenegraph's log only provides limited system information. It is great for strictly graphics and Quick-related issues, but when making bug reports, especially for Windows, it is strongly recommended to post the output of the qtdiag utility as well. This will provide a lot wider set of system information.

Additionally, the contextinfo example in examples/opengl/contextinfo is a good tool to troubleshoot basic OpenGL bringup problems. Launch it normally, click Create Context, see what happens: does the triangle show up? Does it rotate smoothly? Are the vendor and renderer strings as expected? Then set QT_OPENGL=angle and re-run. Then set QT_ANGLE_PLATFORM=d3d9 and re-run. Then set QT_OPENGL=software and, assuming the opengl32sw.dll shipped with the pre-built Qt packages is accessible, re-run. Or on Linux with Mesa, set LIBGL_ALWAYS_SOFTWARE=1 and see what happens. And so on.

Why am I not getting the right GL implementation?

Now, let's say the logs reveal we are stuck with a software rasterizer and our beautiful Qt Quick UI runs sluggishly in a maximized full HD window. What can we do to figure out why?

On Windows, enable the logging category qt.qpa.gl. (e.g. set QT_LOGGING_RULES=qt.qpa.gl=true) This will tell why exactly the OpenGL implementation in question was chosen. The typical reasons are:

On Linux, there are typically three reasons:

A cautionary tale

The Raspberry Pi has at least three OpenGL solutions as of today: the Broadcom graphics stack, Mesa with llvmpipe (software rasterizer), and the upcoming Mesa with proper GPU acceleration (VC4) path.

Unfortunately this can lead to an unholy mess due to some distros prefering to ship Mesa llvmpipe in order to provide some sort of OpenGL under X11 (which the Broadcom stack does not support): Qt applications may unexpectedly pick up Mesa when they should use Broadcom (for Dispmanx without X11), while they may end up with disastrous performance under X11 due to overdriving the poor CPU with software GL rasterization.

While it is easy to blame Qt, JavaScript VMs, scripting languages, C++, and everything but the kitchen sink when one's Quick application runs slowly, the solution to figure out the root cause is often even easier: QSG_INFO=1.

That's all for now. Take care, and make sure to check the output from QSG_INFO=1 next time.

The post Which OpenGL implementation is my Qt Quick app using today? appeared first on Qt Blog.

18 Jan 2017 3:54pm GMT

KDE Flatpak portals introduction

I guess you all have heard about Flatpak, Snappy and sandboxing in general. Flatpak is a new way of distributing applications. With Flatpak applications are running in sandbox, which means they are isolated from the rest of your system. With that in mind you need a way how to access some stuff outside the sandbox, like your files or have access to your hardware. To solve this problem the Flatpak developers came up with portals. Portals are high-level session bus APIs that provide access to resources to sandboxed applications. Idea is that there is one DBus service available and visible for the sandboxed application which is supposed to communicate with it to get access outside the sandbox. Then this one service communicates with backend implementations which may be different per desktop so you have in example a Gnome implementation or in my case KDE implementation. The backend then provides dialogs so users can access files or hardware outside the sandbox. To add portal support you need to add your backend implementation, which is quite easy part and if you don't have any then one from other available ones will be used. Complicated part is to alter the framework the application is using to use the portal DBus service instead of doing what it usually do (e.g. when opening a file dialog you want to send a request over DBus instead of actually displaying the dialog). I've been playing with this for some time and I tried to cover the most common or required portals. Let's go through all of this:

File chooser portal

I think this is the most common and needed portal from all of them. I've added a backend implementation as well as support for this to Qt in form of my own Qt platform plugin. Given you can modify Qt's behaviour using your own Qt platform plugin then I didn't have to modify Qt at all. The platform plugin alters FileDialog to talk around DBus instead of showing the dialog. The dialog is then shown thanks to the backend implementation and user running app in sandbox shouldn't notice any difference. The file chooser portal supports both opening and saving files with possibilities to set properties like filters, accept label text etc. which are all already implemented in both like in the platform plugin and the backend.

App chooser portal

This portal allows the user to select an application outside the sandbox which should be used for opening a document, a file or whatever. It is also used when opening an url. On the backend side this is just a simple dialog with list of possible applications associated with given file/document type. On Qt side I added my own implementation of OpenUrl() again into the platform plugin to make it transparent the same way the file dialog works.

Print portal

I guess the most complicated and also quite important portal. I've been able to add just backend implementation so far which will be used for printing from gtk applications as gtk already supports printing from sandbox. The idea behind this portal is that when app requests to print a document, it calls PreparePrint() method and the backend presents classic print dialog to the user where he can configure printer, setup the page and paper and so on. This configuration is then passed back to the application where the framework is supposed to create a pdf or ps file already pre-formatted and ready for printing. This file is then passed as file descriptor again to the backend using Print() method and printed. This all works with Qt backend and gtk app, or Gnome backend and gtk app, but unfortunately not yet with Qt apps as I still don't know how to do this without touching Qt code as this cannot be done on platform plugin level, at least from what I can see. A simple solution can be to don't touch Qt at all and let the app print the document to file and have a simple utility sending this file through the portal to print it. As you can set application name which should be used for printing in QPrinter, then we maybe can just set this automatically when the app is running in sandbox to make this work automatically. I'm definitely open to your ideas or any help :).

Notification portal

Again very useful portal and not that complicated. I have full backend implementation presenting a notification outside the sandbox when someone calls AddNotification() method. To make this work for KDE applications automatically I had to modify KNotifications framework and implement my own flatpak plugin which replaces NotifyByPopup plugin. All this plugin does instead displaying a popup it calls the portal DBus service which then calls AddNotification() in my backend and presents notification outside the sandbox. Both the plugin and backend supports also sending back information about triggered action so you can also get feedback back to the sandboxed application.

Those are all the portals I have fully or partially covered so far. There are of course more portals designed in Flatpak portal API, like screenshot portal, inhibit portal, but for some of them we don't have any framework/API or they are not that important so they will be added later. I also have a test application which you can run in sandbox and test all the portals.

How to use flatpak portals

In order to use flatpak portals, either my implementation or the Gnome one, you need to install xdg-desktop-portal which is the main portal DBus service visible to sandboxed applications and which calls backend implementation. For gtk implementation you need xdg-desktop-portal-gtk and for KDE/Qt implementation you need xdg-desktop-portal-kde. This is required to be installed outside the sandbox to present dialogs for file and hardware access. To add support for portals to your sandboxed application you should be fine already with gtk, with Qt and KDE you need my Qt platform plugin and my modifications made to KNotifications. To use those you need to modify flatpak manifest to include them during build so they are available in the sandbox. You can get inspiration in my test app manifest. And finally to use my platform plugin as KNotifications will be used automatically you need to start your app using flatpak run your_app -platform flatpak.

I guess that's all from me today. Patches and improvements are warmly welcomed as well as any reported issue. If you want some information about Flatpak and KDE in general, we have setup a wiki page where you can find information about KDE runtimes and applications packaged for Flatpak. There will be also a talk at FOSDEM this year about Flatpak and KDE from Aleix Pol.

18 Jan 2017 9:58am GMT

Get Yourself on www.kde.org

Google Code-in has just finished where school pupils do tasks to introduce themselves to open development. I had one to update the screenshots on www.kde.org. The KDE website is out of date in many ways but here's a wee way to fix one part of it. Despite me having about half a dozen students work on it there's still some old screenshots there so if anyone wants the satisfaction of contributing to www.kde.org's front page here's an easy way.

www.kde.org has screenshots of all our apps but many still use the old KDE 4 Oxygen widget theme and icons.

For 10 screenshots which is using the old theme take a new screenshot using the new theme.

They can be checked out from Subversion here https://websvn.kde.org/trunk/www/sites/www/images/screenshots/ also provide one the resized screenshot which is 400 pixels wide exactly.

Keep the filenames the same and in lower case.

Upload as a single .zip or .tar.gz containing the screenshots with the right file name and a folder resized/ with the 400px screenshots

For bonus points you could go through the index file to make sure it's current with KDE applications https://www.kde.org/applications/index.json

Facebooktwittergoogle_pluslinkedinby feather

18 Jan 2017 9:50am GMT

17 Jan 2017

feedPlanet KDE

Happy Birthday ownCloud

Seven years ago at Camp KDE in San Diego, Frank announced a project to help people protect their privacy, building an alternative to Dropbox: ownCloud.

I was there, sharing a room with Frank at the infamous Banana Bungalow. Epic times, I can tell you that - there was lots of rum, lots of rain and loads of good conversations and making new friends.





Since then, a lot has changed. But the people who started building a self-hosted, privacy protecting alternative in 2010 and 2011 are still on it! In 2011, a first meetup was held, and the 5 participants at that meetup recently got on stage at the Nextcloud conference to recall some good memories:



Of course, today we continue the work at Nextcloud, that just yesterday published its latest bugfix- and security update. It is great to see so many people have stuck with us for all these years - just this month, the KDE sysadmins migrated their ownCloud instance to Nextcloud!

We'll keep up the good work and you're welcome to join, either if you're looking for a job or just want to code. In both cases I can promise you: working with such a motivated, dedicated, professional team is just plain amazing.

I also published a blog on our Nextcloud blog about this milestone.

EDIT: By the way - there's a meetup tonight in C-Base, B'lin, 19:00 - would be fun to drink a beer on ownCloud's birthday and talk about the future! Join! It will be at least until 10 or so, so if you can't be there before then - still come! ;-)

17 Jan 2017 5:36pm GMT

#3 Update on the extractors

Update: Both Flipkart and Amazon Extractor (Python) with fine, expect for the fore-mentioned issue.

The purpose for which i made the python extractors, give quite accurate results. Parsing the email, to find the appropriate data was quite fun, but what worries me is the longevity of the semi-sketchy methods to extract the data.

Scrapely worked beautifully, but there were some unironed kinks which need attention while parsing the information.

{   "id" : "OE1004125T3442...",
    "total": "Rs. 310",
    ...
    ...
    "name":"<div><span><b><a href="http:// .../../..">ProductName</a></b></span></div>"
}

We can see here that the value of "name" is messed up a bit.
The desired result that was needed was:

{"name" : "ProductName"}

Yeah well, for now there was only way which came into my mind to parse this, was some sketchy method . But rest assured, everything else works fine.

17 Jan 2017 1:26pm GMT

16 Jan 2017

feedPlanet KDE

KBibTeX 0.6.1-rc2 released

After quite some delay, I finally assembled a second release candidate for KBibTeX 0.6.1. Version 0.6.1 will be the last release in the 0.6.x series.

The following changes were applied since the release of 0.6:

( Read more to learn which changes were applied )

comment count unavailable comments

16 Jan 2017 10:04pm GMT

15 Jan 2017

feedPlanet KDE

Calligra 3.0 released

A new wonderful era for the Calligra Suite has begun with the release of version 3.0.

Support Calligra!

We have chosen to cut back on the number of applications. Krita has left us to be independent and although it was emotional it was also done with complete support from both sides. We are saying goodbye to Author, which never differentiated itself from Words. We also removed Braindump the purpose of which will be better fitted by a new application (nothing planned from our side). Flow and Stage has gone in this release but we intend to bring them back in the future. And Kexi has own release schedule but is still part of the Calligra community.

What's New?

The 3.x series is built on top of KDE frameworks 5 and Qt5 which in and of itself doesn't bring much new but it ensures that we stay current. It took a lot of effort which means we haven't made many other new features.

15 Jan 2017 2:08pm GMT

FirstAid – PDF Help Viewer

Hi,

in the recent months, I didn't find much time to spend on Kate/KTextEditor development. But at least I was now able to spend a bit more time on OpenSource & Qt things even during work time in our company. Normally I am stuck there with low level binary or source analysis work.

For our products, we were in the need of some online help. As our documentation is delivered as PDFs generated by the tools of the TeX Live distro, a natural idea was to use some PDF viewer and integrate it more tightly in our software than just "open the manual at page 1".

We did review PDF viewers out there, but most (like Okular) have too many dependencies to be just bundled with our product (or a license not permitting that).

Without bundling, we can't ensure that the tight coupling is working, without starting to test the integration with X different viewers which more or less all need other kinds of command line arguments to open the right page or even lack that feature or will not reuse an already running instance, ….

Therefore, as our GUIs are developed with Qt anyways, we did take a look at libpoppler (and its Qt 5 bindings), which is the base of Okular, too.

Easy enough, taking the small demo program shipped with the library and adding a small stdin based interface to tell it "goto <named reference>" we arrived at some small PDF viewer that is fit enough for our use case.

We named the thing "FirstAid", the sources can be grabbed at github.com/AbsInt/FirstAid. Like libpoppler and the demo, its licensed as GPLv2+.

As already the README states, the aim of this small project is not to replace some full fledged viewer like Okular, the design goal is to have a small viewer that is auto-started by some host application and will jump to the requested labels for a tightly coupled online help. It can be used as a pure standalone PDF viewer, too, but that is more intended for testing it e.g. on the documents that should later be shown as online help.

FirstAid

I already annoyed Albert with some small issue I had with libpoppler, perhaps I will provide more useful fixes in the future if more things come up during FirstAid development. In any case, already THANKS A LOT for the Qt 5 bindings around libpoppler, they work nicely for us!

I really think this small project shows the benefit of OpenSource: We needed a PDF viewer, we were able to create a small one in less than a month based on OpenSource libraries and we can give back the results to the community (if it is useful for others is a different story, but perhaps other people have the same itch to scratch, if not, ignore it). I hope more possibilities for such things come up at work in the future.

For building: It should build out of the box if you have some recent Qt and libpoppler-qt5-dev installed, at least the Travis CI is able to build it out of the box with the given config. For me, it shows some small bugs if used with Qt 5.6/7 compared to the Qt 5.8 Beta I used here for testing.

15 Jan 2017 1:18pm GMT