-
Content Count
2510 -
Joined
-
Last visited
-
Days Won
127
Everything posted by Anders Melander
-
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Here's what I have implemented for now. It's very rudimentary and applies globally: -
Delphi by Example: Images and Graphics
Anders Melander replied to Foersom's topic in Tips / Blogs / Tutorials / Videos
BMP, PNG, JPEG, GIF etc. are encoding formats. The sole purpose of TPNGImage, TJPEGImage and TGIFImage is to read, write and display these formats. Their internal representation is optimized to handle the features of the file format. They are not optimized to handle image manipulation. TBitmap on the other hand implements the BMP encoding and is internally represented as a native Windows DIB or DDB. TBitmap can wrap these with a TCanvas and thus provide access to most of the functionality of the GDI through the canvas. Additionally almost all other formats can convert to and from TBitmap so there's no reason why all the other formats should duplicate the functionality in TBitmap/TCanvas/GDI. They would just have to convert to/from TBitmap internally to do so anyway. Btw, using TCanvas.Pixels is extremely slow but fine for learning and very minor drawing tasks. For anything serious you have to mess with the raw DIB data directly - or use something like Graphics32 which does that for you. When you're using Pixels to manipulate the whole bitmap then the optimizations in the code become pretty pointless and only obfuscates the algorithm. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
No. But... OK. I will have to do something about that. For matches from TM the rule is that if I find an exact match in the TM then I do not equalize case (*). For example if I'm translating "Foo" and I find "Foo"->"bar" then I use "bar" as the translation. If I find "FOO"->"BAR" then I equalize "BAR" to "Bar" and use that. *) I still equalize endings and accelerators regardless of match exactness since the I consider TM data fidelity/consistency somewhat poor. I currently have the following equalization rules: If source has an accelerator then make sure target also has one. If possible use the same hot key. If source does not have an accelerator then accelerators are removed from the target. If source ends with a colon, semicolon or ellipsis then make sure the target also does so, but only add new ending if the target ends with an alphanumeric character. If source does not end with a colon, semicolon or ellipsis but the target does then remove the ending from the target. If source is surrounded with ( ), [ ], { }, " ", ' ' or < > then make sure the target also does so. If source is UPPER CASE, lower case, Title Case, Sentence case or simply Starts with an uppercase letter followed by a lowercase letter then make sure the target is too. It's implemented in the MakeAlike function in amLocalization.Utils.pas If I'm understanding you correctly then the only safe case rule between Czech and German is the UPPER CASE and maybe the Title Case rule. So if I'm making equalization configurable at what level should it be configurable. I mean I could make everything optional and all values configurable but it will be a nightmare to implement the UI for it and probably far too complex for the user to manage. I'm also guessing that the desired rules would differ between projects or even within projects, between languages. No. The "Apply new translations..." and "Apply to similar values" options controls if new translations are automatically applied to other identical or similar (via normalization) terms. For example if I translate "Foo" to "Bar" in once place, then it can automatically apply this translation to all other instances of "Foo" in the project. If the "similar" option is enabled then it will also apply the translation to "&Foo"->"&Bar", "FOO"->"BAR", "[foo]"->"[bar]" etc. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
New version up now: http://melander.dk/download/amTranslationManagerInstall-1.0.7251.4.exe BTM should normalize those when they are applied. For example if you have the translation "&Foo:" = "B&ar:" in the TM and you apply it to "(foo)" then the translation automatically becomes "(bar)". I try to equalize case (upper/lower/sentence/title/etc), accelerators, format strings, surrounds ()[]{}, etc. and terminators .:?... There might be more. I can't remember right now. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Bloody hell! The 7234 release was an early beta. This has happened before. From time to time my web hosting provider messes up and replaces new files with old files. I can see that the new files are gone and only the old file are left. I guess this means that everybody has been downloading obsolete versions. Please stop everything until I have resolved this problem. So you understand all those languages? Anyway I understand the use case now. I'll see if I can cook up a good UI for it. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
No not yet. The plan is to have support for multiple TM files and per project TMs. For now you can only change the TM via the registry: HKCU\Software\Melander\TranslationManager\Providers\TranslationMemory\Filename Actually I just realized that you should have (*) been able to use the "portable mode" to get per-project TM. If you copy amTranslationManager.exe to the project folder and then start with the -portable switch then BTM will look for the TM in the project folder. Just make sure that the above registry key value contains the value "%DATA%\TranslationMemory.dat" so the portable config file is initialized with the correct default value. *) Unfortunately it seems I managed to break portable mode just before release so I'll have to get a new version released before that solution can be used. I'll get that done this week end. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
No not yet. The plan is to have support for multiple TM files and per project TMs. For now you can only change the TM via the registry: HKCU\Software\Melander\TranslationManager\Providers\TranslationMemory\Filename No. The file can be saved anywhere. Inside the xlat file (it's an XML file) there should be a reference to the source application and this should contain a relative filename. Like this: <xlat> <project sourcefile=".\Win32\Debug\HelloWorld.exe" stringsymbolfile=".\HelloWorld.drc" language="1033"> ... The sourcefile value is relative to the xlat file. The stringsymbolfile is relative to the source file. There was a bug in an earlier version that broke relative file names but they should work in the latest release (v1.0.7241.65070). Yes. I can add something like that. I already do duplicate detection when adding terms from the translation editor, but I don't do anything when importing translations in bulk (e.g. from TMX). -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
No. The Microsoft Translator Text service only support a single translation per language. That sucks. I guess they're not dogfooding this API. The strange thing is that they claim it powers Bing translate which can find multiple translations per source value. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Just use the [Delete] key... -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Sure it's possible. Translations are always associated with a context, the context being the module (form), the component and the property. If you're doing automatic translation (i.e. machine translation), then the context is not used, only the source language and source text. However if you have more than one translation of a term/text in your Translation Memory, then BTM will prompt you to choose a translation for each of the different source terms. You can choose to use the same for all or use a different one for each of them. For example here I have added the three different Czech translations of the term "Volume" to my Translation Memory (forgive me if I mistranslated - I don't speak Czech 🙂 ): If I now perform a machine translation from Translation Memory then I will be prompted: If doing manual translation then BTM will indicate to you that it already know these translations (even if you haven't added them to the Translation Memory) so they can be easily reused. For example the grid will mark the terms that has known translations and display them as a hint: and during manual edit you can choose from these translations in a drop down list: The principle is the same if I perform machine translation using one of the web services. For example here's the prompt I get when using Microsoft Terminology Service: Strangely, if I use Microsoft Translation Service then I only get one term back: "Objem". but that might be caused by a misconfiguration on my part. I'll investigate. -
How to use Open Street Maps with Delphi - cross platform?
Anders Melander replied to mawg's topic in FMX
Amen! https://killedbygoogle.com/ -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Thanks. I had a feeling I might end up having to script my way out of it. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Well yes, but there's the existing installer types and components to take into account. I mean I currently have the default three Types: Full, Compact and Custom. I don't mind getting rid of Compact but if I must chose between Full and Custom then it's Full that goes. Anyway, let's say I go with your suggestion: Normal and Portable, both of which will probably then install the Full component set. Now I then need to copy some files into {userappdata}\foo in Portable mode but into {app}\bar in Normal mode. How do I do that without having to duplicate the [files] entries? And then there's the [Icons] section. I should probably not create any shortcuts in Portable mode but as fare as I can see it's not possible to control [Icons] based on Type - only based on Components. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
It's no problem creating a separate installer for portable mode. I could even just zip the files and leave it at that. The problem is getting the existing installer to have a "portable mode" option. -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
The application would do this for you automagically, so you wouldn't notice that it's using the registry internally. Anyway I just finished implementing it. It's available in version 1.0.7241.65070 You can now run in portable mode either by specifying it with a command line switch: "amTranslationManager.exe -portable" or by placing a file named "portable" in the application folder. The application settings dialog can also do this for you. When in portable mode, settings are read from and written to a "amTranslationManager.portable" file located in the same folder as the application. Application data files (Translation Memory, user spell check dictionaries, etc.) are also stored in or under that directory. One problem that I haven't solved is how to get the Inno Setup installer to create a portable installation. -
Pointers... loops...
Anders Melander replied to Sonjli's topic in Algorithms, Data Structures and Class Design
Never used it. I just Googled "cnc_rdalmmsg2" to find out if the function provided some means of determining the required buffer size. Like it is common with WinAPI functions (ERROR_INSUFFICIENT_BUFFER). -
Pointers... loops...
Anders Melander replied to Sonjli's topic in Algorithms, Data Structures and Class Design
The array is static and is allocated on the stack. You could also use a dynamic array to have it allocated on the heap. Static is faster but stack space is limited. Regardless the array is automatically deallocated when it goes out of scope. Anyway: procedure TRdAlmMsgActionA.InternalRdAlmMsg; const MaxMsgs = 50; var rn: SmallInt; popmsgs: array[0..MaxMsgs-1] of ODBALMMSG2; i: integer; begin ... while (True) fo begin rn := MaxMsgs; // rn on entry contains max items the buffer can hold // rn on exit contains number of items now in buffer // See: https://www.inventcom.net/fanuc-focas-library/misc/cnc_rdalmmsg2 FConnection.ErrHandle := cnc_rdalmmsg2(FConnection.ConnHandle, -1, rn, @popmsgs[0]); if (rn = 0) then break; // No more available for i := 0 to rn-1 do begin popmsgs[i].whatever... end; end; end; -
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
I've thought about a portable version but the framework I use for configuration persistence is highly dependent on the features provided by the registry so I would have to rewrite most of that. The use of %appdata% is easy enough to redirect to the application folder. I already do that for debug builds. One solution would be to have the application export the content of its registry branch on termination and restore it again on start. Would that be satisfactory? Another solution would be to package it with an application virtualization system, like WMware ThinApp, but I'd rather not go down that road. -
There's generally no need for TForm.Release when you destroy the form from the outside. Just call Free directly.
-
ANN: Better Translation Manager released
Anders Melander replied to Anders Melander's topic in Delphi Third-Party
Thanks. I've now added a download link at the top of the readme to make it a bit more obvious. Feel free to comment or ask for help about anything here or at the issue tracker. I know it could do with some documentation but the readme is too big already and I have other projects in need of some love (also, who likes writing documentation? ). -
Holy sh*t! I looked at the Gimp source and as far as I can tell this is the library they use to support HEIC. I wonder how they have gotten round the patents and after reading about them I'm surprised Gimp would even support the format. Maybe you don't need a license to decode. I'm a bit confused about the difference between HEIC and HEVC. I get that I stands for Image and V for Video, but from Wikipedia I get the impression that Apple's HEIC files have been HEVC encoded: Anyhow, the patents alone are enough that I would stay away from the format.
-
Here's the source for a C++ library: https://github.com/strukturag/libheif Now you just need to convert it to Delphi. Let us know when you are done 🙂
-
Forum favico is unsuitable and huge, need replacing.
Anders Melander replied to a topic in Community Management
What about it? The content is still perfectly valid. -
Forum favico is unsuitable and huge, need replacing.
Anders Melander replied to a topic in Community Management
Sure it is. It's just hard to find these days. https://docs.microsoft.com/en-us/previous-versions/ms997538(v=msdn.10) -
Form no longer repaints after WM_SETREDRAW
Anders Melander replied to aehimself's topic in Windows API
Not a good idea IMO. I use it rigorously on member variables to catch stale pointers but I consider the consequences every time I use it. Sometimes it should not be used: https://www.devexpress.com/Support/Center/Question/Details/T812550/race-condition-in-threaded-load-can-cause-access-violation Anyway, I tried to reproduce your problem but couldn't. I've attached my test case. FWIW there was no flicker to eliminate in the first place... Unit5.pas Unit5.dfm