Wiki

Clone wiki

hachoir / hachoir-wx

hachoir-wx (hwx)

  • wxWidgets-based GUI
  • Current version is largely experimental and unstable
  • There are occasional (hopefully) small code overhauls as the code is progressively refactored. It's a learning process, or something.
  • Code organization is a first priority. Better to delay and think some more than to put in hacks.

Download

Usage

To run hachoir-wx after installation, execute the installed script. Eg on windows:

python c:\python27\Scripts\hachoir-wx

"I want a feature..."

To ask for a feature/bug fix/etc., make a new ticket and assign it to me ("cyril") or ask on the mailing list. Do not put it on the wiki, and do not email me about it, as I will most likely forget. See UserInterface

Feature Voting

Here you can vote for the feature you want most by appending your name to the "Requested By" column. Vote once only -- we're all grownups here. If your desired feature isn't listed, add it.

FeatureRequested ByCompleted
Hex-View Big File Supportcyril, haypoMac OS X, Linux

Work

Keep in mind that the tasks below are candidates for implementation, which means that we'll only implement them if we get enough requests/votes. In other words, the below tasks are mostly ideas that we think may be "nice things" to implement; unless, of course, they are bugs.

Developer Info/Patches

It's important to understand how the hwx code is organized. Otherwise you might waste your time adding your changes in the wrong way, and your patch will be rejected. This section should give you some hints on how to make your patch merge in using as few iterations as possible.

Message Passing

The GUI is driven by message-passing. Each instance of the hwx main window has its own dispatcher. Each widget can use the dispatcher to trigger an event (which can have its own user-data) which will be broadcast to all other widgets that are attached to the dispatcher and have an event handler for the particular event.

The event handler functions have the name on_{event name}. For example, the handler for the "field_selected" event is called "on_field_selected". So in order to handle the "field_selected" event, all you have to do is add an "on_field_selected" function to your class.

A short example: if you click on a field in the field-view widget, a "field_selected" event which contains the field that was selected will be triggered and broadcast to all other widgets. Once the hex_view widget gets the event, the field part of the event will be used to highlight/scroll to the correct part of the hex-view of the file.

This framework allows us to make sure that widgets don't know anything about other widgets, which in turn allows us to modify/replace/remove widgets without affecting anything else in the application.

Suppose we have widget A that handles an event, and we want widget B to do something too for this event. A naive scheme would have it so widget A directly calls widget B's code. Next time widget A is replaced with a better version of widget A, it will have to be modified to include the code that invokes widget B. This is crap. With message passing, widget A would trigger the event, and widget B (somewhere else, far away) will have a handler for the event, and will do whatever it wants. If widget A is suddenly replaced by a better version of widget A, the functionality that makes widget B work based on that event will not have to be touched at all, because widget A doesn't know anything about widget B. Score!

Widget Code Oranization

A widget (called "widget", for example) is split up into three parts.

The widget.py file contains functions concerned with displaying the widget in terms of the toolkit (in this case wxWidgets). For example, the hex_view.py file contains a function called "mark", which will highlight a particular region of the hex view.

The widget_imp.py file is the actual application logic of the widget (and _nothing else_). It handles all kinds of events and makes the widget do stuff by using functions located in the widget.py file, and occasionally triggers new events as required. For example, the "on_field_selected" function in the hex_view_imp.py file is used to make the hex view respond when a field is selected -- it highlights the appropriate section of the hex view using the "mark" function in widget.py.

The widget_fwd.py file handles toolkit (in this case wxWidgets) events and calls the appropriate widget_imp.py event handlers so work can be done.

This framework allows us to separate app behaviour from the drawing toolkit. Widgets don't know how they are drawn (and they shouldn't have to), and they don't know how operating system/toolkit events are handled (and they shouldn't have to, either). This allows us to be able to replace the drawing/event handling implementation of a widget without touching the application-specific widget behaviour.

In a naive scheme, application logic would be mixed with drawing functions and event handling, so every time a bug needs to be fixed in drawing/event handling/application logic the maintainer would have to look through a giant pile of code to figure out what's wrong. In our scheme, drawing/application logic/event handling can be modified separately without affecting the others.

Writing a Good Patch

To write a good patch that won't be rejected:

  • Make sure you understand the above
  • Make sure the functionality you're adding is modular and decoupled
  • Make sure that the functionality you're adding is sitting at the right level of abstraction in the application. For example, making it so a menu item opens a new window is definitely a bad idea.
  • Make sure that compatibility hacks due to bugs in wxWidgets are confined in their own files. See hex_view/ directory for an example.

Don't hesitate to ask questions on the mailing list if you're not sure about something, or want suggestions implementing something. Remember it's better to ask many questions on the mailing list and submit a good patch, than to be lazy and submit crap that will be rejected.

Compatibility

  • hachoir-wx does not work with wxPython 2.7.1 because right-click handling for list controls seems to be broken (it also doesn't work in the wxPython demo, so looks like it's not our fault.) There are also weird issues with the !SplitterWindow.

Testing

If you'd like to volunteer to test this on any other platform (especially Windows), add your name to this section in this page.

  • cyril
    • Mac OS X (Tiger) PPC, Python 2.5, wxWidgets 2.7.2 (unicode) -- works ok
    • GNU/Linux Intel, Python 2.4, wxWidgets 2.6.3.3 (unicode)
  • haypo
    • svn 1230 ok on Ubuntu Dapper and Edgy (wxPython 2.6.3)
    • svn 1230 ok ok Windows XP (wxPython 2.7.2 Unicode)

See also

Updated

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.