Subversion Repositories ES

Compare Revisions

Last modification

Ignore whitespace Rev 1 → Rev HEAD

/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">&#xA0;exchange rates updated to&#xA0;</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