Translate Toolkit & Pootle

Tools to help you make your software local

User Tools


This page is a draft.

Introduction

This is a draft specification for the major architectural changes planned for Virtaal 0.3. The main aim of these changes is to create a stable, robust and easy-to-use platform from which all the future changes can be easily implemented. For this purpose it has been decided to use a MVC architecture.

While this page is in its draft stage all statements made herein should be considered suggestions or opinions. Specific sections, paragraphs or sentences that are not yet decided on will be marked with ”(??)”.

Architecture

MVC

To reach the goals stated in the introduction above we will be implementing a MVC architecture in the code. See the diagram below for the proposed architectural structure.

Diagram

Virtaal's MVC architecture

Description

With a basic understanding of the MVC pattern as well as knowledge of Virtaal's features, the diagram should be reasonably self-explanitory. The following description contains notes about unexpected, unclear or new concepts introduced.

The Store group in the diagram represents the model, view and controller that is related to store-level activities. In terms of the GUI, the StoreView would be the main gtk.TreeView widget as it is in Virtaal 0.2. The StoreModel is a basic wrapper for basic translation store which (mainly) handles the loading, saving and parsing of translation files.

Similarly the Unit group represents the unit-level components. The UnitView specifically represents the GUI of the unit editor (the selected unit) as it is in Virtaal 0.2.

The Mode MVC-triplet produces a ModeCursor that specifies which units are usable in the currently selected mode. This cursor will be used by the StoreController and/or UnitController.

The MainWindow object is responsible for managing the creation of the other main components and may also serve as proxy for communications where no “official” channel is available(??).

Extensions

Adding features to Virtaal will be much easier once this architecture is in place. The way in which this is done can make the difference between a nice, modular system and a convoluted mountain of messy code. Extensions can be done in one of three ways(??):

  • Extending relevant, existing component(s). This is typically how basic functionality will be implemented.
  • As separate MVC modules. Using this approach, a feature (or extension) creates its own model(s), view(s) and/or controller. These components then connect to the signals they are interested in, in order to connect themselves to the system. This should be the preferred method for bigger, more complicated features such as translation memory.(??)
  • As plug-ins. Separate classes (possibly also with a MVC design) that are dynamically loaded and connects to signals of the existing components in order to connect to the system. This approach should be used by smaller, non-critical features.(??)

Source Code

This section contains specifications for all source code-related issues. Please add any missing info.

Naming conventions

Classes

As per PEP 8 class names are written in camel case, starting with a capital letter.

Variables

As per PEP 8, as well as existing conventions in the Translate Toolkit and Virtaal, variable names are all-lower case and words should be split with underscores.

Names of variables representing Gtk+ widgets should have a prefix describing the type of widget it represents. Here are some prefixes:

btn gtk.Button
cmb gtk.ComboBox
mnu gtk.MenuItem
tvw gtk.TreeView
txt gtk.TextView
wnd gtk.Window

(??)

Formatting

  • Lines containing only comments or documentation strings should not be exceed 80 characters.
  • Long lines containing code should be formatted to maximise readability.
  • As a rule there should be only one class per file. Exceptions are allowed in cases where there are small, related classes grouped into a single file.
  • When in doubt, refer to PEP 8
  • If still in doubt, follow the conventions used so far.
  • If still in doubt, ask a dev!

Comments

  • Comments should be written while coding and not afterwards.
  • Missing features, obvious bugs or other important notes should immediately be marked with a FIXME, TODO or XXX mark in a comment.
  • Refrain from adding obvious comments except where used to label separate blocks of code.

Documentation strings

  • Epydoc-compatible document strings should be added where possible. This includes file- and class-level docstrings.
  • Inside classes at least all public and weak-private (one leading underscore) methods should be documented.(??)
  • Method and function documentation strings must at least specify type parameters (the @type directive) and the return value if not None, except where these are very obvious.

Imports

  • Relative imports should not be used. This allows for much more clarity where scope of an imported class/function/variable is concerned.
  • Imports should always be grouped in the following order (separated by a blank line):
    • System/global module
    • Inter-Virtaal / inter-module
    • Intra-module (other files in the same module)

Tests

  • Even though it is not time-efficient to write tests for absolutely everything, there should at least be tests for the most important functionality of a class/module.
  • Tests should be grouped into test classes that test either a specific (large and important) class or a specific module.

File Layout

This is section is only applicable to the virtaal/ source sub-directory, seeing as the rest of the directory structure is serving us quite well.

Related code should definitely be grouped together into modules and sub-modules. Here are some possibilities:

  • Create sub-directories for models, views and controllers and put the files containing the relevant classes in each of those directories. Example for unit-related class files: models/unitmodel.py, views/unitview.py, controllers/unitcontroller.py
  • Create a separate (sub-)module for each MVC group of files/classes. This would mean the creation of at least the store, unit and mode sub-directories. Example for unit-related class files: unit/unitmodel.py, unit/unitview.py, unit/unitcontroller.py

(??)

Note that there is no mention of a plug-ins directory, because it has not been decided if plug-ins will be supported.

Documentation

API documentation should be generated from the epydoc documentation strings in the source code. Other, more descriptive documentation should be maintained on the wiki.

Implementation Planning

Seeing as this implementation will affect our planning schedule, the implementation of specific parts of the code should be ordered in such a way that other planned work can be started as soon as possible.

All implementation should reuse as much code as possible from Virtaal 0.2 in order to save development time.

(Note that all time estimations include the writing of tests)

Phase 1

  • Number of developers: 1
  • Estimated time needed: 3 days
  • Description: This phase consists of creating basic implementations of the following components (in roughly the order they appear in):
    • MainWindow
    • StoreController, StoreModel, StoreView (relatively parallel)
    • UnitController, UnitModel, UnitView (relatively parallel)

Phase 2

  • Number of developers: 1 or more
  • Estimated time needed: 40 developer-hours
  • Description: Implement all extra functionality from Virtaal 0.2. Here are some of the specific sub-goals for this phase:
    • Implement all mode-related classes. This includes creating ModeCursors and using them for navigation.
    • Implement undo functionality using StoreView and UnitView.

TODO

  • Undo
  • Modes
    • Search and replace
    • Incomplete
  • Spell checking
  • AutoCorrection/AutoCompletion
  • Add comments and context fields
  • Test formats other than PO Tested with basic XLIFF files.
  • Update headers - ask user for team info See related bug below.
  • Write tests.
  • Generate docs
  • Use unit-level gettargetlanguage() in stead of the store-level equivalent.

Bugs

  • Mode bar visible even if no file is loaded.
  • “Save as…” should be inactive until a file is loaded.
  • First unit in a file is not selected on load.
  • Pressing Enter in a target does not move focus to the next plural textview.
  • If the first plural form is changed, the change is not visible after switching to a different unit. Problem was much bigger than mentioned. No changes to plurals were saved because of multistring's suckage.
  • Recent files not updating.
  • Editing area does not respond to changes in window size. Could not reproduce
  • Widget heights are not 100% correct for single-row units: too much space at the bottom.
  • Opening a second file does not work.
  • Excessive flickering when changing units.
  • Without specifying your translator e-mail address, each time a file is saved, a contributer heading is added regardless of whether there is one (or more) already. This is probably related to the checks in translate.storage.poheader.poheader.updatecontributor().