PhotoTagStudio 0.7 released

Tags: , ,
No Comments »

Today I released the new version of PhotoTagStudio with a lot of stability and usability enhancements and the ability of changing exif time and date data.

Some more new features are:

  • Support for drag and drop from PTS to other applications (e.g. the explorer).
  • Navigating from picture to picture in the current folder with the PageDown and PageUp keys.
  • Deleting files from within PTS with a Button and the Del key (don’t worry, you will be asked again before deleting and deleting means moving to the recycle bin!)
  • Since PTS contains more and more features form version to version some of them are now by default hidden. Take a look at the configuration dialog or use the right-click-context-menu on the tab header on the right side if you are looking for a missing feature.

See http://phototagstudio.irgendwie.net/

Preventing model elements from being deleted

Tags: , , , ,
4 Comments »

One would think, it is a simple feature in the DSL Tools framework to allow and forbid the deletion of model elements, but it isn’t.

There are a few posts in the DSL Forum and it seems there are even a few methods to forbid the deletion. But every single solution has its pros and cons and you have to write a little bit of code yourself. Just take a look at the following postings:

One solution is to throw an exception from within a DeletingRule, but I personally don’t like this. It means, the user is able to click on a delete menu item and then an error message box pops up. This is not a good user experience!

I think the best would be to hide the "delete" commands from the menus. If you disable the commands, the delete key isn’t working, too. But there are two places where the user can find such a "delete" command for the model elements: on the design surface of the DSL Editor and on the items of the DSL Explorer (and further more: the DSL Explorer has a "delete" and a "delete all" command on different tree nodes). You have to handle both cases.

I would just like to have somewhere a bool CanDelete() method that is called every time the menu is shown and asks my component whether to allow the deletion or not.

Now the good news: I added this Method and wrote a little piece of code for it!

First I created a very simple Interface

public interface IDynamicCanDelete
{
    bool CanDelete();
}

With this interface you can add the missing method to your shapes or model elements. I recommend to implement this method in the model elements since the model explorer knows nothing about your shapes and cannot call this method if implemented in the shape classes. You don’t need to implement this method for every model element, but only for those you want to forbid deletion. Just return false or implement some logic based on the model element state.

If this feature would be part of DSL Tools that is all you need to do. Though since it is only an addition to it, you have to connect some methods with my library:

  • In the DslPackage project add a partial class for your MyLanguageCommandSet and override the following method:
  • protected override void ProcessOnStatusDeleteCommand
                                       (MenuCommand command)
    {
        OnStatusDeleteCommandLogic.ForEditor(command, 
                        this.CurrentDocumentSelection, 
                        base.ProcessOnStatusDeleteCommand);
    }
  • In the same project add a partial class for your MyLanguageExplorer and override two methods:

    protected override void ProcessOnStatusDeleteCommand
                                        (MenuCommand cmd)
    {
        OnStatusDeleteCommandLogic.ForExplorerDelete(cmd, 
                      this.SelectedElement,
                      base.ProcessOnStatusDeleteCommand);
    }
    
    protected override void ProcessOnStatusDeleteAllCommand
                                            (MenuCommand cmd)
    {
        OnStatusDeleteCommandLogic.ForExplorerDeleteAll(cmd, 
                     this.ObjectModelBrowser.SelectedNode, 
                     base.ProcessOnStatusDeleteAllCommand);
    }

That’s all, but what’s happening inside the OnStatusDeleteCommandLogic class? I’m looking for the selected elements (that are shapes in the editor or TreeNodes in the DSL Explorer) and check whether they implement the IDynamicCanDelete interface. If there is this interface I will call the CanDelete() method and if it returns false the delete menu command will be disabled and set to invisible.

For the Editor I will check the shape and the corresponding model element. If there are multiple elements selected only one must report false to disable the command.

The DSL Explorer provides a Delete All command on some nodes. For this command I will check all children but not the grandchildren.

For more details please take a look at the source code.

Download the files

Update

This code is now part of the JaDAL – Just another DSL-Tools Addon Library project. Please download the current version from that page. The download over at CodePlex contains the source code described here, an example DSL language and the library as a binary. Future enhancements of the code will be published there, too.

Additional bug fix for the explorer

DuncanP mentioned at the end of his article a small bug in the behavior of the model explorer. This bug can make the “Delete All” command visible when you don’t want it to be. He described an idea for a bug fix. I can find the same wrong behavior in the current release for Visual Studio 2008 and implemented a bug fix the way DuncanP pointed out:

Add the following code in the MyLanguageExplorer class

public override void AddCommandHandlers(IMenuCommandService menuCommandService)
{
    base.AddCommandHandlers(menuCommandService);

    MenuCommand deleteAllCommand = 
        menuCommandService.FindCommand
            (CommonModelingCommands.ModelExplorerDeleteAll);
    this.ObjectModelBrowser.AfterSelect += 
        delegate
            {
                ProcessOnStatusDeleteAllCommand(deleteAllCommand);
            };
}

WinXP network connection problem: Not enough server memory ("Für den Befehl steht nicht genügend Serverspeicher zur Verfügung")

Tags: ,
No Comments »

Hi!

I just found a solution to a problem that was getting on my nerves for quite a time: I am using three computers, all WinXP Pro. They are all connected in one simple network and I don’t use much more than some folders to copy files from here to there. It worked fine for a long time but one day I couldn’t connect to anyone of the computers anymore. I am pretty sure I didn’t change a thing – it just happened. I browsed a lot (and I mean a lot) of websites that are dedicated to this problem. Most of them say (text copied from here):

  1. Start the registry editor (e.g., regedit.exe).
  2. Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services \lanmanserver\parameters.
  3. Double-click IRPStackSize (or if this registry setting does not exist, create it of type DWORD and ensure the case is correct).
  4. Change the base to decimal, set the value to the default value for your OS, and click OK.
  5. Reboot the computer or restart the “Server service”.

It did not work for me.

But I found the solution two minutes ago one on single German web site: When changing the value of IRPStackSize DON’T CHANGE TO DECIMAL. Change to (or leave it at) hex!.

Hex 30 (= Dec 48) was enough for me and after a reboot it worked again.

What a bug, MS, please fix it!

Bed time story "the weird hard disc"


No Comments »

Here is a true story that happened to me six month ago:

My girl friend Grace wanted to go shopping and put me in the trunk, so I had to join her. We went to some discount supermarket (“Plus”) and she bought veggies, I bought meat, she bought tooth paste, I bought sweets. Then I stumbled about a nice offer: “400GB external USB-HDD for 99€” with a sticker saying “Samsung-HDD inside”. 99 was pretty cheap at that time and my experience with Samsung-HDDs is very good, so I put one in our shopping cart.

Back home I stored the meat and attached the new hdd to my laptop. Plopp – new drive found, drivers installed, everything cool. I did a format which went through quickly. “Here you are – congratulation to you new hard disc! – 3 GB ready to go.”

Uhm.. wait a moment. I didn’t expect 400, but something like 370GB found be fine. 3 GB is a little lesser than I expected. Hmm..

unattached it, attached it again – 3GB.

did another format – 3GB.

looked for a software or even a bios update for my laptop – up to date.

did some silly Google searched – nothing found.

tried another computer – 3GB.

Hmm… I started thinking… okay, let’s face it – 1 kb is officially reduced to 10byte, they just didn’t inform you.  Or maybe there is something wrong with the wires inside, a pin broken for the higher bytes or something. I fetched my mini screw driver and opened the case. Looked okay, the cable was clean and in place, the pins seemed  fine. There was a little table in a blue font giving numbers of sectors, cylinders and heads, but I couldn’t find any information on the size. Then I saw the brand: Maxtor. Maxtor? It was supposed to be a Samsung, wasn’t it? … What the heck?!? Suddenly the light of realization hit me very, very hard. I sat in silence for minutes – in deep disbelieve. It was sooo simple.

Some criminal had bought the original 400GB-HDD and replaced it with his (or her) old 3GB. Then he (or she) had taken it back to the shop, saying it wouldn’t work. He would get another one or his money back. Buy one – get one free. Bastard!

When I discovered this I felt like Monk and I was very excited. I went back to the shop, asked for the store manager (which was a friendly woman who looked like YarYar Binggs) and told her everything. Her reaction was very… well.. minimalistic and a little disappointing – all she did was to hand me a new hdd. (That one was 400GB)

Later I found I should have tried to recover some data from the 3GB-HDD, perhaps I could have helped to arrest a thief of 397GB but the good ideas are always late…

Have a good night and don’t let the bed bug bite you.

To restrict dynamically the usage of Domain Properties in DSL Models

Tags: , , , , ,
1 Comment »

What’s the matter?

If you define Domain Properties on your Domain Classes and Shapes, you can configure the way a user of your DSL can interact with this Domain Properties. With the properties Is Browsable and Is UI Read Only you can hide a property from the Properties Window, make it read only or give the user full access to it.

But I want to change this behavior of certain Domain Properties dynamically at runtime!
Why the heck would someone need this? I don’t know, but I can tell why I need it: I’m designing a DSL with two types of users in mind. The DSL should look the same to both users, but one user can edit the whole DSL and change every property while the other user is not allowed to do so. Some properties will be disabled (read only) and some other properties will be invisible to the second user.

Another scenario could be a simple and advanced mode for some DSL Editor and the user can switch between these modes in some options dialog.

How do you use it?

First I want to describe the using of my library. If you are not interested in understanding how it works, you can use the library after reading this section.

First you have to define an enumeration with the modes your editor should support. The enumeration can contain more then two elements if you need more modes. The special Value 0 is used for the editor in the way you defined it within the DSL Tools. You should define your properties with Is Browsable set to true and Is UI Read Only set to false.

public enum RestrictionModes
{
    Original = 0,
    Simple,
    Advanced
}

Than you can provide your Domain Classes and the Domain Model with the RestrictedProperty-Attribute to configure the different properties:

[RestrictedProperty((int)RestrictionModes.Simple, 
                    "P1", Restriction.Hidden)]
[RestrictedProperty((int)RestrictionModes.Simple,
                    "P2", Restriction.ReadOnly)]
[RestrictedProperty((int)RestrictionModes.Simple, 
                    "P3", Restriction.ReadOnly)]

[RestrictedProperty((int)RestrictionModes.Advanced, 
                    "P1", Restriction.Full)]
[RestrictedProperty((int)RestrictionModes.Advanced, 
                    "P2", Restriction.Full)]
[RestrictedProperty((int)RestrictionModes.Advanced, 
                    "P3", Restriction.ReadOnly)]
partial class ExampleModel
{
}

The ExampleModel has three properties (P1, P2, P3) and in the original DSL Editor these properties are all writable. Properties that are not mentioned by the attributes will work as defined.

If the Restriction Mode is set to RestrictionModes.Advanced two of them are fully assessable (in fact you do not need to create Attributes to set the properties to Restriction.Full since this is the default value) and one is read only. In the RestrictionModes.Simple-case one property will be hidden and two are read only.

You can assign these attribute to each class that shows properties in the Properties Window. That are Model Elements, Shapes, Connectors and the Model itself.

After that you have to create a partial class for your Package and "activate" my library for each Class that uses these attributes:

partial class RestrictPropertiesTestPackage
{
 protected override void Initialize()
 {
  UserRestrictionProvider.RegisterRestrictedElement<ExampleElement>();
  UserRestrictionProvider.RegisterRestrictedElement<ExampleModel>();

  base.Initialize();
 }
}

Or use the shorter way to add all classes with one line of code. This will use reflection to find the classes.

UserRestrictionProvider
 .RegisterAllRestrictedElements
<RestrictPropertiesExampleDiagram>();

Now there is only one step left: how to change the mode. Each Store (that is the class where the Elements of a Model are stored in memory) is mapped to one Restriction Mode. So you can define one mode for each Store and so one mode for each Model or Diagram. The Store can be accessed from each ModelElement, so as a key for this purpose it is a great value. There is a UserRestrictionProvider class with two static methods:

  • public static void SetRestrictionMode(Store store, int mode)
  • public static int GetRestrictionMode(Store store)

You can use these methods whenever you want to change the Restriction Mode. For the demo project I used a Domain Property of the Diagram with Custom Storage.

How does it work?

With the UserRestrictionProvider.RegisterRestrictedElement()method I register a special TypeDescriptionProvider to the global Component Model (via the TypeDescriptor.AddProvider() method). This new Provider is be asked from the IDE whenever a list of all properties of a particular object is needed. At this point it is easy to remove some properties form the original list (this properties are not be shown in the Properties Windows) or make them read only (see the ReadOnlyPropertyDescriptor class in my code).

For more in depth information feel free to take a look at the source code.

…but beware

All these property restrictions effect only the properties windows. The properties can be changed and accessed by code and via other elements of the DSL Designer (for example TextDecorators and the DSL Explorer).

Download

In the zip file you will find all described classes in one project and an example DSL project.

Update

This code is now part of the JaDAL – Just another DSL-Tools Addon Library project. Please download the current version from that page. The download over at CodePlex contains the source code described here, an example DSL language and the library as a binary. Future enhancements of the code will be published there, too.

Some great resources on VSX

Tags: , , ,
1 Comment »

As you all know I’m working with Visual Studio Extensibility (VSX) at the moment. VSX is a interesting field to work with but it is badly documented. There are some samples, some books, communities and so on and if you search the web for a while you can find answers to most of the basic questions. But to begin programming Visual Studio extensions it is hard to find some place to start.

As a starting point I will recommend DiveDeepers blog to you. He posted a great series of articles on VSX. Take a look at the articles starting with "LearnVSXNow!" and "LVN Sidebar".

C# operator I didn’t know: ??

Tags:
No Comments »

I didn’t know how this could happen. There’s a operator part of the language I love and I didn’t see it anywhere till today. I think many of you didn’t knew about the ?? operator either. And by the way: it is part of C# since C# 2.0!

How often do you write code like this?

string a, b;
if (a == null)
    b = "some default value";
else
    b = a;

You have to check for null and use some default value if your object is null. The code can be written a little bit shorter with the ?: operator:

b = (a == null) ? "some default value" : a;

It’s nice but with the ?? operator it is much cooler:

b = a ?? "some default value";

Let me quote the msdn library: "The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand."

You can use this operator with every object type and with every nullable type (like int?).

iTunes and multiple libraries

Tags:
1 Comment »

For some reason it can be a good idea to manage your music shared over multiple libraries in iTunes. For example I have one library with all music stored on the disk of my notebook – this is my favorite music and I use this library when I travel. At home much more music is stored on a Linux server and I can access this music over a samba share. My second library holds all the music I can only listen to at home.

But it seems there is no function in iTunes called open library or similar. It is a well hidden feature: when starting iTunes just hold the Shift-key until the following dialog appears.

iTunesChooseLibrary

 

(On a Mac another key is used to get to this dialog. It’s one of shift, command, apple-key but since I don’t own a Mac I don’t know. Maybe someone can comment it.)

Visual Studio – more recent projects

Tags:
No Comments »

The start page of VS offers a list of the recent projects. It’s default length is 6, which is usually too short. I just found out that you can increase this length up to 24 in the Options\Enviroment\General-Tab.

. bla[7]

I am happy.

Subversion deadlock and Copernic desktop search

Tags:
No Comments »

Subversion is just the right thing for the small sized projects Benjamin and I do. We like it, put it’s not perfect and sometimes you find yourself in a deadlock like this one: Committing fails, because you need to update. Updating fails, because you database is corrupt and needs a clean-up. Cleaning-up fails, because there is lock on some files or folders from a previously failed action. Releasing the lock fails for any other reason.

After working with subversion (and the Tortoise-client) for a couple of years I know how to handle most problems, but last week I ran into an really persistent deadlock that drove me crazy. After almost two hours and finally attacking the problem with process-explorer, I found the cause: Copernic desktop search had locked a file inside a .svn – Folder, so it couldn’t be changed or deleted.

So be sure to have the "Indexing performance" of Copernic desktop search or similar tool switched off, when working with Subversion.

bla[7]

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in