Monday, December 10, 2012

Usability++

I've added hunspell wrappers in Concept Framework (http://www.radgs.com/docs/help/standard.lib.hunspell.html).

Also, I've added into standard.lib.str Soundes, Metaphone and DoubleMetaphone functions.

I've added a few new gadgets in GyroGears applications.

1. Autocorrect in search fields (works for almost every language - defaults comes with English (US+GB) and Romanian.


2. Spell checker in text views.
3. Shortcuts for adding in relation members (see the above screenshots).

4. Beautify solution for GyroGears. This beautifies your app (aligns labels, chose which columns to be visible by default in views and so on).


Sunday, December 2, 2012

GyroGears and usability

I've had some crazy requests in the last few months. The users (end-users) complained about the usability of Gyro applications, and in some aspects they were right.

1. Latest complaint: interfaces are ugly, so I'm working at new ones. 

This is the new main applications screen:



If you think it looks like something, rest assured it is not.

2.  The calendar is useless.

I redesigned the calendar. Now it looks like a classic calendar widget, with drag and drop (you can now reschedule an event by moving it to another day/hour).




3. Database search - redesigned

Pattern search now applies to spaces. So, if somebody looks for "Mikey Mouse", "Mickey The Mouse" will be also returned.

Three new options for entities in GyroGears:
- search by parent
- show parent as a chain
- child search level

Let's consider a client who has contracts. In the contracts master view, I can now type the client's name, and it will return all of its contracts. Same logic for child search level. For example, in the client list, I can enter a contract number and see the client with that contract number.

A few version ago I added "Show parent" options. This way, in a master view, on the first column the parent entity representative member will be shown. But, if parent level was 2 or more, only the final parent shall be shown. When the "show parent as chain", all the parents will be shown. For example, a client, has contracts and on every contract has a service. This way, on the service view, in the parent column, both the contract number and client name will be shown.

4. Horrible Glade for UI design (developers).

Until now I used glade-window as a method for embedding Glade into CIDE (Concept IDE). This meant that on every new Glade version I had to modify the sources.

So, I've wrote my own "glade-window.


Also GTK3 is now used on Windows too.


5. Editable ComboBoxes for many to one relations

For many to one relations you could set in GyroGears "use a combo". Now, you can also set "editable combo box". This way the user can perform a quick look-up for the given member.


6. Too many "Save" buttons for modifying a child object

When you check "enable send to" for a relation, now you get this cool context menu.


This enables the used to add a child object, without editing the parent (and so, avoiding a lock).

7. Localization and international support.

A company in Jordan has Arab employees and Romanian management. So, for the same application, two different languages were needed. This was already fine with Gyro. Now is perfect.


Also, date and time can now be formatted. (Eg: %d/%m/%Y %H:%M).

8. Telephony integration

I've added a SIPPhone class in the Concept Framework. This allows you to initiate a call, answer one and talk using a high level interface.

This is somehow cool if we talk about a CRM, and the client calls in. Then, the application automatically detects the client and opens his or her records.

9. Button press feedback for image buttons on mobile client

A friend of mine tried Concept Client Mobile. He complained about the lack of feedback when he pressed an image button. So, I've added a gray tint when the button was pressed.

10. Flash in WKB (Concept Webkit Browser) on Windows (thanks to Midori)

WebKitGtk finally works as it should on Windows. Also, the left key doesn't hang up the WYSIWYG editors.




This week I will modify the data input interface and add keyboard shortcuts for various operations.

Sunday, October 28, 2012

New features for GyroGears

I've spent nearly 80 hours talking with GyroGears users (both programmers and non-programmers). A year ago the support for smarty-like templates was dropped in favor of XSLT. Then I used Sablotron but switched later to libxslt2 (easier to install). Now, the developers asked me about the possibility of calling Concept functions from XSLT, and I've said no. Not because is not possible, but because I consider it bad practice. However I've been asked about this so many times that I've decided to implement it. I've made a very simple interface - just one function that registers all members of a class:

XSLTRegister(object[, alias, namespace]).

So, you can just call XSLTRegister(this) and you will be able to call from the XSLT every function.

Also, Gyro now generates interfaces functions for XSLT. You could call something like:

<xsl:variable name="invoices" select="csp:WU_Client.GetInvoices(__DBID)"/>

Or even:
<xsl:variable name="clients" select="csp:WU_Client.Search('some client name')"/>

And then:

<xsl:for-each select="invoices/array/element">
   Amount: <xsl:value-of select="invoices/array/element/Amount"/>
</xsl:for-each>





Also, 3 features were implemented:

Reorderable flag for entities (you can reorder objects by drag and drop - lots of fun playing with this one) and reorderable flag for relations (just for non-exclusive ones). This allows the user to reorder objects in related views without affecting the master view order.

The third one - a flag for linking an object list to every HTTP script (for example an entity called "Menu" with this flag set to true will cause the menu items to be linked to every script.


As usual lots of bugs fixed. One was linked with the usage of filters on relation fields.

Monday, October 8, 2012

Android Client and GyroGears Mobile

It's ready and it's cool. Concept Client Android version is available for download (just use your Android device and visit www.devronium.com and download Concept Client. I've managed to make it fully compatible with the existing Concept Framework.

This means that GyroGears can automatically generate Android Applications.

Take a look at how it looks:

















 

Just remember that everything (except the last one) is automatically generated by GyroGears in only a few seconds.

The last screenshot is my telephony application based entirely on Concept Application Server (even the Telephony server is Concept-based)..

Monday, September 10, 2012

Concept Client 2.0 Android Beta1

After implementing 2 mobile clients, one based on MoSync and another one based on Marmalade, I've decided to implement using "the native way". I've made the Concept Client 2.0 for Android devices using only Android SDK and NDK (the socket layer).

After looking into MoSync, I can say that is a nice platform but with a big drawback: the sockets. They implement AsyncSocket and it is a good idea, however, this cannot be a solution for every situation. Just think at a VoIP application.

On the other hand, Marmalade has better sockets and low level APIs, and is significantly faster. However the support is almost zero (Maybe for enterprise licenses is different). Also, the native user interface (IwNUI) it lacks lots of functionality. Audio API's are almost impossible to use, at least if we're talking about streaming (you cannot use locks in audio callbacks).

Now, Android SDK and NDK is straight forward. I've ported the client in about 7 days, which is fine. Next to come is iOS.



This is from a VoIP application that I'm working on - entirely Concept Application Server - based.

Saturday, August 4, 2012

8 years of Concept

It's been 8 years from the first working version of Concept. Now, it's mature, stable, feature rich and used in production in over 200 applications.

As usual lots of bug-fixes, and new features:
  • a bug in MySQL interface library that caused a crash when reading blobs of considerable size
  • UDP socket support
  • New multi-threading core library (uses the same code base - it must be compiled with -DSIMPLE_MULTI_THREADING). With this option you can create applications that are writing to the same variables without any need of semaphores. The speed penalty for non-threaded scripts is under 5% and but when running a multi-threaded script, the penalty can range from 5% to 100% depending on number of memory writes. For usual applications is about 6% to 10%. Also, there is no memory overhead.
  • Faster Garbage Collector (hundreds of time faster) by replacing the pointer list with std::set. - About 7% less memory used. The optimization is made on variables, 32 bits less memory used by each string variables and 64 bits less for each non-string variable.
  • SIP stack library ported to Concept (work in progress) Now, the really cool new feature is in GyroGears. For every generated application it automatically generates the migration script for SQL-based database. NoSQL is to come, and automatic migration from SQL to NoSQL. The problem with NoSQL (MongoDB) is that it uses a different id-system, and the migration cannot be done one to one. Now, you can move from one server to another and back in a few minutes. It supports MySQL, PostgreSQL, SQLite, NuoDB, ODBC amd Firebird (via ODBC). For migration, you just run the required script in migrate.prev folder (ServerRoot/MyProjects/YourAppName/migrate.prev). 

Here's a multi-threading example using the concept MT core - as you will see, no semaphore are used for threads accessing the same variables.


Thursday, June 28, 2012

SVG Surface

A few months ago I've made an experiment: I've created a canvas-independent class that rendered on a SVG. Then, I've added a simple interface that allowed me to render the SVG on an operating-system dependent surface. This was a base for an UI based on SVG and completely independent of the OS. After a few more testing, I've decided to integrate this surface in Concept Client 2.0.190. So here it is:


All the buttons are defined in XML:

_Common.svg
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
  <linearGradient id="linearGradient1">
   <stop stop-color="#ffb100" offset="0"/>
   <stop stop-color="#ffb100" stop-opacity="0.498039" offset="0.5"/>
   <stop stop-color="#ffffff" offset="1"/>
  </linearGradient>
  <linearGradient y2="-0.000052" x2="0.519006" y1="2.485417" x1="0.527431" id="linearGradient11" xlink:href="#linearGradient1"/>

  <linearGradient id="linearGradient2">
   <stop stop-color="#ffff00" offset="0"/>
   <stop stop-color="#ffff00" stop-opacity="0.498039" offset="0.5"/>
   <stop stop-color="#ffffff" offset="1"/>
  </linearGradient>
  <linearGradient y2="-0.000052" x2="0.519006" y1="2.485417" x1="0.527431" id="linearGradient12" xlink:href="#linearGradient2"/>

  <linearGradient id="linearGradient3">
   <stop stop-color="#ffb1ff" offset="0"/>
   <stop stop-color="#ffb1ff" stop-opacity="0.498039" offset="0.5"/>
   <stop stop-color="#ffffff" offset="1"/>
  </linearGradient>
  <linearGradient y2="-0.000052" x2="0.519006" y1="2.485417" x1="0.527431" id="linearGradient13" xlink:href="#linearGradient3"/>

 </defs>
 <metadata>image/svg+xml</metadata>
</svg>


Button.svg
<control class="Button">
    <svg for="normal" width="70" height="30">
        <rect fill="url(#linearGradient11)" stroke-width="0.799956" stroke-opacity="0.805" ry="5.809992" y="0" x="0" height="100%" width="100%"/>
    </svg>

    <svg for="prelight" width="70" height="30">
        <rect fill="url(#linearGradient12)" stroke-width="0.799956" stroke-opacity="0.805" ry="5.809992" y="0" x="0" height="100%" width="100%"/>
    </svg>

    <svg for="clicked" width="70" height="30">
        <rect fill="url(#linearGradient13)" stroke-width="0.799956" stroke-opacity="0.805" ry="5.809992" y="0" x="0" height="100%" width="100%"/>
    </svg>
</control>



Label.svg
<control class="Label" passive="1">
    <svg for="normal" width="70" height="30">
        <text style="font-size: 12; fill:#A0A0A0; font-style:bold; stroke-width:2px; font-family: verdana, arial, sans-serif;" id="text3208" y="100%" x="0" xml:space="preserve">Hello !</text>
    </svg>

    <svg for="prelight" width="70" height="30">
        <text style="font-size: 12; fill:#ffffff; font-style:bold; stroke-width:2px; font-family: verdana, arial, sans-serif;" id="text3208" y="100%" x="0" xml:space="preserve">Hello !</text>
    </svg>

    <svg for="clicked" width="70" height="30">
        <text style="font-size: 12; fill:#FF8080; font-style:bold; stroke-width:2px; font-family: verdana, arial, sans-serif;" id="text3208" y="100%" x="2" xml:space="preserve">Hello !</text>
    </svg>
</control>



This surface enables you do easily define your own custom controls.

I think that this will be the base for Concept Client 4.0 IF and only IF I decide do get rid of GTK+. Gtk is a fabulous UI framework, but moving to my own, backwards-compatible framework, it will give Concept Applications a nicer look and feel. This is just an idea. Most probably I will use both GTK+ and SVG surfaces.

Now, this is Gyro!



Tuesday, June 26, 2012

Treeviewlicious

I've implemented lots of CRM's and search engines using GyroGears. Once in a while I get some unusual request, that GyroGears cannot fulfill

This happened yesterday, two times. A CRM client asked for a solution to group similar client requests in view. Something like the e-mails. You get an e-mail, then a reply, and so on.

So I've decided to add this feature (it was done at about 2 AM in the morning).


As you can see, the "Cereri" (it means "Requests") objects are  grouped together (Notice the expander).


And all this is done by using a flag "Show in tree view when  possible". No other configuration required.

Now, about the second feature. This it will take me a few days. A client of mine asked to use simultaneous AND and OR filters. Now the filters are combined with AND by default and can be combined with OR by default. But never both AND and OR. This is now on my todo list, I hope to have it ready in about a week or so.

Thursday, June 21, 2012

Gyrolicious

I've had some unusual requests in the last two weeks, so I've decided to implement them in Gyro core.

The users asked for navigation buttons (next/previous) for objects. This derives from the fact that all day are using web browsers. And a web browser has next and previous buttons, so here there are:


Even the cursor now follows the displayed object. This is a really simple feature asked by the users.

In several projects I've needed a way to filter some records by some "assigned users". For example in a project management solution, it is possible to add a member called "Responsible" defined as a relation with the user entity. Then, you can set the member as a filter member, and when a user that is listed in the responsible field logs in, it will see only his tasks. Here is a simple example - a meeting and some invited users:


Now, only the invited users will see the meeting. Do notice the Filter level - a user of a greater level will see all the meetings.

Another request was regarding Xapian. When using indexed search, there were some limitation: you couldn't use filters, and the search felled back to the database engine (which is not a good idea when performing complex searches). Now, you can filter Xapian data. Also, sort was added for the results. The results are sorted only for equal relevance (sort first by relevance and then by the selected field).

As usual, lots of bug fixes. The main fix is in Concept Client - there was some inconvenient stuff happening when using multiple displays. The main form opened in a window and, in some cases, the child window in another window. Of course, you can specify programatically what screen to use. Now, the child windows always inherit the parent display.

Sunday, June 10, 2012

NuoDB driver

I've tested these days NuoDB. It's a promising database server, for now in Beta, but there are some problems, that make NuoDB somehow more like a pre-alpha release. It's cool, it's cloud, it's nice and is something that we all want and need: SQL on the NoSQL market - the cloud.

GyroGears already generates code for NuoDB, but since is so unstable, I don't recommend deploying Gyro applications on NuoDB.

The driver low level API's are "pre-documented" here:
http://www.radgs.com/docs/help/standard.db.nuo.html

And the high level version:
http://www.radgs.com/docs/help/NuoConnection.html
http://www.radgs.com/docs/help/NuoDataSet.html

Also, I've optimized the strings and the arrays in Concept core. I've reduced the number of memory reallocations, resulting in faster indexing times. I've added a compile-time flag for using std::map instead of my key-value implementation.

std::map is faster than my implementation when adding more than 200,000 key-value pairs, but I'm faster on access. Also, std::map uses at least 1/3 more memory than my implementation, due to its list-style implementation. I use static vectors, that reallocate when needed. This reallocation is somehow slow, but overall, it performs better.

The string operator += was optimized, being up to 20 times faster now, due to a new memory allocation strategy.

In Gyro, besides NuoDB driver, I've fixed a bug with pagination, discovered in the new version of Concept Client.

Friday, April 27, 2012

UI 3.0

... and is done. Gyro applications have a new look and increased usability.


The search bar is now on top of the category tabs, more user preferences, the forms are faster now, and they restore before showing on the screen (avoiding the annoying resize after the form is shown). There are tons of new things, most of them regarding usability(see previous post).

Wednesday, April 18, 2012

UI models

I've seen some screenshots of enterprise applications, and I've decided that the Gyro application search/results-based UI is not enough for some situations.

I've added a new property for every entity (you can actually combine models for different entities):


You can choose from search/results (standard model) or master view/detail, minimizing the number of open forms for the user (and actually increasing the productivity for the end-user).




The screenshots are from an actual application, so I've blurred some of the data.

I've modified the home screen (yes, again):


And as usual, bug-fixes, most of them regarding the MongoDB applications.

Monday, April 16, 2012

Repli-Gears and bugfixes

I had a few days off, just enough to make some new test units for GyroGears. I've noticed that Gtk+ 3.4 is windows-ready, and I'm waiting for the official release. Concept Client already works on Gtk3, but I'm using unofficial windows builds, that have some problems. The biggest problem is with GtkSheet (from gtk+extra), a widget that is not available on Gtk 3. To avoid this, I've modified the RTreeView control, to act in some situations more like a grid.

This function was already available, but it wasn't very user friendly. The standard behavior is this: the user presses enter or clicks on the column he wishes to edit, types all the text and presses enter. The cursor doesn't move automatically on the next column. To avoid that, I've modified this behavior, and now, beside the enter key, the user can press the tab key, and the cursor moves automatically and remains in edit mode (Avoiding two key events: press the right arrow key and the enter key). It doesn't seem much, but when dealing with large amounts of data, it can make a difference for the user.

The new feature is record duplication.


This allows the end-user to duplicate a record. This will duplicate all the non-exclusive relations (many-to-*), for the new created object.

For the exclusive relations (one-to-*) you can decide in GyroGears if is "duplicable" or not.

If this is checked, the exclusive relation will be duplicated. If the related entity has unique fields, this will bypass the standard validation (this feature is not stupid-proof), and GyroGears will issue a warning.

I've switched the default GyroGears web control to RWebKit (dropping RHTML). This is a preparation for Gtk3 (I'm not sure if they will suport GtkHtml anymore). However, I've emulate the old RHTML control using RWebKit, not to affect the existing software (just Concept Client will use the new control).


I've used some nice CSS3 effects like shadow.

I've modified the multiple delete and archive engine. Now, if an error is encountered when deleting/archiving, the entire operation is undone (rolled back). I've also speed up these operations that take significantly less time when dealing with large amounts of data.

Monday, April 9, 2012

Cranberry tea with end-users

About a week ago I sat with 4 of my end-users. The youngest has about 27 years and the oldest about 55, 2 men and 2 women. I watched how they use a Gyro-generated application, and notice they reflexes. And then, I've noticed how their eyes were looking for information on the screen. They had never used a Gyro application before. After watching them, I came out with a few and simple features that increase the overall usability.

First of all, the notebook tabs. The users sometimes find it hard to look for the tabs on top of the screen. He or she is maybe used with paper notebooks, that are indexed on the left or right side. So, I've added some new options there.


Now you can organize the categories into left- or right- aligned tabs, depending on your users.


I've noticed that some times the users are overwhelmed by the amount of information required for them to fill it in, so, I've added the expanders (by default, an expander containing a mandatory field is opened).


As you can see, every subcategory can now be expanded/collapsed. Simple, but very useful for the end-user.

Usability, usability, usability !


Some bug-fixes, as usual, mostly regarding the UI and one with some unoptimized queries.

For old folks, that use dBase, I've added support for dbf files. Not really needed these days, but useful when interacting with old applications.

Saturday, February 18, 2012

Language candy and Mongo

Finished the implementation for MongoDB. Most Gyro features working with SQL are now working with MongoDB. Just faster. As a down side: no transactions, and different "cancel" behavior. For example, if we have an entity called "Post" and another one called "Comment" (related, one-to-any), on SQL, if the user modifies a comment and saves it, and the presses cancel on the parent object (Post), this causes a rollback for all the modified data in that transaction.

On NoSQL, same scenario, if a comment is modified, and then the parent is not saved, this will cause commit for the comment and rollback (emulated) for the post. Is not really a drawback, just a thing to keep in mind when designing your application.

I've introduced a new language core element: static key specification:
Something you used to do like this:

var arr0=new [];
arr0["key"]="some value";
arr0[3]="some index value";

// you can now do it like this:
var arr=["key" => "some value", 3 => "some index value"];
// or
// => and : are synonyms
var arr2=["key" : "some value", 3 : "some index value"];


Also, a new function (defined in standard.lang.serialize and Serializable.con): ToArray(object). This converts an object into an array, very useful for debugging, because you can now say:

echo ToArray(this);

GyroGears relations on MongoDB are now available using a mixed redundant relation/schema design. The related model is needed for maintaining Gyro-generated framework API compatibility with SQL design. The schema design is used for optimizing relation search. Yes, it is a little redundant, but it works very fast.

While implementing MongoDB driver, I've managed to identify a series of unreported bugs in GyroGears: revisions didn't work as expected for relations, some minor bugs in web search when searching by owner.

A new feature in GyroGears: View option for objects. All objects where opened in edit mode, this causing a locking of the record. Some times, the user just wanted to review the data, so the "View" menu option (when right clicking a record) opens a record in read only mode without locking.

I've made some preventive bug-fixing in Concept Server (automated tests), and MongoDB and MySQL driver.

Sunday, February 5, 2012

MongoDB is the first NoSQL supported database server

It's been a while since I've started pondering about the benefits of NoSQL database engines. After implementing more than 100 GyroGears solutions, I've started to notice some patterns suitable for no-sql engines.



I've finished all the preliminary tests for the MongoDB Concept driver, the auto-documentation is available here:

http://www.radgs.com/docs/help/MongoConnection.html
http://www.radgs.com/docs/help/MongoDataSet.html
http://www.radgs.com/docs/help/MongoCursor.html

And static functions here:
http://www.radgs.com/docs/help/standard.db.mongo.html

I've modified GyroGears to use this driver, though is not yet fully functional. The relations, files and multimedia types are not working properly yet.

Here is a screenshot of a GyroGears application running on MongoDB.



You can see that you can use sql-style wildcard (for backwards compatibility). You can regenerate your old SQL-based Gyro application for MongoDB without the end-user ever noticing.

Here is a shot of how the Mongo data looks like:


I've used MongoVUE, no Concept Application Server tool yet available for managing Mongo data.

Sunday, January 29, 2012

GyroGears is getting cooler

Lots of new stuff available in GyroGears.
Let's see:


New formulas, a lot easier to use:

QueryDB("select sum(`product`.`price`) from product inner join `rel_order_products` on `id_product`=`id` where `id_order`=$id") * (100-Discount)/100 + Shipping_fees

As you can see, it is a combined formula, using both a query and Concept computations (in red).

New member validation expression (PERL-compatible expressions).
[A-Za-z0-9_\.\-]+\@[A-Za-z0-9_\.\-]+\.[A-Za-z0-9_\.\-]+
it validates an email address.


User defined functions can be now defined directly from GyroGears, without any need to open CIDE (see the button).

A new source editor, with code completion, automatic indenting, search functions and zoom. This editor will replace the old editor in Concept IDE.

A new data type: reference.
A reference relation is a virtual relation to a member in a related entity. Then, that object will be mapped in the referring object. Look at the next screenshot to see exactly how it works.


For example, a blog post has comments and images. Each image has its own comments. So, you can add a reference to Image/Comments in the Post entity. This way, the end-user can see all the comments for all the images for a specific post.

A lots of bug were fixes in various areas (especially in reporting and web sources).