Tuesday, May 29, 2007

A new release for Archimedes

Hello,
I'm amost late AGAIN. At least this proves me something: I surely prefer tons of things before writing down to this blog. Sad but true, I'm not a writter, I'm a programmer.
Anyway, yesterday I've released the latest version of Archimedes concentrating several features I've been talking about such as Text, dimension, layers, etc...
We already found about 6 or 7 bugs during our demonstration to the architects that help us but this is only a proof that we should release unstable versions and have more people testing it. I hope make this possible by using maven to control Archimedes build and tests as well as the deploy system. Don't know for sure when this is going to happen but I will work on it in July.
I've tried to test the install system and the zip files on all three platforms and I believe everything is working fine but PLEASE tell me if something goes wrong.

Changing the subject, I've found out today how to write google gadgets and how fun this can be. I felt the need to find a gadget that would show me a UVa problem from the ACM contest each day so I could train a bit more since I wish to show a better performance on the local contest here in São Paulo this year. Looking up on their search system gave me nothing so I decided I could write my create my own gadget since Google has been asking people to do so since they renamed the personalized home to iGoogle. Checking out that feature I discovered it is only a very limited gadget factory aimed to non programmers but there I found the link I added at the begining of the paragraph.

I understood how the system worked (quite simple, it is just xml parsed into HTML code with javascript) and wrote my own gadget. I used google's users page to upload my gadget and there you go: http://nightao.googlepages.com/uvaGadget.xml. I still wish to add tons of features such as a user id preference that would make the gadget load only problems you haven't solved. Maybe parse the site to create 3 tabs with description, input, output and maybe another one to submit a solution. I got tons of ideas and with Javascript, almost anything can be done (although it is very hard to design and debug it). For those of you who use google's personalized home, I do suggest you take a look on how to build your own gadget because I can bet there are gadget you would like to have that does not exists.

That's it for now,
Bye bye

Tuesday, May 22, 2007

Last week of release

Ok! I AM late!
I admit it. But at least I remembered.
Anyways...
Haven't got tons of news. We are entering the last week of iteration and basically this will be devoted to improve the software in a programmer point of view. This means we won't be adding features. The work planned is to improve the software's tests (that are kind of messy since the migration) and maybe focus on a better build system using maven2. I should release the version 0.52.0 late on Sunday or maybe early on Monday.
I could already give some insights. The first one is that we will be using the recently published truetype fonts from RedHat since they are compatible with the Windows core fonts and are GPL compatible. Those will be distributed with Archimedes to ensure full compatibility across platforms. I would like to thank gtroza for this tip.
The other one is not so good. We will not be delivering any persistence system yet. The old xml persistence system that existed previously is not yet ported to this new architecture because we are figuring a way to make it flexible enough to fit all our requirements. The PDF export is not ready either... Those will probably be the highest priority in the next release so it should be done in a month.
Mainly that is it about Archimedes. The rest I have talked about on the last few weeks.
I will probably not post any other news for the rest of the week since I will focus on having the release decently ready and tested not to have as many problems as last time. Again, no screenshot since you will be able to see the news by yourselves!

Bye Bye!

Monday, May 14, 2007

Almost one week later

Ups... I almost failed again to keep this blog up to date.
But recovered "on time". So, what are the news I have to share?

Well, mainly Archimedes news:
We are deciding if we launch the release this week end or the next one. This choice is mainly related to the free time people have to make this happen. The features that we had to develop according to the road map are not ready but a nice bunch is ok.

Just to be a bit more precise:
- The text feature is complete with an Arial font that is being packed with Archimedes. I still have to find out what are the legal issues about that and if I am allowed to distribute this. Otherwise we will have to find a cross-platform TrueType Font open-source or discover how the ones from OpenOffice are used. If anyone has any answer to those questions, please warn me.
- The layers are working again with the combo box and the layer editor window (with a lot of update bugs fixed).
- The Rectangle feature is back.
- The behaviour of the Orto system when you snap to Grid point has been "corrected". Which means that gripping has priority over orto.
- The Pan feature is back (although its shortcut through middle click isn't).
- Moving (or streching) by clicking on the snap points should be ready with a small amout of work.
- Dimensions are walking slowly but surely.
- The mouse cursor now changes when on a command. There is a big cross when waiting for a command and the small rectangle when you are on a command.
- The snap points are now dark red (just like the icons showed) and if you grip to any with the mouse, it will light up to yellow so that it is clear that you snapped.
- The infinite line is almost back. I'm just having a minor problem to render it correctly (meaning infinitely) but it should be solved quickly.

Features that we should have done and will probably be late:
- Zoom command
- Export to PDF
- Open/Save XML(.arc)

There are also several things we would like to improve in the programmer side. I can quote the build process that could be much better with Maven2, the deploy process that could be much better with continuum (or Cruise control), the test coverage of what we have done so far and a few other things.

I will probably focus on the simpler things now which are to finish the features that are almost done and, if I have some time, import the Zoom command from the last version.

I guess that's it. No screenshot this time... I'll let you guys holding your breath for the next release. :)

Tuesday, May 8, 2007

Combos as Contribution Itens on rcp

Okay! Maintaining the post rate for more then 1 day. My current record so far.
This time I will focus on a problem I had last week while implementing Archimedes' layer combo. Using combos in SWT is quite simple, you just create it linking it to its parent and add the texts. In an RCP application things are a bit more complicated since the widgets are positioned in the parent composite only when needed. This basically means that the ContributionItem abstraction is a closure to insert those widgets when needed.

I've implemented about 3 or 4 times this class because I had several problems and couldn't understand why since I got no exception message and the widget just wasn't being shown. I created this implementation thanks to an example posted in this mailing list (http://dev.eclipse.org/newslists/news.eclipse.platform.rcp/msg00952.html) by Jean-Michel Lemieux (author of "Eclipse Rich Client Platform: Designing, Coding, And Packaging Java Applications", one of the best books about eRCP I found). You can find a more complete implementation of this in Archimedes (br.org.archimedes.gui.rca.LayerComboContributionItem) but here goes a simplified version.


public class ComboContributionItem extends ContributionItem implements
  IContributionItem {
  private Combo layersCombo;
  private CoolItem coolItem;
  private List texts;
  public ComboContributionItem(List texts) {
    this.texts = texts;
  }
  public void fill (ToolBar parent, int index) {
    ToolItem item = new ToolItem(parent, SWT.SEPARATOR);
    Control box = createLayersCombo(parent);
    item.setControl(box);
    item.setWidth(500);
  }
  public void fill (CoolBar coolBar, int index) {
    Control box = createLayersCombo(coolBar);
    int flags = SWT.DROP_DOWN;
    if (index >= 0) {
      coolItem = new CoolItem(coolBar, flags, index);
    }
    else {
      coolItem = new CoolItem(coolBar, flags);
    }
    coolItem.setData(this);
    coolItem.setControl(box);
    Point toolBarSize = box.computeSize(SWT.DEFAULT, SWT.DEFAULT);
    coolItem.setMinimumSize(toolBarSize);
    coolItem.setPreferredSize(toolBarSize);
    coolItem.setSize(toolBarSize);
  }
  private Control createLayersCombo (Composite parent) {
    Composite top = new Composite(parent, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    layout.verticalSpacing = 0;
    layout.horizontalSpacing = 0;
    layout.numColumns = 1;
    top.setLayout(layout);
    layersCombo = new Combo(top, SWT.READ_ONLY);
    for (String text : texts) {
      layersCombo.add(text);
    }
    layersCombo.setLayoutData(new GridData(GridData.FILL,
      GridData.BEGINNING, true, false));
    return top;
  }
  public void fill (Composite parent) {
    createLayersCombo(parent);
  }
  public void setText (String text) {
    if (layersCombo != null) {
      layersCombo.setText(text);
    }
  }
}


I've cut the package and imports info but this should not be hard to add. I suggest you just copy this code and alter it to match your needs slowly so you see the result. If you have any problem with this code or need help because things are not rendering, please contact me.

With some minor changes on this code, I managed to enable the layer combo once again. Which means Archimedes is now back with Layers. The layer editor is still a bit buggy since the last refactoring but it should be solved very soon. I hope I have some nice screenshots by the week end with everything solved out.

See you later guys.

Monday, May 7, 2007

Archimedes on going & TrueType fonts

Keeping the speed is now critical. I am trying to make it a habit to write down every problem or achievement I have here so that people can benefit from those and I can get used to post more frequently on this blog.

Last week end I worked a lot on Archimedes to have the text problem solved. Mainly the thing is Archimedes needed to have a text feature so that users could write things on the drawing and the dimension feature could write the dimensions too. Last time we solved this problem, we had no idea about how to draw fonts on OpenGL and therefore the team chose to implement its own font system and fonts. This was heavily critized by the clients and users and by the developers too. So this time, we decided to implement it right. This means that we focused on reading existing fonts and what our clients asked was Arial which is a TrueType font. So we tried to learn how to parse ttf files and then find out how to render those.

After some research on the internet about java ttf parsers we found an interesting Apache project called Batik. This project focuses on SVG support to a lot of things and, especially, having truetype fonts ported in svg paths. Thanks to the Apache Software license (thanks free and open source movements) we were allowed to read the source code, modify it and use it in Archimedes. So after a couple hours studying the code, we grabbed the packages that were in our interest and brought them into an RCP plugin and used them in Archimedes.

Now a few comments about truetype fonts. The Font class in batik that encapsulates a TTF font is mainly formed of 10 or 15 tables that contain infos about the glyph (characters), platform and several other details I don't understand decently. What we needed to use the font was just the cmapTable and the cmapFormats. Those classes contained mapping between several encodings to the glyph number in the font. Also each point of the glyph contains information about whether it is a normal point or an "endContour" point which means it is the last point of a circle and should be connected to the first point non "endContour" found. We also learned (although we didn't implement it) that interpolation between those points should be done with a bezier curve of second degree but this having this on Archimedes is probably an overkill at the moment.

Dropping a bit the technological part (all the code can be found in the br.org.archimedes.batik package and br.org.archimedes.gui.opengl.OpenGlWrapper class), all this information means that the software is now loading a truetype font and rendering it with OpenGL. There are still a few problems to fix like mapping weird characters and having this working perfectly on all platforms but all the rest is working fine. And here is a small screenshot just to prove I'm not lying:

Sunday, May 6, 2007

Loading files with RCP

Keeping my efforts to post about interesting things instead of just complaining most of the time like I use to do, today, I will write about how discover the file path of certain files from within an RCP application.

First of all, the problem of loading a file in that situation must be explained. It sounds a bit stupid to explain something if it seams there is no problem to solve, right?
So, loading a file when you are coding an RCP plug-in is a problem because you can never know where your application will be relatively to the plug-in. You could hack some way out of this by assuming some things about your platform since eRCP, by default, generates always the same structure. But the fact is that this could be broken by just a few minor changes on your platform. So if we want to solve the problem correctly, we have to rely on the main application to load things correctly since it knows exactly where it is and where the plugin is.

Now that the problem should be clear, let's understand what is eRCP solution to it. The first simple solution presented is implemented in the default Activator class eclipse generates for each plugin if required. This class contains a static method findImageDescriptor that loads an image with a relative path. This is very useful since most plug-ins have some kind of image that they wish to load (icons, images, etc...) but it obviously does not solve the problem of loading any file. This operation is a bit trickier because it is pretty well decoupled so that people can load things at the level they desire.

Before version 3.2, eclipse (and eRCP in general) suggested to use the method "find" implemented in the Activator class reachable from Activator.getDefault(). Since version 3.2, this has changed and that old method is now deprecated. I don't know the reason for sure but I would guess that they found out that the Activator class shouldn't contain knowledge about how to load a file. The fact is that the static class FileLocator was created to encapsulate that knowledge.

Now that class is quite simple to use and it is probably not a problem to find out how to use the FileLocator.find(Bundle, IPath, Map) method. Most of the time, you will get the bundle from you Activator class (getDefault().getBundle()) and the Map will be empty because you probably want to load a file that has no dynamic info (otherwise, check the javadoc to know how to use it). Most commons uses of this method will just instantiate a new Path with a String argument that is the path to the file relative to the plug-in's root folder. This will return you an URL instance containing the info about your bundle and the file's path. If you check it, you will notice it is not a normal path but something like "bundleentry://bundle_number/path_to_your_file". As you can guess, there is no way you can use that to instantiate a File or a FileInputStream to read it.

And that is the hard part: You will find two static methods in FileLocator that can help you:
FileLocator.resolve(URL)
and
FileLocator.toFileUrl(URL).

In most of the cases, both method will return the same correct path. But what is the difference about them? I am not sure so please do not take this info for the truth before looking for more information. From my viewpoint, the difference regards only the path you will get at the end. The first method will return URL with http, ftp, jar, etc.. protocols while the second one will only return file protocols which is, in most cases, what you desire. Having tried to explain all this, here is the code you will get to load a file from your RCP plug-in:


Bundle bundle = Activator.getDefault().getBundle();
Path path = new Path("path/to/your/file.extension"); //$NON-NLS-1$
URL url = FileLocator.find(bundle, path, Collections.EMPTY_MAP);
URL fileUrl = null;
try {
fileUrl = FileLocator.toFileURL(url);
}
catch (IOException e) {
// Will happen if the file cannot be read for some reason
e.printStackTrace();
}
File file = new File(fileUrl.getPath());


I hope this helped you guys and please feel free to ask any question if I wasn't clear on something. See you guys later.

Wednesday, May 2, 2007

More errors & Archimedes screenshots

Well,
People always say we should do things while rested and without rush. Otherwise we will screw everything and make it all go wrong all the time. I never really listen to those advices although I really believe they are 100% correct. That is a BIG mistake!

This BIG mistake made me screw out two Archimedes' releases in a row. 0.50.0 was a crap because the zip files were trash and the linux (and windows) installers and zips did NOT contained the OpenGL plugin required to be able to see any drawing. The next day I was there, tired again, trying to fix all the problems and, as it should be, I fixed a couple of them but never even realized that my regular expression to match the openGL plugin was NOT matching with the windows plugin. Just to have a last cherry on the cake, I found out later on (at work) that for some mysterious reason, the linux opengl plugin was generating a nice and friendly crash regarding something on the native library. So great!

This means I will release later on today yet another version of Archimedes with not 1 more feature just trying to have the bloody files to work! While I don't complete this work, I will attend to a request from a greek reader to post some Archimedes's screenshots. I took those using the deploy generated by pde for that next version. Let's hope my script will not screw everything up once again! If it does, I will be forced to stop all development and have Archimedes' core and all the plugins compiled and tested by maven2. This should solve my problems at least for some time.

The first screenshot is a clean view of a drawing on MacOS X (from my development laptop):


The second screenshot is a view of Archimedes with a nice very simple drawing during an arc creation on Ubuntu (GNU/Linux):


The last one is the layer editor view of Archimedes on Windows:

We will probably have nicer and better screenshots after the next release (in about 3 weeks) and I will update the ones at sourceforge and those ones then. For now, this is all. I will be back as soon as possible.

Script errors & eRCP shortcuts

Well,
Let's see the good part of things: I'm posting a lot more on this blog (if that is somehow good). But as I started announcing good parts, it is quite obvious I did something wrong. Well, I screwed the script that generates Archimedes's installers. The result was that the generated zip file was all messed up with the path. Also, the installers were not adding most of the plugins with operations because I forgot to add the entries into the core. So I decided to add a package with those. I should probably enhance that system though. Too bad I won't do it so soon.

Anyway, back to what is important. Retaking that old series I promised about Eclipse Rich Client Platform. I'm going to talk a bit about the new shortcut system on eRCP. I thought this might be usefull because Archimedes' developers will have to do this a lot and a friend of mine was asking me about this and couldn't find anything around.

First thing people will notice when having to handle with shortcuts in eRCP is that all action has a wonderful "accelerator" field which seams to make this help useless. Unfortunatly, if you use that accelerator you friendly get a warning message and once you take a look at it, you'll find out that it is deprecated. Well, as you all should know, deprecated means that you can use it... for now! You have absolutely no guarantee that in a couple weeks it will still be there. Therefore we should try not to create new features with things that might disapear in a couple weeks. So we agree that we should find another solution to it. Great!

Make some research you find out that there is a new way to do accelerators that is much more flexible and powerful. The only problem is you hardly find any example or tip anywhere. After having suffered a lot to find how it should be done, I reached this not so simple way but indeed much more flexible and powerful. Here is an example from Archimedes:

<extension
point="org.eclipse.ui.commands">
<command
defaultHandler="br.org.archimedes.orto.OrtoHandler"
id="br.org.archimedes.orto.command"
name="orto"/>
</extension>
<extension
point="org.eclipse.ui.bindings">
<key
commandId="br.org.archimedes.orto.command"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="F8"/>
</extension>


What this xml does?
Basically defines two new extensions: commands and bindings.
The idea is that each command can have several bindings or diferent bindings for diferent languages or platforms, etc...

Why do you need those?

What you really want is the binding extension which defines a binding between a command and a key sequence. Of course, you need a command in order to have this binding. That's why you need the command. Now, if you pay attention I had to create a new class (OrtoHandler) to deal with the key match event. This class has to implement IHandler interface that is a publisher that allows subscribers to listen to that event and informs whether it is able to run or not and has a run method. In most cases, this will replace or be the same class you used in your Action.

There you go. Now it is easy to define accelerators for your eRCP applications.