Archive for the ‘ DEVELOPMENT ’ Category

Create a webcam face detection within OpenLaszlo by using ActionScript3

Today i found a smart script for a webcam face detection on www.quasimondo.com.
Now i will try to do this within OpenLaszlo, thus post based also on this sample.. 😉

Click here for a quick demo 😉

First of all, we have to download the sourcecode in the Marilena_mod10.zip from www.quasimondo.com and extract it.

To be able to use the source code, we have to compile the ActionScript files into a SWC file. Therefore we need a Flex SDK. If you not already installed it, read here how do you do this under Ubuntu Linux.
When you have the Flex SDK available, navigate into the src directory from the extracted sourcecode and compile the SWC with the following action:

compc -source-path ./ -include-sources ./ -optimize -output ../faceDetection.swc

 
The result is the faceDetection.swc file, which must now be provided to OpenLaszlo. How you can do this, read it here in detail. In short, copy it into your flexlib directory within your OpenLaszlo WEB-INF directory.

Now you can import the required base libaries into a self implemented class by using a passthrough tag:

<class name="faceDetector" width="480" height="640">
	
	<switch>
		<unless property="$as3">
			<handler name="oninit">
			<![CDATA[
				Debug.error("ActionScript 3 required");
			]]>
			</handler>				
		</unless>
		<otherwise>
			<passthrough>
				import com.quasimondo.bitmapdata.CameraBitmap;
				import jp.maaash.ObjectDetection.ObjectDetector;
				import jp.maaash.ObjectDetection.ObjectDetectorEvent;
				import jp.maaash.ObjectDetection.ObjectDetectorOptions;
				...
			</passthrough>

			...

 
The first great step is now done and we will further implement a complete class for using the face detection, so that we in future just have include a tag for using it.
We will do this also on our base sample. The result is a port to OpenLaszlo of these, with just a few differences:

<!---	Object Variables -->
<attribute name="detector" type="expression"/>
<attribute name="camera" type="expression"/>
<attribute name="faceRectContainer" type="expression"/>
<attribute name="detectionMap" type="expression"/>
<attribute name="drawMatrix" type="expression"/>

<!---	Scale factor of the image -->
<attribute name="scaleFactor" type="number" value="4"/>

<!---	Is currently a face detected?! -->
<attribute name="faceDetected" type="boolean" value="false" />
	
<!---	Weight of the face rect -->
<attribute name="rectLineWeight" type="number" value="2"/>

<!---	Starting the initiation -->
<handler name="oninit">
<![CDATA[

	if(this.scaleFactor==0) {
		Debug.error("scaleFactor must be greater 0");
	}

	this.initUI();
	this.initDetector();
]]>
</handler>				

<!---	Init the UI -->
<method name="initUI" args="" returns="void">
<![CDATA[
	var view = new Sprite();
	this.getDisplayObject().addChild(view);

	this.camera = new CameraBitmap(this.width, this.height, 15);
	this.camera.addEventListener(Event.RENDER, this.cameraReadyHandler);
	view.addChild( new Bitmap(this.camera.bitmapData) );
			
	this.detectionMap = new BitmapData(this.width/this.scaleFactor, this.height/this.scaleFactor, false, 0);
	this.drawMatrix = new Matrix(1/this.scaleFactor, 0, 0, 1/this.scaleFactor);
		
	this.faceRectContainer = new Sprite();
	view.addChild(this.faceRectContainer);
]]>
</method>


<!---	Is called when the camera is ready -->
<method name="cameraReadyHandler" args="event:Event" returns="void">
<![CDATA[
	this.detectionMap.draw(this.camera.bitmapData, this.drawMatrix, null, "normal", null, true);
	this.detector.detect(this.detectionMap);
]]>
</method>


<!---	Init the detector -->
<method name="initDetector" args="" returns="void">
<![CDATA[

	// Creat a new ObjectDetector
	this.detector = new ObjectDetector();
	
	// ..and give them the required options 
	var options:ObjectDetectorOptions = new ObjectDetectorOptions();
	options.min_size  = 30;
	this.detector.options = options;
	this.detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE, this.detectionHandler);
]]>
</method>


<!---	Is called at every detection -->
<method name="detectionHandler" args="e:ObjectDetectorEvent" returns="void">
<![CDATA[				

	var g :Graphics = this.faceRectContainer.graphics;
	g.clear();
	if(e.rects) {
		g.lineStyle(this.rectLineWeight);
		e.rects.forEach( function( r :Rectangle, idx :int, arr :Array ) :void {
			
			// Set face detected
			if(!faceDetector.faceDetected) faceDetector.setAttribute("faceDetected", true);
										
			// Timer when face deteced is reset
			if(typeof this.resetDetectionDelegate == "undefined") {
				this.resetDetectionDelegate = new LzDelegate(faceDetector, "resetDetection");
				lz.Timer.addTimer(this.resetDetectionDelegate, 500);
			}
			else {
				lz.Timer.resetTimer(this.resetDetectionDelegate, 500);
			}
			g.drawRect( r.x * faceDetector.scaleFactor, r.y * faceDetector.scaleFactor, r.width * faceDetector.scaleFactor, r.height * faceDetector.scaleFactor );
		});
	}
						
]]>
</method>

<!---	Is called when no face is anymore detected -->
<method name="resetDetection" args="something" returns="void">
<![CDATA[
	if(this.faceDetected) this.setAttribute("faceDetected", false);
]]>
</method>	

 
After finishing the impĺementation of the face detection class, just have to include the new class and place the tag on the required target. We do the as sample in the source code from the snapShot article i have written some days ago:

<simplelayout axis="y" spacing="0" />
<view name="videoView" width="$once{canvas.imageWidth*2}" height="$once{canvas.imageHeight}">
	<simplelayout axis="x" spacing="0" />
	<view name="videoView" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
		<faceDetector name="faceDetector" id="faceDetector" scaleFactor="2" rectLineWeight="1"
					  width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
			<handler name="onfaceDetected">
			<![CDATA[
				Debug.write(this, "onfaceDetected("+this.faceDetected+")")
			]]>
			</handler>
		</faceDetector>
	</view>
	
	<view name="snapshot" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}" />
</view>
			
<view layout="axis: x; spacing:0">
	<button text="Take a snapshot" onclick="canvas.takeSnapshot();" width="$once{canvas.imageWidth}" enabled="${faceDetector.faceDetected}" />
	<button text="Save snapshot" onclick="canvas.saveImage();" width="$once{canvas.imageWidth}" enabled="${canvas.shotAvailable}" />		
</view>	

 
How you see, we just exchange the videoview-tag with the faceDetection-tag, and add the faceDetected-constraint to the enabled attribute of the snapshot button.
This was very easy, or?! And the result pretty nice.. 🙂
Thanks in this place to Mario Klingemann and all other they have optimize and work on this code.

Click here for a demo 😉

Sourcecode: OpenLaszlo - FaceDetection.zip (1621)

If you found some bugs or have some Tips, please contact me.

Read and write files from local filesystem with OpenLaszlo by using ActionScript3

Today i will try to read and write local files from a local storage. After a few searches with google, i found several similar samples. Now i integrate these with the sample from www.mikechambers.com within my OpenLaszlo code. For both, reading and writing files, we need the usual main structure, with a runtime switch and passthrough for the actionscript libraries.

Click here for a quick demo 😉

At first, we have look at the reading of a file. For that we create a few small functions, some of them act as an event handler.
 
1. The function that invokes the loading. Here we instantiate a FileReference object, register the required eventlistener and open the browser window for selecting a file. Further you will find here the fileFilterValue variable, within you are able to restrict the allowed file types for selecting.

<!---	called when the user clicks the load file button -->
<method name="loadFile" returns="void">
<![CDATA[	
	
	// create the FileReference instance
	this.fr = new FileReference();

	// listen for when they select a file
	this.fr.addEventListener(Event.SELECT, this.onFileSelect);

	// listen for when then cancel out of the browse dialog
	this.fr.addEventListener(Event.CANCEL, this.onCancel);

	// open a native browse dialog that filters for text files
	this.fr.browse([new FileFilter(this.fileFilterValue, this.fileFilterValue)]);
								
]]>
</method>

 
2. The function that is called, when the user has selected a file. Here we register two further eventlistener, the onLoadError and onLoadComplete eventlistener, and starting the loading progress.

<!---	called when the user selects a file this.from the browse dialog -->
<method name="onFileSelect" args="e:Event" returns="void">
<![CDATA[
	Debug.write(this, "->onFileSelect()");

	// listen for when the file has loaded
	this.fr.addEventListener(Event.COMPLETE, this.onLoadComplete);

	// listen for any errors reading the file
	this.fr.addEventListener(IOErrorEvent.IO_ERROR, this.onLoadError);

	// load the content of the file
	this.fr.load();						
]]>
</method>

 
3. The onLoadComplete function is called, when the file is transferred to the flash application. Here we receive the file contents and clean up the FileReference instance.

<!---	called when the file has completed loading -->
<method name="onLoadComplete" args="e:Event" returns="void">
<![CDATA[
	Debug.write(this, "->onLoadComplete()");

	// get the data this.from the file as a ByteArray
	var data:ByteArray = this.fr.data;

	// Get the file content
	this.setAttribute("fileContent", data.readUTFBytes(data.bytesAvailable));
	
	// clean up the FileReference instance	
	this.fr = null;					
]]>
</method>

 
4. The onLoadError function will be called in case of a transfer-error.

<!---	called if an error occurs while loading the file -->
<method name="onLoadError" args="e:IOErrorEvent" returns="void">
<![CDATA[
	Debug.error(this, "->onLoadError(): " + e.text);					
]]>
</method>

 
5. The onCancel function is used of both, the reading and writing action, and is just called when the user aborts the file selecting browser window or file saving browser window.

<!---	called if the user cancels out of the file save dialog -->
<method name="onCancel" args="e:Event">
<![CDATA[
	Debug.write(this, "->onCancel()");
	this.fr = null;						
]]>
</method>

 
For the writing of files you need just the three following functions, some of that are also act as a event handler.

1. The saveFile function invokes the saving action. Here we instantiate again a FileReference object, register the requiered eventlistener and open the browser window for selecting the destination for the file.

<!---	called when the user clicks the save file button -->
<method name="saveFile" args="fileContent ='', fileName ='test.txt'" returns="void">
<![CDATA[	
	
	// create the FileReference instance
	this.fr = new FileReference();

	// listen for the file has been saved
	this.fr.addEventListener(Event.COMPLETE, this.onFileSave);

	// listen for when then cancel out of the save dialog
	this.fr.addEventListener(Event.CANCEL, this.onCancel);

	// listen for any errors that occur while writing the file
	this.fr.addEventListener(IOErrorEvent.IO_ERROR, this.onSaveError);

	// open a native save file dialog, using the default file name
	this.fr.save(fileContent, fileName);
								
]]>
</method>

 
2. The onSaveError function will be called in case of an error while saving.

<!---	called if an error occurs while saving the file -->
<method name="onSaveError" args="e:IOErrorEvent">
<![CDATA[
	Debug.write(this, "->onSaveError(): ", e.text);
	this.fr = null;								
]]>
</method>				

 
3. The onFileSave function will be called when the file is successfully saved.

<!---	called once the file has been saved -->
<method name="onFileSave" args="e:Event">
<![CDATA[
	Debug.write(this, "->onFileSave()");
	this.fr = null;							
]]>
</method>

 
All these functions are capsuled in a class, that is extends the node object.

<class name="readAndWriteFileReference" extends="node">

	<passthrough>
		import flash.net.FileReference;
		import flash.net.FileFilter;
		import flash.events.IOErrorEvent;
		import flash.events.Event;
		import flash.utils.ByteArray;
	</passthrough>

	<!---	FileReference -->
	<attribute name="fr" type="expression" />

	...

Is this class implemented, you will only need to create an instance of that and bind an eventlistener with it. Now you are able to load and write file contents, just by calling the load and save function. A canvas could look like:

<canvas name="readAndWriteFileReference" width="800" height="550">
	
	<include href="./readAndWriteFileReference.lzx" />
		
	<attribute name="columnWidth" type="number" value="400"/>
	<attribute name="textHeight" type="number" value="${canvas.height-canvas.buttonBar.height}"/>
	
	<readAndWriteFileReference name="readAndWriteFile">
		<handler name="onfileContent">
		<![CDATA[				
			canvas.textView.textLoad.setAttribute("text", this.fileContent);
		]]>
		</handler>				
	</readAndWriteFileReference>		
		
	<simplelayout axis="y" spacing="0" />
	<view name="textView" width="$once{canvas.columnWidth*2}" height="$once{canvas.textHeight}">
		<simplelayout axis="x" spacing="0" />
		<edittext name="textSave" width="$once{canvas.columnWidth}" height="$once{canvas.textHeight}" multiline="true" />
		<edittext name="textLoad" width="$once{canvas.columnWidth}" height="$once{canvas.textHeight}" multiline="true" />
	</view>
				
	<view name="buttonBar" layout="axis: x; spacing:0" height="27">
		<button text="Save file" onclick="canvas.readAndWriteFile.saveFile(canvas.textView.textSave.text, 'test.txt');" width="$once{canvas.columnWidth}" />
		<button text="Load file" onclick="canvas.readAndWriteFile.loadFile();" width="$once{canvas.columnWidth}" />		
	</view>	
				
</canvas>

And now, happy loading and saving 😉

Click here for a quick demo 😉

Sourcecode: OpenLaszlo - ReadAndWriteFileReference.zip (1084)

If you found some bugs or have some Tips, please contact me.

How to track OpenLaszlo Websites with Google-Analytics

Some time ago, i had to integrate a google analytics tracking into a OpenLaszlo website, compiled to flash or DHTML/HTML5.

How to do this!?
At first, we need a google account and additional a google analytics tracking code, registrated for the site to track.
After a little bit of searching, i have a summary of collected script snippets that we need.

In the HTML file, that’s embed our OpenLaszlo Website, we have to integrate the google analytics tracking code with a little JavaScript snippet:

<script type="text/javascript">
	var _gaq = _gaq || [];
	_gaq.push(['_setAccount', 'UA-XXXXXXXX-1']);
	_gaq.push(['_setDomainName', 'none']);
	_gaq.push(['_setAllowLinker', true]);
	_gaq.push(['_trackPageview']);

	(function() {
		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
	})();
</script>

After that, it is necessary to call a google analytics javascript function at every site switch. A call could be look like:

<method name="switchSite" args="menu='startsite', site='startsite', siteType='site', content='undefined'">
<![CDATA[
	// Google-Analytics
	lz.Browser.callJS("_gaq.push(['_trackPageview', '/"+menu+"/"+site+"/"+siteType+"/"+content+".html'])");
	...

If now a visitor navigate through your site, the _gaq.push function sends a page call like ‚/menu/site/siteType/content.html‘ to google analytics. So you’re able to follow your visitors, see which pages they find interessting or where they exit your page… 😉

How to get PHP-Includes work under Typo3 4.5

By updating some Typo3 websites to the current version 4.5, i have the problem that the PHP-Includes no longer work. Now, at first i have a look about, how and from where the PHP-File is included. The PHP-File is currently located within the fileadmin directory, and included with a bit TypoScript.
After inspect the TypoScript Debugger, quickly turns out that the problem is the directory where the included files are located. The fileadmin directory is in the default configuration of Typo3 4.5 not allowed, as a PHP include path.

After a little research i found two ways for a solution. The first is, to relocate the PHP-File into a valid directory like the uploads directory. The second is, add the current PHP-File directory to the allowed paths.
I decide me for the second solution, because it is the faster way for the existing version.

How to add an allowed path?!

Open the /typo3conf/localconf.php and add the following row:

$TYPO3_CONF_VARS['FE']['addAllowedPaths'] = "folder1/,folder2/";

Tipp: When you set up a new Typo3-Site, don’t forget to place all your files in the uploads directory 😉

Add or edit Code snippets and templates in Aptana Studio 3

I’ve searched now for a while, to edit and create some code snippets and code templates within Aptana Studio 3. These code snippets should help to make my work more efficient and faster, when the content assistent propose them while i’m typing. In Aptana Studio 2 we were able to manage all code snippets within the preferences window, but in Aptana Studio 3 isn’t it so. In Aptana Studio 3 we must integrate our code snippets and templates within bundle.rb files.

At first, a few basic knowledge about the code snippets. The code snippets consists of three parts, named the trigger, expansion and sometimes the scope.
The trigger is the text that is needed to trigger the snippet. That means, when i’m during programming and type the first letters from the trigger, the code assistent propose me the code snippet. Further the expansion is the code snippet it self, that will replace the typed trigger text. The expansion can also contain several variables and tab stops. At least the scope defines in which file the trigger text should response.

Now, after all these informations i would start to create my own code snippets, but there’s direct the first problem:
Where in hell are these ‚bundle.rb‘ and what structure have them?!

‚bundle.rb‘ are, as the name is shown, Ruby files and can simplify edit with a text editor.
To find these bundle.rb files navigate into your Aptana Studio 3 installation directory, and search the files, as sample with:

find . -name bundle.rb

The result are some founded files within the ‚./configuration/org.eclipse.osgi/bundles/84/1/.cp/‘ directory, that are in detail
:

./framework/ruble/bundle.rb
./bundles/php.ruble/bundle.rb
./bundles/xml.ruble/bundle.rb
./bundles/haml.ruble/bundle.rb
./bundles/yaml.ruble/bundle.rb
./bundles/sass.ruble/bundle.rb
./bundles/heroku.ruble/bundle.rb
./bundles/shell-script.ruble/bundle.rb
./bundles/text.ruble/bundle.rb
./bundles/capistrano.ruble/bundle.rb
./bundles/source.ruble/bundle.rb
./bundles/json.ruble/bundle.rb
./bundles/cucumber.ruble/bundle.rb
./bundles/html.ruble/bundle.rb
./bundles/math.ruble/bundle.rb
./bundles/rspec.ruble/bundle.rb
./bundles/engineyard.ruble/bundle.rb
./bundles/bundle-development.ruble/bundle.rb
./bundles/js.ruble/bundle.rb
./bundles/ruby.ruble/bundle.rb
./bundles/rails.ruble/bundle.rb
./bundles/css.ruble/bundle.rb

Now, you can edit these files, while the respective directory name is containing the programming language name.
We want to do it now as a test for PHP, therefore we open the ‚./bundles/php.ruble/bundle.rb‘ in a text editor like gedit:

gedit ./configuration/org.eclipse.osgi/bundles/84/1/.cp/bundles/php.ruble/bundle.rb

In these file you can also manage all menuentries that are placed within the mainmenu under ‚Commands‘->’PHP‘->’…‘

The first sample is very easy. ‚First snippet‘ is the name from our first snippet. These name is in Aptana Studio 3 displayed when the trigger is matched. The trigger and the expansion are as described above.

snippet "First snippet" do |snip|
  snip.trigger = "first"
  snip.expansion = "[first snippet]"
end

After finish the changes within the bundle.rb, you need to restart you Aptana Studio, so now the code snippet is available for using.
Open a PHP file, type the first letters from your snippet ‘fir’ and press ‘strg+space’.

If only one snippet is available, that is matched with the trigger text, the expansion text is automatically included. Are there matched multiple trigger text, it appears a menu with the matched code snippets. Select the needed one and press enter.

When you now add all your code snippets, have attention by using a $ or ” symbol within your expansion. If you need the $ or ” symbol as sample for a PHP variable, you must escape it, like:

snippet "Second snippet" do |snip|
  snip.trigger = "second"
  snip.expansion = "\\$phpVar = \"the value\";"
end

The second sample insert a variable assignment, in detail:

$phpVar = "the value";

Further the code snippets can also have include tab stopps. These tab stopps consists of two parts. The first part is the number of order, in which they are processed. The second part, separated by a :, is the default value.

snippet "Thrid snippet" do |snip|
  snip.trigger = "third"
  snip.expansion = "\\$${1:var_name} = \"${2:var_value}\";"
end

Is now the trigger is matched with the typed text, and you include the snippet, the default text of the tab stopp will be included and automatically selected by the text selection. Now you can direct override these text, or assume with the default text and jump with a ‚tab‘-key press to the next code snippet tab stopp.

The next code snippet shows, that you are also able to create line breakes with in snippets.

snippet "Fourth snippet" do |snip|
  snip.trigger = "fourth"
  snip.expansion = "function ${1:method_name}(${2:attribute}) {\n}\n"
end

In the following snippet are using concatenation to create a multiline snippet for a todo comment, that is also execute a shell command to include the current date. To execute a shell command, you just need insert these command within back ticks.

snippet "Fifth snippet" do |snip|
  snip.trigger = "fifth"
  snip.expansion  = "/**\n"
  snip.expansion += " *\n"
  snip.expansion += " * @todo       ${1:do}\n"
  snip.expansion += " * @date       "+`date +%Y-%m-%d`
  snip.expansion += " *\n"
  snip.expansion += " */\n"
end

The last sample is shows the mirroring. Mirroring means, you include two same tab stopps that are synchron replaced:

snippet "Sixth snippet" do |snip|
  snip.trigger = "sixth"
  snip.expansion = "function ${1:method_name}(${2:attribute}) {\n"
  snip.expansion += "\t${2:attribute}\n"
  snip.expansion += "}\n"
end

Now you are able to edit many useful snippet that can help to save a lot of time.

Notice: If you have an error within your bundle.rb, the console view in Aptana will display them by starting up.

If you work within a group of developers, it’s useful to share all the collected snippet, so that every developer in the group can use it. For these you could mount the snippets folder from a cloud service like ubuntu one. When also every developer in the group must be able to change and add some snippets, you could include the snippet folder with a SVN repository. So every developer check out the snippet repository into the snippet folder, and is now able to make changes, or update the snippets.
How you can do this by using a SVN repsotiory, read it here soon… I will write an article about it!

These are all in all many useful things, but there are some questions available:

  • How can i change a snippet, without an Aptana Studio 3 restart? Without a restart the changed snippet isn’t direct available.
  • How can i use the scope on the best? It is possible to use a wildcard to select as sample all *class.php files?
  • How can i trigger the menu entries from the commands menu named ‚Declarations‘ and ‚Globals‘? The snippets from the ‚Return‘ menu works by me, why the other ones not?

So many questions and more..
If you have any experience with code snippets, answers of my question, and so on.. Contact me or post a comment to complete this article.

Thank you guys 😉

Install and configure Aptana Studio 3

Hi at all 😉
Here are the complete and unabridged posts to install and configure Aptana Studio 3, step by step:

Have fun with it.. 😉
Feed back and so on always welcome!

Install Flex SDK under Ubuntu Linux

Today i want to install the Flex SDK, because i need it for compiling OpenLaszlo sourcecode to an AIR application.

The first thing we need is the Flex SDK. Download it here:
http://www.adobe.com/products/flex/
and extract it within your home-folder.

cd ~/
unzip flex_sdk_4.zip -d tempflex

While the processing of this, you can begin the next step.

The Flex SDK requires Sun Java for compiling the SWF binaries, so if you haven’t already, install Java. If you aren’t sure if java is already installed, you can also try the following command that install java on your system:

sudo apt-get install java-package sun-java6-jdk

Wait a several minutes while the packages download and install, then agree the Sun’s license.

Now you must decide where do you want to place the installation of Flex SDK. Often optional software installations are placed within the ‚opt‘ directory at the root of your system. Because i’m the only user on my system, and also i’ve mount my home directory on a seperatly partition, i prefer to place my optional sotfware within my home directory. Also i create the needed directory within my software directory and move the flex files to the new directory:

mkdir ~/Software/flex -p
mv ~/tempflex/* ~/Software/flex/

Finally for making all the required commands available, from each path of your system, you must edit your ‘.bashrc’ in your home folder. It is also necessary, if you haven’t already done it, to add the LPS home directory and the LZX compiler path. Just type the following command to do this direct from the shell:

gedit ~/.bashrc

Now you must add these rows into the .bashrc:

# Make the FLEX compiler available
export PATH=/home/thomas/Software/flex_sdk_4.5/bin:$PATH

# Export the LPS home directory
export LPS_HOME=/home/thomas/Software/OpenLaszlo/lps-root

# Make the LZX compiler available
export PATH=/home/thomas/Software/OpenLaszlo/lps/bin:$PATH

Save the file and close the text editor. After that you must exit all open terminal windows, then opening a new one. Now should be all commands available that you need.. 😉

You can check if your Flex SDK installation was successful, by run the following command:

mxmlc -version

Is the result something like:

Version 4.5.0 build 20967

..you do all right! 😉

Install Adobe AIR under 64Bit Ubuntu

For trying to develop some Adobe AIR applications, i’ve need to install AIR. After a little research it turns out, that the current version is only available for 32 Bit Ubuntu, so i need a workaround.

First download the 32 Bit adobeair.deb from the Adobe website:

wget http://airdownload.adobe.com/air/lin/download/2.6/adobeair.deb

After that you must extract the deb-file and the control-files, change the architecture parameter from ‚i386‘ to ‚all‘ and repackage all into a new deb-file:

mkdir temp
dpkg-deb -x adobeair.deb temp
dpkg-deb --control adobeair.deb temp/DEBIAN
sed -i "s/i386/all/" temp/DEBIAN/control
dpkg -b temp adobeair_x64.deb

Finally you can install Adobe AIR on a 64-bit system with the following command:

sudo dpkg -i adobeair_x64.deb

Now you are able to install AIR applications and use that.

Update Aptana Studio from Version 3.0.0 to 3.0.2

Today i want to upgrade my Aptana Studio 3 to the current Version. Therefore i need to change the update settings.
I’m always want to try the newest versions of software, like Ubuntu, OpenLaszlo and all the others, also when there are possible bugs in there, i need to try out the new features or be glad about fixed issues. 😉
So at first we must select the update site for the nightly updates. Go to ‚Window‘->’Preferences‘ and select within the tree ‚Install/Update‘->’Available Software Sites‘. Now we must additional select the ‚Aptana Studio 3 Nightly Updates‘ entry.

After waiting for pending, select the Aptana Studio 3 Entry and accept the Terms of the license agreements. After the update progress a finally Aptana restart is required and that’s it.. Now you’re Aptana Studio 3 is up to date again 😉

Insert Google Analytics JavaScript direct within TypoScript

TIPP: Um Google-Analytics noch leichter in jeden TYPO3 Fluid-Template nutzen zu können empfehle ich die Verwendung des Fluid-Template-Manager (kurz FTM).

Um CSS oder JavaScript in TYPOScript zu integrieren, Zum Beispiel das JavaScript für einen Google Analytics Tracking-Code, kann man den folgenden Code verwenden:

page {
  headerData {
    1 = TEXT
    1.value (
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-Y']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
}) ();

</script>
    )
  }
}