* strings.xml - Added currency strings * CurrenciesActivity.java - Read strings from string.xml - Use static date formatter * ConverterApplication.java, MenuActivity.java - Start service with app * UpdateService.java, RatesUpdater.java - Called thread-safe
/trunk/src/de/pointedears/converter/app/CurrenciesActivity.java |
---|
0,0 → 1,424 |
package de.pointedears.converter.app; |
import java.text.DateFormat; |
import java.util.Date; |
import java.util.HashMap; |
import java.util.Map.Entry; |
import android.app.Activity; |
import android.content.BroadcastReceiver; |
import android.content.Context; |
import android.content.Intent; |
import android.content.IntentFilter; |
import android.os.Bundle; |
import android.text.Editable; |
import android.view.KeyEvent; |
import android.view.Menu; |
import android.view.MenuInflater; |
import android.view.MenuItem; |
import android.view.View; |
import android.view.View.OnClickListener; |
import android.view.View.OnKeyListener; |
import android.widget.AdapterView; |
import android.widget.AdapterView.OnItemSelectedListener; |
import android.widget.Button; |
import android.widget.EditText; |
import android.widget.Spinner; |
import android.widget.TableLayout; |
import android.widget.TableRow; |
import android.widget.TextView; |
import de.pointedears.converter.R; |
import de.pointedears.converter.db.ConversionData; |
import de.pointedears.converter.db.CurrenciesDatabase; |
import de.pointedears.converter.helpers.Notifier; |
import de.pointedears.converter.helpers.UpdateService; |
/** |
* Activity that implements currency conversion |
* |
* @author pelinux |
*/ |
public class CurrenciesActivity extends Activity |
{ |
/** |
* String to use to indicate that an exchange rate has never been updated |
*/ |
private String TEXT_NEVER; |
/* |
* Constants for mapping value strings |
* |
* @todo: Use resource IDs |
*/ |
/** |
* Database field/spinner value for Swiss Francs |
*/ |
public static String VALUE_CHF; |
/** |
* Database field/spinner value for Euros |
*/ |
public static String VALUE_EUR; |
/** |
* Database field/spinner value for US Dollars |
*/ |
public static String VALUE_USD; |
/* Unit spinners (dropdowns) */ |
private Spinner spinnerUnit1; |
private Spinner spinnerUnit2; |
private static CurrenciesDatabase database; |
private static HashMap<String, ConversionData> conversionRates; |
private static String EXCHANGE_RATES_UPDATED_TO; |
private final static DateFormat dateFormatter = DateFormat |
.getDateInstance(DateFormat.SHORT); |
/** |
* Receiver for intent broadcasts, registered in |
* {@link CurrenciesActivity#onCreate(Bundle)} |
*/ |
public class UpdateBroadcastReceiver extends BroadcastReceiver |
{ |
/** |
* Notification message template |
*/ |
/* |
* (non-Javadoc) |
* |
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, |
* android.content.Intent) |
*/ |
@Override |
public void onReceive(Context context, Intent intent) |
{ |
if (intent.getAction().equals(UpdateService.ACTION_UPDATE)) |
{ |
CurrenciesActivity.this.fillTableRates(); |
Bundle extras = intent.getExtras(); |
Notifier.sendMessage( |
CurrenciesActivity.this, |
extras.get(UpdateService.EXTRA_NUM_RATES) |
+ CurrenciesActivity.EXCHANGE_RATES_UPDATED_TO |
+ CurrenciesActivity.dateFormatter.format(extras |
.get(UpdateService.EXTRA_DATE))); |
} |
} |
} |
/** Called when the activity is first created. */ |
@Override |
public void onCreate(Bundle savedInstanceState) |
{ |
super.onCreate(savedInstanceState); |
this.setContentView(R.layout.activity_currencies); |
this.TEXT_NEVER = |
this.getString(R.string.currencies_never_updated); |
CurrenciesActivity.VALUE_CHF = this.getString(R.string.currencies_CHF); |
CurrenciesActivity.VALUE_EUR = this.getString(R.string.currencies_EUR); |
CurrenciesActivity.VALUE_USD = this.getString(R.string.currencies_USD); |
CurrenciesActivity.EXCHANGE_RATES_UPDATED_TO = |
this.getString(R.string.currencies_notification); |
UpdateBroadcastReceiver br = new UpdateBroadcastReceiver(); |
this.registerReceiver(br, new IntentFilter(UpdateService.ACTION_UPDATE)); |
/* Set up currency database, and retrieve conversion rates */ |
CurrenciesActivity.database = new CurrenciesDatabase(this); |
this.setConversionRates(CurrenciesActivity.database |
.getConversionRates()); |
this.fillTableRates(); |
final EditText editValue1 = |
(EditText) this.findViewById(R.id.currencies_edit_value1); |
final EditText editValue2 = |
(EditText) this.findViewById(R.id.currencies_edit_value2); |
final OnKeyListener editValue1OnKey = new OnKeyListener() { |
@Override |
public boolean onKey(View v, int keyCode, KeyEvent event) |
{ |
Editable editable1 = ((EditText) v).getText(); |
Double value1; |
try |
{ |
value1 = Double.parseDouble(editable1.toString()); |
} |
catch (NumberFormatException e) |
{ |
value1 = null; |
} |
String string2 = ""; //$NON-NLS-1$ |
if (value1 != null) |
{ |
string2 = CurrenciesActivity.this.getConvertedValue(value1, false); |
} |
editValue2.setText(string2); |
return false; |
} |
}; |
editValue1.setOnKeyListener(editValue1OnKey); |
final OnKeyListener editValue2OnKey = new OnKeyListener() { |
@Override |
public boolean onKey(View v, int keyCode, KeyEvent event) |
{ |
Editable editable2 = ((EditText) v).getText(); |
Double value2; |
try |
{ |
value2 = Double.parseDouble(editable2.toString()); |
} |
catch (NumberFormatException e) |
{ |
value2 = null; |
} |
String string1 = ""; //$NON-NLS-1$ |
if (value2 != null) |
{ |
string1 = CurrenciesActivity.this.getConvertedValue(value2, true); |
} |
editValue1.setText(string1); |
return false; |
} |
}; |
editValue2.setOnKeyListener(editValue2OnKey); |
this.spinnerUnit1 = |
(Spinner) this.findViewById(R.id.currencies_spinner_unit1); |
this.spinnerUnit2 = |
(Spinner) this.findViewById(R.id.currencies_spinner_unit2); |
this.spinnerUnit1.setOnItemSelectedListener(new OnItemSelectedListener() { |
@Override |
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
long arg3) |
{ |
/* Simulate input in second EditText so that first EditText is updated */ |
editValue2OnKey.onKey(editValue2, 0, null); |
} |
@Override |
public void onNothingSelected(AdapterView<?> arg0) |
{ |
/* no-op */ |
} |
}); |
this.spinnerUnit2.setSelection(1); |
this.spinnerUnit2.setOnItemSelectedListener(new OnItemSelectedListener() { |
@Override |
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
long arg3) |
{ |
/* Simulate input in first EditText so that second EditText is updated */ |
editValue1OnKey.onKey(editValue1, 0, null); |
} |
@Override |
public void onNothingSelected(AdapterView<?> arg0) |
{ |
/* no-op */ |
} |
}); |
Button buttonClear = |
(Button) this.findViewById(R.id.currencies_button_clear); |
buttonClear.setOnClickListener(new OnClickListener() { |
@SuppressWarnings("nls") |
@Override |
public void onClick(View v) |
{ |
editValue1.setText(""); |
editValue2.setText(""); |
} |
}); |
} |
/** |
* Fills the table with currency conversion rates |
*/ |
public void fillTableRates() |
{ |
TableLayout tableRates = |
(TableLayout) this.findViewById(R.id.currencies_table_rates); |
/* Remove any pre-existing currency rows */ |
while (tableRates.getChildCount() > 3) |
{ |
tableRates.removeViewAt(3); |
} |
for (Entry<String, ConversionData> factorEntry : CurrenciesActivity |
.getConversionRates() |
.entrySet()) |
{ |
TableRow row = new TableRow(this); |
TextView columnCurrency1 = new TextView(this); |
columnCurrency1.setText(factorEntry.getKey()); |
row.addView(columnCurrency1); |
TextView columnRate = new TextView(this); |
final ConversionData conversionData = factorEntry.getValue(); |
columnRate.setText(conversionData.getRate().toString()); |
row.addView(columnRate); |
TextView columnUpdated = new TextView(this); |
Date updated = conversionData.getUpdated(); |
if (updated.getTime() > 0) |
{ |
columnUpdated.setText(CurrenciesActivity.dateFormatter.format(updated)); |
} |
else |
{ |
columnUpdated.setText(this.TEXT_NEVER); |
} |
row.addView(columnUpdated); |
tableRates.addView(row); |
} |
} |
/** |
* @param value |
* @return |
*/ |
private String getConvertedValue(double value, boolean reverse) |
{ |
int selectedItemPosition1 = this.spinnerUnit1.getSelectedItemPosition(); |
int selectedItemPosition2 = this.spinnerUnit2.getSelectedItemPosition(); |
String[] items = |
this.getResources().getStringArray(R.array.currency_units_values); |
String selectedItemValue1 = items[selectedItemPosition1]; |
String selectedItemValue2 = items[selectedItemPosition2]; |
if (reverse) |
{ |
String tmp = selectedItemValue1; |
selectedItemValue1 = selectedItemValue2; |
selectedItemValue2 = tmp; |
} |
Double newValue = value; |
/* |
* NOTE: Had to do it the complicated way because somehow the Android SDK |
* won't get it another way |
*/ |
ConversionData conversionData1 = null; |
Double factorToEuro = 1.0; |
if (selectedItemValue1 != null) |
{ |
conversionData1 = |
CurrenciesActivity.getConversionRates().get(selectedItemValue1); |
if (conversionData1 != null) |
{ |
factorToEuro = conversionData1.getRate(); |
} |
} |
ConversionData conversionData2 = null; |
Double factorFromEuro = 1.0; |
if (selectedItemValue2 != null) |
{ |
conversionData2 = |
CurrenciesActivity.getConversionRates().get(selectedItemValue2); |
if (conversionData2 != null) |
{ |
factorFromEuro = conversionData2.getRate(); |
} |
} |
newValue = newValue / factorToEuro * factorFromEuro; |
return newValue.toString(); |
} |
/* |
* (non-Javadoc) |
* |
* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) |
*/ |
/* |
* (non-Javadoc) |
* |
* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) |
*/ |
@Override |
public boolean onCreateOptionsMenu(Menu menu) |
{ |
MenuInflater inflater = this.getMenuInflater(); |
inflater.inflate(R.menu.options, menu); |
return true; |
} |
/* |
* (non-Javadoc) |
* |
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) |
*/ |
@Override |
public boolean onOptionsItemSelected(MenuItem item) |
{ |
/* Handle item selection */ |
switch (item.getItemId()) |
{ |
case R.id.item_options_update: |
/* |
* Request the update service to run a thread to fetch the rates from |
* the Web (project requirement) |
*/ |
Intent intent = new Intent(this, UpdateService.class); |
intent.setAction(UpdateService.ACTION_UPDATE); |
this.startService(intent); |
return true; |
default: |
return super.onOptionsItemSelected(item); |
} |
} |
/** |
* @return the conversionRates |
*/ |
public static HashMap<String, ConversionData> getConversionRates() |
{ |
return CurrenciesActivity.conversionRates; |
} |
/** |
* @param conversionRates |
* the conversionRates to set |
*/ |
public void setConversionRates(HashMap<String, ConversionData> conversionRates) |
{ |
CurrenciesActivity.conversionRates = conversionRates; |
} |
/** |
* @return the database |
*/ |
public static CurrenciesDatabase getDatabase() |
{ |
return CurrenciesActivity.database; |
} |
} |
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/app/TemperaturesActivity.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/app/TemperaturesActivity.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/app/TemperaturesActivity.java (revision 20) |
@@ -0,0 +1,275 @@ |
+package de.pointedears.converter.app; |
+ |
+import java.util.HashMap; |
+ |
+import android.app.Activity; |
+import android.os.Bundle; |
+import android.text.Editable; |
+import android.view.KeyEvent; |
+import android.view.View; |
+import android.view.View.OnClickListener; |
+import android.view.View.OnKeyListener; |
+import android.widget.AdapterView; |
+import android.widget.AdapterView.OnItemSelectedListener; |
+import android.widget.Button; |
+import android.widget.EditText; |
+import android.widget.Spinner; |
+import android.widget.TextView; |
+import de.pointedears.converter.R; |
+ |
+/** |
+ * Activity that implements length conversion |
+ * |
+ * @author pelinux |
+ */ |
+public class TemperaturesActivity extends Activity |
+{ |
+ /* |
+ * Constants for mapping value strings to internal IDs |
+ */ |
+ private static final String VALUE_CELSIUS = "C"; //$NON-NLS-1$ |
+ private static final String VALUE_FAHRENHEIT = "F"; //$NON-NLS-1$ |
+ private static final String VALUE_KELVIN = "K"; //$NON-NLS-1$ |
+ private static final int ITEM_CELSIUS = 0; |
+ private static final int ITEM_FAHRENHEIT = 1; |
+ private static final int ITEM_KELVIN = 2; |
+ |
+ /** |
+ * Maps value strings to internal IDs |
+ */ |
+ private final static HashMap<String, Integer> valueToId = |
+ new HashMap<String, Integer>(); |
+ |
+ /* Unit spinners (dropdowns) */ |
+ private Spinner spinnerUnit1; |
+ private Spinner spinnerUnit2; |
+ |
+ /* Hint that value is off scale */ |
+ private TextView textOffScale; |
+ |
+ static |
+ { |
+ TemperaturesActivity.valueToId.put(TemperaturesActivity.VALUE_CELSIUS, |
+ TemperaturesActivity.ITEM_CELSIUS); |
+ TemperaturesActivity.valueToId.put(TemperaturesActivity.VALUE_FAHRENHEIT, |
+ TemperaturesActivity.ITEM_FAHRENHEIT); |
+ TemperaturesActivity.valueToId.put(TemperaturesActivity.VALUE_KELVIN, |
+ TemperaturesActivity.ITEM_KELVIN); |
+ } |
+ |
+ /** Called when the activity is first created. */ |
+ |
+ @Override |
+ public void onCreate(Bundle savedInstanceState) |
+ { |
+ super.onCreate(savedInstanceState); |
+ this.setContentView(R.layout.activity_temperatures); |
+ |
+ this.textOffScale = |
+ (TextView) this.findViewById(R.id.temperatures_text_off_scale); |
+ |
+ final EditText editValue1 = |
+ (EditText) this.findViewById(R.id.temperatures_edit_value1); |
+ final EditText editValue2 = |
+ (EditText) this.findViewById(R.id.temperatures_edit_value2); |
+ |
+ final OnKeyListener editValue1OnKey = new OnKeyListener() { |
+ @Override |
+ public boolean onKey(View v, int keyCode, KeyEvent event) |
+ { |
+ Editable editable1 = ((EditText) v).getText(); |
+ |
+ Double value1; |
+ try |
+ { |
+ value1 = Double.parseDouble(editable1.toString()); |
+ } |
+ catch (NumberFormatException e) |
+ { |
+ value1 = null; |
+ } |
+ |
+ String string2 = ""; //$NON-NLS-1$ |
+ if (value1 != null) |
+ { |
+ string2 = TemperaturesActivity.this.getConvertedValue(value1, false); |
+ } |
+ |
+ editValue2.setText(string2); |
+ |
+ return false; |
+ } |
+ }; |
+ editValue1.setOnKeyListener(editValue1OnKey); |
+ |
+ final OnKeyListener editValue2OnKey = new OnKeyListener() { |
+ @Override |
+ public boolean onKey(View v, int keyCode, KeyEvent event) |
+ { |
+ Editable editable2 = ((EditText) v).getText(); |
+ |
+ Double value2; |
+ try |
+ { |
+ value2 = Double.parseDouble(editable2.toString()); |
+ } |
+ catch (NumberFormatException e) |
+ { |
+ value2 = null; |
+ } |
+ |
+ String string1 = ""; //$NON-NLS-1$ |
+ if (value2 != null) |
+ { |
+ string1 = TemperaturesActivity.this.getConvertedValue(value2, true); |
+ } |
+ |
+ editValue1.setText(string1); |
+ |
+ return false; |
+ } |
+ }; |
+ editValue2.setOnKeyListener(editValue2OnKey); |
+ |
+ this.spinnerUnit1 = |
+ (Spinner) this.findViewById(R.id.temperatures_spinner_unit1); |
+ this.spinnerUnit2 = |
+ (Spinner) this.findViewById(R.id.temperatures_spinner_unit2); |
+ |
+ this.spinnerUnit1.setOnItemSelectedListener(new OnItemSelectedListener() { |
+ @Override |
+ public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
+ long arg3) |
+ { |
+ /* Simulate input in second EditText so that first EditText is updated */ |
+ editValue2OnKey.onKey(editValue2, 0, null); |
+ } |
+ |
+ @Override |
+ public void onNothingSelected(AdapterView<?> arg0) |
+ { |
+ /* no-op */ |
+ } |
+ }); |
+ |
+ this.spinnerUnit2.setSelection(1); |
+ this.spinnerUnit2.setOnItemSelectedListener(new OnItemSelectedListener() { |
+ @Override |
+ public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
+ long arg3) |
+ { |
+ /* Simulate input in first EditText so that second EditText is updated */ |
+ editValue1OnKey.onKey(editValue1, 0, null); |
+ } |
+ |
+ @Override |
+ public void onNothingSelected(AdapterView<?> arg0) |
+ { |
+ /* no-op */ |
+ } |
+ }); |
+ |
+ Button buttonClear = |
+ (Button) this.findViewById(R.id.temperatures_button_clear); |
+ buttonClear.setOnClickListener(new OnClickListener() { |
+ |
+ @SuppressWarnings("nls") |
+ @Override |
+ public void onClick(View v) |
+ { |
+ editValue1.setText(""); |
+ editValue2.setText(""); |
+ } |
+ }); |
+ } |
+ |
+ /** |
+ * @param value |
+ * @return |
+ */ |
+ private String getConvertedValue(double value, boolean reverse) |
+ { |
+ int selectedItemPosition1 = this.spinnerUnit1.getSelectedItemPosition(); |
+ int selectedItemPosition2 = this.spinnerUnit2.getSelectedItemPosition(); |
+ String[] itemArray = |
+ this.getResources().getStringArray(R.array.temperature_units_values); |
+ String selectedItemValue1 = itemArray[selectedItemPosition1]; |
+ String selectedItemValue2 = itemArray[selectedItemPosition2]; |
+ |
+ if (reverse) |
+ { |
+ String tmp = selectedItemValue1; |
+ selectedItemValue1 = selectedItemValue2; |
+ selectedItemValue2 = tmp; |
+ } |
+ |
+ int itemId1 = TemperaturesActivity.valueToId.get(selectedItemValue1); |
+ int itemId2 = TemperaturesActivity.valueToId.get(selectedItemValue2); |
+ |
+ Double newValue = value; |
+ |
+ this.textOffScale.setVisibility(View.INVISIBLE); |
+ |
+ switch (itemId1) |
+ { |
+ case ITEM_CELSIUS: |
+ switch (itemId2) |
+ { |
+ case ITEM_FAHRENHEIT: |
+ newValue = new Double(value * 9.0 / 5 + 32); |
+ break; |
+ |
+ case ITEM_KELVIN: |
+ newValue = new Double(value + 273.15); |
+ |
+ if (newValue < 0.0) |
+ { |
+ this.textOffScale.setVisibility(View.VISIBLE); |
+ return "*" + newValue.toString(); //$NON-NLS-1$ |
+ } |
+ break; |
+ } |
+ break; |
+ |
+ case ITEM_FAHRENHEIT: |
+ switch (itemId2) |
+ { |
+ case ITEM_CELSIUS: |
+ newValue = new Double((value - 32) * 5.0 / 9); |
+ break; |
+ |
+ case ITEM_KELVIN: |
+ newValue = new Double((value + 459.67) * 5.0 / 9); |
+ |
+ if (newValue < 0.0) |
+ { |
+ this.textOffScale.setVisibility(View.VISIBLE); |
+ return "*" + newValue.toString(); //$NON-NLS-1$ |
+ } |
+ break; |
+ } |
+ break; |
+ |
+ case ITEM_KELVIN: |
+ switch (itemId2) |
+ { |
+ case ITEM_CELSIUS: |
+ newValue = new Double(value - 273.15); |
+ break; |
+ |
+ case ITEM_FAHRENHEIT: |
+ newValue = new Double(value * 9.0 / 5 - 459.67); |
+ break; |
+ } |
+ |
+ if (value < 0.0) |
+ { |
+ this.textOffScale.setVisibility(View.VISIBLE); |
+ return "*" + newValue.toString(); //$NON-NLS-1$ |
+ } |
+ break; |
+ } |
+ |
+ return newValue.toString(); |
+ } |
+} |
/trunk/src/de/pointedears/converter/app/TemperaturesActivity.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/app/LengthsActivity.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/app/LengthsActivity.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/app/LengthsActivity.java (revision 20) |
@@ -0,0 +1,282 @@ |
+package de.pointedears.converter.app; |
+ |
+import java.util.HashMap; |
+ |
+import android.app.Activity; |
+import android.os.Bundle; |
+import android.text.Editable; |
+import android.view.KeyEvent; |
+import android.view.View; |
+import android.view.View.OnClickListener; |
+import android.view.View.OnKeyListener; |
+import android.widget.AdapterView; |
+import android.widget.AdapterView.OnItemSelectedListener; |
+import android.widget.Button; |
+import android.widget.EditText; |
+import android.widget.Spinner; |
+import de.pointedears.converter.R; |
+ |
+/** |
+ * Activity that implements length conversion |
+ * |
+ * @author pelinux |
+ */ |
+public class LengthsActivity extends Activity |
+{ |
+ /* |
+ * Constants for mapping value strings to internal IDs |
+ */ |
+ private static final String VALUE_INCHES = "inch"; //$NON-NLS-1$ |
+ private static final String VALUE_KILOMETERS = "km"; //$NON-NLS-1$ |
+ private static final String VALUE_METERS = "m"; //$NON-NLS-1$ |
+ private static final String VALUE_MILES = "mi"; //$NON-NLS-1$ |
+ private static final int ITEM_INCHES = 0; |
+ private static final int ITEM_KILOMETERS = 1; |
+ private static final int ITEM_METERS = 2; |
+ private static final int ITEM_MILES = 3; |
+ |
+ /** |
+ * Maps value strings to internal IDs |
+ */ |
+ private final static HashMap<String, Integer> valueToId = |
+ new HashMap<String, Integer>(); |
+ static |
+ { |
+ LengthsActivity.valueToId.put(LengthsActivity.VALUE_INCHES, |
+ LengthsActivity.ITEM_INCHES); |
+ LengthsActivity.valueToId.put(LengthsActivity.VALUE_KILOMETERS, |
+ LengthsActivity.ITEM_KILOMETERS); |
+ LengthsActivity.valueToId.put(LengthsActivity.VALUE_METERS, |
+ LengthsActivity.ITEM_METERS); |
+ LengthsActivity.valueToId.put(LengthsActivity.VALUE_MILES, |
+ LengthsActivity.ITEM_MILES); |
+ } |
+ |
+ /* Unit spinners (dropdowns) */ |
+ private Spinner spinnerUnit1; |
+ private Spinner spinnerUnit2; |
+ |
+ /** Called when the activity is first created. */ |
+ |
+ @Override |
+ public void onCreate(Bundle savedInstanceState) |
+ { |
+ super.onCreate(savedInstanceState); |
+ this.setContentView(R.layout.activity_lengths); |
+ |
+ final EditText editValue1 = (EditText) this.findViewById(R.id.edit_value1); |
+ final EditText editValue2 = (EditText) this.findViewById(R.id.edit_value2); |
+ |
+ final OnKeyListener editValue1OnKey = new OnKeyListener() { |
+ @Override |
+ public boolean onKey(View v, int keyCode, KeyEvent event) |
+ { |
+ Editable editable1 = ((EditText) v).getText(); |
+ |
+ Double value1; |
+ try |
+ { |
+ value1 = Double.parseDouble(editable1.toString()); |
+ } |
+ catch (NumberFormatException e) |
+ { |
+ value1 = null; |
+ } |
+ |
+ String string2 = ""; //$NON-NLS-1$ |
+ if (value1 != null) |
+ { |
+ string2 = LengthsActivity.this.getConvertedValue(value1, false); |
+ } |
+ |
+ editValue2.setText(string2); |
+ |
+ return false; |
+ } |
+ }; |
+ editValue1.setOnKeyListener(editValue1OnKey); |
+ |
+ final OnKeyListener editValue2OnKey = new OnKeyListener() { |
+ @Override |
+ public boolean onKey(View v, int keyCode, KeyEvent event) |
+ { |
+ Editable editable2 = ((EditText) v).getText(); |
+ |
+ Double value2; |
+ try |
+ { |
+ value2 = Double.parseDouble(editable2.toString()); |
+ } |
+ catch (NumberFormatException e) |
+ { |
+ value2 = null; |
+ } |
+ |
+ String string1 = ""; //$NON-NLS-1$ |
+ if (value2 != null) |
+ { |
+ string1 = LengthsActivity.this.getConvertedValue(value2, true); |
+ } |
+ |
+ editValue1.setText(string1); |
+ |
+ return false; |
+ } |
+ }; |
+ editValue2.setOnKeyListener(editValue2OnKey); |
+ |
+ this.spinnerUnit1 = (Spinner) this.findViewById(R.id.spinner_unit1); |
+ this.spinnerUnit2 = (Spinner) this.findViewById(R.id.spinner_unit2); |
+ |
+ this.spinnerUnit1.setOnItemSelectedListener(new OnItemSelectedListener() { |
+ @Override |
+ public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
+ long arg3) |
+ { |
+ /* Simulate input in second EditText so that first EditText is updated */ |
+ editValue2OnKey.onKey(editValue2, 0, null); |
+ } |
+ |
+ @Override |
+ public void onNothingSelected(AdapterView<?> arg0) |
+ { |
+ /* no-op */ |
+ } |
+ }); |
+ |
+ this.spinnerUnit2.setSelection(1); |
+ this.spinnerUnit2.setOnItemSelectedListener(new OnItemSelectedListener() { |
+ @Override |
+ public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
+ long arg3) |
+ { |
+ /* Simulate input in first EditText so that second EditText is updated */ |
+ editValue1OnKey.onKey(editValue1, 0, null); |
+ } |
+ |
+ @Override |
+ public void onNothingSelected(AdapterView<?> arg0) |
+ { |
+ /* no-op */ |
+ } |
+ }); |
+ |
+ Button buttonClear = |
+ (Button) this.findViewById(R.id.lengths_button_clear); |
+ buttonClear.setOnClickListener(new OnClickListener() { |
+ |
+ @SuppressWarnings("nls") |
+ @Override |
+ public void onClick(View v) |
+ { |
+ editValue1.setText(""); |
+ editValue2.setText(""); |
+ } |
+ }); |
+ } |
+ |
+ /** |
+ * @param value |
+ * @return |
+ */ |
+ private String getConvertedValue(double value, boolean reverse) |
+ { |
+ int selectedItemPosition1 = this.spinnerUnit1.getSelectedItemPosition(); |
+ int selectedItemPosition2 = this.spinnerUnit2.getSelectedItemPosition(); |
+ String[] itemArray = |
+ this.getResources().getStringArray(R.array.length_units_values); |
+ String selectedItemValue1 = itemArray[selectedItemPosition1]; |
+ String selectedItemValue2 = itemArray[selectedItemPosition2]; |
+ |
+ if (reverse) |
+ { |
+ String tmp = selectedItemValue1; |
+ selectedItemValue1 = selectedItemValue2; |
+ selectedItemValue2 = tmp; |
+ } |
+ |
+ int itemId1 = LengthsActivity.valueToId.get(selectedItemValue1); |
+ int itemId2 = LengthsActivity.valueToId.get(selectedItemValue2); |
+ |
+ Double newValue = value; |
+ |
+ switch (itemId1) |
+ { |
+ case ITEM_INCHES: |
+ switch (itemId2) |
+ { |
+ case ITEM_KILOMETERS: |
+ /* see ITEM_METERS */ |
+ newValue = new Double((value * 0.0254) / 1000); |
+ break; |
+ |
+ case ITEM_METERS: |
+ newValue = new Double(value * 0.0254); |
+ break; |
+ |
+ case ITEM_MILES: |
+ /* 12 in/ft and 5280 ft/mi */ |
+ newValue = new Double(value / 12 / 5280); |
+ break; |
+ } |
+ break; |
+ |
+ case ITEM_KILOMETERS: |
+ switch (itemId2) |
+ { |
+ case ITEM_INCHES: |
+ /* 1 m = 39.370 in */ |
+ newValue = new Double(value * 1000 * 39.370); |
+ break; |
+ |
+ case ITEM_METERS: |
+ newValue = new Double(value * 1000); |
+ break; |
+ |
+ case ITEM_MILES: |
+ newValue = new Double(value / 1.609344); |
+ break; |
+ } |
+ break; |
+ |
+ case ITEM_METERS: |
+ switch (itemId2) |
+ { |
+ case ITEM_INCHES: |
+ /* 1 m = 39.370 in */ |
+ newValue = new Double(value * 39.370); |
+ break; |
+ |
+ case ITEM_KILOMETERS: |
+ newValue = new Double(value / 1000); |
+ break; |
+ |
+ case ITEM_MILES: |
+ /* 1 mi = 1609.344 m */ |
+ newValue = new Double(value / 1609.344); |
+ break; |
+ } |
+ break; |
+ |
+ case ITEM_MILES: |
+ switch (itemId2) |
+ { |
+ case ITEM_INCHES: |
+ /* 1 mi = 5280 ft, 1 ft = 12 in */ |
+ newValue = new Double(value * 5280 * 12); |
+ break; |
+ |
+ case ITEM_KILOMETERS: |
+ newValue = new Double(value * 1.609344); |
+ break; |
+ |
+ case ITEM_METERS: |
+ newValue = new Double(value * 1609.344); |
+ break; |
+ } |
+ break; |
+ } |
+ |
+ return newValue.toString(); |
+ } |
+} |
/trunk/src/de/pointedears/converter/app/LengthsActivity.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/MenuActivity.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/MenuActivity.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/MenuActivity.java (revision 20) |
@@ -0,0 +1,203 @@ |
+package de.pointedears.converter; |
+ |
+/* |
+ * Copyright (C) 2007 The Android Open Source Project |
+ * |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
+ * you may not use this file except in compliance with the License. |
+ * You may obtain a copy of the License at |
+ * |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
+ * |
+ * Unless required by applicable law or agreed to in writing, software |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+ * See the License for the specific language governing permissions and |
+ * limitations under the License. |
+ */ |
+ |
+import java.text.Collator; |
+import java.util.ArrayList; |
+import java.util.Collections; |
+import java.util.Comparator; |
+import java.util.HashMap; |
+import java.util.List; |
+import java.util.Map; |
+ |
+import android.app.ListActivity; |
+import android.content.Intent; |
+import android.content.pm.PackageManager; |
+import android.content.pm.ResolveInfo; |
+import android.os.Bundle; |
+import android.view.View; |
+import android.widget.ListView; |
+import android.widget.SimpleAdapter; |
+ |
+/** |
+ * Generates the main menu as a list of activities from the manifest |
+ * |
+ * @author |
+ * Thomas 'PointedEars' Lahn; |
+ * Class courtesy of The Android Open Source Project |
+ * (Android 2.2 SDK Examples), slightly adapted |
+ */ |
+public class MenuActivity extends ListActivity |
+{ |
+ @Override |
+ public void onCreate(Bundle savedInstanceState) |
+ { |
+ super.onCreate(savedInstanceState); |
+ |
+ Intent intent = this.getIntent(); |
+ String path = intent.getStringExtra("de.pointedears.converter.Path"); //$NON-NLS-1$ |
+ |
+ if (path == null) |
+ { |
+ path = ""; //$NON-NLS-1$ |
+ } |
+ |
+ this.setListAdapter(new SimpleAdapter(this, this.getData(path), |
+ android.R.layout.simple_list_item_1, new String[] { "title" }, //$NON-NLS-1$ |
+ new int[] { android.R.id.text1 })); |
+ this.getListView().setTextFilterEnabled(true); |
+ } |
+ |
+ /** |
+ * @param prefix |
+ * @return |
+ */ |
+ protected List getData(String prefix) |
+ { |
+ List<Map> myData = new ArrayList<Map>(); |
+ |
+ Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); |
+ mainIntent.addCategory(ConverterApplication.CATEGORY_CONVERTER); |
+ |
+ PackageManager pm = this.getPackageManager(); |
+ List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0); |
+ |
+ if (null == list) |
+ { |
+ return myData; |
+ } |
+ |
+ String[] prefixPath; |
+ |
+ if (prefix.equals("")) //$NON-NLS-1$ |
+ { |
+ prefixPath = null; |
+ } |
+ else |
+ { |
+ prefixPath = prefix.split("/"); //$NON-NLS-1$ |
+ } |
+ |
+ int len = list.size(); |
+ |
+ Map<String, Boolean> entries = new HashMap<String, Boolean>(); |
+ |
+ for (int i = 0; i < len; i++) |
+ { |
+ ResolveInfo info = list.get(i); |
+ CharSequence labelSeq = info.loadLabel(pm); |
+ String label = labelSeq != null |
+ ? labelSeq.toString() |
+ : info.activityInfo.name; |
+ |
+ if (prefix.length() == 0 || label.startsWith(prefix)) |
+ { |
+ |
+ String[] labelPath = label.split("/"); //$NON-NLS-1$ |
+ |
+ String nextLabel = |
+ prefixPath == null ? labelPath[0] : labelPath[prefixPath.length]; |
+ |
+ if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) |
+ { |
+ this.addItem(myData, nextLabel, this.activityIntent( |
+ info.activityInfo.applicationInfo.packageName, |
+ info.activityInfo.name)); |
+ } |
+ else |
+ { |
+ if (entries.get(nextLabel) == null) |
+ { |
+ this.addItem( |
+ myData, |
+ nextLabel, |
+ this.browseIntent(prefix.equals("") ? nextLabel : prefix + "/" //$NON-NLS-1$//$NON-NLS-2$ |
+ + nextLabel)); |
+ entries.put(nextLabel, true); |
+ } |
+ } |
+ } |
+ } |
+ |
+ Collections.sort(myData, MenuActivity.sDisplayNameComparator); |
+ |
+ return myData; |
+ } |
+ |
+ private final static Comparator<Map> sDisplayNameComparator = |
+ new Comparator<Map>() { |
+ private final Collator collator = Collator.getInstance(); |
+ |
+ public int compare(Map map1, Map map2) |
+ { |
+ return this.collator.compare(map1.get("title"), map2.get("title")); //$NON-NLS-1$ //$NON-NLS-2$ |
+ } |
+ }; |
+ |
+ /** |
+ * @param pkg |
+ * @param componentName |
+ * @return |
+ */ |
+ protected Intent activityIntent(String pkg, String componentName) |
+ { |
+ Intent result = new Intent(); |
+ result.setClassName(pkg, componentName); |
+ return result; |
+ } |
+ |
+ /** |
+ * @param path |
+ * @return |
+ */ |
+ protected Intent browseIntent(String path) |
+ { |
+ Intent result = new Intent(); |
+ result.setClass(this, MenuActivity.class); |
+ result.putExtra("de.pointedears.converter.Path", path); //$NON-NLS-1$ |
+ return result; |
+ } |
+ |
+ /** |
+ * @param data |
+ * @param name |
+ * @param intent |
+ */ |
+ protected void addItem(List<Map> data, String name, Intent intent) |
+ { |
+ Map<String, Object> temp = new HashMap<String, Object>(); |
+ temp.put("title", name); //$NON-NLS-1$ |
+ temp.put("intent", intent); //$NON-NLS-1$ |
+ data.add(temp); |
+ } |
+ |
+ /* |
+ * (non-Javadoc) |
+ * |
+ * @see android.app.ListActivity#onListItemClick(android.widget.ListView, |
+ * android.view.View, int, long) |
+ */ |
+ @Override |
+ protected void onListItemClick(ListView l, View v, int position, long id) |
+ { |
+ Map map = (Map) l.getItemAtPosition(position); |
+ |
+ Intent intent = (Intent) map.get("intent"); //$NON-NLS-1$ |
+ this.startActivity(intent); |
+ } |
+ |
+} |
/trunk/src/de/pointedears/converter/MenuActivity.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/helpers/UpdateService.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/helpers/UpdateService.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/helpers/UpdateService.java (revision 20) |
@@ -0,0 +1,137 @@ |
+package de.pointedears.converter.helpers; |
+ |
+import android.app.Service; |
+import android.content.Intent; |
+import android.os.Handler; |
+import android.os.IBinder; |
+import de.pointedears.converter.app.CurrenciesActivity; |
+import de.pointedears.converter.net.RatesUpdater; |
+ |
+/** |
+ * Update service to run a thread to update currency rates |
+ * |
+ * @author Thomas 'PointedEars' Lahn |
+ */ |
+public class UpdateService extends Service |
+{ |
+ private ConverterThread updateThread; |
+ private Handler handler; |
+ private RatesUpdater ratesUpdater; |
+ |
+ public static final String ACTION_UPDATE = |
+ "de.pointedears.converter.ACTION_UPDATE"; //$NON-NLS-1$ |
+ public static final String EXTRA_ACTIVITY = |
+ "de.pointedears.converter.extra_activity"; //$NON-NLS-1$ |
+ public static final String EXTRA_NUM_RATES = |
+ "de.pointedears.converter.extra_num_rates"; //$NON-NLS-1$ |
+ public static final String EXTRA_DATE = "de.pointedears.converter.extra_date"; //$NON-NLS-1$ |
+ |
+ /* NOTE: Don't remove; may be used later for automated updates */ |
+ // private sendTimerTask sendTime = null; |
+ |
+ // /** inner class implements the broadcast timer */ |
+ // private class BroadcastTimerTask extends TimerTask |
+ // { |
+ // int counter = 0; |
+ // |
+ // @Override |
+ // public void run() |
+ // { |
+ // Intent intent = new Intent(UpdateService.ACTION_UPDATE); |
+ // String theTime = |
+ // "Time: " + System.currentTimeMillis() + ", Counter = " |
+ // + Integer.toString(this.counter); |
+ // this.counter++; |
+ // intent.putExtra("TIME", theTime); |
+ // UpdateService.this.sendBroadcast(intent); |
+ // } |
+ // }; |
+ |
+ @Override |
+ public IBinder onBind(Intent intent) |
+ { |
+ /* NOTE: Clients cannot bind to this service */ |
+ return null; |
+ } |
+ |
+ @Override |
+ public void onCreate() |
+ { |
+ super.onCreate(); |
+ // this.myTimer = new Timer("myTimer"); |
+ |
+ if (this.handler == null) |
+ { |
+ this.handler = new Handler(); |
+ } |
+ |
+ this.updateThread = null; |
+ } |
+ |
+ // /* |
+ // * (non-Javadoc) |
+ // * |
+ // * @see android.app.Service#onStartCommand(android.content.Intent, int, int) |
+ // */ |
+ // @Override |
+ // public int onStartCommand(Intent intent, int flags, int startId) |
+ // { |
+ // // TODO Auto-generated method stub |
+ // return super.onStartCommand(intent, flags, startId); |
+ // } |
+ |
+ @Override |
+ /** |
+ * @deprecated since SDK 2.0 |
+ */ |
+ public void onStart(Intent intent, int startId) |
+ { |
+ super.onStart(intent, startId); |
+ // this.myTimer.cancel(); |
+ // this.myTimer = new Timer("myTimer"); |
+ // this.sendTime = new BroadcastTimerTask(); |
+ // this.myTimer.scheduleAtFixedRate(this.sendTime, 0, 1000 * 5); |
+ |
+ String action = intent.getAction(); |
+ if (UpdateService.ACTION_UPDATE.equals(action)) |
+ { |
+ if (this.updateThread == null) |
+ { |
+ this.ratesUpdater = new RatesUpdater(this); |
+ this.updateThread = |
+ new ConverterThread(this.ratesUpdater, this.handler); |
+ this.ratesUpdater.setUpdateThread(this.updateThread); |
+ } |
+ |
+ try |
+ { |
+ this.updateThread.start(); |
+ // this.editValue1.setText("Gestartet!"); |
+ } |
+ catch (IllegalThreadStateException e) |
+ { |
+ // this.editValue1.setText("Bereits gestartet!"); |
+ } |
+ |
+ // case R.id.item_options_quit: |
+ // if (this.updateThread != null) |
+ // { |
+ // try |
+ // { |
+ // this.updateThread.join(); |
+ // } |
+ // catch (InterruptedException e) |
+ // { |
+ // // TODO Auto-generated catch block |
+ // } |
+ // |
+ // // this.editValue1.setText("Gestoppt -> Warten auf Start"); |
+ // } |
+ // else |
+ // { |
+ // // this.editValue1.setText("Bereits gestoppt -> Warten auf Start"); |
+ // } |
+ // return true; |
+ } |
+ } |
+} |
/trunk/src/de/pointedears/converter/helpers/UpdateService.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/helpers/Notifier.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/helpers/Notifier.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/helpers/Notifier.java (revision 20) |
@@ -0,0 +1,96 @@ |
+/** |
+ * A simple notifier for Activities, encapsulating all the work necessary |
+ * to send a notification message on Android. |
+ */ |
+package de.pointedears.converter.helpers; |
+ |
+import android.app.Activity; |
+import android.app.Notification; |
+import android.app.NotificationManager; |
+import android.app.PendingIntent; |
+import android.content.Context; |
+import android.content.Intent; |
+import de.pointedears.converter.R; |
+import de.pointedears.converter.R.drawable; |
+ |
+/** |
+ * Sends notification messages for {@link Activity Activities} |
+ * |
+ * @author Thomas 'PointedEars' Lahn |
+ */ |
+public class Notifier |
+{ |
+ private static int nextId = 1; |
+ |
+ /** |
+ * |
+ */ |
+ public Context activityContext; |
+ |
+ /** |
+ * @param activityContext |
+ * The activity for which a notification will be sent. This |
+ * allows the user to select the notification and go back |
+ * directly to the activity that issued it. |
+ * @param tickerText |
+ * The text to be displayed as notification, both as ticker message |
+ * and in the notification list. |
+ * @param notificationTitle |
+ * The title for the notification message. The default ( |
+ * <code>null</code>) |
+ * is the application name (R.strings.app_name). |
+ * @see Notifier#sendMessage(Context, CharSequence) |
+ */ |
+ public static void sendMessage(Context activityContext, |
+ CharSequence tickerText, CharSequence notificationTitle) |
+ { |
+ NotificationManager mNotificationManager = |
+ (NotificationManager) activityContext |
+ .getSystemService(Context.NOTIFICATION_SERVICE); |
+ |
+ Notification notification = |
+ new Notification(drawable.icon, tickerText, System.currentTimeMillis()); |
+ |
+ Context applicationContext = |
+ activityContext.getApplicationContext(); |
+ |
+ Intent notificationIntent = |
+ new Intent(activityContext, activityContext.getClass()); |
+ |
+ PendingIntent contentIntent = |
+ PendingIntent.getActivity(activityContext, 0, |
+ notificationIntent, 0); |
+ |
+ if (notificationTitle == null) |
+ { |
+ notificationTitle = activityContext.getString(R.string.app_name); |
+ } |
+ |
+ CharSequence contentTitle = notificationTitle; |
+ CharSequence contentText = tickerText; |
+ |
+ notification.setLatestEventInfo(applicationContext, contentTitle, |
+ contentText, |
+ contentIntent); |
+ |
+ mNotificationManager.notify(Notifier.nextId, notification); |
+ ++Notifier.nextId; |
+ } |
+ |
+ /** |
+ * Sends a notification message where the the application name |
+ * (R.strings.app_name) |
+ * is used as message title. |
+ * |
+ * @param activityContext |
+ * The activity for which a notification will be sent |
+ * @param tickerText |
+ * The text to be displayed as notification |
+ * @see Notifier#sendMessage(Context, CharSequence, CharSequence) |
+ */ |
+ public static void sendMessage(Context activityContext, |
+ CharSequence tickerText) |
+ { |
+ Notifier.sendMessage(activityContext, tickerText, null); |
+ } |
+} |
\ No newline at end of file |
/trunk/src/de/pointedears/converter/helpers/Notifier.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/helpers/ConverterThread.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/helpers/ConverterThread.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/helpers/ConverterThread.java (revision 20) |
@@ -0,0 +1,30 @@ |
+package de.pointedears.converter.helpers; |
+ |
+import android.os.Handler; |
+ |
+/** |
+ * General thread to perform background tasks |
+ * |
+ * @author pelinux |
+ */ |
+public class ConverterThread extends Thread |
+{ |
+ private Handler handler = null; |
+ private Runnable runnable = null; |
+ |
+ /** |
+ * @param runnable |
+ * @param handler |
+ */ |
+ public ConverterThread(Runnable runnable, Handler handler) |
+ { |
+ this.handler = handler; |
+ this.runnable = runnable; |
+ } |
+ |
+ @Override |
+ public void run() |
+ { |
+ this.handler.post(this.runnable); |
+ } |
+} |
/trunk/src/de/pointedears/converter/helpers/ConverterThread.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java (revision 20) |
@@ -0,0 +1,58 @@ |
+package de.pointedears.converter.helpers; |
+ |
+import java.util.HashMap; |
+import java.util.Iterator; |
+ |
+import javax.xml.XMLConstants; |
+import javax.xml.namespace.NamespaceContext; |
+ |
+/** |
+ * @author pelinux |
+ * |
+ */ |
+public final class ConverterNamespaceContext implements NamespaceContext |
+{ |
+ private final HashMap<String, String> namespaces = |
+ new HashMap<String, String>(); |
+ |
+ public void add(String prefix, String uri) |
+ { |
+ this.namespaces.put(prefix, uri); |
+ } |
+ |
+ @Override |
+ public Iterator getPrefixes(String namespaceURI) |
+ { |
+ throw new UnsupportedOperationException(); |
+ } |
+ |
+ @Override |
+ public String getPrefix(String namespaceURI) |
+ { |
+ throw new UnsupportedOperationException(); |
+ } |
+ |
+ @Override |
+ public String getNamespaceURI(String prefix) |
+ { |
+ if (prefix == null) |
+ { |
+ throw new NullPointerException("Null prefix"); |
+ } |
+ else |
+ { |
+ if ("xml".equals(prefix)) |
+ { |
+ return XMLConstants.XML_NS_URI; |
+ } |
+ |
+ String storedPrefix = this.namespaces.get(prefix); |
+ if (storedPrefix != null) |
+ { |
+ return storedPrefix; |
+ } |
+ |
+ return XMLConstants.NULL_NS_URI; |
+ } |
+ } |
+} |
\ No newline at end of file |
/trunk/src/de/pointedears/converter/helpers/ConverterNamespaceContext.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/net/RatesUpdater.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/net/RatesUpdater.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/net/RatesUpdater.java (revision 20) |
@@ -0,0 +1,218 @@ |
+/** |
+ * |
+ */ |
+package de.pointedears.converter.net; |
+ |
+import java.io.IOException; |
+import java.text.DateFormat; |
+import java.text.ParseException; |
+import java.text.SimpleDateFormat; |
+import java.util.Date; |
+import java.util.HashMap; |
+ |
+import javax.xml.parsers.DocumentBuilder; |
+import javax.xml.parsers.DocumentBuilderFactory; |
+import javax.xml.parsers.ParserConfigurationException; |
+import javax.xml.xpath.XPath; |
+import javax.xml.xpath.XPathConstants; |
+import javax.xml.xpath.XPathExpression; |
+import javax.xml.xpath.XPathExpressionException; |
+import javax.xml.xpath.XPathFactory; |
+ |
+import org.w3c.dom.Document; |
+import org.w3c.dom.Element; |
+import org.w3c.dom.NodeList; |
+import org.xml.sax.SAXException; |
+ |
+import android.content.Intent; |
+import android.util.Log; |
+import de.pointedears.converter.app.CurrenciesActivity; |
+import de.pointedears.converter.db.ConversionData; |
+import de.pointedears.converter.helpers.ConverterThread; |
+import de.pointedears.converter.helpers.UpdateService; |
+ |
+/** |
+ * @author pelinux |
+ * |
+ */ |
+public class RatesUpdater implements Runnable |
+{ |
+ /* |
+ * XML markup attributes |
+ */ |
+ private static final String ATTR_RATE = "rate"; //$NON-NLS-1$ |
+ private static final String ATTR_CURRENCY = "currency"; //$NON-NLS-1$ |
+ private static final String ATTR_TIME = "time"; //$NON-NLS-1$ |
+ |
+ private static final String URL_ECB = |
+ "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; //$NON-NLS-1$ |
+ |
+ private ConverterThread updateThread = null; |
+ |
+ private final UpdateService service; |
+ |
+ /** |
+ * @param activityContext |
+ * The activityContext for this updater. |
+ * FIXME: Required only for database access |
+ * @param updateService |
+ * The service that started this updater |
+ */ |
+ public RatesUpdater(UpdateService updateService) |
+ { |
+ this.service = updateService; |
+ } |
+ |
+ /** |
+ * @return the updateThread |
+ */ |
+ public ConverterThread getUpdateThread() |
+ { |
+ return this.updateThread; |
+ } |
+ |
+ /** |
+ * @param updateThread |
+ * the thread that this updater is running in |
+ */ |
+ public void setUpdateThread(ConverterThread updateThread) |
+ { |
+ this.updateThread = updateThread; |
+ } |
+ |
+ /* |
+ * (non-Javadoc) |
+ * |
+ * @see java.lang.Runnable#run() |
+ */ |
+ @Override |
+ public void run() |
+ { |
+ int len = 0; |
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$ |
+ Date updated = new Date(); |
+ |
+ if (this.getUpdateThread() != null) |
+ { |
+ // TextView textUpdating = |
+ // (TextView) this.activityContext |
+ // .findViewById(R.id.currencies_text_updating); |
+ // textUpdating.setVisibility(View.VISIBLE); |
+ |
+ DocumentBuilderFactory documentBuilderFactory = |
+ DocumentBuilderFactory.newInstance(); |
+ documentBuilderFactory.setNamespaceAware(true); |
+ DocumentBuilder builder; |
+ try |
+ { |
+ builder = documentBuilderFactory.newDocumentBuilder(); |
+ Document doc; |
+ try |
+ { |
+ doc = builder.parse(RatesUpdater.URL_ECB); |
+ XPathFactory xpathFactory = XPathFactory.newInstance(); |
+ XPath xpath = xpathFactory.newXPath(); |
+ // NamespaceContextHelper namespaceContext = |
+ // new NamespaceContextHelper(); |
+ // namespaceContext.add("gesmes", |
+ // "http://www.gesmes.org/xml/2002-08-01"); |
+ // xpath.setNamespaceContext(namespaceContext); |
+ |
+ try |
+ { |
+ /* |
+ * FIXME: Why doesn't a simple "./Cube/Cube/Cube" work even with a |
+ * namespace resolver? |
+ */ |
+ @SuppressWarnings("nls") |
+ XPathExpression expr = |
+ xpath |
+ .compile("./*[local-name() = 'Cube']/*[local-name() = 'Cube']"); |
+ NodeList nodes = (NodeList) |
+ expr.evaluate(doc.getDocumentElement(), XPathConstants.NODESET); |
+ Element parentCube = (Element) nodes.item(0); |
+ if (parentCube == null) |
+ { |
+ return; |
+ } |
+ |
+ try |
+ { |
+ updated = |
+ df.parse(parentCube.getAttribute(RatesUpdater.ATTR_TIME)); |
+ } |
+ catch (ParseException e) |
+ { |
+ Log.e(this.getClass().toString(), |
+ "Could not parse the `time' attribute into a Date", e); //$NON-NLS-1$ |
+ } |
+ |
+ expr = |
+ xpath |
+ .compile("./*[local-name()='Cube' and (@currency='CHF' or @currency='USD')]"); //$NON-NLS-1$ |
+ nodes = |
+ (NodeList) expr.evaluate(parentCube, XPathConstants.NODESET); |
+ NodeList childCubes = nodes; |
+ |
+ len = childCubes.getLength(); |
+ |
+ HashMap<String, ConversionData> conversionRates = |
+ CurrenciesActivity.getConversionRates(); |
+ for (int i = 0; i < len; ++i) |
+ { |
+ Element item = (Element) childCubes.item(i); |
+ String currency = item.getAttribute(RatesUpdater.ATTR_CURRENCY); |
+ |
+ try |
+ { |
+ Double rate = |
+ Double.parseDouble(item.getAttribute(RatesUpdater.ATTR_RATE)); |
+ conversionRates |
+ .put(currency, new ConversionData(rate, updated)); |
+ } |
+ catch (NumberFormatException e) |
+ { |
+ |
+ } |
+ } |
+ |
+ CurrenciesActivity.getDatabase().writeConversionsToDatabase(null); |
+ } |
+ catch (XPathExpressionException e) |
+ { |
+ Log.e(this.getClass().toString(), "Error in XPath expression", e); //$NON-NLS-1$ |
+ } |
+ } |
+ catch (SAXException e) |
+ { |
+ Log.e(this.getClass().toString(), |
+ "Exception while parsing external XML resource", e); //$NON-NLS-1$ |
+ } |
+ catch (IOException e) |
+ { |
+ Log.e(this.getClass().toString(), |
+ "I/O exception while parsing external XML resource", e); //$NON-NLS-1$ |
+ } |
+ } |
+ catch (ParserConfigurationException e) |
+ { |
+ Log.e(this.getClass().toString(), |
+ "Document builder cannot be created", e); //$NON-NLS-1$ |
+ } |
+ |
+ if (len > 0) |
+ { |
+ /* |
+ * Notify the activity that we are done (causes a notification to be |
+ * shown) |
+ */ |
+ Intent intent = new Intent(UpdateService.ACTION_UPDATE); |
+ intent.putExtra(UpdateService.EXTRA_NUM_RATES, len); |
+ intent.putExtra(UpdateService.EXTRA_DATE, updated); |
+ this.service.sendBroadcast(intent); |
+ } |
+ |
+ // textUpdating.setVisibility(View.GONE); |
+ } |
+ } |
+} |
/trunk/src/de/pointedears/converter/net/RatesUpdater.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/ConverterApplication.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/ConverterApplication.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/ConverterApplication.java (revision 20) |
@@ -0,0 +1,51 @@ |
+/* |
+ * Copyright (C) 2010 Thomas Lahn |
+ */ |
+ |
+package de.pointedears.converter; |
+ |
+import android.app.Application; |
+import android.content.Intent; |
+import de.pointedears.converter.helpers.UpdateService; |
+ |
+/** |
+ * Converter application class. Holds the intent category for building |
+ * the list menu. Might later initialize prefs. |
+ * |
+ * @author Thomas 'PointedEars' Lahn |
+ */ |
+public class ConverterApplication extends Application |
+{ |
+ /** |
+ * Activity category for automatically filtering converter Activities |
+ */ |
+ public final static String CATEGORY_CONVERTER = |
+ "android.intent.category.CONVERTER"; //$NON-NLS-1$ |
+ |
+ /* |
+ * (non-Javadoc) |
+ * |
+ * @see android.app.Application#onCreate() |
+ */ |
+ @Override |
+ public void onCreate() |
+ { |
+ this.startService(new Intent(this, UpdateService.class)); |
+ |
+ /* |
+ * This populates the default values from the preferences XML file. See |
+ * {@link DefaultValues} for more details. |
+ */ |
+ // PreferenceManager.setDefaultValues(this, R.xml.default_values, false); |
+ } |
+ |
+ /* |
+ * (non-Javadoc) |
+ * |
+ * @see android.app.Application#onTerminate() |
+ */ |
+ @Override |
+ public void onTerminate() |
+ { |
+ } |
+} |
/trunk/src/de/pointedears/converter/ConverterApplication.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/db/ConversionData.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/db/ConversionData.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/db/ConversionData.java (revision 20) |
@@ -0,0 +1,60 @@ |
+package de.pointedears.converter.db; |
+ |
+import java.util.Date; |
+ |
+/** |
+ * Stores conversion data for a currency |
+ * |
+ * @author pelinux |
+ */ |
+public class ConversionData |
+{ |
+ private double rate; |
+ private Date updated; |
+ |
+ /** |
+ * @param rate |
+ * 1 EUR equals this value in a currency |
+ * @param updated |
+ * Date that the rate was updated |
+ */ |
+ public ConversionData(Double rate, Date updated) |
+ { |
+ this.setRate(rate); |
+ this.setUpdated(updated); |
+ } |
+ |
+ /** |
+ * @return the rate |
+ */ |
+ public Double getRate() |
+ { |
+ return this.rate; |
+ } |
+ |
+ /** |
+ * @param rate |
+ * the rate to set |
+ */ |
+ public void setRate(Double rate) |
+ { |
+ this.rate = rate; |
+ } |
+ |
+ /** |
+ * @return the updated |
+ */ |
+ public Date getUpdated() |
+ { |
+ return this.updated; |
+ } |
+ |
+ /** |
+ * @param updated |
+ * the updated to set |
+ */ |
+ public void setUpdated(Date updated) |
+ { |
+ this.updated = updated; |
+ } |
+} |
\ No newline at end of file |
/trunk/src/de/pointedears/converter/db/ConversionData.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/de/pointedears/converter/db/CurrenciesDatabase.java |
=================================================================== |
--- trunk/src/de/pointedears/converter/db/CurrenciesDatabase.java (nonexistent) |
+++ trunk/src/de/pointedears/converter/db/CurrenciesDatabase.java (revision 20) |
@@ -0,0 +1,235 @@ |
+/** |
+ * |
+ */ |
+package de.pointedears.converter.db; |
+ |
+import java.text.DateFormat; |
+import java.text.ParseException; |
+import java.text.SimpleDateFormat; |
+import java.util.Date; |
+import java.util.HashMap; |
+import java.util.Map.Entry; |
+ |
+import android.content.ContentValues; |
+import android.content.Context; |
+import android.database.Cursor; |
+import android.database.sqlite.SQLiteDatabase; |
+import android.database.sqlite.SQLiteException; |
+import android.database.sqlite.SQLiteOpenHelper; |
+import android.util.Log; |
+import de.pointedears.converter.app.CurrenciesActivity; |
+ |
+/** |
+ * @author pelinux |
+ * |
+ */ |
+public class CurrenciesDatabase extends SQLiteOpenHelper |
+{ |
+ |
+ private static final String DATABASE_NAME = "currency.db"; //$NON-NLS-1$ |
+ private static final int DATABASE_VERSION = 8; |
+ |
+ private static final String TABLE = "currency"; //$NON-NLS-1$ |
+ private static final String COLUMN_CURRENCY = "currency1"; //$NON-NLS-1$ |
+ private static final String COLUMN_FACTOR = "factor"; //$NON-NLS-1$ |
+ private static final String COLUMN_UPDATED = "updated"; //$NON-NLS-1$ |
+ |
+ private static HashMap<String, ConversionData> conversionRates = |
+ new HashMap<String, ConversionData>(); |
+ static |
+ { |
+ /* Default conversion rates from Euro (EUR) to other currencies */ |
+ Date epoch = new Date(0); |
+ CurrenciesDatabase.conversionRates |
+ .put(CurrenciesActivity.VALUE_CHF, |
+ new ConversionData(1.3013, epoch)); |
+ CurrenciesDatabase.conversionRates |
+ .put(CurrenciesActivity.VALUE_USD, |
+ new ConversionData(1.3521, epoch)); |
+ } |
+ |
+ private SQLiteDatabase database; |
+ private final DateFormat iso8601format = new SimpleDateFormat( |
+ "yyyy-MM-dd HH:mm:ss"); |
+ |
+ /** |
+ * @param context |
+ * The Activity in which this wrapper is used |
+ */ |
+ public CurrenciesDatabase(Context context) |
+ { |
+ super(context, CurrenciesDatabase.DATABASE_NAME, null, |
+ CurrenciesDatabase.DATABASE_VERSION); |
+ this.readConversionsFromDatabase(); |
+ } |
+ |
+ /* |
+ * (non-Javadoc) |
+ * |
+ * @see |
+ * android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite |
+ * .SQLiteDatabase) |
+ */ |
+ @SuppressWarnings("nls") |
+ @Override |
+ public void onCreate(SQLiteDatabase db) |
+ { |
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + CurrenciesDatabase.TABLE |
+ + " (" + CurrenciesDatabase.COLUMN_CURRENCY + " TEXT" |
+ + ", " + CurrenciesDatabase.COLUMN_FACTOR + " NUMERIC" |
+ + ", " + CurrenciesDatabase.COLUMN_UPDATED |
+ + " TEXT" |
+ + ", CONSTRAINT unique_currency_pair UNIQUE (" |
+ + CurrenciesDatabase.COLUMN_CURRENCY + ") ON CONFLICT REPLACE)"); |
+ |
+ this.writeConversionsToDatabase(db); |
+ } |
+ |
+ /** |
+ * @param db |
+ * The database; <code>null</code> uses the default database |
+ */ |
+ public void writeConversionsToDatabase(SQLiteDatabase db) |
+ { |
+ HashMap<String, ConversionData> currencyConversions = |
+ this.getConversionRates(); |
+ |
+ if (db == null) |
+ { |
+ db = this.database; |
+ } |
+ |
+ if (!db.isOpen()) |
+ { |
+ try |
+ { |
+ db = this.getWritableDatabase(); |
+ } |
+ catch (SQLiteException e) |
+ { |
+ Log.e(this.getClass().toString(), "Could not open database", e); |
+ throw e; |
+ } |
+ } |
+ |
+ if (db.isOpen()) |
+ { |
+ for (Entry<String, ConversionData> factorEntry : currencyConversions |
+ .entrySet()) |
+ { |
+ ContentValues values = new ContentValues(); |
+ values.put(CurrenciesDatabase.COLUMN_CURRENCY, factorEntry.getKey()); |
+ values.put(CurrenciesDatabase.COLUMN_FACTOR, factorEntry.getValue() |
+ .getRate()); |
+ values.put(CurrenciesDatabase.COLUMN_UPDATED, |
+ this.iso8601format.format(factorEntry.getValue() |
+ .getUpdated())); |
+ |
+ /* INSERT suffices here, thanks to ON CONFLICT REPLACE */ |
+ db.insert(CurrenciesDatabase.TABLE, |
+ CurrenciesDatabase.COLUMN_FACTOR, |
+ values); |
+ } |
+ } |
+ } |
+ |
+ /* |
+ * (non-Javadoc) |
+ * |
+ * @see |
+ * android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite |
+ * .SQLiteDatabase, int, int) |
+ */ |
+ @SuppressWarnings("nls") |
+ @Override |
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) |
+ { |
+ /* NOTE: We should migrate an existing database instead */ |
+ db.execSQL("DROP TABLE IF EXISTS " + CurrenciesDatabase.TABLE); |
+ this.onCreate(db); |
+ } |
+ |
+ /** |
+ * @return |
+ */ |
+ public HashMap<String, ConversionData> getConversionRates() |
+ { |
+ return CurrenciesDatabase.conversionRates; |
+ } |
+ |
+ /** |
+ * Reads currency conversions and updates the static currencyConversions field |
+ * of this class |
+ */ |
+ public void readConversionsFromDatabase() |
+ { |
+ try |
+ { |
+ /* Get database connection, but upgrade database first if necessary! */ |
+ this.database = this.getWritableDatabase(); |
+ |
+ Cursor cursor = |
+ this.database.query(true, CurrenciesDatabase.TABLE, null, null, null, |
+ null, null, CurrenciesDatabase.COLUMN_CURRENCY, null); |
+ |
+ if (cursor != null) |
+ { |
+ try |
+ { |
+ int currency1Id = |
+ cursor |
+ .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY); |
+ int factorId = |
+ cursor.getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_FACTOR); |
+ int updatedId = |
+ cursor.getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_UPDATED); |
+ |
+ /* NOTE: Don't change the default values if the table is empty */ |
+ if (cursor.moveToFirst()) |
+ { |
+ HashMap<String, ConversionData> newCurrencyConversions = |
+ new HashMap<String, ConversionData>(); |
+ |
+ do |
+ { |
+ String currencyStr = cursor.getString(currency1Id); |
+ Double factor = cursor.getDouble(factorId); |
+ String updatedStr = cursor.getString(updatedId); |
+ |
+ Date updated = new Date(0); |
+ try |
+ { |
+ if (updatedStr != null) |
+ { |
+ updated = this.iso8601format.parse(updatedStr); |
+ } |
+ } |
+ catch (ParseException e) |
+ { |
+ Log.e(this.getClass().toString(), |
+ "Parsing ISO8601 datetime failed: '" + updatedStr + "'", e); |
+ } |
+ |
+ newCurrencyConversions.put(currencyStr, new ConversionData( |
+ factor, updated)); |
+ } |
+ while (cursor.moveToNext()); |
+ |
+ CurrenciesDatabase.conversionRates = newCurrencyConversions; |
+ } |
+ } |
+ catch (IllegalArgumentException e) |
+ { |
+ Log.e(this.getClass().toString(), "Could not retrieve column index", |
+ e); |
+ } |
+ } |
+ |
+ this.database.close(); |
+ } |
+ catch (SQLiteException e1) |
+ { |
+ Log.e(this.getClass().toString(), "Could not open database", e1); |
+ } |
+ } |
+} |
/trunk/src/de/pointedears/converter/db/CurrenciesDatabase.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java |
=================================================================== |
--- trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java (nonexistent) |
+++ trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java (revision 20) |
@@ -0,0 +1,394 @@ |
+/* |
+ * The contents of this file are subject to the terms |
+ * of the Common Development and Distribution License |
+ * (the "License"). You may not use this file except |
+ * in compliance with the License. |
+ * |
+ * You can obtain a copy of the license at |
+ * https://jaxp.dev.java.net/CDDLv1.0.html. |
+ * See the License for the specific language governing |
+ * permissions and limitations under the License. |
+ * |
+ * When distributing Covered Code, include this CDDL |
+ * HEADER in each file and include the License file at |
+ * https://jaxp.dev.java.net/CDDLv1.0.html |
+ * If applicable add the following below this CDDL HEADER |
+ * with the fields enclosed by brackets "[]" replaced with |
+ * your own identifying information: Portions Copyright |
+ * [year] [name of copyright owner] |
+ */ |
+ |
+/* |
+ * $Id: NamespaceContextHelper.java,v 1.2 2006-03-28 20:54:02 ndw Exp $ |
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. |
+ * Portions Copyright 2010 Thomas 'PointedEars' Lahn |
+ */ |
+ |
+package com.nwalsh.namespace; |
+ |
+import java.util.Enumeration; |
+import java.util.Hashtable; |
+import java.util.Iterator; |
+ |
+import javax.xml.namespace.NamespaceContext; |
+ |
+/* |
+ * NOTE: Skip XML 1.1 validity tests because we don't want to recompile |
+ * org.apache.xerces for Android -- PointedEars |
+ */ |
+// import org.apache.xerces.util.XML11Char; |
+ |
+/** |
+ * Helper implementation of the javax.xml.namespace.NamespaceContext interface. |
+ * |
+ * <p> |
+ * This class implements the JAXP (1.3+) |
+ * {@link javax.xml.namespace.NamespaceContext} interface. This is the interface |
+ * used by the JAXP XPath APIs to establish namespace bindings for XPath |
+ * expressions. |
+ * <p> |
+ * |
+ * <p> |
+ * There are two errors (in retrospect) with respect to the namespace context in |
+ * the XPath API. First, there's no way to construct a new one. Given an XPath |
+ * you can find out what context it is using, but if you want to construct a new |
+ * expression, there's no standard class that you can instantiate to build a new |
+ * context. Second, the {@link javax.xml.namespace.NamespaceContext} interface |
+ * is obviously (again, in retrospect) missing a method that returns an iterator |
+ * that will allow you to find <emph>all</emph> the namespace URIs (and/or |
+ * prefixes, which would be equivalent) in the context. |
+ * </p> |
+ * |
+ * <p> |
+ * This class addresses the first error by providing an object that you can |
+ * instantiate that implements the {@link javax.xml.namespace.NamespaceContext} |
+ * interface. It's not a <emph>standard</emph> class, but it at least saves you |
+ * the trouble of writing it yourself. (Feel free to move it into your own |
+ * package, of course.) |
+ * </p> |
+ * |
+ * <p> |
+ * There's really no way to address the second error. An interface, like |
+ * {@link javax.xml.namespace.NamespaceContext}, is immutable once released into |
+ * the wild in the Java platform. (This is a consequence of backwards |
+ * compatibility rules.) To really address the problem, we'll have to invent a |
+ * new interface or provide an alternative abstract class that implementations |
+ * will be required to use, or something. However, as an experiment, this class |
+ * implements a couple of extra methods that we might wish had been in the |
+ * interface. These methods are carefully identified as non-standard. Having |
+ * them here really isn't all that useful because your underlying XPath |
+ * implementation isn't likely to return instances of this class. |
+ * </p> |
+ * |
+ * <p> |
+ * There are three ways to instantiate this class: |
+ * </p> |
+ * |
+ * <ol> |
+ * <li>The no-argument constructor produces an initially empty namespace |
+ * context.</li> |
+ * <li>Another constructor takes a prefix and URI and produces a namespace |
+ * context with that binding.</li> |
+ * <li>Finally, there's a constructor that takes a hash of namespace/uri pairs |
+ * and produces a namespace context with those initial bindings.</li> |
+ * <li>The obvious constructor, one that takes an existing |
+ * {@link javax.xml.namespace.NamespaceContext} so that you can extend it, isn't |
+ * there because you can't get the current bindings from that interface; see the |
+ * aforementioned bug.</li> |
+ * </ol> |
+ * |
+ * <p> |
+ * After the object has been instantiated, you can call the |
+ * {@link #add(String,String)} method to add additional bindings to the |
+ * namespace context. Because I'm not sure how and where the XPath API |
+ * implementations might save pointers to the context object, I've imposed a |
+ * number of rules designed to make sure that the context remains coherent: |
+ * </p> |
+ * |
+ * <ul> |
+ * <li>Namespace bindings can only be added, not removed.</li> |
+ * <li>Once a prefix is bound, its binding cannot be changed.</li> |
+ * <li>The XML restrictions on the 'xml' prefix, the 'xmlns' prefix, and their |
+ * respective namespace URIs are enforced.</li> |
+ * <li>Namespace prefixes must be valid NCNames (or "" for the default |
+ * namespace). Note that unprefixed element and attribute names in an XPath |
+ * expression can <em>never</em> match a name that's in a namespace. In |
+ * particular, setting the default namespace won't have that effect.</li> |
+ * </ul> |
+ * |
+ * <p> |
+ * Even with these rules, you can't assume that the context is thread safe. |
+ * Don't allow it to be changed while someone else is reading it. |
+ * </p> |
+ * |
+ * <p> |
+ * <b>Other notes:</b> |
+ * </p> |
+ * |
+ * <ul> |
+ * <li>There's no <code>getNamespaceURIs(String prefix)</code> method because |
+ * there can be at most one URI bound to any given prefix. Wrapping an interator |
+ * around the mapping available with {@link #getNamespaceURI(String)} seemed |
+ * silly.</li> |
+ * <li>This class relies on {@link org.apache.xerces.util.XML11Char} to test |
+ * that the prefixes are valid NCNames. Note that this means that they're valid |
+ * XML 1.1 names. XML 1.1 names are a superset of XML 1.0 names and it didn't |
+ * seem worth the extra effort that would be required to allow the user to |
+ * choose XML 1.0 or XML 1.1. You might not think it's worth the effort to check |
+ * at all. Fair enough.</li> |
+ * <li>I've used generics here and there to make the JDK 1.5 compiler stop |
+ * complaining. Just delete them for JDK 1.4 and everything should work fine.</li> |
+ * </ul> |
+ * |
+ * @author <a href="mailto:Norman.Walsh@Sun.COM">Norman Walsh</a> |
+ * @version $Revision: 1.2 $, $Date: 2006-03-28 20:54:02 $ |
+ * @see <a href="http://jaxp.dev.java.net/">Java API for XML Processing</a> |
+ * @see <a href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames"> Namespaces |
+ * in XML</a> |
+ * @see <a href="http://www.w3.org/XML/xml-names-19990114-errata"> Namespaces in |
+ * XML Errata</a> |
+ */ |
+public class NamespaceContextHelper implements NamespaceContext |
+{ |
+ private final Hashtable<String, String> ns = new Hashtable<String, String>(); |
+ |
+ /** |
+ * Creates a new instance of NamespaceContextHelper. |
+ * |
+ * <p> |
+ * Creates an empty namespace context. |
+ * </p> |
+ */ |
+ public NamespaceContextHelper() |
+ { |
+ } |
+ |
+ /** |
+ * Creates a new instance of NamespaceContextHelper. |
+ * |
+ * <p> |
+ * Creates a namespace context with the bindings specified in |
+ * <code>initialNamespaces</code>. |
+ * </p> |
+ */ |
+ public NamespaceContextHelper(Hashtable initialNamespaces) |
+ { |
+ Enumeration keys = initialNamespaces.keys(); |
+ while (keys.hasMoreElements()) |
+ { |
+ String prefix = (String) keys.nextElement(); |
+ String uri = (String) initialNamespaces.get(prefix); |
+ |
+ this.add(prefix, uri); |
+ } |
+ } |
+ |
+ /** |
+ * Creates a new instance of NamespaceContextHelper. |
+ * |
+ * <p> |
+ * Creates a namespace context with the specified <code>prefix</code> bound to |
+ * <code>uri</code>. |
+ * </p> |
+ */ |
+ public NamespaceContextHelper(String prefix, String uri) |
+ { |
+ this.add(prefix, uri); |
+ } |
+ |
+ /** |
+ * Adds a new prefix/uri binding to the namespace context. |
+ * |
+ * @throws NullPointerException |
+ * if the <code>prefix</code> or <code>uri</code> is |
+ * <code>null</code>. |
+ * @throws IllegalArgumentException |
+ * if the caller attempts to change the binding of |
+ * <code>prefix</code>, if the caller attempts to bind the prefix " |
+ * <code>xml</code>" |
+ * or the namespace " |
+ * <code>http://www.w3.org/XML/1998/namespace</code>" incorrectly, |
+ * if the caller attempts to bind the prefix "<code>xmlns</code>" or |
+ * the namespace |
+ * "<code>http://www.w3.org/2000/xmlns</code>", or if the |
+ * <code>prefix</code> is |
+ * not a valid NCName. |
+ */ |
+ public void add(String prefix, String uri) |
+ { |
+ if (prefix == null || uri == null) |
+ { |
+ throw new NullPointerException( |
+ "Null prefix or uri passed to NamespaceContextHelper"); |
+ } |
+ |
+ if (this.ns.containsKey(prefix)) |
+ { |
+ String curURI = this.ns.get(prefix); |
+ if (uri.equals(curURI)) |
+ { |
+ return; |
+ } |
+ throw new IllegalArgumentException( |
+ "Attempt to change binding in NamespaceContextHelper"); |
+ } |
+ |
+ if ("xml".equals(prefix) |
+ && !"http://www.w3.org/XML/1998/namespace".equals(uri)) |
+ { |
+ throw new IllegalArgumentException( |
+ "The prefix 'xml' can only be bound to 'http://www.w3.org/XML/1998/namespace' in NamespaceContextHelper"); |
+ } |
+ |
+ if ("http://www.w3.org/XML/1998/namespace".equals(uri) |
+ && !"xml".equals(prefix)) |
+ { |
+ throw new IllegalArgumentException( |
+ "The namespace 'http://www.w3.org/XML/1998/namespace' can only have the prefix 'xml' in NamespaceContextHelper"); |
+ } |
+ |
+ if ("xmlns".equals(prefix) |
+ || "http://www.w3.org/2000/xmlns".equals(uri)) |
+ { |
+ throw new IllegalArgumentException( |
+ "Neither the prefix 'xmlns' nor the URI 'http://www.w3.org/2000/xmlns' can be bound in NamespaceContextHelper"); |
+ } |
+ |
+ if ("".equals(prefix)) |
+ { |
+ this.ns.put(prefix, uri); |
+ } |
+ else |
+ { |
+ /* |
+ * NOTE: Skip XML 1.1 validity tests because we don't want to recompile |
+ * org.apache.xerces for Android -- PointedEars |
+ */ |
+ // if (XML11Char.isXML11ValidNCName (prefix)) { |
+ this.ns.put(prefix, uri); |
+ // } else { |
+ // throw new IllegalArgumentException |
+ // ("Prefix is not a valid NCName in NamespaceContextHelper"); |
+ // } |
+ } |
+ } |
+ |
+ /** Implements the NamespaceContext getNamespaceURI method. */ |
+ public String getNamespaceURI(String prefix) |
+ { |
+ return this.ns.get(prefix); |
+ } |
+ |
+ /** Implements the NamespaceContext getPrefix method. */ |
+ public String getPrefix(String namespaceURI) |
+ { |
+ if (this.ns.containsValue(namespaceURI)) |
+ { |
+ Enumeration<String> keys = this.ns.keys(); |
+ while (keys.hasMoreElements()) |
+ { |
+ String pfx = keys.nextElement(); |
+ String uri = this.ns.get(pfx); |
+ if (namespaceURI.equals(uri)) |
+ { |
+ return pfx; |
+ } |
+ } |
+ } |
+ return null; |
+ } |
+ |
+ /** |
+ * Implements a <emph>NON STANDARD</emph> method for finding all of the |
+ * prefixes |
+ * in the namespace context. |
+ * |
+ * <p> |
+ * Returns an iterator over all of the prefixes in the namespace context. Note |
+ * that multiple prefixes may be bound to the same URI. |
+ * </p> |
+ */ |
+ public Iterator getPrefixes() |
+ { |
+ return this.getPrefixes(null); |
+ } |
+ |
+ /** Implements the NamespaceContext getPrefixes method. */ |
+ public Iterator getPrefixes(String namespaceURI) |
+ { |
+ return new NSIterator(this.ns, namespaceURI); |
+ } |
+ |
+ /** |
+ * Implements a <emph>NON STANDARD</emph> method for finding all of the |
+ * namespace URIs |
+ * in the namespace context. |
+ * |
+ * <p> |
+ * Returns an iterator over all of the namespace URIs in the namespace |
+ * context. Note that each namespace URI is returned exactly once, even if it |
+ * is bound to several different prefixes. |
+ * </p> |
+ */ |
+ public Iterator getNamespaceURIs() |
+ { |
+ // Make sure each URI is returned at most once... |
+ Hashtable<String, String> uriHash = new Hashtable<String, String>(); |
+ Enumeration<String> keys = this.ns.keys(); |
+ while (keys.hasMoreElements()) |
+ { |
+ String pfx = keys.nextElement(); |
+ String uri = this.ns.get(pfx); |
+ if (!uriHash.containsKey(uri)) |
+ { |
+ uriHash.put(uri, pfx); |
+ } |
+ } |
+ |
+ return new NSIterator(uriHash, null); |
+ } |
+ |
+ /** Implements the Iterator interface over namespace bindings. */ |
+ private class NSIterator implements Iterator |
+ { |
+ private Enumeration<String> keys; |
+ |
+ public NSIterator(Hashtable<String, String> hash, String value) |
+ { |
+ this.keys = hash.keys(); |
+ if (value != null) |
+ { |
+ // We have to copy the hash to get only the keys that have the specified |
+ // value |
+ Hashtable<String, String> vHash = new Hashtable<String, String>(); |
+ while (this.keys.hasMoreElements()) |
+ { |
+ String key = this.keys.nextElement(); |
+ String val = hash.get(key); |
+ if (val.equals(value)) |
+ { |
+ vHash.put(key, val); |
+ } |
+ } |
+ this.keys = vHash.keys(); |
+ } |
+ } |
+ |
+ public boolean hasNext() |
+ { |
+ return this.keys.hasMoreElements(); |
+ } |
+ |
+ public String next() |
+ { |
+ return this.keys.nextElement(); |
+ } |
+ |
+ public void remove() |
+ { |
+ throw new UnsupportedOperationException( |
+ "Cannot remove prefix in NamespaceContextHelper"); |
+ } |
+ } |
+ |
+} |
/trunk/src/com/nwalsh/namespace/NamespaceContextHelper.java |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/src/com/nwalsh/namespace/package.html |
=================================================================== |
--- trunk/src/com/nwalsh/namespace/package.html (nonexistent) |
+++ trunk/src/com/nwalsh/namespace/package.html (revision 20) |
@@ -0,0 +1,49 @@ |
+<?xml version="1.0" encoding="UTF-8"?> |
+<!-- |
+/* |
+ * The contents of this file are subject to the terms |
+ * of the Common Development and Distribution License |
+ * (the "License"). You may not use this file except |
+ * in compliance with the License. |
+ * |
+ * You can obtain a copy of the license at |
+ * https://jaxp.dev.java.net/CDDLv1.0.html. |
+ * See the License for the specific language governing |
+ * permissions and limitations under the License. |
+ * |
+ * When distributing Covered Code, include this CDDL |
+ * HEADER in each file and include the License file at |
+ * https://jaxp.dev.java.net/CDDLv1.0.html |
+ * If applicable add the following below this CDDL HEADER |
+ * with the fields enclosed by brackets "[]" replaced with |
+ * your own identifying information: Portions Copyright |
+ * [year] [name of copyright owner] |
+ */ |
+ |
+/* |
+ * $Id: package.html,v 1.1 2006-03-28 20:54:02 ndw Exp $ |
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. |
+ */ |
+--> |
+<!DOCTYPE html |
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
+ |
+<html xmlns="http://www.w3.org/1999/xhtml"> |
+ |
+<head> |
+ <title>com.nwalsh.namespace</title> |
+ |
+ <meta name="CVS" |
+ content="$Id: package.html,v 1.1 2006-03-28 20:54:02 ndw Exp $" /> |
+ <meta name="AUTHOR" |
+ content="Norman.Walsh@Sun.COM" /> |
+</head> |
+ |
+<body> |
+ |
+<p>This package contains a helper class for the |
+javax.xml.namespace.NamespaceContext interface and the XPath APIs.</p> |
+ |
+</body> |
+</html> |
/trunk/src/com/nwalsh/namespace/package.html |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/values/strings.xml |
=================================================================== |
--- trunk/res/values/strings.xml (nonexistent) |
+++ trunk/res/values/strings.xml (revision 20) |
@@ -0,0 +1,26 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<resources> |
+ <string name="app_name">Converter</string> |
+ <string name="title">Android Unit Converter</string> |
+ <string name="button_clear">Clear</string> |
+ |
+ <string name="activity_lengths">Lengths</string> |
+ |
+ <string name="activity_temperatures">Temperatures</string> |
+ <string name="temperatures_off_scale"><sup>*</sup> Theoretical value off the scale</string> |
+ |
+ <string name="activity_currencies">Currencies</string> |
+ <string name="currencies_CHF">CHF</string> |
+ <string name="currencies_EUR">EUR</string> |
+ <string name="currencies_USD">USD</string> |
+ <string name="currencies_notification"> exchange rates updated to </string> |
+ <string name="currencies_updating">Updating table rates ...</string> |
+ <string name="currencies_currency"><b>Currency</b></string> |
+ <string name="currencies_rate"><b>Rate (1 EUR)</b></string> |
+ <string name="currencies_updated"><b>Updated</b></string> |
+ <string name="currencies_never_updated"><b>Updated</b></string> |
+ <string name="caption_update">Update exchange rates</string> |
+ <string name="option_quit">Quit</string> |
+ |
+ <string name="activity_browser">Browser</string> |
+</resources> |
/trunk/res/values/strings.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/values/arrays.xml |
=================================================================== |
--- trunk/res/values/arrays.xml (nonexistent) |
+++ trunk/res/values/arrays.xml (revision 20) |
@@ -0,0 +1,39 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+ |
+<resources> |
+ <string-array name="length_units_display"> |
+ <item>in (inch)</item> |
+ <item>km (kilometer)</item> |
+ <item>m (meter)</item> |
+ <item>mi (mile)</item> |
+ </string-array> |
+ <string-array name="length_units_values"> |
+ <!-- TODO: Must not be "in", why? --> |
+ <item>inch</item> |
+ <item>km</item> |
+ <item>m</item> |
+ <item>mi</item> |
+ </string-array> |
+ |
+ <string-array name="temperature_units_display"> |
+ <item>°C (Celsius)</item> |
+ <item>°F (Fahrenheit)</item> |
+ <item>K (Kelvin)</item> |
+ </string-array> |
+ <string-array name="temperature_units_values"> |
+ <item>C</item> |
+ <item>F</item> |
+ <item>K</item> |
+ </string-array> |
+ |
+ <string-array name="currency_units_display"> |
+ <item>CHF</item> |
+ <item>EUR</item> |
+ <item>USD</item> |
+ </string-array> |
+ <string-array name="currency_units_values"> |
+ <item>CHF</item> |
+ <item>EUR</item> |
+ <item>USD</item> |
+ </string-array> |
+</resources> |
/trunk/res/values/arrays.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/layout/activity_lengths.xml |
=================================================================== |
--- trunk/res/layout/activity_lengths.xml (nonexistent) |
+++ trunk/res/layout/activity_lengths.xml (revision 20) |
@@ -0,0 +1,37 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
+ android:orientation="vertical" android:layout_height="match_parent" |
+ android:layout_width="match_parent"> |
+ |
+ <LinearLayout android:orientation="horizontal" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_marginTop="10sp"> |
+ <EditText android:id="@+id/edit_value1" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:inputType="numberDecimal" /> |
+ <TextView android:text="=" android:layout_width="wrap_content" |
+ android:layout_height="wrap_content" android:minWidth="10sp" |
+ android:gravity="center" android:textSize="25sp" /> |
+ <EditText android:id="@+id/edit_value2" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:inputType="numberDecimal" /> |
+ </LinearLayout> |
+ |
+ <LinearLayout android:orientation="horizontal" |
+ android:layout_width="match_parent" android:layout_height="wrap_content"> |
+ <Spinner android:id="@+id/spinner_unit1" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:drawSelectorOnTop="true" |
+ android:entries="@array/length_units_display" android:entryValues="@array/length_units_values" /> |
+ <TextView android:text="" android:layout_width="wrap_content" |
+ android:layout_height="wrap_content" android:minWidth="10sp" /> |
+ <Spinner android:id="@+id/spinner_unit2" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:drawSelectorOnTop="true" |
+ android:entries="@array/length_units_display" android:entryValues="@array/length_units_values" /> |
+ </LinearLayout> |
+ |
+ <Button android:text="@string/button_clear" android:id="@+id/lengths_button_clear" |
+ android:layout_height="wrap_content" android:layout_width="100sp" |
+ android:layout_gravity="center_horizontal" /> |
+</LinearLayout> |
/trunk/res/layout/activity_lengths.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/layout/activity_temperatures.xml |
=================================================================== |
--- trunk/res/layout/activity_temperatures.xml (nonexistent) |
+++ trunk/res/layout/activity_temperatures.xml (revision 20) |
@@ -0,0 +1,43 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
+ android:orientation="vertical" android:layout_height="match_parent" |
+ android:layout_width="match_parent"> |
+ |
+ <LinearLayout android:orientation="horizontal" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_marginTop="10sp"> |
+ <EditText android:id="@+id/temperatures_edit_value1" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:inputType="numberSigned|numberDecimal" /> |
+ <TextView android:text="=" android:minWidth="10sp" |
+ android:layout_width="wrap_content" android:layout_height="wrap_content" |
+ android:gravity="center" android:textSize="25sp" /> |
+ <EditText android:id="@+id/temperatures_edit_value2" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:inputType="numberSigned|numberDecimal" /> |
+ </LinearLayout> |
+ |
+ <LinearLayout android:orientation="horizontal" |
+ android:layout_width="match_parent" android:layout_height="wrap_content"> |
+ <Spinner android:id="@+id/temperatures_spinner_unit1" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:drawSelectorOnTop="true" |
+ android:entries="@array/temperature_units_display" |
+ android:entryValues="@array/temperature_units_values" /> |
+ <TextView android:minWidth="10sp" android:layout_width="wrap_content" |
+ android:layout_height="wrap_content" /> |
+ <Spinner android:id="@+id/temperatures_spinner_unit2" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:drawSelectorOnTop="true" |
+ android:entries="@array/temperature_units_display" |
+ android:entryValues="@array/temperature_units_values" /> |
+ </LinearLayout> |
+ |
+ <TextView android:id="@+id/temperatures_text_off_scale" |
+ android:text="@string/temperatures_off_scale" android:layout_width="wrap_content" |
+ android:layout_height="wrap_content" android:visibility="invisible" /> |
+ <Button android:text="@string/button_clear" android:id="@+id/temperatures_button_clear" |
+ android:layout_height="wrap_content" android:layout_width="100sp" |
+ android:layout_gravity="center_horizontal" /> |
+ |
+</LinearLayout> |
/trunk/res/layout/activity_temperatures.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/layout/activity_currencies.xml |
=================================================================== |
--- trunk/res/layout/activity_currencies.xml (nonexistent) |
+++ trunk/res/layout/activity_currencies.xml (revision 20) |
@@ -0,0 +1,53 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
+ android:orientation="vertical" android:layout_height="match_parent" |
+ android:layout_width="match_parent"> |
+ |
+ <LinearLayout android:orientation="horizontal" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_marginTop="10sp"> |
+ <EditText android:id="@+id/currencies_edit_value1" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:inputType="numberDecimal" /> |
+ <TextView android:text="=" android:minWidth="10sp" |
+ android:layout_width="wrap_content" android:layout_height="wrap_content" |
+ android:gravity="center" android:textSize="25sp" /> |
+ <EditText android:id="@+id/currencies_edit_value2" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:inputType="numberDecimal" /> |
+ </LinearLayout> |
+ <LinearLayout android:orientation="horizontal" |
+ android:layout_width="match_parent" android:layout_height="wrap_content"> |
+ <Spinner android:id="@+id/currencies_spinner_unit1" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:drawSelectorOnTop="true" |
+ android:entries="@array/currency_units_display" |
+ android:entryValues="@array/currency_units_values" /> |
+ <TextView android:text="" android:layout_width="wrap_content" |
+ android:layout_height="wrap_content" android:minWidth="10sp" /> |
+ <Spinner android:id="@+id/currencies_spinner_unit2" |
+ android:layout_width="match_parent" android:layout_height="wrap_content" |
+ android:layout_weight="1" android:drawSelectorOnTop="true" |
+ android:entries="@array/currency_units_display" |
+ android:entryValues="@array/currency_units_values" /> |
+ </LinearLayout> |
+ |
+ <Button android:text="@string/button_clear" android:id="@+id/currencies_button_clear" |
+ android:layout_height="wrap_content" android:layout_width="100sp" |
+ android:layout_gravity="center_horizontal"></Button> |
+ <TextView android:id="@+id/currencies_text_updating" |
+ android:text="@string/currencies_updating" android:layout_height="wrap_content" |
+ android:layout_width="match_parent" android:visibility="gone" /> |
+ |
+ <TableLayout android:id="@+id/currencies_table_rates" |
+ android:layout_height="match_parent" android:layout_width="match_parent" |
+ android:stretchColumns="*"> |
+ <View android:layout_height="2dip" android:background="#FF909090" /> |
+ <TableRow> |
+ <TextView android:text="@string/currencies_currency" /> |
+ <TextView android:text="@string/currencies_rate" /> |
+ <TextView android:text="@string/currencies_updated" /> |
+ </TableRow> |
+ <View android:layout_height="1dip" android:background="#FF909090" /> |
+ </TableLayout> |
+</LinearLayout> |
/trunk/res/layout/activity_currencies.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/layout/main.xml |
=================================================================== |
--- trunk/res/layout/main.xml (nonexistent) |
+++ trunk/res/layout/main.xml (revision 20) |
@@ -0,0 +1,20 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
+ android:orientation="vertical" |
+ android:layout_width="fill_parent" |
+ android:layout_height="fill_parent" |
+ > |
+ |
+ <TextView |
+ android:layout_width="fill_parent" |
+ android:layout_height="wrap_content" |
+ android:text="@string/title" |
+ /> |
+ |
+ <ListView android:id="@id/android:list" |
+ android:background="#00FF00" |
+ android:layout_weight="1" |
+ android:drawSelectorOnTop="false" |
+ /> |
+ |
+</LinearLayout> |
/trunk/res/layout/main.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/drawable-hdpi/icon.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/res/drawable-hdpi/icon.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/res/drawable-ldpi/icon.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/res/drawable-ldpi/icon.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/res/drawable-mdpi/icon.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/res/drawable-mdpi/icon.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/res/menu/options.xml |
=================================================================== |
--- trunk/res/menu/options.xml (nonexistent) |
+++ trunk/res/menu/options.xml (revision 20) |
@@ -0,0 +1,11 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
+<!-- android:icon="@drawable/ic_new_game" --> |
+ |
+ <item android:id="@+id/item_options_update" |
+ android:title="@string/caption_update" /> |
+ |
+<!-- android:icon="@drawable/ic_quit" --> |
+<!-- <item android:id="@+id/item_options_quit" |
+ android:title="@string/option_quit" /> --> |
+</menu> |
\ No newline at end of file |
/trunk/res/menu/options.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/res/xml/default_values_old.xml |
=================================================================== |
--- trunk/res/xml/default_values_old.xml (nonexistent) |
+++ trunk/res/xml/default_values_old.xml (revision 20) |
@@ -0,0 +1,24 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<!-- Copyright (C) 2008 The Android Open Source Project |
+ |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
+ you may not use this file except in compliance with the License. |
+ You may obtain a copy of the License at |
+ |
+ http://www.apache.org/licenses/LICENSE-2.0 |
+ |
+ Unless required by applicable law or agreed to in writing, software |
+ distributed under the License is distributed on an "AS IS" BASIS, |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+ See the License for the specific language governing permissions and |
+ limitations under the License. |
+--> |
+ |
+<!-- This is a primitive example showing how to set default values for preferences. |
+ See DefaultValues.java for more information. --> |
+<PreferenceScreen |
+ xmlns:android="http://schemas.android.com/apk/res/android"> |
+ |
+ |
+ |
+</PreferenceScreen> |
/trunk/res/xml/default_values_old.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/AndroidManifest.xml |
=================================================================== |
--- trunk/AndroidManifest.xml (nonexistent) |
+++ trunk/AndroidManifest.xml (revision 20) |
@@ -0,0 +1,52 @@ |
+<?xml version="1.0" encoding="utf-8"?> |
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
+ package="de.pointedears.converter" android:versionName="0.9.1" android:versionCode="17"> |
+ |
+ <uses-sdk android:minSdkVersion="8" /> |
+ <uses-permission android:name="android.permission.VIBRATE" /> |
+ <uses-permission android:name="android.permission.INTERNET" /> |
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
+ |
+ <application android:name="ConverterApplication" |
+ android:label="@string/app_name" android:icon="@drawable/icon" |
+ android:debuggable="true"> |
+ |
+ <activity android:name="MenuActivity" android:label="@string/app_name"> |
+ <intent-filter> |
+ <action android:name="android.intent.action.MAIN" /> |
+ <category android:name="android.intent.category.DEFAULT" /> |
+ <category android:name="android.intent.category.LAUNCHER" /> |
+ </intent-filter> |
+ </activity> |
+ |
+ <activity android:name=".app.LengthsActivity" |
+ android:label="@string/activity_lengths"> |
+ <intent-filter> |
+ <action android:name="android.intent.action.MAIN" /> |
+ <category android:name="android.intent.category.CONVERTER" /> |
+ </intent-filter> |
+ </activity> |
+ |
+ <activity android:name=".app.TemperaturesActivity" |
+ android:label="@string/activity_temperatures"> |
+ <intent-filter> |
+ <action android:name="android.intent.action.MAIN" /> |
+ <category android:name="android.intent.category.CONVERTER" /> |
+ </intent-filter> |
+ </activity> |
+ |
+ <activity android:name=".app.CurrenciesActivity" |
+ android:label="@string/activity_currencies"> |
+ <intent-filter> |
+ <action android:name="android.intent.action.MAIN" /> |
+ <category android:name="android.intent.category.CONVERTER" /> |
+ </intent-filter> |
+ </activity> |
+ |
+ <service android:enabled="true" android:name=".helpers.UpdateService"> |
+ <intent-filter> |
+ <category android:name="android.intent.category.LAUNCHER" /> |
+ </intent-filter> |
+ </service> |
+ </application> |
+</manifest> |
\ No newline at end of file |
/trunk/AndroidManifest.xml |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/bin/Converter.apk |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/bin/Converter.apk |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/bin/resources.ap_ |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/bin/resources.ap_ |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/bin/classes.dex |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/bin/classes.dex |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/Converter.pdf |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/Converter.pdf |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/Architektur.xmi |
=================================================================== |
--- trunk/doc/Architektur.xmi (nonexistent) |
+++ trunk/doc/Architektur.xmi (revision 20) |
@@ -0,0 +1,109 @@ |
+<?xml version="1.0" encoding="UTF-8"?> |
+<XMI verified="false" xmi.version="1.2" timestamp="2011-01-27T20:02:25" xmlns:UML="http://schema.omg.org/spec/UML/1.3"> |
+ <XMI.header> |
+ <XMI.documentation> |
+ <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter> |
+ <XMI.exporterVersion>1.5.8</XMI.exporterVersion> |
+ <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding> |
+ </XMI.documentation> |
+ <XMI.metamodel xmi.version="1.3" href="UML.xml" xmi.name="UML"/> |
+ </XMI.header> |
+ <XMI.content> |
+ <UML:Model isSpecification="false" isAbstract="false" isLeaf="false" xmi.id="m1" isRoot="false" name="UML-Modell"> |
+ <UML:Namespace.ownedElement> |
+ <UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="folder" name="folder"/> |
+ <UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="datatype" name="datatype"/> |
+ <UML:Model stereotype="folder" visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Logical View" name="Logical View"> |
+ <UML:Namespace.ownedElement> |
+ <UML:Package stereotype="folder" visibility="public" isSpecification="false" namespace="Logical View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Datatypes" name="Datatypes"> |
+ <UML:Namespace.ownedElement> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="GuIDPEDWQEpo" name="int"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="KsHFV0NYie4P" name="char"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="fFnZwH5ABLLa" name="bool"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ZY50lsm5j3LE" name="float"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="3gmjKq8x3uXx" name="double"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Ba6KuRvT0yRj" name="short"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="oDoXE7lGlVz3" name="long"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="J61M0YIB6OV0" name="unsigned int"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="nOSlKtU95JgH" name="unsigned short"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="OQXAvVDDZCXZ" name="unsigned long"/> |
+ <UML:DataType stereotype="datatype" visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ipipBDnzaFku" name="string"/> |
+ </UML:Namespace.ownedElement> |
+ </UML:Package> |
+ <UML:Package visibility="public" isSpecification="false" namespace="Logical View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="WiRs8x01SCC1" name="de.pointedears.converter"> |
+ <UML:Namespace.ownedElement> |
+ <UML:Class visibility="public" isSpecification="false" namespace="WiRs8x01SCC1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="OkY7XGujRhg1" name="R"/> |
+ </UML:Namespace.ownedElement> |
+ </UML:Package> |
+ </UML:Namespace.ownedElement> |
+ <XMI.extension xmi.extender="umbrello"> |
+ <diagrams> |
+ <diagram showopsig="1" linecolor="#ff0000" snapx="10" showattribassocs="1" snapy="10" linewidth="0" showattsig="1" showpubliconly="1" showpackage="1" showstereotype="1" name="Klassendiagramm" font="Haettenschweiler,12,-1,5,50,0,0,0,0,0" canvasheight="578" canvaswidth="1136" localid="" snapcsgrid="0" showgrid="0" showops="1" usefillcolor="1" fillcolor="#ffff00" zoom="100" xmi.id="1JN85Vvcj75j" documentation="" showscope="1" snapgrid="0" showatts="1" type="1"> |
+ <widgets> |
+ <packagewidget width="143" showstereotype="1" x="11" y="10" usesdiagramusefillcolor="1" usesdiagramfillcolor="1" isinstance="0" fillcolor="none" height="45" linecolor="none" xmi.id="WiRs8x01SCC1" usefillcolor="1" linewidth="none" font="Haettenschweiler,12,-1,5,75,0,0,0,0,0"/> |
+ <classwidget linecolor="none" usesdiagramfillcolor="1" linewidth="none" showoperations="1" usesdiagramusefillcolor="1" showpubliconly="1" showpackage="1" x="63" showattsigs="601" showstereotype="1" y="223" showattributes="1" font="Haettenschweiler,12,-1,5,75,0,0,0,0,0" width="155" isinstance="0" usefillcolor="1" fillcolor="none" xmi.id="OkY7XGujRhg1" showscope="1" height="33" showopsigs="601"/> |
+ </widgets> |
+ <messages/> |
+ <associations> |
+ <assocwidget indexa="1" indexb="1" visibilityA="0" widgetaid="WiRs8x01SCC1" visibilityB="0" roleBdoc="" roleAdoc="" linecolor="none" changeabilityA="900" totalcounta="2" changeabilityB="900" widgetbid="OkY7XGujRhg1" totalcountb="2" type="509" documentation="" linewidth="none"> |
+ <linepath> |
+ <startpoint startx="154" starty="55"/> |
+ <endpoint endx="154" endy="223"/> |
+ </linepath> |
+ </assocwidget> |
+ </associations> |
+ </diagram> |
+ </diagrams> |
+ </XMI.extension> |
+ </UML:Model> |
+ <UML:Model stereotype="folder" visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Use Case View" name="Use Case View"> |
+ <UML:Namespace.ownedElement/> |
+ </UML:Model> |
+ <UML:Model stereotype="folder" visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Component View" name="Component View"> |
+ <UML:Namespace.ownedElement/> |
+ </UML:Model> |
+ <UML:Model stereotype="folder" visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Deployment View" name="Deployment View"> |
+ <UML:Namespace.ownedElement/> |
+ </UML:Model> |
+ <UML:Model stereotype="folder" visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Entity Relationship Model" name="Entity Relationship Model"> |
+ <UML:Namespace.ownedElement/> |
+ </UML:Model> |
+ </UML:Namespace.ownedElement> |
+ </UML:Model> |
+ </XMI.content> |
+ <XMI.extensions xmi.extender="umbrello"> |
+ <docsettings viewid="1JN85Vvcj75j" uniqueid="psTLmeXMpbIt" documentation=""/> |
+ <listview> |
+ <listitem open="1" type="800" id="Views"> |
+ <listitem open="1" type="801" id="Logical View"> |
+ <listitem open="0" type="807" id="1JN85Vvcj75j" label="Klassendiagramm"/> |
+ <listitem open="1" type="818" id="WiRs8x01SCC1"> |
+ <listitem open="1" type="813" id="OkY7XGujRhg1"> |
+ <listitem open="1" type="814" label="neues_attribut"/> |
+ </listitem> |
+ </listitem> |
+ <listitem open="0" type="830" id="Datatypes"> |
+ <listitem open="1" type="829" id="fFnZwH5ABLLa"/> |
+ <listitem open="1" type="829" id="KsHFV0NYie4P"/> |
+ <listitem open="1" type="829" id="3gmjKq8x3uXx"/> |
+ <listitem open="1" type="829" id="ZY50lsm5j3LE"/> |
+ <listitem open="1" type="829" id="GuIDPEDWQEpo"/> |
+ <listitem open="1" type="829" id="oDoXE7lGlVz3"/> |
+ <listitem open="1" type="829" id="Ba6KuRvT0yRj"/> |
+ <listitem open="1" type="829" id="ipipBDnzaFku"/> |
+ <listitem open="1" type="829" id="J61M0YIB6OV0"/> |
+ <listitem open="1" type="829" id="OQXAvVDDZCXZ"/> |
+ <listitem open="1" type="829" id="nOSlKtU95JgH"/> |
+ </listitem> |
+ </listitem> |
+ <listitem open="1" type="802" id="Use Case View"/> |
+ <listitem open="1" type="821" id="Component View"/> |
+ <listitem open="1" type="827" id="Deployment View"/> |
+ <listitem open="1" type="836" id="Entity Relationship Model"/> |
+ </listitem> |
+ </listview> |
+ <codegeneration> |
+ <codegenerator language="C++"/> |
+ </codegeneration> |
+ </XMI.extensions> |
+</XMI> |
/trunk/doc/Architektur.xmi |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/doc/currencies.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/currencies.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/lengths.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/lengths.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/Converter.zargo |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/Converter.zargo |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/main_menu.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/main_menu.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/Converter.odt |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/Converter.odt |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/temperatures.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/temperatures.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/MenuActivity.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/MenuActivity.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/Datenbank.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/Datenbank.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/Internet.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/Internet.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/UseCase.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/doc/UseCase.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: trunk/doc/notizen.txt |
=================================================================== |
--- trunk/doc/notizen.txt (nonexistent) |
+++ trunk/doc/notizen.txt (revision 20) |
@@ -0,0 +1,4 @@ |
+Tipps: |
+- Bearbeitungsfeld nicht editierbar, dann kommt keine Tastatur; |
+ stattdessen numerische Tastatur als Buttons im Grid |
+- Debug-Zeile einblenden oder |
\ No newline at end of file |
/trunk/doc/notizen.txt |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/doc/Verteilung_ConverterApp.jpg |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = image/jpeg |
/trunk/doc/Verteilung_ConverterApp.jpg |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+image/jpeg |
\ No newline at end of property |
Index: trunk/doc/A-UM_Prototyp_V 01.pdf |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/pdf |
/trunk/doc/A-UM_Prototyp_V 01.pdf |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/pdf |
\ No newline at end of property |
Index: trunk/doc/A-UM_Systemanforderungen_V_03.pdf |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/pdf |
/trunk/doc/A-UM_Systemanforderungen_V_03.pdf |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/pdf |
\ No newline at end of property |
Index: trunk/doc/Masseinheit_umrechnen.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = image/png |
/trunk/doc/Masseinheit_umrechnen.png |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+image/png |
\ No newline at end of property |
Index: trunk/doc/Use-Case-Diagramm.xmi |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/x-uml |
/trunk/doc/Use-Case-Diagramm.xmi |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/x-uml |
\ No newline at end of property |
Index: trunk/doc/A-UM_UseCases_V_02.doc |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/msword |
/trunk/doc/A-UM_UseCases_V_02.doc |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/msword |
\ No newline at end of property |
Index: trunk/doc/A-UM.pdf.zip |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/zip |
/trunk/doc/A-UM.pdf.zip |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/zip |
\ No newline at end of property |
Index: trunk/doc/A-UM_UseCases_V_02.pdf |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/pdf |
/trunk/doc/A-UM_UseCases_V_02.pdf |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/pdf |
\ No newline at end of property |
Index: trunk/doc/A-UM_Systemanforderungen_V_02.doc |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/msword |
/trunk/doc/A-UM_Systemanforderungen_V_02.doc |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/msword |
\ No newline at end of property |
Index: trunk/.classpath |
=================================================================== |
--- trunk/.classpath (nonexistent) |
+++ trunk/.classpath (revision 20) |
@@ -0,0 +1,7 @@ |
+<?xml version="1.0" encoding="UTF-8"?> |
+<classpath> |
+ <classpathentry excluding="com/nwalsh/namespace/" kind="src" path="src"/> |
+ <classpathentry kind="src" path="gen"/> |
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> |
+ <classpathentry kind="output" path="bin"/> |
+</classpath> |
/trunk/.classpath |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/.project |
=================================================================== |
--- trunk/.project (nonexistent) |
+++ trunk/.project (revision 20) |
@@ -0,0 +1,33 @@ |
+<?xml version="1.0" encoding="UTF-8"?> |
+<projectDescription> |
+ <name>Converter</name> |
+ <comment></comment> |
+ <projects> |
+ </projects> |
+ <buildSpec> |
+ <buildCommand> |
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name> |
+ <arguments> |
+ </arguments> |
+ </buildCommand> |
+ <buildCommand> |
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name> |
+ <arguments> |
+ </arguments> |
+ </buildCommand> |
+ <buildCommand> |
+ <name>org.eclipse.jdt.core.javabuilder</name> |
+ <arguments> |
+ </arguments> |
+ </buildCommand> |
+ <buildCommand> |
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name> |
+ <arguments> |
+ </arguments> |
+ </buildCommand> |
+ </buildSpec> |
+ <natures> |
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature> |
+ <nature>org.eclipse.jdt.core.javanature</nature> |
+ </natures> |
+</projectDescription> |
/trunk/.project |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |
Index: trunk/default.properties |
=================================================================== |
--- trunk/default.properties (nonexistent) |
+++ trunk/default.properties (revision 20) |
@@ -0,0 +1,11 @@ |
+# This file is automatically generated by Android Tools. |
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED! |
+# |
+# This file must be checked in Version Control Systems. |
+# |
+# To customize properties used by the Ant build system use, |
+# "build.properties", and override values to adapt the script to your |
+# project structure. |
+ |
+# Project target. |
+target=android-8 |
/trunk/default.properties |
---|
Property changes: |
Added: svn:mime-type |
## -0,0 +1 ## |
+text/plain |
\ No newline at end of property |