<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[GlotPress] [466] trunk: Translation set syncing between projects</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd>466</dd>
<dt>Author</dt> <dd>nbachiyski</dd>
<dt>Date</dt> <dd>2010-04-09 15:23:52 +0000 (Fri, 09 Apr 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>Translation set syncing between projects</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkcssstylecss">trunk/css/style.css</a></li>
<li><a href="#trunkgpincludesassetsloaderphp">trunk/gp-includes/assets-loader.php</a></li>
<li><a href="#trunkgpincludesmiscphp">trunk/gp-includes/misc.php</a></li>
<li><a href="#trunkgpincludesroutes_mainphp">trunk/gp-includes/routes/_main.php</a></li>
<li><a href="#trunkgpincludesroutesprojectphp">trunk/gp-includes/routes/project.php</a></li>
<li><a href="#trunkgpincludesroutestranslationsetphp">trunk/gp-includes/routes/translation-set.php</a></li>
<li><a href="#trunkgpincludesroutesphp">trunk/gp-includes/routes.php</a></li>
<li><a href="#trunkgpincludestemplatephp">trunk/gp-includes/template.php</a></li>
<li><a href="#trunkgpincludesthingsprojectphp">trunk/gp-includes/things/project.php</a></li>
<li><a href="#trunkgptemplatesfooterphp">trunk/gp-templates/footer.php</a></li>
<li><a href="#trunkgptemplatesprojectformphp">trunk/gp-templates/project-form.php</a></li>
<li><a href="#trunkgptemplatesprojectphp">trunk/gp-templates/project.php</a></li>
<li><a href="#trunkgptemplatestranslationsetformphp">trunk/gp-templates/translation-set-form.php</a></li>
<li><a href="#trunkjscommonjs">trunk/js/common.js</a></li>
<li><a href="#trunkjstranslationspagejs">trunk/js/translations-page.js</a></li>
<li><a href="#trunkttest_miscphp">trunk/t/test_misc.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkgptemplatesprojectmasscreatesetsphp">trunk/gp-templates/project-mass-create-sets.php</a></li>
<li><a href="#trunkjsmasscreatesetspagejs">trunk/js/mass-create-sets-page.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkcssstylecss"></a>
<div class="modfile"><h4>Modified: trunk/css/style.css (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/css/style.css        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/css/style.css        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -2,6 +2,8 @@
</span><span class="cx">         font-family: &quot;Helvetica&quot;, &quot;Arial&quot;, sans-serif;
</span><span class="cx">         color: #333;
</span><span class="cx">         line-height: 1.5em;
</span><ins>+        font-size: 14px;
+        margin: 0 .5em 0 .5em;
</ins><span class="cx"> }
</span><span class="cx"> input, textarea {
</span><span class="cx">     font-size: 1em;
</span><span class="lines">@@ -27,6 +29,10 @@
</span><span class="cx"> a img {
</span><span class="cx">     border: 0;
</span><span class="cx"> }
</span><ins>+a.disabled {
+    color: #aaa;
+    text-decoration: none;
+}
</ins><span class="cx"> h2 {
</span><span class="cx">     border-bottom: 0.08em solid #CCC;
</span><span class="cx"> }
</span><span class="lines">@@ -405,3 +411,9 @@
</span><span class="cx">         padding-left: 1em;
</span><span class="cx">         border-left: 3px solid #aaa;
</span><span class="cx"> }
</span><ins>+span.added {
+    color: green;
+}
+span.removed {
+    color: red;
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesassetsloaderphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/assets-loader.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/assets-loader.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/assets-loader.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx">         $scripts-&gt;add( 'common', '/common.js', array( 'jquery' ) );
</span><span class="cx">         $scripts-&gt;add( 'editor', '/editor.js', array( 'common', 'google-js-api' ) );
</span><span class="cx">         $scripts-&gt;add( 'translations-page', '/translations-page.js', array( 'common' ) );
</span><ins>+        $scripts-&gt;add( 'mass-create-sets-page', '/mass-create-sets-page.js', array( 'common' ) );
</ins><span class="cx">         $scripts-&gt;add( 'google-js-api', 'http://www.google.com/jsapi', array(), '' );
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkgpincludesmiscphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/misc.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/misc.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/misc.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -43,7 +43,6 @@
</span><span class="cx">         return isset( $object-&gt;$key )? $object-&gt;$key : $default;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> /**
</span><span class="cx">  * Makes from an array of arrays a flat array.
</span><span class="cx">  *
</span><span class="lines">@@ -268,4 +267,22 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx">         return $res;
</span><ins>+}
+
+function gp_array_any( $callback, $array ) {
+        foreach( $array as $item ) {
+                if ( $callback( $item ) ) {
+                        return true;
+                }
+        }
+        return false;
+}
+
+function gp_array_all( $callback, $array ) {
+        foreach( $array as $item ) {
+                if ( !$callback( $item ) ) {
+                        return false;
+                }
+        }
+        return false;
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesroutes_mainphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/routes/_main.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/routes/_main.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/routes/_main.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -3,42 +3,4 @@
</span><span class="cx">  * Holds common functionality for routes.
</span><span class="cx">  */
</span><span class="cx"> class GP_Route_Main extends GP_Route {
</span><del>-        // TODO: move these as a template helper
-        
-        function _options_from_projects( $projects ) {
-                // TODO: mark which nodes are editable by the current user
-                $tree = array();
-                $top = array();
-                foreach( $projects as $p ) {
-                        $tree[$p-&gt;id]['self'] = $p;
-                        if ( $p-&gt;parent_project_id ) {
-                                $tree[$p-&gt;parent_project_id]['children'][] = $p-&gt;id;
-                        } else {
-                                $top[] = $p-&gt;id;
-                        }
-                }
-                $options = array( '' =&gt; __('No parent') );
-                $stack = array();
-                foreach( $top as $top_id ) {
-                        $stack = array( $top_id );
-                        while ( !empty( $stack ) ) {
-                                $id = array_pop( $stack );
-                                $tree[$id]['level'] = gp_array_get( $tree[$id], 'level', 0 );
-                                $options[$id] = str_repeat( '-', $tree[$id]['level'] ) . $tree[$id]['self']-&gt;name;
-                                foreach( gp_array_get( $tree[$id], 'children', array() ) as $child_id ) {
-                                        $stack[] = $child_id;
-                                        $tree[$child_id]['level'] = $tree[$id]['level'] + 1;
-                                }
-                        }
-                }
-                return $options;
-        }
-
-        function _options_from_locales( $locales ) {
-                $values = array_map( create_function( '$l', 'return $l-&gt;slug;'), $locales );
-                $labels = array_map( create_function( '$l', 'return $l-&gt;slug.&quot; - &quot;. $l-&gt;english_name;'), $locales );
-                sort( $values );
-                sort( $labels );
-                return array_combine($values, $labels);
-        }
</del><span class="cx"> }
</span></span></pre></div>
<a id="trunkgpincludesroutesprojectphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/routes/project.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/routes/project.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/routes/project.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -70,7 +70,6 @@
</span><span class="cx">                 $project = GP::$project-&gt;by_path( $project_path );
</span><span class="cx">                 if ( !$project ) gp_tmpl_404();
</span><span class="cx">                 $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
</span><del>-                $all_project_options = self::_options_from_projects( GP::$project-&gt;all() );
</del><span class="cx">                 gp_tmpl_load( 'project-edit', get_defined_vars() );
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -111,7 +110,6 @@
</span><span class="cx">                 $project = new GP_Project();
</span><span class="cx">                 $project-&gt;parent_project_id = gp_get( 'parent_project_id', null );
</span><span class="cx">                 $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;parent_project_id );
</span><del>-                $all_project_options = self::_options_from_projects( GP::$project-&gt;all() );
</del><span class="cx">                 gp_tmpl_load( 'project-new', get_defined_vars() );
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -125,7 +123,6 @@
</span><span class="cx">                 if ( !$project ) {
</span><span class="cx">                         $project = new GP_Project();
</span><span class="cx">                         $this-&gt;errors[] = __('Error in creating project!');
</span><del>-                        $all_project_options = self::_options_from_projects( GP::$project-&gt;all() );
</del><span class="cx">                         gp_tmpl_load( 'project-new', get_defined_vars() );
</span><span class="cx">                 } else {
</span><span class="cx">                         $this-&gt;notices[] = __('The project was created!');
</span><span class="lines">@@ -197,4 +194,47 @@
</span><span class="cx">                 }
</span><span class="cx">                 gp_redirect( gp_url_project( $project, array( '-permissions' ) ) );
</span><span class="cx">         }
</span><ins>+
+        function mass_create_sets_get( $project_path ) {
+                $project = GP::$project-&gt;by_path( $project_path );
+                if ( !$project ) gp_tmpl_404();
+                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
+                $this-&gt;tmpl( 'project-mass-create-sets', get_defined_vars() );
+        }
+
+        function mass_create_sets_post( $project_path ) {
+                $project = GP::$project-&gt;by_path( $project_path );
+                if ( !$project ) gp_tmpl_404();
+                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
+                $other_project = GP::$project-&gt;get( gp_post( 'project_id' ) );
+                if ( !$other_project ) {
+                        $this-&gt;die_with_error( __('Project wasn&amp;#8217;found') );
+                }
+                $changes = $project-&gt;set_difference_from( $other_project );
+                $errors = 0;
+                foreach( $changes['added'] as $to_add ) {
+                        if ( !GP::$translation_set-&gt;create( array('project_id' =&gt; $project-&gt;id, 'name' =&gt; $to_add-&gt;name, 'locale' =&gt; $to_add-&gt;locale, 'slug' =&gt; $to_add-&gt;slug) ) ) {
+                                $this-&gt;errors[] = __('Couldn&amp;#8217;t add translation set named %s', esc_html( $to_add-&gt;name ) );
+                        }
+                }
+                foreach( $changes['removed'] as $to_remove ) {
+                        if ( !$to_remove-&gt;delete() ) {
+                                $this-&gt;errors[] = __('Couldn&amp;#8217;t delete translation set named %s', esc_html( $to_remove-&gt;name ) );
+                        }
+                }
+                if ( !$this-&gt;errors ) $this-&gt;notices[] = __('Translation sets were added and removed successfully');
+                gp_redirect( gp_url_project( $project ) );
+        }
+
+        function mass_create_sets_preview_post( $project_path ) {
+                $project = GP::$project-&gt;by_path( $project_path );
+                if ( !$project ) gp_tmpl_404();
+                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
+                $other_project = GP::$project-&gt;get( gp_post( 'project_id' ) );
+                if ( !$other_project ) {
+                        $this-&gt;die_with_error( __('Project wasn&amp;#8217;found') );
+                }
+                header('Content-Type: application/json');
+                echo json_encode( $project-&gt;set_difference_from( $other_project ) );
+        }        
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesroutestranslationsetphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/routes/translation-set.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/routes/translation-set.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/routes/translation-set.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -6,8 +6,6 @@
</span><span class="cx">                 if ( $set-&gt;project_id ) {
</span><span class="cx">                         $this-&gt;can_or_redirect( 'write', 'project', $set-&gt;project_id, gp_url_project( GP::$project-&gt;get( $set-&gt;project_id ) ) );
</span><span class="cx">                 }
</span><del>-                $all_project_options = self::_options_from_projects( GP::$project-&gt;all() );
-                $all_locale_options = self::_options_from_locales( GP_Locales::locales() );
</del><span class="cx">                 gp_tmpl_load( 'translation-set-new', get_defined_vars() );
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkgpincludesroutesphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/routes.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/routes.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/routes.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -58,6 +58,10 @@
</span><span class="cx">                         &quot;post:/$project/-permissions&quot; =&gt; array('GP_Route_Project', 'permissions_post'),
</span><span class="cx">                         &quot;get:/$project/-permissions/-delete/$dir&quot; =&gt; array('GP_Route_Project', 'permissions_delete'),
</span><span class="cx">                         
</span><ins>+                        &quot;get:/$project/-mass-create-sets&quot; =&gt; array('GP_Route_Project', 'mass_create_sets_get'),
+                        &quot;post:/$project/-mass-create-sets&quot; =&gt; array('GP_Route_Project', 'mass_create_sets_post'),
+                        &quot;post:/$project/-mass-create-sets/preview&quot; =&gt; array('GP_Route_Project', 'mass_create_sets_preview_post'),
+                        
</ins><span class="cx"> 
</span><span class="cx">                         &quot;get:/$projects&quot; =&gt; array('GP_Route_Project', 'index'),
</span><span class="cx">                         &quot;get:/$projects/-new&quot; =&gt; array('GP_Route_Project', 'new_get'),
</span></span></pre></div>
<a id="trunkgpincludestemplatephp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/template.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/template.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/template.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -29,7 +29,6 @@
</span><span class="cx">         gp_tmpl_load( 'footer', $args );
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> function gp_head() {
</span><span class="cx">         do_action( 'gp_head' );
</span><span class="cx"> }
</span><span class="lines">@@ -165,10 +164,41 @@
</span><span class="cx">         return $attrs;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function gp_locales_dropdown( $name_and_id, $selected_slug = '', $attrs = array() ) {
-        $options = array( '' =&gt; '&amp;mdash; Locale &amp;mdash;' );
-        foreach( GP_Locales::locales() as $locale ) {
-                $options[$locale-&gt;slug] = sprintf( '%s &amp;ndash; %s', $locale-&gt;slug, $locale-&gt;english_name );
</del><ins>+function gp_locales_dropdown( $name_and_id, $selected_slug = null, $attrs = array() ) {
+        $locales = GP_Locales::locales();
+        $values = array_map( create_function( '$l', 'return $l-&gt;slug;'), $locales );
+        $labels = array_map( create_function( '$l', 'return $l-&gt;slug.&quot; &amp;mdash; &quot;. $l-&gt;english_name;'), $locales );
+        sort( $values );
+        sort( $labels );
+        return gp_select( $name_and_id, array_merge( array( '' =&gt; __('&amp;mdash; Locale &amp;mdash;') ), array_combine( $values, $labels ) ), $selected_slug, $attrs );
+}
+
+function gp_projects_dropdown( $name_and_id, $selected_project_id = null, $attrs = array() ) {
+        $projects = GP::$project-&gt;all();
+        // TODO: mark which nodes are editable by the current user
+        $tree = array();
+        $top = array();
+        foreach( $projects as $p ) {
+                $tree[$p-&gt;id]['self'] = $p;
+                if ( $p-&gt;parent_project_id ) {
+                        $tree[$p-&gt;parent_project_id]['children'][] = $p-&gt;id;
+                } else {
+                        $top[] = $p-&gt;id;
+                }
</ins><span class="cx">         }
</span><del>-        return gp_select( $name_and_id, $options, $selected_slug, $attrs );
</del><ins>+        $options = array( '' =&gt; __('&amp;mdash; No parent &amp;mdash;') );
+        $stack = array();
+        foreach( $top as $top_id ) {
+                $stack = array( $top_id );
+                while ( !empty( $stack ) ) {
+                        $id = array_pop( $stack );
+                        $tree[$id]['level'] = gp_array_get( $tree[$id], 'level', 0 );
+                        $options[$id] = str_repeat( '-', $tree[$id]['level'] ) . $tree[$id]['self']-&gt;name;
+                        foreach( gp_array_get( $tree[$id], 'children', array() ) as $child_id ) {
+                                $stack[] = $child_id;
+                                $tree[$child_id]['level'] = $tree[$id]['level'] + 1;
+                        }
+                }
+        }
+        return gp_select( $name_and_id, $options, $selected_project_id, $attrs );
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesthingsprojectphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/things/project.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/things/project.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-includes/things/project.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -127,5 +127,25 @@
</span><span class="cx">                 }
</span><span class="cx">                 return array_merge( array( &amp;$this ), $path );
</span><span class="cx">         }
</span><ins>+        
+        function set_difference_from( $other_project ) {
+                $this_sets = (array)GP::$translation_set-&gt;by_project_id( $this-&gt;id );
+                $other_sets = (array)GP::$translation_set-&gt;by_project_id( $other_project-&gt;id );
+                $added = array();
+                $removed = array();
+                foreach( $other_sets as $other_set ) {
+                        $vars = array( 'locale' =&gt; $other_set-&gt;locale, 'slug' =&gt; $other_set-&gt;slug );
+                        if ( !gp_array_any( lambda('$set', '$set-&gt;locale == $locale &amp;&amp; $set-&gt;slug == $slug', $vars ), $this_sets ) ) {
+                                $added[] = $other_set;
+                        }
+                }
+                foreach( $this_sets as $this_set ) {
+                        $vars = array( 'locale' =&gt; $this_set-&gt;locale, 'slug' =&gt; $this_set-&gt;slug );
+                        if ( !gp_array_any( lambda('$set', '$set-&gt;locale == $locale &amp;&amp; $set-&gt;slug == $slug', $vars ), $other_sets ) ) {
+                                $removed[] = $this_set;
+                        }
+                }
+                return compact( 'added', 'removed' );
+        }
</ins><span class="cx"> }
</span><span class="cx"> GP::$project = new GP_Project();
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgptemplatesfooterphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-templates/footer.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/footer.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-templates/footer.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-        &lt;p id=&quot;footer&quot;class=&quot;secondary&quot;&gt;
</del><ins>+        &lt;p id=&quot;footer&quot; class=&quot;secondary&quot;&gt;
</ins><span class="cx">                 &lt;?php printf( __('Proudly powered by &lt;a href=&quot;%s&quot; title=&quot;Found in translation&quot;&gt;GlotPress&lt;/a&gt;.'), 'http://glotpress.org/' ); ?&gt;
</span><span class="cx">                 &lt;?php gp_footer(); ?&gt;
</span><span class="cx">         &lt;/p&gt;
</span></span></pre></div>
<a id="trunkgptemplatesprojectformphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-templates/project-form.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/project-form.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-templates/project-form.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -19,7 +19,7 @@
</span><span class="cx">         &lt;/dd&gt;
</span><span class="cx"> 
</span><span class="cx">         &lt;dt&gt;&lt;label for=&quot;project[parent_project_id]&quot;&gt;&lt;?php _e('Parent Project');  ?&gt;&lt;/label&gt;&lt;/dt&gt;
</span><del>-        &lt;dd&gt;&lt;?php echo gp_select( 'project[parent_project_id]', $all_project_options, $project-&gt;parent_project_id); ?&gt;&lt;/dd&gt;
</del><ins>+        &lt;dd&gt;&lt;?php echo gp_projects_dropdown( 'project[parent_project_id]', $project-&gt;parent_project_id); ?&gt;&lt;/dd&gt;
</ins><span class="cx"> &lt;/dl&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;?php echo gp_js_focus_on( 'project[name]' ); ?&gt;
</span></span></pre></div>
<a id="trunkgptemplatesprojectmasscreatesetsphp"></a>
<div class="addfile"><h4>Added: trunk/gp-templates/project-mass-create-sets.php (0 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/project-mass-create-sets.php                                (rev 0)
+++ trunk/gp-templates/project-mass-create-sets.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+&lt;?php
+gp_title( sprintf( __( 'Mass-create Translation Sets &amp;lt; %s &amp;lt; GlotPress' ),  $project-&gt;name ) );
+gp_breadcrumb( array(
+        gp_link_project_get( $project, $project-&gt;name ),
+) );
+wp_enqueue_script( 'mass-create-sets-page' );
+wp_localize_script( 'mass-create-sets-page', '$gp_mass_create_sets_options', array(
+        'url' =&gt; gp_url_join( gp_url_current(), 'preview'),
+        'loading' =&gt; __('Loading translation sets to create&amp;hellip;'),
+));
+gp_tmpl_header();
+?&gt;
+&lt;h2&gt;&lt;?php _e( sprintf( __('Mass-create Project Sets in &lt;q&gt;%s&lt;/q&gt;'), esc_html( $project-&gt;name ) ) ); ?&gt;&lt;/h2&gt;
+&lt;p&gt;&lt;?php _e('Here you can mass-create translation sets in this project.
+The list of translation sets will be mirrored with the sets of a project you choose.
+Usually this is one of the parent projects.'); ?&gt;&lt;/p&gt;
+&lt;form action=&quot;&lt;?php echo esc_url( gp_url_current() ); ?&gt;&quot; method=&quot;post&quot;&gt;
+        &lt;dl&gt;
+                &lt;dt&gt;&lt;label for=&quot;project_id&quot;&gt;&lt;?php _e('Project to take translation sets from:');  ?&gt;&lt;/label&gt;&lt;/dt&gt;
+                &lt;dd&gt;&lt;?php echo gp_projects_dropdown( 'project_id', $project-&gt;parent_project_id ); ?&gt;&lt;/dd&gt;
+        &lt;/dl&gt;
+        &lt;div id=&quot;preview&quot;&gt;&lt;/div&gt;
+        &lt;p&gt;&lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;&lt;?php echo esc_attr( __('Create Translation Sets') ); ?&gt;&quot; id=&quot;submit&quot; /&gt;&lt;/p&gt;
+&lt;/form&gt;
+&lt;?php gp_tmpl_footer();
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/gp-templates/project-mass-create-sets.php
</span><span class="cx">___________________________________________________________________
</span><span class="cx">Name: svn:eol-style
</span><span class="cx">   + native
</span></span></pre></div>
<a id="trunkgptemplatesprojectphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-templates/project.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/project.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-templates/project.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -75,8 +75,9 @@
</span><span class="cx">         &lt;p class=&quot;secondary actionlist&quot;&gt;
</span><span class="cx">                 &lt;?php gp_link( gp_url_project( $project, 'import-originals' ), __( 'Import originals' ) ); ?&gt; &amp;bull;
</span><span class="cx">                 &lt;?php gp_link( gp_url_project( $project, array( '-permissions' ) ), __('Permissions') ); ?&gt; &amp;bull;
</span><del>-                &lt;?php gp_link( gp_url_project( '', '-new', array('parent_project_id' =&gt; $project-&gt;id) ), __('Create a New Sub-Project') ); ?&gt; &amp;bull;
-                &lt;?php gp_link( gp_url( '/sets/-new', array( 'project_id' =&gt; $project-&gt;id ) ), __('Create a New Translation Set') ); ?&gt;
</del><ins>+                &lt;?php gp_link( gp_url_project( '', '-new', array('parent_project_id' =&gt; $project-&gt;id) ), __('New Sub-Project') ); ?&gt; &amp;bull;
+                &lt;?php gp_link( gp_url( '/sets/-new', array( 'project_id' =&gt; $project-&gt;id ) ), __('New Translation Set') ); ?&gt; &amp;bull;
+                &lt;?php gp_link( gp_url_project( $project, array( '-mass-create-sets' ) ), __('Mass-create Translation Sets') ); ?&gt;
</ins><span class="cx">         &lt;/p&gt;
</span><span class="cx"> &lt;?php endif; ?&gt;
</span><span class="cx"> &lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;
</span></span></pre></div>
<a id="trunkgptemplatestranslationsetformphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-templates/translation-set-form.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/translation-set-form.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/gp-templates/translation-set-form.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> &lt;dl&gt;
</span><span class="cx">         &lt;dt&gt;&lt;label for=&quot;set[locale]&quot;&gt;&lt;?php _e('Locale');  ?&gt;&lt;/label&gt;&lt;/dt&gt;
</span><span class="cx">         &lt;dd&gt;
</span><del>-                &lt;?php echo gp_select( 'set[locale]', $all_locale_options, $set-&gt;locale); ?&gt;
</del><ins>+                &lt;?php echo gp_locales_dropdown( 'set[locale]', $set-&gt;locale ); ?&gt;
</ins><span class="cx">                 &lt;a href=&quot;#&quot; id=&quot;copy&quot;&gt;&lt;?php _e('Use as name'); ?&gt;&lt;/a&gt;
</span><span class="cx">         &lt;/dd&gt;
</span><span class="cx">         
</span><span class="lines">@@ -13,15 +13,13 @@
</span><span class="cx">         &lt;dd&gt;&lt;input type=&quot;text&quot; name=&quot;set[slug]&quot; value=&quot;&lt;?php echo esc_html( $set-&gt;slug? $set-&gt;slug : 'default' ); ?&gt;&quot; id=&quot;set[slug]&quot;&gt;&lt;/dd&gt;
</span><span class="cx"> 
</span><span class="cx">         &lt;dt&gt;&lt;label for=&quot;set[project_id]&quot;&gt;&lt;?php _e('Project');  ?&gt;&lt;/label&gt;&lt;/dt&gt;
</span><del>-        &lt;dd&gt;&lt;?php echo gp_select( 'set[project_id]', $all_project_options, $set-&gt;project_id); ?&gt;&lt;/dd&gt;
-        
-        
</del><ins>+        &lt;dd&gt;&lt;?php echo gp_projects_dropdown( 'set[project_id]', $set-&gt;project_id ); ?&gt;&lt;/dd&gt;
</ins><span class="cx"> &lt;/dl&gt;
</span><span class="cx"> &lt;?php echo gp_js_focus_on( 'set[locale]' ); ?&gt;
</span><span class="cx"> &lt;script type=&quot;text/javascript&quot;&gt;
</span><span class="cx">         jQuery(function($){
</span><span class="cx">                 $('#copy').click(function() {
</span><del>-                        $('#set\\[name\\]').val($('#set\\[locale\\] option:selected').html().replace(/^\S+\s+\S+\s+/, ''));
</del><ins>+                        $('#set\\[name\\]').val($('#set\\[locale\\] option:selected').html().replace(/^\S+\s+\S+\s+/, '').replace(/&amp;mdash|—/, ''));
</ins><span class="cx">                         return false;
</span><span class="cx">                 });
</span><span class="cx">         });
</span></span></pre></div>
<a id="trunkjscommonjs"></a>
<div class="modfile"><h4>Modified: trunk/js/common.js (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/js/common.js        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/js/common.js        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -28,12 +28,14 @@
</span><span class="cx">                         $gp.notices.element.css('left', ($(document).width() - $gp.notices.element.width()) / 2);
</span><span class="cx">                 }
</span><span class="cx">         },
</span><ins>+        esc_html: function(s) {
+                return $('&lt;div/&gt;').text(s).html();
+        },
</ins><span class="cx">         init: function() {
</span><span class="cx">                 $gp.notices.init();
</span><span class="cx">         }
</span><span class="cx"> }}(jQuery);
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> $gp.showhide = function($) { return function(link, show_text, hide_text, container, focus) {
</span><span class="cx">         link = $(link);
</span><span class="cx">         container = $(container);
</span></span></pre></div>
<a id="trunkjsmasscreatesetspagejs"></a>
<div class="addfile"><h4>Added: trunk/js/mass-create-sets-page.js (0 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/js/mass-create-sets-page.js                                (rev 0)
+++ trunk/js/mass-create-sets-page.js        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+jQuery(function($) {
+        $gp.notices.init();
+        $('#project_id').change(function() {
+                var select = $(this);
+                var project_id = $('option:selected', select).attr('value');
+                if ( !project_id ) {
+                        $('#submit').attr('disabled', 'disabled');
+                        $('#preview').hide();
+                        return;
+                }
+                $gp.notices.notice($gp_mass_create_sets_options.loading);
+                select.attr('disabled', 'disabled');
+                $.ajax({type: &quot;POST&quot;, url: $gp_mass_create_sets_options.url, data: {project_id: project_id}, dataType: 'json',
+                        success: function(data){
+                                select.attr('disabled', '');
+                                $gp.notices.clear();
+                                if (data.added.length || data.removed.length) $('#submit').attr('disabled', '');
+                                var preview = $('#preview');
+                                preview.html('&lt;h3&gt;Preview changes:&lt;/h3&gt;');
+                                var preview_html = '';
+                                preview_html += '&lt;ul&gt;';
+                                function preview_html_for(kind, text) {
+                                        var sets = data[kind];
+                                        var html = '';                                        
+                                        html += '&lt;li&gt;&lt;span class=&quot;'+kind+'&quot;&gt;'+text.replace('{count}', sets.length)+'&lt;/span&gt;';
+                                        if (sets.length) {
+                                                html += '&lt;ul&gt;';
+                                                $.each(sets, function() {
+                                                        html += '&lt;li&gt;'+$gp.esc_html(this.name)+' ('+this.locale+'/'+this.slug+')&lt;/li&gt;';
+                                                });
+                                                html += '&lt;/ul&gt;';
+                                        }
+                                        html += '&lt;/li&gt;';
+                                        return html;
+                                }
+                                preview_html += preview_html_for('added', '{count} set(s) will be added');
+                                preview_html += preview_html_for('removed', '{count} set(s) will be removed');
+                                preview_html += '&lt;/ul&gt;';
+                                preview.append(preview_html);
+                                preview.fadeIn();
+                        },
+                        error: function(xhr, msg, error) {
+                                select.attr('disabled', '');
+                                msg = xhr.responsehtml? 'Error: '+ xhr.responsehtml : 'Error saving the translation!';
+                                $gp.notices.error(msg);
+                        }
+                });                
+        });
+        $('#submit').attr('disabled', 'disabled');
+        $('#preview').hide();
+});
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/js/mass-create-sets-page.js
</span><span class="cx">___________________________________________________________________
</span><span class="cx">Name: svn:eol-style
</span><span class="cx">   + native
</span></span></pre></div>
<a id="trunkjstranslationspagejs"></a>
<div class="modfile"><h4>Modified: trunk/js/translations-page.js (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/js/translations-page.js        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/js/translations-page.js        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -80,4 +80,4 @@
</span><span class="cx">                 window.location = url;
</span><span class="cx">                 return false;
</span><span class="cx">         });
</span><del>-});
</del><span class="cx">\ No newline at end of file
</span><ins>+});
</ins></span></pre></div>
<a id="trunkttest_miscphp"></a>
<div class="modfile"><h4>Modified: trunk/t/test_misc.php (465 => 466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/t/test_misc.php        2010-04-08 14:23:31 UTC (rev 465)
+++ trunk/t/test_misc.php        2010-04-09 15:23:52 UTC (rev 466)
</span><span class="lines">@@ -31,4 +31,12 @@
</span><span class="cx">                 $this-&gt;assertEquals( array( array('baba', 'dyado') ), gp_array_zip( array('baba', 'boom'), array('dyado') ) );
</span><span class="cx">                 $this-&gt;assertEquals( array( array( array('baba'), 'dyado') ), gp_array_zip( array( array('baba'), 'boom'), array('dyado') ) );
</span><span class="cx">         }
</span><ins>+        
+        function test_gp_array_any() {
+                $this-&gt;assertEquals( false, gp_array_any( 'intval', array( 0 ) ) );
+                $this-&gt;assertEquals( false, gp_array_any( returner(false), array( 1, 2, 3, 4 ) ) );
+                $this-&gt;assertEquals( false, gp_array_any( returner(true), array() ) );
+                $this-&gt;assertEquals( true, gp_array_any( returner(true), array( 1, 2, 3, 4 ) ) );
+                $this-&gt;assertEquals( true, gp_array_any( returner('$x', '$x % 2'), array( 1, 2, 3, 4 ) ) );
+        }
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>