Quantcast
Channel: TMS Software
Viewing all 1008 articles
Browse latest View live

A busy Business week

$
0
0

In the last week we had very busy days. There were two Delphi events happening in Belgium: TMS Business Day, on Wednesday 19th, in Kortrijk, and BE-Delphi, on Thursday 20th, in Antwerp.

On both days we had Wagner Landgraf, the product manager of TMS Business Subscription product line - who flew from Brazil especially for the events - doing presentations about products included in the TMS Business subscription, like our ORM TMS Aurelius, multi-tier TMS XData and TMS RemoteDB, TMS Data Modeler among others. At BE-Delphi, TMS has also done a strong presence with many team members at the TMS booth and a session on multi-tier by Wagner Landgraf.

The most important result of the week was the great feedback we got from the attendees and existing customers. We had time to discuss existing features, future plans for the products, hear suggestions, and most important of all, we have received mostly positive comments about presentations and the products. So thank you all that participated with us! We'll be planning more events on TMS tools in 2015. Let us know where you'd like to meet us and what topics you want to be covered.


TMS Team at BE-Delphi 2014


BE-Delphi 2014 presentation


TMS Business Day 2014




Using the new iOS Sprite Kit from Delphi, a little XMas gift from the TMS team

$
0
0

With iOS 7, Apple introduced the new SpriteKit framework for game development on iOS 7. This framework manages things like graphics, animation, physics, particle effects, gravity, ... all things typically needed for game development. The full documentation for SpriteKit can be found in the "SpriteKit Programming Guide"

We did some research here on using the SpriteKit framework from Delphi XE7 and that triggered the idea of creating a small demo with it in XMas spirit as it is the time of the year for it.

In the little demo, we use an XMas tree with gifts under it as background. This is provided as 4 PNG files, a retina and non-retina version for both portrait and landscape mode. The snowflakes in the demo are particles and therefore we need to create a SpriteKit particle file which can be done from XCode. The SpriteKit particle file contains the PNG for a snow flake and the "snow" particle type is chosen. The result is a .SKS file that is linked as resource with the application.
To make the app a little fun, we added a MotionManager. The snow starts falling when you first shake the device. This is accomplished by handling the motionEnded method at UIViewController level. The motion manager is used to make the snow fall faster according to the angle with which you hold the device. The Delphi TMotionSensor makes this possible.
Finally, to stay in the XMas spirit, we added an MP3 files as resource that plays Jingle Bells as background music.


Video demonstration of the application:


Have fun exploring the iOS SpriteKit framework with the full source code for Delphi XE7* of this gift you can download here.

Note: you'll need to add the SpriteKit framework to the Delphi XE7 IDE to compile the app



WYSIWYG formatted text & images editor for VCL & FireMonkey

$
0
0

Early this year, our team started the challenging task to create a new component for WYSIWYG editing of formatted text & images for Delphi. From the start, we want to create a control for FireMonkey that would fit neatly the FMX paradigm of one source code to rule all platforms (Windows, iOS, Android, Mac OSX at this time) but realising this would be a huge effort, we wanted that this effort would also be usable for VCL developers targetting Windows only.

After a lot of research was done on performance (as we knew from our experience with other FMX controls this would be difficult) we decided on what we internally disrespectfully call a sandwich architecture. This sandwich architecture should enable us to isolate a core formatted text handling layer from the framework, i.e. the VCL and FireMonkey framework. The benefit clearly is that work on the core only needs to be done once and further evolutions of the core and its maintenance automatically benefits both VCL and FireMonkey framework versions. Visually, this can be seen as:



The core middle layer not only deals with rendering the formatted text and images but also with all the manipulations that can happen with it. Non-trivial areas in this core middle layer abstraction are: dealing with font handling, coordinates and images that are all treated in a different way in VCL and FireMonkey frameworks. Between this architecture and its final implementation is of course lots and lots of hard work both in development and testing. The final result in VCL and FireMonkey platform running on Windows looks like:

TAdvRichEditor : VCL component from TMS Component Pack



TTMSFMXRichEditor : FireMonkey component from TMS Pack for FireMonkey



To whet your appetite to get started with the new editors regardless of what platform or framework you want to use, here is a short feature list:

  • Compact light-weight WYSIWYG editor for formatted text
  • Supports formatted text with bullets, hyperlinks, images, indenting
  • Paragraphs with left,center,right alignment
  • Support for images, plain text and formatted text on clipboard
  • Undo/redo support
  • Find & replace + text highlighting
  • Mailmerge function
  • Printing (on Windows)
  • Exports to .TXT, .RTF, .HTML files.


A customer speaks out on TMS components ...

$
0
0

To our big surprise, we found out yesterday a customer gave his feedback in the Embarcadero thirdpartytools forum (nntp://embarcadero.public.thirdpartytools.general) when asked for experiences with our ORM and related products;
The saying is, "a picture is worth a thousand words", but in this case, I would rather say "thousand positive words from a customer are priceless". It speaks for itself that our team was delighted to find out about this posting and it's an incredible motivation and boost to continue the development of our components.

The original post is here in its entirety and unedited:

Bernd

I can tell you about my experience with Aurelius and other TMS products.

One year ago I started a new project for a ERP and needed to have it in a 
more modernized way. Pretty much the way you intend to do.

I had some goals:

- using modern Delphi language features. I had no need to be compatible with 
anything from previous versions.

- capable of going crossplatform (so it is FIREMONKEY): in my case i have 
an entire ERP running on android :) very nice this. This is important since 
we are now in a multi OS era. There is no guarantee on wich platform will 
remain in 10 years.

- possibility of isolate modules, or even replace them in case of the vendor/open 
source gets out of the market (or just not get more updates)

- something I could understand withou need to be a phD on the area.

I choose the TMS products because they met this parameters for me.

This is my current result:
AURELIUS

I have Aurelius as my ORM layer. I have an application based on MVP, so my 
Model part understands Aurelius entities. That are plain simple classes. 
I have created my base class with all funcionality needed and Aurelius does 
the rest.

It is fast, and it is bugs free. I have it working on real conditions for 
1 year now and did not get any problem at all. 

The Idea is simple, the code is modern, and it relies on the new delphi language 
features.

It is compatible with mobile and then you can have all the functionality 
on Android or whatever you need. Using most of the important databases, including 
SQLite

I am using frames to create the view part of my MVP. I wire everything with 
LiveBInding and Aurelius provides to you a TAureliusDataSet, a fantastic 
TDataSet descendant that publish by several ways the entities you get from 
the ORM.

Right now it is very handy to me, since I have my data prepared on a parallel 
thread and when done it is set to the TAureliusDataSet. The result is a fluid 
application.

You can Edit one entity, a TLIST<> or a Cursor to your database. You can 
access all the properties of your Entity as fields on the Dataset. It is 
very handy to deal with LiveBindings. 

See, since it is Firemonkey this is the only way if not manual). But I can 
tell you, after getting some experience it is reliable and fast enought for 
work based on XE7 

REMOTEDB

it is the product that permit you connect remotely, you have a server based 
on the http.sys that is the core windows http service and you "write" a server 
based on the documentation. I could add some flavors of my interest of the 
comunication between client and server. (there is another layer called Sparkle 
that is the real http transport here, but just to be simple)

The good thing is that you isolate the native database drivers and you can 
have either mobile using it to connect to your database

XDATA

I am about to move my application to use it. In my case I am waiting for 
a new feature where I would be capable to use Aurelius over XData. XData 
is a OData standard way to share your data. You create your own server following 
the examples and you can use Aurelius in the server side to create your business 
module.

With eh upcoming feature you will be also possible to use Aurelius with the 
Xdata result. Then you can hide business logic on the server side and publish 
only what is relevant.

FLEXCEL

This is the way to go for Reporting. It is not only reporting, but for me 
is a fantastic tool.

It has a core based on excel spreadsheet, you can load, create, change, save 
them, in ANY Platform.

But there is a way to use TEMPLATES. So in my ERP i have created XLS templates 
that are embeded on the exe as resources (25k), then I load it and pass the 
Aurelius results from queries based on Linq. The result is commonly a TList 
or can be anything else. But the Entity objects can be directly accessed 
from the Excel Template!

And the good thing is that it works on any platform! it is very fast. Much 
better than FastReports. Easier to work. You can do a lot more, and you can 
even let your customer create Excel templates (wich customer you have that 
does not know how to use them?)
My ERP is already in use on a big chain pilot project. No trouble at all.

I do not work for TMS, but their support was so help ful for me in many cases 
that I have to give you this information.

I am extremelly satisfied. The price is not high for the product benefits, 
and the result is professional.

Any other specific question please let me know...

Eduardo Elias

Well, what more can I say than a big thanks to Eduardo Elias and many other customers who help shape our products every day, 7 by 7, year in, year out and who steer our developments!

From Lego to TComponent...

$
0
0

In my childhood, I was always fascinated by Lego. I spent countless hours building all kinds of things with Lego, many times a town, all kinds of houses but never forgetting a few sporty cars to accompany each house. What I could build with Lego was mostly limited by my imagination and the number of blocks I had (which was eventually quite a lot as I didn't let any anniversary or special celebration go by to ask for more Lego blocks as a gift). What is so nice about Lego is the easy to use interface between all kinds of blocks. All blocks fit on other blocks and can be effortlessly put together.

From my Lego time, fast-forward about 20 years, in 1995 Delphi brought us the concept of TComponent, an evolution of the TObject originated in Turbo Pascal. TComponent was an invention as magic as the Lego building block. While seamlessly interfacing with its parent, siblings, childs, the major difference with the basic Lego block is that a component can be heavily characterized through its properties. This makes 'playing' with components even more fun, interesting & challenging than playing with Lego was. At TMS software, it is always my objective to build interesting components that are as intuitive as possible to use and that could do interesting things while requiring to write a minimum amount of plumbing code to use them. With a wave of new components we released in the past quarter, I set a challenge for myself to explore and smoothen the ways to interface these building blocks to each other. In this article I wanted to highlight the easiness of bringing together quite sophisticated stand-alone components or building blocks to create powerful solutions.
To demonstrate this, we start with the versatile TMS TAdvStringGrid. With a few properties, this turns into an editable 2D data structure. In our sample, the grid is used to present or capture sales information for a 12 month period. The majority of the effort to write code for this sample goes into initializing the grid. In this case, all we still need to do in code is initialize the data contained in the grid:

var
  i: integer;
begin
  AdvStringGrid1.EditLink := AdvRichEditorEditLink1;
  AdvStringGrid1.Cells[1,1] := '';
  AdvStringGrid1.Cells[2,1] := 'Sales of development tools products per month';
  AdvStringGrid1.MergeCells(2,1,2,1);
  AdvStringGrid1.Cells[0,1] := 'Name';
  AdvStringGrid1.Cells[0,0] := 'Month';
  AdvStringGrid1.Cells[1,0] := 'Units';
  AdvStringGrid1.Cells[2,0] := 'Sales';
  AdvStringGrid1.Cells[3,0] := '% Market';

  for i := 2 to 13 do
  begin
    AdvStringGrid1.Cells[0,i] := FormatSettings.ShortMonthNames[i - 1];
    AdvStringGrid1.Ints[1,i] := Random(100);
    AdvStringGrid1.Ints[2,i] := Random(10000);
    AdvStringGrid1.Ints[3,i] := Random(50);
  end;
end;
All other settings are done by setting properties at design-time. Now, what we want to do is represent the information entered in the grid in a chart. The 3 columns of sales related data are represented in 3 series bar charts in TAdvChartView, the TMS chart component. With the easy interfaces of Lego in mind, we also want and can do this without writing much code (3 lines actually to be exact). We drop a TAdvChartView on the form and also 3 TAdvChartLink components. The TAdvChartLink is a component that takes on the interface between the grid data and a chart series data. The TAdvChartLink is so smart to update the chart series when the grid data changes through editing. All we need to do is setup the relationship between a specific range of cells and a series. Grid and chart are connected by assigning the grid to AdvChartLink.Grid and the chart to AdvChartLink.ChartView. What data from the grid is connected to what series is also configured at design-time via properties through the AdvChartLink.GridValues property. The chart itself can be configured at design-time with a special pane and series design-time editor that allows to customize the X-axis, Y-axis, colors, markers, ... everything about the chart actually. So, the only code left to write is the activation of the chartlink after the data is set in the grid:
  AdvChartLink1.Active := true;
  AdvChartLink2.Active := true;
  AdvChartLink3.Active := true;
Next step, we want to do is display the chart within an editable rich formatted document as we want to allow the user to create a customizable sales report that includes the chart. To do this, TAdvRichEditor is put on the form as well as a TAdvRichEditorEditToolBar and TAdvRichEditorFormatToolBar. We could have opted for a ribbon UI as well with TAdvRichEditorClipboardRibbonToolBar, TAdvRichEditorFontRibbonToolBar, TAdvRichEditorParagraphRibbonToolBar. TAdvRichEditorEditToolBar and TAdvRichEditorFormatToolBar or the ribbon toolbars are building blocks derived from our TMS Advanced ToolBars & Menus product that provides docking toolbars or ribbon controls. These 3 components together are already sufficient to have a rich formatted document editor without needing to write a single line of code.

All we do is initialize the content of the document a little bit with:
  AdvRichEditor1.InsertMultiLineText('Dear Mr. NAME'#13);
  AdvRichEditor1.SelStart := 9;
  AdvRichEditor1.SelLength := 4;
  AdvRichEditor1.SetSelectionMergeField('NAME');

  AdvRichEditor1.InsertMultiLineText('Included is the chart of sales for our development tool product.'#13#13);
  AdvRichEditor1.AddGraphic(500,400,'CHART');
With this initialization, we have inserted a merge field and a chart instance in the document. The merge field will be used to insert the addressee name with data from the grid.

The chart is added with initial dimensions 500 x 400px and with ID CHART. To have the chart displayed in the document, the event handler to draw custom graphic objects in the document needs to be coded:
procedure TForm1.AdvRichEditor1DrawGraphic(Sender: TObject; ACanvas: TCanvas;
  ARect: TRect; AID: string);
begin
  if AID = 'CHART' then
    AdvChartView1.PrintAllPanes(ACanvas, ARect);
end;
The merge of the addressee, NAME merge field in the document is done from the grid's OnCellValidate event for the cell 1,1 that holds the name. The code in this event handler is:
procedure TForm1.AdvStringGrid1CellValidate(Sender: TObject; ACol,
  ARow: Integer; var Value: string; var Valid: Boolean);
var
  sl: TStringList;
begin
  if (ACol = 1) and (ARow = 1) then
  begin
    AdvRichEditor1.UnMerge;
    sl := TStringList.Create;
    try
      sl.Values['NAME'] := Value;
      AdvRichEditor1.Merge(sl);
    finally
      sl.Free;
    end;
  end;
end;
But we are not satisfied yet. Wanting to generate a PDF document from the TAdvRichEditor content, a TAdvRichEditorPDFIO component is dropped on the form and connected to the TAdvRichEditor. All we need to do to get the PDF document from the TAdvRichEditor is add the code:
begin
  AdvRichEditorPDFIO1.Save;
end;
This will prompt for the filename to use and can optionally automatically display the generated PDF in the Windows default PDF viewer, again all without needing to write any additional code.


While not really functionally used in the sample, we just wanted to show yet another seamless integration between the TAdvRichEditor and TAdvStringGrid. In this case, the integration means we can use the TAdvRichEditor as inplace editor in the grid. And here comes yet another integration as this inplace TAdvRichEditor can optionally have a popup formatting toolbar for on-the-fly formatting of the editor content without the need for extra screen estate to put another toolbar or ribbon.


Get started by playing with these building blocks with the sample you can download here and the latest versions of TMS Component Pack and TMS Advanced Charts. We hope this article is an inspiration to have you create other powerful integrations. We're curious to see your results and hear about any suggestions you might have for new integrations or things that can make the integrations even smoother.

Latest Additions to TMS Workflow

$
0
0

TMS products could be categorized by "application user-oriented" or "application developer-oriented".

Products like TMS Aurelius are heavily developer-oriented: it's the developer that "uses" the product during most of development time and the application user have no idea it even exists. Products like TAdvStringGrid stays in the middle: programming effort might be required to achieve the desired behavior of the grid, but at the same time the application user benefits from grid features, viewing data, interacting with the grid, etc..

TMS Workflow is in the "user-oriented" extreme: it's the application user, that will mostly use it. You will do the effort to do some initial setup, setup some configuration, build some initial integration, and that's it: now it's up to your user to benefit and live with TMS Workflow for the rest of your application life.

This post shows the new features introduced in most recent release of TMS Workflow, version 2.1. And you will see how it's heavily user-oriented and focused to make the life of application user - your customer! - easier.

Variables Tool Window
When building the workflow definition, there are many parameters that can use expressions and thus workflow or system variables. With this new helper tool, users can see all the existing variables that can be used in expressions, and can drag a variable name and drop in a control that accepts expressions to create an expression with the variable name. It's even useful to know which parameters can accept expressions.


Transition Scripts
TMS Workflow provides the Script Block to allow users to execute scripts when the workflow reaches a specified point in the diagram flowchart. But it's often not very productive to create the block, connect lines, etc.. And it also pollutes the workflow diagram with irrelevant information (most managers and workflow developers don't want to a script block in the middle of the process indicating that some low level stuff is being done).
To improve that TMS Workflow 2.1 introduces transition scripts: each transition can have a script associated to it. If the execution flow goes through a specified transition, the script associated with it (if any) is executed. Much easier to setup and makes your workflow diagram display only the relevant parts of the business process.


Send Mail Block
A block to send an e-mail notification. In addition to the automatic e-mail notification about tasks, if the user one to send a custom e-mail to someone, this is a very straightforward way to do it.


Database SQL Block
Executes an SQL statement in the database. Users don't need to create datasets or wait for you to build custom functions. If they just want to update some status in database or set some field value, that's an easy way to do so.


Status Templates
When creating tasks, users need to specify the list of valid status for the task. In many cases, the status are the same: "open/closed", or "pending/approved/rejected". Although TMS Workflow already has the Approval Task Block that automatically creates "approved/rejected" status, your user might have other needs for a different list of status, and still use it to create several different tasks. With status templates, you can predefine a list of status under a specified name, and your user can just choose from those predefined templates to quickly create the list of status in a task.


Comment and Text Blocks
Visual blocks to display information in the workflow diagram. The nice thing about text blocks is that they are dynamic, so your user can build a definition that shows a date, a task status, or other relevant information that changes as the workflow is being executed and tasks are being completed.




CORS and preflighted requests with TMS XData

$
0
0

From Wikipedia: Cross-origin resource sharing (CORS) is a mechanism that enables many resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from another domain outside the domain from which the resource originated. In other words, if you are trying to access entities in a TMS XData server from a web page (for example, using AJAX requests), this mechanism (CORS) will eventually get in action.

Enabling CORS in TMS XData is very simple. Actually a single line of code:

    XDataServerModule.AccessControlAllowOrigin := '*';

And it will handle most of what's needed, including preflighted requests. This post could end here if you are looking about how to deal with CORS in TMS XData. But let me use the opportunity to explain and illustrate how CORS works.

Let's use the SQLiteConsolerServer demo that is included in TMS XData distribution. This very simple demo creates an SQLite database in memory, fill it with some predefined data (artists, albums and tracks), and starts a XData server in the address "http://localhost:2001/tms/music" to provide the objects from the database. This is what you will get after running the demo.

Now if we go to our browser (I'm using Chrome here) and enter the URL "http://localhost:2001/tms/music/Track(1)", this is what we get:

So far so good, our server is providing the JSON representation of our Track object with id equals to 1. But what happens if we try to do the same request using AJAX? Let's create a small HTML page with some JavaScript that performs the same GET request we're doing directly with the browser. Here is the full code of the HTML:


<!DOCTYPE html>
<html>
<body>

<script>
	function processResponse(xmlhttp) {
		switch(xmlhttp.status) {
			case 200:
				var track = JSON.parse(xmlhttp.responseText);
				document.getElementById("getButton").innerText=track.Name;
				break;
			case 404:
				document.getElementById("getButton").innerText="(not found)";
				break;
			default:
				document.getElementById("getButton").innerText="(invalid)";
		}
	}

	function getTrack1Name() { 
		var xmlhttp=new XMLHttpRequest(); 
		
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4) {
				processResponse(xmlhttp);
			}
		}
		xmlhttp.open("GET","http://localhost:2001/tms/music/Track(1)",true);
		xmlhttp.send(null); 
    }

	function deleteTrack1() { 
		var xmlhttp=new XMLHttpRequest(); 
		xmlhttp.open("DELETE","http://localhost:2001/tms/music/Track(1)",true) 
		xmlhttp.send(null); 
	}
</script>

<button onclick="getTrack1Name();" id="getButton">Get Track 1 Name</button> 
<br><br>
<button onclick="deleteTrack1();">Delete Track 1</button> 

</body>
</html>


Code is very simple, it just provides two buttons that perform GET and DELETE requests to get the name of Track 1 and delete Track 1, respectively.

Let's open that page in browser (I'm using a WAMP server here but you could just double-click the HTML file):

If we click the first button to retrieve the name of Track 1, we get this:

It doesn't work. Why is that? If we press F12 in Chrome to get more info about it, you can get a clue about what's going on:

That's CORS in action. The browser doesn't allow a request from domain "localhost:8080" (where our web page is located) to the domain "localhost:2001" (where our XData server is located) unless our server states that it allows it (using the mentioned response header).

We can then modify our SQLiteConsoleServer demo to add that small line of code mentioned in the beginning of this post:

   {...}
    Module.AccessControlAllowOrigin := '*'; // Add this line
    Server.AddModule(Module);
    Server.Start;
    {...}

Then if we restart our server, refresh our test page, and try pressing the button again, here is what we get:

Now it works! Here is the response returned by the XData server:

HTTP/1.1 200 OK
Content-Length: 228
Content-Type: application/json
Server: Microsoft-HTTPAPI/2.0
access-control-allow-origin: *
Date: Fri, 10 Apr 2015 14:08:03 GMT

{
    "$id": 1,
    "@xdata.type": "XData.Default.Track",
    "Id": 1,
    "Name": "Black Dog",
    "Composer": "Jimmy Page, Robert Plant, John Paul Jones",
    "Milliseconds": 296672,
    "Genre@xdata.ref": "Genre(1)"
}

Note the presence of header "access-control-allow-origin" which states that the server allows requests from any server. You could just restrict this to a specific server origin address by simply defining the name of the server instead of using "*" when setting the property.

Now what about preflighted requests? It will happen when we click our "Delete Track 1" button. From this nice Mozilla web page explaining CORS, it explains that a request must be preflighted if the HTTP method is different than GET, HEAD or POST, or even if request use custom headers or content-type different than some accepted ones. This covers a lot of very common REST requests: DELETE, PUT, or POSTing JSON data.

So what happens exactly when we click "Delete Track 1" button? This is the request Chrome will send to our XData server:

OPTIONS http://localhost:2001/tms/music/Track(1) HTTP/1.1
Host: localhost:2001
Connection: keep-alive
Access-Control-Request-Method: DELETE
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept: */*
Referer: http://localhost:8080/tests/cors.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,pt;q=0.6

Note that instead of sending a DELETE request, it sent an OPTIONS request, which is the preflighted one. This means the browser is "checking" the server if the request he's going to perform is valid. It indicates it's going to perform a DELETE method using the "Access-Control-Request-Method" header. If the request had different headers, it would also send header "Access-Control-Request-Headers" to check with the server if the headers will be allowed.

The XData server then responds informing the client that the DELETE request will be accepted:

HTTP/1.1 200 OK
Server: Microsoft-HTTPAPI/2.0
access-control-allow-methods: GET,PUT,PATCH,DELETE,OPTIONS
access-control-allow-origin: *
access-control-max-age: 1728000
Date: Fri, 10 Apr 2015 14:16:15 GMT
Connection: close
Content-Length: 0

And finally, Chrome performs the actual DELETE request:

DELETE http://localhost:2001/tms/music/Track(1) HTTP/1.1
Host: localhost:2001
Connection: keep-alive
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept: */*
Referer: http://localhost:8080/tests/cors.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,pt;q=0.6

If we press the "Get Track 1 Name" button again, we will be informed it doesn't exist:

So, although enabling CORS in XData is just a single line of code, my intention here was to explain CORS with little more details, including preflighted requests, and show how XData makes it work under the hood.



Audit Log using TMS Aurelius events

$
0
0

The latest release of TMS Aurelius introduces an event system that allows you to subscribe listeners to some events that might be fired while you are using Aurelius, especially the TObjectManager.

One key difference between regular Delphi events and Aurelius events is that the latter are multicast events, meaning you can add listeners (handlers) to the events without worrying if you are replacing a listener that was already set to event. This way it's possible to create "plugins" to Aurelius that perform additional logic. For example you can easily add code that will be executed whenever an entity is inserted in the database:

TMappingExplorer.Default.Events.OnInserted.Subscribe(
  procedure(Args: TInsertedArgs)
  begin
    // Use Args.Entity to retrieve the inserted entity
  end
);

One very common use of that feature is implementing Audit Trail, a mechanism where you can log every entity (or database record, if you prefer to see it that way) that is created (inserted), deleted or modified (updated). The Music Library demo included in TMS Aurelius distribution was updated to include a simple Audit Log Viewer that illustrates how to use the events.

In the demo, the Audit Log Viewer just listen to the events and log them in a memo component in a form. You can enable/disable the logging. In real applications, you will just log the modifications to another place, like a text log file, or even the database itself, using Aurelius, if you prefer.



You can check the demo for the full source code. In this blog post, I will show only the relevant parts, for the OnInserted and OnUpdated events. Other parts of the code even inside procedures were removed for simplicity. Here is how we subscribe to the events:
  TfmAuditLogViewer = class(TForm)
  private
    FInsertedProc: TInsertedProc;
    FUpdatedProc: TUpdatedProc;
    procedure InsertedHandler(Args: TInsertedArgs);
    procedure UpdatedHandler(Args: TUpdatedArgs);
    procedure SubscribeListeners;
    procedure UnsubscribeListeners;
    {...}
  end;

constructor TfmAuditLogViewer.Create(AOwner: TComponent);
begin
  inherited;
  FInsertedProc := InsertedHandler;
  FUpdatedProc := UpdatedHandler;
end;

procedure TfmAuditLogViewer.SubscribeListeners;
var
  E: TManagerEvents;
begin
  E := TMappingExplorer.Default.Events;
  E.OnInserted.Subscribe(FInsertedProc);
  E.OnUpdated.Subscribe(FUpdatedProc);
end;


Note that we set the method reference in field variables so that we can later unsubscribe them if we want to:

procedure TfmAuditLogViewer.UnsubscribeListeners;
var
  E: TManagerEvents;
begin
  E := TMappingExplorer.Default.Events;
  E.OnInserted.Unsubscribe(FInsertedProc);
  E.OnUpdated.Unsubscribe(FUpdatedProc);
end;


And here is how we implemented our event listeners:

procedure TfmAuditLogViewer.InsertedHandler(Args: TInsertedArgs);
begin
  Log(Format('Inserted: %s', [EntityDesc(Args.Entity, Args.Manager)]));
  BreakLine;
end;

procedure TfmAuditLogViewer.UpdatedHandler(Args: TUpdatedArgs);
var
  Pair: TPair<string, Variant>;
  OldValue: Variant;
begin
  Log(Format('Updated: %s', [EntityDesc(Args.Entity, Args.Manager)]));
  for Pair in Args.NewColumnValues do
    if not (Args.OldColumnValues.TryGetValue(Pair.Key, OldValue) and (OldValue = Pair.Value)) then
      Log(Format('   %s Changed from %s to %s',
        [Pair.Key, TUtils.VariantToString(OldValue), TUtils.VariantToString(Pair.Value)]));
  BreakLine;
end;


Some different methods are called from those event handlers, but they are just helper methods. EntityDesc just retrieves a string representation of the entity being logged (class name and id), and Log and BreakLine just add text to the memo component:

function TfmAuditLogViewer.EntityDesc(Entity, Manager: TObject): string;
var
  IdValue: Variant;
  IdString: string;
begin
  IdValue :=  TObjectManager(Manager).Explorer.GetIdValue(Entity);
  IdString := TUtils.VariantToString(IdValue);
  Result := Format('%s(%s)', [Entity.ClassName, IdString]);
end;

procedure TfmAuditLogViewer.Log(const S: string);
begin
  Memo.Lines.Add(S);
end;

procedure TfmAuditLogViewer.BreakLine;
begin
  Memo.Lines.Add('================================================');
end;


After playing with Music Library demo for a while, adding and updating entities, we have our audit log results:






TMS coming to Delphi events near you

$
0
0

I'm honored to have been invited to two upcoming first-class Delphi events in Europe (United Kingdom and Germany) in May. I'm looking forward to meet again with so many fellow Delphi developers and discuss topics that excite us all software developers in a changing world. The focus in my session will as-always be on utilizing TMS components to bring to your applications a maximum set of features with a minimum effort, in this case, to FireMonkey cross-platform applications targetting Windows, Android, iOS and Mac OS-X.
What I'm most thrilled about though is the opportunity to let you see a first glimpse of a major new component for FireMonkey under development in our labs for quite some time now. The upcoming events in May will be the very first and only place for now for this sneak preview. Ok, to keep a kind of nostalgic atmosphere of mystery, I say no more here :)



May 6,2015: Spring Delphi Community Conference: National History Museum London, UK

With 20 years of Delphi development, the UK Delphi community comes together on this major event with key speakers Marco Cantu, Jason Vokes, Pawel Glowacki and Stephen Ball covering all the power our beloved language Delphi brings in XE8, MVC / MVVM, multitier development, deployment via Google Play, FireDac ...
Places are limited, so rush to register now for this free event!





May 11-12, 2015: Delphi Developer Days: Holiday Inn Express, Frankfurt am Main, Germany

There is no match in technical depth and amount of information transfer for the Delphi Developer Days. Going strong for years, Delphi Developer Days means 2 days diving deep into all the power Delphi brings for developers. On the menu is modern VCL programming techniques, utilizing the latest database access technologies with FireDac, cross-platform FireMonkey development, REST services, ... in both break-out sessions and sessions in one room. As there is so much information that even 2 days is little to grasp everything, you go home with an over 300 pages conference book to catch-up at home later. This year, Delphi Developer Days is brought by Delphi guru, book writer, consultant, speaker Cary Jensen and Ray Konopka: Embarcadero MVP, winner of the coveted Spirit of Delphi award, and owner and founder of Raize Software, one of the first providers of third-party Delphi components. Places are extremely limited! More information and registration can be found at: Delphi Developer Days




Introducing the upcoming TMS Planner for FireMonkey

$
0
0

We're thrilled to introduce to you the TMS Planner for FireMonkey, in short TTMSFMXPlanner that has been in development for many months and that is near to being released now.

While TMS Planner for FireMonkey design benefits from the significant experience the TMS team built-up with the award-winning VCL, IntraWeb and ASP.NET Planner components, the new component has been architected from the ground up for cross-platform, multi-device usage. This includes tuning for performance & footprint to run smoothly on Android or iOS smartphones and making the component flexible enough for complex scheduling applications in desktop or tablet applications.



In a nutshell, the TMS Planner for FireMonkey is a user-interface control representing a timeline and events for single or multiple resources.

Timeline
The timeline in the TTMSFMXPlanner is configurable. Default, it represents the standard 24hr timeline but this can be easily changed to month mode, a day period mode, a half-day period mode, multi-month mode or a custom timeline mode. With the custom timeline mode, the unit of time along the timeline can be fully programmatically set. In one of the included demos will be a timeline in seconds mode that represents a schedule of TV-adds.
Within the displayed timeline, the TTMSFMXPlanner has the notion of active and inactive time, typically used for open office hours that can be shown in a different collor as well as various ways to to display the actual time on screen. In addition, for period, month, multi-month modes, specific days of the week can also be set as inactive time.

Resources
The TTMSFMXPlanner can display events for a single resource or can deal with multiple resources. Multiple-resources can be displayed in different columns (when the timeline is vertical) or different rows (when the timeline is horizontal). But there is more. Views with multiple resources can be combined with multiple days. In this way, multiple resources per day and multiple days per resource can be shown. And in addition to this, there is also the flexible capability to create groups of a different nr. of resources or days, like grouping a number of days in a week or grouping a number of resources to a company etc...





Event Editing
Also for editing events in a TTMSFMXPlanner view, we went to great lengths to offer built-in easy to use and flexible to customize editing capabilities. First of all, changing the start time, end time or dragging the event to a different day or resource is optimized for both classic desktop mouse & keyboard interaction as touch based mobile device operation. Editing of event notes can be done via inplace editing or via a popup dialog. Both inplace editing and use of popup dialogs can be fully customized.





Cloud connectivity
If you want to hookup your TTMSFMXPlanner to a cloud calendar service, we have the adapters ready for you that let you interface the TTMSFMXPlanner to a Google calendar or Microsoft Live calendar. This is achieved by an adapter that interfaces the TTMSFMXPlanner via TTMSFMXPlannerGoogleAdapter or TTMSFMXPlannerLiveAdapter to TMS Cloud Pack components for access to these cloud calendar services.



Customization
We realize that scheduling applications all have different rules and particularities. Therefore, the TTMSFMXPlanner has overall extensive customization capabilities. From putting custom text in timeslots, defining event conflict handling, restricting events to resources, custom drawing over events, timeline, resource header, editing validation and much much more. And of course, the TMSFMXPlanner also visually automatically integrates with the selected FireMonkey application style.





All this and more is coming to you in the next major release of TMS Pack for FireMonkey. This new version will be free for all active registered users.

TMS Pack for FireMonkey v3.0: 3 new components: delivered

$
0
0

About 2 weeks ago we announced the upcoming new FireMonkey scheduling/planner component TTMSFMXPlanner here and revealed the first details about it. For quite some time, this was the number one requested component. Today we are excited to confirm its availability as part of TMS Pack for FireMonkey v3.0. So, we are happy to deliver on your requests. But there is more. Check here what TMS Pack for FireMonkey v3.0 brings:

TTMSFMXPlanner v1.0

Targetting Windows, Mac OS-X, iOS and Android devices, fine-tuned for desktop and mobile use and packed with features is our new scheduling/planner control TTMSFMXPlanner. It's suitable for a wide range of use-cases, from single resource day planning to multi-resource scenarios with fully customized timeline. In combination with TMS Cloud Pack for FireMonkey, it offers seamless connectivity to a cloud calendar like Google calendar or Microsoft Live calendar. Read more about TTMSFMXPlanner in this blog, the developers guide or check out the fully functional trial version.

TTMSFMXRatingGrid v1.0

Also new in TMS Pack for FireMonkey is this control for capturing ratings for different items, making questionaires or for presenting feature comparison lists. It supports customizable tickmarks, radiogroup or checkgroup behavior for items.

TTMSFMXPassLock v1.0

To protect the use of your applications or access to certain parts of your application, the TTMSFMXPassLock is a component for input of a configurable length pass code or pass pattern. One property controls in what mode the pass code can be entered and the component features a pass code learn mode as well. An event is triggered when the pass code is correct or wrong.

Other improvements

Other than these 3 new controls, there are several improvements to existing components as well. The full version history is here.

More good news

And to round up the good news, all customers with an active registration for TMS Pack for FireMonkey receive this v3.0 free. For customers with an expired registration, a renewal discount of about 50% is available for 30 days.

Call to action

Add your feature request or vote on existing feature requests. It is one of the tools that help us align our development efforts with your needs.

Weekend fun with Raspberry Pi 2 and TMS Cloud Pack

$
0
0

Thinking to myself, why go through the hassle of sacrificing a desktop computer or fiddle around with VMs to test something on a Linux machine when I have here several 85mmx56mm Raspberry Pi boards laying around capable of amazing things. For my experiments, I wanted to have an ownCloud available and first thing to do was getting an ownCloud up and running on the Raspberry Pi 2, which turned out to be a piece of cake. To do this, follow these instructions:

Step 1: getting Apache up and running

If Apache is already setup on your device, skip this step, otherwise, from the command line, execute:

$ sudo apt-get install apache2

The Raspberry Pi 2 LED flashes for a short while and when completed, verify it is working by opening a browser on a machine in the network and navigate to the IP address of the Raspberry Pi 2 like http://192.168.1.100. When install was successful, you'll be greeted with an "It works!" page.

Step 2: install PHP and tools

In case you had Apache already configured with PHP 5, you can also skip this step.
To install, execute following commands:

$ sudo apt-get install php5
$ sudo apt-get install php5-gd
$ sudo apt-get install sqlite
$ sudo apt-get install php5-sqlite
$ sudo apt-get install php5-curl

After some more LED flickering, these steps will also be executed and the Apache environment with PHP 5 is ready.

Step 3: install ownCloud

To install ownCloud, start by downloading the latest distribution. At this time, this is v8.0.3 and is downloaded with:

$ sudo wget https://download.owncloud.org/community/owncloud-8.0.3.tar.bz2

Next step is to unpack the ownCloud distribution and install it under Apache.

$ sudo mv owncloud-8.0.3.tar.bz2 /var/www
$ cd /var/www
$ sudo bunzip2 owncloud-8.0.3.tar.bz2
$ sudo tar xf owncloud-8.0.3.tar

Step 4: setting up ownCloud

To finalize, the data folder for ownCloud must be created and an admin account added.
The data folder is created with following steps:

$ sudo mkdir /var/www/owncloud/data
$ sudo chown www-data:www-data /var/www/owncloud/data
$ sudo chmod 750 /var/www/owncloud/data

At this time it is more convenient to continue the setup from a browser. Either start the graphical shell on the Raspberry Pi 2 or connect from a browser on an external machine and navigate to http://localhost/owncloud or from external machine http://192.168.1.100/owncloud/
The first screen that appears is to create an admin account, so add the credentials for an admin account on this page. With this account added, owncloud is up and running and ready for use.

Step 5: Connecting from Delphi to ownCloud

Now Delphi kicks in and with a little help from the TMS Cloud Pack, let's start using ownCloud from a Delphi app.

Start your IDE, make sure TMS Cloud Pack is installed and drop the component TAdvCalDAV on the form. Configure the TAdvCalDAV component to access your ownCloud. Verify the ownCloud primary CalDAV address by opening the calendar app within ownCloud via: http://192.168.1.100/owncloud/index.php/apps/calendar/ and in the bottom left corner, click on settings where this primary address is shown. By default, this should be:

http://192.168.1.100/owncloud/remote.php/caldav/

So, now we can configure the TAdvCalDAV component to connect to ownCloud on Raspberry Pi 2:

try
  AdvCalDav1.URL := 'http://192.168.1.100/owncloud/remote.php/caldav/';
  AdvCalDav1.Username := 'tms';
  AdvCalDav1.Password := 'tmsrocks!';
  AdvCalDav1.Active := true;
except
   Exit;
end;

After a successful connect, the calendars and their events available on ownCloud can be retrieved, here by filling the info in a listview:

var
  i: integer;
  cdi: TCalDavItem;
  li: TListItem;
begin
  // get events
  for i := 0 to AdvCalDav1.Items.Count - 1 do
  begin
    cdi := AdvCalDav1.Items[i];

    if cdi.vCalendar.vEvents.Count > 0 then
    begin
      li := ListView1.Items.Add;
      li.Caption := cdi.vCalendar.vEvents[0].Summary;
      li.SubItems.Add(FormatDateTime('dd/mm/yyyy hh:nn',cdi.vCalendar.vEvents[0].DTStart));
      li.SubItems.Add(FormatDateTime('dd/mm/yyyy hh:nn',cdi.vCalendar.vEvents[0].DTEnd));
      li.SubItems.Add(cdi.vCalendar.vEvents[0].Location);
      li.SubItems.Add(cdi.vCalendar.vEvents[0].Description.Text);
      li.Data := cdi;     
    end;
  end;
end;

Adding a new calendar item is equally easy:

var
  cdi: TCalDavItem;
  li: TListItem;
begin
  // set the calendar for the event
  cdi := AdvCalDav1.Items.Insert('Personal');  // add item to the "Personal" calendar
  cdi.vCalendar.vEvents.Add;
  cdi.vCalendar.vEvents[0].Summary := 'Schloss Dyck Classic Days';
  cdi.vCalendar.vEvents[0].Location := 'Jüchen, Deutschland';
  cdi.vCalendar.vEvents[0].Description.Text := 'Automobile Kulturgeschichte auf der Museums-Insel';
  cdi.vCalendar.vEvents[0].DTStart := EncodeDate(2015,7,31);
  cdi.vCalendar.vEvents[0].DTEnd := EncodeDate(2015,8;2);
  cdi.Post;
end;

or modifying an existing item

var
  cdi: TCalDavItem;
  li: TListItem;
begin
  cdi := ListView1.Selected.Data;
  cdi.vCalendar.vEvents[0].Summary := 'Schloss Dyck Classic Days 2015';
  cdi.Update;
end;

Similar to accessing the calendars of ownCloud, you can also access the contacts with the TAdvCardDAV component in a very similar way. And this rounded up my little weekend fun experiment. With so much ubiquitous computing power around and wonderful technology, aren't we living in very exciting times?

Querying objects in your REST server with XData

$
0
0

One of my favourite features of TMS XData is its powerful querying capabilities. With no extra line of code in your server, clients can choose how to retrieve the server objects, filter them, set an order, etc..
For example, you can perform a GET request to get Customer objects but filter only those which name is John:

http://server:2001/tms/xdata/Customer?$filter=Name eq 'John'

You can also filter by properties of associated objects, at any level. The next example gets all customers which associated country name is "USA":
http://server:2001/tms/xdata/Customer?$filter=Country/Name eq 'USA'

You can use order, top and skip to get paged results (get next 20 orders from 41st one):
http://server:2001/tms/xdata/Order?$orderby=Date&$top=20&$skip=40

And, of course, you can combine all those with parenthesis and relational operators to build really complex queries:
http://server:2001/tms/xdata/Customer?$filter=(Name eq 'John' or Name eq 'Jack') and Country/Name eq 'USA'

But the purpose of this post is to tell about the new built-in functions introduced in version 1.5. They increase flexibility of the queries even more. Functions that extract part of of a date/time property were added, so now you can for example filter invoices for year 2014:
http://server:2001/tms/xdata/Invoice?$filter=year(IssueDate) eq 2014

There are of course similar functions to extract Month, Day, Hour, Minute and Second.
String-related functions were also added. Upper and Lower were introduced:
http://server:2001/tms/xdata/Customer?$filter=lower(Name) eq 'paul'

You can also use length function to retrieve the length of a string in characters:
http://server:2001/tms/xdata/Customer?$filter=length(Name) eq 15

And Position and Substring functions can also be used to retrieve the position of a substring in a string (Position) or to retrieve part of a string (Substring). They would be the equivalent of Delphi functions Pos and Copy, respectively:
http://server:2001/tms/xdata/Customer?$filter=substring(CompanyName, 2, 4) eq 'oogl'
http://server:2001/tms/xdata/Customer?$filter=position('jr', Name) gt 0

And it's worth to remember that having TMS Aurelius working behind the scenes, all those queries will work the same way regardless of the database your are using at the server side, be it MS SQL Server, MySQL, Oracle, or any supported database you want. Best part is that it's not going to stop here, stay tuned for future releases that will bring even more querying features!

TMS hands-on training day

$
0
0

TMS software organizes a new training day on Tuesday November 24th in Kortrijk, Belgium. On this training day we will cover following 3 product areas to help you getting the maximum out of your applications with TMS components:

  • TMS VCL UI components for Windows application development.
  • TMS FireMonkey UI components for cross-platform FireMonkey application development.
  • TMS components to access cloud services from Windows and FireMonkey applications.

In tentative program

  • 09h00-09h30: Registration & coffee
  • 09h30-10h30: In depth with TMS VCL components pt 1
  • 10h30-10h45: Q&A
  • 10h45-11h15: Coffee break
  • 11h15-12h15: In depth with TMS VCL components pt 2
  • 12h15-12h30: Q&A
  • 12h30-13h30: Lunch
  • 13h30-14h30: In depth with TMS FireMonkey components pt 1
  • 14h30-14h45: Q&A
  • 14h45-15h15: Coffee break
  • 15h15-16h15: In depth with TMS FireMonkey components pt 2
  • 16h15-16h30: Q&A
  • 16h30-17h30: In depth with TMS Cloud components
  • 17h30-17h45: Q&A
Given the large number of components we have, we like to hear which topics are of most interest to you to fine-tune our program to your needs. Therefore you can vote on your favorite topics in the online registration form

We also suggest to bring your laptop if you want to follow the samples live or if you want one of our experts to have a look at your implementations. For a maximum interactivity, the number of seats will be limited to 20 persons.

Registrations until October 31st

The cost of the TMS training day is 75 EU + VAT. This includes a full day access to the sessions and coffee/drinks during this day. A hot meal is served for lunch.

Location

  • Kennedy Hotel, Pres. Kennedypark 1, B-8500 Kortrijk
  • Free parking
  • Nearby highway (E17) exit
  • Facilities for hotel rooms at the event are available for international attendees



Fixing the FMX TWebBrowser issue on iOS 9

$
0
0

Linking against iOS 9 introduces the new Application Transport Security feature that enforces a secure network connection. This means that in a default RAD Studio 10 Seattle project, the default TWebBrowser but also our TTMSFMXWebBrowser, TTMSFMXWebGMaps,
TTMSFMXWebOSMaps components and the TMS Cloud Pack for FireMonkey cloud services can no longer make a connection to the web. A solution for this issue is to add the following key to the Info.plist file:

<key>NSAppTransportSecurity</key>
   <dict>
      <key>NSAllowsArbitraryLoads</key>
         <true/>
   </dict>

As the Info.plist is automatically generated based on the project options, there is no option to specify a boolean key in a dictionary. To make sure the Info.plist file contains the correct keys in order to link against iOS 9 we have created an iOS9Fix command line executable and a post-build command.

1) Copy the iOS9Fix.exe to the project directory.

2) Add the following post-build command to your project options.

call "$(PROJECTDIR)iOS9Fix.exe" "$(OUTPUTPATH).info.plist"

If the above steps are executed correctly, your application should then be able to make a connection with one of the components mentioned in this blog post.

The solution with the above instructions can be downloaded at http://www.tmssoftware.net/public/iOS9Fix.zip


This was the month September at tmssoftware.com

$
0
0

Another busy month went by at tmssoftware.com and so much happened that it is good to quickly summarize everything new that was introduced.

TMS All-Access

We introduced the TMS All-Access subscription which is an easy no-nonsense subscription to simply ALL our products. ALL products means all products we offer now but also all new products we'll release in the year of the subscription. It gives you also access to betas, previews and of course our priority support services. So, with TMS All-Access, you never have to worry again if you will miss something or if you have to take budget in account for future products. TMS All-Access has you covered for VCL, FMX, .NET, IntraWeb and new frameworks we'll start to support in the coming months.

TMS Component Pack v8.0

A major update of our popular UI suite, featuring meanwhile over 400 components was released. Highlight of this new release is TAdvTreeView. TAdvTreeView is a high-performance & feature-rich, multi-column treeview that easily handles millions of nodes. TAdvTreeView can be used in virtual & normal modes. Other new components are TAdvMultiInputQueryDialog and TAdvScrollMenu and as always, there are numerous extensions to existing components in the suite.

TMS VCL Cloud Pack, TMS FMX Cloud Pack

The goal of our TMS Cloud products is to make consuming popular cloud services from your client applications as seamless as possible. Be it from Windows VCL apps, FMX cross platform apps, .NET Windows or web apps or IntraWeb web apps, with our cloud components, access to these cloud services is plug & play. In new versions of the cloud packs is now also support for Google Analytics, GMail, Google Sheets, Trello & Stripe payments.

TMS Hands-on training day

Our team also started the planning of a new focused hands-on training day on using our components. In a small group, we aim to give you as much as possible insights, tips & tricks in using our VCL, FMX, Cloud components. Number of attendees is kept small to have as much interaction as possible and have the ability to look at your specific questions. A few places are still available, so register quickly if you want to participate.

TMS Flexcel DLL

We're proud to have released a new product this month, which is TMS Flexcel DLL. With TMS Flexcel DLL, the power of the Flexcel library to natively handle .XLS, .XLSX files becomes available to any programming language for Windows that is able to use DLLs.

TMS Pack for FireMonkey v3.2

Also for TMS Pack for FireMonkey, we released a major update. Our flag-ship suite of FMX controls features grids, planner, rich-text/html editor, syntax highlighting memo and with this new release from now on also a powerful treeview control. This high-performance, editable, optionally multi-column treeview deals with millions of nodes in a regular or virtual way. Also new is a virtual keyboard for touchscreens on Windows and Mac OS X.

RAD Studio 10 Seattle support

Our entire product suite got support for RAD Studio 10 Seattle. All active registered users get free updates of our products with now included RAD Studio 10 Seattle support.

New developments

And if this was not enough, our team was meanwhile also busy with research on new developments on VCL, FMX components as well as new products in the area of cloud, node.js, embedded C++, IoT, mobile, remoting, replication and more... Watch this space for announcements soon.

TMS FMX Chart update with new virtual mode available

$
0
0

Where in earlier versions, the method for adding values to a chart was via multiple calls to TMSFMXChart.Series[x].AddSinglePoint(), the new virtual mode offers a faster solution that is more flexible and typically consumes less memory. This can of course make a welcome difference when creating applications for mobile devices.
To start using the new TMS FMX Chart virtual mode, two events need to be implemented:

TMSFMXChart.OnGetNumberOfPoints()
and
TMSFMXChart.OnGetPoint()

In the first event, OnGetNumberOfPoints(), that is triggered for each series in the chart, the number of desired data points can be returned via the ANumberOfPoints parameter.
In this sample event handler, the number of points is set to 10000 for each series in the chart:

procedure TForm1.TMSFMXChart1GetNumberOfPoints(Sender: TObject;
  ASerie: TTMSFMXChartSerie; var ANumberOfPoints: Integer);
begin
  ANumberOfPoints := 10000;
end;
The second event, OnGetPoint() is used to return the value for each point in the chart series. Here comes the flexibility that these values can be retrieved directly from another data structure (even a database). In this sample example, we assume the values are in a dynamic array of 10000 values and for the sake of this example filled with random floating point values. This is the code that initializes two dynamic arrays that have the data for 2 series:
var
  data_arr_1, data_arr_2: array of double;
begin
  SetLength(data_arr_1,10000);
  SetLength(data_arr_2,10000);
  for i := 0 to Length(data_arr) - 1 do
    begin
      data_arr_1[i] := random(100) / 33;
      data_arr_2[i] := random(200) / 25;
    end;
end;
and now the event handler that sets the values for the virtual chart:
procedure TForm1.TMSFMXChart1GetPoint(Sender: TObject;
  ASerie: TTMSFMXChartSerie; AIndex: Integer;
  var APoint: TTMSFMXChartPointVirtual);
begin
   case ASerie.Index of
   0: if AIndex < Length(data_arr_1) then  
          APoint.YValue  := data_arr_1[AIndex]
   1: if AIndex < Length(data_arr_2) then  
          APoint.YValue  := data_arr_2[AIndex]
   end;
end;
A final touch is to apply some settings that will let the Y-axis scale automatically adapt to the values in the series and define the number of visible points along the X-axis (in this case 100 points of 10000 simultaneously visible along the X-axis, other values are shown when the chart is horizontally scrolled). This is done with:
  TMSFMXChart1.Series[0].AutoYRange := arEnabled;
  TMSFMXChart1.Series[0].MaxX := 100;
  TMSFMXChart1.Series[1].AutoYRange := arEnabled;
  TMSFMXChart1.Series[1].MaxX := 100;


TMS makes accessing cloud services from Raspberry Pi a piece of cake

$
0
0

The world of IoT opens fascinating & innovative capabilities to steer & sense the physical world from small programmable devices like the Raspberry Pi. It becomes even more interesting when this can be connected to cloud services. Imagine a device that unlocks a door at times controlled by a Google Calendar, a device monitoring noise levels in a room and sending a push notification to a mobile phone when a level is exceeded, a device automatically controlling a step motor with data retrieved from a Google Sheet, a device that counts people passing a door and logging this data in a DropBox data file, ... and so much more...

All this is nowadays not only possible, but it is also cheap to make and easy to write software for with the Pascal programming language.
With respect to writing the software that connects embedded apps to all kinds of popular cloud services, the all new TMS LCL Cloud Pack offers numerous easy to use components that seamlessly interact with these cloud services. It offers access to all popular cloud storage services, social media, calendering services, push notification services and more... See full list here.

In our lab, we had fun making a sample app that shows the number of visitors on our website that is retrieved with the Google Analytics realtime data API on a quad 7 segment LED with only a few lines of code.

In order to get started writing cloud-connected apps for the Raspberry Pi, all you need to do is download & install Lazarus v1.5 on your Raspberry Pi and then download & install the TMS LCL Cloud Pack. After install, over 30 new components are available for you. Then register for an application key & secret at your favorite cloud service and use our new Access Token generator app for Windows & Mac OS-X we created especially for TMS LCL Cloud Pack and have it generate the access token and export the token to your Raspberry Pi. With this mechanism, your embedded app can connect to cloud services without requiring any user interaction on the device for authentication & authorization for using a service. Once this is done, you're ready to let the cloud service component of your choice start consuming or producing data for the cloud service.

Finally, note that with Lazarus and our TMS LCL Cloud Pack, you're not limited to Raspberry Pi only. You can develop the prototype of the Raspberry Pi app on a Windows, Mac OS-X, Linux machine or can make full apps for these operating systems as well.


We hope you'll have as much fun creating this brand new type of applications as we had developing TMS LCL Cloud Pack and we're thrilled to learn about what your innovative apps will be!

This was the month November and December at tmssoftware.com

$
0
0

Just like September, November & December were again very busy months here at tmssoftware.com. A small overview:

TMS Logging

In the beginning of this month we released TMS Logging v1.0.0.0, a new logging framework that makes use of log levels to output values/objects. We developed TMS Logging to have a cross-platform solution that is flexible, compact and offers informative logs with a minimum amount of log code. TMS Logging is available for XE7 update 1 or newer (due to using the newest Delphi language features extensively) releases and supports VCL Win32/Win64 apps and FMX Win32/Win64/Mac OS-X/iOS/Android apps.


TMS LCL Cloud Pack

Begin November, our TMS Cloud Studio has been extended with TMS LCL Cloud Pack v1.0.0.0 . TMS LCL Cloud Pack offers easy access from Windows, Raspberry Pi, Mac OS-X, Linux applications to cloud services like Amazon, Facebook, Flickr, FourSquare, Picasa, Google, LinkedIn, Twitter,Wunderground weather, YouTube, ... . It offers access to all popular cloud storage services like OneDrive, Box, DropBox, calendering services, push notification services and more...



Watch our twitter account or facebook page for announcements about new developments on LCL components soon!

TMS Hands-on training day

The second edition of the TMS hands-on training day end November was again very successful. It was not only interesting for the attendees, but also for our team! We could talk to our customers face to face, hear stories about their experiences with Delphi, and could see what fantastic applications were developed with TMS components. We also got interesting suggestions on new features and new components some of which already found their way into product releases and others we will definitely work on in 2016. After this successful edition, we can say with certainty we'll be planning more events on TMS tools next year!


myWebMachine

We also acquired myWebMachine.com, a small company focusing on offering zero-client solutions to control a personal computer.

myWebMachine offers great & innovative technology to access your PC literally from anywhere, anytime: a Windows PC can be remotely controlled from another Windows PC, Mac OS-X or Linux computer or from devices such as iPad, iPhone, Android tablet, Microsoft Surface, Smart TV without the need to install any software on the client machine. Using the standard installed browser is sufficient.

If you wish to try out myWebMachine yourself, a free fully functional trial version is available at http://www.mywebmachine.com


TMS iCL v2.8.0.0

Our set of native iOS controls was also extended and improved. There were new capabilities and improvements in TTMSFMXNativeUITableView and a new control was added: TTMSFMXNativeAVPlayerViewController. This new control surfaces the iOS capability to display streaming video content along with system-supplied playback controls. It supports wireless movie playback to AirPlay-enabled hardware such as Apple TV and also the new iOS 9 picture-in-picture view.

TMS Component Pack updates

Our flagship bundle of productivity feature-packed VCL controls for Windows application development got 4! updates in the past 2 months. Our team is day-in, day-out listening to your requests & feedback and added no less than 29 new features and numerous smaller improvements and fixes over the last 4 free updates. And yes, also documentation was extended and samples were improved. Check out the latest version of TMS Component Pack and stay tuned for more new capabilities to be added in upcoming versions.

TMS FMX Chart v1.5.0.0

And finally, this week we released a major update of our cross-platform chart component. In TMS Charts for FireMonkey v1.5.0.0 we've added ctBand support.


Knowledge base alert

We would also like to say a small word about our monthly Knowledge base alert we started with this year. From the positive feedback we received from several subscribers, and for which we want to thank you, we can conclude many of our users appreciated this technical knowledge base alert. We will keep gathering these useful articles about our products and provide them to you via our newsletter. You can always consult these tips at: http://www.tmssoftware.com/site/kbnewsletters.asp our via http://www.tmssoftware.com/site/tips.asp
If you are not yet subscribed, you can add your email address here.

Best wishes for a happy & prosperous New Year from the TMS team!

We can conclude we ended 2015 with some new exciting developments. We're already brainstorming on several things for 2016 and we look forward to be at your service in 2016!



Our little New-Year gift for Pascal developers

$
0
0

On this last day of the year, we'd like to introduce a first version of a little New Year's gift for you, Pascal developers. If you are, like us, excited about Internet of Things, embedded software development, DIY projects, controlling electronics from your code, ... we have for you a first version of our new free & open-source bundle of hardware access components for Raspberry Pi. You can download full source code from here

  
This is a first small step into making interfacing with all kinds of external electronic devices like sensors, displays, step motor, input devices etc... as easy as setting a few properties or calling a few methods of a class. If you would for example like to measure some analog voltage and display the result on a small LCD display, this becomes as simple as:
var
  v: integer;
  s: string;
begin
TMSLCLAdaDispl16x2.Init;
v := TMSLCLAdaADC12B.ReadChannel(0);
s := 'Value: ' + IntToStr(v) + 'V';
TMSLCLAdaDispl16x2.DrawText(s);
end;

At this moment we have components for following Raspberry Pi breakouts and more are coming...

Adafruit 4 digit 7 segment display


Adafruit monochrome 128X32 OLED graphic display


Adafruit 12bit DAC


Adafruit 12bit 4 channel ADC


Adafruit RGB 16x2 LCD + keypad


Adafruit barometric pressure/temperature sensor


We of course also welcome you to contribute to this open-source package. Contact us with your suggestions, feedback, contributions.

Viewing all 1008 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>