Merge lp:~tlnd/financisto/csv-export into lp:~financisto-dev/financisto/trunk

Proposed by tlnd
Status: Merged
Approved by: Denis Solonenko
Approved revision: 60
Merged at revision: 82
Proposed branch: lp:~tlnd/financisto/csv-export
Merge into: lp:~financisto-dev/financisto/trunk
Diff against target: 344 lines (+136/-40)
8 files modified
assets/credits.htm (+1/-1)
res/layout/csv_export.xml (+38/-25)
res/values-de/strings.xml (+5/-3)
res/values/common.xml (+5/-0)
res/values/strings.xml (+2/-0)
src/ru/orangesoftware/financisto/activity/CsvExportActivity.java (+55/-2)
src/ru/orangesoftware/financisto/activity/MainActivity.java (+12/-5)
src/ru/orangesoftware/financisto/export/CSVExport.java (+18/-4)
To merge this branch: bzr merge lp:~tlnd/financisto/csv-export
Reviewer Review Type Date Requested Status
Denis Solonenko Approve
Review via email: mp+35904@code.launchpad.net

Commit message

CSV export: Custom value separator and persistent preferences

Description of the change

Hey,

I tackled the blueprint to "Allow custom separator for values in CSV export". Besides the comma, the user now can also select a semicolon or a tabulator. Additionally, he can choose whether the headers should be exported. Furthermore, the selection is persistent, thus the user does not have to reselect his preferences every time he does an export.

It would be great if somebody could review the code. If necessary, I'm willing to rework it to get it merged eventually.

Regards,
Timo

To post a comment you must log in.
Revision history for this message
Denis Solonenko (denis-solonenko) wrote :

Looks good, thank you! Please integrate into trunk.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'assets/credits.htm'
--- assets/credits.htm 2010-09-04 22:15:18 +0000
+++ assets/credits.htm 2010-09-18 00:44:43 +0000
@@ -31,7 +31,7 @@
31</p>31</p>
32<p><b>Contributors</b></p>32<p><b>Contributors</b></p>
33<p>33<p>
34tlnd<br/>34Timo Lindhorst<br/>
35</p>35</p>
36<p><b>Localizators</b></p>36<p><b>Localizators</b></p>
37<p>37<p>
3838
=== modified file 'res/layout/csv_export.xml'
--- res/layout/csv_export.xml 2010-06-02 15:22:10 +0000
+++ res/layout/csv_export.xml 2010-09-18 00:44:43 +0000
@@ -19,33 +19,46 @@
19 android:text="@string/period"></TextView>19 android:text="@string/period"></TextView>
20 <Button android:layout_height="wrap_content" android:id="@+id/bPeriod"20 <Button android:layout_height="wrap_content" android:id="@+id/bPeriod"
21 android:layout_width="fill_parent"></Button>21 android:layout_width="fill_parent"></Button>
22 <View android:layout_height="1dp" android:background="@drawable/divider_horizontal_dark"
23 android:layout_width="fill_parent" android:layout_marginLeft="10dp"
24 android:layout_marginRight="10dp" />
25
22 <TableLayout android:layout_height="wrap_content"26 <TableLayout android:layout_height="wrap_content"
23 android:layout_width="fill_parent">27 android:layout_width="fill_parent"
24 <TableRow android:layout_width="wrap_content"28 android:stretchColumns="*">
25 android:layout_height="wrap_content">29 <TableRow>
26 <TextView android:layout_height="wrap_content"30 <TextView android:layout_marginLeft="3dp"
27 android:layout_width="fill_parent" android:layout_marginLeft="3dp"31 android:text="@string/decimals"></TextView>
28 android:text="@string/decimals" android:layout_weight="1"></TextView>32 <TextView android:layout_marginLeft="3dp"
29 <TextView android:layout_height="wrap_content"33 android:text="@string/decimal_separator"></TextView>
30 android:layout_width="fill_parent" android:layout_marginLeft="3dp"34 <TextView android:layout_marginLeft="3dp"
31 android:layout_weight="1" android:text="@string/decimal_separator"></TextView>35 android:text="@string/group_separator"></TextView>
32 <TextView android:layout_height="wrap_content"36 </TableRow>
33 android:layout_width="fill_parent" android:layout_marginLeft="3dp"37 <TableRow>
34 android:layout_weight="1" android:text="@string/group_separator"></TextView>38 <Spinner android:id="@+id/spinnerDecimals"
35 </TableRow>39 android:entries="@array/decimals"></Spinner>
36 <TableRow android:layout_width="wrap_content"40 <Spinner android:id="@+id/spinnerDecimalSeparators"
37 android:layout_height="wrap_content">41 android:entries="@array/decimal_separators"></Spinner>
38 <Spinner android:layout_height="wrap_content" android:id="@+id/spinnerDecimals"42 <Spinner android:id="@+id/spinnerGroupSeparators"
39 android:entries="@array/decimals" android:layout_width="wrap_content"43 android:entries="@array/group_separators"></Spinner>
40 android:layout_weight="1"></Spinner>44 </TableRow>
41 <Spinner android:layout_height="wrap_content"45 <View android:layout_height="1dp" android:background="@drawable/divider_horizontal_dark"
42 android:layout_width="wrap_content" android:layout_weight="1"46 android:layout_width="fill_parent" android:layout_marginLeft="10dp"
43 android:id="@+id/spinnerDecimalSeparators" android:entries="@array/decimal_separators"></Spinner>47 android:layout_marginRight="10dp" />
44 <Spinner android:layout_height="wrap_content"48 <TableRow>
45 android:layout_width="wrap_content" android:layout_weight="1"49 <TextView android:layout_marginLeft="3dp"
46 android:id="@+id/spinnerGroupSeparators" android:entries="@array/group_separators"></Spinner>50 android:text="@string/field_separator"></TextView>
51 <TextView android:layout_marginLeft="3dp"
52 android:text="@string/include_header"></TextView>
53 </TableRow>
54 <TableRow>
55 <Spinner android:id="@+id/spinnerFieldSeparator"
56 android:entries="@array/field_separators"></Spinner>
57 <CheckBox android:id="@+id/checkboxIncludeHeader"
58 android:checked="true"></CheckBox>
47 </TableRow>59 </TableRow>
48 </TableLayout>60 </TableLayout>
61
49 <include layout="@layout/ok_cancel_buttons" />62 <include layout="@layout/ok_cancel_buttons" />
5063
51</LinearLayout>64</LinearLayout>
52\ No newline at end of file65\ No newline at end of file
5366
=== modified file 'res/values-de/strings.xml'
--- res/values-de/strings.xml 2010-08-24 11:39:10 +0000
+++ res/values-de/strings.xml 2010-09-18 00:44:43 +0000
@@ -177,9 +177,11 @@
177 <string name="is_default">Standard</string>177 <string name="is_default">Standard</string>
178 <string name="is_included_into_totals">Bei Gesamtrechnung berücksichtigen</string>178 <string name="is_included_into_totals">Bei Gesamtrechnung berücksichtigen</string>
179 <string name="is_included_into_totals_summary">Berücksichtigt die Transaktionen dieses Kontos in der Gesamtrechnung</string>179 <string name="is_included_into_totals_summary">Berücksichtigt die Transaktionen dieses Kontos in der Gesamtrechnung</string>
180 <string name="decimals">\nDezimal</string>180 <string name="decimals">Dezimal-\nstellen</string>
181 <string name="decimal_separator">Dezimal\ntrenner</string>181 <string name="decimal_separator">Dezimal-\ntrenner</string>
182 <string name="group_separator">Gruppen\nstrenner</string>182 <string name="group_separator">Gruppen-\ntrenner</string>
183 <string name="field_separator">Feld-\ntrenner</string>
184 <string name="include_header">Spalten-\nüberschriften</string>
183 <string name="delete_account_confirm">Konto löschen?</string>185 <string name="delete_account_confirm">Konto löschen?</string>
184 <string name="delete_transaction_confirm">Transaktion löschen?</string>186 <string name="delete_transaction_confirm">Transaktion löschen?</string>
185 <string name="delete_budget_confirm">Budget löschen?</string>187 <string name="delete_budget_confirm">Budget löschen?</string>
186188
=== modified file 'res/values/common.xml'
--- res/values/common.xml 2010-09-12 11:06:23 +0000
+++ res/values/common.xml 2010-09-18 00:44:43 +0000
@@ -56,6 +56,11 @@
56 <item>\' \'</item> 56 <item>\' \'</item>
57 <item>\'\'</item>57 <item>\'\'</item>
58 </string-array>58 </string-array>
59 <string-array name="field_separators">
60 <item>\',\'</item>
61 <item>\';\'</item>
62 <item>\'\t\'</item>
63 </string-array>
59 <string-array name="sort_order_entities">64 <string-array name="sort_order_entities">
60 <item>1</item>65 <item>1</item>
61 <item>2</item>66 <item>2</item>
6267
=== modified file 'res/values/strings.xml'
--- res/values/strings.xml 2010-09-12 11:06:23 +0000
+++ res/values/strings.xml 2010-09-18 00:44:43 +0000
@@ -209,6 +209,8 @@
209 <string name="decimals">\nDecimals</string>209 <string name="decimals">\nDecimals</string>
210 <string name="decimal_separator">Decimal\nseparator</string>210 <string name="decimal_separator">Decimal\nseparator</string>
211 <string name="group_separator">Group\nseparator</string>211 <string name="group_separator">Group\nseparator</string>
212 <string name="field_separator">Field\nseparator</string>
213 <string name="include_header">Include\nheader</string>
212 <string name="delete_account_confirm">Delete account?</string>214 <string name="delete_account_confirm">Delete account?</string>
213 <string name="delete_transaction_confirm">Delete transaction?</string>215 <string name="delete_transaction_confirm">Delete transaction?</string>
214 <string name="delete_budget_confirm">Delete budget?</string>216 <string name="delete_budget_confirm">Delete budget?</string>
215217
=== modified file 'src/ru/orangesoftware/financisto/activity/CsvExportActivity.java'
--- src/ru/orangesoftware/financisto/activity/CsvExportActivity.java 2010-06-06 08:16:58 +0000
+++ src/ru/orangesoftware/financisto/activity/CsvExportActivity.java 2010-09-18 00:44:43 +0000
@@ -21,10 +21,12 @@
21import ru.orangesoftware.financisto.utils.DateUtils.PeriodType;21import ru.orangesoftware.financisto.utils.DateUtils.PeriodType;
22import android.app.Activity;22import android.app.Activity;
23import android.content.Intent;23import android.content.Intent;
24import android.content.SharedPreferences;
24import android.os.Bundle;25import android.os.Bundle;
25import android.view.View;26import android.view.View;
26import android.view.View.OnClickListener;27import android.view.View.OnClickListener;
27import android.widget.Button;28import android.widget.Button;
29import android.widget.CheckBox;
28import android.widget.Spinner;30import android.widget.Spinner;
2931
30public class CsvExportActivity extends Activity {32public class CsvExportActivity extends Activity {
@@ -34,6 +36,8 @@
34 public static final String CSV_EXPORT_GROUP_SEPARATOR = "CSV_EXPORT_GROUP_SEPARATOR";36 public static final String CSV_EXPORT_GROUP_SEPARATOR = "CSV_EXPORT_GROUP_SEPARATOR";
35 public static final String CSV_EXPORT_DATE_FORMAT = "CSV_EXPORT_DATE_FORMAT";37 public static final String CSV_EXPORT_DATE_FORMAT = "CSV_EXPORT_DATE_FORMAT";
36 public static final String CSV_EXPORT_TIME_FORMAT = "CSV_EXPORT_TIME_FORMAT";38 public static final String CSV_EXPORT_TIME_FORMAT = "CSV_EXPORT_TIME_FORMAT";
39 public static final String CSV_EXPORT_FIELD_SEPARATOR = "CSV_EXPORT_FIELD_SEPARATOR";
40 public static final String CSV_EXPORT_INCLUDE_HEADER = "CSV_EXPORT_INCLUDE_HEADER";
3741
38 private final WhereFilter filter = WhereFilter.empty();42 private final WhereFilter filter = WhereFilter.empty();
3943
@@ -47,8 +51,6 @@
47 51
48 df = DateUtils.getShortDateFormat(this);52 df = DateUtils.getShortDateFormat(this);
49 53
50 final Spinner groupSeparators = (Spinner)findViewById(R.id.spinnerGroupSeparators);
51 groupSeparators.setSelection(1);
52 filter.put(new DateTimeCriteria(PeriodType.THIS_MONTH));54 filter.put(new DateTimeCriteria(PeriodType.THIS_MONTH));
53 55
54 bPeriod = (Button)findViewById(R.id.bPeriod);56 bPeriod = (Button)findViewById(R.id.bPeriod);
@@ -67,6 +69,9 @@
67 public void onClick(View view) {69 public void onClick(View view) {
68 Spinner decimals = (Spinner)findViewById(R.id.spinnerDecimals);70 Spinner decimals = (Spinner)findViewById(R.id.spinnerDecimals);
69 Spinner decimalSeparators = (Spinner)findViewById(R.id.spinnerDecimalSeparators);71 Spinner decimalSeparators = (Spinner)findViewById(R.id.spinnerDecimalSeparators);
72 Spinner groupSeparators = (Spinner)findViewById(R.id.spinnerGroupSeparators);
73 Spinner fieldSeparators = (Spinner)findViewById(R.id.spinnerFieldSeparator);
74 CheckBox includeHeader = (CheckBox)findViewById(R.id.checkboxIncludeHeader);
7075
71 Intent data = new Intent();76 Intent data = new Intent();
72 filter.toIntent(data);77 filter.toIntent(data);
@@ -74,6 +79,8 @@
74 data.putExtra(CSV_EXPORT_DECIMALS, 2-decimals.getSelectedItemPosition());79 data.putExtra(CSV_EXPORT_DECIMALS, 2-decimals.getSelectedItemPosition());
75 data.putExtra(CSV_EXPORT_DECIMAL_SEPARATOR, decimalSeparators.getSelectedItem().toString());80 data.putExtra(CSV_EXPORT_DECIMAL_SEPARATOR, decimalSeparators.getSelectedItem().toString());
76 data.putExtra(CSV_EXPORT_GROUP_SEPARATOR, groupSeparators.getSelectedItem().toString());81 data.putExtra(CSV_EXPORT_GROUP_SEPARATOR, groupSeparators.getSelectedItem().toString());
82 data.putExtra(CSV_EXPORT_FIELD_SEPARATOR, fieldSeparators.getSelectedItem().toString().charAt(1));
83 data.putExtra(CSV_EXPORT_INCLUDE_HEADER, includeHeader.isChecked());
77 84
78 setResult(RESULT_OK, data);85 setResult(RESULT_OK, data);
79 finish();86 finish();
@@ -92,6 +99,52 @@
92 updatePeriod();99 updatePeriod();
93 }100 }
94101
102 @Override
103 protected void onPause() {
104 super.onPause();
105 savePreferences();
106 }
107
108 @Override
109 protected void onResume() {
110 super.onResume();
111 restorePreferences();
112 }
113
114 private void savePreferences() {
115 Spinner decimals = (Spinner)findViewById(R.id.spinnerDecimals);
116 Spinner decimalSeparators = (Spinner)findViewById(R.id.spinnerDecimalSeparators);
117 Spinner groupSeparators = (Spinner)findViewById(R.id.spinnerGroupSeparators);
118 Spinner fieldSeparators = (Spinner)findViewById(R.id.spinnerFieldSeparator);
119 CheckBox includeHeader = (CheckBox)findViewById(R.id.checkboxIncludeHeader);
120
121 SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
122
123 editor.putInt(CSV_EXPORT_DECIMALS, decimals.getSelectedItemPosition());
124 editor.putInt(CSV_EXPORT_DECIMAL_SEPARATOR, decimalSeparators.getSelectedItemPosition());
125 editor.putInt(CSV_EXPORT_GROUP_SEPARATOR, groupSeparators.getSelectedItemPosition());
126 editor.putInt(CSV_EXPORT_FIELD_SEPARATOR, fieldSeparators.getSelectedItemPosition());
127 editor.putBoolean(CSV_EXPORT_INCLUDE_HEADER, includeHeader.isChecked());
128
129 editor.commit();
130 }
131
132 private void restorePreferences() {
133 Spinner decimals = (Spinner)findViewById(R.id.spinnerDecimals);
134 Spinner decimalSeparators = (Spinner)findViewById(R.id.spinnerDecimalSeparators);
135 Spinner groupSeparators = (Spinner)findViewById(R.id.spinnerGroupSeparators);
136 Spinner fieldSeparators = (Spinner)findViewById(R.id.spinnerFieldSeparator);
137 CheckBox includeHeader = (CheckBox)findViewById(R.id.checkboxIncludeHeader);
138
139 SharedPreferences prefs = getPreferences(MODE_PRIVATE);
140
141 decimals.setSelection(prefs.getInt(CSV_EXPORT_DECIMALS, 0));
142 decimalSeparators.setSelection(prefs.getInt(CSV_EXPORT_DECIMAL_SEPARATOR, 0));
143 groupSeparators.setSelection(prefs.getInt(CSV_EXPORT_GROUP_SEPARATOR, 1));
144 fieldSeparators.setSelection(prefs.getInt(CSV_EXPORT_FIELD_SEPARATOR, 0));
145 includeHeader.setChecked(prefs.getBoolean(CSV_EXPORT_INCLUDE_HEADER, true));
146 }
147
95 private void updatePeriod() {148 private void updatePeriod() {
96 DateTimeCriteria c = filter.getDateTime();149 DateTimeCriteria c = filter.getDateTime();
97 if (c == null) {150 if (c == null) {
98151
=== modified file 'src/ru/orangesoftware/financisto/activity/MainActivity.java'
--- src/ru/orangesoftware/financisto/activity/MainActivity.java 2010-09-12 11:06:23 +0000
+++ src/ru/orangesoftware/financisto/activity/MainActivity.java 2010-09-18 00:44:43 +0000
@@ -145,18 +145,20 @@
145 if (resultCode == RESULT_OK) {145 if (resultCode == RESULT_OK) {
146 WhereFilter filter = WhereFilter.fromIntent(data);146 WhereFilter filter = WhereFilter.fromIntent(data);
147 Currency currency = new Currency();147 Currency currency = new Currency();
148 char fieldSeparator = data.getCharExtra(CsvExportActivity.CSV_EXPORT_FIELD_SEPARATOR, ',');
149 boolean includeHeader = data.getBooleanExtra(CsvExportActivity.CSV_EXPORT_INCLUDE_HEADER, true);
148 currency.symbol = "$";150 currency.symbol = "$";
149 currency.decimals = data.getIntExtra(CsvExportActivity.CSV_EXPORT_DECIMALS, 2);151 currency.decimals = data.getIntExtra(CsvExportActivity.CSV_EXPORT_DECIMALS, 2);
150 currency.decimalSeparator = data.getStringExtra(CsvExportActivity.CSV_EXPORT_DECIMAL_SEPARATOR);152 currency.decimalSeparator = data.getStringExtra(CsvExportActivity.CSV_EXPORT_DECIMAL_SEPARATOR);
151 currency.groupSeparator = data.getStringExtra(CsvExportActivity.CSV_EXPORT_GROUP_SEPARATOR);153 currency.groupSeparator = data.getStringExtra(CsvExportActivity.CSV_EXPORT_GROUP_SEPARATOR);
152 doCsvExport(filter, currency);154 doCsvExport(filter, currency, fieldSeparator, includeHeader);
153 }155 }
154 }156 }
155 }157 }
156 158
157 private void doCsvExport(WhereFilter filter, Currency currency) {159 private void doCsvExport(WhereFilter filter, Currency currency, char fieldSeparaotr, boolean includeHeader) {
158 ProgressDialog d = ProgressDialog.show(this, null, getString(R.string.csv_export_inprogress), true);160 ProgressDialog d = ProgressDialog.show(this, null, getString(R.string.csv_export_inprogress), true);
159 new CsvExportTask(d, filter, currency).execute((String[])null);161 new CsvExportTask(d, filter, currency, fieldSeparaotr, includeHeader).execute((String[])null);
160 }162 }
161 163
162 private void initialLoad() {164 private void initialLoad() {
@@ -499,16 +501,21 @@
499 501
500 private final WhereFilter filter; 502 private final WhereFilter filter;
501 private final Currency currency;503 private final Currency currency;
504 private final char fieldSeparator;
505 private final boolean includeHeader;
502 506
503 public CsvExportTask(ProgressDialog dialog, WhereFilter filter, Currency currency) {507 public CsvExportTask(ProgressDialog dialog, WhereFilter filter, Currency currency,
508 char fieldSeparator, boolean includeHeader) {
504 super(MainActivity.this, dialog, null);509 super(MainActivity.this, dialog, null);
505 this.filter = filter;510 this.filter = filter;
506 this.currency = currency;511 this.currency = currency;
512 this.fieldSeparator = fieldSeparator;
513 this.includeHeader = includeHeader;
507 }514 }
508 515
509 @Override516 @Override
510 protected Object work(Context context, DatabaseAdapter db, String...params) throws Exception {517 protected Object work(Context context, DatabaseAdapter db, String...params) throws Exception {
511 CSVExport export = new CSVExport(db, filter, currency);518 CSVExport export = new CSVExport(db, filter, currency, fieldSeparator, includeHeader);
512 return export.export();519 return export.export();
513 }520 }
514521
515522
=== modified file 'src/ru/orangesoftware/financisto/export/CSVExport.java'
--- src/ru/orangesoftware/financisto/export/CSVExport.java 2010-09-12 11:06:23 +0000
+++ src/ru/orangesoftware/financisto/export/CSVExport.java 2010-09-18 00:44:43 +0000
@@ -33,12 +33,21 @@
3333
34 private final DatabaseAdapter db;34 private final DatabaseAdapter db;
35 private final WhereFilter filter;35 private final WhereFilter filter;
36 private final NumberFormat f; 36 private final NumberFormat f;
37 private final char fieldSeparator;
38 private final boolean includeHeader;
37 39
38 public CSVExport(DatabaseAdapter db, WhereFilter filter, Currency currency) {40 public CSVExport(DatabaseAdapter db, WhereFilter filter, Currency currency,
41 char fieldSeparator, boolean includeHeader) {
39 this.db = db;42 this.db = db;
40 this.filter = filter;43 this.filter = filter;
41 this.f = CurrencyCache.createCurrencyFormat(currency);44 this.f = CurrencyCache.createCurrencyFormat(currency);
45 this.fieldSeparator = fieldSeparator;
46 this.includeHeader = includeHeader;
47 }
48
49 public CSVExport(DatabaseAdapter db, WhereFilter filter, Currency currency) {
50 this(db, filter, currency, ',', true);
42 }51 }
43 52
44 @Override53 @Override
@@ -48,12 +57,17 @@
4857
49 @Override58 @Override
50 protected void writeHeader(BufferedWriter bw) throws IOException {59 protected void writeHeader(BufferedWriter bw) throws IOException {
51 bw.write("date,time,account,amount,currency,category,parent,location,project,note\n");60 if (includeHeader) {
61 Csv.Writer w = new Csv.Writer(bw).delimiter(fieldSeparator);
62 w.value("date").value("time").value("account").value("amount").value("currency");
63 w.value("category").value("parent").value("location").value("project").value("note");
64 w.newLine();
65 }
52 }66 }
5367
54 @Override68 @Override
55 protected void writeBody(BufferedWriter bw) throws IOException {69 protected void writeBody(BufferedWriter bw) throws IOException {
56 Csv.Writer w = new Csv.Writer(bw).delimiter(',');70 Csv.Writer w = new Csv.Writer(bw).delimiter(fieldSeparator);
57 try {71 try {
58 HashMap<Long, Category> categoriesMap = db.getAllCategoriesMap(false);72 HashMap<Long, Category> categoriesMap = db.getAllCategoriesMap(false);
59 Cursor c = db.getBlotter(filter);73 Cursor c = db.getBlotter(filter);