Merge lp:~s-mika/financisto/csv_import into lp:~financisto-dev/financisto/trunk

Proposed by smika
Status: Merged
Merge reported by: smika
Merged at revision: not available
Proposed branch: lp:~s-mika/financisto/csv_import
Merge into: lp:~financisto-dev/financisto/trunk
Diff against target: 1201 lines (+952/-53)
16 files modified
.classpath (+14/-13)
.project (+40/-33)
AndroidManifest.xml (+3/-1)
default.properties (+2/-0)
res/layout/csv_import.xml (+70/-0)
res/values-de/strings.xml (+10/-0)
res/values/common.xml (+2/-1)
res/values/strings.xml (+14/-1)
src/ru/orangesoftware/financisto/activity/AbstractImportActivity.java (+125/-0)
src/ru/orangesoftware/financisto/activity/CsvImportActivity.java (+306/-0)
src/ru/orangesoftware/financisto/activity/MainActivity.java (+78/-3)
src/ru/orangesoftware/financisto/db/DatabaseAdapter.java (+31/-0)
src/ru/orangesoftware/financisto/export/ImportExportAsyncTask.java (+1/-0)
src/ru/orangesoftware/financisto/export/csv/Csv.java (+1/-1)
src/ru/orangesoftware/financisto/imports/csv/CsvImport.java (+200/-0)
src/ru/orangesoftware/financisto/imports/csv/CsvImportOptions.java (+55/-0)
To merge this branch: bzr merge lp:~s-mika/financisto/csv_import
Reviewer Review Type Date Requested Status
Financisto Developers Pending
Review via email: mp+80151@code.launchpad.net

Description of the change

Hi,
this is my first release for csv import function.
I am working now for some weeks with this import feature and it works for me.
Got no feedback from function requestor but think its worth for merging review.
Any feedback is welcome.
Regards
Sebastian

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.classpath'
2--- .classpath 2011-06-29 17:46:15 +0000
3+++ .classpath 2011-10-23 17:45:27 +0000
4@@ -1,13 +1,14 @@
5-<?xml version="1.0" encoding="UTF-8"?>
6-<classpath>
7- <classpathentry kind="src" path="gen"/>
8- <classpathentry kind="src" path="src"/>
9- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/Android 2.2 Google APIs"/>
10- <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
11- <classpathentry kind="lib" path="lib/trace-0.2.0.jar"/>
12- <classpathentry exported="true" kind="lib" path="lib/rfc2445-no-joda.jar" sourcepath="H:/Work/Java/Android/google-rfc-2445-read-only/src"/>
13- <classpathentry kind="lib" path="lib/GDocsAPI.jar"/>
14- <classpathentry kind="lib" path="lib/CWAC-WakefulIntentService.jar"/>
15- <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Android 2.2 Google APIs"/>
16- <classpathentry kind="output" path="bin"/>
17-</classpath>
18+<?xml version="1.0" encoding="UTF-8"?>
19+<classpath>
20+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/Java SE 6 (MacOS X Default)"/>
21+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
22+ <classpathentry kind="lib" path="lib/trace-0.2.0.jar"/>
23+ <classpathentry exported="true" kind="lib" path="lib/rfc2445-no-joda.jar" sourcepath="H:/Work/Java/Android/google-rfc-2445-read-only/src"/>
24+ <classpathentry kind="lib" path="lib/GDocsAPI.jar"/>
25+ <classpathentry kind="lib" path="lib/CWAC-WakefulIntentService.jar"/>
26+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Android 2.2 Google APIs"/>
27+ <classpathentry kind="src" path="src"/>
28+ <classpathentry kind="src" path="gen"/>
29+ <classpathentry kind="src" path="GreenDroid_src"/>
30+ <classpathentry kind="output" path="bin"/>
31+</classpath>
32
33=== modified file '.project'
34--- .project 2011-02-20 19:39:08 +0000
35+++ .project 2011-10-23 17:45:27 +0000
36@@ -1,33 +1,40 @@
37-<?xml version="1.0" encoding="UTF-8"?>
38-<projectDescription>
39- <name>Financisto</name>
40- <comment></comment>
41- <projects>
42- </projects>
43- <buildSpec>
44- <buildCommand>
45- <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
46- <arguments>
47- </arguments>
48- </buildCommand>
49- <buildCommand>
50- <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
51- <arguments>
52- </arguments>
53- </buildCommand>
54- <buildCommand>
55- <name>org.eclipse.jdt.core.javabuilder</name>
56- <arguments>
57- </arguments>
58- </buildCommand>
59- <buildCommand>
60- <name>com.android.ide.eclipse.adt.ApkBuilder</name>
61- <arguments>
62- </arguments>
63- </buildCommand>
64- </buildSpec>
65- <natures>
66- <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
67- <nature>org.eclipse.jdt.core.javanature</nature>
68- </natures>
69-</projectDescription>
70+<?xml version="1.0" encoding="UTF-8"?>
71+<projectDescription>
72+ <name>Financisto</name>
73+ <comment></comment>
74+ <projects>
75+ </projects>
76+ <buildSpec>
77+ <buildCommand>
78+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
79+ <arguments>
80+ </arguments>
81+ </buildCommand>
82+ <buildCommand>
83+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
84+ <arguments>
85+ </arguments>
86+ </buildCommand>
87+ <buildCommand>
88+ <name>org.eclipse.jdt.core.javabuilder</name>
89+ <arguments>
90+ </arguments>
91+ </buildCommand>
92+ <buildCommand>
93+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
94+ <arguments>
95+ </arguments>
96+ </buildCommand>
97+ </buildSpec>
98+ <natures>
99+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
100+ <nature>org.eclipse.jdt.core.javanature</nature>
101+ </natures>
102+ <linkedResources>
103+ <link>
104+ <name>GreenDroid_src</name>
105+ <type>2</type>
106+ <locationURI>_android_GreenDroid_612cb559/src</locationURI>
107+ </link>
108+ </linkedResources>
109+</projectDescription>
110
111=== modified file 'AndroidManifest.xml'
112--- AndroidManifest.xml 2011-09-19 12:45:09 +0000
113+++ AndroidManifest.xml 2011-10-23 17:45:27 +0000
114@@ -183,7 +183,9 @@
115
116 <activity android:name=".activity.SplitTransactionActivity" android:label="@string/split_transaction" />
117 <activity android:name=".activity.SplitTransferActivity" android:label="@string/split_transfer"/>
118-
119+ <activity android:name=".activity.CsvImportActivity" android:label="@string/csv_import"
120+ android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden"/>
121+
122 </application>
123
124 <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="5"/>
125
126=== modified file 'default.properties'
127--- default.properties 2011-02-20 19:39:08 +0000
128+++ default.properties 2011-10-23 17:45:27 +0000
129@@ -12,3 +12,5 @@
130 # Project target.
131 target=Google Inc.:Google APIs:8
132 apk-configurations=
133+android.library=false
134+android.library.reference.1=../../workspace/GreenDroid
135
136=== added file 'res/drawable/ic_launcher_folder_small.png'
137Binary files res/drawable/ic_launcher_folder_small.png 1970-01-01 00:00:00 +0000 and res/drawable/ic_launcher_folder_small.png 2011-10-23 17:45:27 +0000 differ
138=== added file 'res/layout/csv_import.xml'
139--- res/layout/csv_import.xml 1970-01-01 00:00:00 +0000
140+++ res/layout/csv_import.xml 2011-10-23 17:45:27 +0000
141@@ -0,0 +1,70 @@
142+<!--
143+ Copyright (c) 2010 Denis Solonenko.
144+ All rights reserved. This program and the accompanying materials
145+ are made available under the terms of the GNU Public License v2.0
146+ which accompanies this distribution, and is available at
147+ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
148+
149+ Contributors:
150+ Denis Solonenko - initial API and implementation
151+-->
152+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
153+ android:layout_width="fill_parent" android:layout_height="fill_parent"
154+ android:orientation="vertical" android:padding="3dp">
155+ <View android:layout_height="1dp" android:background="@drawable/divider_horizontal_dark"
156+ android:layout_width="fill_parent" android:layout_marginLeft="10dp"
157+ android:layout_marginRight="10dp" />
158+ <TextView android:layout_height="wrap_content"
159+ android:layout_width="fill_parent" android:layout_marginLeft="3dp" android:text="@string/file_name"/>
160+ <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
161+ <EditText android:layout_weight="1" android:layout_width="0dip" android:layout_height="wrap_content" android:id="@+id/edFilename">
162+ <requestFocus></requestFocus>
163+ </EditText>
164+ <ImageButton android:layout_width="wrap_content" android:layout_gravity="center_vertical" android:src="@drawable/ic_launcher_folder_small" android:id="@+id/btn_browse" android:layout_height="wrap_content"></ImageButton>
165+ </LinearLayout>
166+ <TextView android:layout_height="wrap_content"
167+ android:layout_width="fill_parent" android:layout_marginLeft="3dp"
168+ android:text="@string/accounts"/>
169+ <Button android:layout_height="wrap_content" android:id="@+id/bAccounts"
170+ android:layout_width="fill_parent" android:text="@string/choose_account"/>
171+ <View android:layout_height="1dp" android:background="@drawable/divider_horizontal_dark"
172+ android:layout_width="fill_parent" android:layout_marginLeft="10dp"
173+ android:layout_marginRight="10dp" />
174+
175+ <TableLayout android:layout_height="wrap_content"
176+ android:layout_width="fill_parent"
177+ android:stretchColumns="*">
178+ <TableRow>
179+ <TextView android:layout_marginLeft="3dp"
180+ android:text="@string/decimals"/>
181+ <TextView android:layout_marginLeft="3dp"
182+ android:text="@string/decimal_separator"/>
183+ <TextView android:layout_marginLeft="3dp"
184+ android:text="@string/group_separator"/>
185+ </TableRow>
186+ <TableRow>
187+ <Spinner android:id="@+id/spinnerDecimals"
188+ android:entries="@array/decimals"/>
189+ <Spinner android:id="@+id/spinnerDecimalSeparators"
190+ android:entries="@array/decimal_separators"/>
191+ <Spinner android:id="@+id/spinnerGroupSeparators"
192+ android:entries="@array/group_separators"/>
193+ </TableRow>
194+ <TableRow>
195+ <TextView android:layout_marginLeft="3dp" android:text="@string/field_separator"></TextView>
196+ </TableRow>
197+ <TableRow>
198+ <Spinner android:entries="@array/field_separators" android:id="@+id/spinnerFieldSeparator"></Spinner>
199+ </TableRow>
200+ <View android:layout_height="1dp" android:background="@drawable/divider_horizontal_dark"
201+ android:layout_width="fill_parent" android:layout_marginLeft="10dp"
202+ android:layout_marginRight="10dp" />
203+ </TableLayout>
204+ <TextView android:layout_height="wrap_content"
205+ android:layout_width="fill_parent" android:layout_marginLeft="3dp"
206+ android:text="@string/date_format"/>
207+ <Spinner android:layout_height="wrap_content" android:layout_width="fill_parent"
208+ android:id="@+id/spinnerDateFormats" android:entries="@array/date_format_values"/>
209+
210+ <include layout="@layout/ok_cancel_buttons" />
211+</LinearLayout>
212\ No newline at end of file
213
214=== modified file 'res/values-de/strings.xml'
215--- res/values-de/strings.xml 2011-09-12 22:55:24 +0000
216+++ res/values-de/strings.xml 2011-10-23 17:45:27 +0000
217@@ -653,6 +653,11 @@
218 <string name="date_format">Datumsformat</string>
219 <string name="pin_protection_lock_transaction">Neue(n) Transaktion\\Transfer sperren</string>
220 <string name="pin_protection_lock_transaction_summary">\'Neue Transaktion\'- und \'Neuer Transfer\'-Bildschirm mit PIN sperren</string>
221+ <string name="file_name">Dateiname</string>
222+ <string name="chosse_account">Wähle Konto</string>
223+ <string name="no_filemanager_installed">Kein Dateimanager installiert</string>
224+ <string name="csv_import">CSV Import</string>
225+ <string name="csv_import_inprogress">CSV Import in Bearbeitung</string>
226
227 <string name="split">[Split-Buchung...]</string>
228 <string name="split_transaction">[Split-Transaktion]</string>
229@@ -670,5 +675,10 @@
230 <string name="unsplit_adjust_last_summary">Letzte Buchung anpassen</string>
231
232 <string name="add_transfer">Transfer hinzufügen</string>
233+ <string name="select_filename">Wähle Import Dateiname</string>
234+ <string name="import_file_not_found">Import Datei nicht gefunden</string>
235+ <string name="import_unknown_category">Unbekannte Kategorie in Importdatei</string>
236+ <string name="import_unknown_project">Unbekanntes Projekt in Importdatei</string>
237+ <string name="import_wrong_currency">Falsche Währung in Importdatei</string>
238
239 </resources>
240
241=== modified file 'res/values/common.xml'
242--- res/values/common.xml 2011-07-25 17:44:44 +0000
243+++ res/values/common.xml 2011-10-23 17:45:27 +0000
244@@ -154,7 +154,8 @@
245 <string-array name="date_format_values">
246 <item>dd/MM/yyyy</item>
247 <item>MM/dd/yyyy</item>
248- <item>yyyy-MM-dd</item>
249+ <item>yyyy-MM-dd</item>
250+ <item>dd.MM.yyyy</item>
251 </string-array>
252
253 <string-array name="unsplit_quick_action_items">
254
255=== modified file 'res/values/strings.xml'
256--- res/values/strings.xml 2011-07-25 17:44:44 +0000
257+++ res/values/strings.xml 2011-10-23 17:45:27 +0000
258@@ -659,6 +659,19 @@
259 <string name="unsplit_adjust_last">Last</string>
260 <string name="unsplit_adjust_last_summary">Adjust last</string>
261
262- <string name="add_transfer">Add Transfer</string>
263+ <string name="add_transfer">Add Transfer</string>
264+ <string name="file_name">File name</string>
265+ <string name="choose_account">Choose account</string>
266+ <string name="no_filemanager_installed">No filemanager installed</string>
267+ <string name="csv_import">CSV Import</string>
268+ <string name="csv_import_inprogress">CSV Import in progress</string>
269+ <string name="select_filename">Select Import filename</string>
270+ <string name="import_file_not_found">Import file not found</string>
271+ <string name="import_unknown_category">Unknown category in import file</string>
272+ <string name="import_unknown_project">Unknown project in import file</string>
273+ <string name="import_wrong_currency">Wrong currency in import file</string>
274+ <string name="import_illegal_argument_exception">Illegal argument exception</string>
275+ <string name="import_parse_error">Parsing error in import file</string>
276+ <string name="csv_import_error">CSV import error</string>
277
278 </resources>
279
280=== added file 'src/ru/orangesoftware/financisto/activity/AbstractImportActivity.java'
281--- src/ru/orangesoftware/financisto/activity/AbstractImportActivity.java 1970-01-01 00:00:00 +0000
282+++ src/ru/orangesoftware/financisto/activity/AbstractImportActivity.java 2011-10-23 17:45:27 +0000
283@@ -0,0 +1,125 @@
284+/*******************************************************************************
285+ * Copyright (c) 2010 Denis Solonenko.
286+ * All rights reserved. This program and the accompanying materials
287+ * are made available under the terms of the GNU Public License v2.0
288+ * which accompanies this distribution, and is available at
289+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
290+ *
291+ * Contributors:
292+ * Denis Solonenko - initial API and implementation
293+ ******************************************************************************/
294+package ru.orangesoftware.financisto.activity;
295+
296+import android.app.Activity;
297+import android.content.ActivityNotFoundException;
298+import android.content.Intent;
299+import android.net.Uri;
300+import android.os.Bundle;
301+import android.util.Log;
302+import android.view.View;
303+import android.view.View.OnClickListener;
304+import android.widget.Button;
305+import android.widget.EditText;
306+import android.widget.ImageButton;
307+import android.widget.Toast;
308+import ru.orangesoftware.financisto.R;
309+import ru.orangesoftware.financisto.blotter.WhereFilter;
310+import ru.orangesoftware.financisto.blotter.WhereFilter.DateTimeCriteria;
311+import ru.orangesoftware.financisto.utils.DateUtils;
312+import ru.orangesoftware.financisto.utils.PinProtection;
313+import ru.orangesoftware.financisto.utils.DateUtils.Period;
314+import ru.orangesoftware.financisto.utils.DateUtils.PeriodType;
315+
316+import java.text.DateFormat;
317+import java.util.Date;
318+
319+public abstract class AbstractImportActivity extends Activity {
320+
321+ public static final int IMPORT_FILENAME_REQUESTCODE=0xff;
322+ public static final int IMPORT_XSLFILENAME_REQUESTCODE=0xfe;
323+
324+ private final int layoutId;
325+ private DateFormat df;
326+ protected ImageButton bBrowse;
327+ protected EditText edFilename;
328+
329+
330+ public AbstractImportActivity(int layoutId) {
331+ this.layoutId = layoutId;
332+ }
333+
334+ @Override
335+ protected void onCreate(Bundle savedInstanceState) {
336+ super.onCreate(savedInstanceState);
337+ setContentView(layoutId);
338+
339+ df = DateUtils.getShortDateFormat(this);
340+
341+ bBrowse = (ImageButton) findViewById(R.id.btn_browse);
342+ bBrowse.setOnClickListener(new View.OnClickListener() {
343+ @Override
344+ public void onClick(View v) {
345+ openFile();
346+ }
347+ });
348+ edFilename=(EditText) findViewById(R.id.edFilename);
349+
350+ internalOnCreate();
351+ }
352+
353+ protected void openFile() {
354+ String filename = edFilename.getText().toString();
355+
356+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
357+ intent.addCategory(Intent.CATEGORY_OPENABLE);
358+
359+ intent.setData(Uri.parse("file://" + filename));
360+ intent.setType("*/*");
361+
362+ try {
363+ startActivityForResult(intent,IMPORT_FILENAME_REQUESTCODE);
364+ } catch (ActivityNotFoundException e) {
365+ // No compatible file manager was found.
366+ Toast.makeText(this, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show();
367+ }
368+
369+ }
370+
371+
372+ protected abstract void internalOnCreate();
373+
374+ protected abstract void updateResultIntentFromUi(Intent data);
375+
376+
377+ @Override
378+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
379+ if (requestCode ==IMPORT_FILENAME_REQUESTCODE) {
380+ if (resultCode == RESULT_OK && data != null) {
381+ String filename = data.getDataString();
382+ if (filename != null) {
383+ if (filename.startsWith("file://")) {
384+ filename = filename.substring(7);
385+ }
386+ filename = Uri.decode(filename);
387+ edFilename.setText(filename);
388+ savePreferences();
389+ }
390+ }
391+ }
392+
393+ }
394+
395+ @Override
396+ protected void onPause() {
397+ super.onPause();
398+ PinProtection.lock(this);
399+ }
400+
401+ @Override
402+ protected void onResume() {
403+ super.onResume();
404+ PinProtection.unlock(this);
405+ }
406+
407+ abstract void savePreferences();
408+}
409
410=== added file 'src/ru/orangesoftware/financisto/activity/CsvImportActivity.java'
411--- src/ru/orangesoftware/financisto/activity/CsvImportActivity.java 1970-01-01 00:00:00 +0000
412+++ src/ru/orangesoftware/financisto/activity/CsvImportActivity.java 2011-10-23 17:45:27 +0000
413@@ -0,0 +1,306 @@
414+/*******************************************************************************
415+ * Copyright (c) 2010 Denis Solonenko.
416+ * All rights reserved. This program and the accompanying materials
417+ * are made available under the terms of the GNU Public License v2.0
418+ * which accompanies this distribution, and is available at
419+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
420+ *
421+ * Contributors:
422+ * Denis Solonenko - initial API and implementation
423+ ******************************************************************************/
424+package ru.orangesoftware.financisto.activity;
425+
426+import java.util.ArrayList;
427+import java.util.List;
428+
429+import ru.orangesoftware.financisto.R;
430+import ru.orangesoftware.financisto.db.DatabaseAdapter;
431+import ru.orangesoftware.financisto.model.Account;
432+import ru.orangesoftware.financisto.model.MultiChoiceItem;
433+import ru.orangesoftware.financisto.utils.CurrencyExportPreferences;
434+import ru.orangesoftware.financisto.view.NodeInflater;
435+import android.app.AlertDialog;
436+import android.app.ProgressDialog;
437+import android.content.ActivityNotFoundException;
438+import android.content.Context;
439+import android.content.DialogInterface;
440+import android.content.Intent;
441+import android.content.SharedPreferences;
442+import android.net.Uri;
443+import android.text.TextUtils;
444+import android.view.LayoutInflater;
445+import android.view.View;
446+import android.view.View.OnClickListener;
447+import android.widget.Button;
448+import android.widget.EditText;
449+import android.widget.ImageButton;
450+import android.widget.ListAdapter;
451+import android.widget.Spinner;
452+import android.widget.Toast;
453+
454+
455+
456+public class CsvImportActivity extends AbstractImportActivity implements ActivityLayoutListener {
457+
458+ public static final String CSV_IMPORT_SELECTED_ACCOUNT = "CSV_IMPORT_SELECTED_ACCOUNT";
459+ public static final String CSV_IMPORT_DATE_FORMAT = "CSV_IMPORT_DATE_FORMAT";
460+ public static final String CSV_IMPORT_FILENAME="CSV_IMPORT_FILENAME";
461+ public static final String CSV_IMPORT_FIELD_SEPARATOR="CSV_IMPORT_FIELD_SEPARATOR";
462+
463+ private final CurrencyExportPreferences currencyPreferences = new CurrencyExportPreferences("csv");
464+
465+ private DatabaseAdapter db;
466+ private ArrayList<Account> accounts;
467+ private int checkedAccount=1;
468+ private Button bAccounts;
469+
470+
471+ public CsvImportActivity() {
472+ super(R.layout.csv_import);
473+ }
474+
475+ @Override
476+ protected void internalOnCreate() {
477+ LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
478+ NodeInflater nodeInflater = new NodeInflater(layoutInflater);
479+ final ActivityLayout activityLayout = new ActivityLayout(nodeInflater, this);
480+
481+ db = new DatabaseAdapter(this);
482+ db.open();
483+
484+ accounts = db.em().getAllAccountsList();
485+
486+
487+ bAccounts = (Button)findViewById(R.id.bAccounts);
488+ bAccounts.setOnClickListener(new View.OnClickListener() {
489+ @Override
490+ public void onClick(View view) {
491+ int count = accounts.size();
492+ String[] accountsTitles = new String[count];
493+ for (int i=0; i<count; i++) {
494+ accountsTitles[i] = accounts.get(i).getTitle();
495+ if (accounts.get(i).isChecked()){
496+ checkedAccount=i;
497+ }
498+ }
499+
500+ AlertDialog show = new AlertDialog.Builder(CsvImportActivity.this)
501+ .setTitle(R.string.accounts)
502+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener(){
503+ public void onClick(DialogInterface dialog, int which) {
504+ for (int i=0; i<accounts.size(); i++) {
505+ if (i==checkedAccount){
506+ accounts.get(i).setChecked(true);
507+ }else
508+ accounts.get(i).setChecked(false);
509+ }
510+ bAccounts.setText(accounts.get(checkedAccount).getTitle());
511+ savePreferences();
512+ }
513+
514+ })
515+ .setSingleChoiceItems(accountsTitles, checkedAccount, new DialogInterface.OnClickListener(){
516+ public void onClick(DialogInterface dialog, int which) {
517+ checkedAccount=which;
518+ }
519+ })
520+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener(){
521+ @Override
522+ public void onClick(DialogInterface dialog, int which) {
523+
524+ }
525+ })
526+ .show();
527+
528+ }
529+ });
530+
531+ Button bOk = (Button)findViewById(R.id.bOK);
532+ bOk.setOnClickListener(new OnClickListener() {
533+ public void onClick(View view) {
534+ if (edFilename.getText().toString().equals("")) {
535+ Toast.makeText(CsvImportActivity.this, R.string.select_filename, Toast.LENGTH_SHORT).show();
536+ return;
537+ }
538+ if (checkedAccount==-1) {
539+ Toast.makeText(CsvImportActivity.this, R.string.choose_account, Toast.LENGTH_SHORT).show();
540+ return;
541+ }
542+
543+ Intent data = new Intent();
544+ updateResultIntentFromUi(data);
545+ setResult(RESULT_OK, data);
546+ finish();
547+ }
548+ });
549+
550+ Button bCancel = (Button)findViewById(R.id.bCancel);
551+ bCancel.setOnClickListener(new OnClickListener() {
552+ public void onClick(View view) {
553+ setResult(RESULT_CANCELED);
554+ finish();
555+ }
556+ });
557+
558+ }
559+
560+
561+
562+ @Override
563+ protected void onDestroy() {
564+ db.close();
565+ super.onDestroy();
566+ }
567+
568+ @Override
569+ public void onSelected(int id, List<? extends MultiChoiceItem> items) {
570+ List<Account> selectedAccounts = getSelectedAccounts();
571+ if (selectedAccounts.size() == 0 || selectedAccounts.size() == accounts.size()) {
572+ bAccounts.setText(R.string.choose_account);
573+ checkedAccount=-1;
574+ } else {
575+ StringBuilder sb = new StringBuilder();
576+ for (Account a : selectedAccounts) {
577+ appendItemTo(sb, a.title);
578+ checkedAccount=1;
579+ }
580+ bAccounts.setText(sb.toString());
581+ }
582+ }
583+
584+ private ArrayList<Account> getSelectedAccounts() {
585+ ArrayList<Account> selected = new ArrayList<Account>();
586+ for (MultiChoiceItem i : accounts) {
587+ if (i.isChecked()) {
588+ selected.add((Account)i);
589+ }
590+ }
591+ return selected;
592+ }
593+
594+ private void appendItemTo(StringBuilder sb, String s) {
595+ if (sb.length() > 0) {
596+ sb.append(", ");
597+ }
598+ sb.append(s);
599+ }
600+
601+ @Override
602+ public void onSelectedPos(int id, int selectedPos) {
603+ }
604+
605+ @Override
606+ public void onSelectedId(int id, long selectedId) {
607+ }
608+
609+ @Override
610+ public void onClick(View view) {
611+ }
612+
613+ @Override
614+ protected void updateResultIntentFromUi(Intent data) {
615+ currencyPreferences.updateIntentFromUI(this, data);
616+ long[] selectedIds = getSelectedAccountsIds();
617+ if (selectedIds.length > 0) {
618+ data.putExtra(CSV_IMPORT_SELECTED_ACCOUNT, selectedIds);
619+ }
620+ Spinner dateFormats = (Spinner)findViewById(R.id.spinnerDateFormats);
621+ data.putExtra(CSV_IMPORT_DATE_FORMAT, dateFormats.getSelectedItem().toString());
622+ data.putExtra(CSV_IMPORT_FILENAME, edFilename.getText().toString());
623+ Spinner fieldSeparator = (Spinner)findViewById(R.id.spinnerFieldSeparator);
624+ data.putExtra(CSV_IMPORT_FIELD_SEPARATOR, fieldSeparator.getSelectedItem().toString().charAt(1));
625+
626+ }
627+
628+ private long[] getSelectedAccountsIds() {
629+ List<Long> selectedAccounts = new ArrayList<Long>(accounts.size());
630+ for (Account account : accounts) {
631+ if (account.isChecked()) {
632+ selectedAccounts.add(account.id);
633+ }
634+ }
635+ int count = selectedAccounts.size();
636+ long[] ids = new long[count];
637+ for (int i=0; i<count; i++) {
638+ ids[i] = selectedAccounts.get(i);
639+ }
640+ return ids;
641+ }
642+
643+ @Override
644+ protected void onPause() {
645+ super.onPause();
646+ savePreferences();
647+ }
648+
649+ @Override
650+ protected void onResume() {
651+ super.onResume();
652+ restorePreferences();
653+ }
654+
655+ void savePreferences() {
656+ SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
657+
658+ currencyPreferences.savePreferences(this, editor);
659+
660+ long[] selectedIds = getSelectedAccountsIds();
661+ if (selectedIds.length > 0) {
662+ editor.putString(CSV_IMPORT_SELECTED_ACCOUNT, joinSelectedAccounts(selectedIds));
663+ }
664+
665+ Spinner dateFormats = (Spinner)findViewById(R.id.spinnerDateFormats);
666+ editor.putInt(CSV_IMPORT_DATE_FORMAT, dateFormats.getSelectedItemPosition());
667+ editor.putString(CSV_IMPORT_FILENAME, edFilename.getText().toString());
668+ Spinner fieldSeparator = (Spinner)findViewById(R.id.spinnerFieldSeparator);
669+ editor.putInt(CSV_IMPORT_FIELD_SEPARATOR, fieldSeparator.getSelectedItemPosition());
670+ editor.commit();
671+ }
672+
673+ private String joinSelectedAccounts(long[] selectedIds) {
674+ StringBuilder sb = new StringBuilder();
675+ for (long selectedId : selectedIds) {
676+ if (sb.length() > 0) sb.append(",");
677+ sb.append(selectedId);
678+ }
679+ return sb.toString();
680+ }
681+
682+ private void restorePreferences() {
683+ SharedPreferences preferences = getPreferences(MODE_PRIVATE);
684+
685+ currencyPreferences.restorePreferences(this, preferences);
686+
687+ String selectedIds = preferences.getString(CSV_IMPORT_SELECTED_ACCOUNT, "");
688+ parseSelectedAccounts(selectedIds);
689+ onSelected(-1, accounts);
690+
691+ Spinner dateFormats = (Spinner)findViewById(R.id.spinnerDateFormats);
692+ dateFormats.setSelection(preferences.getInt(CSV_IMPORT_DATE_FORMAT, 0));
693+ edFilename=(EditText)findViewById(R.id.edFilename);
694+ edFilename.setText(preferences.getString(CSV_IMPORT_FILENAME,""));
695+ Spinner fieldSeparator = (Spinner)findViewById(R.id.spinnerFieldSeparator);
696+ fieldSeparator.setSelection(preferences.getInt(CSV_IMPORT_FIELD_SEPARATOR, 0));
697+ }
698+
699+ private void parseSelectedAccounts(String selectedIds) {
700+ try {
701+ TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
702+ splitter.setString(selectedIds);
703+ for (String s : splitter) {
704+ long id = Long.parseLong(s);
705+ for (Account account : accounts) {
706+ if (account.id == id) {
707+ account.setChecked(true);
708+ break;
709+ }
710+ }
711+ }
712+ } catch (Exception ex) {
713+ // ignore
714+ }
715+ }
716+
717+
718+
719+}
720
721=== modified file 'src/ru/orangesoftware/financisto/activity/MainActivity.java'
722--- src/ru/orangesoftware/financisto/activity/MainActivity.java 2011-07-25 17:44:44 +0000
723+++ src/ru/orangesoftware/financisto/activity/MainActivity.java 2011-10-23 17:45:27 +0000
724@@ -57,6 +57,8 @@
725 import ru.orangesoftware.financisto.export.csv.CsvExportTask;
726 import ru.orangesoftware.financisto.export.qif.QifExportOptions;
727 import ru.orangesoftware.financisto.export.qif.QifExportTask;
728+import ru.orangesoftware.financisto.imports.csv.CsvImport;
729+import ru.orangesoftware.financisto.imports.csv.CsvImportOptions;
730 import ru.orangesoftware.financisto.utils.*;
731
732 import java.io.IOException;
733@@ -68,7 +70,8 @@
734
735 private static final int ACTIVITY_CSV_EXPORT = 2;
736 private static final int ACTIVITY_QIF_EXPORT = 3;
737-
738+ private static final int ACTIVITY_CSV_IMPORT = 4;
739+
740 private static final int MENU_PREFERENCES = Menu.FIRST+1;
741 private static final int MENU_ABOUT = Menu.FIRST+2;
742 private static final int MENU_BACKUP = Menu.FIRST+3;
743@@ -81,7 +84,8 @@
744 private static final int MENU_MASS_OP = Menu.FIRST+10;
745 private static final int MENU_DONATE = Menu.FIRST+11;
746 private static final int MENU_QIF_EXPORT = Menu.FIRST+12;
747-
748+ private static final int MENU_CSV_IMPORT = Menu.FIRST+13;
749+
750 private final HashMap<String, Boolean> started = new HashMap<String, Boolean>();
751
752 @Override
753@@ -139,7 +143,12 @@
754 QifExportOptions options = QifExportOptions.fromIntent(data);
755 doQifExport(options);
756 }
757- }
758+ } else if (requestCode == ACTIVITY_CSV_IMPORT) {
759+ if (resultCode == RESULT_OK) {
760+ CsvImportOptions options = CsvImportOptions.fromIntent(data);
761+ doCsvImport(options);
762+ }
763+ }
764 }
765
766 private void doCsvExport(CsvExportOptions options) {
767@@ -147,6 +156,12 @@
768 new CsvExportTask(this, progressDialog, options).execute();
769 }
770
771+ private void doCsvImport(CsvImportOptions options) {
772+ ProgressDialog progressDialog = ProgressDialog.show(this, null, getString(R.string.csv_import_inprogress), true);
773+ new CsvImportTask(this, progressDialog, options).execute();
774+ }
775+
776+
777 private void doQifExport(QifExportOptions options) {
778 ProgressDialog progressDialog = ProgressDialog.show(this, null, getString(R.string.qif_export_inprogress), true);
779 new QifExportTask(this, progressDialog, options).execute();
780@@ -246,6 +261,7 @@
781 menu.addSubMenu(0, MENU_BACKUP_GDOCS, 0, R.string.backup_database_gdocs);
782 menu.addSubMenu(0, MENU_RESTORE_GDOCS, 0, R.string.restore_database_gdocs);
783 menu.addSubMenu(0, MENU_CSV_EXPORT, 0, R.string.csv_export);
784+ menu.addSubMenu(0, MENU_CSV_IMPORT, 0, R.string.csv_import);
785 menu.addSubMenu(0, MENU_QIF_EXPORT, 0, R.string.qif_export);
786 menu.addSubMenu(0, MENU_DONATE, 0, R.string.donate);
787 menu.addSubMenu(0, MENU_ABOUT, 0, R.string.about);
788@@ -305,6 +321,9 @@
789 case MENU_RESTORE_GDOCS:
790 doImportFromGoogleDocs();
791 break;
792+ case MENU_CSV_IMPORT:
793+ doCsvImport();
794+ break;
795 }
796 return false;
797 }
798@@ -394,6 +413,11 @@
799 startActivityForResult(intent, ACTIVITY_CSV_EXPORT);
800 }
801
802+ private void doCsvImport() {
803+ Intent intent = new Intent(this, CsvImportActivity.class);
804+ startActivityForResult(intent, ACTIVITY_CSV_IMPORT);
805+ }
806+
807 private void doQifExport() {
808 Intent intent = new Intent(this, QifExportActivity.class);
809 startActivityForResult(intent, ACTIVITY_QIF_EXPORT);
810@@ -653,6 +677,57 @@
811
812 }
813
814+ public class CsvImportTask extends ImportExportAsyncTask {
815+
816+ private final CsvImportOptions options;
817+
818+ public CsvImportTask(Context context, ProgressDialog dialog, CsvImportOptions options) {
819+
820+ //super(context, dialog, null);
821+ super(MainActivity.this, dialog, new ImportExportAsyncTaskListener(){
822+ public void onCompleted() {
823+ onTabChanged(getTabHost().getCurrentTabTag());
824+ }
825+ });
826+
827+ this.options = options;
828+ }
829+
830+
831+ @Override
832+ protected Object work(Context context, DatabaseAdapter db, String...params) throws Exception {
833+ try{
834+ CsvImport csvimport = new CsvImport(db, options,context);
835+ return csvimport.doImport();
836+ }catch(Exception e)
837+ {
838+ if(e.getMessage().equals("Import file not found"))
839+ handler.sendEmptyMessage(R.string.import_file_not_found);
840+ else if(e.getMessage().equals("Unknown category in import line"))
841+ handler.sendEmptyMessage(R.string.import_unknown_category);
842+ else if(e.getMessage().equals("Unknown project in import line"))
843+ handler.sendEmptyMessage(R.string.import_unknown_project);
844+ else if(e.getMessage().equals("Wrong currency in import line"))
845+ handler.sendEmptyMessage(R.string.import_wrong_currency);
846+ else if(e.getMessage().equals("IllegalArgumentException"))
847+ handler.sendEmptyMessage(R.string.import_illegal_argument_exception);
848+ else if(e.getMessage().equals("ParseException"))
849+ handler.sendEmptyMessage(R.string.import_parse_error);
850+ else
851+ handler.sendEmptyMessage(R.string.csv_import_error);
852+ throw e;
853+ }
854+
855+ }
856+
857+ @Override
858+ protected String getSuccessMessage(Object result) {
859+ return String.valueOf(result);
860+ }
861+
862+ }
863+
864+
865 private enum MenuEntities implements EntityEnum {
866
867 CURRENCIES(R.string.currencies, R.drawable.menu_entities_currencies, CurrencyListActivity.class),
868
869=== modified file 'src/ru/orangesoftware/financisto/db/DatabaseAdapter.java'
870--- src/ru/orangesoftware/financisto/db/DatabaseAdapter.java 2011-09-02 18:49:54 +0000
871+++ src/ru/orangesoftware/financisto/db/DatabaseAdapter.java 2011-10-23 17:45:27 +0000
872@@ -596,6 +596,37 @@
873 }
874 }
875
876+ public Category getCategory(String title) {
877+ Cursor c = db.query(V_CATEGORY, CategoryViewColumns.NORMAL_PROJECTION,
878+ CategoryViewColumns.title+"=?", new String[]{String.valueOf(title)}, null, null, null);
879+ try {
880+ if (c.moveToNext()) {
881+ Category cat = new Category();
882+ cat.id = c.getInt(CategoryViewColumns._id.ordinal());
883+ cat.title = title;
884+ cat.level = c.getInt(CategoryViewColumns.level.ordinal());
885+ cat.left = c.getInt(CategoryViewColumns.left.ordinal());
886+ cat.right = c.getInt(CategoryViewColumns.right.ordinal());
887+ cat.type = c.getInt(CategoryViewColumns.type.ordinal());
888+ String s = String.valueOf(cat.id);
889+ Cursor c2 = db.query(GET_PARENT_SQL, new String[]{CategoryColumns._id.name()}, null, new String[]{s,s},
890+ null, null, null, "1");
891+ try {
892+ if (c2.moveToFirst()) {
893+ cat.parent = new Category(c2.getLong(0));
894+ }
895+ } finally {
896+ c2.close();
897+ }
898+ return cat;
899+ } else {
900+ return null;
901+ }
902+ } finally {
903+ c.close();
904+ }
905+ }
906+
907 public Category getCategoryByLeft(long left) {
908 Cursor c = db.query(V_CATEGORY, CategoryViewColumns.NORMAL_PROJECTION,
909 CategoryViewColumns.left+"=?", new String[]{String.valueOf(left)}, null, null, null);
910
911=== modified file 'src/ru/orangesoftware/financisto/export/ImportExportAsyncTask.java'
912--- src/ru/orangesoftware/financisto/export/ImportExportAsyncTask.java 2011-02-20 19:39:08 +0000
913+++ src/ru/orangesoftware/financisto/export/ImportExportAsyncTask.java 2011-10-23 17:45:27 +0000
914@@ -17,6 +17,7 @@
915 import android.content.Context;
916 import android.os.AsyncTask;
917 import android.util.Log;
918+import android.widget.Toast;
919
920 public abstract class ImportExportAsyncTask extends AsyncTask<String, Void, Object> {
921
922
923=== modified file 'src/ru/orangesoftware/financisto/export/csv/Csv.java'
924--- src/ru/orangesoftware/financisto/export/csv/Csv.java 2011-02-20 19:39:08 +0000
925+++ src/ru/orangesoftware/financisto/export/csv/Csv.java 2011-10-23 17:45:27 +0000
926@@ -215,7 +215,7 @@
927 return result;
928 }
929
930- private String unmarkDoubleQuotes(String s) { return s.replace(impossibleString, "\""); }
931+ private String unmarkDoubleQuotes(String s) { return s.replace(impossibleString, "\"\""); }
932 private String markDoubleQuotes(String s) { return s.replace("\"\"", impossibleString); }
933
934 private String removeLeadingSpaces(String s) { return s.replaceFirst(" +", ""); }
935
936=== added directory 'src/ru/orangesoftware/financisto/imports'
937=== added directory 'src/ru/orangesoftware/financisto/imports/csv'
938=== added file 'src/ru/orangesoftware/financisto/imports/csv/CsvImport.java'
939--- src/ru/orangesoftware/financisto/imports/csv/CsvImport.java 1970-01-01 00:00:00 +0000
940+++ src/ru/orangesoftware/financisto/imports/csv/CsvImport.java 2011-10-23 17:45:27 +0000
941@@ -0,0 +1,200 @@
942+package ru.orangesoftware.financisto.imports.csv;
943+
944+import static ru.orangesoftware.financisto.db.DatabaseHelper.ACCOUNT_TABLE;
945+import static ru.orangesoftware.financisto.db.DatabaseHelper.V_BLOTTER_FOR_ACCOUNT;
946+
947+import java.io.File;
948+import java.io.FileNotFoundException;
949+import java.io.FileReader;
950+import java.io.IOException;
951+import java.lang.reflect.Field;
952+import java.text.ParseException;
953+import java.text.ParsePosition;
954+import java.text.SimpleDateFormat;
955+import java.util.Date;
956+import java.util.HashMap;
957+import java.util.List;
958+
959+import javax.xml.parsers.ParserConfigurationException;
960+import javax.xml.parsers.SAXParser;
961+import javax.xml.parsers.SAXParserFactory;
962+
963+import org.xml.sax.SAXException;
964+import org.xml.sax.helpers.DefaultHandler;
965+
966+import android.app.AlertDialog;
967+import android.content.ContentValues;
968+import android.content.Context;
969+import android.database.Cursor;
970+import android.os.Looper;
971+import android.util.Log;
972+import android.widget.Toast;
973+
974+import ru.orangesoftware.financisto.R;
975+import ru.orangesoftware.financisto.activity.AccountActivity;
976+import ru.orangesoftware.financisto.db.DatabaseAdapter;
977+import ru.orangesoftware.financisto.db.DatabaseHelper.AccountColumns;
978+import ru.orangesoftware.financisto.db.DatabaseHelper.BlotterColumns;
979+import ru.orangesoftware.financisto.export.csv.Csv;
980+import ru.orangesoftware.financisto.model.Account;
981+import ru.orangesoftware.financisto.model.Category;
982+import ru.orangesoftware.financisto.model.Project;
983+import ru.orangesoftware.financisto.model.Transaction;
984+
985+public class CsvImport {
986+ private final DatabaseAdapter db;
987+ private final CsvImportOptions options;
988+ private final Account account;
989+ private Context context;
990+ private char decimalSeparator;
991+ private char groupSeparator;
992+
993+ public CsvImport(DatabaseAdapter db, CsvImportOptions options,
994+ Context context) {
995+ this.db = db;
996+ this.options = options;
997+ this.account = db.em().getAccount(options.selectedAccounts[0]);
998+ this.context = context;
999+ this.decimalSeparator = options.currency.decimalSeparator.charAt(1);
1000+ this.groupSeparator = options.currency.groupSeparator.charAt(1);
1001+ }
1002+
1003+ public Object doImport() throws Exception {
1004+ String csvFilename = options.filename;
1005+ Csv.Reader reader;
1006+ Boolean isTableHeadLine = false;
1007+ List<String> tableHeadLine = null;
1008+ List<Project> projectList = db.em().list(Project.class);
1009+ try {
1010+ reader = new Csv.Reader(new FileReader(csvFilename)).delimiter(
1011+ options.fieldSeparator).ignoreComments(true);
1012+ List<String> line;
1013+ int countLine = 0;
1014+ while ((line = reader.readLine()) != null) {
1015+ // get table head line
1016+ countLine = countLine++;
1017+ if (isTableHeadLine) {
1018+ Transaction transaction = new Transaction();
1019+ transaction.dateTime = 0;
1020+ transaction.fromAccountId=this.account.id;
1021+ long time = 0;
1022+
1023+ int countOfColumns = line.size();
1024+ for (int i = 0; i < countOfColumns; i++) {
1025+ String transactionField = tableHeadLine.get(i);
1026+ /*
1027+ * ToDo:workaround needed for reimport of files from CsvExport function - first column (date) in header shows nonprintable
1028+ * Character which is not replaceable by "trim" function. Have to look in CsvExport function
1029+ */
1030+ transactionField = myTrim(transactionField);
1031+ if (!transactionField.equals("")) {
1032+ Log.d("CsvImport",
1033+ transactionField + ":" + line.get(i) + " ");
1034+ try {
1035+ String fieldValue = line.get(i);
1036+ if (!fieldValue.equals("")) {
1037+
1038+ if (transactionField.equals("date")) {
1039+ transaction.dateTime = options.dateFormat
1040+ .parse(fieldValue).getTime();
1041+ Log.d("CsvImport", "date:"
1042+ + transaction.dateTime);
1043+ } else if (transactionField.equals("time")) {
1044+ SimpleDateFormat format = new SimpleDateFormat(
1045+ "HH:mm:ss");
1046+ ParsePosition p = new ParsePosition(0);
1047+ time = format.parse(fieldValue, p)
1048+ .getTime();
1049+ Log.d("CsvImport", "time:" + time);
1050+
1051+ } else if (transactionField
1052+ .equals("amount")) {
1053+ fieldValue = fieldValue.replace(
1054+ groupSeparator+"", "");
1055+ fieldValue = fieldValue.replace(
1056+ decimalSeparator, '.');
1057+ double fromAmount = Double
1058+ .parseDouble(fieldValue);
1059+ Double fromAmountDouble = new Double(
1060+ fromAmount) * 100.0;
1061+ long amount = fromAmountDouble
1062+ .longValue();
1063+ transaction.fromAmount = amount;
1064+ } else if (transactionField.equals("payee")) {
1065+ transaction.payeeId = db
1066+ .insertPayee(fieldValue);
1067+ } else if (transactionField
1068+ .equals("category")) {
1069+ Category cat = db
1070+ .getCategory(fieldValue);
1071+ if (cat != null) {
1072+ transaction.categoryId = cat.id;
1073+ } else {
1074+ throw new Exception(
1075+ "Unknown category in import line");
1076+ }
1077+ } else if (transactionField.equals("note")) {
1078+ transaction.note = fieldValue;
1079+ } else if (transactionField
1080+ .equals("project")) {
1081+ //Test for "No project" just to be compatible for importing of files from CsvExport function
1082+ if (!fieldValue.equals("No project")) {
1083+ for (int i1 = 0; i1 < projectList
1084+ .size(); i1++) {
1085+ if (projectList.get(i1)
1086+ .getTitle()
1087+ .equals(fieldValue)) {
1088+ transaction.projectId = projectList
1089+ .get(i1).getId();
1090+ break;
1091+ }
1092+ }
1093+ if (transaction.projectId == 0) {
1094+ throw new Exception(
1095+ "Unknown project in import line");
1096+ }
1097+ }
1098+
1099+ } else if (transactionField
1100+ .equals("currency")) {
1101+ if (!account.currency.name
1102+ .equals(fieldValue)) {
1103+ throw new Exception(
1104+ "Wrong currency in import line");
1105+ }
1106+ }
1107+ }
1108+ } catch (IllegalArgumentException e) {
1109+ throw new Exception("IllegalArgumentException");
1110+ } catch (ParseException e) {
1111+ throw new Exception("ParseException");
1112+ }
1113+ }
1114+ }
1115+ transaction.dateTime = transaction.dateTime + time;
1116+ long id = db.insertOrUpdate(transaction);
1117+ Log.d("CsvImport", "Insert transactionId:" + id);
1118+ } else {
1119+ // first line of csv-file is table headline
1120+ isTableHeadLine = true;
1121+ tableHeadLine = line;
1122+ }
1123+ }
1124+ } catch (FileNotFoundException e) {
1125+ throw new Exception("Import file not found");
1126+ }
1127+
1128+ return options.filename + " imported!";
1129+ }
1130+
1131+ //Workaround function which is needed for reimport of CsvExport files
1132+ public String myTrim(String s) {
1133+ if (Character.isLetter(s.charAt(0))) {
1134+ return s;
1135+ } else {
1136+ return s.substring(1);
1137+ }
1138+
1139+ }
1140+
1141+}
1142
1143=== added file 'src/ru/orangesoftware/financisto/imports/csv/CsvImportOptions.java'
1144--- src/ru/orangesoftware/financisto/imports/csv/CsvImportOptions.java 1970-01-01 00:00:00 +0000
1145+++ src/ru/orangesoftware/financisto/imports/csv/CsvImportOptions.java 2011-10-23 17:45:27 +0000
1146@@ -0,0 +1,55 @@
1147+/*
1148+ * Copyright (c) 2011 Denis Solonenko.
1149+ * All rights reserved. This program and the accompanying materials
1150+ * are made available under the terms of the GNU Public License v2.0
1151+ * which accompanies this distribution, and is available at
1152+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
1153+ */
1154+
1155+package ru.orangesoftware.financisto.imports.csv;
1156+
1157+import android.content.Intent;
1158+import ru.orangesoftware.financisto.activity.CsvExportActivity;
1159+import ru.orangesoftware.financisto.activity.CsvImportActivity;
1160+import ru.orangesoftware.financisto.blotter.WhereFilter;
1161+import ru.orangesoftware.financisto.model.Currency;
1162+import ru.orangesoftware.financisto.utils.CurrencyExportPreferences;
1163+
1164+import java.text.SimpleDateFormat;
1165+
1166+/**
1167+ * Created by IntelliJ IDEA.
1168+ * User: Denis Solonenko
1169+ * Date: 7/10/11 7:01 PM
1170+ */
1171+public class CsvImportOptions {
1172+
1173+ public static final String DEFAULT_DATE_FORMAT = "dd.MM.yyyy";
1174+
1175+ public final Currency currency;
1176+ public final SimpleDateFormat dateFormat;
1177+ public final char fieldSeparator;
1178+ public final WhereFilter filter;
1179+ public final long[] selectedAccounts;
1180+ public final String filename;
1181+
1182+ public CsvImportOptions(Currency currency, String dateFormat, long[] selectedAccounts, WhereFilter filter,String filename,char fieldSeparator) {
1183+ this.currency = currency;
1184+ this.dateFormat = new SimpleDateFormat(dateFormat);
1185+ this.selectedAccounts = selectedAccounts;
1186+ this.filter = filter;
1187+ this.filename=filename;
1188+ this.fieldSeparator=fieldSeparator;
1189+ }
1190+
1191+ public static CsvImportOptions fromIntent(Intent data) {
1192+ WhereFilter filter = WhereFilter.fromIntent(data);
1193+ Currency currency = CurrencyExportPreferences.fromIntent(data, "csv");
1194+ char fieldSeparator = data.getCharExtra(CsvImportActivity.CSV_IMPORT_FIELD_SEPARATOR, ',');
1195+ String dateFormat = data.getStringExtra(CsvImportActivity.CSV_IMPORT_DATE_FORMAT);
1196+ long[] selectedAccounts = data.getLongArrayExtra(CsvImportActivity.CSV_IMPORT_SELECTED_ACCOUNT);
1197+ String filename =data.getStringExtra(CsvImportActivity.CSV_IMPORT_FILENAME);
1198+ return new CsvImportOptions(currency, dateFormat, selectedAccounts, filter,filename,fieldSeparator);
1199+ }
1200+
1201+}