jump to navigation

How to (not) Activate or Deactivate Widgets (or any other thing) October 29, 2015

Posted by tumaix in planetkde-tomazcanabrava.
7 comments

Looking at the source code of a few programs while I was hunting for things to do I found similar patterns to this one:

	QAction *action = new QAction("Action Name Here", this);
	connect(action, &QAction::triggered, this, &MainWindow::viewActionTriggered);
	actionList << action; 
        for(QAction *action : actionList) { 
             mapWidgetAction[action->text()] = createWidget(action->text());
	}
	MainWindow::viewActionTriggered() {
		QSettings settings;
		QAction *action = qobject_cast<QAction*>(sender());
		if (action->text() == "Widget 1") {
			widget1->show();

		} else if (action->text() == "Widget 2") {
			widget2->show()
		} else if (action->text() == "Widget 3") {
			widget3->show();
		}
		s.setValue("visibleWidget", action->text());
	}

Now, looking at this particular code it’s simple to see what could be wrong: the Widget Title could be translated to another language and the comparissons would fail, or the text of the widget could have an ‘&’ to create an accelerator and the comparisson would also fail, you could change your language and when opening the application it could also fail, there are actually tons of possible errors with that approach.

One of the possibilities is to use the data() member of QAction to store a untranslated string, and use that as comparator:

	QAction *action = new QAction("Action Name Here", this);
	action->setData("Widget 1");
	connect(action, &QAction::triggered, this, &MainWindow::viewActionTriggered);
	actionList << action; 
        for(QAction *action : actionList) { 
           mapWidgetAction[action->text()] = createWidget(action->text());
	}
	
	[snip]

	MainWindow::viewActionTriggered() {
		QSettings settings;
		QAction *action = qobject_cast<QAction*>(sender());
		if (action->data().toString() == "Widget 1") {
			widget1->show();

		} else if (action->data().toString() == "Widget 2") {
			widget2->show()
		} else if (action->data().toString() == "Widget 3") {
			widget3->show();
		}
		s.setValue("visibleWidget", action->data().toString());
	}

But that second approach has also tons of flaws: I’m not caching the QString returned, I’m returning a QString while I could have used a QByteArray(much faster for non-utf8 stuff), I could have used something that doesn’t use multiple cpu-cycles to tell me if it’s true or not. Now, third try:

	enum WidgetTypes { WIDGET_1, WIDGET_2... , WIDGET_X };
	QAction *action = new QAction("Action Name Here", this);
	action->setData( WIDGET_1 );
	connect(action, &QAction::triggered, this, &MainWindow::viewActionTriggered);
	actionList << action; 
        for(QAction *action : actionList) { 
             mapWidgetAction[action->text()] = createWidget(action->text());
	}
	
	[snip]

	MainWindow::viewActionTriggered() {
		QSettings settings;
		QAction *action = qobject_cast<QAction*>(sender());
		switch(action->data().toInt()) {
		case WIDGET_1 : widget1->show(); break;
		case WIDGET_2 : widget2->show(); break;
		...
		case WIDGET_X : widget3->show(); break;
		}

		s.setValue("visibleWidget", action->data().toInt());
	}

By changing the key of the Widget to an enum I’m having the following benefits

  1. Not Comparing Strings, but comparing integers (much faster)
  2. Not having issues with collation
  3. simplifying my code (switch vs if’s with string comparissons)
  4. behaving correctly even if I change the system’s language
  5. now, I know that this is something that seems easy enougth to catch, but since I loocked this in three different softwares already this week I think it’s worth saying.

 

Now, if there’s anything wrong in what I said, please correct me as we can only improve by learning something new. ­čÖé

Subsurface 4.5(.1) Released October 28, 2015

Posted by tumaix in planetkde-tomazcanabrava.
add a comment

Subsurface 4.5 (and Subsurface 4.5.1)  just got released

 

subsurface1

This was one mounstrous huge amount of work: Three successfull Summer of Code projects got merged onto subsurface code, a *ton* of work from quite a few hackers that had nothing better to do than to create an awesome dive log.

subsurface4

We managed to get a lot of wishes and bugfixes on this version:

  • Subsurface now uses Grantlee to print the dive templates
  • Git for remote file storage
  • Automatic Geo Coordinates Name Retrieval for Dive Sites
  • (Experimental) Android UI
  • *TONS* of bugfixes and code cleanups
  • Dive Computer Management from within subsurface

subsurface3
Since the Move from Gtk to Qt almost two and a half years ago Subsurface has gained a boost in productivity that’s very, *VERY* visible:

2109 commits by git’s counting, That’s the most we ever had between two major releases (for comparison, the switch from Gtk to Qt (3.1->4.0) was only 1643 commits.

Let me Quote Dirk Hohndel,

“What’s interesting is how many new people are in this list. GSoC students, but also quite a few others who haven’t contributed before. 35 people sent at least one commit, 20 sent more than 10 commits. For comparison, from the start of Subsurface until the last Gtk release (3.1.1) only 15 different developers had 10 or more commits.”

subsurface2

Here is the Detailed commit list for Subsurface 4.5:

Dirk Hohndel, Tomaz Canabrava, Miika Turkia, Gehad Elrobey, Robert Helling, Anton Lundin, Grace Karanja, Lubomir I. Ivanov, Rick Walsh, Claudiu Olteanu, Salvador Cu├▒at, Guido Lerch, Willem Ferguson, Joakim Bygdell, Jan Darowski, Linus Torvalds, Guillaume GARDET, Sergey Starosek, Marcos CARDINOT, Sander Kleijwegt, Patrick Valsecchi, Sebastian K├╝gler, Gaetan Bisson, Tim Wootton,┬á Henrik Brautaset Aronsen, Thiago Macieira, Venkatesh Shukla, Giorgio Marzano, Martin Long, Paul-Erik T├Ârr├Ânen, pestophagous, Jan Mulder, Pedro Neves, Torstein Huseb├Ş, Yousef Hamza

A huge Thank You ÔŁĄ You rock.
You guys can know more about subsurface in it’s official homepage: http://www.subsurface-divelog.org