Imagine we want an editor that has undo and redo capability. But the operations on the editor are all asynchronous. This implies that also undo and redo are asynchronous operations.
Planet maemo

Dear friends and Maemoans. It is again the time for us to elect the new Community Council.
The schedule for the voting process is as follows:
- The nomination period starts next Monday, on the 1st of May 2017 and will continue until the 23rd of May 2017.
- The election starts on Thursday, on the 1st of June 2017 and will continue until the 7th of June 2017. In order for us to keep the community strong, we need to have new people with fresh ideas to carry on the torch. So, please consider volunteering for the position of Maemo Council.
On behalf of the outgoing Community Council,
eekkelund
As mentioned in my Working on Android post, I’ve been using a mechanical keyboard for a couple of years now. Now that I work on Flowhub from home, it was a good time to re-evaluate the whole work setup. As far as regular keyboards go, the MiniLa was nice, but I wanted something more compact and ergonomic.
Combining QFuture with QUndoCommand made a lot of sense for us. The undo and the redo methods of the QUndoCommand can also be asynchronous, of course. We wanted to use QFuture without involving threads, because our asynchronosity is done through a process and IPC, and not a thread. It’s the design mistake of QtConcurrent‘s run method, in my opinion. That meant using QFutureInterface instead (which is undocumented, but luckily public – so it’ll remain with us until at least Qt’s 6.y.z releases).
So how do we make a QUndoCommand that has a undo, and that has a redo method that returns a asynchronous QFuture<ResultType>?
We just did that, today. I’m very satisfied with the resulting API and design. It might have helped if QUndoStack would be a QUndoStack<T> and QUndoCommand would have been a QUndoCommand<T> with undo and redo’s return type being T. Just an idea for the Qt 6.y.z developers.
Among the problems we’ll face is that we want asynchronous APIs that are undoable and that we want to switch to read only, undoable editing, non-undoable editing and that QML doesn’t really work well with QFuture. At least not yet. We want an interface that is easy to talk with from QML. Yet we want to switch between complicated behaviors.
Perfection has been reached not when there is nothing left to add, but when there is nothing left to take away.

I've been bicycling all my life, and its one of the very few things I miss here in Venice. Berlin, on the other hand, is full of bicycles.
The post Bicycles in Berlin appeared first on René Seindal.

Berlin 25 years later could just as well be another city.
The post Berlin 25 years later appeared first on René Seindal.
Imagine you have a duck. Imagine you have a wall. Now imagine you throw the duck with a lot of force against a wall. Duck typing means that the duck hitting the wall quacks like a duck would.
ps. Replace wall with API and duck with ugly stupid script written by an idiot. You can leave quacks.
First one should ask though: why? My main motivation was that many of the apps I use were easily available in the nextcloud store, while with owncloud I had to manually pull them from github.
Additionally some of the app authors migrated to nextcloud and did not provide further updates for owncloud.
Another reason is this:
the graphs above show the number of commits for owncloud and nextcloud. Owncloud has taken a very noticeable hit here after the fork – even though they deny it.
From the user perspective the lack of contribution is visible for instance in the admin interface where with nextcloud you get a nice log browser and system stats while with owncloud you do not. Furthermore the nextcloud android app handles Auto-Upload much better and generally seems more polished – I think one can expect nextcloud to advance faster in general.
MigratingFor migrating you can follow the excellent instructions of Jos Poortvliet.
In my case owncloud 9.1 was installed on Ubuntu in /var/www/owncloud and I put nextcloud 11 to /var/www/nextcloud. Then the following steps had to be applied:
- put owncloud in maintenance mode
sudo -u www-data php occ maintenance:mode --on
- copy over the config.php
cp /var/www/owncloud/config/config.php /var/www/nextcloud/config/
- adapt the path in config.php
# from 'path' => '/var/www/owncloud/apps', # to 'path' => '/var/www/nextcloud/apps',
- adapt the path in crontab
sudo crontab -u www-data -e
- adapt the paths in the apache config
- run the upgrade script which takes care of the actual migration. Then disable the maintanance mode.
sudo -u www-data php occ upgrade sudo -u www-data php occ maintenance:mode --off
and thats it.
Back in 2013 I was working exclusively on an Android tablet. Then with the NoFlo Kickstarter I needed a device with a desktop browser. What followed were brief periods working on a Chromebook, on a 12” MacBook, and even an iPad Pro.
MyPlugin/MyPlugin.cpp:
#include <ViewModels/MyListClass.h> #include <ViewModels/DisplayViewModel.h> qmlRegisterUncreatableType<MyListClass>( a_uri, 1, 0, "MyListClass", "Use access via DisplayViewModel instead"); qmlRegisterType<DisplayViewModel>( a_uri, 1, 0, "DisplayViewModel");
Utils/MyQMLListUtils.h
#define MY_DECLARE_QML_LIST(type, name, owner, prop) \ QQmlListProperty<type> name(){ \ return QQmlListProperty<type>( \ this, 0,&owner::count ## type ## For ## name ## List, \ &owner::at ## type ## For ## name ## List); \ } \ static int count ## type ## For ## name ## List(QQmlListProperty<type>*property){ \ owner *m = qobject_cast<owner *>(property->object); \ return m->prop.size(); \ } \ static type *at ## type ## For ## name ## List( \ QQmlListProperty<type>*property, int index){ \ owner *m = qobject_cast<owner *>(property->object); \ return m->prop[index]; \ }
ViewModels/DisplayViewModel.h
#ifndef DISPLAYVIEWMODEL_H #define DISPLAYVIEWMODEL_H #include <QObject> #include <QtQml> #include <ViewModels/MyListClass.h> #include <Utils/MyQMLListUtils.h> class DisplayViewModel : public QObject { Q_OBJECT Q_PROPERTY(constQString title READ title WRITE setTitle NOTIFY titleChanged ) Q_PROPERTY(constQList<MyListClass*> objects READ objects NOTIFY objectsChanged ) Q_PROPERTY( QQmlListProperty<MyListClass> objectList READ objectList NOTIFY objectsChanged ) public: explicit DisplayViewModel( QObject *a_parent = nullptr ); explicit DisplayViewModel( const QString &a_title, QList<MyListClass*> a_objects, QObject *a_parent = nullptr ); const QString title() { return m_title; } void setTitle( const QString &a_title ); const QList<MyListClass*> objects () { return m_objects; } Q_INVOKABLE void appendObject( MyListClass *a_object); Q_INVOKABLE void deleteObject( MyListClass *a_object); Q_INVOKABLE void reset( ); protected: MY_DECLARE_QML_LIST(MyListClass, objectList, DisplayViewModel, m_objects) signals: void titleChanged(); void objectsChanged(); private: QString m_title; QList<MyListObject*> m_objects; }; #endif// DISPLAYVIEWMODEL_H
DisplayViewModel.cpp
#include "DisplayViewModel.h" DisplayViewModel::DisplayViewModel( const QString &a_title, QList<MyListClass*> a_objects, QObject *a_parent ) : QObject ( a_parent ) , m_title ( a_title ) , m_objects ( a_objects ) { foreach (MyListClass* mobject, m_objects) { mobject->setParent (this); } } void DisplayViewModel::setTitle (const QString &a_title ) { if ( m_title != a_title ) { m_title = a_title; emit titleChanged(); } } void DisplayViewModel::reset( ) { foreach ( MyListClass *mobject, m_objects ) { mobject->deleteLater(); } m_objects.clear(); emit objectsChanged(); } void DisplayViewModel::appendObject( MyListClass *a_object ) { a_object->setParent( this ); m_objects.append( a_object ); emit objectsChanged(); } void DisplayViewModel::deleteObject( MyListClass *a_object ) { if (m_objects.contains( a_object )) { m_objects.removeOne( a_object ); a_object->deleteLater(); emit objectsChanged(); } }
Tester.cpp
#include <ViewModels/DisplayViewModel.h> #include <ViewModels/MyListClass.h> QList<MyListClass*> objectList; for( int i = 0; i < 100 ; ++i ) { objectList.append ( new MyListClass (i) ); } DisplayViewModel *viewModel = new DisplayViewModel (objectList); viewModel->appendObject ( new MyListClass (101) );
Display.qml
import QtQuick 2.5 import MyPlugin 1.0 Repeater { property DisplayViewModel viewModel: DisplayViewModel { } model: viewModel.objectList delegate: Item { property MyListClass object: modelData Text { text: object.property } } }