Archive
QTX Library for Smart Mobile Studio updated
QTX (Quartex) is a library written for Smart Mobile Studio users. It extends the run-time library with a wide range of capabilities, including database (dataset) support, custom effects, tag-attribute storage and much, much more.
If you are a serious HTML5 developer using Smart Mobile Studio, then this library is a must. The font and content measurement alone is worth the download – and did I mention that it’s free?
Library overview
QTX is packed with classes and methods, and I have done my best to make it as easy as possible to understand. I take it for granted that you understand the concept of HTML-Tags, and that you understand that Smart Mobile Studio code creates TAGS when it’s constructor fires, and removes the tag when the destructor executes. As such, we have no need for libraries like JQuery – because the handle (reference) to the element is always known. JQuery is ultimately about extracting tags within a criteria from the DOM (hence “Query” in the title, as in SQL for querying a database).
What we do like however, is plenty of effects – and dead simple syntax for using them. Well it doesnt get any easier than with QTX. The QTX library extends TW3CustomControl with it’s own class helper, meaning that once you have included the qtx.effects unit – all your controls supports the whole range of effects.
Also, effects are executed in sequence. You can trigger 10 effects and they will execute one by one, which is no small feat under HTML5 (but easy with QTX tag attribute support).
Here is a brief overview of the classes and methods you get when installing QTX:
Database
- TQTXDataset
- TQTXDatasetField
- TQTXBooleanField
- TQTXIntegerField
- TQTXFloatField
- TQTXStringField
- TQTXDatasetFields
- TQTXFieldDef
- TQTXFieldDefs
Tag-Attribute Storage
- TQTXAttrAccess
CSS3 GPU powered animations
- TQTXMoveAnimation
- TQTXFadeAnimation
- TQTXSizeAnimation
- TQTXAnimationHelper
Effect management
- TQTXEffectsHelper
- fxSetBusy
- fxBusy:boolean
- fxScaleUp
- fxScaleDown
- fxSizeTo
- fxMoveDown
- fxMoveUp
- fxMoveBy
- fxMoveTo
- fxScaleTo
- fxZoomOut
- fxZoomIn
- fxWarpIn
- fxWarpOut
- fxFadeIn
- fxFadeOut
Font and content measurement
- TQTXTextMetric
- TQTXFontInfo
- TQTXFontDetector
Helper classes
- TQTXHandleHelper
- TQTXIntegerHelper
- TQTXStringHelper
Media IO management
- TQTXIOAccess
- LoadXML
- LoadFile
- LoadCSS
- LoadScript
- LoadImage
- PreloadImages
Delayed execution
- TQTXRuntime
- DelayedDispatch
- CancelDelayedDispatch
- Execute
- Ready
- ExecuteDocumentReady
Dynamic stylesheets
- TQTXStyleSheet
Flicker free, smooth momentum scroll baseclasses
- TQTXScrollOptions,
- TQTXScrollController
- TQTXScrollWindow
3D for any HTML elements
- TQTXSprite3DController
Custom controls
- TQTXHeaderButton
- TQTXBackButton
- TQTXNextButton
- TQTXHeaderTitle
- TQTXHeaderBar
- TQTXLabel
- TQTXScrollText
Downloading
Simply point your SVN client to: svn checkout http://qtxlibrary.googlecode.com/svn/trunk/ and grab the units.
Installing
Copy the target folder into your Smart Mobile Studio -> Libraries folder and re-start the IDE. That’s it! Now include the units in your uses-clause and kick some serious HTML5 butt!
Heres a little parser I wrote
If you plan on parsing source-code in some form or another, you need a proper text-buffer that let’s you parse the text as simple as possible.
Here is a cool one I wrote during my lunch break. It’s written in Smart Pascal (Smart Mobile Studio) but should be easy enough to port back to Delphi or Lazarus.
Here is how you use it to dump out word-by-word from a snippet:
procedure TForm1.testNewBuffer; var mbuffer: TPascalTextBuffer; mText: String; begin mBuffer:=TPascalTextBuffer.Create; try mBuffer.Buffer:=#"procedure TForm1.test(first,second,third); begin // this is cool end;"; mBuffer.first; while not mBuffer.EOF do begin mtext:=mBuffer.ReadWord; if mtext.length>0 then writeln(mText) else break; end; finally mBuffer.free; end; end;
Which gives you the following output:
unit uniparse; interface uses SmartCL.System; type (* About: Generic string buffer class Comments: This class allows you to traverse a text-buffer using next/back/first/last methods. The current character is always exposed in the "current" property. It also contains simple bookmark features, allowing you do recurse into the buffer for validation, and jump back with a single line. *) TCustomTextBuffer = Class(TObject) private FBuffer: string; Fpos: Integer; FBookmarks: Array of Integer; protected procedure setBuffer(Value:String); procedure setPosition(Value:Integer); function getLength:Integer; function getEmpty:Boolean; function getBOF:Boolean; function getEOF:Boolean; function getCurrent:String; public property Position:Integer read Fpos write setPosition; property Buffer:String read FBuffer write setBuffer; Property BufferLength:Integer read getLength; Property Empty:Boolean read getEmpty; property BOF:Boolean read getBOF; property EOF:Boolean read getEOF; Property Current:String read getCurrent; procedure Skip(Value:Array of String); function PeekAhead(count:Integer):String; Function CompareAhead(value:String):Boolean; function Peek(count:Integer):String; function Compare(Value:String):Boolean; procedure Bookmark; procedure UnBookmark; procedure Next; procedure Back; Procedure First; procedure Last; procedure Clear;virtual; end; (* About: word based buffer class Comments: This class extents TCustomTextBuffer with word-reading capabilities. This means you can traverse a text buffer word-by-word rather than character-by-character. Note: The parser automatically skips un-readable characters like space, linefeed, cariage return and tab. Note: "Breaker" characters will count as a single word. For instance, a text like this: "Procedure test(sender:TObject)" will break down into: - Procedure - test - ( - sender - : - TObject - ) This makes it much easier to write parsers which deals with expected sequences and text structures. It also makes it much easier to deal with character-combinations, such as "(*" and "/*" combinations which are typically used for remarks. Note: Expected sequences can be validated easily with the Ensure() method. *) TWordTextBuffer = Class(TCustomTextBuffer) public function ReadTo(aBreakChars:Array of String):String; function ReadWord:String; function &Ensure(Sequence:Array of string):Boolean; end; TLanguageBuffer = Class(TWordTextBuffer) public function Remark:Boolean;virtual;abstract; procedure SkipRemark;virtual;abstract; end; TNPPTextBuffer = Class(TWordTextBuffer) end; TPascalTextBuffer = Class(TLanguageBuffer) public function Remark:Boolean;override; procedure SkipRemark;override; end; implementation //############################################################################# // TPascalTextBuffer //############################################################################# function TPascalTextBuffer.Remark:Boolean; Begin result:=((Current ='/') and (PeekAhead(1)='/')) or ((current ='(') and (PeekAhead(1)='*')) or ((current ='/') and (PeekAhead(1)='*')); end; procedure TPascalTextBuffer.SkipRemark; Begin if not Empty and not EOF then begin if ((Current ='/') and (PeekAhead(1)='/')) then Begin self.ReadTo([#13]); next; end else if ((current ='(') and (PeekAhead(1)='*')) then Begin next; next; self.ReadTo(['*']); if PeekAhead(1)=')' then next; end else if ((current ='/') and (PeekAhead(1)='*')) then begin next; next; ReadTo(['*']); if PeekAhead(1)='/' then next; end; end; end; //############################################################################# // TWordTextBuffer //############################################################################# function TWordTextBuffer.ReadTo(aBreakChars:Array of String):String; Begin setLength(result,0); if not Empty then Begin while not EOF do begin if not (current in aBreakChars) then result+=Current else break; next; end; end; end; function TWordTextBuffer.&Ensure(Sequence:Array of string):Boolean; var x: Integer; mRead: String; Begin result:=False; if not Empty and not EOF then begin if sequence.length>0 then begin for x:=sequence.low to sequence.high do begin mRead:=readWord; result:=sameText(mRead,Sequence[x]); if not result then break; end; end; end; end; function TWordTextBuffer.ReadWord:String; Begin if not Empty and not EOF then begin Skip([' ',#9,#10,#13]); while not EOF do begin if (current in ['A'..'Z','a'..'z','0'..'9','_']) then result += current else break; next; end; if (result.length=0) and not EOF then Begin result:=Current; next; end; end; end; //############################################################################# // TCustomTextBuffer //############################################################################# Function TCustomTextBuffer.CompareAhead(value:String):Boolean; var mText: String; begin if not empty and not EOF then Begin mText:=peekAhead(Length(Value)); result:=Sametext(mText,Value); end else result:=False; end; function TCustomTextBuffer.Compare(Value:String):Boolean; var mText: String; mlen: Integer; begin if not empty and not EOF then Begin mLen:=Length(Value); mText:=Current + peekAhead(mLen-1); result:=Sametext(mText,Value); end else result:=False; end; function TCustomTextBuffer.Peek(count:Integer):String; begin if Count>0 then begin bookmark; try setLength(result,0); if not EOF then Begin while length(result)<Count do Begin result:=result + current; if not EOF then next else break; end; end; finally unBookmark; end; end; end; function TCustomTextBuffer.PeekAhead(count:Integer):String; Begin if Count>0 then begin bookmark; try setLength(result,0); next; if not EOF then Begin while length(result)<Count do Begin result:=result + current; if not EOF then next else break; end; end; finally unBookmark; end; end; end; procedure TCustomTextBuffer.Skip(Value:Array of String); Begin if not empty and not EOF then Begin repeat if (current in Value) then next else break; until EOF; end; end; procedure TCustomTextBuffer.Bookmark; Begin if not Empty then FBookmarks.add(FPos) else raise exception.create('Failed to add bookmark, buffer is empty error'); end; procedure TCustomTextBuffer.UnBookmark; Begin if FBookmarks.Length>0 then begin FPos:=FBookmarks[FBookmarks.high]; FBookmarks.delete(FBookmarks.high,1); end else raise Exception.Create ('Failed to revert to bookmark, no bookmarks found error'); end; function TCustomTextBuffer.getCurrent:String; begin if not Empty and not EOF and not BOF then result:=FBuffer[FPos] else raise exception.Create('Read failed, invalid position'); end; Procedure TCustomTextBuffer.First; Begin if not empty then Fpos:=1; end; procedure TCustomTextBuffer.Last; Begin if not empty then Fpos:=Length(FBuffer); end; procedure TCustomTextBuffer.Next; Begin if not Empty and not EOF then inc(FPos); end; procedure TCustomTextBuffer.Back; Begin if not empty and not BOF then dec(Fpos); end; function TCustomTextBuffer.getBOF:Boolean; Begin result:=FPos<1; end; function TCustomTextBuffer.getEOF:Boolean; Begin result:=FPos>Length(FBuffer); end; function TCustomTextBuffer.getEmpty:Boolean; Begin result:=Length(FBuffer)<1; end; procedure TCustomTextBuffer.Clear; begin Fbookmarks.Clear; FBuffer:=''; FPos:=0; end; procedure TCustomTextBuffer.setBuffer(Value: String); begin FBuffer:=Value; FBookmarks.Clear; FPos:=0; end; function TCustomTextBuffer.getLength: Integer; begin result:=Length(FBuffer); end; procedure TCustomTextBuffer.setPosition(Value: Integer); begin if (value>0) and (value<length(FBuffer)) then FPos:=value; end; end.
CodeTyphoon, GPL and the whole money thing
After my initial post regarding “Free Sparta” and “CodeTyphoon” by PilotLogic, both separate products which are in violation of the GPL license and (not withstanding) morally bankrupt I received a lot of comments. Both here and on the Delphi Developer group where the post was issued first.
the majority of the human population are socially programmed to think exclusively in terms of gain and loss, checks and bills, making a quick buck and taking advantage of a situation.
First, turns out that the Free Sparta project died out a few weeks back, so we can at least scratch that off the list. apparently the package introduced no changes to the original codebase, something I find very hard to believe since the one of its core selling points was its ease of use and better IDE. Either way, it’s out of circulation so no point wasting time on that.
The second product, CodeTyphoon, is in direct violation of the GPL. They do not provide source-access to their product or alterations to the original code, which is the fundamental point of GPL. Namely to allow others to evolve a piece of software, improving and building on the initial system.
Since there seem to a lot of confusion, let’s go through a few facts
Selling GPL software
First off, yes – you are allowed to sell GPL software. This was initially included to cover the cost of distribution back in the days of floppy-disks and modems; back when a 50 megabyte hard disk would cost you an arm and a leg. Be that as it may – yes, you are allowed to sell GPL based software —- but once again, a part of that states that you must also provide source-code access to the sold GPL based software. So once again, PilotLogic is off the mark.
Secondly, regarding the “open source” model. A lot of people seem to be under the impression that OSS is money agnostic or “open for personal interpretation”. But that could not be further from the truth. OSS as a concept is very much against profit based on software. The entire point of OSS is to ensure that no corporation or financial entity is able to control the market through closed source. Closed source is regarded essentially as robbing the individual of the right to choose, hindering scientific research through patents and establishing information based monopolies. Source: Revolution OS, documentary on Linux
But OSS is not against making money, but rather it pushes potential for income into services around the product. A prime example is Open-Office which itself is free. It’s used by probably hundreds of thousands of schools around the world and is responsible for breaking Microsoft’s monopoly in the office space.
So where does the money come from? From tutoring, from presentations and from sponsorship. What typically happens is that a company hires you to do custom adaptations of a product. They pay the bills and finances your work, and in return they get to promote the work (and use the tools).
Besides from that you are expected to sell your expertise, using the product to create or achieve something. And you can also scrape in some cash for distribution, both binaries and source-code.
This way of working may seem alien to most programmers out there, but it’s actually how researchers work around the world. You live off grants, sponsorships and custom work for various institutions. When operating with open-source software, especially under Apache or GPL, you have to remember that these both originate at universities and scientific establishments. They dont originate from a software house or “club”, but are designed to cater for scientists and researchers first of all.
Back to the future
Richard Stallman, the founder of the GNU foundation and the author of the GPL license – and pretty much the grandfather of the open-source movement, holds a completely different philosophy than most people. And this has to be underlined because the majority of the human population are socially programmed to think exclusively in terms of gain and loss, checks and bills, making a quick buck and taking advantage of a situation. This is the thicket in which the goat of reason easily get’s stuck.
Stallman said his primary goal is to live off the prize money so that he can devote his time to continue his not-for-profit work leading the Free Software Foundation, developing the GNU operating system, and campaigning for social change in the way software is written and distributed. Source: Stallman to Recieve Price
The entire point of the GNU operative system (what people today call Linux, which is actually just the kernel. The operative system, libraries, desktop and software is actually called GNU) and it’s license was to ensure that a free alternative existed. An operative system that went completely against everything Microsoft, Apple, IBM and all the other big-wigs from way-back times stood for: namely economic power based on digital secrecy.
The reason a license exists in the first place, is to define a moral framework in which to work, which ensures that people use and behave according to the intention of the original authors
Stallman comes from a very different place than most people; His roots go back to the late hippie movement of the 60’s and 70’s. You could say that he is the drug-free, non flower power, scientific version of a hippie. He believes in total freedom within a moral framework (as opposed to limited freedom within a larger framework, which is the ideology the western world presently lives under) which has resulted in one of the biggest software archives in the world. All of it written to avoid and bypass the whole corporate culture which Stallman and his posse hates.
Stallman is an ideologist which has more than often spoken against concepts like patents, because they cripple technological achievements (and I have to agree on that point) when allowed to be held for more than the initial 6 years (which was the original time-frame you could hold a patent back in the late 1800’s). So the entire GPL culture is all about free research, free evolution of software and free access to software.
What people have to understand is that this line of thinking does not mean you can do whatever you want. That’s the difference between the hippie-movement and anarchists. You are still expected to show ordinary social respect for other people’s work, to ask and to behave as an intelligent, responsible human being. The reason a license exists in the first place, is to define a moral framework in which to work, which ensures that people use and behave according to the intention of the original authors. This has to do with respect.
Freedom under responsibility
Freedom without boundaries is not freedom, that would be chaos. Without boundaries it’s impossible to set goals and perform co-operation. As such Stallman and his crew made damn sure that no-one would be able to do exactly what PilotLogic is doing. Namely to grab an open-source project, evolve it and then keep the code behind closed doors.
That is, when you think about it, the very definition of greed. It is equal to being poor, getting a truck with food to give out to others — only to keep the whole thing for yourself. You were given access to the code under the premise that you, just like the original authors, demonstrate solidarity and transparency.
It doesn’t really get much clearer than this.
Easy to point the finger
I am not perfect, and surely I have grabbed some piece of code I found online over the years, fixed it up and stuffed it in a library. But I have always tried to add the name of the original author or source to the unit. I mean, sending an e-mail to someone asking if you can re-name a unit and classes — it wont really cost you anything.
I just want to underline that im not doing a witch hunt here. I am not “perfect” in any way, and I have for a long time given PilotLogic the benefit of the doubt. Maybe they just forgot about it? Maybe they did not have the resources? But I think it’s become quite evident that PilotLogic simply don’t care.
They post updates and keep evolving their product, and last time I checked a sourceforge or GIT account is free. So there really is no excuse that can validate ignoring emails from users, ignoring complaints by programmers who suddenly find their own work available inside CodeTyphoon.
Summing up
Since PilotLogic is in direct violation, it should not be necessary to preach morality. But I know that I would personally be quite offended if I suddenly discovered my code in some RTL out there, completely stripped of my name or any form or info regarding origin. This is in fact the reason I publish code under “COPYRIGHT”, even on this blog.
People are allowed to read, study and use my code – but if you want to use it in a commercial product, then just ask me. I’m a fairly mellow individual and not a hard-ass at all, so if you need a unit, just send me an email.
Most programmers are fairly laid back, but unless otherwise stated, it’s good to send an email before you grab a huge piece of code. I do that myself.
That’s not too much to ask for.
But when it comes to open source, the rules are clear. I have two open-source projects myself, with one Lazarus fork of ByteRage out in the wild. And as expected the converter contacted me via Facebook asking if it was ok. Of course it’s ok.
And he also had the ordinary decency to leave the header alone, adding a secondary header on top of the unit with his information. No problem at all, use and have fun.
See how easy that was?
Free sparta and CodeTyphoon violates GPL
Look around the net for alternatives to Delphi is like looking for water in the desert. To date there are really just 3 real options: Smart Mobile Studio, Freepascal & Lazarus– or Oxygene Pascal from Remobjects.
But FPC and Lazarus are open-source products, meaning that anyone can freely fork and create their own versions within certain limits. There is however one significant rule to this: you must publish whatever changes you have made, or at least provide a working download link so that people have free access to your variation of the root product. That is the deal you signed when you forked the source code and you have an obligation by law to honor that agreement.

Violating individual rights is not a good idea, you will get a response
What really pisses me off is that the two forks of Lazarus out there, being sold as commercial solutions, completely ignores the license. Recently I came across a fork of Lazarus called “free sparta” – which is, as it stands now, is a complete insult to the people who have created FPC and Lazarus, dedicating years of hard work to build and maintain both product and community.
First of all the product is commercial (GPL to commercial? Wow! That’s a new twist), meaning that you are basically asked to pay for a product which is bound by international law to be free. Secondly, and this just infuriates me so much, they do not provide any links or SVN/GIT access to the sources. Which they are bound to do by law since the original codebase is GPL.
A second product, called CodeTyphoon takes the whole thing even further; besides being “selective” about the GPL – they demonstrate no scruples re-naming components and units, removing author information and origin of code just to suit their own needs.
Clean up your act
If you are going to compete with commercial products then at least have the balls to follow the rules. Stop stealing code which is illegal, and stop re-branding other people’s work as your own to make a profit (which is not only illegal and a violation of the license but also immoral and intellectually bankrupt).
And what are the rules? You should think they were oh-so complex, but in both these cases they can be summed up as:
- Ask the original authors about re-branding their units
- Do not remove author notes and/or comments from the code
- If they decline your question, show some bloody respect and either exclude it from your product, or use the names provided by the authors.
- Stop violating the GPL license because that will have consequences
- Stop trying to make money on other people’s work
- Provide public read access to either SVN or GIT where people can fork your changes, that is how you got the code in the first place – denying others the same access tells volumes about what type of person you are
Ignoring these simple steps is not just a violation of the GPL license, it’s also a sure way to fuck-up the resolve and determination of the original authors. Why the hell should the FPC and Lazarus community keep working for free while you earn money on their work? Bet your mother must be real proud of you.
But yes, doing what you do is against the law and it is a violation of the GPL license. There is no middle ground here, you either follow the rules or you fucking leave it alone.
As you probably know the GPL license is connected to some of the largest companies in the world – back up by a bloody army of lawyers. As such, anyone violating the GPL can quickly find themselves in a shit-load of trouble, because the GPL is protected by the same organization which protects Linux. This means that if anyone reports your sorry-ass to the GNU foundation – you will be held financially accountable. No matter where you live.
Dont think it wont happen, I’ll happily make the phone-call myself if I have to. And believe you me, the GNU foundation have made examples out of smaller fish that you.
Stealing code and re-branding it is something that makes me furious. Sharing code, learning from each other is one things – but trying to gain financially on what other people have made? Thats just fucking rotten.
If you want to play soccer, then you play by the rules or you don’t play at all. It’s not a debate or open for your personal interpretations of the law. You publish the code ASAP or you will be reported to the GNU foundation.
How to make money on GPL
The open-source model was initially created “TO NOT MAKE MONEY”. So just wrap your mind around that straight away. No middle ground, no “but I could” — no. Forget it. It doesnt work that way. It’s founded on a 100% no-money philosophy.
Open Source pushes the potential of income away from the product, and places the potential in the use of the product and services around the product. In other words you dont have to publish your DOC’s as free, they can be sold separately. Also, you dont need to provide an installer – that can also be sold separately.
But the product itself, no matter if you spend 10 years evolving the code — if it’s GPL it’s free. And if you persist in forking FPC and Lazarus you must provide a working, open for all, SVN, GIT or otherwise functioning download URL.
End of debate.
I rarely get involved in stuff like this, but this time — failure to follow this and respect the original authors, will result in a formal report to the GNU foundation.
Boycott these products

Support FPC, say no to thieves!
I urge everyone to boycot these illegal products. Several individuals have already sent protest emails to pilotLogic, the company behind CodeTyphoon, as well as the “free sparta” cash-in project; They refuse to respond (as expected).
It is an insult to the programmers behind FPC and Lazarus and to show your support of FPC and Lazarus, I hope you agree and stay away or stop using these products.
You may also want to send an email requesting SVN/GIT access to both — reminding them that they are obliged by international law to provide this, regardless of their own personal “interpretation” of the law.
You must be logged in to post a comment.