remove custom localization stuff

I had a scheme where, as on WinMobile, I could download localization
data based on the local of the device I was on. Saved a lot of
space. Google didn't care about space, and I haven't for a while
either, so it's coming out except for the API that did in-place
translation of UI elements.
This commit is contained in:
Eric House 2022-03-10 11:45:24 -08:00
parent c79137452f
commit 4813eb4689
18 changed files with 35 additions and 1560 deletions

View file

@ -115,6 +115,7 @@ android {
buildConfigField "boolean", "FOR_FDROID", "false"
buildConfigField "boolean", "HAVE_PASSWORD", "false"
buildConfigField "boolean", "NO_NEW_RELAY", "true"
buildConfigField "boolean", "LOCUTILS_ENABLED", "false"
}
xw4GPlay {
@ -394,20 +395,12 @@ clean.dependsOn cleanLocStrings, cleanPrefsWrapper
task myPreBuild(dependsOn: ['mkImages',
'copyLocStrings',
'mkXml',
'mkPrefsWrapper',
'copyStringsXw4D',
'copyStringsXw4DGPlay']) {
}
preBuild.dependsOn myPreBuild
task mkXml(type: Exec) {
workingDir '../'
commandLine './scripts/mk_xml.py', '-o',
"app/src/main/java/org/eehouse/android/xw4/loc/LocIDsData.java",
'-t', "debug"
}
task copyStringsXw4D(type: Exec) {
workingDir './'
environment.put('APPNAME', 'CrossDbg')

View file

@ -156,8 +156,6 @@
/>
<activity android:name="ChatActivity"
/>
<activity android:name=".loc.LocActivity"
/>
<activity android:name=".loc.LocItemEditActivity"
/>

View file

@ -56,7 +56,6 @@ public class PrefsDelegate extends DelegateBase
R.string.key_enable_nbs,
R.string.key_download_path,
R.string.key_thumbsize,
R.string.key_xlations_locale,
R.string.key_default_language,
R.string.key_force_radio,
R.string.key_disable_nag,
@ -269,9 +268,6 @@ public class PrefsDelegate extends DelegateBase
case R.string.key_thumbsize:
DBUtils.clearThumbnails( mActivity );
break;
case R.string.key_xlations_locale:
LocUtils.localeChanged( mActivity, sp.getString( key, null ) );
break;
case R.string.key_default_language:
// forceDictsMatch( sp.getString( key, null ) );
break;

View file

@ -174,14 +174,14 @@ public class UpdateCheckReceiver extends BroadcastReceiver {
}
// Xlations update
JSONArray xlationUpdate = LocUtils.makeForXlationUpdate( context );
if ( null != xlationUpdate ) {
try {
params.put( k_XLATEINFO, xlationUpdate );
} catch ( org.json.JSONException jse ) {
Log.ex( TAG, jse );
}
}
// JSONArray xlationUpdate = LocUtils.makeForXlationUpdate( context );
// if ( null != xlationUpdate ) {
// try {
// params.put( k_XLATEINFO, xlationUpdate );
// } catch ( org.json.JSONException jse ) {
// Log.ex( TAG, jse );
// }
// }
if ( 0 < params.length() ) {
try {
@ -387,17 +387,17 @@ public class UpdateCheckReceiver extends BroadcastReceiver {
}
// translations info
if ( jobj.has( k_XLATEINFO ) ) {
JSONArray data = jobj.getJSONArray( k_XLATEINFO );
int nAdded = LocUtils.addXlations( m_context, data );
if ( 0 < nAdded ) {
gotOne = true;
String msg = LocUtils
.getQuantityString( m_context, R.plurals.new_xlations_fmt,
nAdded, nAdded );
Utils.showToast( m_context, msg );
}
}
// if ( jobj.has( k_XLATEINFO ) ) {
// JSONArray data = jobj.getJSONArray( k_XLATEINFO );
// int nAdded = LocUtils.addXlations( m_context, data );
// if ( 0 < nAdded ) {
// gotOne = true;
// String msg = LocUtils
// .getQuantityString( m_context, R.plurals.new_xlations_fmt,
// nAdded, nAdded );
// Utils.showToast( m_context, msg );
// }
// }
}
} catch ( org.json.JSONException jse ) {
Log.ex( TAG, jse );

View file

@ -44,7 +44,6 @@ public class XWApp extends Application
private static final String TAG = XWApp.class.getSimpleName();
public static final boolean DEBUG_EXP_TIMERS = false;
public static final boolean LOCUTILS_ENABLED = false;
public static final boolean CONTEXT_MENUS_ENABLED = true;
public static final boolean OFFER_DUALPANE = false;

View file

@ -452,16 +452,6 @@ public class XWPrefs {
setPrefsString( context, keyID, TextUtils.join( "\n", value ) );
}
public static String getFakeLocale( Context context )
{
return getPrefsString( context, R.string.key_xlations_locale );
}
public static boolean getXlationEnabled( Context context )
{
return getPrefsBoolean( context, R.string.key_xlations_enabled, false );
}
public static void setHaveCheckedUpgrades( Context context, boolean haveChecked )
{
setPrefsBoolean( context, key_checked_upgrades, haveChecked );

View file

@ -1,34 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.os.Bundle;
import org.eehouse.android.xw4.XWActivity;
public class LocActivity extends XWActivity {
@Override
protected void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState,
new LocDelegate( this, savedInstanceState ) );
} // onCreate
}

View file

@ -1,130 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import org.eehouse.android.xw4.Delegator;
import org.eehouse.android.xw4.ListDelegateBase;
import org.eehouse.android.xw4.Log;
import org.eehouse.android.xw4.R;
public class LocDelegate extends ListDelegateBase
implements View.OnClickListener,
OnItemSelectedListener {
private static final String TAG = LocDelegate.class.getSimpleName();
private Activity m_activity;
private LocListAdapter m_adapter;
private EditText m_searchField;
private Spinner m_filterBy;
private ImageButton m_searchButton;
private LocSearcher m_searcher;
private String m_curSearch;
private LocListItem m_lastItem;
protected LocDelegate( Delegator delegator, Bundle savedInstanceState )
{
super( delegator, savedInstanceState, R.layout.loc_main );
m_activity = delegator.getActivity();
}
@Override
protected boolean handleBackPressed()
{
LocUtils.saveLocalData( m_activity );
return false;
}
@Override
public void onClick( View view )
{
if ( view instanceof LocListItem ) {
m_lastItem = (LocListItem)view;
LocItemEditDelegate.launch( m_activity, m_lastItem.getKey() );
} else if ( view == m_searchButton ) {
String newText = m_searchField.getText().toString();
if ( null == m_curSearch || ! m_curSearch.equals( newText ) ) {
m_curSearch = newText;
m_searcher.start( newText ); // synchronous for now
makeNewAdapter();
}
}
}
protected void onWindowFocusChanged( boolean hasFocus )
{
if ( hasFocus && null != m_lastItem ) {
Log.i( TAG, "updating LocListItem instance %H", m_lastItem );
m_lastItem.update();
m_lastItem = null;
}
}
private void makeNewAdapter()
{
ListView listview = getListView();
m_adapter = new LocListAdapter( m_activity, listview, m_searcher, this );
setListAdapter( m_adapter );
}
@Override
protected void init( Bundle savedInstanceState )
{
m_searchButton = (ImageButton)findViewById( R.id.loc_search_button );
m_searchButton.setOnClickListener( this );
m_searchField = (EditText)findViewById( R.id.loc_search_field );
m_filterBy = (Spinner)findViewById( R.id.filters );
m_filterBy.setOnItemSelectedListener( this );
TextView view = (TextView)findViewById( R.id.other_lang );
view.setText( LocUtils.getCurLocaleName( m_activity ) );
LocSearcher.Pair[] pairs = LocUtils.makePairs( m_activity );
String contextName = getIntent().getStringExtra( LocUtils.CONTEXT_NAME );
m_searcher = new LocSearcher( m_activity, pairs, contextName );
makeNewAdapter();
}
//////////////////////////////////////////////////
// AdapterView.OnItemSelectedListener interface
//////////////////////////////////////////////////
@Override
public void onItemSelected( AdapterView<?> parent, View view,
int position, long id )
{
m_searcher.start( position );
makeNewAdapter();
}
@Override
public void onNothingSelected( AdapterView<?> parent ) {}
}

View file

@ -1,63 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.content.Context;
import org.eehouse.android.xw4.Log;
import java.util.HashMap;
public class LocIDs extends LocIDsData {
private static final String TAG = LocIDs.class.getSimpleName();
private static String[] s_keys;
private static HashMap<String, Integer> S_MAP = null;
protected static int getID( Context context, String key )
{
int result = LocIDsData.NOT_FOUND;
if ( null != key && getS_MAP(context).containsKey( key ) ) {
// Assert.assertNotNull( LocIDsData.S_MAP );
Log.w( TAG, "calling get with key %s", key );
result = getS_MAP( context ).get( key ); // NPE
}
return result;
}
protected static int size()
{
return S_IDS.length;
}
protected static HashMap<String, Integer> getS_MAP( Context context )
{
if ( null == S_MAP ) {
S_MAP = new HashMap<>(S_IDS.length);
for ( int id : S_IDS ) {
String str = context.getString( id );
S_MAP.put( str, id );
}
LocIDsData.checkStrings( context );
}
return S_MAP;
}
}

View file

@ -1,38 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.os.Bundle;
import org.eehouse.android.xw4.XWActivity;
public class LocItemEditActivity extends XWActivity {
private LocItemEditDelegate m_dlgt;
@Override
protected void onCreate( Bundle savedInstanceState )
{
m_dlgt = new LocItemEditDelegate( this, savedInstanceState );
super.onCreate( savedInstanceState, m_dlgt );
} // onCreate
}

View file

@ -1,224 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextWatcher;
import android.text.style.BackgroundColorSpan;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import org.eehouse.android.xw4.DelegateBase;
import org.eehouse.android.xw4.Delegator;
import org.eehouse.android.xw4.R;
import org.eehouse.android.xw4.Utils;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LocItemEditDelegate extends DelegateBase implements TextWatcher {
private static final String KEY = "KEY";
private Activity m_activity;
private String m_key;
private HashSet<String> m_keyFmts;
private EditText m_edit;
private boolean m_haveBlessed;
private static Pattern s_patFormat = Pattern.compile( LocUtils.RES_FORMAT );
protected LocItemEditDelegate( Delegator delegator, Bundle savedInstanceState )
{
super( delegator, savedInstanceState, R.layout.loc_item_edit,
R.menu.loc_item_menu );
m_activity = delegator.getActivity();
}
@Override
protected void init( Bundle savedInstanceState )
{
String key = getIntent().getStringExtra( KEY );
m_key = key;
TextView view = (TextView)findViewById( R.id.english_view );
m_keyFmts = getFmtSet( key, view );
if ( 0 < m_keyFmts.size() ) {
makeNotAgainBuilder( R.string.not_again_fmt_expl,
R.string.key_na_fmt_expl )
.show();
}
view = (TextView)findViewById( R.id.xlated_view_blessed );
String blessed = LocUtils.getBlessedXlation( m_activity, key, true );
m_haveBlessed = null != blessed && 0 < blessed.length();
view.setText( blessed );
m_edit = (EditText)findViewById( R.id.xlated_view_local );
m_edit.addTextChangedListener( this );
m_edit.setTextColor( LocListItem.LOCAL_COLOR );
m_edit.setText( LocUtils.getLocalXlation( m_activity, key, true ) );
view = (TextView)findViewById( R.id.english_label );
view.setText( LocUtils.getString( m_activity, R.string.lang_name_english ) );
String langName = LocUtils.getCurLocaleName( m_activity );
view = (TextView)findViewById( R.id.blessed_label );
view.setText( LocUtils.getString( m_activity, R.string.loc_lang_blessed,
langName ) );
view = (TextView)findViewById( R.id.local_label );
view.setText( LocUtils.getString( m_activity, R.string.loc_lang_local,
langName ) );
}
@Override
protected void onPause()
{
// Save any local translation
LocUtils.setXlation( m_activity, m_key, m_edit.getText() );
super.onPause();
}
@Override
public boolean onPrepareOptionsMenu( Menu menu )
{
CharSequence editTxt = m_edit.getText();
boolean haveTxt = null != editTxt && 0 < editTxt.length();
Utils.setItemVisible( menu, R.id.loc_item_clear, haveTxt );
Utils.setItemVisible( menu, R.id.loc_item_check, haveTxt );
Utils.setItemVisible( menu, R.id.loc_item_copy_eng, !haveTxt );
Utils.setItemVisible( menu, R.id.loc_item_copy_bless,
m_haveBlessed && !haveTxt );
return true;
}
@Override
public boolean onOptionsItemSelected( MenuItem item )
{
String newText = null;
int id = item.getItemId();
switch ( id ) {
case R.id.loc_item_clear:
newText = "";
break;
case R.id.loc_item_check:
checkLocal();
break;
case R.id.loc_item_copy_eng:
newText = m_key;
break;
case R.id.loc_item_copy_bless:
newText = LocUtils.getBlessedXlation( m_activity, m_key, true );
break;
}
if ( null != newText ) {
m_edit.setText( newText );
invalidateOptionsMenuIf();
}
return true;
}
// return true to prevent exiting
protected boolean backPressed()
{
return !checkLocal();
}
// Check that syntax is legal, and alert if not
private boolean checkLocal()
{
boolean ok = true;
CharSequence cs = m_edit.getText();
if ( null != cs && 0 < cs.length() ) {
ok = m_keyFmts.equals( getFmtSet( cs.toString(), null ) );
if ( !ok ) {
makeOkOnlyBuilder( R.string.loc_fmts_mismatch ).show();
}
}
return ok;
}
// Performance hack: set up highlighting of format specifiers since we're
// searching for them anyway.
private HashSet<String> getFmtSet( String txt, TextView owner )
{
HashSet<String> fmts = new HashSet<>();
Spannable spanText = null; // null unless used
Matcher matcher = s_patFormat.matcher( txt );
while ( matcher.find() ) {
int start = matcher.start();
int end = matcher.end();
fmts.add( txt.substring( start, end ) );
if ( null == owner ) {
continue;
}
if ( null == spanText ) {
spanText = new SpannableString( txt );
}
spanText.setSpan( new BackgroundColorSpan(Color.BLUE), start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
}
if ( null != owner ) {
if ( null != spanText ) {
owner.setText( spanText );
} else {
owner.setText( txt );
}
}
return fmts;
}
//////////////////////////////////////////////////////////////////////
// TextWatcher interface
//////////////////////////////////////////////////////////////////////
public void afterTextChanged( Editable s )
{
invalidateOptionsMenuIf();
}
public void beforeTextChanged( CharSequence s, int start, int count, int after ){}
public void onTextChanged( CharSequence s, int start, int before, int count ){}
protected static void launch( Context context, String key )
{
Intent intent = new Intent( context, LocItemEditActivity.class );
intent.putExtra( KEY, key );
context.startActivity( intent );
}
}

View file

@ -1,64 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2009 - 2014 by Eric House (xwords@eehouse.org). All
* rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import org.eehouse.android.xw4.XWListAdapter;
public class LocListAdapter extends XWListAdapter {
private static final String TAG = LocListAdapter.class.getSimpleName();
private Context m_context;
private ListView m_listView;
private LocSearcher m_searcher;
private View.OnClickListener m_listener;
protected LocListAdapter( Context context, ListView listView,
LocSearcher searcher,
View.OnClickListener listener )
{
m_context = context;
m_listView = listView;
m_searcher = searcher;
m_listener = listener;
}
@Override
public int getCount()
{
int count = m_searcher.matchSize();
// DbgUtils.logf(" LocListAdapter.getCount() => %d", count );
return count;
}
public View getView( int position, View convertView, ViewGroup parent )
{
// DbgUtils.logf( "LocListAdapter.getView(position=%d)", position );
LocSearcher.Pair pair = m_searcher.getNthMatch( position );
View view = LocListItem.create( m_context, pair, position );
view.setOnClickListener( m_listener );
return view;
}
}

View file

@ -1,98 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.eehouse.android.xw4.R;
public class LocListItem extends LinearLayout {
protected static final int LOCAL_COLOR = Color.argb( 0xFF, 0x7f, 0x00, 0x00 );
private LocSearcher.Pair m_pair;
private int m_position;
private TextView m_xlated;
public LocListItem( Context cx, AttributeSet as )
{
super( cx, as );
}
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
m_xlated = (TextView)findViewById( R.id.xlated_view );
}
protected void update()
{
setXlated();
}
protected String getKey()
{
return m_pair.getKey();
}
private void setEnglish()
{
TextView tv = (TextView)findViewById( R.id.english_view );
tv.setText( getKey() );
}
private void setXlated()
{
boolean local = false;
String key = getKey();
String xlation = LocUtils.getLocalXlation( getContext(), key, true );
if ( null != xlation ) {
local = true;
} else {
xlation = LocUtils.getBlessedXlation( getContext(), key, true );
}
m_pair.setXlation( xlation );
m_xlated.setText( xlation );
if ( local ) {
m_xlated.setTextColor( LOCAL_COLOR );
}
}
protected static LocListItem create( Context context,
LocSearcher.Pair pair,
int position )
{
LocListItem result =
(LocListItem)LocUtils.inflate( context, R.layout.loc_list_item );
result.m_pair = pair;
result.m_position = position;
result.setEnglish();
result.setXlated();
return result;
}
}

View file

@ -1,184 +0,0 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4.loc;
import android.content.Context;
import org.eehouse.android.xw4.Log;
import java.util.ArrayList;
/** This class provides filtering on the list of translations, first by
* built-in filters like "recent menu", and then by a search string. Either
* can be changed independently of the other.
*
*/
public class LocSearcher {
private static final String TAG = LocSearcher.class.getSimpleName();
private String m_contextName;
private interface FilterFunc {
public boolean passes( Context context, Pair pair );
}
// keep in sync with loc_filters in common_rsrc.xml
protected static enum SHOW_BYS {
LOC_FILTERS_ALL
,LOC_FILTERS_SCREEN
,LOC_FILTERS_MENU
,LOC_FILTERS_MODIFIED
};
private SHOW_BYS m_showBy;
public static class Pair {
public Pair( String key, String eng, String xlation ) {
m_key = key;
m_english = eng;
m_xlation = xlation;
}
public boolean matches( String term )
{
return m_english.contains( term ) ||
(null != m_xlation && m_xlation.contains( term ) );
}
public void setXlation( String xlation )
{
m_xlation = xlation;
}
public String getKey() { return m_key; }
private String m_key;
private String m_english;
private String m_xlation;
}
private Context m_context;
private Pair[] m_pairs;
private Pair[] m_filteredPairs;
private Pair[] m_matchingPairs;
private String m_lastTerm;
public LocSearcher( Context context, Pair pairs[], String contextName )
{
m_pairs = m_filteredPairs = m_matchingPairs = pairs;
m_context = context;
m_contextName = contextName;
}
protected void start( int position )
{
if ( 0 <= position && position < SHOW_BYS.values().length ) {
SHOW_BYS showBy = SHOW_BYS.values()[position];
if ( m_showBy != showBy ) {
m_showBy = showBy;
if ( SHOW_BYS.LOC_FILTERS_ALL == showBy ) {
m_filteredPairs = m_pairs;
} else {
FilterFunc proc = null;
switch ( showBy ) {
case LOC_FILTERS_SCREEN:
proc = new ScreenFilter( m_contextName );
break;
case LOC_FILTERS_MENU:
proc = s_menuProc;
break;
case LOC_FILTERS_MODIFIED:
proc = s_modifiedProc;
break;
}
ArrayList<Pair> matches = new ArrayList<>();
for ( Pair pair : m_pairs ) {
if ( proc.passes( m_context, pair ) ) {
matches.add( pair );
}
}
m_filteredPairs = m_matchingPairs =
matches.toArray( new Pair[matches.size()] );
}
String term = m_lastTerm;
m_lastTerm = null;
start( term );
}
}
}
protected void start( String term )
{
if ( null == term || 0 == term.length() ) {
m_matchingPairs = m_filteredPairs;
} else {
Pair[] usePairs = null != m_lastTerm && term.contains(m_lastTerm)
? m_matchingPairs : m_filteredPairs;
Log.i( TAG, "start: searching %d pairs", usePairs.length );
ArrayList<Pair> matches = new ArrayList<>();
for ( Pair pair : usePairs ) {
if ( pair.matches( term ) ) {
matches.add( pair );
}
}
m_matchingPairs = matches.toArray( new Pair[matches.size()] );
}
m_lastTerm = term;
}
protected Pair getNthMatch( int nn )
{
return m_matchingPairs[nn];
}
protected int matchSize()
{
return m_matchingPairs.length;
}
private static FilterFunc s_modifiedProc = new FilterFunc() {
public boolean passes( Context context, Pair pair ) {
return null !=
LocUtils.getLocalXlation( context, pair.getKey(), true );
}
};
private static FilterFunc s_menuProc = new FilterFunc() {
public boolean passes( Context context, Pair pair ) {
return LocUtils.inLatestMenu( pair.getKey() );
}
};
private static class ScreenFilter implements FilterFunc {
private String m_contextName;
public ScreenFilter( String contextName )
{
m_contextName = contextName;
}
public boolean passes( Context context, Pair pair )
{
return LocUtils.inLatestScreen( pair.getKey(), m_contextName );
}
}
}

View file

@ -22,95 +22,38 @@ package org.eehouse.android.xw4.loc;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.res.Resources;
import android.preference.DialogPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import org.eehouse.android.xw4.Assert;
import org.eehouse.android.xw4.DBUtils;
import org.eehouse.android.xw4.DbgUtils;
import org.eehouse.android.xw4.Log;
import org.eehouse.android.xw4.BuildConfig;
import org.eehouse.android.xw4.R;
import org.eehouse.android.xw4.Utils;
import org.eehouse.android.xw4.XWApp;
import org.eehouse.android.xw4.XWPrefs;
import org.json.JSONArray;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IllegalFormatConversionException;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LocUtils {
private static final String TAG = LocUtils.class.getSimpleName();
public static final String CONTEXT_NAME = "CONTEXT_NAME";
protected static final String RES_FORMAT = "%[\\d]\\$[ds]";
private static final int FMT_LEN = 4;
private static final String k_LOCALE = "locale";
private static final String k_XLATEVERS = "xlatevers";
private static Map<String, String> s_xlationsLocal = null;
private static Map<String, String> s_xlationsBlessed = null;
private static HashMap<Integer, String> s_idsToKeys = null;
private static Boolean s_enabled = null;
private static String s_curLocale;
private static String s_curLang;
private static WeakReference<Menu> s_latestMenuRef;
private static Map<WeakReference<Menu>, HashSet<String> > s_menuSets
= new HashMap<WeakReference<Menu>, HashSet<String> >();
private static Map<String, HashSet<String> > s_contextSets
= new HashMap<String, HashSet<String> >();
private static Map<String, String> s_langMap = null;
public static void localeChanged( Context context, String newLocale )
{
saveLocalData( context );
s_curLocale = newLocale;
s_curLang = splitLocale( newLocale );
s_xlationsLocal = null;
s_xlationsBlessed = null;
s_enabled = null;
}
public static View inflate( Context context, int resID )
{
LayoutInflater factory = LayoutInflater.from( context );
View view = factory.inflate( resID, null );
xlateView( context, view );
return view;
return factory.inflate( resID, null );
}
public static void xlateTitle( Activity activity )
{
String title = activity.getTitle().toString();
String xlated = xlateString( activity, title );
if ( ! title.equals(xlated) ) {
activity.setTitle( xlated );
}
}
public static String xlateLang( Context context, String lang )
@ -153,32 +96,14 @@ public class LocUtils {
public static void xlateView( Activity activity )
{
xlateView( activity, Utils.getContentView( activity ) );
}
public static void xlatePreferences( PreferenceActivity activity )
{
if ( XWApp.LOCUTILS_ENABLED ) {
xlatePreferences( activity, activity.getPreferenceScreen(), 0 );
}
}
public static void xlateView( Context context, View view )
{
// DbgUtils.logf( "xlateView(%s, %s)", context.getClass().getName(),
// view.getClass().getName() );
if ( XWApp.LOCUTILS_ENABLED ) {
xlateView( context, context.getClass().getSimpleName(), view, 0 );
}
}
public static void xlateMenu( Activity activity, Menu menu )
{
if ( XWApp.LOCUTILS_ENABLED ) {
pareMenus();
xlateMenu( activity, new WeakReference<>( menu ), menu, 0 );
}
}
private static String xlateString( Context context, CharSequence str )
@ -193,35 +118,17 @@ public class LocUtils {
private static String xlateString( Context context, String str,
boolean associate )
{
if ( LocIDs.getS_MAP( context ).containsKey( str ) ) {
if ( associate ) {
associateContextString( context, str );
}
String xlation = getXlation( context, str, true );
if ( null != xlation ) {
str = xlation;
}
}
return str;
}
public static String xlateString( Context context, String str )
{
if ( XWApp.LOCUTILS_ENABLED ) {
if ( BuildConfig.LOCUTILS_ENABLED ) {
str = xlateString( context, str, true );
}
return str;
}
public static CharSequence[] xlateStrings( Context context, CharSequence[] strs )
{
CharSequence[] result = new CharSequence[strs.length];
for ( int ii = 0; ii < strs.length; ++ii ) {
result[ii] = xlateString( context, strs[ii].toString() );
}
return result;
}
public static String[] getStringArray( Context context, int resID )
{
Resources res = context.getResources();
@ -240,65 +147,32 @@ public class LocUtils {
public static String getString( Context context, int id )
{
return getString( context, true, id );
return context.getString( id );
}
public static String getStringOrNull( int id )
{
String result = null;
if ( 0 != id ) {
Context context = XWApp.getContext();
result = getString( context, true, id );
result = getString( XWApp.getContext(), true, id );
}
return result;
}
public static String getString( Context context, boolean canUseDB, int id )
{
String result = null;
if ( XWApp.LOCUTILS_ENABLED ) {
String key = keyForID( context, id );
if ( null != key ) {
associateContextString( context, key );
result = getXlation( context, key, canUseDB );
}
}
if ( null == result ) {
result = context.getString( id );
}
return result;
return getString( context, id );
}
public static String getString( Context context, int id, Object... params )
{
Assert.assertNotNull( params );
String result;
if ( XWApp.LOCUTILS_ENABLED ) {
result = getString( context, id );
if ( null != result ) {
try {
result = String.format( result, params );
} catch ( IllegalFormatConversionException fce ) {
dropXLations( context );
result = getString( context, id, params );
}
}
} else {
result = context.getString( id, params );
}
return result;
return context.getString( id, params );
}
public static String getQuantityString( Context context, int id,
int quantity )
{
if ( XWApp.LOCUTILS_ENABLED ) {
Log.w( TAG, "getQuantityString(%d): punting on locutils stuff for"
+ " now. FIXME", quantity );
}
String result = context.getResources().getQuantityString( id, quantity );
return result;
}
@ -306,239 +180,11 @@ public class LocUtils {
public static String getQuantityString( Context context, int id,
int quantity, Object... params )
{
if ( XWApp.LOCUTILS_ENABLED ) {
Log.w( TAG, "getQuantityString(%d): punting on locutils stuff for"
+ " now. FIXME", quantity );
}
String result = context.getResources()
.getQuantityString( id, quantity, params );
return result;
}
public static void setXlation( Context context, String key, CharSequence txt )
{
if ( XWApp.LOCUTILS_ENABLED ) {
loadXlations( context );
if ( null == txt || 0 == txt.length() ) {
s_xlationsLocal.remove( key );
} else {
s_xlationsLocal.put( key, txt.toString() );
}
}
}
protected static String getLocalXlation( Context context, String key,
boolean canUseDB )
{
String result = null;
if ( XWApp.LOCUTILS_ENABLED ) {
if ( canUseDB ) {
loadXlations( context );
}
if ( null != s_xlationsLocal ) {
result = s_xlationsLocal.get( key );
}
}
return result;
}
protected static String getBlessedXlation( Context context, String key,
boolean canUseDB )
{
String result = null;
if ( XWApp.LOCUTILS_ENABLED ) {
if ( canUseDB ) {
loadXlations( context );
}
if ( null != s_xlationsBlessed ) {
result = s_xlationsBlessed.get( key );
}
}
return result;
}
protected static String getXlation( Context context, String key,
boolean canUseDB )
{
String result = null;
result = getLocalXlation( context, key, canUseDB );
if ( null == result ) {
result = getBlessedXlation( context, key, canUseDB );
}
return result;
}
public static void saveLocalData( Context context )
{
if ( XWApp.LOCUTILS_ENABLED ) {
DBUtils.saveXlations( context, getCurLocale( context ),
s_xlationsLocal, false );
}
}
public static JSONArray makeForXlationUpdate( Context context )
{
JSONArray result = null;
if ( XWApp.LOCUTILS_ENABLED ) {
String locale = getCurLocale( context );
String fake = XWPrefs.getFakeLocale( context );
result = new JSONArray().put( entryForLocale( context, locale ) );
if ( null != fake && 0 < fake.length() && ! fake.equals(locale) ) {
result.put( entryForLocale( context, fake ) );
}
}
return result;
}
private static JSONObject entryForLocale( Context context, String locale )
{
JSONObject result = null;
if ( XWApp.LOCUTILS_ENABLED ) {
try {
String version =
DBUtils.getStringFor( context, localeKey(locale), "0" );
result = new JSONObject()
.put( k_LOCALE, locale )
.put( k_XLATEVERS, version );
} catch ( org.json.JSONException jse ) {
Log.ex( TAG, jse );
}
}
return result;
}
private static String localeKey( String locale )
{
return String.format( "%s:%s", k_XLATEVERS, locale );
}
private static final String k_OLD = "old";
private static final String k_NEW = "new";
private static final String k_PAIRS = "pairs";
public static int addXlations( Context context, JSONArray data )
{
int nAdded = 0;
if ( XWApp.LOCUTILS_ENABLED ) {
try {
int nLocales = data.length();
for ( int ii = 0; ii < nLocales; ++ii ) {
JSONObject entry = data.getJSONObject( ii );
String locale = entry.getString( k_LOCALE );
String newVersion = entry.getString( k_NEW );
JSONArray pairs = entry.getJSONArray( k_PAIRS );
Log.i( TAG, "addXlations: locale %s: got pairs of len %d,"
+ " version %s", locale,
pairs.length(), newVersion );
int len = pairs.length();
Map<String,String> newXlations = new HashMap<>( len );
for ( int jj = 0; jj < len; ++jj ) {
JSONObject pair = pairs.getJSONObject( jj );
int id = pair.getInt( "id" );
String key = context.getString( id );
Assert.assertNotNull( key );
String txt = pair.getString( "loc" );
txt = replaceEscaped( txt );
newXlations.put( key, txt );
}
DBUtils.saveXlations( context, locale, newXlations, true );
DBUtils.setStringFor( context, localeKey(locale), newVersion );
nAdded += len;
}
s_xlationsBlessed = null;
loadXlations( context );
} catch ( org.json.JSONException jse ) {
Log.ex( TAG, jse );
}
}
return nAdded;
}
protected static LocSearcher.Pair[] makePairs( Context context )
{
loadXlations( context );
Map<String,Integer> map = LocIDs.getS_MAP( context );
int siz = map.size();
LocSearcher.Pair[] result = new LocSearcher.Pair[siz];
Iterator<String> iter = map.keySet().iterator();
for ( int ii = 0; iter.hasNext(); ++ii ) {
String key = iter.next();
String english = context.getString( map.get( key ) );
Assert.assertTrue( english.equals( key ) );
String xlation = getXlation( context, key, true );
result[ii] = new LocSearcher.Pair( key, english, xlation );
}
return result;
}
private static void xlateMenu( final Activity activity,
final WeakReference<Menu> rootRef,
Menu menu, int depth )
{
int count = menu.size();
for ( int ii = 0; ii < count; ++ii ) {
MenuItem item = menu.getItem( ii );
CharSequence ts = item.getTitle();
if ( null != ts ) {
String title = ts.toString();
if ( LocIDs.getS_MAP( activity ).containsKey(title) ) {
associateMenuString( rootRef, title );
title = xlateString( activity, title, false );
item.setTitle( title );
}
}
if ( item.hasSubMenu() ) {
xlateMenu( activity, rootRef, item.getSubMenu(), 1 + depth );
}
}
// The caller is loc-aware, so add our menu -- at the top level!
if ( 0 == depth && XWPrefs.getXlationEnabled( activity ) ) {
String title = activity.getString( R.string.loc_menu_xlate );
associateMenuString( rootRef, title );
String xlated = getXlation( activity, title, true );
if ( null != xlated ) {
title = xlated;
}
menu.add( title )
.setOnMenuItemClickListener( new OnMenuItemClickListener() {
public boolean onMenuItemClick( MenuItem item ) {
s_latestMenuRef = rootRef;
Intent intent =
new Intent( activity, LocActivity.class );
intent.putExtra( CONTEXT_NAME,
activity.getClass().getName() );
activity.startActivity( intent );
return true;
}
});
}
}
private static void pareMenus()
{
DbgUtils.assertOnUIThread();
Set<WeakReference<Menu>> keys = s_menuSets.keySet();
Iterator<WeakReference<Menu>> iter = keys.iterator();
while ( iter.hasNext() ) {
WeakReference<Menu> ref = iter.next();
if ( null == ref.get() ) {
iter.remove();
}
}
}
protected static String getCurLocaleName( Context context )
{
String locale_code = getCurLocale( context );
@ -550,18 +196,11 @@ public class LocUtils {
public static String getCurLangCode( Context context )
{
if ( null == s_curLang ) {
String lang = null;
String locale = XWPrefs.getFakeLocale( context );
if ( null != locale && 0 < locale.length() ) {
lang = splitLocale( locale );
}
if ( null == lang ) {
lang = Locale.getDefault().getLanguage();
// sometimes I get "en-us" in this case, i.e. the locale's
// there too. Strip it.
if ( lang.contains( "-" ) ) {
lang = TextUtils.split(lang, "-")[0];
}
String lang = Locale.getDefault().getLanguage();
// sometimes I get "en-us" in this case, i.e. the locale's there
// too. Strip it.
if ( lang.contains( "-" ) ) {
lang = TextUtils.split(lang, "-")[0];
}
s_curLang = lang;
}
@ -571,308 +210,18 @@ public class LocUtils {
public static String getCurLocale( Context context )
{
if ( null == s_curLocale ) {
String locale = XWPrefs.getFakeLocale( context );
if ( null == locale || 0 == locale.length() ) {
locale = Locale.getDefault().toString();
}
s_curLocale = locale;
s_curLocale = Locale.getDefault().toString();
}
return s_curLocale;
}
private static void loadXlations( Context context )
{
if ( null == s_xlationsLocal || null == s_xlationsBlessed ) {
Object[] asObjs =
DBUtils.getXlations( context, getCurLocale( context ) );
s_xlationsLocal = (Map<String,String>)asObjs[0];
s_xlationsBlessed = (Map<String,String>)asObjs[1];
Log.i( TAG, "loadXlations: got %d local strings, %d blessed strings",
s_xlationsLocal.size(), s_xlationsBlessed.size() );
}
}
private static String keyForID( Context context, int id )
{
if ( null == s_idsToKeys ) {
Map<String,Integer> map = LocIDs.getS_MAP( context );
HashMap<Integer, String> idsToKeys = new HashMap<>( map.size() );
Iterator<String> iter = map.keySet().iterator();
while ( iter.hasNext() ) {
String key = iter.next();
idsToKeys.put( map.get( key ), key );
}
s_idsToKeys = idsToKeys;
}
return s_idsToKeys.get( id );
}
private static void xlateView( Context context, String contextName,
View view, int depth )
{
// DbgUtils.logf( "xlateView(depth=%d, view=%s, canRecurse=%b)", depth,
// view.getClass().getName(), view instanceof ViewGroup );
if ( view instanceof Button ) {
Button button = (Button)view;
String str = xlateAndStore( context, button.getText() );
if ( null != str ) {
button.setText( str );
}
} else if ( view instanceof TextView ) {
TextView tv = (TextView)view;
String str = xlateAndStore( context, tv.getText() );
if ( null != str ) {
tv.setText( str );
}
} else if ( view instanceof Spinner ) {
Spinner sp = (Spinner)view;
String str = xlateAndStore( context, sp.getPrompt() );
if ( null != str ) {
sp.setPrompt( str );
}
SpinnerAdapter adapter = sp.getAdapter();
if ( null != adapter ) {
sp.setAdapter( new XlatingSpinnerAdapter( context, adapter ) );
}
}
// A Spinner, for instance, ISA ViewGroup, so this is a separate test.
if ( view instanceof ViewGroup ) {
ViewGroup asGroup = (ViewGroup)view;
int count = asGroup.getChildCount();
for ( int ii = 0; ii < count; ++ii ) {
View child = asGroup.getChildAt( ii );
xlateView( context, contextName, child, depth + 1 );
}
}
}
public static void xlatePreferences( Context context, Preference pref,
int depth )
{
// DbgUtils.logf( "xlatePreferences(depth=%d, view=%s, canRecurse=%b)", depth,
// pref.getClass().getName(), pref instanceof PreferenceGroup );
String str = xlateString( context, pref.getSummary() );
if ( null != str ) {
pref.setSummary( str );
}
str = xlateString( context, pref.getTitle() );
if ( null != str ) {
pref.setTitle( str );
}
if ( pref instanceof DialogPreference ) {
DialogPreference dp = (DialogPreference)pref;
if ( null != (str = xlateString( context, dp.getDialogMessage()))) {
dp.setDialogMessage( str );
}
if ( null != (str = xlateString( context, dp.getDialogTitle()))) {
dp.setDialogTitle( str );
}
if ( null != (str = xlateString( context, dp.getNegativeButtonText()))) {
dp.setNegativeButtonText( str );
}
if ( null != (str = xlateString( context, dp.getPositiveButtonText()))) {
dp.setPositiveButtonText( str );
}
// ListPreference isa DialogPreference
if ( dp instanceof ListPreference ) {
ListPreference lp = (ListPreference) dp;
CharSequence[] entries = lp.getEntries();
if ( null != entries ) {
CharSequence[] newEntries = xlateStrings( context, entries );
lp.setEntries( newEntries );
}
}
}
if ( pref instanceof PreferenceGroup ) {
PreferenceGroup group = (PreferenceGroup)pref;
int count = group.getPreferenceCount();
for ( int ii = 0; ii < count; ++ii ) {
xlatePreferences( context, group.getPreference(ii), 1 + depth );
}
}
}
public static boolean inLatestMenu( String key )
{
boolean result = false;
if ( null != s_latestMenuRef ) {
HashSet<String> keys = s_menuSets.get( s_latestMenuRef );
if ( null != keys ) {
result = keys.contains( key );
}
}
return result;
}
public static boolean inLatestScreen( String key, String contextName )
{
boolean result = false;
HashSet<String> keys = s_contextSets.get( contextName );
if ( null != keys ) {
result = keys.contains( key );
}
return result;
}
private static String xlateAndStore( Context context, CharSequence cs )
{
String result = null;
if ( null == cs ) {
// DbgUtils.logf( "xlateAndStore: cs null" );
} else if ( 0 == cs.length() ) {
Assert.assertTrue( 0 == cs.toString().length() );
// DbgUtils.logf( "xlateAndStore: cs 0 len" );
} else {
String key = cs.toString();
// DbgUtils.logf( "xlateAndStore: key=%s", key );
result = xlateString( context, key );
if ( null != result ) {
associateContextString( context, key );
}
}
return result;
}
private static void dropXLations( Context context )
{
s_xlationsBlessed = null;
s_idsToKeys = null;
String locale = getCurLocale( context );
String msg = String.format( "Dropping bad translations for %s", locale );
Utils.showToast( context, msg );
Log.w( TAG, msg );
DBUtils.dropXLations( context, locale );
DBUtils.setStringFor( context, localeKey(locale), "" );
}
// Add key (english string) to the hashset associated with this menu
private static void associateMenuString( WeakReference<Menu> ref, String key )
{
HashSet<String> keys = s_menuSets.get( ref );
if ( null == keys ) {
keys = new HashSet<>();
s_menuSets.put( ref, keys );
}
keys.add( key );
}
private static void associateContextString( Context context, final String key )
{
associateContextString( context.getClass().getName(), key );
}
private static void associateContextString( String contextName, final String key )
{
HashSet<String> keys = s_contextSets.get( contextName );
if ( null == keys ) {
keys = new HashSet<>();
s_contextSets.put( contextName, keys );
// DbgUtils.logf( "adding keys hash to %s", contextName );
}
keys.add( key );
// DbgUtils.logf( "associated with context %s string '%s'", contextName, key );
}
private static Pattern s_patUnicode = Pattern.compile("(\\\\[Uu][0-9a-fA-F]{4})");
private static Pattern s_patCr = Pattern.compile("\\\\n");
private static String replaceEscaped( String txt )
{
// String orig = txt;
// Swap unicode escapes for real chars
Matcher matcher = s_patUnicode.matcher( txt );
StringBuffer sb = new StringBuffer();
while ( matcher.find() ) {
int start = matcher.start();
int end = matcher.end();
String match = txt.substring( start, end );
char ch = (char)Integer.parseInt( match.substring(2), 16 );
matcher.appendReplacement( sb, String.valueOf(ch) );
}
matcher.appendTail(sb);
txt = sb.toString();
// Swap in real carriage returns
txt = s_patCr.matcher( txt ).replaceAll( "\n" );
// if ( ! orig.equals( txt ) ) {
// DbgUtils.logf( "replaceEscaped: <<%s>> -> <<%s>>", orig, txt );
// }
return txt;
}
private static String splitLocale( String locale )
{
String result = null;
String[] tuple = TextUtils.split( locale, "_" );
if ( null != tuple && 2 == tuple.length ) {
result = tuple[0];
}
return result;
}
public static AlertDialog.Builder makeAlertBuilder( Context context )
{
return new AlertBuilder( context );
return new AlertDialog.Builder( context );
}
private static class AlertBuilder extends AlertDialog.Builder {
Context m_context;
private AlertBuilder( Context context )
{
super( context );
m_context = context;
}
@Override
public AlertDialog.Builder setTitle( int id )
{
if ( 0 != id ) {
String str = getString( m_context, id );
setTitle( str );
}
return this;
}
public AlertDialog.Builder setMessage( int textId )
{
String str = getString( m_context, textId );
return setMessage( str );
}
@Override
public AlertDialog.Builder setPositiveButton( int textId,
OnClickListener listener )
{
String str = getString( m_context, textId );
return setPositiveButton( str, listener );
}
@Override
public AlertDialog.Builder setNeutralButton( int textId,
OnClickListener listener )
{
String str = getString( m_context, textId );
return setNeutralButton( str, listener );
}
@Override
public AlertDialog.Builder setNegativeButton( int textId,
OnClickListener listener )
{
String str = getString( m_context, textId );
return setNegativeButton( str, listener );
}
}
}

View file

@ -153,8 +153,6 @@
<string name="key_nag_intervals">key_nag_intervals</string>
<string name="key_download_path">key_download_path</string>
<string name="key_got_langdict">key_got_langdict</string>
<string name="key_xlations_locale">key_xlations_locale</string>
<string name="key_xlations_enabled">key_xlations_enabled</string>
<string name="key_invite_multi">key_invite_multi</string>
<string name="key_na_rematch_two_only">key_notagain_rematch_two_only</string>
<string name="key_notagain_dfltname">key_notagain_dfltname</string>

View file

@ -2073,8 +2073,6 @@
<item quantity="one">Installed one new translation</item>
<item quantity="other">Installed %1$d new translations</item>
</plurals>
<string name="xlations_enabled_title">Enable local translating</string>
<string name="xlations_enabled_summary">Add option to every screen menu</string>
<string name="loc_filters_prompt">Filter by:</string>
<string name="loc_search_prompt">Search for:</string>
<string name="loc_filters_all">All</string>
@ -2278,7 +2276,6 @@
<string name="gamel_menu_storedb">Write games to SD card</string>
<string name="gamel_menu_loaddb">Load games from SD card</string>
<string name="gamel_menu_writegit">Copy git info to clipboard</string>
<string name="xlations_locale">Fake locale for translation</string>
<string name="enable_pending_count_title">Show Pending messages</string>
<string name="enable_pending_count_summary">Show number not yet acknowledged</string>
<string name="nag_intervals">Reminder intervals (minutes1,minutes2,…)</string>

View file

@ -12,15 +12,5 @@
android:defaultValue="false"
/>
<org.eehouse.android.xw4.XWEditTextPreference
android:key="@string/key_xlations_locale"
android:title="@string/xlations_locale"
/>
<CheckBoxPreference android:key="@string/key_xlations_enabled"
android:title="@string/xlations_enabled_title"
android:summary="@string/xlations_enabled_summary"
android:defaultValue="false"
/>
</PreferenceCategory>
</PreferenceScreen>