Background

Have you heard about Google’s latest service – Google Cloud Print?

It’s a cool service which allows you to print stuff from your home printer using any other computer in the world or even (and especially) mobile devices.

The service is still in beta, so right now you can only print through mobile devices with HTML5 compliant browsers which can access Google’s Gmail and Docs mobile version.
They claim that their next step is embedding this functionality in Chrome OS notebooks.

It kind of looks like they skipped over Google Chrome’s version.
That’s why I developed an extension for Google Chrome through which you may print using the Google Cloud Print service to any of your connected printers.

I encountered quite a few technical challenges while developing this extension. But I’ve overcome all of then and I’m proud to present the final outcome.
Everyone is welcome to download and study the extension’s source code.

Download

You may download the extension here: (A 5 star rating will be greatly appreciated :)
https://chrome.google.com/webstore/detail/ffaifmgpcdjedlffbhenaloimajbdkfg

What does the extension do?

The extension gives you the ability to print any doc/pdf/txt file, Gmail attachment, email or Google Docs document using Google Cloud Print™.

Screenshots

Here are some screenshots of the extension in action:

Some more screenshots people took I found on Flicker:
http://www.flickr.com/photos/nda/5411410871/
http://www.flickr.com/photos/nda/5411411069/
http://www.flickr.com/photos/nda/5411410263/
http://www.flickr.com/photos/nda/5411410395/
http://www.flickr.com/photos/nda/5411410871/
http://www.flickr.com/photos/nda/5412023376/

Instructions

Print a pdf/doc/txt/jpg/jpeg file

Navigate your way to the desired file and click the extension’s icon.

The icon will appear on the left side of the address bar only when the current tab’s URL ends with .pdf, .doc or .txt.

Print a Gmail attachment or email

Look for the “Print using Google Cloud Print” links (you can see where they are located in the screenshots).

Print a Google Docs document

Open a document and click File > Print using Google Cloud Print.

Demo Video

Here is a demo video of the extension in action (thanks to Digital Inspiration):

Changelog

Version 0.31 (5/3/1011)

Version 0.3 (15/2/1011)

Version 0.22 (10/2/1011)

Version 0.21 (9/2/1011)

Version 0.2 (7/2/1011)

Press

This extension has been broadly reviewed by bloggers and news sites:

Feedback

Please leave any feedback / suggestions you might have at the extension’s feedback forum (no registration needed):
http://printusinggooglecloudprint.uservoice.com

or in the comments section below, or by contacting me.

Learn more

About Google Cloud Print™:
http://www.google.com/support/cloudprint/
http://www.google.com/chrome/intl/en/p/cloudprint.html
http://code.google.com/apis/cloudprint/docs/overview.html

Search terms:

I was curious to see what’s inside a wireless keyboard that was laying around the house. So I cracked it open. And boy did I learn some interesting stuff.

Tip of the day – follow your curiosity and instincts. Only good can come out of it.
Or like National Geographic says: “Live Curious“.

Anyhow, I had some fun with what used to be a wireless keyboard and this is the end result:

The odd ball at the top acts as the mouse. It’s surprisingly comfortable and accurate.
The upper trigger acts as a left mouse button.
The lower trigger acts as a right mouse button.
The scroll wheel at the bottom acts as a… scroll wheel.

You can turn the remote sideways and control any TV using the mini universal remote control glued to the side (thanks eBay!).

It comes real handy when watching TV series while in bed (oh the laziness!).

box2d warningsWhen I started developing in flash using the Box2d physics engine, I had this problem which held me back for a couple of hair pulling hours. So I thought, why not spare other people from this misery?

The Problem’s Symptoms

If you encountered any of these error messages when compiling a Box2d flash project:
b2World.as, Line 871 - 1046: Type was not found or was not a compile-time constant: Vector. - public function RayCastAll(point1:b2Vec2, point2:b2Vec2):Vector.
b2World.as, Line 917 - Warning: 3590: void used where a Boolean value was expected. The expression will be type coerced to Boolean. - return (m_flags & e_locked) > 0;
Input.as, Line 155 - Warning: 3590: void used where a Boolean value was expected. The expression will be type coerced to Boolean. - mouseReleased = !e.buttonDown;
Input.as, Line 189 - Warning: 3590: void used where a Boolean value was expected. The expression will be type coerced to Boolean. - return (keyState[k] > 0);
Input.as, Line 199 - Warning: 3590: void used where a Boolean value was expected. The expression will be type coerced to Boolean. - return (keyState[k] == 1);
Input.as, Line 208 - Warning: 3590: void used where a Boolean value was expected. The expression will be type coerced to Boolean. - return (keyState[k] == -1);
Input.as, Line 217 - Warning: 3590: void used where a Boolean value was expected. The expression will be type coerced to Boolean. - return (keyBuffer[i][0] == k && keyBuffer[i][1] <= t);
1046: Type was not found or was not a compile-time constant: b2PolygonDef. - var the_box:b2PolygonDef;
1067: Implicit coercion of a value of type Box2D.Collision:b2AABB to an unrelated type Box2D.Common.Math:b2Vec2. - the_world=new b2World(environment,gravity,true);
1137: Incorrect number of arguments. Expected no more than 2. - the_world=new b2World(environment,gravity,true);
1178: Attempted access of inaccessible property m_sprite through a reference with static type Box2D.Dynamics:b2DebugDraw. - debug_draw.m_sprite=debug_sprite;
1178: Attempted access of inaccessible property m_drawScale through a reference with static type Box2D.Dynamics:b2DebugDraw. - debug_draw.m_drawScale=30;
1178: Attempted access of inaccessible property m_fillAlpha through a reference with static type Box2D.Dynamics:b2DebugDraw. - debug_draw.m_fillAlpha=0.5;
1178: Attempted access of inaccessible property m_lineThickness through a reference with static type Box2D.Dynamics:b2DebugDraw. - debug_draw.m_lineThickness=1;
1178: Attempted access of inaccessible property m_drawFlags through a reference with static type Box2D.Dynamics:b2DebugDraw. - debug_draw.m_drawFlags=b2DebugDraw.e_shapeBit;
1180: Call to a possibly undefined method b2PolygonDef. - the_box = new b2PolygonDef();
1061: Call to a possibly undefined method CreateShape through a reference with static type Box2D.Dynamics:b2Body. - final_body.CreateShape(the_box);
1061: Call to a possibly undefined method SetMassFromShapes through a reference with static type Box2D.Dynamics:b2Body. - final_body.SetMassFromShapes();
1046: Type was not found or was not a compile-time constant: b2PolygonDef. - var the_box:b2PolygonDef;
1180: Call to a possibly undefined method b2PolygonDef. - final_body.CreateShape(the_box);
1061: Call to a possibly undefined method SetMassFromShapes through a reference with static type Box2D.Dynamics:b2Body. - final_body.SetMassFromShapes();
1136: Incorrect number of arguments. Expected 3. - the_world.Step(1/30, 10);
Warning: 3590: Box2D.Common.Math:b2Vec2 used where a Boolean value was expected. The expression will be type coerced to Boolean. - the_world=new b2World(environment,gravity,true);
1046: Type was not found or was not a compile-time constant: b2World. - public var the_world:b2World;
1046: Type was not found or was not a compile-time constant: b2AABB. - var environment:b2AABB = new b2AABB();
1046: Type was not found or was not a compile-time constant: b2Vec2. - var gravity:b2Vec2=new b2Vec2(0.0,10.0);
1046: Type was not found or was not a compile-time constant: b2DebugDraw. - var debug_draw:b2DebugDraw = new b2DebugDraw();
1046: Type was not found or was not a compile-time constant: b2Body. - var final_body:b2Body;
1046: Type was not found or was not a compile-time constant: b2BodyDef. - var the_body:b2BodyDef;
1046: Type was not found or was not a compile-time constant: b2PolygonDef. - var the_box:b2PolygonDef;
1180: Call to a possibly undefined method b2AABB. - var environment:b2AABB = new b2AABB();
1180: Call to a possibly undefined method b2Vec2. - var gravity:b2Vec2=new b2Vec2(0.0,10.0);
1180: Call to a possibly undefined method b2World. - the_world=new b2World(environment,gravity,true);
1180: Call to a possibly undefined method b2DebugDraw. - var debug_draw:b2DebugDraw = new b2DebugDraw();
1120: Access of undefined property b2DebugDraw. - debug_draw.m_drawFlags=b2DebugDraw.e_shapeBit;
1180: Call to a possibly undefined method b2BodyDef. - the_body = new b2BodyDef();
1180: Call to a possibly undefined method b2PolygonDef. - the_box = new b2PolygonDef();
1046: Type was not found or was not a compile-time constant: b2Body. - var final_body:b2Body;
1046: Type was not found or was not a compile-time constant: b2BodyDef. - var the_body:b2BodyDef;
1046: Type was not found or was not a compile-time constant: b2PolygonDef. - var the_box:b2PolygonDef;
1180: Call to a possibly undefined method b2BodyDef. - the_body = new b2BodyDef();
1180: Call to a possibly undefined method b2PolygonDef. - the_box = new b2PolygonDef();
1172: Definition Box2D.Dynamics could not be found. - import Box2D.Dynamics.*;
1172: Definition Box2D.Collision could not be found. - import Box2D.Collision.*;
1172: Definition Box2D.Collision.Shapes could not be found. - import Box2D.Collision.Shapes.*;
1172: Definition Box2D.Common.Math could not be found. - import Box2D.Common.Math.*;

I have the solution.

Possible Causes

There are two main causes for these type of errors:

  1. The Box2d code you are compiling doesn't match the Box2d source files' version.
  2. Flash can not locate the Box2d engine source files.

Version Difference

Personally, I first encountered the first cause. As it seems, when the Box2d guys updated their SVN and downloads for the latest version (for the time writing this post: 2.1 alpha aka 2.1a), they forgot to also update their code samples. So if one downloads the latest version and tries to compile the example projects, it simply won't work. Instead, flash will throw some of the errors listed above.

In addition, all of the online resources and tutorials regarding Box2D don't work with the latest Box2D version. I have yet to find an article or a code sample that works flawlessly with the latest version. They really rewrote major parts of the engine thus making lots of code (if not all) incompatible.

Missing Box2D files

The second cause is also very common. When compiling any project which uses the Box2d physics engine, Abobe must be able to find the needed Box2d source files. Adobe Flash looks for the files in the projects directory (is our case, for a Box2D subdirectory), and at the locations which one can specify in the preferences menu.

The Solutions

These solutions have solved my problems. If these won't help you, or if you have a better solution that you'd like to suggest - comment below.

Version Difference

As I've mentioned before, the examples in the latest Box2D download don't match the correct version and almost any code sample you will find online won't work with the latest version of Box2D.

Visit their full download page which contains all previous versions and download version 2.0.2. All the examples work great in this package. And any other code should also work using this version.

Missing Box2D files

Many times, Adobe Flash (also Flash Develop and any other Flash IDE) won't find the correct Box2D directory to use. As a result it will throw those errors.

To fix this, you have two options:

  1. You can simply copy the correct Box2D source folder (a folder named Box2D) to the directory of your project. For instance, if your project lies under C:\projects\box2d-demo\demo.fla, you will need to copy the Box2D folder there. In the end the Box2D folder should lie at C:\projects\box2d-demo\Box2D.
  2. The second option is to inform your IDE about the location of your Box2D folder. I use this option and I store my Box2D directory at C:\Documents and Settings\Oren Yomtov\My Documents\FlashUtilities\Box2D.

    To inform your IDE, follow the following steps:

    In Adobe Flash:

    1. Open your project in Adobe Flash.
    2. Navigate to "Edit->Preferences...".
    3. Click the "ActionScript" tab/category.
    4. Click the "ActionScript 3.0 Settings..." button.
    5. Click the "Browser To Path" (folder/cross icon) button under "Source path:".
    6. Browse to the folder which contains the Box2D folder and click "OK".
    7. Click "OK" twice to save the changes.

    In Flash Develop (If you use it):

    1. Open Flash Develop
    2. Navigate to "Project->Settings..."
    3. Click the "Classpaths" tab.
    4. Click the "Add Classpath..." button.
    5. Browse to the folder which contains the Box2D folder and click "OK".
    6. Click "OK" to save the changes.

    NOTE: If you use both, you will need to configure both.
    Do not browse directly to the Box2D folder. Instead, browse to it's parent folder.

Now recompile your code and it should all work.

By the way, if you are looking for video tutorials on the Box2D engine - check out Todd's great videos. They are very detailed and fun. Good luck.

Search terms:

Google ReaderSurfing the web, you find many interesting websites or blogs which you want to subscribe to. But the never-ending search for the RSS link is a burden we all share. If you are using Google Reader, I may have the perfect solution for you.

Bookmark or favorite the following URL:javascript:var%20b=document.body;var%20GR________bookmarklet_domain='http://www.google.com';if(b&&!document.xmlVersion){void(z=document.createElement('script'));void(z.src='http://www.google.com/reader/ui/subscribe-bookmarklet.js');void(b.appendChild(z));}else{location='http://www.google.com/reader/view/feed/'+encodeURIComponent(location.href)}Using Google Chrome or Firefox, you can drag this link to your bookmarks bar – Subscribe.

Now, you may skip the RSS link seeking and simply click the link you have just bookmarked.

In my browser, Google Chrome, it looks like this:
Subscribe Bookmark

If you want to check it out, feel free to give it a shot and subscribe to my blog.

Search terms:

dot comHave a look at your browser’s address bar – your sight is just fine. You actually are on orenyomtov.com as opposed to this morning, when this website lived under the .info TLD.

It has been quite a long time since I made the decision to move to the new domain. But there were two drawbacks which delayed the domain transfer. The first one is lack of time, and the second one is… Well, my laziness.

Anyways, I thought I would share some of the steps I took in order to move the website to the new domain. I was lucky enough that I didn’t have to change hosts. Doing that may have required some additional steps.

  1. I bought the new domain and linked it to my hosting.
  2. I downloaded the latest WordPress installation and uploaded it into the new domain by FTP (Looking for an FTP client?).
  3. I copied the wp-content folder. And in my case, the “downloads” folder which is the folder I chose to store the uploads in (Default is wp-content/uploads).
  4. I also copied the wp-config.php file and the .htaccess file.
  5. I used the Search and Replace WordPress plugin to replace “orenyomtov.info” with “orenyomtov.com” in the database.
  6. I notified Google of the domain change in Google Webmaster Tools.
  7. I exported a new sitemap using the Google XML Sitemap Generator plugin and submitted it to Google Webmaster Tools.
  8. I opened a new Google Analytics account and deployed the new tracking code in the theme I copied in step 3.
  9. I edited the old .htaccess file to contain only:
    RewriteEngine on
    RewriteRule (.*) http://orenyomtov.com/$1 [R=301,L]
  10. I updated my FeedBurner account and all other similar services.
  11. I updated my website to the new URL in all of my favorite social platforms (@orenyomtov) and forums.
  12. Twit twit.
  13. And then I began writing this post.

The move didn’t take as long as I expected it to take. Even though it does seem a little complicated after writing it all down.

I hope that your move will be as smooth as mine. Good luck, Oren.

Search terms:

Last month I participated in two amazing events. The first one is The Big Geek and is considerably similar to the second event called Startup Weekend. They both took place in Israel.

The Big Geek II

BigGeek 2 Logo

Startupseeds

StartupSeeds
This event was organized by StartupSeeds, a non-profit organisation encouraging teen Israeli entrepreneurs to make their first steps in the entrepreneurship world. Whether it’s by giving them a place to talk about technology, or by conducting monthly meetings with the most interesting lectures (for free!). StartupSeeds even assists young innovative kids with starting their own startups by providing them financial help and the best mentors available. The online forum and meetings created a large and friendly community for the Israeli teenager who breaths technology and internet.

What’s the event about?

Sixteen kids (Ages 14-18), divided into four “teams”, worked 24 hours non-stop on their unique idea for a startup. Each team raised a fully working service within those 24 hours (!). While the projects are not breath-taking nor unbelievable, they are still awesome considering the time spent working on them. Actually, they’re awesome not matter what.

FixedInch
The project that my team and I developed is FixedInch. It’s a free online service for displaying objects in their real size over any screen in the world. We have discussed the possibility to continue working on it, and we most likely will, in the near future.

What else can I say? It was an awesome experience that I will never forget. It was 24 hours of fun and jokes, some of could not be told anywhere else like (via @TalDromi):

“Let’s use JSON for this”
“Who’s this Jason you are talking about?”
“XML’s brother!”

View photos from the event

Startup Weekend Israel 2009

Startup Weekend Israel

This is a world-wide known event, which started in 2007. Since then it took place in over 50 cities and growing (!). This is kind of a grown-up version of the Big Geek.

During the first day, 140 Israeli entrepreneurs pitched 50 unique ideas which turned into thirteen motivated teams. Each team consisted of about 4-8 people who designed and developed their idea for three days. The second day was all about work and food (lots of it!). On the third day of the event, the teams finished their work and presented their project.

Frayer Meter
My team and I worked on Frayer Meter – an online free service that suggests the most economical cellular plan according to one’s needs. While it’s not fully functional, we plan to continue working on it as we believe in it’s potential.

NOTE: If you don’t know Hebrew, feel free to use Google Translate when visiting links from this post.

Search terms:

I used to having FlashFXP as my default FTP client. It’s fast (so I thought), easy to use and I feel comfortable using it because I know some keyboard shourtcuts.
Even in my workplace where FileZilla was the default FTP client that everyone used, I insisted on bringing my disk-on-key with a portable version of FlashFXP.

When you start using a particular FTP client it’s very hard to say goodbye. You already have all the usernames,passwords and hosts laying there ordered just as you like it. You don’t even think about moving the whole list to another client one by one. Another thing that keeps you from changing your FTP client is that FTP access is very sensitive and you don’t want to transfer/rename/delete files by accident. Deleting or overwriting a certain file that has no backup can cost you a lot of valuable time.

So why did I change my client software? There were two major differences between FileZilla and FlashFXP that convinced me to switch.

  1. The speed, oh the speed. With FlashFXP you can’t transfer two files at the same time while using FileZilla you can transfer up to 10(!) files simultaneously. This improves the transfer time of say… a WordPress install in hundreds of percents.
  2. Simultaneous file editing.When using FlashFXP to edit files you can only edit one file at a certain time. While editing that file you can do nothing until you commit the file and after committing the file, if you wish to continue editing it you need to close your text editor and reopen the file. Luckily FileZilla improves the file editing experience and brings it into a new level. In FileZilla you can edit as many files as you want at the same time, you can do whatever you want while editing (Such as browsing folders, refreshing the file list,committing other files and so on…) and you don’t have to close and reopen the file each time you make a change.

This was my experience using FTP clients, as for the FTP accounts list, I just add them one by one each time I need to log in to a certain website.

Search terms:

1000 Downloads on the WordPress Plugin Directory
As you can see in the plugin‘s stats page, It currently has 1050 downloads!

Although the number may be not as big as other plugins (All in On SEO got over 2.5 million downloads), it means a lot to me. Every time you see numbers on the internet you don’t really think about them as you would outside the monitor. When viewing YouTube videos, if I see a video that has less then 5k views most of the times I won’t enter it and try to find another one with millions of views.

But when you think about the actual numbers it’s a huge amount of people sitting on their chair at home or at work, entering YouTube and watching the video. The same goes to plugin downloads, It’s really cool to know that my plugin helped over 300 (?) other people around the world that have their own website.

Update: It how has over 3000 downloads!

Search terms:

I just wanted to let you all know that Gmail is no longer in beta mode.
You can see for yourself when you enter Gmail and get the following logo:
Gmail logo not beta

It took Google five (!) years to go from Gmail beta to an official release. I don’t think that any major updates have been added to Gmail’s interface recently except for the drag n’ drop interface.

Anyways, I think Gmail is awesome and if you don’t use it then you have no idea what I’m talking about.