Monday, 28 October 2013

How to run Inkscape in OS X 10.9 Mavericks

Problem:

After upgrading to OS X 10.9, Inkscape, as well as other X11 apps do not seem to work any longer. How can I run Inkscape?

Solution:

  • Install Inkscape (if haven't done so already) from http://inkscape.org/
  • Install XQuartz from http://xquartz.macosforge.org/landing/
  • Run Inkscape.app
  • When asked for "Where is X11?", click "browse ..." and select /Applications/Utilities/XQuartz.app (or just /Applications/Utilities/XQuartz)

Explanation:

As of OS X Mountain Lion, Apple no longer installs the X11.app by default, which was previously needed to run any X11 applications. XQuartz or another compatible X Server is now needed to run any X11 apps as a result. A full explanation can be found in the Apple knowledge base article here: http://support.apple.com/kb/HT5293

Additional comments:

This solution was tested to work with the default installation of OS X 10.9 and Inkscape 0.48.2.

Note that if XQuartz starts up when launching Inkscape, but Inkscape doesn't launch the first time along with XQuartz, (or the Inkscape window doesn't show up), you can try to quit both Inkscape and XQuartz, then launch Inkscape once more (which should also launch XQuartz). This bug occurred on the system that the above fix was tested on, and the workaround seems to have worked. Your mileage might vary.

Addendum:

(Added in 2014)

A useful post from commenter @Birtanish below seems to have helped a few people when the above instructions weren't sufficient, so it's reproduced below in case it helps. Best of luck!:

"Hi! I tried the above solution which in the end did not work at all unfortunately. Another solution is to launch Inkscape from within XQuartz, this is done by opening a terminal and type: open /Applications/Inkscape.app Additionally it is possible to create a shortcut for this in the XQuartz menu, by clicking on Applications -> Customize and the above command as the command and set name to Inkscape for instance. This worked for me, hope it can help somebody else as well. Good luck."

Saturday, 7 September 2013

VirtualBox OS X Host Ubuntu Guest - USB device captured but not mounting/showing - One workaround

Problem:

I am using VirtualBox 4.2.x on OS X 10.7.x running an Ubuntu Guest. When I try to plug in a USB device, such as a USB drive, USB MIDI keyboard such as the Keystation 88-es, etc., VirtualBox shows the device as captured (with a checkmark in the USB devices list), yet Ubuntu can't find it. I've already tried things such as installing VirtualBox Guest Additions, setting proper user permissions, etc.

One Workaround:

If you've managed to mount and capture the USB device but it's still not showing, you've probably already made it past most How-To's Googling will offer. One bug fix that seems harder to come across is this: Set the number of virtual CPUs to 1.

Apparently after VirtualBox version 3.2.0, a bug has caused USB devices to not show up in some Linux-based guests when the number of virtual CPUs is set to more than 1.

If this obscure bug fix doesn't help, check out the references below to lots of other potential solutions to the USB-won't-mount problem.

Good luck!

Notes:

I realize that this post isn't complete, however it was this one somewhat obscure bug that caused many hours of attempted debugging and Googling until it was found. So to save others the trouble of finding it buried in a page full of instructions and fixes, I opted to highlight only this one bug, and link to other pages full of good solutions.

Hopefully by the time you've reached this blog page Oracle, VirtualBox, Apple, or some others have managed to fix the problem!

This workaround is version specific so your mileage may vary depending on the version of OS X, VirtualBox, VirtualBox Guest Additions, Linux, etc., that you are running.

References:

Friday, 6 September 2013

Facebook Android SDK v3.5 tutorial workaround for error regarding android.support.v4.content.LocalBroadcastManager.getInstance

Problem:

In the very first Facebook SDK tutorial, when I finish the final steps to get a MainActivity.java that looks like the tutorial, instead of getting the message "Hello !" the app crashes and gives an error like "Could not find method android.support.v4.content.LocalBroadcastManager.getInstance, referenced from method com.facebook.Session.postActiveSessionAction", then followed by a bunch of exceptions, starting with "java.lang.NoClassDefFoundError: android.support.v4.content.LocalBroadcastManager".

My code looks exactly like the tutorial found at https://developers.facebook.com/docs/android/getting-started/facebook-sdk-for-android/. (For reference, the tutorial code as of September 6, 2013 is below, as it could be revised by now:)

package com.firstandroidapp;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.widget.TextView;
import com.facebook.*;
import com.facebook.model.*;

public class MainActivity extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // start Facebook Login
    Session.openActiveSession(this, true, new Session.StatusCallback() {

      // callback when session changes state
      @Override
      public void call(Session session, SessionState state, Exception exception) {
        if (session.isOpened()) {

          // make request to the /me API
          Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {

            // callback after Graph API response with user object
            @Override
            public void onCompleted(GraphUser user, Response response) {
              if (user != null) {
                TextView welcome = (TextView) findViewById(R.id.welcome);
                welcome.setText("Hello " + user.getName() + "!");
              }
            }
          });
        }
      }
    });
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
  }

}

Please Note First:

This problem and its workaround appears to be version specific. Your mileage may vary if the error isn't exactly the same as the one encountered. The versions of things used when this error was encountered were Android ADT v22, facebook-android-SDK-3.5, with a build target set to Android 4.2.2. All source code, tool, etc., were unmodified from the versions downloaded from Google and Facebook. This problem was worked around September 6, 2013, so hopefully someone from Facebook or Google's Android team has already made the appropriate fixes (making this post no longer needed =p).

Workaround:

This problem is caused by a missing method that the Facebook SDK is expecting to find in android.support.v4, but cannot find in the current version of the Android libraries. A hint to this is a strange error (which you may or may not have seen when importing the Facebook SDK demos into Eclipse) mentions that the versions of android.support.v4 do not match. The demos seem to run properly when compiled, however the very first Facebook SDK program you write yourself does not.

To work around this problem, the Facebook SDK version 3.5 includes a jar file you need to link to your project, located in "/path/to/facebook-android-sdk-3.5/libs/android-support-v4.jar".

One way to do this is as follows:

  • Go to your project's properties in Eclipse, then go to "Java Build Path"
  • Click on the "Libraries" tab
  • Click on either "Add JARs..." or "Add External JARs...", depending on which of the two you'd like to do
  • Add the android-support-v4.jar that comes with the Facebook Android SDK v3.5
  • Click on the "Order and Export" tab
  • Check the newly-imported android-support-v4.jar
  • Clean the project (Project->Clean...) (this step is important as attempting to re-run the project without cleaning it first or altering its code will simply run the existing binary again, which will give the error once more)

Additional Notes:

There's also another change in the tutorial which you may want to make. The function "Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {....});" is deprecated in the v3.5 SDK. You can get rid of the "deprecated method" warning in Eclipse by changing the above code to "Request.newMeRequest(session, new Request.GraphUserCallback() {...}).executeAsync();".

Hopefully this post helped someone out there. I realize it's a pretty basic problem to debug for experienced coders, but I decided to post this anyway in case it came in handy.

Wednesday, 21 August 2013

Inkscape 0.48.x OS X extensions problem workaround

Problem:

When using extensions with Inkscape 0.48.2 in OS X I get an error similar to: "the fantastic lxml wrapper for libxml2 is required ..." and extensions won't work.

Prerequisites:

This workaround worked on the system it was used on, however the solution is potentially version specific. The versions of stuff installed on this system were:

  • OS X 10.7.5 with the installation of Python that came with it
  • Python 2.7.5 (you can find your version in the terminal by typing "python --version")
  • Fresh install of Inkscape 0.48.2
  • XCode (required to compile the modules that we're going to install)

Notes:

The following steps are not necessarily a permanent fix for this problem, however they worked on the system that they was tested on. Your mileage may vary as the problem seems to be version-specific. Make sure you know what you're doing and follow the instructions at your own risk. If you're unsure, refer to the links in the references for a more complete explanation before starting. Good luck!

Workaround:

This problem is caused by the OS X version of Inkscape not being able to find the version-specific Python module for libxml2 that it was compiled/packaged to use. OS X comes with its own version of python which happens to be missing a few things usually installed in other operating systems. To install the required modules for Inkscape extensions to work, the following steps were taken (though not all may be required for this workaround to succeed.)

This workaround is a combination of two solutions found on internet forums. One of them modifies Inkscape to use version 2.6 of python if it's on the system. (If it is, that modification can be done without installing the libxml modules). The other installs the libxml2 module Inkscape is looking for in version 2.7 of python.

If you're not comfortable with using the terminal, there's an unofficial patch you can install instead of using the below workaround. It can be found at this forum thread: http://boardgamegeek.com/thread/769281/installing-on-osx-lion-the-fantastic-lxml-wrapper (just search for "EggBot2.2.2.r2.mpkg.zip")

Caution: do not proceed if you are not comfortable with the Terminal, command line, or code editing

  • Make sure your install of Inkscape is a fresh, unmodified copy
  • Make sure your python 2 version is at least 2.7.5 (as this workaround was only tested with that version) If it's older, you can get 2.7.5 here: http://www.python.org/download/
  • Open Terminal
  • The following steps may produce errors. If they do, look at the errors and try to fix them to complete the steps before moving on! (The usual: Google if unsure, or do not proceed further)
  • Type the command "sudo easy_install pip" to install the python package manager pip
  • Type the command "sudo pip install virtualenv" (probably not required, but useful)
  • Type the command "sudo pip install lxml"
  • If there are no errors in the above few steps, you're good so far. If there are any errors, try to get the steps to complete without errors (the usual: look at the errors, Google a solution, etc.)
  • In a text editor, open the file "/Applications/Inkscape.app/Contents/Resources/bin/inkscape"
  • Above the line 32 (which reads: "export VERSIONER_PYTHON_PREFER_32_BIT=yes"), add the following line without quotes and save the modified file: "export VERSIONER_PYTHON_VERSION=2.6"
  • (Note that the python version 2.6 specification in the inkscape file may not do anything if version 2.6 isn't on the system, and inkscape may just default to the system's version of python. The above steps to install lxml should make libxml work on the current version of python nonetheless.)
  • Restart Inkscape. The extensions menu should work now.

References:

Friday, 7 June 2013

Test if an app is running on an android emulator

Problem:

How do I test that my app is running on the Android emulator and not a real device?

Solution:

import android.os.Build;

...

if( "sdk".equals( Build.PRODUCT ) ){
 // do emulator specific stuff here,
 // like set configs that are missing
}

Notes:

Tested to work using ADT Build: v22.0.1-685705. Your mileage may vary with other versions.

Note that in some versions you might need to test that Build.PRODUCT is "google_sdk" or "sdk_x86" instead of "sdk". An easy way to find the string is to print the value of Build.PRODUCT to the log or console while running your app in the emulator, then use that string.

This test can be useful if one needs to set configurations that would normally work on a device by default (but be missing in the emulator, such as needing to call setEGLConfigChooser(...) prior to doing anything else with a GLSurfaceView, as of ADT Build: v22.0.1-685705).

Tuesday, 23 April 2013

Getting "Must be a StateFieldPathExpression" Symfony2/Doctrine exception

Problem:

I'm getting a weird error when making a DQL query in my Symfony2 project. The error contains the phrase "Must be a StateFieldPathExpression". This seems to happen with queries that try to select an identity field (or something with a foreign key.)

Solution:

This may be a bit of a work around, but you can try using the IDENTITY() function in the DQL query to get the id. For instance, imagine that you wanted to select an external ID (un-creatively named 'extern_id'), among other (more un-creatively named) fields:

$dql = "
SELECT IDENTITY(s.extern_id) AS eid, 
  s.some_col AS sc,
  s.another  AS ac
FROM something s WHERE 1";

$em->createQuery($dql);

// ... etc ...

Notes:

This was tested to work using up to Symfony 2.1.4-DEV.

This workaround seems to work for now. If there's anyone out there with more knowledge of Doctrine and DQL, here's a question for you: is using IDENTITY() the right way to go on a permanent basis?

Find the length of an array in Twig

Problem:

How do I find the length of an array using Twig?

Solution:

Use the length filter, for instance:

{% if my_array|length < 1 %}
  {# ... do default thing ... #}
{% else %}
  {# ... do something ... #}
{% endif %}

Or if you'd like to use a variable instead ...

{% set arr_size = my_array|length %}

Friday, 15 March 2013

Disable spelling autocorrect in Safari

Problem:

I'd like to disable spelling auto-correct in Safari!

Solution:

Using OS X 10.7 or higher, there are at least two ways to disable automatic spelling correction: globally, and on an individual app basis. Disabling autocorrect can be useful for those who often need to spell out things that would come up as incorrect in the dictionary, such as HTML CSS style editors who need to use "center" instead of the autocorrected "centre".

To disable automatic spelling correction globally (at least across apps that use OS X's dictionary):

  • click on the apple icon on the top-left of the screen
  • click on System Preferences ...
  • click on Language & Text
  • click on the Text tab
  • uncheck Correct spelling automatically

To disable automatic spelling correction in Safari:

  • first click on any text field where you can type (otherwise the relevant menu option will be greyed out)
  • in the menu on the top of the screen, click Edit -> Spelling and Grammar
  • if checked, uncheck Correct Spelling Automatically

Notes:

Both of these worked using Safari 6.0.2 under OS X 10.7 and 10.8. Your mileage may vary across other versions of OS X and Safari.

Tuesday, 5 February 2013

Selectively and recursively copy all files of a single file type in OS X and Linux

Problem:

In OS X or Linux, how do I selectively copy only one type of file to a folder? For instance, how can I recursively copy all .mp3 files from a folder with many sub-folders into a single folder?

Solution:

Note: this solution assumes you have basic knowledge of using the Terminal and know how to avoid destructive commands.

To recursively check the paths of all files for instance all .mp3 in a folder and all its sub-folders, type the following into the Terminal (replacing the path and file extension to fit your need):

find /path/to/files/to/search -iname '*.mp3'

If everything looks alright, to copy the files use the following command (replacing the paths and the extension to fit your need - also note that this is a single line/command, but it's long so it may wrap to more than one line in your browser):

find /path/to/files/to/search -iname '*.mp3' -exec cp {} /path/to/destination/ ./mp3 \;

Important: make sure that the / is at the end of the destination path! (It will all be copied as a single file otherwise as it'll think that your destination is a file name and not a folder.)

Sunday, 3 February 2013

Passing a named associative array via URL

Problem:

How do I manually pass an associative array via URL?

Solution:

Let's say we have an associative array named 'arr_args' with the key-value pairs 'key1'=>'value1', 'key2'=>'value2', i.e. arr_args = [key1=>value1, key2=>value2]. Let's also assume we have a sample script called 'sample.php' that will be receiving this associative array.

One way that you can pass this into a URL as the following:

sample.php?arr_args[key1]=value1&arr_args[key2]=value2