Code templates - unit name clash between Delphi versions - delphi

Different Delphi versions (in my case 2007, XE and XE2) seem to use the same code-template repository, such as ..\Documents\RAD Studio\code_templates. Since XE2 uses namespaced units, this causes problems when one have to use a unit name in a template.
For instance I have a template when I write winbeep which completes to windows.Beep(300, 100); and selects and stops on frequency etc.. This does not compile on XE2 unless I remove the Winapi. part of the Windows unit in the uses clause (or of course add the prefix manually). I have to have the unit name because otherwise SysUtils.Beep gets referred.
I couldn't find an option entry or a registry key or an environment variable specifying the place of the templates. It is not even related to BDSUSERDIR, in fact I don't even have a directory in my computer having the path of BDSUSERDIR (which is ..\Documents\RAD Studio\9.0). Is this my oversight and in fact there's an option to relocate code templates? If not, is it possible to make the IDE use unit aliases in uses clause for new forms?
edit:
Here it is stated that (emphasis by me) "Templates that you create (and templates provided by third party add-ins) are saved by default in the \My Documents\RAD Studio\code templates\ directory." That would imply there should be way to save them in a non-default place. But the article does not mention how.

You can put your templates in "Delphi installation folder"\ObjRepos\en\Code_Templates to make them visible only on one Delphi version.

Edit
As Sertac points out in the comments, Template libraries are related to project templates, not code templates. Leaving this answer in place because it may help people looking for ways to structure / share / split their project template repositories.
In Delphi XE2 you have a "Template libraries" option under the "Tools" menu. When you open that, you get this dialog:
The "Add" button allows you to add a folder, the "Properties" button allows you to view and manage the contents of that repository.
So it would seem to me that you can simply copy the template library, change it XE2 specific stuff, and then point XE2 to its own repository. Or you could do that only for the templates that require specific XE2 unit handling.

Related

Can the Option Set file for Delphi 10 be set programmatically using the OTAPI?

Is it possible to automate setting the Option Set file reference programmatically when creating a new Delphi project using the IOTAProjectOptions respectively IOTAProjectOptionsConfigurations interface1?
Or can I do that using any of the other OTAPI IDE services2?
I'm currently using the RAD Studio Delphi 10 Seattle IDE. Though, if newer OTAPI versions would support that feature, I'd still like to know about that.
I couldn't find any appropriate property or function, that seems to do that action in my current ToolsAPI.pas.
I want to achieve the same as choosing Apply Option Set -> Reference at the root project configurations root node in the IDE's project manager view:
Hypothetically I'm looking for some functionality like
procedure IOTAProjectOptionsConfigurations.BaseConfiguration.ApplyOptionSetReference
(const optSetFilePath : string);
A bit more background:
I'm currently developing legacy project wizards for our company wide Delphi project settings. I already have a working IOTAProjectCreator implementation that also manipulates the .dproj MSBuild XML file after it was generated and saved by the IDE. I'm just adding some conditional Import elements there.
Now we also want to use a Options Set file that is stored at a central repository. I know and studied the differences done in the .dproj XML, after that action was applied using the GUI, but there's a non negligible amount of logic going on (regarding dependencies and such), and I'm refraining to (re-)implement that logic via plain XML file manipulations. Not to mention that the necessary logic is prone to be changed with future versions of the IDE.
1)I'm trying to use that in the context of a IOTAProjectCreator implementation, with the definition of the procedure SetInitialProjectOptions(NewProject : IOTAProject); function.
2)It's a shame that these features are documented so poorly.

Delphi Prompt to Add to Uses

Just upgraded from Delphi XE to Tokyo, and was hoping for some updated IDE features.
One nice to have feature would be automatically providing options to add a unit to the uses clause. For example, if you reference something in code that isn't in a uses, it would be nice if the IDE prompted you to add the related unit(s).
For example, keeping it simple, in IntelliJ, you might declare a Button, but not yet have added the associated Library to the Import clause.
When this happens, the offending line is highlighted (just like in Delphi), but the IDE will let you add the necessary library with an Alt-Enter. If there are multiple libraries (it knows about it) it will prompt you for the one you want.
Anything like this for Delphi?
Delphi 2007 and later versions support this for most types that it knows about (in the search or library path). (It may have been available in D2005/2006; I don't have them installed anywhere now to check. I know it was not in Delphi 7.)
Put in the type, and use the Refactor menu (Refactor->Find Unit) or press Ctrl+Shift+A.
Here's an example:
It's not 100% effective, but it's a vast improvement over the old way.
(And yes, I know about TArray<string>, before someone chimes in. I just grabbed a quick type that I knew wouldn't be in the default VCL form uses clause for an example.)

delphi integrate custom file editor into IDE

I have deveoped a custom file type, together with a custom editor (basically a tree with several data pages attached and a few extra buttons). OK, I can run it stand alone and that is fine, and even add it to the tools menu, but I would like to integrate it into the Delphi IDE so that my custom editor (or a similar new version) appears in the IDE, rather like a DFM file has a custom editor. I can find references to most extensions in the Delphi IDE, but not this one. Any guiding hands? Note that this is not a property or component editor (the file type has nothing to do with either of these) nor is it simply syntax highlighting of a text file.
AFAIK it currently isn't possible to reliably integrate a custom editor into the Delphi IDE. The required API simply isn't there. See QC89028 Custom Module support.
During the Delphi 2010 and XE betas I spent most my spare time trying to get a resource editor integrated. Although the effort had the official blessing of Embarcadero and got some, half hearted, support from the IDE engineer, I was never able to get them to deliver on their promises and surface the module API. I eventually abandoned the project.
Update: I've now checked my old correspondence regarding this and it turns out part of the problem was that IOTAModuleCreator (used to implement File|New for custom file types) and IOTAEditorContent (used to transfer data to/from the custom module) only supports text data. Binary data gets mangled.
You can probably do this via an IDE plugin that uses the ToolsAPI (see ToolsAPI.pas in the IDE's source folder (e.g. Program Files (x86)\Embarcadero\Studio\source\ToolsAPI\ToolsAPI.pas.)
For information on writing a plugin in general, see David G Hoyle's excellent blog. Once you know the basics - i.e., write a 'wizard' and get it to do something - you will need to work on integrating your editor.
I have never done this, and so I can't guarantee it is possible. However, some interfaces that look worth investigating and implementing are INTACustomEditorView, which represents a 'view' (file tab when that file is open - think the code editor, Welcome view, type library editor, etc) and IOTAEditorViewServices, to register your custom view. I do not know how you associate a view type with a file type, sorry - possibly something to do with the personality interfaces. You might also be interested in INTACustomEditorSubView which is what creates a tab on the bottom of a file.
Good luck, and if you find a solution please write here so that other people can learn too!

Delphi - locating path of a unit which the compiler can not search in its default path

I have downloaded a component that has many packages in it, then I have install all the design time packages and generated all the other dcu files.I have to assign its path in Delphi search path every time I create a new application. Is there a way to assign its path to Delphi compiler search path once and all application will get access to these unit, so that I need not to manually set every time the path for a new application.
If you want to have some component automatically available for every new projects you need to change the default Delphi IDE options - specifically path locations - so that Delphi IDE knows where to find needed files.
You do this by going into menu Tools -> Options. Then in the TreeView which is used for splitting the options into multiple categories you select Enviroment Options -> Delphi options -> Library.
On the right side of the window you will now have different options regarding the path locations for libraries and source files.
In order to allow Delphi to find needed precompiled units of your component you need to add the folder in which they are located to Library path.
In order to allow Delphi to find source files of your component you need to add the folder in which they are located to Browsing path.
You can read more information about these settings in the Delphi documentation which is also available online here:
http://docwiki.embarcadero.com/RADStudio/XE6/en/Library
Note if you don't own Delphi XE6 but one of the previous XE versions simply change the webpage URL by replacing "XE6" with the one you own.
EDIT: I have edited my answer to provide more specific information. Old post below:
If you got to Tools -> Options (or is it Enviroment Options in latest versions) you can set Default options for the Delphi IDE. These options also include the Default path settings which will be automatically used in all new projects.
The way I do this is to have a folder "Lib2" which I use as the unit output directory whenever I compile/install components - I let the components (I mean their source files, etc) be installed whereever they want).
(I call it "Lib2" because traditionally Delphi has placed its own DCUs in a folder called "Lib", and putting all the third-party ones in a folder separate from that one avoided having to re-install Delphi if my set-up got into a mess.)
If you do that, all you need do for new projects is to include the path to that folder in the project search path and set that as the default search path.
The way to do that varies with Delphi version - the D7 era it was just a question of ticking the "Default" checkbox on the Directories/Conditionals tab of Project | Options. The only minor problem is that sometimes the component needs a resource file; if the compiler complains about that, just copy it to there manually.
In XE4, there are several ways of getting Delphi to find compiled DCUs that you've send to Lib2 or whatever you care to call it:
The simplest seems to to do what the other answer suggests, namely add the Lib2 path to the list of Library paths under Tools | Options. The compiler will then use the DCUs it finds there without needing to be able to finds their sources, which is generally a good thing (see "btw" section below).
A second way is to create a project "Option Set" (see the OLH for details of what they are and how to create one, and then edit it (again, see OLH) to include Lib2 in the list of search paths. After that, you can apply that Option Set to any project which it suits. There may be a way to automatically apply your Option Set to new projects, but I haven't managed to find it yet. In any case ...
A third way is to add a project which has Lib2 amongst its search paths to the Delphi repository and then create new projects that you want to use Lib2's contents from this entry in the repository.
Btw, there is an important practical point to having 3rd party libraries and any of your own standard ones output their DCUs to your Lib2 or equivalent. Because the compiler can find the compiled DCUs there, it does not have to be able to find the source code of those libraries in order to be able to compile your project. Isolating the compiled DCUs in this way helps avoid the dreaded "unit x was compiled with a different version of y" error message (y usually being a bpl) which has been the cause of so many cries for help in Delphi newsgroups over the years.

Package (BPL) Automatic Naming Suffix

I write a lot of components and libraries for Delphi, most of which require the use of BPL Packaging so that they may be installed into the IDE.
This is simple enough and works well, right up until you want to maintain a single set of Package Project Files (in a single Project Group), but also want to compile and distribute those same packages for different Delphi versions.
Up to now I've been creating a different Package Project for each version of Delphi, and explicitly defining a Delphi Version Identifier as a suffix (e.g. Kinect_XE.bpl and Kinect_XE2.bpl).
I am aware that, in the Project Options for a Package Project, under Description, there are the fields LIB prefix and (more importantly for my needs) LIB suffix.
I am further aware that if I place a value in LIB suffix, it'll be appended to the end of the compiled BPL's filename.
My question, however, is first whether it is possible to have the IDE automatically populate the LIB suffix field with the IDE/RTL Version number, and if so... how?
I'm fairly certain this is possible, as it would appear that vcl120.bpl (and its counterparts for each respective version of Delphi) can be Referenced (as requirements) of your own packages using just vcl rather than having to type the full vcl120. It is, in fact, this same behaviour I'm hoping to achieve... where my packages can intra-reference eachother (as neccessary) without having to provide version-specific references to accommodate the suffixes.
Equally important is that resolving this will enable me to maintain a single set of Project Files in a single Project Group (with the obvious exception of XE2 where its Project Files don't necessarily behave very well with previous versions of Delphi due to the Platforms addition).
I suspect that I may need to put a value like $(VER) (or something similar) in the LIB suffix field, but this appears not to work and I've scoured Google looking for the correct solution.
Hope you can help!
UPDATE 1
I am now writing an IDE plugin to be used with (in the very least) Delphi 2007 to XE2, which gives DLL and BPL projects a new option called AutoSuffix. When toggled On, any IDE with the AutoSuffix plugin installed will immediately apply the correct IDE version suffix to the project.
The AutoSuffix plugin will be made available (freely) for everyone within the next 24 hours, and this question updated accordingly.
UPDATE 2
Okay... Delphi 2007 is being a pain! I've made AutoSuffix work with 2009 to XE2, so far, but 2007 requires a little more time (patience appreciated).
UPDATE 3
It would appear as though Embarcadero have heard our collective cry for simplier package unification between versions.
Mark is going to push this through to see if future versions of Delphi can accommodate a {$LIBSUFFIX AUTO} feature. I hope to hear back very soon whether this will be the case. If so, it certainly affects the way AutoSuffix will need to work on XE2 and older versions (as presently it doesn't provide the simple AUTO switch.. it has its own method).
My hope now is that EMB will take this request seriously, provide it as an integral feature going forward, so that it becomes a simple case of using AutoSuffix on existing versions to unify the process accross all versions!
AFAIK for Delphi up to XE2 there is no automatism for doing this.
Concerning the requires clause: when you require another package you are actually using the dcp, which doesn't inherit the LIBSUFFIX. Thus it is sufficient to require VCL.dcp during compile time, while VCL160.bpl is actually used during runtime. The DCP includes the complete BPL name to resolve that.
This makes the LIBSUFFIX approach superior to the simple "rename the package for each version of Delphi" one.
A solution like that suggested in QC83229 would make it easier to port a package to a newer Delphi version, but then you are still stuck with dproj files that are not backwards compatible.
I normally use different folders for each Delphi version, where only the project files are stored. For a new Delphi version I only have to copy a folder and change the LIBSUFFIX.
LIBSUFFIX directive is in *.dpk file, and you can edit *.dpk file manually.
You can write, for example
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF CompilerVersion = 20.0}
{$LIBSUFFIX '120'}
{$IFEND}
{$IF CompilerVersion = 21.0}
{$LIBSUFFIX '140'}
{$IFEND}
{$ENDIF}
The bad thing is that IDE does not respect your manual edits of *.dpk file and deletes them then you make changes in a package. That is why some component vendors that use conditional defines in *.dpk file say in installation instruction if asked to save changes say 'NO'.
My suggestion would be to add this as a configurable option to project option sets (see QC #86491.) Rather than updating all the packages it would be sufficient to update a single option set file.
In fact, it seems the DllSuffix tag is recognized by the option set files in Delphi XE/XE2. Adding <DllSuffix>160</DllSuffix> to the <PropertyGroup> section of an option set file will cause the suffix to be appended to the package in the project manager. However, you still have to open the project options and click OK in order for it to be saved to the .dpk file.
I agree that it would be extremely useful with this feature (I would think also for the packages in the RTL.)
{$LIBSUFFIX AUTO} feature was added in Delphi 10.4.1:
In previous versions (version 10.3 and earlier) of C++Builder and
Delphi developers building packages needed to manually set their
package’s library suffix setting. The DocWiki “What’s new in version
10.4.1” mentions a new IDE projects option for setting the library suffix:
“Package AUTO libsuffix: packages can now have an automatic version
suffix, instead of manually updating and specifying the right version
suffix with each new release. (The compiler quietly supported this in
10.4, but full support for the feature in the IDE and package project settings is introduced in 10.4.1.)”

Resources