<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8709754195953818893</id><updated>2012-02-22T19:20:15.989+01:00</updated><category term='mobile'/><category term='flash'/><category term='mail'/><category term='proxy'/><category term='urlshortener'/><category term='javascript'/><category term='sms'/><category term='memoization'/><category term='command prompt'/><category term='videolan'/><category term='dynamic programming'/><category term='word'/><category term='api'/><category term='lua'/><category term='windows 7'/><category term='css'/><category term='license'/><category term='windows'/><category term='iptv'/><category term='freebsd'/><category term='actionscript'/><category term='linux'/><category term='facebook'/><category term='xml'/><category term='sharing'/><category term='math'/><category term='extensions'/><category term='office'/><category term='java'/><category term='google maps'/><category term='mysql'/><category term='php'/><category term='netbios'/><category term='sockets'/><category term='security'/><category term='programming'/><category term='bsd'/><category term='mysql replication'/><category term='goo.gl'/><category term='networking'/><category term='vlc'/><category term='novice'/><category term='jquery'/><category term='android'/><category term='wireless'/><category term='software'/><category term='unix'/><category term='arcgis'/><category term='samba'/><category term='statistics'/><category term='ubuntu'/><category term='subtitles'/><category term='esri'/><category term='ftp'/><category term='vista'/><category term='google'/><category term='recursion'/><title type='text'>dev.kafol.net</title><subtitle type='html'>For troubleshooting I use Colt Python .357</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dev.kafol.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default?start-index=26&amp;max-results=25'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>64</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-3754705828460151123</id><published>2012-02-22T19:19:00.001+01:00</published><updated>2012-02-22T19:20:15.997+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbios'/><category scheme='http://www.blogger.com/atom/ns#' term='sharing'/><category scheme='http://www.blogger.com/atom/ns#' term='samba'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>NETBIOS / Samba share does not accept username and password</title><content type='html'>If your username and password gets rejected when logging in MS file share, try using the INT domain for login.&lt;br /&gt;
&lt;br /&gt;
example:&lt;br /&gt;
&lt;br /&gt;
username: INT\your_username&lt;br /&gt;
password: your_password&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-3754705828460151123?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/3754705828460151123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=3754705828460151123&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3754705828460151123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3754705828460151123'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2012/02/netbios-samba-share-does-not-accept.html' title='NETBIOS / Samba share does not accept username and password'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-2778747956821358299</id><published>2012-02-21T18:04:00.001+01:00</published><updated>2012-02-21T18:05:10.191+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ftp'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Linux/Ubuntu :: pure-ftpd does not allow login to user with /usr/sbin/nologin shell</title><content type='html'>&lt;b&gt;Expectations:&lt;/b&gt;&lt;br /&gt;
You have created a user with&amp;nbsp;/usr/sbin/nologin shell (ftp-only user) in Linux/Ubuntu.&lt;br /&gt;
If you SSH to the box with this username and password it should not work.&lt;br /&gt;
If you FTP to the box with this username and password it should.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Symptoms:&lt;/b&gt;&lt;br /&gt;
Pure-ftpd does not permit login if the shell is set to /bin/false or&amp;nbsp;/usr/sbin/nologin.&lt;br /&gt;
If you change the shell to /bin/bash it works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Connected to localhost.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;220-You are user number 2 of 50 allowed.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;220-Local time is now 17:53. Server port: 21.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;220-This is a private system - No anonymous login&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;220-IPv6 connections are also welcome on this server.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;220 You will be disconnected after 15 minutes of inactivity.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Name (localhost:root): ftponly&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;331 User ftponly OK. Password required&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Password:&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;530 Login authentication failed&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Login failed.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Remote system type is UNIX.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Using binary mode to transfer files.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Solution:&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
You need to add the nologin or false shell to the file&amp;nbsp;/etc/shells.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;root@box:/# cat /etc/shells&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;# /etc/shells: valid login shells&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/csh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/sh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/bin/es&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/bin/ksh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/ksh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/bin/rc&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/bin/tcsh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/tcsh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/bin/esh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/dash&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/bash&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/rbash&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/bin/screen&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/false&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/sbin/nologin&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-2778747956821358299?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/2778747956821358299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=2778747956821358299&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/2778747956821358299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/2778747956821358299'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2012/02/linuxubuntu-pure-ftpd-does-not-allow.html' title='Linux/Ubuntu :: pure-ftpd does not allow login to user with /usr/sbin/nologin shell'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-2987518278100101476</id><published>2012-02-18T23:46:00.001+01:00</published><updated>2012-02-18T23:52:07.300+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='sms'/><title type='text'>PHP :: sending SMS via najdi.si FREE SMS</title><content type='html'>You need to make an account on https://id.najdi.si before you can use the code.
&lt;br/&gt;&lt;br/&gt;
All info and description is in the code comments.&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
Example usage:
&lt;pre&gt;
$sms = new sms();
$sms-&amp;gt;send('090666666','one does not simply send an SMS');
&lt;/pre&gt;
&lt;br/&gt;
Enjoy!&lt;br/&gt;
&lt;pre name="code" class="php"&gt;
&amp;lt;?php
/**
* Purpose: 
* Sending SMS via Najdi.si Free SMS
*
* Description: 
* Script logs in using your username and password for https://id.najdi.si and then it sends an SMS to a mobile phone number. 
* There is a 160 character limit per message and daily limit of 40 sent messages.
* The script tries to limit the number of requests to a page and tries to hold on to the session as long as possible. 
* The session cookie is stored in a /tmp/folder for later use, if the script restarts. 
* Once instantiated, object can be reused for sending a number of SMS messages. 
* If a new object is instantiated, it will prefer to use a stored session.
*
* @version Date: 1. february 2012
* @author Žan Kafol
* @access public
*/

class sms {
 
 public $username = 'your_username';
 public $pass = '...';
 
 public $cookie_jar = '/tmp/cookie.najdi.si';
 
 private $error = '';
 
 /*
 * Construct function
 * @param string $username
 * @param string $password
 */
 function __construct($u = null, $p = null) {
  if(!is_null($u)) {
   $this-&amp;gt;username = $u;
  }
  
  if(!is_null($p)) {
   $this-&amp;gt;pass = $p;
  }
 }
 
 /*
 * Sends SMS
 * @param string $number
 * @param string $message
 */
 public function send($number,$message) {
  $message = urlencode(substr(iconv('UTF-8', 'ASCII//TRANSLIT', $message), 0, 160));
  $number = ltrim(preg_replace('/[^\d]/','',$number),'0');
  
  @list($area,$num1,$num2) = explode(' ',preg_replace('/(\d{2})(\d{3})(\d{3})/','\1 \2 \3',$number));
  
  $url = &amp;quot;http://www.najdi.si/sms/smsController.jsp?sms_action=4&amp;amp;sms_so_ac_={$area}&amp;amp;sms_so_l_={$num1}%20{$num2}&amp;amp;myContacts=&amp;amp;sms_message_=$message&amp;quot;;
  
  $response = $this-&amp;gt;response($this-&amp;gt;req($url));
  
  if($response === false) {
   $this-&amp;gt;login();
   $response = $this-&amp;gt;response($this-&amp;gt;req($url));
  }
  
  return $response;
 }
 
 /*
 * Returns last error as stdclass
 */
 public function get_error() {
  return $this-&amp;gt;error;
 }
 
 private function login() {
  $this-&amp;gt;req('http://www.najdi.si/auth/login.jsp?lg=0&amp;amp;target_url=http%3A%2F%2Fwww.najdi.si%2Findex.jsp');
  
  return $this-&amp;gt;req(&amp;quot;https://id.najdi.si/j_spring_security_check&amp;quot;, array(
   'j_username'     =&amp;gt; $this-&amp;gt;username,
   'j_password'     =&amp;gt; $this-&amp;gt;pass,
   '_spring_security_remember_me' =&amp;gt; 'on'
  ));
 }
 
 private function response($r) {
  $r = json_decode($r);
  
  if($r-&amp;gt;dialog == 3) {
   $this-&amp;gt;error = false;
   return $r;
  }
  
  $this-&amp;gt;error = $r;
  return false;
 }
 
 private function req($url, $post = false) {
  $ack = curl_init();
  
  curl_setopt($ack, CURLOPT_USERAGENT, &amp;quot;Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1&amp;quot; );
  curl_setopt($ack, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ack, CURLOPT_FOLLOWLOCATION, true);
  curl_setopt($ack, CURLOPT_URL, $url);
  curl_setopt($ack, CURLOPT_COOKIEFILE, $this-&amp;gt;cookie_jar); 
  curl_setopt($ack, CURLOPT_COOKIEJAR, $this-&amp;gt;cookie_jar); 
  
  if($post) {
   curl_setopt($ack, CURLOPT_POST, true);
   curl_setopt($ack, CURLOPT_POSTFIELDS, http_build_query($post));
  }
  
  $dat = curl_exec($ack);
  curl_close($ack);
  
  return $dat;
 }
}
?&amp;gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-2987518278100101476?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/2987518278100101476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=2987518278100101476&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/2987518278100101476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/2987518278100101476'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2012/02/php-sending-sms-via-najdisi-free-sms.html' title='PHP :: sending SMS via najdi.si FREE SMS'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-5049910438671339755</id><published>2011-11-19T21:29:00.001+01:00</published><updated>2011-11-19T21:30:16.389+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android :: wrong image / data in ListView rows</title><content type='html'>&lt;blockquote&gt;
Android's ListView reuses list items when they aren't need anymore. 
For this reason, you need to make sure all views that should change, will actually get changed.
Your problem is that if you don't find a drawable for the current list item, you don't empty nor hide the ImageView. 
You should do thumb.setImageDrawable(null) in that case, or thumb.setVisibility(View.GONE).&lt;/blockquote&gt;
- From &lt;a href="http://stackoverflow.com/questions/3889549/wrong-image-show-up-in-my-listview-rows"&gt;stackoverflow&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Example code:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;
 @Override
     public View getView(int pos, View v, ViewGroup parent) {
      TimetableViewHolder timetableHolder;
         if (v == null) {
             LayoutInflater vi = ((Activity)context).getLayoutInflater();
             v = vi.inflate(R.layout.timetable_item, parent, false);
             timetableHolder = new TimetableViewHolder();
             timetableHolder.rel = (TextView) v.findViewById(R.id.rel);
             timetableHolder.time = (TextView) v.findViewById(R.id.time);
             timetableHolder.icon = (ImageView) v.findViewById(R.id.icon);
             v.setTag(timetableHolder);
         } else {
          timetableHolder = (TimetableViewHolder) v.getTag(); 
         }

         TimetableItem item = items.get(pos);

         if(item != null) {
          timetableHolder.rel.setText(item.rel);
          timetableHolder.time.setText(item.time);
          if(item.url.equals("ERROR")) {
           timetableHolder.icon.setImageResource(android.R.drawable.ic_menu_close_clear_cancel);
          } else if(item.url.equals("PRESTOP")) {
           timetableHolder.icon.setImageResource(android.R.drawable.ic_menu_directions);
          } else { // THIS IS IMPORTANT
           timetableHolder.icon.setImageResource(android.R.drawable.ic_dialog_info);
          }
         }

         return v;
     }
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-5049910438671339755?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/5049910438671339755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=5049910438671339755&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/5049910438671339755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/5049910438671339755'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/11/android-wrong-image-data-in-listview.html' title='Android :: wrong image / data in ListView rows'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-1838399559488340392</id><published>2011-11-19T15:15:00.001+01:00</published><updated>2011-11-19T15:30:49.638+01:00</updated><title type='text'>Android search dialog doesn't appear</title><content type='html'>Have a problem?&lt;br /&gt;
The search dialog doesn't show up?&lt;br /&gt;
&lt;br /&gt;
I just thought you should know, I found this interesting comment on &lt;a href="http://stackoverflow.com/questions/5926895/android-search-dialog-doesnt-appear"&gt;stackoverflow&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
oh my god. this is f*ing stupid. i had to use android:label="@string/xyz" instead of android:label="lol" and no single word about this in the documentation. unbelievable&lt;/blockquote&gt;&lt;br /&gt;
&amp;nbsp;This is my manifest:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;
&amp;lt;activity android:name=".SearchableActivity" &amp;gt;
 &amp;lt;intent-filter &amp;gt;
  &amp;lt;action android:name="android.intent.action.SEARCH" /&amp;gt;
 &amp;lt;/intent-filter&amp;gt;

 &amp;lt;meta-data
  android:name="android.app.searchable"
  android:resource="@xml/searchable" /&amp;gt;
&amp;lt;/activity&amp;gt;
&amp;lt;activity
 android:label="Preferred stations"
 android:name="PreferredStation"
 android:theme="@android:style/Theme.NoTitleBar" &amp;gt;
 &amp;lt;meta-data
  android:name="android.app.default_searchable"
  android:value=".SearchableActivity" /&amp;gt;
&amp;lt;/activity&amp;gt;
&lt;/pre&gt;

And searchable

&lt;pre name="code" class="xml"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_label"
    android:hint="@string/search_hint" &amp;gt;
&amp;lt;/searchable&amp;gt;
&lt;/pre&gt;

&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-1838399559488340392?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/1838399559488340392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=1838399559488340392&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1838399559488340392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1838399559488340392'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/11/android-search-dialog-doesnt-appear.html' title='Android search dialog doesn&apos;t appear'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-4798673095544980058</id><published>2011-11-19T03:02:00.001+01:00</published><updated>2011-11-19T04:30:43.740+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='google maps'/><title type='text'>Android :: google maps (MapView) hacks, tricks, workarounds</title><content type='html'>MapView isn't very developer friendly now is it?&lt;br /&gt;
&lt;br /&gt;
Here are some hacks I've had to work with:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;1) When tapping on the overlay, the app crashes if you're trying to display the dialog.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Unable to add window -- token null is not for an application&lt;/b&gt;&lt;br /&gt;
Yes, this is due to context. Especially if you're trying to do this in a seperate thread or AsyncTask.&lt;br /&gt;
Turns out the context you need to pass to your dialog is mapView.getContext();&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;AlertDialog.Builder dialog = new AlertDialog.Builder(mapView.getContext());&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;2) Displaying only the overlays which are within map bounds&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Oh yeah, several problems here. You've probably come across at least one of these:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Wrong map bounds in onCreate (0, 360000000),&lt;/b&gt;&lt;br /&gt;Yeah, in onCreate those haven't been calculated yet. onStart doesn't help either. Try this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Runnable waitForMapTimeTask = new Runnable() {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; public void run() {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; if(mapView.getLatitudeSpan()==0||mapView.getLongitudeSpan()== 360000000) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;mapView.postDelayed(this, 100);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; } else {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; redrawMarkers(); // draw here&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;};&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;mapView.postDelayed(waitForMapTimeTask, 100);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You create a new thread and wait until you get the right bounds. Recursively call it again.&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Map bounds ???&lt;/b&gt;&lt;br /&gt;Don't worry, it's simple.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public Rect getMapBounds() {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return new Rect(&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;mapView.getMapCenter().getLongitudeE6() - mapView.getLongitudeSpan()/2,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;mapView.getMapCenter().getLatitudeE6() - mapView.getLatitudeSpan()/2,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;mapView.getMapCenter().getLongitudeE6() + mapView.getLongitudeSpan()/2,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;mapView.getMapCenter().getLatitudeE6() + mapView.getLatitudeSpan()/2&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;...&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;if(!s.drawn &amp;amp;&amp;amp; rect.contains(point.getLongitudeE6(), point.getLatitudeE6())) {&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Yeah, okay, but what about panning / zooming?&lt;/b&gt;&lt;br /&gt;Well, there are no methods, like onPan or onZoom, but some people found their way around this problem. There is no perfect solution, you'll see.&lt;br /&gt;Check these links out:&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/2328650/how-can-i-detect-if-an-android-mapview-has-been-panned-or-zoomed"&gt;http://stackoverflow.com/questions/2328650/how-can-i-detect-if-an-android-mapview-has-been-panned-or-zoomed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/2328650/how-can-i-detect-if-an-android-mapview-has-been-panned-or-zoomed"&gt;http://bricolsoftconsulting.com/2011/10/31/extending-mapview-to-add-a-change-event/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/3567420/how-to-catch-that-map-panning-and-zoom-are-really-finished"&gt;http://stackoverflow.com/questions/3567420/how-to-catch-that-map-panning-and-zoom-are-really-finished&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Zoom in on double tap?&lt;/b&gt;&lt;br /&gt;Click here:&amp;nbsp;&lt;a href="http://dev.kafol.net/2011/11/how-hard-is-it-to-make-simple-zoom-in.html"&gt;http://dev.kafol.net/2011/11/how-hard-is-it-to-make-simple-zoom-in.html&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Overlays don't get drawn immediately!&lt;/b&gt;&lt;br /&gt;Try this:&lt;br /&gt;mapView.postInvalidate();&lt;br /&gt;or this:&lt;br /&gt;mapView.invalidate();&lt;br /&gt;&lt;br /&gt;But keep in mind, that&lt;b&gt; invalidate() needs to be called from an UI!&lt;/b&gt; If you're trying to get it working &lt;b&gt;from a thread, use postInvalidate()!&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b style="text-decoration: line-through;"&gt;MapView java.util.ConcurrentModificationException when adding new overlays&lt;/b&gt;&lt;br /&gt;&lt;strike&gt;Not sure if I solved this one, but it seems to work now. I read somewhere that this could happen if you add overlays in a non UI thread. I moved the&amp;nbsp;&lt;/strike&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Nope, sorry, this one was my bad. I was doing some crazy async sorting and all hell broke loose.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;itemizedOverlay.populateNow();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mapOverlays.add(itemizedOverlay);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mapView.postInvalidate();&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
From&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;doInBackground &lt;/span&gt;to &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;onPostExecute &lt;/span&gt;in &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;AsyncTask&lt;/span&gt;.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
You could also run something in a UI thread like this:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;runOnUiThread(new Runnable() {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; @Override&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public void run() {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//do stuff here&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;});&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-4798673095544980058?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/4798673095544980058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=4798673095544980058&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4798673095544980058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4798673095544980058'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/11/android-google-maps-mapview-hacks.html' title='Android :: google maps (MapView) hacks, tricks, workarounds'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-3190910414974973796</id><published>2011-11-18T03:44:00.001+01:00</published><updated>2011-11-19T21:08:53.653+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='google maps'/><title type='text'>Android :: google maps on double tap zoom in</title><content type='html'>How hard is it to make a simple zoom in call on double tap in MapView in Android?&lt;br /&gt;
&lt;br /&gt;
Not very.&lt;br /&gt;
&lt;br /&gt;
How hard is it to get the information on how to do it?&lt;br /&gt;
&lt;br /&gt;
Very.&lt;br /&gt;
&lt;br /&gt;
Here's what you probably didn't know:&lt;br /&gt;
You need to extend the MapView and use this extended class in the Android XML layout file.&lt;br /&gt;
In the extended class you instantiate the gesture detector and set on double tap listener.&lt;br /&gt;
In the Map Activity you implement&amp;nbsp;OnGestureListener and OnDoubleTapListener.&lt;br /&gt;
&lt;br /&gt;
Example:

&lt;pre name="code" class="xml"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal" &amp;gt;
    
 &amp;lt;net.kafol.vlaki.ExtMapView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/mapview"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:clickable="true"
     android:enabled="true"
     android:apiKey=""
 /&amp;gt;

&amp;lt;/RelativeLayout&amp;gt;
&lt;/pre&gt;


&lt;pre name="code" class="java"&gt;
package net.kafol.vlaki;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.MotionEvent;
import android.view.GestureDetector.OnGestureListener;
import com.google.android.maps.MapView;

public class ExtMapView extends MapView {
 private Context context;
 private GestureDetector gestureDetector;

 public ExtMapView(Context c, AttributeSet attrs) {
  super(c, attrs);
  context = c;

  gestureDetector = new GestureDetector((OnGestureListener) context);
  gestureDetector.setOnDoubleTapListener((OnDoubleTapListener) context);
 }

 public boolean onTouchEvent(MotionEvent ev) {
  if (this.gestureDetector.onTouchEvent(ev))
   return true;
  else
   return super.onTouchEvent(ev);
 }
}
&lt;/pre&gt;

&lt;pre name="code" class="java"&gt;
public class Map extends MapActivity implements OnGestureListener, OnDoubleTapListener {
...
 @Override
 public boolean onDoubleTap(MotionEvent e) {
     int x = (int)e.getX(), y = (int)e.getY();;
     Projection p = mapView.getProjection();
     mapView.getController().animateTo(p.fromPixels(x, y)); // zoom in to a point you tapped 
     mapView.getController().zoomIn();
  return true;
 }
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-3190910414974973796?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/3190910414974973796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=3190910414974973796&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3190910414974973796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3190910414974973796'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/11/how-hard-is-it-to-make-simple-zoom-in.html' title='Android :: google maps on double tap zoom in'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-6110542522611690973</id><published>2011-11-18T02:29:00.001+01:00</published><updated>2011-11-18T02:41:09.798+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android : Checkbox ListView - (un) check all</title><content type='html'>This recycling of views in android is preety insane. Pain to work with.&lt;br /&gt;
&lt;br /&gt;
So the problem is how to check all check boxes in a list view, if a list view only contains the visible items.&lt;br /&gt;
&lt;br /&gt;
Iterating through the adapter or array of holders was pretty unreliable, some checkboxes weren't affected.&lt;br /&gt;
&lt;br /&gt;
What I did was actually add an attribute to the data object and iterate through this object array (the same way it get's added in the adapter)-&lt;br /&gt;
&lt;br /&gt;
Here are some functions:&lt;br /&gt;
&lt;pre class="java" name="code"&gt; public void toggleCheck(Boolean val) {
  
  for(Station s : stations.list) {
   s.checked = val;
   editor.putBoolean("PF_"+s.getID(), val);
  }
  
  for(int i=0 ; i &amp;lt; lv.getChildCount() ; i++) {
   CheckBox cb = (CheckBox) lv.getChildAt(i).findViewById(R.id.cb);
   cb.setChecked(val);
  }

  editor.apply();
 }
 
    private class StationCBViewHolder {
        public CheckBox cb;
        public Station s;
    }
 
 private class StationListAdapter extends ArrayAdapter&lt;station&gt; {
     private ArrayList&lt;station&gt; items;
     private Context context;
     
     public StationListAdapter(Context context, int tvResId, ArrayList&lt;station&gt; items) {
         super(context, tvResId, items);
         this.items = items;
         this.context = context;
     }

     @Override
     public View getView(int pos, View v, ViewGroup parent) {
      final StationCBViewHolder holder;
      final Station item = items.get(pos);
      
         if (v == null) {
             LayoutInflater vi = ((Activity)context).getLayoutInflater();
             v = vi.inflate(R.layout.stationcheckboxitem, parent, false);
             
             holder = new StationCBViewHolder();
             holder.cb = (CheckBox) v.findViewById(R.id.cb);
             holder.s = item;
             
             item.checked = prefs.getBoolean("PF_"+item.getID(),true);
             
             //holder.cb.setTag(holder);
             holder.cb.setTag(item);
             holder.cb.setChecked(item.checked);
             holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
     @Override
     public void onCheckedChanged(CompoundButton v, boolean isChecked) {
      Station s = (Station) v.getTag();
      editor.putBoolean("PF_"+s.getID(), isChecked);
      editor.apply();
     }
    });
                        
             v.setTag(holder);
         } else {
          holder = (StationCBViewHolder) v.getTag(); 
         }

         holder.cb.setText(item.toString());
         holder.cb.setChecked(item.checked);

         return v;
     }

 }
&lt;/station&gt;&lt;/station&gt;&lt;/station&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Full code here:&amp;nbsp;&lt;a href="http://pastebin.com/8NMbHqRV"&gt;http://pastebin.com/8NMbHqRV&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The code still has some bugs related to SharedPreferences and&amp;nbsp;SharedPreferences.Editor, but at least it checks and unchecks all checkboxes.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-6110542522611690973?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/6110542522611690973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=6110542522611690973&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/6110542522611690973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/6110542522611690973'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/11/android-checkbox-listview-un-check-all.html' title='Android : Checkbox ListView - (un) check all'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-4463067519302390980</id><published>2011-09-14T23:26:00.000+02:00</published><updated>2011-09-15T00:25:09.575+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='urlshortener'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>URL shortening - make your own URL shortener</title><content type='html'>If you ever thought about URL shortening, you've probably already figured out, how it works.&lt;br /&gt;
&lt;br /&gt;
Those random letters and numbers which serve as a key (in hashtable data structures) are basically encoded integers, which are AUTO_INCREMENT values in the database.&lt;br /&gt;
&lt;br /&gt;
Here are the encoding and decoding functions:
&lt;br /&gt;
&lt;pre class="php" name="code"&gt;const ALLOWED_CHARS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

function id2short($integer, $base = self::ALLOWED_CHARS) {
	$out = '';
	$length = strlen($base);
	while($integer &amp;gt; $length-1) {
		$out = $base[fmod($integer, $length)].$out;
		$integer = floor( $integer / $length);
	}
	return $base[$integer].$out;
}

function short2id($string, $base = self::ALLOWED_CHARS) {
	$length = strlen($base);
	$size = strlen($string)-1;
	$string = str_split($string);
	$out = strpos($base, array_pop($string));
	foreach($string as $i=&amp;gt;$char) {
		$out += strpos($base, $char) * pow($length, $size - $i);
	}
	return $out;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;a href="http://go.kafol.net/2K"&gt;Full code here.&lt;/a&gt;
&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-4463067519302390980?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/4463067519302390980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=4463067519302390980&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4463067519302390980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4463067519302390980'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/09/url-shortening-make-your-own-url.html' title='URL shortening - make your own URL shortener'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-3320050343440464236</id><published>2011-09-03T02:01:00.000+02:00</published><updated>2011-09-03T02:06:22.983+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql replication'/><title type='text'>MySQL error 1236: Client requested master to start replication from impossible position</title><content type='html'>&lt;span style="font-size: large;"&gt;&lt;b&gt;Symptoms:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
[1236] Got fatal error 1236 from master when reading data from binary 
log: 'Client requested master to start replication from impossible 
position'&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;110902 16:47:08 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;110902 16:47:08 [ERROR] Slave I/O: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position', Error_code: 1236&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;110902 16:47:08 [Note] Slave I/O thread exiting, read up to log '&lt;/span&gt;&lt;u style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;mysql-bin.000033&lt;/b&gt;&lt;/u&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;', position &lt;/span&gt;&lt;u style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;4621679&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;on the master&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;root@dimko:/var/lib/mysql# ls -la mysql-bin.000033&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-rw-rw---- 1 mysql mysql &lt;/span&gt;&lt;u style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;4620018&lt;/b&gt;&lt;/u&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; 2011-09-01 13:45 mysql-bin.000033&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4620018 is less than &lt;/b&gt;&lt;b&gt;4621679, &lt;/b&gt;therefore it's an invalid position.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Causes:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Master server has crashed and the binlog cache has not been flushed to disk. Slave has recieved a new position, did not recieve data, and data gets lost in a crash (however it might have been written to table, but not in binlog).&lt;b&gt; &lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Solution:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Use this CHANGE MASTER statement on the slave.&lt;br /&gt;
CHANGE MASTER TO MASTER_LOG_FILE=&lt;b&gt;&lt;u&gt;&lt;i&gt;[NEXT FILE]&lt;/i&gt;&lt;/u&gt;&lt;/b&gt;, MASTER_LOG_POS=4;&lt;br /&gt;
SLAVE START;&lt;br /&gt;
&lt;br /&gt;
in my case that would be&lt;br /&gt;
&lt;br /&gt;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000034', MASTER_LOG_POS=4;&lt;br /&gt;
SLAVE START;&lt;br /&gt;
&lt;br /&gt;
I don't know why the master log position needs to be 4 for the new file.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;What happens:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
When the master server restarts it logs binary changes to a new binlog file, so that we minimize data loss by skipping to the next file (everything from the previous file was written already).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Prevention&lt;/span&gt;&lt;/b&gt;:&lt;br /&gt;
Add this line to &lt;b style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;my.cnf&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sync_binlog = 1&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;With this setting the master server flushes cache in the binlog after every write, so that in case of a crash you can lose one statement at most.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-3320050343440464236?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/3320050343440464236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=3320050343440464236&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3320050343440464236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3320050343440464236'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/09/mysql-error-1236-client-requested.html' title='MySQL error 1236: Client requested master to start replication from impossible position'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-6832564444334035814</id><published>2011-07-28T00:39:00.006+02:00</published><updated>2011-07-28T01:05:06.581+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Facebook php-sdk 3.0 changes getLoginURL()</title><content type='html'>Somehow these frequent changes are still poorly documented. Documentation is scattered across forums, changelogs, code comments and docs pages. Never on the single place. This is horrible. I'm sorry Facebook people, but this makes you look incompetent.
&lt;br&gt;&lt;br&gt;
The most obvious change is the abandonment of the getSession method. I have also found out that getLoginURL has been changed.
&lt;br&gt;
'req_perms' has been changed to 'scope'
&lt;br&gt;
'next' has been changed to 'redirect_uri'
&lt;br&gt;
'cancel_url' option has been removed. You'll have to find another way. If the user denies access it will be redirected to 'redirect_uri'. The user will also be redirected to 'redirect_uri' if he clicks allow.
&lt;br&gt;
You can know if the user denied access by looking at these GET parameters:
&lt;pre&gt;
[error_reason] =&gt; user_denied 
[error] =&gt; access_denied 
[error_description] =&gt; The user denied your request.
&lt;/pre&gt;

Also worth knowing is that redirect_uri will not work every time on a single page load (without refreshing the page).
&lt;br&gt;
Explanation:
&lt;br&gt;
The first time the users sees the oauth dialog there will be two options: Allow and Deny. Both buttons will redirect to 'redirect_uri'.
&lt;br&gt;
The second time the user sees the oauth dialog, Deny option will be renamed to 'Leave app'. 'redirect_uri' will still work.
&lt;br&gt;
The third time and so on, the button 'Leave app' will redirect to facebook.com/home.php
&lt;br&gt;
&lt;br&gt;
While this may not be entirely precise, it is true that eventually the Deny/Leave app button will not follow the redirect_uri parameter.
&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-6832564444334035814?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/6832564444334035814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=6832564444334035814&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/6832564444334035814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/6832564444334035814'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/07/facebook-php-sdk-30-changes-getloginurl.html' title='Facebook php-sdk 3.0 changes getLoginURL()'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-5397518531821383446</id><published>2011-07-24T23:57:00.006+02:00</published><updated>2011-07-28T01:01:34.110+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows 7'/><category scheme='http://www.blogger.com/atom/ns#' term='iptv'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='vlc'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>SiOL TV, dve mrežni kartici, VLC player, Windows 7 x64-bit</title><content type='html'>V primeru da vam IPTv ne deluje, če imate dve mrežni kartici (eno za internet in drugo za TV), poskusite pri mrežnem adapterju za TV nastaviti metriko na 2.
&lt;br&gt;&lt;br&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://i.imgur.com/AucpC.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px;" src="http://i.imgur.com/AucpC.png" border="0" alt="" /&gt;&lt;/a&gt;
&lt;br&gt;&lt;br&gt;
Ne pozabite na ostale nastavitve za vzpostavitev TV na VLC playerju:&lt;br&gt;
-odprite VLC in pritisnite CTRL+P (Preferences)
&lt;br&gt;-spodaj levo obkljukate Show settings "All"-s tem se omogočijo napredne nastavitve
&lt;br&gt;-v meniju gremo na Input/Codecs - na desni pri UDP portu vnesemo pravi port, ki je za t2 "5000", pri MTU pa imam "1492", potem pa še obkljukamo "Force IPv4"
&lt;br&gt;-gremo v meni "Video" in nato kliknemo "output modules" - pri "Video output modules" izberemo možnost iz seznama "OpenGL video output"
&lt;br&gt;-nato v levem meniju izberemo meni "Stream output" in nato "Access output"
&lt;br&gt;-V Access output sem v okence kjer piše "Multicast output interface" vpisal IP mrežne kartice, ki jo uporabljam za internet, v okence "IPv4 multicast output interface adress" pa sem vpisal IP mrežne kartice, ki jo uporabljam zgolj za IPTV
&lt;br&gt;-zadevo shranite in ponovno zaženite program.
&lt;br&gt;&lt;br&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://i.imgur.com/DhS56.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px;" src="http://i.imgur.com/DhS56.png" border="0" alt="" /&gt;&lt;/a&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-5397518531821383446?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/5397518531821383446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=5397518531821383446&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/5397518531821383446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/5397518531821383446'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/07/siol-tv-dve-mrezni-kartici-vlc-player.html' title='SiOL TV, dve mrežni kartici, VLC player, Windows 7 x64-bit'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-7319337079219191620</id><published>2011-07-24T12:56:00.005+02:00</published><updated>2011-07-24T13:03:19.436+02:00</updated><title type='text'>M3U file editor</title><content type='html'>M3U are playlist files. I have developed this &lt;a href="http://kafol.net/code/m3u-edit/"&gt;simple editor&lt;/a&gt; for a friend, that needed to edit IPTv playlist files.
&lt;br&gt;&lt;br&gt;
The editor includes mass (bulk) edits as well as item editor. You can upload and export the same filetype.
&lt;br&gt;&lt;br&gt;
You can check out the editor here:
&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;&lt;a href="http://kafol.net/code/m3u-edit/"&gt;http://kafol.net/code/m3u-edit/&lt;/a&gt;&lt;/span&gt;
&lt;br&gt;&lt;br&gt;
M3U files are easy to parse:
&lt;br&gt;
&lt;pre name="code" class="php"&gt;
&amp;lt;?
class m3u {
 public $data = array();
 public $name = '';
 
 public function __construct($data = null) {
  if(!is_null($data)) {
   $this-&amp;gt;load($data);
  }
 }
 
 public function load($data) {
  if(!is_array($data)) explode("\n",$data);
  
  foreach($data as $i=&amp;gt;$line) {
   if(preg_match('/^#EXTNAME:(.+)/is',$line,$m)) {
    $this-&amp;gt;name = clean($m[1]);
   }
   if(preg_match('/^#EXTINF:(\d+),(.+)/is',$line,$m)) {
    $item = new m3uitem();
    $item-&amp;gt;length = intval($m[1]);
    $item-&amp;gt;setName($m[2]);
    if(preg_match('/^#EXTTV:(.+)/is',$data[$i+1],$m)) {
     $item-&amp;gt;setCategories($m[1]);
    }
    $item-&amp;gt;file = trim($data[$i+2]);
    $this-&amp;gt;data[] = $item;
   }
  }
 }
 
 public function sort() {
  usort($this-&amp;gt;data, array(__CLASS__,'cmp'));
 }
 
 public static function cmp($a,$b) {
  if($a-&amp;gt;sort == $b-&amp;gt;sort) {
   return 0;
  }
  return ($a-&amp;gt;sort &amp;gt; $b-&amp;gt;sort) ? +1 : -1;
 }
 
 public function export() {
  $r = "#EXTM3U\n#EXTNAME:{$this-&amp;gt;name}\n\n";
  foreach($this-&amp;gt;data as $d) {
   $r .= "#EXTINF:{$d-&amp;gt;length},{$d-&amp;gt;getName()}\n";
   if($d-&amp;gt;getCategories() != '') {
    $r .= "#EXTTV:{$d-&amp;gt;getCategories()}\n";
   }
   $r .= "{$d-&amp;gt;file}\n\n";
  }
  return $r;
 }
 
}

class m3uitem {
 public $sort = 0;
 public $length = 0;
 public $file = '';
 private $name = '';
 private $categories = array();
 
 public function __construct() {}
 
 public function getName() { 
  return $this-&amp;gt;name; 
 }
 
 public function setName($name) {
  $this-&amp;gt;name = clean($name);
 }
 
 public function getCategories() {
  return implode(';',$this-&amp;gt;categories);
 }
 
 public function setCategories($data) {
  $this-&amp;gt;categories = is_array($data) ? $data : explode(';',clean($data));
  
  foreach($this-&amp;gt;categories as $i=&amp;gt;$cat) {
   if(empty($cat)) {
    unset($this-&amp;gt;categories[$i]);
   } else {
    $this-&amp;gt;categories[$i] = clean($this-&amp;gt;categories[$i]);
   }
  }
 }
}
?&amp;gt;
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-7319337079219191620?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/7319337079219191620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=7319337079219191620&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/7319337079219191620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/7319337079219191620'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/07/m3u-file-editor.html' title='M3U file editor'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-6144146686607791335</id><published>2011-07-19T14:14:00.006+02:00</published><updated>2011-09-16T15:17:21.014+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='subtitles'/><category scheme='http://www.blogger.com/atom/ns#' term='vlc'/><category scheme='http://www.blogger.com/atom/ns#' term='videolan'/><category scheme='http://www.blogger.com/atom/ns#' term='lua'/><title type='text'>Automatically download subtitles in VLC player</title><content type='html'>You can write VideoLAN VLC player's extensions in LUA programming language.
Extensions are in Videolan\VLC directory lua\extensions.
&lt;br /&gt;
&lt;br /&gt;
This is a &lt;a href="http://addons.videolan.org/CONTENT/content-files/141787-subtitles-mod.lua"&gt;modified&lt;/a&gt; extension to automatically download subtitles.
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 22px; font-weight: bold;"&gt;&lt;a href="http://kafol.net/code/vlc/AutoSubtitles.lua"&gt;Download extension&lt;/a&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
Will add more languages upon request.&lt;br /&gt;
Currently this extension is intended for personal use.&lt;br /&gt;
&lt;br /&gt;
Screenshots:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-m8F9CXzQmxE/TnMmaCHS1CI/AAAAAAAADXc/wl0Dzk7ByQI/s1600/lua.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-m8F9CXzQmxE/TnMmaCHS1CI/AAAAAAAADXc/wl0Dzk7ByQI/s320/lua.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-0IIVGWZbTwU/TnMmadVORWI/AAAAAAAADXg/XsztGxfQZuc/s1600/vlc.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="125" src="http://2.bp.blogspot.com/-0IIVGWZbTwU/TnMmadVORWI/AAAAAAAADXg/XsztGxfQZuc/s320/vlc.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-6144146686607791335?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/6144146686607791335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=6144146686607791335&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/6144146686607791335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/6144146686607791335'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/07/automatically-download-subtitles-in-vlc.html' title='Automatically download subtitles in VLC player'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-m8F9CXzQmxE/TnMmaCHS1CI/AAAAAAAADXc/wl0Dzk7ByQI/s72-c/lua.PNG' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-4527988491585070308</id><published>2011-07-19T14:11:00.003+02:00</published><updated>2011-07-19T14:12:54.687+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='goo.gl'/><category scheme='http://www.blogger.com/atom/ns#' term='urlshortener'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>PHP goo.gl url shortener</title><content type='html'>Here's an implementation of Google's url shortener: goo.gl.

&lt;pre name="code" class="php"&gt;
&amp;lt;?
class googl {
 const api = 'https://www.googleapis.com/urlshortener/v1/url';
 private $key = null;
 
 public function __construct($key = null) {
  if(defined('GOOGLE_API_KEY')) {
   $this-&amp;gt;setKey(GOOGLE_API_KEY);
  }
  
  if(!is_null($key)) {
   $this-&amp;gt;setKey($key);
  }
 }
 
 public function setKey($key) {
  $this-&amp;gt;key = $key;
 }
 
 public function s($url) {
  $data = $this-&amp;gt;shorten($url);
  return isset($data-&amp;gt;id) ? $data-&amp;gt;id : $url;
 }
 
 public function shorten($url) {
  $key = '';
  $data = array();
  $data['longUrl'] = $url;
  
  if(!is_null($this-&amp;gt;key)) {
   $key = '?key='.$this-&amp;gt;key;
  }
  
  return $this-&amp;gt;fetch(self::api.$key,$data);
 }
 
 public function expand($url) {
  $key = is_null($this-&amp;gt;key) ? '' : "&amp;key={$this-&amp;gt;key}";
  return $this-&amp;gt;fetch(self::api.'?shortUrl='.urlencode($url)."$key&amp;projection=FULL");
 }
 
 private function fetch($url, $data = array()) {
  $ch = curl_init();
  
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
  
  if(!empty($data)) {
   curl_setopt($ch, CURLOPT_POST, 1);
   curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  }
  
  $r = curl_exec($ch);
  curl_close($ch);
  
  return json_decode($r);
 }
}
?&amp;gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-4527988491585070308?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/4527988491585070308/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=4527988491585070308&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4527988491585070308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4527988491585070308'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/07/php-googl-url-shortener.html' title='PHP goo.gl url shortener'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-4774235784054013668</id><published>2011-05-25T18:20:00.002+02:00</published><updated>2011-05-25T18:24:02.366+02:00</updated><title type='text'>Disable Ubuntu Unity Launcher</title><content type='html'>I guess I'm the only one that hates launchers in desktop environment systems. They're too dumbed down and I can't tell which apps are running and which are just shortcuts.
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;The easiest way to disable the Unity Netbook Launcher in Ubuntu is to log out from the session, click on the user name and before you enter the password, click on the bottom on the screen and switch to Ubuntu classic&lt;/span&gt;
&lt;br&gt;&lt;br&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.madtomatoe.com/wp-content/uploads/2011/04/Ubuntu-Unity-580x419.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 580px; height: 419px;" src="http://www.madtomatoe.com/wp-content/uploads/2011/04/Ubuntu-Unity-580x419.png" border="0" alt="" /&gt;&lt;/a&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-4774235784054013668?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/4774235784054013668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=4774235784054013668&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4774235784054013668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/4774235784054013668'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/05/disable-ubuntu-unity-launcher.html' title='Disable Ubuntu Unity Launcher'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-3557111790444108508</id><published>2011-04-27T12:54:00.013+02:00</published><updated>2011-05-22T21:54:50.424+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='word'/><category scheme='http://www.blogger.com/atom/ns#' term='office'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Custom page numbering in MS Word</title><content type='html'>I'm sure most of you came across this problem before - how to add custom page numbering. 

&lt;br&gt;&lt;br&gt;
I don't really like making seperate documents for the pages I don't want numbered and options in MS Word are preety limited. You can set up the numbering to start with a different number. You can't, however, set it up to start with a negative number.

&lt;br&gt;
&lt;br&gt;
Example: You have the first three pages you don't want numbered (front page, page index, thanks). Everything after those pages is numbered and starts with 1.
&lt;br&gt;
&lt;br&gt;
- Go to the header/footer - wherever you want to set up page numbering.
&lt;br&gt;
- Add page numbering, set it up to start with zero and check the option to have a different header/footer on the first page. This way the front page will have the page number zero, but you can delete numbering for that page.
&lt;br&gt;
- Now you need to "extend" the first page, so that the second (or third) page will also be unnumbered. You can do this with page breaks, go to Insert -&gt; page break. There are a couple of different page breaks, choose the one that fits your needs.
&lt;br&gt;&lt;br&gt;
There's an other way to do a completely custom page numbering, but it involves a tiny amount of "programming" and it won't work the same if you add page index, but here goes:
&lt;br&gt;&lt;br&gt;
- Go to the header/footer
&lt;br&gt;
- Retype this code for the example above:
&lt;pre&gt;{ IF { PAGE } &lt; 4 "" "{ = { PAGE } - 3 }" }&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
The important thing here is that you need to press CTRL+F9 to get the curly braces. If you retype them, it won't work.
&lt;br&gt;
- After you've written the conditions for page numbering, right-click on it and choose "Update field".
&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;{ IF { PAGE } &lt; 4 "" "{ = { PAGE } - 3 }" }&lt;/pre&gt;
This is a simple conditional statement, if the current page number is less than four, the first argument (The empty "" string) will be used, otherwise it will calculate the current page number minus three.
&lt;br&gt;
&lt;br&gt;
Here are some other examples:
&lt;pre&gt;{ IF { PAGE } &lt; 3 "" "{ = { PAGE } - 2 }" }&lt;/pre&gt;
Skip the first two pages
&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;{ IF { PAGE } &lt; 3 "{ PAGE }" "{ = { PAGE } + 5 }" }&lt;/pre&gt;
Number the first two pages normally, then add 5 to the current page number.
&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;{ IF { PAGE } &lt; 3 "{ PAGE }" "" }&lt;/pre&gt;
Add a page number only to the first two pages.
&lt;br&gt;&lt;br&gt;
&lt;a href="http://word.mvps.org/faqs/numbering/pagenumbering.htm"&gt;Source&lt;/a&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-3557111790444108508?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/3557111790444108508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=3557111790444108508&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3557111790444108508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3557111790444108508'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/04/custom-page-numbering-in-ms-word.html' title='Custom page numbering in MS Word'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-303636525994004414</id><published>2011-04-25T17:34:00.002+02:00</published><updated>2011-04-25T17:35:50.076+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PHP: in_range()</title><content type='html'>&lt;pre name="code" class="php"&gt;
function in_range($num,$low,$high,$step=1) {
    return in_array($num,range($low,$high,$step));
}
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-303636525994004414?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/303636525994004414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=303636525994004414&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/303636525994004414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/303636525994004414'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/04/php-inrange.html' title='PHP: in_range()'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-3609317706989715516</id><published>2011-04-16T16:44:00.006+02:00</published><updated>2011-04-16T16:54:02.131+02:00</updated><title type='text'>jQuery cycle flash - swf file reloads</title><content type='html'>Flash object gets reloaded if you use &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; functions .hide() and .show() or to be exact, setting the css property display from 'block' to 'none' resets the swf (flash) objects.
&lt;br&gt;&lt;br&gt;
&lt;a href=http://stackoverflow.com/questions/1825792/jquery-hide-a-div-that-contains-flash-without-resetting-it"&gt;This&lt;/a&gt; topic has some info on how to hide a flash object without resetting it.
&lt;br&gt;&lt;br&gt;
&lt;a href="http://jquery.malsup.com/cycle/"&gt;jQuery Cycle&lt;/a&gt; plugin hides slides with .hide(), so I changed all .hide(), .show() functions and .display properties to use the 'visibility' property. The topic mentioned above says that this is not a cross-browser solution, so it needs some testing.
&lt;br&gt;&lt;br&gt;
Here's the fixed code&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;&lt;a href="http://pastebin.com/r5bySug4"&gt;http://pastebin.com/r5bySug4&lt;/a&gt;&lt;/span&gt;

&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-3609317706989715516?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/3609317706989715516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=3609317706989715516&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3609317706989715516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3609317706989715516'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/04/jquery-cycle-flash-swf-file-reloads.html' title='jQuery cycle flash - swf file reloads'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-7226397508801542538</id><published>2011-04-14T00:13:00.001+02:00</published><updated>2011-04-14T00:15:10.425+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='wireless'/><category scheme='http://www.blogger.com/atom/ns#' term='command prompt'/><title type='text'>Exporting wireless network passwords in windows</title><content type='html'>Open command prompt as an administrator
&lt;br&gt;
&lt;br&gt;
netsh wlan export profile folder=C:\
&lt;br&gt;
&lt;br&gt;
To import, type:
&lt;br&gt;
&lt;br&gt;
netsh wlan add profile filename="c:\Wireless Network Connection-whatever.xml" user=all&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-7226397508801542538?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/7226397508801542538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=7226397508801542538&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/7226397508801542538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/7226397508801542538'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/04/exporting-wireless-network-passwords-in.html' title='Exporting wireless network passwords in windows'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-8230081208417616552</id><published>2011-03-18T19:16:00.043+01:00</published><updated>2011-03-18T22:49:33.073+01:00</updated><title type='text'>Configuring repcached service on Debian/Ubuntu</title><content type='html'>&lt;a href="http://repcached.lab.klab.org/"&gt;Repcached&lt;/a&gt; is a slightly modified version of &lt;a href="http://memcached.org/"&gt;memcached&lt;/a&gt;, that supports replication of data between two repcached nodes.
&lt;br&gt;&lt;br&gt;
Let's say you've read all about these two and you know the benefits of replication and why this article could be useful to you.

&lt;br&gt;&lt;br&gt;

One example of why replicated memcache could be useful are replicated PHP sessions between servers.

&lt;br&gt;&lt;br&gt;

If you want to configure that PHP sessions are stored in memcache's memory, you need to edit these settings in &lt;span style="font-weight: bold;"&gt;/etc/php5/apache2/php.ini&lt;/span&gt;:

&lt;pre name="code" class="ini"&gt;
session.save_handler = memcache
session.save_path = "tcp://IP_OF_REPCACHE_1:11311, tcp://IP_OF_REPCACHE_2:11311"
&lt;/ip&gt;&lt;/ip&gt;&lt;/pre&gt;
and these optional settings in &lt;span style="font-weight: bold;"&gt;/etc/php5/apache2/conf.d
/memcache.ini&lt;/span&gt;:
&lt;pre name="code" class="ini"&gt;
memcache.maxratio=0
memcache.allow_failover=1
&lt;/pre&gt;

memcache.allow_failover setting is used if one of the servers becomes unreachable, so there is an automatic failover.

&lt;br&gt;
Read more about configuring PHP sessions in memcached &lt;a href="http://www.coderslash.com/blog/development/repcache-and-php-sessions"&gt;here&lt;/a&gt;.

&lt;br&gt;&lt;br&gt;

&lt;span style="font-weight:bold;"&gt;Now, let's set up repcached to start on boot and System V init scripts, so you can easly start and stop the daemon with the service command.&lt;/span&gt;

&lt;br&gt;&lt;br&gt;

Steps described here imitate memcached's default configuration &lt;span style="font-weight:bold;"&gt;in great detail&lt;/span&gt;, so you shoud set up memcached before repcached.

&lt;br&gt;
&lt;pre&gt;sudo apt-get install memcached&lt;/pre&gt;
&lt;br&gt;

&lt;a href="http://sourceforge.net/projects/repcached/files/repcached/2.2-1.2.8/memcached-1.2.8-repcached-2.2.tar.gz/download"&gt;Obtain&lt;/a&gt;, configure, compile and install repcached. There is a dependancy with libevent-dev for repcached.
&lt;pre&gt;
sudo apt-get install libevent-dev
tar xvf memcached-1.2.8-repcached-2.2.tar 
cd memcached-1.2.8-repcached-2.2/
./configure &lt;span style="font-weight:bold;"&gt;--enable-replication&lt;/span&gt;
make
make install
&lt;/pre&gt;

At this point you have two installations of memcached. Default memcached that came from apt packages, which is installed in /usr/bin/memcached and repcached, that installed itself in /usr/local/bin/memcached, leaving the original memcached intact.

&lt;br&gt;&lt;br&gt;

Now that we have both versions installed, we can &lt;span style="font-weight:bold;"&gt;copy memcached's default settings &lt;/span&gt;and init script and modify them to use repcached. This way you can quickly switch between versions. I would even recommend using default ports (just remember to &lt;span style="font-weight:bold;"&gt;firewall &lt;/span&gt;them!)

Arguments are saved in /etc/memcached.conf, so we will create &lt;span style="font-weight:bold;"&gt;/etc/repcached.conf&lt;/span&gt;

&lt;br&gt;&lt;br&gt;
&lt;a href="http://kafol.net/code/repcached/repcached.conf"&gt;&lt;span style="font-weight:bold;"&gt;See example here.&lt;/span&gt;&lt;/a&gt;
&lt;br&gt;&lt;br&gt;

Note that the only differences with memcached.conf is the name (repcached) and two extra arguments: -x for the server IP and -X for replication port.

&lt;br&gt;&lt;br&gt;

Memcached has an enable/disable config in /etc/default so you can quickly switch between daemons or disable them. We will copy this as well.

&lt;pre&gt;
cp /etc/default/memcached /etc/default/repcached
vi /etc/default/repcached
&lt;/pre&gt;

Change the line to:
&lt;span style="font-weight:bold;"&gt;ENABLE_REPCACHED=yes&lt;/span&gt;, and then edit /etc/default/memcached

&lt;pre&gt;
vi /etc/default/memcached
&lt;/pre&gt;
and disable it, by changing the line to &lt;span style="font-weight:bold;"&gt;ENABLE_MEMCACHED=no&lt;/span&gt;.

&lt;br&gt;&lt;br&gt;

Now let's move on to init scripts.

&lt;pre&gt;
cd /etc/init.d
cp memcached repcached
&lt;/pre&gt;
Edit the file /etc/init.d/repcached.

&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;&lt;a href="http://kafol.net/code/repcached/repcached.txt"&gt;Here is my example&lt;/a&gt;&lt;/span&gt;.
&lt;br&gt;&lt;br&gt;

Again, we didn't change much, mostly changed from memcached to repcached, but note that the actual start-up of the service happens in this file:&lt;span style="font-weight:bold;"&gt; /usr/share/memcached/scripts/start-repcached&lt;/span&gt; which doesn't exist yet, so we will copy &lt;span style="font-weight:bold;"&gt;and edit&lt;/span&gt; it.
&lt;pre&gt;
cp /usr/share/memcached/scripts/start-memcached /usr/share/memcached/scripts/start-repcached
&lt;/pre&gt;
File contents or &lt;span style="font-weight:bold;"&gt;&lt;a href="http://kafol.net/code/repcached/start-repcached.txt"&gt;/usr/share/memcached/scripts/start-repcached&lt;/a&gt;&lt;/span&gt; 
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;Setting up repcached to start at boot&lt;/span&gt;
&lt;br&gt;&lt;br&gt;
We need to be sure that /etc/init.d/repcached is executable. If you copied it from memcached, everything should be OK, but if init's not recognising the repcached service, you need to &lt;span style="font-weight:bold;"&gt;chmod +x /etc/init.d/repcached&lt;/span&gt;
&lt;br&gt;&lt;br&gt;
After you've run &lt;a href="http://www.debian.org/doc/debian-policy/ch-opersys.html#s-sysvinit"&gt;update-rc.d&lt;/a&gt; command in the terminal it will create shortcuts in rc?.d files which are read at boot.
&lt;pre&gt;
update-rc.d repcached defaults
&lt;/pre&gt;
For more information on update-rc.d, click &lt;a href="http://www.debian.org/doc/debian-policy/ch-opersys.html#s-sysvinit"&gt;here&lt;/a&gt;.

&lt;br&gt;&lt;br&gt;

You have successfully configured repcached as a service and to start on boot.
&lt;br&gt;&lt;br&gt;
To start/stop repcached use

&lt;pre&gt;
service repcached start
service repcached stop
&lt;/pre&gt;

Try to run repcached by hand at first with the configuration you provided in /etc/repcached.conf.
&lt;br&gt;
In my example it's this: 
&lt;br&gt;
/usr/local/bin/memcached -m 64 -p 11211 -u memcache -X 11212 -x 22.163.130.33
&lt;br&gt;&lt;br&gt;
After installing repcached on another machine I've found out that the default user for memcached is &lt;span style="font-style:italic;"&gt;nobody&lt;/span&gt;, not &lt;span style="font-style:italic;"&gt;memcache&lt;/span&gt;, so please &lt;span style="font-weight: bold;"&gt;always check the differences from the default memcache config with the repcached config you've modified or copied from here.&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-8230081208417616552?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/8230081208417616552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=8230081208417616552&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/8230081208417616552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/8230081208417616552'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/03/configuring-repcached-service-on.html' title='Configuring repcached service on Debian/Ubuntu'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-1717171664671052552</id><published>2011-02-05T01:54:00.001+01:00</published><updated>2011-02-05T01:56:02.462+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sockets'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>PHP:: socket_select(), socket_write() and socket_recv()</title><content type='html'>As it was already said, some clients need \0 character to end transmission, for example Flash's XMLSocket.
&lt;br&gt;&lt;br&gt;
You should also be prepared to read less data than you have requested. 
&lt;br&gt;&lt;br&gt;
Here is an example of a socket buffer - it's an array which has socket resources for keys and an array of a timestamp and recieved data as values.
&lt;br&gt;&lt;br&gt;
I find that the best practice for sending data is trailing it with a new line and zero character (\n\0), because you will probably have different types of clients which behave differently for reading data from sockets. Some need a \n to fire an event, some need \0.
&lt;br&gt;&lt;br&gt;
For recieving data, sometimes you will get splitted data - this can hapen because the buffer is full (in my example 8192 bytes) or it just gets broken during transmission in lower levels.
&lt;br&gt;&lt;br&gt;
Sometimes you can read two messages at once, but they have a zero character in between, so you can just use preg_split() to split the messages. The second message may not be complete, so you add it to your buffer.
&lt;br&gt;&lt;br&gt;

&lt;pre name="code" class="php"&gt;
 const message_delimiter = "\n\0";

 /*
  * Clear socket buffers older than 1 hour
  */
 function clear_buffer() {
  foreach($this-&amp;gt;buffer as $key=&amp;gt;$val) {
   if(time() - $val['ts'] &amp;gt; 3600) {
    unset($this-&amp;gt;buffer[$key]);
   }
  }
 }

 /*
  * Add data to a buffer
  */
 function buffer_add($sock,$data) {
  if(!isset($this-&amp;gt;buffer[$sock])) {
   $this-&amp;gt;buffer[$sock]['data'] = '';
  }

  $this-&amp;gt;buffer[$sock]['data'] .= $data;
  $this-&amp;gt;buffer[$sock]['ts'] = time();
 }

 function buffer_get($sock) {
  // split buffer by the end of string
  $lines = preg_split('/\0/',$this-&amp;gt;buffer[$sock]['data']);

  // reset buffer to the last line of input
  // if the buffer was sent completely, the last line of input should be
  // an empty string
  $this-&amp;gt;buffer[$sock]['data'] = trim($lines[count($lines)-1]);

  if(!empty($this-&amp;gt;buffer[$sock]['data'])) {
   debug("buffer is not empty for $sock, len: ".strlen($this-&amp;gt;buffer[$sock]['data']));
  }

  // remove the last line of input (incomplete data)
  // parse any complete data
  unset($lines[count($lines)-1]);

  // return only the fully sent data
  return $lines;
 }

 function read(&amp;$sock,$len=8192,$flag=MSG_DONTWAIT) {
  $lines = array();

  $this-&amp;gt;clear_buffer();

  $bytes_read = @socket_recv($sock,$read_data,$len,$flag);

  if ($bytes_read === false || $bytes_read == 0) {
   return false;
  } else {
   debug("recv: $read_data");
   $this-&amp;gt;buffer_add($sock,$read_data);
   return $this-&amp;gt;buffer_get($sock);
  }
 }

 /*
  * Write to a socket
  * add a newline and null character at the end
  * some clients don't read until new line is recieved
  *
  * try to send the rest of the data if it gets truncated
  */
 function write(&amp;$sock,$msg) {
  $msg = $msg.self::message_delimiter;
  $length = strlen($msg);
  while(true) {
   $sent = @socket_write($sock,$msg,$length);
   if($sent &amp;lt;= 0) {
    return false;
   }
   if($sent &amp;lt; $length) {
    $msg = substr($msg, $sent);
    $length -= $sent;
    debug("Message truncated: Resending: $msg");
   } else {
    return true;
   }
  }
  return false;
 }
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-1717171664671052552?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/1717171664671052552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=1717171664671052552&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1717171664671052552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1717171664671052552'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2011/02/php-socketselect-socketwrite-and.html' title='PHP:: socket_select(), socket_write() and socket_recv()'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-3113185645899578633</id><published>2010-12-29T09:57:00.004+01:00</published><updated>2011-07-28T00:57:58.287+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PHP:: Facebook getLoginUrl iframe next parameter redirect issue</title><content type='html'>&lt;span style="font-weight:bold;color:red;"&gt;DUE TO FREQUENT FACEBOOK API CHANGES THIS ARTICLE IS OUTDATED.&lt;/span&gt;
&lt;br&gt;&lt;br&gt;
The php-sdk from Facebook has some bugs in it.
&lt;br&gt;&lt;br&gt;
http://stackoverflow.com/questions/3380876/how-to-authorize-facebook-app-using-redirect-in-canvas
http://forum.developers.facebook.net/viewtopic.php?id=70575
&lt;br&gt;&lt;br&gt;
These solutions didn't work for me, so I had to change the function getLoginUrl in class Facebook
&lt;br&gt;&lt;br&gt;
&lt;pre name="code" class="php"&gt;
  public function getLoginUrl($params=array()) {
 $currentUrl = $this-&amp;gt;getCurrentUrl();
 $args = array(
        'api_key'         =&amp;gt; $this-&amp;gt;getAppId(),
        'cancel_url'      =&amp;gt; 'http://www.facebook.com/',
        'display'         =&amp;gt; 'page',
        'fbconnect'       =&amp;gt; 0,
        'next'            =&amp;gt; $currentUrl,
        'return_session'  =&amp;gt; 1,
        'session_version' =&amp;gt; 3,
  'canvas'          =&amp;gt; 1,
        'v'               =&amp;gt; '1.0',
      );
 foreach($params as $key=&amp;gt;$val) {
  $args[$key] = $val;
 }
 return $this-&amp;gt;getUrl(
  'www',
  'login.php',
  $args
 );
  }
&lt;/pre&gt;
Example:
&lt;pre name="code" class="php"&gt;
if($me) {
 $logoutUrl = $facebook-&amp;gt;getLogoutUrl();
} else {
 $loginUrl = $facebook-&amp;gt;getLoginUrl(array('next'=&amp;gt;'http://apps.facebook.com/xxxxxxx/'));
 ?&amp;gt;
 &amp;lt;script type="text/javascript"&amp;gt;
 top.location.href = '&amp;lt;?=$loginUrl?&amp;gt;';
 &amp;lt;/script&amp;gt;
 &amp;lt;?php 
 exit;
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-3113185645899578633?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/3113185645899578633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=3113185645899578633&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3113185645899578633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/3113185645899578633'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2010/12/php-facebook-getloginurl-iframe-next.html' title='PHP:: Facebook getLoginUrl iframe next parameter redirect issue'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-1695766149142814134</id><published>2010-12-06T00:40:00.002+01:00</published><updated>2010-12-06T00:46:24.385+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PHP:: relative paths in include() or require()</title><content type='html'>While this might seem fairly obvious, I'd still like to point out that PHP's functions include(), include_once(), require() and require_once() have problems including files in different directories where paths of the filenames are relative. The absolute path of the included files is generated from the filename of the first included file, so any relative path in the second nested include will not have relative paths starting from it's directory, but the directory of the first file. To avoid confusion I find it's best to use absolute paths with the magic constant __FILE__, which is always the current script's filename.
&lt;br&gt;
&lt;br&gt;
Example:
&lt;br&gt;
&lt;pre&gt;
require_once(dirname(__FILE__).'/../../include_all.php');
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-1695766149142814134?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/1695766149142814134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=1695766149142814134&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1695766149142814134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1695766149142814134'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2010/12/php-relative-paths-in-include-or.html' title='PHP:: relative paths in include() or require()'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8709754195953818893.post-1010353594214605457</id><published>2010-11-21T20:43:00.009+01:00</published><updated>2010-11-21T20:53:11.690+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Flash wmode (transparent/opaque/window) z-index</title><content type='html'>In flash player 9 and below there was a problem with the object's z-index if the wmode was set to window.


&lt;br&gt;&lt;br&gt;



When this option is set to transparent, it fixes the z-index issue, but messes up the keyboard layout and mouse wheel events in flash object.
Flash player 10.1 fixes the keyboard layout issue.
&lt;br&gt;&lt;br&gt;

&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Workaround&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;

Setting &lt;span style="font-weight: bold;"&gt;wmode &lt;/span&gt;to &lt;span style="font-weight: bold;"&gt;opaque &lt;/span&gt;keeps the mouse wheel functionality and z-index of absolute elements on the page, &lt;span style="font-weight: bold;color:red;" &gt;but only if you set the background color for the element!&lt;/span&gt;

&lt;br&gt;&lt;br&gt;


&lt;b&gt;
Having a transparent background (or setting the opacity attribute in CSS) (still) does not solve the issue.&lt;/b&gt;

&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8709754195953818893-1010353594214605457?l=dev.kafol.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev.kafol.net/feeds/1010353594214605457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8709754195953818893&amp;postID=1010353594214605457&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1010353594214605457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8709754195953818893/posts/default/1010353594214605457'/><link rel='alternate' type='text/html' href='http://dev.kafol.net/2010/11/flash-wmode-z-index.html' title='Flash wmode (transparent/opaque/window) z-index'/><author><name>jean caffou</name><uri>http://www.blogger.com/profile/02503059980285430433</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_R5lpE147Xe0/TFRPhUo0xCI/AAAAAAAADDc/uUCFIrWuTyY/S220/IMG_0822.JPG'/></author><thr:total>0</thr:total></entry></feed>
