GSoC: Things I've been doing and what I learned until now
The second month of Google Summer of Code passed quickly. Last weeks I’ve been working on my markers code. My early implementation, while functional, needed a lot of cleaning, refactoring and refining to fit into Pitivi. Mathieu Duponchell and Alexandru Băluț have been guiding me through this process.
In GES I expanded the GESMarkerList with new signals, writed new tests and changed some unusual structures for others more usual in GES.
In Pitivi I added a new module with the markers logic, ‘markers.py’. Roughly speaking, now we have the class MarkersBox, which is a GTK.EventBox containing a GESMarkerList and a GTK.Layout to put on markers. The class Marker is also a GTK.EventBox, so we have a widget for every GESMarker, which allows to move, remove and select markers. The class MarkerPopover brings a popover menu to edit metadata in every marker. I also implemented undo and redo actions.
The process of rewriting a lot of my previous code has been hard and challenging. I knew that my original code wasn’t clear or optimized but I wasn’t sure how to exactly improve it. It implied to learn and apply some concepts which wasn’t clear to me. While hard work it felt as a rewarding and foundamental learning.
For future GSoC students I would like to recap some of the things and concepts I have learned or worked on with Pitivi. Maybe this would be useful for someone:
Pitivi follows the Model-View-Controller pattern. In my early code I was binding together the View and Controller parts. For example, removing a marker: first I called the method to remove a marker and after that I had a line of code to redraw the removed marker. This would make impossible to use other controllers.
To change this I had to implement new signals in GESMarkerList, for removed and moved markers. Then in Pitivi I wrote handlers for these signals which updates the View. So, every time the Model is updated with a ‘remove marker’ it triggers a remote signal and the handler updates the view.
Undo/Redo actions are alternative controllers. Alternative controllers need the MVC. Without the signals that I wrote previously my undo/redo actions couldn’t work. The class MarkerObserver monitorize what happen with markers. It have handlers for every GESMarkerList signal. With every signal (add, remove and move) a new action is created and added to an action log. Every action have a method to implement undo and redo.
One complicate thing was that when a marker is removed and the user wants to undo that action, a new marker has to be created. This brings a new problem, if the user wants to undo to previous actions the reference to the original marker get lost, and previous actions in the stack don’t know about the last marker created to substitute the original marker.
Lucky me, Aleb guided me to the UndoableAutomaticObjectAction class who takes care of these situations, but it took me a while to discover how it works.
Pitivi uses GTK, a toolkit for creating graphical user interfaces. And not everything is evident in GTK documentation.
To display markers we chose to use CSS styles. I wanted that the interface of the markers change while they are hovered or selected. But it was hard to make it work in EventBoxes. While in GTK.Button it works just right, it took me time to discover why that wasn’t working in our case. After some talk in the GTK channel we discovered that we needed to manually update the flags state in our widget:
` def do_enter_notify_event(self, unused_event): self.set_state_flags(Gtk.StateFlags.PRELIGHT, clear=False)`
` def do_leave_notify_event(self, unused_event): self.unset_state_flags(Gtk.StateFlags.PRELIGHT)`
Slightly out of context but this code made our CSS work
TIME AND COMMUNICATION:
These things took me more time that I would like. Being a beginner programmer isn’t easy, there are multiple factors which can block you. It’s hard to know if the thing that is blocking you is a trivial one or a hard one. Also, the desire of resolve all the problems by my own often result in a slower and inefficient pace. In my case all my problems got a new light when I talked with my menthors.
THE DEVIL IS IN THE DETAILS:
When I read quickly through the code I have a loose knowledge of what it does. Stackoverflow gives me the false impression that I understand everything in a hurry. Most of the time these approaches drive me to get stuck.
If I read carefully, line by line, taking my time to understand, to explain things to myself, to make questions, everything starts to make sense and flow. The same happens when I try to go for a big task without subtasking. And I noted that when I have a good understanding of the little parts is easier to refine the code later.