Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #332 from matburt/widget

Quick capture widget
  • Loading branch information...
commit 1e731824d5e428451c018764350c81afdec0015a 2 parents bbf9155 + 8a1148f
Matthew Jones authored
Showing with 1,889 additions and 22 deletions.
  1. +23 −1 AndroidManifest.xml
  2. BIN  libs/CWAC-MergeAdapter.jar
  3. BIN  libs/CWAC-SackOfViewsAdapter.jar
  4. BIN  res/drawable-hdpi/widget_capture.png
  5. +16 −0 res/drawable/capture_widget_text_bg.xml
  6. +8 −0 res/layout/agenda.xml
  7. +166 −0 res/layout/agenda_entry_setting.xml
  8. +10 −0 res/layout/agenda_header.xml
  9. +55 −0 res/layout/agenda_settings.xml
  10. +8 −0 res/layout/agendas.xml
  11. +25 −0 res/layout/capture_widget.xml
  12. +53 −0 res/layout/capture_widget_config.xml
  13. +15 −0 res/menu/agenda_block.xml
  14. +15 −0 res/menu/agenda_entry.xml
  15. +6 −2 res/menu/outline_menu.xml
  16. +2 −1  res/values/strings.xml
  17. +10 −0 res/xml/capture_widget_provider.xml
  18. +59 −0 src/com/matburt/mobileorg/Gui/Agenda/AgendaActivity.java
  19. +156 −0 src/com/matburt/mobileorg/Gui/Agenda/AgendaEntrySetting.java
  20. +77 −0 src/com/matburt/mobileorg/Gui/Agenda/AgendaFragment.java
  21. +169 −0 src/com/matburt/mobileorg/Gui/Agenda/AgendaSettings.java
  22. +15 −0 src/com/matburt/mobileorg/Gui/Agenda/AgendasActivity.java
  23. +126 −0 src/com/matburt/mobileorg/Gui/Agenda/AgendasFragment.java
  24. +151 −0 src/com/matburt/mobileorg/Gui/Agenda/BlockAgenda.java
  25. +148 −0 src/com/matburt/mobileorg/Gui/Agenda/OrgAgenda.java
  26. +133 −0 src/com/matburt/mobileorg/Gui/Agenda/OrgQueryBuilder.java
  27. +14 −3 src/com/matburt/mobileorg/Gui/Capture/EditActivity.java
  28. +12 −0 src/com/matburt/mobileorg/Gui/Capture/EditHost.java
  29. +5 −5 src/com/matburt/mobileorg/Gui/Capture/HeadingFragment.java
  30. +9 −7 src/com/matburt/mobileorg/Gui/Capture/LocationFragment.java
  31. +8 −0 src/com/matburt/mobileorg/Gui/Outline/OutlineActivity.java
  32. +6 −0 src/com/matburt/mobileorg/Gui/Outline/OutlineAdapter.java
  33. +10 −2 src/com/matburt/mobileorg/Gui/Outline/OutlineItem.java
  34. +94 −0 src/com/matburt/mobileorg/Gui/TabsAdapter.java
  35. +110 −0 src/com/matburt/mobileorg/Gui/Widget/CaptureWidgetConfig.java
  36. +79 −0 src/com/matburt/mobileorg/Gui/Widget/CaptureWidgetProvider.java
  37. +1 −1  src/com/matburt/mobileorg/{Services → Gui/Widget}/MobileOrgWidget.java
  38. +1 −0  src/com/matburt/mobileorg/Services/CalendarSyncService.java
  39. +43 −0 src/com/matburt/mobileorg/util/OrgUtils.java
  40. +51 −0 tests/src/com/matburt/mobileorg/test/Gui/AgendaTests.java
24 AndroidManifest.xml
View
@@ -24,7 +24,7 @@
android:value=".Gui.SearchActivity" />
<receiver
- android:name=".Services.MobileOrgWidget"
+ android:name=".Gui.Widget.MobileOrgWidget"
android:label="MobileOrg Tasks" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -188,6 +188,28 @@
<service android:name=".Services.CalendarSyncService" >
</service>
+
+ <activity android:name=".Gui.Agenda.AgendasActivity" >
+ </activity>
+ <activity android:name=".Gui.Agenda.AgendaActivity" >
+ </activity>
+
+ <receiver android:name=".Gui.Widget.CaptureWidgetProvider"
+ android:label="MobileOrg Capture" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/capture_widget_provider" />
+ </receiver>
+
+ <activity android:name=".Gui.Widget.CaptureWidgetConfig" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
BIN  libs/CWAC-MergeAdapter.jar
View
Binary file not shown
BIN  libs/CWAC-SackOfViewsAdapter.jar
View
Binary file not shown
BIN  res/drawable-hdpi/widget_capture.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 res/drawable/capture_widget_text_bg.xml
View
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@android:color/background_dark"/>
+
+ <padding
+ android:left="5dp"
+ android:top="1dp"
+ android:right="5dp"
+ android:bottom="1dp"/>
+
+ <corners
+ android:bottomRightRadius="10dp"
+ android:bottomLeftRadius="10dp"
+ android:topLeftRadius="10dp"
+ android:topRightRadius="10dp"/>
+</shape>
8 res/layout/agenda.xml
View
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="com.matburt.mobileorg.Gui.Agenda.AgendaFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:tag="agenda_fragment" >
+
+</fragment>
166 res/layout/agenda_entry_setting.xml
View
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="3dip" >
+
+ <EditText
+ android:id="@+id/agenda_entry_title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:hint="Title"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="3dip" >
+
+ <CheckBox
+ android:id="@+id/agenda_entry_active_todos"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Only active todos" />
+
+ <CheckBox
+ android:id="@+id/agenda_entry_habits"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Filter habits" />
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="3dip" >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_margin="5dp"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="Todo"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_menu_agenda" />
+
+ <EditText
+ android:id="@+id/agenda_entry_todo"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:hint="TODO:DONE..." >
+ </EditText>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_margin="5dp"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="5dp"
+ android:contentDescription="@string/tags"
+ android:src="@drawable/ic_menu_tag" />
+
+ <EditText
+ android:id="@+id/agenda_entry_tag"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:hint="Tag1:Tag2..." />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_margin="5dp"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="Priority"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_menu_star" />
+
+ <EditText
+ android:id="@+id/agenda_entry_priority"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:hint="A:B..." />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_margin="5dp"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="Priority"
+ android:scaleType="fitCenter" />
+
+ <EditText
+ android:id="@+id/agenda_entry_payload"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:hint="Payload1:Payload2..." />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="3dip" >
+
+ <TextView
+ android:id="@+id/textView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:text="Files"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <LinearLayout
+ android:id="@+id/agenda_entry_files"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+ </LinearLayout>
+ </LinearLayout>
+
+</ScrollView>
10 res/layout/agenda_header.xml
View
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/agenda_header"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:paddingBottom="10dp"
+ android:textSize="20dp"
+ android:textStyle="bold" />
+
55 res/layout/agenda_settings.xml
View
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="3dip" >
+
+ <EditText
+ android:id="@+id/agenda_title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="5dp"
+ android:ems="10"
+ android:hint="Title" >
+
+ <requestFocus />
+ </EditText>
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="3dip"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/textView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center"
+ android:text="Entries"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <ListView
+ android:id="@+id/agenda_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="5dp" >
+ </ListView>
+
+ <Button
+ android:id="@+id/agenda_create"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Add entry" />
+ </LinearLayout>
+
+</LinearLayout>
8 res/layout/agendas.xml
View
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="com.matburt.mobileorg.Gui.Agenda.AgendasFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:tag="agendas_fragment" >
+
+</fragment>
25 res/layout/capture_widget.xml
View
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/capture_widget_root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <ImageView
+ android:id="@+id/capture_widget_icon"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_gravity="center"
+ android:layout_margin="5dp"
+ android:layout_weight="1"
+ android:src="@drawable/widget_capture" />
+
+ <TextView
+ android:id="@+id/capture_widget_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:background="@drawable/capture_widget_text_bg"
+ android:textColor="@android:color/primary_text_dark" />
+
+</LinearLayout>
53 res/layout/capture_widget_config.xml
View
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="3dip" >
+
+ <EditText
+ android:id="@+id/widget_title"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/title"
+ android:inputType="text|textMultiLine|textAutoCorrect|textCapSentences" />
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/EditBorders"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="3dip" >
+
+ <fragment
+ android:name="com.matburt.mobileorg.Gui.Capture.LocationFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:tag="captureLocationFragment" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/widget_cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+
+ <Button
+ android:id="@+id/widget_save"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/save" />
+ </LinearLayout>
+
+</LinearLayout>
15 res/menu/agenda_block.xml
View
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/agenda_block_cancel"
+ android:icon="@drawable/ic_menu_close_clear_cancel"
+ android:showAsAction="always"
+ android:title="@string/menu_cancel"/>
+ <item
+ android:id="@+id/agenda_block_save"
+ android:icon="@drawable/ic_menu_save"
+ android:showAsAction="always"
+ android:title="Save"/>
+
+</menu>
15 res/menu/agenda_entry.xml
View
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/agenda_entry_cancel"
+ android:icon="@drawable/ic_menu_close_clear_cancel"
+ android:showAsAction="always"
+ android:title="@string/menu_cancel"/>
+ <item
+ android:id="@+id/agenda_entry_save"
+ android:icon="@drawable/ic_menu_save"
+ android:showAsAction="always"
+ android:title="Save"/>
+
+</menu>
8 res/menu/outline_menu.xml
View
@@ -2,6 +2,10 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
+ android:id="@+id/menu_agenda"
+ android:icon="@drawable/ic_menu_agenda"
+ android:title="@string/menu_agenda"/>
+ <item
android:id="@+id/menu_outline"
android:icon="@drawable/ic_menu_agenda"
android:title="@string/menu_outline"/>
@@ -13,9 +17,9 @@
<item
android:id="@+id/menu_capturechild"
android:icon="@drawable/ic_menu_add"
- android:visible="true"
android:showAsAction="ifRoom"
- android:title="@string/menu_capture"/>
+ android:title="@string/menu_capture"
+ android:visible="true"/>
<item
android:id="@+id/menu_search"
android:icon="@drawable/ic_menu_search"
3  res/values/strings.xml
View
@@ -3,6 +3,7 @@
<string name="app_name">MobileOrgActivity</string>
<string name="menu_outline">Outline</string>
+ <string name="menu_agenda">Agenda</string>
<string name="menu_capture">Capture</string>
<string name="menu_capture_simple">Simple Capture</string>
<string name="menu_settings">Settings</string>
@@ -200,4 +201,4 @@
<string name="title_index_file_path">Full local path to index.org</string>
<string name="summary_web_url">Full URL path to your index.org file</string>
-</resources>
+</resources>
10 res/xml/capture_widget_provider.xml
View
@@ -0,0 +1,10 @@
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+ android:configure="com.matburt.mobileorg.Gui.Widget.CaptureWidgetConfig"
+ android:initialLayout="@layout/capture_widget"
+ android:minHeight="40dp"
+ android:minWidth="40dp"
+ android:previewImage="@drawable/widget_capture"
+ android:resizeMode="horizontal|vertical"
+ android:updatePeriodMillis="86400000" >
+
+</appwidget-provider>
59 src/com/matburt/mobileorg/Gui/Agenda/AgendaActivity.java
View
@@ -0,0 +1,59 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.matburt.mobileorg.R;
+import com.matburt.mobileorg.Synchronizers.Synchronizer;
+
+public class AgendaActivity extends SherlockFragmentActivity {
+ public static final String POSITION = "position";
+ private int position;
+ private SynchServiceReceiver syncReceiver;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.agenda);
+
+ position = getIntent().getIntExtra(POSITION, 0);
+
+ syncReceiver = new SynchServiceReceiver();
+ registerReceiver(syncReceiver, new IntentFilter(
+ Synchronizer.SYNC_UPDATE));
+ }
+
+ @Override
+ protected void onDestroy() {
+ unregisterReceiver(syncReceiver);
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ refresh();
+ }
+
+ public void refresh() {
+ AgendaFragment agendaFragment = (AgendaFragment) getSupportFragmentManager()
+ .findFragmentByTag("agenda_fragment");
+
+ agendaFragment.agendaPos = position;
+ agendaFragment.showBlockAgenda(position);
+ }
+
+ private class SynchServiceReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ boolean syncDone = intent.getBooleanExtra(Synchronizer.SYNC_DONE, false);
+
+ if (syncDone)
+ refresh();
+ }
+ }
+}
156 src/com/matburt/mobileorg/Gui/Agenda/AgendaEntrySetting.java
View
@@ -0,0 +1,156 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import android.os.Bundle;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import com.actionbarsherlock.app.SherlockActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuItem;
+import com.matburt.mobileorg.R;
+import com.matburt.mobileorg.OrgData.OrgProviderUtils;
+
+public class AgendaEntrySetting extends SherlockActivity {
+ public static final String AGENDA_NUMBER = "agenda_number";
+ public static final String ENTRY_NUMBER = "entry_number";
+
+ private int agendaPos;
+ private int entryPos;
+
+ private EditText titleView;
+ private EditText payloadView;
+ private EditText todoView;
+ private EditText priorityView;
+ private EditText tagsView;
+ private CheckBox filterHabitsView;
+
+ private CheckBox activeTodosView;
+ private LinearLayout fileListView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.agenda_entry_setting);
+
+ this.titleView = (EditText) findViewById(R.id.agenda_entry_title);
+ this.priorityView = (EditText) findViewById(R.id.agenda_entry_priority);
+ this.todoView = (EditText) findViewById(R.id.agenda_entry_todo);
+ this.tagsView = (EditText) findViewById(R.id.agenda_entry_tag);
+ this.payloadView = (EditText) findViewById(R.id.agenda_entry_payload);
+
+ this.filterHabitsView = (CheckBox) findViewById(R.id.agenda_entry_habits);
+ this.activeTodosView = (CheckBox) findViewById(R.id.agenda_entry_active_todos);
+
+ this.agendaPos = getIntent().getIntExtra(AGENDA_NUMBER, -1);
+ this.entryPos = getIntent().getIntExtra(ENTRY_NUMBER, -1);
+
+ this.fileListView = (LinearLayout) findViewById(R.id.agenda_entry_files);
+
+ setupSettings(OrgAgenda.getAgendaEntry(agendaPos, entryPos, this));
+ }
+
+ public void setupSettings(OrgQueryBuilder agenda) {
+ titleView.setText(agenda.title);
+ payloadView.setText(combineToString(agenda.payloads));
+ todoView.setText(combineToString(agenda.todos));
+ priorityView.setText(combineToString(agenda.priorities));
+ tagsView.setText(combineToString(agenda.tags));
+ filterHabitsView.setChecked(agenda.filterHabits);
+ activeTodosView.setChecked(agenda.activeTodos);
+
+ setupFileList(agenda);
+ }
+
+ public OrgQueryBuilder getQueryFromSettings() {
+ OrgQueryBuilder agenda = new OrgQueryBuilder(titleView.getText().toString());
+
+ agenda.tags = splitToArrayList(tagsView.getText().toString());
+ agenda.payloads = splitToArrayList(payloadView.getText().toString());
+ agenda.priorities = splitToArrayList(priorityView.getText().toString());
+ agenda.todos = splitToArrayList(todoView.getText().toString());
+ agenda.filterHabits = filterHabitsView.isChecked();
+ agenda.activeTodos = activeTodosView.isChecked();
+
+ agenda.files = getFileList();
+
+ return agenda;
+ }
+
+ private String combineToString(ArrayList<String> list) {
+ if(list.size() == 0)
+ return "";
+
+ StringBuilder builder = new StringBuilder();
+ for(String item: list)
+ builder.append(item).append(":");
+
+ builder.delete(builder.length() - 1, builder.length());
+ return builder.toString();
+ }
+
+ private ArrayList<String> splitToArrayList(String string) {
+ ArrayList<String> result = new ArrayList<String>();
+
+ if(string == null || string.trim().length() == 0)
+ return result;
+
+ String[] split = string.split(":");
+ return new ArrayList<String>(Arrays.asList(split));
+ }
+
+ private void setupFileList(OrgQueryBuilder agenda) {
+ ArrayList<String> filenames = OrgProviderUtils
+ .getFilenames(getContentResolver());
+ for (String filename : filenames) {
+ CheckBox checkBox = new CheckBox(this);
+ checkBox.setText(filename);
+ checkBox.setChecked(agenda.files.contains(filename));
+
+ fileListView.addView(checkBox);
+ }
+ }
+
+ private ArrayList<String> getFileList() {
+ ArrayList<String> files = new ArrayList<String>();
+
+ int fileSize = fileListView.getChildCount();
+ for (int i = 0; i < fileSize; i++) {
+ CheckBox checkBox = (CheckBox) fileListView.getChildAt(i);
+ if (checkBox.isChecked())
+ files.add(checkBox.getText().toString());
+ }
+
+ return files;
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getSupportMenuInflater().inflate(R.menu.agenda_entry, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.agenda_entry_save:
+ OrgAgenda.writeAgendaEntry(getQueryFromSettings(), agendaPos,
+ entryPos, this);
+ finish();
+ break;
+ case R.id.agenda_entry_cancel:
+ finish();
+ break;
+
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+
+ return true;
+ }
+}
77 src/com/matburt/mobileorg/Gui/Agenda/AgendaFragment.java
View
@@ -0,0 +1,77 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.actionbarsherlock.app.SherlockFragment;
+import com.commonsware.cwac.merge.MergeAdapter;
+import com.matburt.mobileorg.R;
+import com.matburt.mobileorg.Gui.Outline.OutlineActionMode;
+import com.matburt.mobileorg.Gui.Outline.OutlineAdapter;
+import com.matburt.mobileorg.OrgData.OrgDatabase;
+
+public class AgendaFragment extends SherlockFragment {
+
+ public int agendaPos = 0;
+ private ListView agendaList;
+ private MergeAdapter mergeAdapter;
+ private SQLiteDatabase db;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ this.db = new OrgDatabase(getActivity()).getReadableDatabase();
+
+ this.agendaList = new ListView(getActivity());
+ this.agendaList.setOnItemClickListener(agendaClickListener);
+
+ return agendaList;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ showBlockAgenda(agendaPos);
+ }
+
+ public void showBlockAgenda(int agendaPos) {
+ this.mergeAdapter = new MergeAdapter();
+
+ OrgAgenda blockAgenda = OrgAgenda.getAgenda(agendaPos, getActivity());
+
+ for (OrgQueryBuilder agenda : blockAgenda.queries)
+ addAgenda(agenda);
+
+ this.agendaList.setAdapter(mergeAdapter);
+ this.agendaList.setOnItemClickListener(agendaClickListener);
+ //getSherlockActivity().getSupportActionBar().setTitle(blockAgenda.title);
+ }
+
+ public void addAgenda(OrgQueryBuilder query) {
+ TextView titleView = (TextView) View.inflate(getActivity(), R.layout.agenda_header, null);
+ titleView.setText(query.title);
+ mergeAdapter.addView(titleView);
+
+ OutlineAdapter adapter = new OutlineAdapter(getActivity());
+ adapter.setLevelIndentation(false);
+ adapter.setState(query.getNodes(db, getActivity()));
+ mergeAdapter.addAdapter(adapter);
+ }
+
+ private OnItemClickListener agendaClickListener = new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View v, int position,
+ long id) {
+ long nodeId = mergeAdapter.getItemId(position);
+ OutlineActionMode.runEditNodeActivity(nodeId, getActivity());
+ }
+ };
+}
169 src/com/matburt/mobileorg/Gui/Agenda/AgendaSettings.java
View
@@ -0,0 +1,169 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.actionbarsherlock.app.SherlockActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuItem;
+import com.matburt.mobileorg.R;
+
+public class AgendaSettings extends SherlockActivity {
+ public static final String AGENDA_NUMBER = "agenda_number";
+ private static final String AGENDA_TITLE = "agenda_title";
+
+ private int agendaPos;
+
+ private TextView titleView;
+ private ListView agendaList;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.agenda_settings);
+ this.titleView = (TextView) findViewById(R.id.agenda_title);
+ this.agendaList = (ListView) findViewById(R.id.agenda_list);
+
+ Button createButton = (Button) findViewById(R.id.agenda_create);
+ createButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ createAgendaBlockEntry();
+ }
+ });
+
+ agendaList.setOnItemClickListener(agendaItemClick);
+ agendaList.setOnCreateContextMenuListener(this);
+ registerForContextMenu(agendaList);
+
+ this.agendaPos = getIntent().getIntExtra(AGENDA_NUMBER, -1);
+
+ if(this.agendaPos == -1)
+ this.agendaPos = OrgAgenda.addAgenda(this);
+ }
+
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putString(AGENDA_TITLE, titleView.getText().toString());
+ super.onSaveInstanceState(outState);
+ }
+
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+
+ if (savedInstanceState != null) {
+ String title = savedInstanceState.getString(AGENDA_TITLE);
+ if(title != null)
+ titleView.setText(title);
+ }
+ }
+
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ refresh();
+ }
+
+ public void refresh() {
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1,
+ OrgAgenda.getAgendaQueryTitles(agendaPos, this));
+ agendaList.setAdapter(adapter);
+ String agendaTitle = OrgAgenda.getAgenda(agendaPos, this).title;
+ this.titleView.setText(agendaTitle);
+ getSupportActionBar().setTitle("Block settings");
+ }
+
+
+ private OnItemClickListener agendaItemClick = new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> adapter, View view, int position,
+ long id) {
+ Intent intent = new Intent(AgendaSettings.this, AgendaEntrySetting.class);
+ intent.putExtra(AgendaEntrySetting.AGENDA_NUMBER, agendaPos);
+ intent.putExtra(AgendaEntrySetting.ENTRY_NUMBER, position);
+ startActivity(intent);
+ }
+ };
+
+
+ private void createAgendaBlockEntry() {
+ Intent intent = new Intent(AgendaSettings.this, AgendaEntrySetting.class);
+ intent.putExtra(AgendaEntrySetting.AGENDA_NUMBER, this.agendaPos);
+ startActivity(intent);
+ }
+
+ private void saveAgendaBlock() {
+ OrgAgenda blockAgenda = OrgAgenda.getAgenda(agendaPos, this);
+ blockAgenda.title = this.titleView.getText().toString();
+ OrgAgenda.replaceAgenda(blockAgenda, agendaPos, this);
+ }
+
+ private void removeAgendaBlockEntry(int blockPos) {
+ OrgAgenda.removeAgendaEntry(agendaPos, blockPos, this);
+ refresh();
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getSupportMenuInflater().inflate(R.menu.agenda_block, menu);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ switch(item.getItemId()) {
+ case R.id.agenda_block_save:
+ saveAgendaBlock();
+ finish();
+ break;
+
+ case R.id.agenda_block_cancel:
+ finish();
+ break;
+
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+
+ return true;
+ }
+
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ menu.add("Remove");
+ }
+
+ @Override
+ public boolean onContextItemSelected(android.view.MenuItem item) {
+ if(item.getTitle().equals("Remove")) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+ removeAgendaBlockEntry(info.position);
+ return true;
+ }
+ else
+ return super.onContextItemSelected(item);
+ }
+}
15 src/com/matburt/mobileorg/Gui/Agenda/AgendasActivity.java
View
@@ -0,0 +1,15 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import android.os.Bundle;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.matburt.mobileorg.R;
+
+public class AgendasActivity extends SherlockFragmentActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.agendas);
+ }
+}
126 src/com/matburt/mobileorg/Gui/Agenda/AgendasFragment.java
View
@@ -0,0 +1,126 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import com.actionbarsherlock.app.SherlockFragment;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+import com.matburt.mobileorg.R;
+
+public class AgendasFragment extends SherlockFragment {
+
+ private ListView agendaList;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ this.agendaList = new ListView(getActivity());
+ this.agendaList.setOnItemClickListener(agendaClickListener);
+ this.agendaList.setOnCreateContextMenuListener(this);
+
+ setHasOptionsMenu(true);
+
+ return agendaList;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ refresh();
+ }
+
+ private void refresh() {
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
+ android.R.layout.simple_list_item_1,
+ OrgAgenda.getAgendasTitles(getActivity()));
+ agendaList.setAdapter(adapter);
+ }
+
+
+ private OnItemClickListener agendaClickListener = new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> adapter, View view,
+ int position, long id) {
+ showBlockAgendaFragment(position);
+ }
+ };
+
+ private void showBlockAgendaFragment(int position) {
+// FragmentTransaction transaction = getFragmentManager().beginTransaction();
+// transaction.hide(this);
+//
+// AgendaFragment blockFragment = new AgendaFragment();
+// blockFragment.agendaPos = position;
+// //transaction.add("agendaFragment", blockFragment, "agendaBlockFragment");
+// //transaction.show(blockFragment);
+// transaction.addToBackStack(getTag());
+//
+// transaction.commit();
+
+ Intent intent = new Intent(getActivity(), AgendaActivity.class);
+ intent.putExtra(AgendaActivity.POSITION, position);
+ startActivity(intent);
+ }
+
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ menu.add("Remove");
+ menu.add("Configure");
+ }
+
+ @Override
+ public boolean onContextItemSelected(android.view.MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+ int position = info.position;
+
+ if(item.getTitle().equals("Remove")) {
+ OrgAgenda.removeAgenda(position, getActivity());
+ refresh();
+ return true;
+ } else if(item.getTitle().equals("Configure")) {
+ Intent intent = new Intent(getActivity(), AgendaSettings.class);
+ intent.putExtra(AgendaSettings.AGENDA_NUMBER, position);
+ startActivity(intent);
+ return true;
+ }
+ else
+ return super.onContextItemSelected(item);
+ }
+
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+
+ MenuItem create = menu.add("Create");
+ create.setIcon(R.drawable.ic_menu_add);
+ create.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ if(item.getTitle().equals("Create")) {
+ Intent intent = new Intent(getActivity(), AgendaSettings.class);
+ startActivity(intent);
+ return true;
+ }
+ else
+ return super.onOptionsItemSelected(item);
+ }
+}
151 src/com/matburt/mobileorg/Gui/Agenda/BlockAgenda.java
View
@@ -0,0 +1,151 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import android.content.Context;
+
+import com.matburt.mobileorg.util.OrgUtils;
+
+public class BlockAgenda implements Serializable {
+ private static final long serialVersionUID = 2;
+ private static final String AGENDA_CONFIG_FILE = "agendas.conf";
+
+ public String title = "";
+
+ public ArrayList<OrgQueryBuilder> queries = new ArrayList<OrgQueryBuilder>();
+
+
+ public static ArrayList<BlockAgenda> readAgendas(Context context) throws IOException {
+ FileInputStream fis = context.openFileInput(AGENDA_CONFIG_FILE);
+ byte[] serializedObject = new byte[fis.available()];
+ fis.read(serializedObject);
+ fis.close();
+
+ @SuppressWarnings("unchecked")
+ ArrayList<BlockAgenda> result = (ArrayList<BlockAgenda>) OrgUtils
+ .deserializeObject(serializedObject);
+ return result;
+ }
+
+ public static void writeAgendas(ArrayList<BlockAgenda> agendas, Context context) throws IOException {
+ byte[] serializeObject = OrgUtils.serializeObject(agendas);
+ FileOutputStream fos = context.openFileOutput(AGENDA_CONFIG_FILE, Context.MODE_PRIVATE);
+ fos.write(serializeObject);
+ fos.close();
+ }
+
+/** Agendas **/
+ public static ArrayList<String> getAgendasTitles(Context context) {
+ ArrayList<String> result = new ArrayList<String>();
+ try {
+ ArrayList<BlockAgenda> agendas = readAgendas(context);
+
+ for(BlockAgenda agenda: agendas)
+ result.add(agenda.title);
+
+ return result;
+ } catch (IOException e) {
+ return result;
+ }
+ }
+
+ public static void removeAgenda(int position, Context context) {
+ try {
+ ArrayList<BlockAgenda> agendas = readAgendas(context);
+ agendas.remove(position);
+ writeAgendas(agendas, context);
+ } catch (IOException e) {}
+ }
+
+ public static void replaceAgenda(BlockAgenda agenda, int position, Context context) {
+ try {
+ ArrayList<BlockAgenda> agendas = readAgendas(context);
+ agendas.remove(position);
+ agendas.add(position, agenda);
+ writeAgendas(agendas, context);
+ } catch (IOException e) {}
+ }
+
+
+/** Block Agendas **/
+
+ public static BlockAgenda getBlockAgenda(int agendaPos, Context context) {
+ try {
+ ArrayList<BlockAgenda> agendas = readAgendas(context);
+
+ if(agendaPos >= 0 && agendaPos < agendas.size())
+ return agendas.get(agendaPos);
+ } catch (IOException e) {}
+ return new BlockAgenda();
+ }
+
+
+ public static int addBlockAgenda(Context context, String title) {
+ try {
+ ArrayList<BlockAgenda> agendas = readAgendas(context);
+ BlockAgenda blockAgenda = new BlockAgenda();
+ blockAgenda.title = title;
+ agendas.add(blockAgenda);
+ writeAgendas(agendas, context);
+ return agendas.size() - 1;
+ } catch (IOException e) {}
+ return -1;
+ }
+
+ public static ArrayList<String> getBlockAgendaQueryTitles(int agendaPos, Context context) {
+ ArrayList<String> result = new ArrayList<String>();
+ BlockAgenda blockAgenda = getBlockAgenda(agendaPos, context);
+
+ for (OrgQueryBuilder query : blockAgenda.queries)
+ result.add(query.title);
+
+ return result;
+ }
+
+
+/** Block Agenda Query **/
+
+ public static OrgQueryBuilder getAgendaBlockEntry(int agendaPos, int blockPos, Context context) {
+ BlockAgenda blockAgenda = getBlockAgenda(agendaPos, context);
+ if(blockPos >= 0 && blockPos < blockAgenda.queries.size())
+ return blockAgenda.queries.get(blockPos);
+ else
+ return new OrgQueryBuilder("");
+ }
+
+ public static void removeBlockAgendaEntry(int agendaPos, int blockPos, Context context) {
+ try {
+ ArrayList<BlockAgenda> agendas = readAgendas(context);
+
+ BlockAgenda blockAgenda = agendas.get(agendaPos);
+ blockAgenda.queries.remove(blockPos);
+
+ writeAgendas(agendas, context);
+ } catch (IOException e) {}
+ }
+
+
+ public static void writeAgendaBlockEntry(OrgQueryBuilder query, int agendaPos, int blockPos, Context context) {
+ try {
+ ArrayList<BlockAgenda> agendas = readAgendas(context);
+
+ if(agendaPos < 0 || agendaPos >= agendas.size())
+ return;
+
+ BlockAgenda blockAgenda = agendas.get(agendaPos);
+
+ if(blockPos >= 0 && blockPos < blockAgenda.queries.size()) {
+ blockAgenda.queries.remove(blockPos);
+ blockAgenda.queries.add(blockPos, query);
+ } else
+ blockAgenda.queries.add(query);
+
+ writeAgendas(agendas, context);
+
+ } catch (IOException e) {}
+ }
+}
148 src/com/matburt/mobileorg/Gui/Agenda/OrgAgenda.java
View
@@ -0,0 +1,148 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import android.content.Context;
+
+import com.matburt.mobileorg.util.OrgUtils;
+
+public class OrgAgenda implements Serializable {
+ private static final long serialVersionUID = 2;
+ private static final String AGENDA_CONFIG_FILE = "agendas.conf";
+
+ public String title = "";
+
+ public ArrayList<OrgQueryBuilder> queries = new ArrayList<OrgQueryBuilder>();
+
+ public static ArrayList<OrgAgenda> readAgendas(Context context) throws IOException {
+ FileInputStream fis = context.openFileInput(AGENDA_CONFIG_FILE);
+ byte[] serializedObject = new byte[fis.available()];
+ fis.read(serializedObject);
+ fis.close();
+
+ @SuppressWarnings("unchecked")
+ ArrayList<OrgAgenda> result = (ArrayList<OrgAgenda>) OrgUtils
+ .deserializeObject(serializedObject);
+ return result;
+ }
+
+ public static void writeAgendas(ArrayList<OrgAgenda> agendas, Context context) throws IOException {
+ byte[] serializeObject = OrgUtils.serializeObject(agendas);
+ FileOutputStream fos = context.openFileOutput(AGENDA_CONFIG_FILE, Context.MODE_PRIVATE);
+ fos.write(serializeObject);
+ fos.close();
+ }
+
+ public static ArrayList<String> getAgendasTitles(Context context) {
+ ArrayList<String> result = new ArrayList<String>();
+ try {
+ ArrayList<OrgAgenda> agendas = readAgendas(context);
+
+ if(agendas == null)
+ return result;
+
+ for(OrgAgenda agenda: agendas)
+ result.add(agenda.title);
+
+ return result;
+ } catch (IOException e) {
+ return result;
+ }
+ }
+
+ public static void removeAgenda(int position, Context context) {
+ try {
+ ArrayList<OrgAgenda> agendas = readAgendas(context);
+ agendas.remove(position);
+ writeAgendas(agendas, context);
+ } catch (IOException e) {}
+ }
+
+ public static void replaceAgenda(OrgAgenda agenda, int position, Context context) {
+ try {
+ ArrayList<OrgAgenda> agendas = readAgendas(context);
+ agendas.remove(position);
+ agendas.add(position, agenda);
+ writeAgendas(agendas, context);
+ } catch (IOException e) {}
+ }
+
+ public static OrgAgenda getAgenda(int agendaPos, Context context) {
+ try {
+ ArrayList<OrgAgenda> agendas = readAgendas(context);
+
+ if(agendaPos >= 0 && agendaPos < agendas.size())
+ return agendas.get(agendaPos);
+ } catch (IOException e) {}
+ return new OrgAgenda();
+ }
+
+
+ public static int addAgenda(Context context) {
+ try {
+ ArrayList<OrgAgenda> agendas = readAgendas(context);
+ OrgAgenda agenda = new OrgAgenda();
+ agendas.add(agenda);
+ writeAgendas(agendas, context);
+ return agendas.size() - 1;
+ } catch (IOException e) {}
+ return -1;
+ }
+
+ public static ArrayList<String> getAgendaQueryTitles(int agendaPos, Context context) {
+ ArrayList<String> result = new ArrayList<String>();
+ OrgAgenda agenda = getAgenda(agendaPos, context);
+
+ for (OrgQueryBuilder query : agenda.queries)
+ result.add(query.title);
+
+ return result;
+ }
+
+
+/** Agenda Query **/
+
+ public static OrgQueryBuilder getAgendaEntry(int agendaPos, int entryPos, Context context) {
+ OrgAgenda agenda = getAgenda(agendaPos, context);
+ if(entryPos >= 0 && entryPos < agenda.queries.size())
+ return agenda.queries.get(entryPos);
+ else
+ return new OrgQueryBuilder("");
+ }
+
+ public static void removeAgendaEntry(int agendaPos, int entryPos, Context context) {
+ try {
+ ArrayList<OrgAgenda> agendas = readAgendas(context);
+
+ OrgAgenda agenda = agendas.get(agendaPos);
+ agenda.queries.remove(entryPos);
+
+ writeAgendas(agendas, context);
+ } catch (IOException e) {}
+ }
+
+
+ public static void writeAgendaEntry(OrgQueryBuilder query, int agendaPos, int entryPos, Context context) {
+ try {
+ ArrayList<OrgAgenda> agendas = readAgendas(context);
+
+ if(agendaPos < 0 || agendaPos >= agendas.size())
+ return;
+
+ OrgAgenda agenda = agendas.get(agendaPos);
+
+ if(entryPos >= 0 && entryPos < agenda.queries.size()) {
+ agenda.queries.remove(entryPos);
+ agenda.queries.add(entryPos, query);
+ } else
+ agenda.queries.add(query);
+
+ writeAgendas(agendas, context);
+
+ } catch (IOException e) {}
+ }
+}
133 src/com/matburt/mobileorg/Gui/Agenda/OrgQueryBuilder.java
View
@@ -0,0 +1,133 @@
+package com.matburt.mobileorg.Gui.Agenda;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import com.matburt.mobileorg.OrgData.OrgContract.OrgData;
+import com.matburt.mobileorg.OrgData.OrgDatabase.Tables;
+import com.matburt.mobileorg.OrgData.OrgFile;
+import com.matburt.mobileorg.OrgData.OrgProviderUtils;
+import com.matburt.mobileorg.util.OrgFileNotFoundException;
+import com.matburt.mobileorg.util.SelectionBuilder;
+
+public class OrgQueryBuilder implements Serializable {
+ private static final long serialVersionUID = 2;
+
+ public String title = "";
+
+ public ArrayList<String> files = new ArrayList<String>();
+ public ArrayList<String> todos = new ArrayList<String>();
+ public ArrayList<String> tags = new ArrayList<String>();
+ public ArrayList<String> priorities = new ArrayList<String>();
+ public ArrayList<String> payloads = new ArrayList<String>();
+
+ public boolean filterHabits = false;
+ public boolean activeTodos = false;
+
+ public OrgQueryBuilder(String title) {
+ this.title = title;
+ }
+
+ public long[] getNodes(SQLiteDatabase db, Context context) {
+ long[] result = null;
+
+ Cursor cursor = getQuery(context).query(db, OrgData.DEFAULT_COLUMNS, OrgData.DEFAULT_SORT);
+
+ result = new long[cursor.getCount()];
+ cursor.moveToFirst();
+
+ int i = 0;
+ while(cursor.isAfterLast() == false) {
+ result[i++] = cursor.getLong(cursor.getColumnIndex(OrgData.ID));
+ cursor.moveToNext();
+ }
+ cursor.close();
+ return result;
+ }
+
+ public SelectionBuilder getQuery(Context context) {
+ final SelectionBuilder builder = new SelectionBuilder();
+ builder.table(Tables.ORGDATA);
+
+ getFileSelection(builder, context);
+
+ if (activeTodos)
+ builder.where(getSelection(OrgProviderUtils.getActiveTodos(context
+ .getContentResolver()), OrgData.TODO));
+
+ if(todos != null && todos.size() > 0)
+ builder.where(getSelection(todos, OrgData.TODO));
+
+ if(tags != null && tags.size() > 0)
+ builder.where(getLikeSelection(tags, OrgData.TAGS));
+
+ if(priorities != null && priorities.size() > 0)
+ builder.where(getSelection(priorities, OrgData.PRIORITY));
+
+ if(payloads != null && payloads.size() > 0)
+ builder.where(getLikeSelection(payloads, OrgData.PAYLOAD));
+
+ if(filterHabits)
+ builder.where("NOT " + OrgData.PAYLOAD + " LIKE ?", "'%:STYLE: habit%'");
+
+ return builder;
+ }
+
+ private String getLikeSelection(ArrayList<String> values, String column) {
+ StringBuilder builder = new StringBuilder();
+
+ if(values == null)
+ return "";
+
+ for (String value: values) {
+ builder.append(column + " LIKE '%" + value + "%'").append(" OR ");
+ }
+
+ builder.delete(builder.length() - " OR ".length(), builder.length() - 1);
+ return builder.toString();
+ }
+
+ private String getSelection(ArrayList<String> values, String column) {
+ StringBuilder builder = new StringBuilder();
+
+ if(values == null)
+ return "";
+
+ for (String value: values) {
+ builder.append(column + "='" + value + "'").append(" OR ");
+ }
+
+ builder.delete(builder.length() - " OR ".length(), builder.length() - 1);
+ return builder.toString();
+ }
+
+ private void getFileSelection(SelectionBuilder builder, Context context) {
+ if(files == null || files.size() == 0) {
+ builder.where("NOT " + OrgData.FILE_ID + "=?",
+ Long.toString(getFileId(OrgFile.AGENDA_FILE,
+ context.getContentResolver())));
+ return;
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ for (String filename: files) {
+ long fileId = getFileId(filename, context.getContentResolver());
+ stringBuilder.append(OrgData.FILE_ID + "=" + Long.toString(fileId)).append(" OR ");
+ }
+ stringBuilder.delete(stringBuilder.length() - " OR ".length(), stringBuilder.length() - 1);
+
+ builder.where(stringBuilder.toString());
+ }
+
+ private long getFileId(String filename, ContentResolver resolver) {
+ try {
+ OrgFile agendaFile = new OrgFile(filename, resolver);
+ return agendaFile.id;
+ } catch (OrgFileNotFoundException e) { return -1;}
+ }
+}
17 src/com/matburt/mobileorg/Gui/Capture/EditActivity.java
View
@@ -6,6 +6,7 @@
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.text.TextUtils;
import android.util.Log;
import com.actionbarsherlock.app.SherlockFragmentActivity;
@@ -20,10 +21,11 @@
import com.matburt.mobileorg.util.OrgNodeNotFoundException;
import com.matburt.mobileorg.util.OrgUtils;
-public class EditActivity extends SherlockFragmentActivity implements
+public class EditActivity extends SherlockFragmentActivity implements EditHost,
PayloadFragment.OnPayloadModifiedListener,
DatesFragment.OnDatesModifiedListener {
public final static String NODE_ID = "node_id";
+ public final static String OLP_LOCATION = "olp_location";
public final static String ACTIONMODE = "actionMode";
public final static String ACTIONMODE_CREATE = "create";
public final static String ACTIONMODE_EDIT = "edit";
@@ -38,7 +40,7 @@
private String actionMode;
private ContentResolver resolver;
-
+
@Override
public void onCreate(Bundle savedInstanceState) {
OrgUtils.setTheme(this);
@@ -64,7 +66,16 @@ protected void onDestroy() {
private void initState() {
Intent intent = getIntent();
this.actionMode = intent.getStringExtra(ACTIONMODE);
- long node_id = intent.getLongExtra(NODE_ID, -1);
+ long node_id = intent.getLongExtra(NODE_ID, -1);
+ String olpLocation = intent.getStringExtra(OLP_LOCATION);
+
+ if (TextUtils.isEmpty(olpLocation) == false) {
+ try {
+ OrgNode parentNode = OrgProviderUtils.getOrgNodeFromOlpPath(
+ olpLocation, getContentResolver());
+ node_id = parentNode.id;
+ } catch (Exception e) {}
+ }
if (this.actionMode == null) {
this.node = OrgUtils.getCaptureIntentContents(intent);
12 src/com/matburt/mobileorg/Gui/Capture/EditHost.java
View
@@ -0,0 +1,12 @@
+package com.matburt.mobileorg.Gui.Capture;
+
+import com.matburt.mobileorg.OrgData.OrgNode;
+
+public interface EditHost {
+ public boolean isNodeEditable();
+ public OrgNode getOrgNode();
+ public String getActionMode();
+
+ public boolean isNodeRefilable();
+ public OrgNode getParentOrgNode();
+}
10 src/com/matburt/mobileorg/Gui/Capture/HeadingFragment.java
View
@@ -46,9 +46,9 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- EditActivity activity = ((EditActivity)getActivity());
+ EditHost activity = ((EditHost)getActivity());
- this.resolver = activity.getContentResolver();
+ this.resolver = getActivity().getContentResolver();
this.node = activity.getOrgNode();
if(savedInstanceState != null)
@@ -128,15 +128,15 @@ public OrgNode getEditedOrgNode() {
}
- private String getTitle() {
+ public String getTitle() {
return titleView.getText().toString();
}
- private String getTodo() {
+ public String getTodo() {
return todoStateView.getSelectedItem().toString();
}
- private String getPriority() {
+ public String getPriority() {
return priorityView.getSelectedItem().toString();
}
}
16 src/com/matburt/mobileorg/Gui/Capture/LocationFragment.java
View
@@ -40,18 +40,20 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
-
- EditActivity activity = (EditActivity) getActivity();
- this.resolver = activity.getContentResolver();
+
+ this.resolver = getActivity().getContentResolver();
+ EditHost activity = (EditHost) getActivity();
restoreFromBundle(savedInstanceState);
- if(this.node == null)
- this.node = activity.getParentOrgNode();
+ EditHost editActivity = (EditHost) activity;
+
+ if (this.node == null)
+ this.node = editActivity.getParentOrgNode();
initLocationView();
-
- setModifiable(activity.isNodeRefilable());
+
+ setModifiable(editActivity.isNodeRefilable());
}
@Override
8 src/com/matburt/mobileorg/Gui/Outline/OutlineActivity.java
View
@@ -17,6 +17,7 @@
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.matburt.mobileorg.R;
+import com.matburt.mobileorg.Gui.Agenda.AgendasActivity;
import com.matburt.mobileorg.Gui.Wizard.WizardActivity;
import com.matburt.mobileorg.OrgData.OrgProviderUtils;
import com.matburt.mobileorg.Services.SyncService;
@@ -158,6 +159,10 @@ public boolean onOptionsItemSelected(MenuItem item) {
runExpandableOutline(-1);
return true;
+ case R.id.menu_agenda:
+ runAgenda();
+ return true;
+
case R.id.menu_capturechild:
OutlineActionMode.runCaptureActivity(listView.getCheckedNodeId(), this);
return true;
@@ -198,6 +203,9 @@ private void runExpandableOutline(long id) {
startActivity(intent);
}
+ private void runAgenda() {
+ startActivity(new Intent(this, AgendasActivity.class));
+ }
private boolean runSearch() {
return onSearchRequested();
6 src/com/matburt/mobileorg/Gui/Outline/OutlineAdapter.java
View
@@ -23,6 +23,8 @@
private DefaultTheme theme;
+ private boolean levelIndentation = true;
+
public OutlineAdapter(Context context) {
super(context, R.layout.outline_item);
this.resolver = context.getContentResolver();
@@ -94,10 +96,14 @@ public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
outlineItem = new OutlineItem(getContext());
+ outlineItem.setLevelFormating(levelIndentation);
outlineItem.setup(getItem(position), this.expanded.get(position), theme, resolver);
return outlineItem;
}
+ public void setLevelIndentation(boolean enabled) {
+ this.levelIndentation = enabled;
+ }
@Override
public void clear() {
12 src/com/matburt/mobileorg/Gui/Outline/OutlineItem.java
View
@@ -29,6 +29,7 @@
private TextView titleView;
private TextView tagsView;
+ private boolean levelFormatting = true;
public OutlineItem(Context context) {
super(context);
@@ -39,6 +40,10 @@ public OutlineItem(Context context) {
tagsView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
}
+ public void setLevelFormating(boolean enabled) {
+ this.levelFormatting = enabled;
+ }
+
public void setup(OrgNode node, boolean expanded, DefaultTheme theme, ContentResolver resolver) {
setupTags(node.tags, theme);
@@ -49,11 +54,14 @@ public void setup(OrgNode node, boolean expanded, DefaultTheme theme, ContentRes
return;
}
- applyLevelFormating(theme, node.level, titleSpan);
+ if (levelFormatting)
+ applyLevelFormating(theme, node.level, titleSpan);
setupTitle(node.name, theme, titleSpan);
setupPriority(node.priority, theme, titleSpan);
setupTodo(node.todo, titleSpan, theme, resolver);
- applyLevelIndentation(node.level, titleSpan);
+
+ if (levelFormatting)
+ applyLevelIndentation(node.level, titleSpan);
if(expanded == false)
setupChildrenIndicator(node, resolver, theme, titleSpan);
94 src/com/matburt/mobileorg/Gui/TabsAdapter.java
View
@@ -0,0 +1,94 @@
+package com.matburt.mobileorg.Gui;
+
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.view.ViewPager;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.actionbarsherlock.app.ActionBar.Tab;
+
+public class TabsAdapter extends FragmentPagerAdapter implements
+ ActionBar.TabListener, ViewPager.OnPageChangeListener {
+ private final Context mContext;
+ private final ActionBar mActionBar;
+ private final ViewPager mViewPager;
+ private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
+
+ static final class TabInfo {
+ private final Class<?> clss;
+ private final Bundle args;
+
+ TabInfo(Class<?> _class, Bundle _args) {
+ clss = _class;
+ args = _args;
+ }
+ }
+
+ public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
+ super(activity.getSupportFragmentManager());
+ mContext = activity;
+ mActionBar = activity.getSupportActionBar();
+ mViewPager = pager;
+ mViewPager.setAdapter(this);
+ mViewPager.setOnPageChangeListener(this);
+ }
+
+ public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
+ TabInfo info = new TabInfo(clss, args);
+ tab.setTag(info);
+ tab.setTabListener(this);
+ mTabs.add(info);
+ mActionBar.addTab(tab);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mTabs.size();
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ TabInfo info = mTabs.get(position);
+ return Fragment.instantiate(mContext, info.clss.getName(),
+ info.args);
+ }
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset,
+ int positionOffsetPixels) {
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ mActionBar.setSelectedNavigationItem(position);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+
+ @Override
+ public void onTabSelected(Tab tab, FragmentTransaction ft) {
+ Object tag = tab.getTag();
+ for (int i = 0; i < mTabs.size(); i++) {
+ if (mTabs.get(i) == tag) {
+ mViewPager.setCurrentItem(i);
+ }
+ }
+ }
+
+ @Override
+ public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+ }
+
+ @Override
+ public void onTabReselected(Tab tab, FragmentTransaction ft) {
+ }
+}
110 src/com/matburt/mobileorg/Gui/Widget/CaptureWidgetConfig.java
View
@@ -0,0 +1,110 @@
+package com.matburt.mobileorg.Gui.Widget;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.matburt.mobileorg.R;
+import com.matburt.mobileorg.Gui.Capture.EditActivity;
+import com.matburt.mobileorg.Gui.Capture.EditHost;
+import com.matburt.mobileorg.Gui.Capture.LocationFragment;
+import com.matburt.mobileorg.OrgData.OrgNode;
+
+public class CaptureWidgetConfig extends SherlockFragmentActivity implements EditHost {
+
+ private int mAppWidgetId;
+ private LocationFragment locationFragment;
+ private EditText titleView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.capture_widget_config);
+
+ Intent intent = getIntent();
+ Bundle extras = intent.getExtras();
+ if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+
+ ((Button) findViewById(R.id.widget_save)).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ saveConfig();
+ }
+ });
+
+ ((Button) findViewById(R.id.widget_cancel)).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ cancelConfig();
+ }
+ });
+
+ titleView = (EditText) findViewById(R.id.widget_title);
+
+ locationFragment = (LocationFragment) getSupportFragmentManager()
+ .findFragmentByTag("captureLocationFragment");
+ }
+
+
+ private void saveConfig() {
+ save();
+ AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
+ CaptureWidgetProvider.updateWidget(mAppWidgetId, appWidgetManager, this);
+
+ Intent resultValue = new Intent();
+ resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+ setResult(RESULT_OK, resultValue);
+ finish();
+ }
+
+ private void save() {
+ OrgNode node = locationFragment.getLocationSelection();
+ String locationOlpId = node.getOlpId(getContentResolver());
+ String title = titleView.getText().toString();
+
+ CaptureWidgetProvider.writeConfig(mAppWidgetId, this, locationOlpId, title);
+ }
+
+ private void cancelConfig() {
+ Intent resultValue = new Intent();
+ resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+ setResult(RESULT_CANCELED, resultValue);
+ finish();
+ }
+
+
+ @Override
+ public boolean isNodeEditable() {
+ return true;
+ }
+
+
+ @Override
+ public OrgNode getOrgNode() {
+ return null;
+ }
+
+ @Override
+ public String getActionMode() {
+ return EditActivity.ACTIONMODE_ADDCHILD;
+ }
+
+ @Override
+ public boolean isNodeRefilable() {
+ return true;
+ }
+
+ @Override
+ public OrgNode getParentOrgNode() {
+ return null;
+ }
+}
79 src/com/matburt/mobileorg/Gui/Widget/CaptureWidgetProvider.java
View
@@ -0,0 +1,79 @@
+package com.matburt.mobileorg.Gui.Widget;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.widget.RemoteViews;
+
+import com.matburt.mobileorg.R;
+import com.matburt.mobileorg.Gui.Capture.EditActivity;
+
+public class CaptureWidgetProvider extends AppWidgetProvider {
+ public static final String LOCATION = "location";
+ public static final String TITLE = "title";
+
+ @Override
+ public void onUpdate(Context context, AppWidgetManager appWidgetManager,
+ int[] appWidgetIds) {
+ super.onUpdate(context, appWidgetManager, appWidgetIds);
+ try {
+ for (int i = 0; i < appWidgetIds.length; i++) {
+ int appWidgetId = appWidgetIds[i];
+ updateWidget(appWidgetId, appWidgetManager, context);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void updateWidget(int appWidgetId,
+ AppWidgetManager appWidgetManager, Context context) {
+ SharedPreferences prefs = getPreferences(appWidgetId, context);
+ if (null == prefs)
+ return;
+
+ RemoteViews views = new RemoteViews(context.getPackageName(),
+ R.layout.capture_widget);
+
+ String title = prefs.getString(TITLE, "???");
+ views.setTextViewText(R.id.capture_widget_text,
+ prefs.getString("name", title));
+
+ Intent intent = getWidgetIntent(appWidgetId, context);
+
+ PendingIntent pendingIntent = PendingIntent.getActivity(
+ context, appWidgetId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+ views.setOnClickPendingIntent(R.id.capture_widget_root,
+ pendingIntent);
+
+ appWidgetManager.updateAppWidget(appWidgetId, views);
+ }
+
+ private static Intent getWidgetIntent(int appWidgetId, Context context) {
+ Intent intent = new Intent(context, EditActivity.class);
+ intent.putExtra(EditActivity.ACTIONMODE, EditActivity.ACTIONMODE_ADDCHILD);
+
+ SharedPreferences prefs = getPreferences(appWidgetId, context);
+ String olpLocation = prefs.getString(LOCATION, "");
+ intent.putExtra(EditActivity.OLP_LOCATION, olpLocation);
+
+ return intent;
+ }
+
+ public static void writeConfig(int appWidgetId, Context context, String locationOlp, String title) {
+ Editor edit = getPreferences(appWidgetId, context).edit();
+ edit.putString(LOCATION, locationOlp);
+ edit.putString(TITLE, title);
+ edit.commit();
+ }
+
+ public static SharedPreferences getPreferences(int appWidgetId, Context context) {
+ SharedPreferences prefs = context.getSharedPreferences("widget_"
+ + appWidgetId, Context.MODE_PRIVATE);
+ return prefs;
+ }
+}
2  ...m/matburt/mobileorg/Services/MobileOrgWidget.java → ...matburt/mobileorg/Gui/Widget/MobileOrgWidget.java
View
@@ -1,4 +1,4 @@
-package com.matburt.mobileorg.Services;
+package com.matburt.mobileorg.Gui.Widget;
import android.app.PendingIntent;
import android.app.Service;
1  src/com/matburt/mobileorg/Services/CalendarSyncService.java
View
@@ -264,6 +264,7 @@ private void refreshPreferences() {
this.activeTodos = new HashSet<String>(
OrgProviderUtils.getActiveTodos(resolver));
this.allTodos = new HashSet<String>(OrgProviderUtils.getTodos(resolver));
+ this.allTodos.remove("");
this.calendarWrapper.refreshPreferences();
}
43 src/com/matburt/mobileorg/util/OrgUtils.java
View
@@ -1,9 +1,14 @@
package com.matburt.mobileorg.util;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
@@ -17,6 +22,7 @@
import android.content.pm.PackageInfo;
import android.preference.PreferenceManager;
import android.text.TextUtils;
+import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
@@ -201,4 +207,41 @@ public static void setTheme(Activity activity) {
else
activity.setTheme(R.style.Theme_MobileOrg_Light);
}
+
+ public static byte[] serializeObject(Object o) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try {
+ ObjectOutput out = new ObjectOutputStream(bos);
+ out.writeObject(o);
+ out.close();
+
+ byte[] buf = bos.toByteArray();
+
+ return buf;
+ } catch (IOException ioe) {
+ Log.e("serializeObject", "error", ioe);
+
+ return null;
+ }
+ }
+
+ public static Object deserializeObject(byte[] b) {
+ try {
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(b));
+ Object object = in.readObject();
+ in.close();
+
+ return object;
+ } catch (ClassNotFoundException cnfe) {
+ Log.e("deserializeObject", "class not found error", cnfe);
+
+ return null;
+ } catch (IOException ioe) {
+ Log.e("deserializeObject", "io error", ioe);
+
+ return null;
+ }
+ }
}
51 tests/src/com/matburt/mobileorg/test/Gui/AgendaTests.java
View
@@ -0,0 +1,51 @@
+package com.matburt.mobileorg.test.Gui;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.matburt.mobileorg.Gui.Agenda.OrgQueryBuilder;
+import com.matburt.mobileorg.Gui.Agenda.OrgAgenda;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+public class AgendaTests extends AndroidTestCase {
+
+ private Context context;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.context = getContext();
+ }
+
+ public void testBlockSerialization() throws IOException {
+ ArrayList<OrgAgenda> agendas = new ArrayList<OrgAgenda>();
+ OrgAgenda blockAgenda = new OrgAgenda();
+ blockAgenda.title = "test";
+ agendas.add(blockAgenda);
+
+ OrgAgenda.writeAgendas(agendas, context);
+ ArrayList<OrgAgenda> readAgendas = OrgAgenda.readAgendas(context);
+
+ assertEquals(agendas.size(), readAgendas.size());
+ OrgAgenda readBlockAgenda = readAgendas.get(0);
+ assertEquals(blockAgenda.title, readBlockAgenda.title);
+ }
+
+ public void testQuerySerialization() throws IOException {
+ ArrayList<OrgAgenda> agendas = new ArrayList<OrgAgenda>();
+ OrgAgenda blockAgenda = new OrgAgenda();
+ agendas.add(blockAgenda);
+
+ OrgQueryBuilder builder = new OrgQueryBuilder("test");
+ blockAgenda.queries.add(builder);
+
+ OrgAgenda.writeAgendas(agendas, context);
+ ArrayList<OrgAgenda> readAgendas = OrgAgenda.readAgendas(context);
+
+ OrgAgenda readBlockAgenda = readAgendas.get(0);
+ assertEquals(blockAgenda.queries.size(), readBlockAgenda.queries.size());
+ assertEquals(blockAgenda.queries.get(0).title, readBlockAgenda.queries.get(0).title);
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.