Hello,
Telepathy-butterfly 0.5.5 has just been released, along with telepathy-python 0.15.16 and papyon 0.4.5.
Butterfly is the MSN connection manager, the "back-end" for MSN, for the Telepathy IM and VoIP framework. Telepathy python is a convenience module to use telepathy and papyon is a python MSN library.
Sadly in this release we had to disable the Audio/Video calls which were broken since Microsoft removed the necessary servers. For more informations on the subject I invite you to read Kakaroto's post
On the good news this release should resolve the issues with the lost messages thanks to William Grant excellent investigation of the issue and it should also fix some other annoying bugs.
This new papyon release don't display the password in the logs any more so I recommend using this version if you want to submit bug reports.
Hopefully the next butterfly release will bring you the long awaited File Transfer support. We will also have proper multi-user chat thanks to Jonny Lamb implementing the conference interface.
Hi all,
The PiTiVi development team is thrilled to announce a new release of the PiTiVi video editor.
Amongst the new features:
More info in the release notes , tarballs available on ftp.gnome.org and should be available on your distros any time soon (will be included in Lucid Lynx).
Update : The gstreamer-developers PPA has been updated for Ubuntu Karmik with 0.13.4 and all required dependencies : https://launchpad.net/~gstreamer-developers/+archive/ppa
by Robin Burchell (noreply@blogger.com) at March 09, 2010 11:15 PM
As some of you might have noticed, we’ve now released aMSN 0.98.3! Another bugfix version, but this time also removing completely the Audio/Video functionality because of the reasons previously explained.
Enjoy!
by Tomeu Vizoso (noreply@blogger.com) at March 06, 2010 10:38 AM
by Robin Burchell (noreply@blogger.com) at March 04, 2010 10:34 PM
While GStreamer has been working on Windows for a long time and one can compile GStreamer using Visual Studio, the lack of pre-made binaries for Windows developers has been a bit of an issue. Various groups and people have tried providing windows binaries for a while, but most efforts have stalled after a short while. The GStreamer winbuilds project however seems quite solid however and have now been doing good windows packages for quite a while. If you have been looking for Windows builds for GStreamer this is a good place to start. They already have a list of users on Windows and the reason I became aware is that the jokosher guys are using it for their windows porting effort.
I work out of coffee shops. It just depresses me to sit at home and not see a living soul all day besides the occasional house-mate.
There is one shop that really allows me to get into my zone. It might have something to do with the liquor license, the ping pong table and loud music. The problem is, they somehow blocked all non-web traffic on their wifi hotspot. Since my day primarily revolves around IRC, XMPP, SMTP and SSH, I really can’t sit there for too long before I need to find somewhere that will allow me to push my git changes.
So I thought I was being all clever when I set up OpenVPN on my private server and configured it to listen on TCP port 443. Does anyone have tips for tunneling arbitrary protocols through port 80/443? I thought the OpenVPN setup was especially nifty because it only required one NetworkManager click.
Decided to join the early adopters crowd today and use the desktop of the future by switching to using GNOME Shell on my desktop. Luckily with Fedora its dead simple, you just yum install gnome-shell and then switch using the desktop effects widget under Preferences. Scarily simple.
So far GNOME shell has been very stable for me and the user experience has been mostly good. Still feels a little alien compared to what I was used to before, but nothing annoyingly alien. Only irritant so far is that the clock on the shell is using the luddite AM/PM time system instead of the proper 24H clock and I can’t figure out how/where to fix it.
Will report back next week if I decided GNOME shell is here to stay on my desktop or if its still needs some more love before I am ready to let it rule my life.
...
- I have to narrow my focus on the goals I have for the children. Objectives will include:
The children will generate a list of responsibilities a QA engineer, or “tester” has;
The children will generate a list of what makes a good QA engineer;
The children will write about their experience – not only about what they figured things out, but also how they did it.
The children will provide feedback for future SoaS deployment or pilots.
...
by Tomeu Vizoso (noreply@blogger.com) at March 03, 2010 10:32 AM
From now on to the next Sugar release in about 6 months (0.90), I'm going to be working on improving the collaboration stack in Sugar, graciously sponsored by Collabora. Collabora employees developed almost all of the collaboration code in Sugar, and are the main force behind the Telepathy framework, on which Sugar's collaboration is based. Though pervasive collaboration is one of the major features of Sugar, it hasn't been funded for a long time and there's large room for improvement, also due to the new developments in Telepathy. My work will aim to make presence and collaboration more reliable and to put the pieces in place for enriching the experience with the new features in Telepathy.by Tomeu Vizoso (noreply@blogger.com) at March 03, 2010 10:26 AM
Hey,
We (the aMSN team) want to soon release aMSN version 0.98.2 because of the various issues we faced with 0.98.1 because Microsoft changed their protocols.. mainly the problem with the nickname changing to the email at every connection.
We also recently realized that the Audio/Video capability would need to be dropped because it just doesn’t work anymore unfortunately
Microsoft forced everyone to upgrade to the latest version of Windows Live Messenger : WLM 2009 which uses MSNP18 and has the ability to do Audio/Video calls through a tunneled SIP (P2P SIP messages, not using an external SIP server) and so, they realized that their SIP servers aren’t being used anymore, so they had this great idea of shutting down their servers… the result? aMSN can’t do Audio/Video calls because the SIP server refuses our connections.
Now we have two choices, either use MSNP18, or disable SIP calls completely. Obviously, we can’t move to MSNP18 at the moment, because MPOP support isn’t really ready yet, and because MSNP2PV2 hasn’t been implemented, so we had to remove the Audio/Video support in aMSN SVN for now, and only have it available for those who are brave enough to try out MSNP18.
We will soon release 0.98.2 as it is long overdue now, and we want to let people know why their A/V calls are not available to them anymore.
I hope everybody will understand why this is happening and we won’t get flooded by n00b questions everyday…
The reason I haven’t been around as much in the last few weeks:
Everybody’s doing great, our friends and neighbors have been spoiling us with delicious meals, and he’s been a remarkably content baby so far.
# -*- coding: utf-8 -*-
# Written by Robin Burchell
# No licence specified or required, but please give credit where it's due,
# and please let me know if this helped you. Feel free to contact with corrections or suggestions.
#
# We're using PySide, Nokia's official LGPL bindings.
# You can however easily use PyQt (Riverside Computing's GPL bindings) by
# commenting these and fixing the appropriate imports.
from PySide.QtCore import *
from PySide.QtGui import *
#from PyQt4 import *
#from PyQt4.QtCore import *
#from PyQt4.QtGui import *
import sys
# As always, Qt allows us to subclass objects to override behaviour and generally monkey around
# with them how we want. This is the exact way that custom widget painting operates:
# you subclass the widget that you want as your base, and override paintEvent() to do your own painting.
class CustomWidget(QWidget):
# We're taking a number and displaying it twice in different formats. Nothing complicated.
def __init__(self, parent, anumber):
QWidget.__init__(self, parent)
# store the passed number
self._number = anumber
# This is where our custom painting happens. Qt calls paintEvent() whenever this widget needs
# to repaint itself.
#
# If you ever need to force a widget to repaint, which you will if you e.g. change any data the widget
# displays, you shouldn't invoke paintEvent manually: instead, you should use QWidget::update().
# For more information on invoking a repaint, see:
# http://doc.trolltech.com/4.6/qwidget.html#update
#
# For more information on paintEvent, see:
# http://doc.trolltech.com/4.6/qwidget.html#paintEvent
def paintEvent(self, ev):
# We first need to create a painter. Think of the painter as the brains of the rendering operation:
# they control the pen, and the brush, in order to do the actual drawing operations. More on them later.
#
# We pass 'self' to QPainter so it knows what it is painting on.
# You can also use QPainter::begin() and QPainter::end(), but this method is easier since it will
# automatically end() when it deallocates.
# See also:
# http://doc.trolltech.com/4.6/qpainter.html
p = QPainter(self)
# Simple operation here. Let's paint the background spotted red, so we can see that painting
# is actually occuring. This will look hideous, but feel free to experiment.
#
# This demonstrates the first use of QBrush - QBrush is used for any fill operations performed
# by QPainter. In terms of painting a picture, think of it like this: a painter will pick up a brush
# to paint broad strokes of the background etc.
#
# QBrush is very versatile, you can do all sorts of things with it like drawing textures.
# For more information on QBrush, see:
# http://doc.trolltech.com/4.6/qbrush.html
#
# This also demonstrates another aspect of the painting system: that of rects. Painting in Qt is done
# around the concept of small areas where painting occurs, we're using a convenience method here (QWidget::rect())
# to get the entire area of the widget, but you can define and adjust rects yourself.
# We'll go into more detail on that another time.
# For more information on QRect, see:
# http://doc.trolltech.com/4.6/qrect.html
p.fillRect(self.rect(), QBrush(Qt.red, Qt.Dense2Pattern))
# Now, we're going to draw the number we were passed. This won't be using the brush, but the
# pen: more on that later. Let's just draw some text in the middle left of the widget for now.
# Thankfully, Qt provides a way to do this for us, so we don't need to do any work on adjusting the rect.
# For more information on drawing text, see:
# http://doc.trolltech.com/4.6/qpainter.html#drawText
p.drawText(self.rect(), Qt.AlignLeft | Qt.AlignVCenter, str(self._number))
# Now, let's draw a different number (just for demonstration purposes) with a different colour.
# To do this, we first need to set a new pen - but now you're probably wondering what that is.
#
# A pen is, like it's real world counterpart, used to draw fine detail, like text, lines, and outlines.
# It is the emphasis, where the brush is the background.
# For more information on QPen, see:
# http://doc.trolltech.com/4.6/qpen.html
#
# QColor is fairly simplistic here, so I won't go into it. We're just using the RGB constructor to create
# a grey color.
# For more information, see:
# http://doc.trolltech.com/4.6/qcolor.html#QColor-2
p.setPen(QColor(220, 220, 220))
# Now we've set our grey pen, let's take the value we have, multiply it by two, and draw it on the right hand
# side of the widget.
p.drawText(self.rect(), Qt.AlignRight | Qt.AlignVCenter, str(self._number * 2))
class MyMainWindow(QMainWindow):
def __init__(self, parent):
QMainWindow.__init__(self, parent)
# Add content
central = CustomWidget(self, 666)
self.setCentralWidget(central)
if __name__ == '__main__':
app = QApplication(sys.argv)
sw = MyMainWindow(None)
sw.show()
app.exec_()
sys.exit()
by Robin Burchell (noreply@blogger.com) at March 01, 2010 11:38 AM
by Tomeu Vizoso (noreply@blogger.com) at February 26, 2010 04:31 PM
So due to sometimes needing to run a few Windows applications I have a Windows Vista partition on my hard drive. Today I decided to upgrade it to Windows 7 using the upgrade media Lenovo had sent me. So one would assume that upgrading a Vista partition which was the original Vista installation my laptop came with and that I had almost nothing installed on would be simple and straight forward. Wrong. Very wrong. I ended up on a screen with a absolutely useless error message saying that the upgrade failed due to an error and I should try again later. Brilliant. What made it even more fun was that there was another field listing applications which might malfunction after the upgrade. Due to the useless language above I assumed those concrete applications was the actual problem so I started an effort to try to deinstall said applications. One would think that would be a simple process, but as it turned out, some of them I still got complaints about even after deinstalling them….brilliant. First batch of 3-4 wasted hours gone.
Finally I gave up on the upgrade and re-installed Windows 7 instead. Install went fine, but of course the Windows bootloader overwrote grub. Not a to big of a hassle as I was able to restore it quickly enough with the Fedora rescue disk. Or so I thought. It turns out there is some weird kind of installation activation checking in the Windows 7 bootloader, which means that when I tried to use grub it failed giving me a error about my installation probably having been attacked by malicious software and thus refusing to let me boot into windows.
So after 3-4 hours later again and after getting the beta version of a windows boot loader editing application I finally had my system working again, this time booting from the windows bootloader into grub for my linux partition.
Conclusion: Claims of Windows being an enterprise ready and user friendly commercial operating systems turns out to be highly overstated.

by Tomeu Vizoso (noreply@blogger.com) at February 24, 2010 06:33 PM
We just went to lunch today and decided to try out the new Jamie Oliver restaurant in town. Think the general consensus was that is was a disappointment. Nothing inherently wrong with the food, just that it tasted a bit bland, and when you go to a restaurant where a famous chef has put his name on the door you do not expect bland.
Been following the news and discussion about Google and their recent acquisition of on2. For those who doesn’t know On2 is a codec company that created such codecs as VP3 (which become Theora) and VP6 which became Flash video. Their latest codec is VP8 which they claim is comparable to H264 in terms of quality.
The big question of course is what Google plans on doing with On2 and the codec acquired. I guess there are two likely routes Google could be going. One is to try to create some kind of vendor lock in with Youtube offering higher quality video using VP8 for Google clients like Android and Chrome. The other is that they want to remove the dependency on proprietary video formats on the web and will thus release VP8 as open source in a similar vein to Theora and Dirac. If they combine that with youtube offering high quality HTML5 videos in VP8 combined with ensuring that Firefox and Opera supporting the format in addition to Chrome then it could be a big move. Silvia Pfeiffer got some good thoughts and comments on the subject in her blog, including interesting comments from Monty and former On2 employee Dan.
From a Collabora Multimedia viewpoint we would of course love to add support for liberated On2 codecs in GStreamer, so if anyone from Google is reading this, just know that we would happily help you implement the needed GStreamer plugin code to get these codecs supported in GStreamer and the linux desktop.
Since my last post I have worked on applying a similar approach of making HTTP range requests to obtain indexes necessary for seeking in the Flash Video format version 1 (‘old’ FLV, if you will) and AVI (both legacy and ODML) in GStreamer.
Legacy AVI was fairly straightforward as we only need to do one seek to get the index. ODML AVI was somewhat messy because we had to perform multiple seeks as there can be multiple indexes spread across the file. As such, within the GStreamer framework, we have to handle the multiple seeks in the streaming thread rather than in the seek thread as we might prefer. This is because we cannot block the seek thread.
Check out the head commit of git master or the next release of GStreamer to try out this work. If you find bugs, file them on bugzilla as normal for GStreamer.
Hello World! It’s been a long time since I last wrote anything here, and for that I’m sorry. The autumn was consumed by university work, and the last few weeks I’ve been discreetly coding and writing to get everything ready for this announcement. Anyway, without further irrelevance, let me present the KDE Real-time Communication and Collaboration Project. You’ve probably heard me blathering about Telepathy before, but now for the first time we have a coherent plan for world domination, concocted by Abner Silva, Matt Rogers and myself (with help from many other people).
Let me briefly introduce the project and our aims:
So, if any of this interests you, we’d love your help. Hop in to #kde-telepathy on freenode IRC, or join our mailing list.
And, while you’re at it, why not take a look at our code so far.
Warning: this is highly experimental code which may cause all kinds of side effects, especially the Nepomuk related stuff, which is likely to make a complete mess of your Nepomuk database, so use with care.
If you’ve read the above warning and want to take a look at what we’ve done so far, here are some instructions. For the first phase of this project, our attentions are focused on building Telepathy based components for basic IM usage on top of the existing Kopete codebase. So far, you can create an account (Jabber is the only kind tested, so expect minor bugs with other protocols), set its presence and see a list of your contacts. Not the most exciting stuff ever, but with this core stuff in place, more features should arrive very soon.
Prerequisites
You need recent telepathy-mission-control-5, telepathy-gabble and telepathy-qt4. Best to install these from your distribution. If telepathy-qt4 is not provided, or older than 0.2.0, then download the source here.
The Account Management GUI
Checkout and build the account management gui from svn here:
svn://anonsvn.kde.org/home/kde/trunk/playground/network/telepathy-accounts-kcm
Also install its plugins from
svn://anonsvn.kde.org/home/kde/trunk/playground/network/telepathy-accounts-kcm-plugins
You can launch it by running:
kcmshell4 kcm_telepathy_accounts
And then follow the wizard to set up your Jabber account.
Setting the Account Presence
To set the account presence through a GUI (ie. bring the account on/offline), you will need the presence plasma dataengine and applet, available again from svn:
svn://anonsvn.kde.org/home/kde/trunk/playground/base/plasma/applets/presence svn://anonsvn.kde.org/home/kde/trunk/playground/base/plasma/dataengines/presence
You can then add the applet to your Plasma workspace and use it to bring the account(s) created with the GUI in the previous section on/offline.
Nepomuk Integration
Your contact list is integrated into Nepomuk by means of the telepathy-integration-daemon. Best to install it and launch it before bringing any accounts online. Code, again is in svn.
svn://anonsvn.kde.org/home/kde/trunk/playground/network/telepathy-integration-daemon
You can run it by calling telepathy-integration-daemon on the command line.
Contact List App
Finally, in order to see our contact list, we need a contact list app installed. Currently, this is in the very early stages of development, but you can at least see a list of contacts in it (although you can’t interact with that list yet). Source code is at:
svn://anonsvn.kde.org/home/kde/trunk/playground/network/telepathy-contactlist (corrected)
and you can run it by calling telepathy_contactlist_prototype on a command line.
If you like what you see or have any problems with getting it working, come talk to us in #kde-telepathy. We’re very happy to help out

Besides being a great designer, Seth Nickel is a really good writer. Maybe that’s what it takes if you want to pass on your vision and ideas to stubborn developers. He wrote one paragraph yesterday that resonated with me:
…we’ve been framing the hacker<->designer conversation around low level usability. Maybe we could get more done if the default conversation was different? If it happened earlier? If it was about deep design rather than surface bodangles?
This is exactly how I feel about the designer<->accessibility-advocate conversation. Accessibility is too often an afterthought that is divorced from the design process.
In the past I did some contract work as an “accessibility engineer” on a certain project. It went something like this (at the risk of encouraging an annoying meme):
projectmanager: It is soooo important for us that this application be really really accessible, and support ATK really really well. And that people with disabilities have really really good access to this. Also, if you could make sure your ATK support is good enough for automated testing, that would be greeaaaat.
accessibilityperson: I would love to help. I noticed that the color theme is hard-coded, this is problematic since users with visual impairments have different needs regarding color and contrast.
artsyfartspants: The color scheme is deliberate and has been very carefully thought out. And besides, it is white on black, which is technically high-contrast, so anybody could read it.
accessibilityperson: I also noticed that animations in this application are hard-coded and cannot be disabled. This is an issue since people may be very sensitive to animations and get motion sickness. The application should respect a system-wide animation-disable toggle.
artsyfartspants: Please see my answer above. The animation’s effect and timing have been very carefully thought out. This is old news, I wrote the design spec 6 months ago, you are wasting my time.
accessibilityperson: The user notification is transient, and disappears after a few, hard-coded, seconds. Users with cognitive disabilities, slow readers or users who are not native speakers of the interface’s language will have a hard time understanding the notification before it disappears.
artsyfartspants: By design, see above.
accessibilityperson: The user notification appears, hard-coded, in the upper right corner of the screen. Users with bad peripheral vision will miss these notification if their gaze is not set on the screen’s corner.
artsyfartspants: By design, go away.
accessibilityperson: But..
artsyfartspants: Bye!
A week later
accessibilityperson: I completed adding ATK support to the application, you could grab my branch and try it out. I have other concerns regarding accessibility issues in this application that need to be addressed.
projectmanager: Great! Could we now do automated testing on our POS and increase it’s quality a lot?
accessibilityperson: Sure. I also wrote an Orca script for the app so that screen reader users have a pleasant experience using it.
projectmanager: k. Write automated tests.
Do I have a good solution to all the accessibility issues I brought up? Not necessarily, that is why we have good designers.
designguru: Here is a writeup and a few mockups for the app. I did my best at universal design and included a diverse array of users in the use cases I designed for.
hackmaster2000 : This looks good! I will implement this while making sure that mechanism and policy are separate so that edge-case users can be accommodated for without intrusive patches and hacks.
projectmanager: Great work guys! The universality of the design, and the modular implementation will allow us to make some extra cash as we deploy this app for mobile devices and e-readers with little modification.
accessibilityguy: Lookin’ good. I have a branch with ATK support, I am currently testing this app with different assistive technologies. Could I suggest just tweaking this and that?
projectmanager, hackmaster2000, designguru: Absolutely, making sure our software is accessible is very important for our project. We support all our users, not just the first 80%.
projectmanager: I can haz magic testing now plz?
Máirín’s writeup about the accessibility discussions at the UX hackfest really made me happy. So glad Willie Walker made it there, I thought of going, but Willie really knows how to drive a point home.
My friend just came by and asked if I am blogging about Open Sores. I guess so!
# -*- coding: utf-8 -*-
# Written by Robin Burchell
# No licence specified or required, but please give credit where it's due,
# and please let me know if this helped you. Feel free to contact with corrections or suggestions.
#
# We're using PySide, Nokia's official LGPL bindings.
# You can however easily use PyQt (Riverside Computing's GPL bindings) by
# commenting these and fixing the appropriate imports.
from PySide.QtCore import *
from PySide.QtGui import *
#from PyQt4 import *
#from PyQt4.QtCore import *
#from PyQt4.QtGui import *
import sys
# This is our model. It will maintain, modify, and present data to our view(s).
# For more information on list models, take a look at:
# http://doc.trolltech.com/4.6/qabstractitemmodel.html
class SimpleListModel(QAbstractListModel):
def __init__(self, mlist):
QAbstractListModel.__init__(self)
# Store the passed data list as a class member.
self._items = mlist
# We need to tell the view how many rows we have present in our data. see tutorial #3
def rowCount(self, parent = QModelIndex()):
return len(self._items)
# view is asking us about some of our data.
# see tutorial #3 for more information on this.
def data(self, index, role = Qt.DisplayRole):
if role == Qt.DisplayRole:
return QVariant(self._items[index.row()])
elif role == Qt.EditRole:
# The view is asking for the editable form of the data. i.e. unformatted.
# See the comment in setData().
return QVariant(self._items[index.row()])
else:
return QVariant()
# the view is asking us to *change* some aspect of our data.
# as in the above, it can be any aspect of the data, not *just* the information contained in the model.
# remember to return true if you handle a data change, and false otherwise, always!
# for more information, see:
# http://doc.trolltech.com/4.6/qabstractitemmodel.html#setData
def setData(self, index, value, role = Qt.EditRole):
# You might be expecting Qt.DisplayRole here, but no.
# Qt.DisplayRole is the *displayed* value of an item, like, a formatted currency value: "$44.00"
# Qt.EditRole is the raw data of an item, e.g. "4400" (as in cents).
if role == Qt.EditRole:
# set the data.
# the str() cast here is mostly for peace of mind, you can't perform some operations
# in python with Qt types, like pickling.
self._items[index.row()] = str(value.toString().toUtf8())
# *always* emit the dataChanged() signal after changing any data inside the model.
# this is so e.g. the different views know they need to do things with it.
#
# don't be lazy and pass a huge range of values to this, because it is processing-heavy.
#
# because we are a simple list, we only have one index to worry about for topleft/bottom right,
# so just reuse the index we are passed.
QObject.emit(self, SIGNAL("dataChanged(const QModelIndex&, const QModelIndex &)"), index, index)
return True
# unhandled change.
return False
# if you e.g. don't want to make an item selectable, or draggable, here's the place to do it.
# by default, items are enabled, and selectable, but we want to make them editable too, so we need to
# reimplement this. of course, this means you can make only specific items selectable, for example,
# by using the 'index' parameter.
# For more information, see:
# http://doc.trolltech.com/4.6/qabstractitemmodel.html#flags
def flags(self, index):
return Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled
# remove rows from our model.
# 'row' is the row number to be removed, 'count' are the total number of rows to remove.
# 'parent' is the 'parent' of the initial row: this is pretty much only relevant for tree models etc.
# For more information, see:
# http://doc.trolltech.com/4.6/qabstractitemmodel.html#removeRows
def removeRows(self, row, count, parent = QModelIndex()):
# make sure the index is valid, to avoid IndexErrors ;)
if row < 0 or row > len(self._items):
return
# let the model know we're changing things.
# we may have to remove multiple rows, if not, this could be handled simpler.
self.beginRemoveRows(parent, row, row + count - 1)
# actually remove the items from our internal data representation
while count != 0:
del self._items[row]
count -= 1
# let the model know we're done
self.endRemoveRows()
# while we could use QAbstractItemModel::insertRows(), we'd have to shoehorn around the API
# to get things done: we'd need to call setData() etc.
# The easier way, in this case, is to use our own method to do the heavy lifting.
def addItem(self, item):
# The str() cast is because we don't want to be storing a Qt type in here.
self.beginInsertRows(QModelIndex(), len(self._items), len(self._items))
self._items.append(str(item))
self.endInsertRows()
# This widget is our view of the readonly list.
# For more information, see:
# http://doc.trolltech.com/4.6/qlistview.html
class SimpleListView(QListView):
def __init__(self, parent = None):
QListView.__init__(self, parent)
# unlike the previous tutorial, we'll do background colours 'properly'. ;)
self.setAlternatingRowColors(True)
# we want our listview to have a context menu taken from the actions on this widget
# those actions will be to delete an item :)
self.setContextMenuPolicy(Qt.ActionsContextMenu)
# create a menu item for our context menu that will delete the selected item.
a = QAction("Delete Selected", self)
# hook up the triggered() signal on the menu item to the slot below.
QObject.connect(a, SIGNAL("triggered()"), self, SLOT("onTriggered()"))
self.addAction(a)
# this is a slot! we covered signals and slots in tutorial #2,
# but this is the first time we've created one ourselves.
@pyqtSlot()
def onTriggered(self):
# tell our model to remove the selected row.
self.model().removeRows(self.currentIndex().row(), 1)
# Our main application window.
# You should be used to this from previous tutorials.
class MyMainWindow(QWidget):
def __init__(self):
QWidget.__init__(self, None)
# main section of the window
vbox = QVBoxLayout()
# create a data source:
self._model = SimpleListModel(["test", "tes1t", "t3est", "t5est", "t3est"])
# let's add two views of the same data source we just created:
v = SimpleListView()
v.setModel(self._model)
vbox.addWidget(v)
# second view..
v = SimpleListView()
v.setModel(self._model)
vbox.addWidget(v)
# bottom section of the window:
# let's have a text input and a pushbutton that add an item to our model.
hbox = QHBoxLayout()
self._itemedit = QLineEdit()
# create the button, and hook it up to the slot below.
b = QPushButton("Add Item")
QObject.connect(b, SIGNAL("clicked()"), self, SLOT("doAddItem()"))
hbox.addWidget(self._itemedit)
hbox.addWidget(b)
# add bottom to main window layout
vbox.addLayout(hbox)
# set layout on the window
self.setLayout(vbox)
@pyqtSlot()
def doAddItem(self):
# instruct the model to add an item
self._model.addItem(self._itemedit.text())
# blank the text input.
self._itemedit.setText("")
# set things up, and run it. :)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyMainWindow()
w.show()
app.exec_()
sys.exit()
by Robin Burchell (noreply@blogger.com) at February 22, 2010 12:14 AM
My company was really kind to get me a Macbook Pro (the 13.3-inch “5.5″ variant). It is an awesome piece of hardware! (especially after my own PoS HP laptop I’ve been cussing at for a while now)
That said, I still don’t like the idea of running a proprietary operating system on it (as beautiful as OS X is ;)), so I continue to happily use Gentoo. The standard amd64 install works just fine with some minor hiccups (keyboard doesn’t work on the LiveCD, kernel only shows a console with vesafb).
The one thing that did bother me is BIOS-emulation. For those coming from the PC world, Macs don’t have a BIOS. They run something called EFI which is significantly more advanced (though I think the jury’s out on quirkiness issues and Linus certainly doesn’t approve of the added complexity).
Anyway, in order to support booting other OSes (=> Windows) exactly as they would on PCs, Apple has added a BIOS emulation layer. This is how Ubuntu (at least as of 9.10) boots on Macbooks. Given that both the bootloader (be it Grub2 or elilo) and the Linux kernel support booting in an EFI environment, it rubbed me the wrong way to take the easy way out and just boot them in BIOS mode. There is a reasonable technical argument for this – I see no good reason to add one more layer of software (read bugs) when there is no need at all. After a lot of pain, I did manage do make Linux boot in EFI-only mode. There is not enough (accurate, easily-findable) documentation out there, so this is hard-won knowledge. :) I’m putting this up to help others avoid this pain.
Here’s what I did (I might be missing some stuff since this was done almost a month ago). The basic boot steps look something like this:
Now you could use elilo instead of Grub2, but I found this it to not work well (or at all) for me, so I just used a Grub2 (1.97.1, with some minor modifications) (just adds an “efi” USE-flag to build with --with-platform=efi). While I could make /boot a FAT partition, this would break the installkernel script (it’s run by make install in your kernel source directory), which makes symlinks for your latest/previous kernel image.
Instructions for installing the Grub2 EFI image are here. Just ignore the “bless” instructions (that’s for OS X), and put the EFI image and other stuff in something like /efi/grub (the /efi is mandatory). You can create a basic config file using grub-mkconfig and then tweak it to taste. The Correct Way™ to do this, though, is to edit the files in /etc/grub.d/.
Of course, you need to enable EFI support in the kernel, but that’s it. With this, you’re all set for the (slightly obsessive-compulsive) satisfaction of not having to enable yet another layer to support yet another proprietary interface, neither of which you have visibility or control over.
easy_install pep8 pyling
by kalfa (noreply@blogger.com) at February 20, 2010 12:05 PM