Posts Tagged ‘Embarcadero’

LiveBindings in XE3: Updating Objects via an Adapter

Where I left off in my last post, we were able to bind our UI elements to an object, or indeed a collection of objects, by using the TAdapterBindSource combined with a TObjectBindSourceAdapter<T> or a TListBindSourceAdapter<T>.

Over a few posts I want to drill a bit deeper into what happens when you make changes to those objects, specifically in this post, when you make changes via the bound controls. I’ll explore the notification system that LiveBindings uses in later posts. Read On…

Call for Papers for ADUG Symposium 2013

The ADUG (Australian Delphi User Group) hold two, one-day conferences in the first half of the year, and each year they “import” a keynote speaker. They’ve just put out the call for papers for 2013, so if you’d like to score a free trip to Australia to present to a bunch of Delphi developers (don’t worry, we are mostly harmless), head over to their site and give them your ideas.

LiveBindings in XE3 – TBindSourceDB

RAD Studio XE3 brought significant enhancements to LiveBindings. The LiveBindings Designer is the most obvious of these, but there have also been a lot of additions made in the process of enabling the designer, some of which I’m going to explore over the next few posts.

First up are BindSources. If you did any work with LiveBindings in XE2, you would have used BindScopes. BindScopes were the way that you exposed different sources of data to the binding engine. TBindScopeDB, for example, let you connect to a TDataSource, and then bind the exposed fields to controls using LiveBindings. Read On…

One man’s URL encoding is another man’s bug

I got an email last night from someone who was using my sample code to open URLs in the default browser on OSX. However, he was having trouble when his URL contained a string.

Easy peasy, I thought, just URL Encode it. (Actually, easy peasy isn’t the phrase I used, but I’m trying to keep this relatively clean). I jumped into Delphi for what I thought would be a quick 5 minutes to alter the code, and finished 2 hours later with it finally working, having learnt more than I really wanted to know about URL encoding along the way. Read On…

Migrating SVN to Git with history

I’ve been using Git more and more lately, mostly because it allows me to do lots of checkins locally, even when disconnected, and then push those centrally when I get back online.

I’ve just gone through the process of migrating all my public and private SVN repositories to github (for the public ones) and BitBucket (for the private ones). A one-way migration is not that difficult, but a one-way migration with all the checkin history, branches and tags proved to be a little more involved. Read On…

Tool Palette OpenTools API sample available – MenuPalette

Back in 2007 I wrote an OpenTools add-in for Delphi and C++Builder called MenuPalette. It allowed you to search through all the IDE menu items inside the Tool Palette. You can read the post I made at the time for more details.

In a later version of Delphi, IDE Insight took this same idea much further, so I never bothered updating MenuPalette, although it’s still available for people on older versions. However, recently I’ve had a couple of people ask about the source code. I finally dug it out last night and published it on github, as I thought it might be a useful example of interfacing with the Tool Palette via the OpenTools API. I also updated it to work with the latest version of Delphi, as one of the questions was specifically about doing this in XE2.

Hope it’s useful.

Delphi, Dropbox and Live Templates

Live Templates have been in Delphi and C++Builder since BDS2006 and they offer a way to automate a lot of routine typing in the code editor, especially if you put in the effort to both tailor the standard templates and create new templates. There are plenty of other, better, resources about Live Templates, like this, and this, so I don’t intend to go into how to write your own.

However, customisations like this are a dual-edged sword: yes, they can make you more productive, but sit down in front of a machine that doesn’t have them and suddenly you’re even less productive than before you started. This has been happening more and more frequently to me as I find myself using Delphi in multiple VMs on multiple machines in multiple physical locations.

My Live Templates are in version control, so for awhile I was just trying to remember to checkout the latest versions prior to starting the IDE, but I’d forget more often than not, so while I intend keeping them in version control, this isn’t the solution I’m looking for.

What I want is a way to make sure my Live Templates are kept up to date on every machine, physical or virtual, with no ongoing intervention on my part. You know, kind of like Dropbox?

Well, actually, exactly like Dropbox.

When this realisation hit me, I got very excited. I already had Dropbox installed in most of the VMs I was using, so it should be a relatively easy thing to tell it to sync the xml files RAD Studio uses to store Live Templates, right?

Yes… and no.

Getting Dropbox to sync them is stupidly easy. I created a templates folder in my Dropbox folder and copied all my custom Live Templates into it (actually, checked them out of version control, but that’s beside the point). I gave Dropbox some time to do its magic and Bob’s your father’s brother, my templates are on all my machines!

Now I just have to tell all my instances of Delphi to look in this dropbox/templates folder. That should be as easy as setting the path to my Live Templates folder in the IDE options, and….err, hang on, there’s no IDE option for that?

OK Delphi, you’re gonna make me earn this I see.

So let’s have a look. In a default installation, the standard Live Templates that come with RAD Studio are stored in:

C:\Program Files\Embarcadero\RAD Studio\9.0\ObjRepos\en\Code_Templates

In addition, the IDE will look for any custom Live Templates you create in:

C:\Users\mgroves\Documents\RAD Studio\code_templates

Hmmm, that ObjRepos bit in the first path gives me an idea.

Attempt 1: There is an IDE option for setting a Shared Object Repository, really meant for sharing common forms and projects across a team so they are visible when you use File | New. This was there long before Live Templates were even a glimmer in someone’s eye, but still, maybe it’ll work for everything under that directory?

Unfortunately not. This could still be useful for sharing Object Gallery forms and projects across machines, if you use that feature, but no luck for templates.

Attempt 2: I didn’t really expect this one to work, but it was so easy to try I thought I’d quickly rule it out. I created a Windows Shortcut to my LiveTemplates DropBox folder inside my C:\Users\mgroves\Documents\RAD Studio\code_templates folder. Windows Explorer was happy, but the IDE was not fooled.

Attempt 3: OK, being polite didn’t get me anywhere, so let’s try a different tack: regedit. I spelunked around in the IDE registry keys for quite awhile, sure that I would find an option to change to tell the IDE where to look for user-defined Live Templates. It may well be there, but I didn’t find it.

I gave up and went and had a coffee. Something about Attempt 2 with the shortcut was nagging at me. I vaguely remembered something about a later Windows version getting a feature like Symbolic Links from Unix. Couldn’t remember what they were called, but basically, Shortcuts done properly. When I got back, a quick search revealed that in fact I was right, and that in Windows they were cunningly called….Symbolic Links. Read up on them here, but they are NTFS specific and introduced with Windows Vista. NB: See the comment below from Stefano Moratto about the junction command line tool, that looks like it will probably work for earlier versions of windows such as XP.

You create a Symbolic Link at the command line using mklink. You’ll need Administrator rights to do this, so start up cmd.exe as Administrator, navigate to your user-defined live templates folder (in my case C:\Users\mgroves\Documents\RAD Studio\code_templates) and type the following command:

mklink /D SharedTemplates c:\Users\mgroves\Dropbox\templates

The params are:

  • /D – tells it to create a symbolic link to a directory rather than a file
  • SharedTemplates – the name of the symbolic link that will be created
  • c:\Users\mgroves\Dropbox\templates – the directory to which the symbolic link should point. In this case, my templates folder being sync’d by Dropbox.

Do all that properly and you should see a message like this:

symbolic link created for SharedTemplates <<===>> c:\Users\mgroves\Dropbox\templates

Now, if my theory works, as far as RAD Studio is concerned, the contents of my Dropbox templates folder is actually in a subdirectory of C:\Users\mgroves\Documents\RAD Studio\code_templates called SharedTemplates.

Indeed, my theory did work. Firing up the IDE shows that all the templates in that dropbox/templates directory are available when you hit Ctrl-J, and Dropbox takes care of the hard work of keeping all my machines up to date.

This will probably also work if you’re using some other service apart from Dropbox. It could also be a way to get multiple people on your team sharing a single set of templates from a shared network folder, as a few people have asked about.

Oh, and if you don’t already use Dropbox, then consider signing up using this link and we both get an extra 500MB of space (yes, I’m shameless, I know, but I shove a LOT of stuff into dropbox).

Opening files and URLs in default applications in OS X

After my article on Special Folders, a few people asked how to open a file in the default application.

For example, if I open a JPEG, whichever application is registered as the default app for JPEGs will execute. This is roughly analogous to ShellExecute in Windows.

The question was also asked about opening a URL in the default browser and also sending an email with the default mail application. These are closely related so I’ll cover them at the same time.

It’s actually pretty easy. I’ve got a TOpenDialog on a form, and the following code in a TButton.OnClick event:

procedure TForm2.Button1Click(Sender: TObject);
var
  Workspace : NSWorkspace;
begin
  if OpenDialog1.Execute then
  begin
    Label1.Text := OpenDialog1.FileName;
    Workspace := TNSWorkspace.Create;
    Workspace.openFile(NSSTR(Label1.Text));
  end;
end;

Once we have the filename from the TOpenDialog, we create a NSWorkspace reference and use the openFile method, converting the filename string to a NSString on the way. NSWorkspace is defined in Macapi.Appkit and the NSSTR function to convert a String to a NSString is defined in Macapi.Foundation;

Opening a URL in a browser is slightly longer but not much:

procedure TForm2.Button3Click(Sender: TObject);
var
  URL : NSURL;
  Workspace : NSWorkspace;
begin
    URL := TNSURL.Create;
    URL.initWithString(NSSTR('http://www.malcolmgroves.com'));

    Workspace := TNSWorkspace.Create;
    Workspace.openURL(URL);
end;

Instead of the NSWorkspace.openFile method, we need to use openURL. This expects a NSURL as a parameter, so we construct that and load it up with the initWithString method, again converting our String to a NSString along the way. Executing that code causes Safari (on my machine) to open my website.

Opening a new mail and setting the To, Subject and Body is much the same, just down to the string we pass into our NSURL:

procedure TForm2.Button2Click(Sender: TObject);
var
  URL : NSURL;
  Workspace : NSWorkspace;
begin
    URL := TNSURL.Create;
    URL.initWithString(NSSTR('mailto:fred@flintstones.com?subject=Hello&body=Hello%20Fred'));

    Workspace := TNSWorkspace.Create;
    Workspace.openURL(URL);
end;

You can download the sample project from my delphi-samples repository on github.