1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2024-12-23 11:21:29 +00:00

Use PreferenceFragments with a wrapper instead of SettingsFragments (fixes #64).

This commit is contained in:
Felix Ableitner 2014-08-03 21:54:30 +02:00
parent 299c901086
commit d2e0c291b6
16 changed files with 377 additions and 289 deletions

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "ext/syncthing/src/github.com/syncthing/syncthing"] [submodule "ext/syncthing/src/github.com/syncthing/syncthing"]
path = ext/syncthing/src/github.com/syncthing/syncthing path = ext/syncthing/src/github.com/syncthing/syncthing
url = https://github.com/syncthing/syncthing.git url = https://github.com/syncthing/syncthing.git
[submodule "libraries/android-support-v4-preferencefragment"]
path = libraries/android-support-v4-preferencefragment
url = https://github.com/kolavar/android-support-v4-preferencefragment.git

View file

@ -20,6 +20,7 @@ repositories {
dependencies { dependencies {
compile 'com.android.support:appcompat-v7:19.1.+' compile 'com.android.support:appcompat-v7:19.1.+'
compile project(':android-support-v4-preferencefragment')
} }
preBuild { preBuild {

@ -0,0 +1 @@
Subproject commit 269e53b7b94b8001d2192b0ff2effb12eadaab07

2
settings.gradle Normal file
View file

@ -0,0 +1,2 @@
include ':android-support-v4-preferencefragment'
project(':android-support-v4-preferencefragment').projectDir = new File('libraries/android-support-v4-preferencefragment')

View file

@ -39,8 +39,7 @@
android:value=".gui.MainActivity" /> android:value=".gui.MainActivity" />
</activity> </activity>
<activity <activity
android:name=".gui.SettingsActivity" android:name=".gui.SettingsActivity" >
android:label="@string/settings_title" >
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".gui.MainActivity" /> android:value=".gui.MainActivity" />
@ -48,10 +47,6 @@
<service android:name=".syncthing.SyncthingService" /> <service android:name=".syncthing.SyncthingService" />
<activity
android:name=".gui.RepoSettingsActivity" />
<activity
android:name=".gui.NodeSettingsActivity" />
<activity <activity
android:name=".gui.FolderPickerActivity" android:name=".gui.FolderPickerActivity"
android:label="@string/folder_picker_title" > android:label="@string/folder_picker_title" >

View file

@ -23,7 +23,6 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab; import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener; import android.support.v7.app.ActionBar.TabListener;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -270,20 +269,23 @@ public class MainActivity extends ActionBarActivity
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.add_repo: case R.id.add_repo:
Intent intent = new Intent(this, RepoSettingsActivity.class); Intent intent = new Intent(this, SettingsActivity.class)
intent.setAction(RepoSettingsActivity.ACTION_CREATE); .setAction(SettingsActivity.ACTION_REPO_SETTINGS_FRAGMENT)
.putExtra(SettingsActivity.EXTRA_IS_CREATE, true);
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.add_node: case R.id.add_node:
intent = new Intent(this, NodeSettingsActivity.class); intent = new Intent(this, SettingsActivity.class)
intent.setAction(NodeSettingsActivity.ACTION_CREATE); .setAction(SettingsActivity.ACTION_NODE_SETTINGS_FRAGMENT)
.putExtra(SettingsActivity.EXTRA_IS_CREATE, true);
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.web_gui: case R.id.web_gui:
startActivity(new Intent(this, WebGuiActivity.class)); startActivity(new Intent(this, WebGuiActivity.class));
return true; return true;
case R.id.settings: case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class)); startActivity(new Intent(this, SettingsActivity.class)
.setAction(SettingsActivity.ACTION_APP_SETTINGS_FRAGMENT));
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);

View file

@ -9,13 +9,13 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.support.v4.preference.PreferenceFragment;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
@ -31,16 +31,12 @@ import java.util.Map;
/** /**
* Shows node details and allows changing them. * Shows node details and allows changing them.
*/ */
public class NodeSettingsActivity extends PreferenceActivity implements public class NodeSettingsFragment extends PreferenceFragment implements
Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
RestApi.OnReceiveConnectionsListener, SyncthingService.OnApiChangeListener, RestApi.OnReceiveConnectionsListener, SyncthingService.OnApiChangeListener,
RestApi.OnNodeIdNormalizedListener { RestApi.OnNodeIdNormalizedListener {
public static final String ACTION_CREATE = "create"; public static final String EXTRA_NODE_ID = "node_id";
public static final String ACTION_EDIT = "edit";
public static final String KEY_NODE_ID = "node_id";
private static final int SCAN_QR_REQUEST_CODE = 235; private static final int SCAN_QR_REQUEST_CODE = 235;
@ -51,7 +47,7 @@ public class NodeSettingsActivity extends PreferenceActivity implements
public void onServiceConnected(ComponentName className, IBinder service) { public void onServiceConnected(ComponentName className, IBinder service) {
SyncthingServiceBinder binder = (SyncthingServiceBinder) service; SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
mSyncthingService = binder.getService(); mSyncthingService = binder.getService();
mSyncthingService.registerOnApiChangeListener(NodeSettingsActivity.this); mSyncthingService.registerOnApiChangeListener(NodeSettingsFragment.this);
} }
public void onServiceDisconnected(ComponentName className) { public void onServiceDisconnected(ComponentName className) {
@ -73,20 +69,19 @@ public class NodeSettingsActivity extends PreferenceActivity implements
private Preference mDelete; private Preference mDelete;
private boolean mIsCreate;
@Override @Override
@SuppressLint("AppCompatMethod") public void onCreate(Bundle savedInstanceState) {
@TargetApi(11)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { mIsCreate = ((SettingsActivity) getActivity()).getIsCreate();
getActionBar().setDisplayHomeAsUpEnabled(true); setHasOptionsMenu(true);
}
if (getIntent().getAction().equals(ACTION_CREATE)) { if (mIsCreate) {
addPreferencesFromResource(R.xml.node_settings_create); addPreferencesFromResource(R.xml.node_settings_create);
} }
else if (getIntent().getAction().equals(ACTION_EDIT)) { else {
addPreferencesFromResource(R.xml.node_settings_edit); addPreferencesFromResource(R.xml.node_settings_edit);
} }
@ -96,7 +91,7 @@ public class NodeSettingsActivity extends PreferenceActivity implements
mName.setOnPreferenceChangeListener(this); mName.setOnPreferenceChangeListener(this);
mAddresses = (EditTextPreference) findPreference("addresses"); mAddresses = (EditTextPreference) findPreference("addresses");
mAddresses.setOnPreferenceChangeListener(this); mAddresses.setOnPreferenceChangeListener(this);
if (getIntent().getAction().equals(ACTION_EDIT)) { if (!mIsCreate) {
mVersion = findPreference("version"); mVersion = findPreference("version");
mVersion.setSummary("?"); mVersion.setSummary("?");
mCurrentAddress = findPreference("current_address"); mCurrentAddress = findPreference("current_address");
@ -105,38 +100,39 @@ public class NodeSettingsActivity extends PreferenceActivity implements
mDelete.setOnPreferenceClickListener(this); mDelete.setOnPreferenceClickListener(this);
} }
bindService(new Intent(this, SyncthingService.class), getActivity().bindService(new Intent(getActivity(), SyncthingService.class),
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE); mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
} }
@Override @Override
public void onApiChange(SyncthingService.State currentState) { public void onApiChange(SyncthingService.State currentState) {
if (currentState != SyncthingService.State.ACTIVE) { if (currentState != SyncthingService.State.ACTIVE) {
SyncthingService.showDisabledDialog(this); SyncthingService.showDisabledDialog(getActivity());
finish(); getActivity().finish();
return; return;
} }
if (getIntent().getAction().equals(ACTION_CREATE)) { if (mIsCreate) {
setTitle(R.string.add_node); getActivity().setTitle(R.string.add_node);
mNode = new RestApi.Node(); mNode = new RestApi.Node();
mNode.Name = ""; mNode.Name = "";
mNode.NodeID = ""; mNode.NodeID = "";
mNode.Addresses = "dynamic"; mNode.Addresses = "dynamic";
((EditTextPreference) mNodeId).setText(mNode.NodeID); ((EditTextPreference) mNodeId).setText(mNode.NodeID);
} }
else if (getIntent().getAction().equals(ACTION_EDIT)) { else {
setTitle(R.string.edit_node); getActivity().setTitle(R.string.edit_node);
List<RestApi.Node> nodes = mSyncthingService.getApi().getNodes(); List<RestApi.Node> nodes = mSyncthingService.getApi().getNodes();
for (int i = 0; i < nodes.size(); i++) { for (int i = 0; i < nodes.size(); i++) {
if (nodes.get(i).NodeID.equals(getIntent().getStringExtra(KEY_NODE_ID))) { if (nodes.get(i).NodeID.equals(
getActivity().getIntent().getStringExtra(EXTRA_NODE_ID))) {
mNode = nodes.get(i); mNode = nodes.get(i);
break; break;
} }
} }
mNodeId.setOnPreferenceClickListener(this); mNodeId.setOnPreferenceClickListener(this);
} }
mSyncthingService.getApi().getConnections(NodeSettingsActivity.this); mSyncthingService.getApi().getConnections(NodeSettingsFragment.this);
mNodeId.setSummary(mNode.NodeID); mNodeId.setSummary(mNode.NodeID);
mName.setText((mNode.Name)); mName.setText((mNode.Name));
@ -146,16 +142,15 @@ public class NodeSettingsActivity extends PreferenceActivity implements
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getMenuInflater().inflate(R.menu.node_settings, menu); super.onCreateOptionsMenu(menu, inflater);
return true; inflater.inflate(R.menu.node_settings, menu);
} }
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.create).setVisible(getIntent().getAction().equals(ACTION_CREATE)); menu.findItem(R.id.create).setVisible(mIsCreate);
menu.findItem(R.id.share_node_id).setVisible(getIntent().getAction().equals(ACTION_EDIT)); menu.findItem(R.id.share_node_id).setVisible(!mIsCreate);
return true;
} }
@Override @Override
@ -163,22 +158,22 @@ public class NodeSettingsActivity extends PreferenceActivity implements
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.create: case R.id.create:
if (mNode.NodeID.equals("")) { if (mNode.NodeID.equals("")) {
Toast.makeText(this, R.string.node_id_required, Toast.LENGTH_LONG) Toast.makeText(getActivity(), R.string.node_id_required, Toast.LENGTH_LONG)
.show(); .show();
return true; return true;
} }
if (mNode.Name.equals("")) { if (mNode.Name.equals("")) {
Toast.makeText(this, R.string.node_name_required, Toast.LENGTH_LONG) Toast.makeText(getActivity(), R.string.node_name_required, Toast.LENGTH_LONG)
.show(); .show();
return true; return true;
} }
mSyncthingService.getApi().editNode(mNode, this); mSyncthingService.getApi().editNode(mNode, this);
return true; return true;
case R.id.share_node_id: case R.id.share_node_id:
RestApi.shareNodeId(this, mNode.NodeID); RestApi.shareNodeId(getActivity(), mNode.NodeID);
return true; return true;
case android.R.id.home: case android.R.id.home:
finish(); getActivity().finish();
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@ -188,7 +183,7 @@ public class NodeSettingsActivity extends PreferenceActivity implements
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
unbindService(mSyncthingServiceConnection); getActivity().unbindService(mSyncthingServiceConnection);
} }
@Override @Override
@ -219,13 +214,13 @@ public class NodeSettingsActivity extends PreferenceActivity implements
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
if (preference.equals(mDelete)) { if (preference.equals(mDelete)) {
new AlertDialog.Builder(this) new AlertDialog.Builder(getActivity())
.setMessage(R.string.delete_node_confirm) .setMessage(R.string.delete_node_confirm)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
mSyncthingService.getApi().deleteNode(mNode, NodeSettingsActivity.this); mSyncthingService.getApi().deleteNode(mNode, getActivity());
finish(); getActivity().finish();
} }
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
@ -257,7 +252,7 @@ public class NodeSettingsActivity extends PreferenceActivity implements
* Sends the updated node info if in edit mode. * Sends the updated node info if in edit mode.
*/ */
private void nodeUpdated() { private void nodeUpdated() {
if (getIntent().getAction().equals(ACTION_EDIT)) { if (!mIsCreate) {
mSyncthingService.getApi().editNode(mNode, this); mSyncthingService.getApi().editNode(mNode, this);
} }
} }
@ -274,7 +269,8 @@ public class NodeSettingsActivity extends PreferenceActivity implements
startActivityForResult(intentScan, SCAN_QR_REQUEST_CODE); startActivityForResult(intentScan, SCAN_QR_REQUEST_CODE);
} }
catch (ActivityNotFoundException e) { catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.no_qr_scanner_installed, Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), R.string.no_qr_scanner_installed,
Toast.LENGTH_LONG).show();
} }
} }
@ -282,7 +278,7 @@ public class NodeSettingsActivity extends PreferenceActivity implements
* Receives value of scanned QR code and sets it as node ID. * Receives value of scanned QR code and sets it as node ID.
*/ */
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SCAN_QR_REQUEST_CODE && resultCode == Activity.RESULT_OK) { if (requestCode == SCAN_QR_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
mNode.NodeID = data.getStringExtra("SCAN_RESULT"); mNode.NodeID = data.getStringExtra("SCAN_RESULT");
((EditTextPreference) mNodeId).setText(mNode.NodeID); ((EditTextPreference) mNodeId).setText(mNode.NodeID);
@ -300,11 +296,10 @@ public class NodeSettingsActivity extends PreferenceActivity implements
@Override @Override
public void onNodeIdNormalized(String normalizedId, String error) { public void onNodeIdNormalized(String normalizedId, String error) {
if (error != null) { if (error != null) {
Toast.makeText(NodeSettingsActivity.this, error, Toast.makeText(getActivity(), error, Toast.LENGTH_LONG).show();
Toast.LENGTH_LONG).show();
} }
else if (getIntent().getAction().equals(ACTION_CREATE)) { else if (mIsCreate) {
finish(); getActivity().finish();
} }
} }

View file

@ -87,9 +87,10 @@ public class NodesFragment extends ListFragment implements SyncthingService.OnAp
@Override @Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getActivity(), NodeSettingsActivity.class); Intent intent = new Intent(getActivity(), SettingsActivity.class);
intent.setAction(NodeSettingsActivity.ACTION_EDIT); intent.setAction(SettingsActivity.ACTION_NODE_SETTINGS_FRAGMENT);
intent.putExtra(NodeSettingsActivity.KEY_NODE_ID, mAdapter.getItem(i).NodeID); intent.putExtra(SettingsActivity.EXTRA_IS_CREATE, false);
intent.putExtra(NodeSettingsFragment.EXTRA_NODE_ID, mAdapter.getItem(i).NodeID);
startActivity(intent); startActivity(intent);
} }

View file

@ -16,9 +16,10 @@ import android.os.IBinder;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.support.v4.preference.PreferenceFragment;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.Toast; import android.widget.Toast;
@ -34,17 +35,17 @@ import java.util.List;
/** /**
* Shows repo details and allows changing them. * Shows repo details and allows changing them.
*/ */
public class RepoSettingsActivity extends PreferenceActivity public class RepoSettingsFragment extends PreferenceFragment
implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener, implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
SyncthingService.OnApiChangeListener { SyncthingService.OnApiChangeListener {
private static final int DIRECTORY_REQUEST_CODE = 234; private static final int DIRECTORY_REQUEST_CODE = 234;
public static final String ACTION_CREATE = "create"; /**
* The ID of the repo to be edited. To be used with {@link SettingsActivity#EXTRA_IS_CREATE}
public static final String ACTION_EDIT = "edit"; * set to false.
*/
public static final String KEY_REPO_ID = "repo_id"; public static final String EXTRA_REPO_ID = "repo_id";
private static final String KEY_NODE_SHARED = "node_shared"; private static final String KEY_NODE_SHARED = "node_shared";
@ -55,7 +56,7 @@ public class RepoSettingsActivity extends PreferenceActivity
public void onServiceConnected(ComponentName className, IBinder service) { public void onServiceConnected(ComponentName className, IBinder service) {
SyncthingServiceBinder binder = (SyncthingServiceBinder) service; SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
mSyncthingService = binder.getService(); mSyncthingService = binder.getService();
mSyncthingService.registerOnApiChangeListener(RepoSettingsActivity.this); mSyncthingService.registerOnApiChangeListener(RepoSettingsFragment.this);
} }
public void onServiceDisconnected(ComponentName className) { public void onServiceDisconnected(ComponentName className) {
@ -79,20 +80,19 @@ public class RepoSettingsActivity extends PreferenceActivity
private Preference mDelete; private Preference mDelete;
private boolean mIsCreate;
@Override @Override
@SuppressLint("AppCompatMethod") public void onCreate(Bundle savedInstanceState) {
@TargetApi(11)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { mIsCreate = ((SettingsActivity) getActivity()).getIsCreate();
getActionBar().setDisplayHomeAsUpEnabled(true); setHasOptionsMenu(true);
}
if (getIntent().getAction().equals(ACTION_CREATE)) { if (mIsCreate) {
addPreferencesFromResource(R.xml.repo_settings_create); addPreferencesFromResource(R.xml.repo_settings_create);
} }
else if (getIntent().getAction().equals(ACTION_EDIT)) { else {
addPreferencesFromResource(R.xml.repo_settings_edit); addPreferencesFromResource(R.xml.repo_settings_edit);
} }
@ -108,36 +108,37 @@ public class RepoSettingsActivity extends PreferenceActivity
mVersioning.setOnPreferenceChangeListener(this); mVersioning.setOnPreferenceChangeListener(this);
mVersioningKeep = (EditTextPreference) findPreference("versioning_keep"); mVersioningKeep = (EditTextPreference) findPreference("versioning_keep");
mVersioningKeep.setOnPreferenceChangeListener(this); mVersioningKeep.setOnPreferenceChangeListener(this);
if (getIntent().getAction().equals(ACTION_EDIT)) { if (!mIsCreate) {
mDelete = findPreference("delete"); mDelete = findPreference("delete");
mDelete.setOnPreferenceClickListener(this); mDelete.setOnPreferenceClickListener(this);
} }
bindService(new Intent(this, SyncthingService.class), getActivity().bindService(new Intent(getActivity(), SyncthingService.class),
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE); mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
} }
@Override @Override
public void onApiChange(SyncthingService.State currentState) { public void onApiChange(SyncthingService.State currentState) {
if (currentState != SyncthingService.State.ACTIVE) { if (currentState != SyncthingService.State.ACTIVE) {
SyncthingService.showDisabledDialog(this); SyncthingService.showDisabledDialog(getActivity());
finish(); getActivity().finish();
return; return;
} }
if (getIntent().getAction().equals(ACTION_CREATE)) { if (mIsCreate) {
setTitle(R.string.create_repo); getActivity().setTitle(R.string.create_repo);
mRepo = new RestApi.Repo(); mRepo = new RestApi.Repo();
mRepo.ID = ""; mRepo.ID = "";
mRepo.Directory = ""; mRepo.Directory = "";
mRepo.Nodes = new ArrayList<RestApi.Node>(); mRepo.Nodes = new ArrayList<RestApi.Node>();
mRepo.Versioning = new RestApi.Versioning(); mRepo.Versioning = new RestApi.Versioning();
} }
else if (getIntent().getAction().equals(ACTION_EDIT)) { else {
setTitle(R.string.edit_repo); getActivity().setTitle(R.string.edit_repo);
List<RestApi.Repo> repos = mSyncthingService.getApi().getRepos(); List<RestApi.Repo> repos = mSyncthingService.getApi().getRepos();
for (int i = 0; i < repos.size(); i++) { for (int i = 0; i < repos.size(); i++) {
if (repos.get(i).ID.equals(getIntent().getStringExtra(KEY_REPO_ID))) { if (repos.get(i).ID.equals(
getActivity().getIntent().getStringExtra(EXTRA_REPO_ID))) {
mRepo = repos.get(i); mRepo = repos.get(i);
break; break;
} }
@ -150,11 +151,10 @@ public class RepoSettingsActivity extends PreferenceActivity
mRepoMaster.setChecked(mRepo.ReadOnly); mRepoMaster.setChecked(mRepo.ReadOnly);
List<RestApi.Node> nodesList = mSyncthingService.getApi().getNodes(); List<RestApi.Node> nodesList = mSyncthingService.getApi().getNodes();
for (RestApi.Node n : nodesList) { for (RestApi.Node n : nodesList) {
ExtendedCheckBoxPreference cbp = ExtendedCheckBoxPreference cbp = new ExtendedCheckBoxPreference(getActivity(), n);
new ExtendedCheckBoxPreference(RepoSettingsActivity.this, n);
cbp.setTitle(n.Name); cbp.setTitle(n.Name);
cbp.setKey(KEY_NODE_SHARED); cbp.setKey(KEY_NODE_SHARED);
cbp.setOnPreferenceChangeListener(RepoSettingsActivity.this); cbp.setOnPreferenceChangeListener(RepoSettingsFragment.this);
cbp.setChecked(false); cbp.setChecked(false);
for (RestApi.Node n2 : mRepo.Nodes) { for (RestApi.Node n2 : mRepo.Nodes) {
if (n2.NodeID.equals(n.NodeID)) { if (n2.NodeID.equals(n.NodeID)) {
@ -175,15 +175,14 @@ public class RepoSettingsActivity extends PreferenceActivity
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getMenuInflater().inflate(R.menu.repo_settings, menu); super.onCreateOptionsMenu(menu, inflater);
return true; inflater.inflate(R.menu.repo_settings, menu);
} }
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.create).setVisible(getIntent().getAction().equals(ACTION_CREATE)); menu.findItem(R.id.create).setVisible(mIsCreate);
return true;
} }
@Override @Override
@ -191,18 +190,20 @@ public class RepoSettingsActivity extends PreferenceActivity
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.create: case R.id.create:
if (mRepo.ID.equals("")) { if (mRepo.ID.equals("")) {
Toast.makeText(this, R.string.repo_id_required, Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), R.string.repo_id_required, Toast.LENGTH_LONG)
.show();
return true; return true;
} }
if (mRepo.Directory.equals("")) { if (mRepo.Directory.equals("")) {
Toast.makeText(this, R.string.repo_path_required, Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), R.string.repo_path_required, Toast.LENGTH_LONG)
.show();
return true; return true;
} }
mSyncthingService.getApi().editRepo(mRepo, true, this); mSyncthingService.getApi().editRepo(mRepo, true, getActivity());
finish(); getActivity().finish();
return true; return true;
case android.R.id.home: case android.R.id.home:
finish(); getActivity().finish();
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@ -211,7 +212,7 @@ public class RepoSettingsActivity extends PreferenceActivity
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
unbindService(mSyncthingServiceConnection); getActivity().unbindService(mSyncthingServiceConnection);
} }
@Override @Override
@ -280,7 +281,7 @@ public class RepoSettingsActivity extends PreferenceActivity
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
if (preference.equals(mDirectory)) { if (preference.equals(mDirectory)) {
Intent intent = new Intent(this, FolderPickerActivity.class) Intent intent = new Intent(getActivity(), FolderPickerActivity.class)
.putExtra(FolderPickerActivity.EXTRA_INITIAL_DIRECTORY, .putExtra(FolderPickerActivity.EXTRA_INITIAL_DIRECTORY,
(mRepo.Directory.length() != 0) (mRepo.Directory.length() != 0)
? mRepo.Directory ? mRepo.Directory
@ -288,16 +289,17 @@ public class RepoSettingsActivity extends PreferenceActivity
startActivityForResult(intent, DIRECTORY_REQUEST_CODE); startActivityForResult(intent, DIRECTORY_REQUEST_CODE);
} }
else if (preference.equals(mNodes) && mSyncthingService.getApi().getNodes().isEmpty()) { else if (preference.equals(mNodes) && mSyncthingService.getApi().getNodes().isEmpty()) {
Toast.makeText(this, R.string.no_nodes, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), R.string.no_nodes, Toast.LENGTH_SHORT)
.show();
} }
else if (preference.equals(mDelete)) { else if (preference.equals(mDelete)) {
new AlertDialog.Builder(this) new AlertDialog.Builder(getActivity())
.setMessage(R.string.delete_repo_confirm) .setMessage(R.string.delete_repo_confirm)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
mSyncthingService.getApi().deleteRepo(mRepo, RepoSettingsActivity.this); mSyncthingService.getApi().deleteRepo(mRepo, getActivity());
finish(); getActivity().finish();
} }
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
@ -308,7 +310,7 @@ public class RepoSettingsActivity extends PreferenceActivity
} }
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == DIRECTORY_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK && requestCode == DIRECTORY_REQUEST_CODE) {
mRepo.Directory = data.getStringExtra(FolderPickerActivity.EXTRA_RESULT_DIRECTORY); mRepo.Directory = data.getStringExtra(FolderPickerActivity.EXTRA_RESULT_DIRECTORY);
mDirectory.setSummary(mRepo.Directory); mDirectory.setSummary(mRepo.Directory);
@ -317,8 +319,8 @@ public class RepoSettingsActivity extends PreferenceActivity
} }
private void repoUpdated() { private void repoUpdated() {
if (getIntent().getAction().equals(ACTION_EDIT)) { if (!mIsCreate) {
mSyncthingService.getApi().editRepo(mRepo, false, this); mSyncthingService.getApi().editRepo(mRepo, false, getActivity());
} }
} }

View file

@ -86,9 +86,10 @@ public class ReposFragment extends ListFragment implements SyncthingService.OnAp
@Override @Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getActivity(), RepoSettingsActivity.class); Intent intent = new Intent(getActivity(), SettingsActivity.class)
intent.setAction(RepoSettingsActivity.ACTION_EDIT); .setAction(SettingsActivity.ACTION_REPO_SETTINGS_FRAGMENT)
intent.putExtra(RepoSettingsActivity.KEY_REPO_ID, mAdapter.getItem(i).ID); .putExtra(SettingsActivity.EXTRA_IS_CREATE, false)
.putExtra(RepoSettingsFragment.EXTRA_REPO_ID, mAdapter.getItem(i).ID);
startActivity(intent); startActivity(intent);
} }

View file

@ -1,183 +1,86 @@
package com.nutomic.syncthingandroid.gui; package com.nutomic.syncthingandroid.gui;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.support.v4.app.Fragment;
import android.preference.CheckBoxPreference; import android.support.v4.app.FragmentManager;
import android.preference.EditTextPreference; import android.support.v7.app.ActionBarActivity;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.support.v4.app.NavUtils;
import android.text.InputType;
import android.view.MenuItem;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.syncthing.RestApi;
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder;
public class SettingsActivity extends PreferenceActivity /**
implements SyncthingService.OnApiChangeListener, Preference.OnPreferenceChangeListener { * General Activity used by all PreferenceFragments.
*/
public class SettingsActivity extends ActionBarActivity {
private static final String SYNCTHING_OPTIONS_KEY = "syncthing_options"; public static final String ACTION_APP_SETTINGS_FRAGMENT = "app_settings_fragment";
private static final String SYNCTHING_GUI_KEY = "syncthing_gui"; public static final String ACTION_NODE_SETTINGS_FRAGMENT = "node_settings_fragment";
private static final String SYNCTHING_VERSION_KEY = "syncthing_version"; public static final String ACTION_REPO_SETTINGS_FRAGMENT = "repo_settings_fragment";
private CheckBoxPreference mStopNotCharging;
private CheckBoxPreference mStopMobileData;
private Preference mVersion;
private PreferenceScreen mOptionsScreen;
private PreferenceScreen mGuiScreen;
private SyncthingService mSyncthingService;
/** /**
* Binds to service and sets syncthing preferences from Rest API. * Must be set for {@link #ACTION_NODE_SETTINGS_FRAGMENT} and
* {@link #ACTION_REPO_SETTINGS_FRAGMENT} to determine if an existing repo/node should be
* edited or a new one created.
*
* If this is false, {@link RepoSettingsFragment#EXTRA_REPO_ID} or
* {@link NodeSettingsFragment#EXTRA_NODE_ID} must be set (according to the selected fragment).
*/ */
private final ServiceConnection mSyncthingServiceConnection = new ServiceConnection() { public static final String EXTRA_IS_CREATE = "create";
public void onServiceConnected(ComponentName className, IBinder service) { private Fragment mFragment;
SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
mSyncthingService = binder.getService();
mSyncthingService.registerOnApiChangeListener(SettingsActivity.this);
}
public void onServiceDisconnected(ComponentName className) {
mSyncthingService = null;
}
};
@Override @Override
public void onApiChange(SyncthingService.State currentState) { protected void onCreate(Bundle savedInstanceState) {
mOptionsScreen.setEnabled(currentState == SyncthingService.State.ACTIVE);
mGuiScreen.setEnabled(currentState == SyncthingService.State.ACTIVE);
mVersion.setSummary(mSyncthingService.getApi().getVersion());
if (currentState == SyncthingService.State.ACTIVE) {
for (int i = 0; i < mOptionsScreen.getPreferenceCount(); i++) {
Preference pref = mOptionsScreen.getPreference(i);
pref.setOnPreferenceChangeListener(SettingsActivity.this);
String value = mSyncthingService.getApi()
.getValue(RestApi.TYPE_OPTIONS, pref.getKey());
applyPreference(pref, value);
}
for (int i = 0; i < mGuiScreen.getPreferenceCount(); i++) {
Preference pref = mGuiScreen.getPreference(i);
pref.setOnPreferenceChangeListener(SettingsActivity.this);
String value = mSyncthingService.getApi()
.getValue(RestApi.TYPE_GUI, pref.getKey());
applyPreference(pref, value);
}
}
}
/**
* Applies the given value to the preference.
*
* If pref is an EditTextPreference, setText is used and the value shown as summary. If pref is
* a CheckBoxPreference, setChecked is used (by parsing value as Boolean).
*/
private void applyPreference(Preference pref, String value) {
if (pref instanceof EditTextPreference) {
((EditTextPreference) pref).setText(value);
pref.setSummary(value);
}
else if (pref instanceof CheckBoxPreference) {
((CheckBoxPreference) pref).setChecked(Boolean.parseBoolean(value));
}
}
/**
* Loads layout, sets version from Rest API.
*
* Manual target API as we manually check if ActionBar is available (for ActionBar back button).
*/
@Override
@SuppressLint("AppCompatMethod")
@TargetApi(11)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
FragmentManager fm = getSupportFragmentManager();
if (savedInstanceState != null) {
mFragment = fm.getFragment(savedInstanceState,
savedInstanceState.getString("fragment_name"));
} }
else {
bindService(new Intent(this, SyncthingService.class), switch (getIntent().getAction()) {
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE); case ACTION_APP_SETTINGS_FRAGMENT:
setTitle(R.string.settings_title);
addPreferencesFromResource(R.xml.app_settings); mFragment = new SettingsFragment();
PreferenceScreen screen = getPreferenceScreen(); break;
mStopNotCharging = (CheckBoxPreference) findPreference("stop_sync_on_mobile_data"); case ACTION_NODE_SETTINGS_FRAGMENT:
mStopNotCharging.setOnPreferenceChangeListener(this); mFragment = new NodeSettingsFragment();
mStopMobileData = (CheckBoxPreference) findPreference("stop_sync_while_not_charging"); if (!getIntent().hasExtra(EXTRA_IS_CREATE)) {
mStopMobileData.setOnPreferenceChangeListener(this); throw new IllegalArgumentException("EXTRA_IS_CREATE must be set");
mVersion = screen.findPreference(SYNCTHING_VERSION_KEY);
mOptionsScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_OPTIONS_KEY);
mGuiScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_GUI_KEY);
} }
break;
@Override case ACTION_REPO_SETTINGS_FRAGMENT:
public void onDestroy() { mFragment = new RepoSettingsFragment();
super.onDestroy(); if (!getIntent().hasExtra(EXTRA_IS_CREATE)) {
unbindService(mSyncthingServiceConnection); throw new IllegalArgumentException("EXTRA_IS_CREATE must be set");
} }
break;
/**
* Handles ActionBar back selected.
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
default: default:
return super.onOptionsItemSelected(item); throw new IllegalArgumentException(
"You must provide the requested fragment type as an extra.");
} }
} }
/** fm.beginTransaction()
* Sends the updated value to {@link }RestApi}, and sets it as the summary .replace(android.R.id.content, mFragment)
* for EditTextPreference. .commit();
*/ }
@Override @Override
public boolean onPreferenceChange(Preference preference, Object o) { protected void onSaveInstanceState(Bundle outState) {
if (preference instanceof EditTextPreference) { super.onSaveInstanceState(outState);
String value = (String) o; String fragmentClassName = mFragment.getClass().getName();
preference.setSummary(value); outState.putString("fragment_name", fragmentClassName);
EditTextPreference etp = (EditTextPreference) preference; FragmentManager fm = getSupportFragmentManager();
if (etp.getEditText().getInputType() == InputType.TYPE_CLASS_NUMBER) { fm.putFragment(outState, fragmentClassName, mFragment);
o = Integer.parseInt((String) o);
}
} }
if (preference.equals(mStopNotCharging) || preference.equals(mStopMobileData)) { public boolean getIsCreate() {
mSyncthingService.updateState(); return getIntent().getBooleanExtra(EXTRA_IS_CREATE, false);
}
else if (mOptionsScreen.findPreference(preference.getKey()) != null) {
mSyncthingService.getApi().setValue(RestApi.TYPE_OPTIONS, preference.getKey(), o,
preference.getKey().equals("ListenAddress"), this);
}
else if (mGuiScreen.findPreference(preference.getKey()) != null) {
mSyncthingService.getApi().setValue(
RestApi.TYPE_GUI, preference.getKey(), o, false, this);
} }
return true;
}
} }

View file

@ -0,0 +1,177 @@
package com.nutomic.syncthingandroid.gui;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.support.v4.app.Fragment;
import android.support.v4.app.NavUtils;
import android.support.v4.preference.PreferenceFragment;
import android.support.v7.app.ActionBarActivity;
import android.text.InputType;
import android.view.MenuItem;
import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.syncthing.RestApi;
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder;
public class SettingsFragment extends PreferenceFragment
implements SyncthingService.OnApiChangeListener, Preference.OnPreferenceChangeListener {
private static final String SYNCTHING_OPTIONS_KEY = "syncthing_options";
private static final String SYNCTHING_GUI_KEY = "syncthing_gui";
private static final String SYNCTHING_VERSION_KEY = "syncthing_version";
private CheckBoxPreference mStopNotCharging;
private CheckBoxPreference mStopMobileData;
private Preference mVersion;
private PreferenceScreen mOptionsScreen;
private PreferenceScreen mGuiScreen;
private SyncthingService mSyncthingService;
/**
* Binds to service and sets syncthing preferences from Rest API.
*/
private final ServiceConnection mSyncthingServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
mSyncthingService = binder.getService();
mSyncthingService.registerOnApiChangeListener(SettingsFragment.this);
}
public void onServiceDisconnected(ComponentName className) {
mSyncthingService = null;
}
};
@Override
public void onApiChange(SyncthingService.State currentState) {
mOptionsScreen.setEnabled(currentState == SyncthingService.State.ACTIVE);
mGuiScreen.setEnabled(currentState == SyncthingService.State.ACTIVE);
mVersion.setSummary(mSyncthingService.getApi().getVersion());
if (currentState == SyncthingService.State.ACTIVE) {
for (int i = 0; i < mOptionsScreen.getPreferenceCount(); i++) {
Preference pref = mOptionsScreen.getPreference(i);
pref.setOnPreferenceChangeListener(SettingsFragment.this);
String value = mSyncthingService.getApi()
.getValue(RestApi.TYPE_OPTIONS, pref.getKey());
applyPreference(pref, value);
}
for (int i = 0; i < mGuiScreen.getPreferenceCount(); i++) {
Preference pref = mGuiScreen.getPreference(i);
pref.setOnPreferenceChangeListener(SettingsFragment.this);
String value = mSyncthingService.getApi()
.getValue(RestApi.TYPE_GUI, pref.getKey());
applyPreference(pref, value);
}
}
}
/**
* Applies the given value to the preference.
*
* If pref is an EditTextPreference, setText is used and the value shown as summary. If pref is
* a CheckBoxPreference, setChecked is used (by parsing value as Boolean).
*/
private void applyPreference(Preference pref, String value) {
if (pref instanceof EditTextPreference) {
((EditTextPreference) pref).setText(value);
pref.setSummary(value);
}
else if (pref instanceof CheckBoxPreference) {
((CheckBoxPreference) pref).setChecked(Boolean.parseBoolean(value));
}
}
/**
* Loads layout, sets version from Rest API.
*
* Manual target API as we manually check if ActionBar is available (for ActionBar back button).
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().bindService(new Intent(getActivity(), SyncthingService.class),
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
addPreferencesFromResource(R.xml.app_settings);
PreferenceScreen screen = getPreferenceScreen();
mStopNotCharging = (CheckBoxPreference) findPreference("stop_sync_on_mobile_data");
mStopNotCharging.setOnPreferenceChangeListener(this);
mStopMobileData = (CheckBoxPreference) findPreference("stop_sync_while_not_charging");
mStopMobileData.setOnPreferenceChangeListener(this);
mVersion = screen.findPreference(SYNCTHING_VERSION_KEY);
mOptionsScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_OPTIONS_KEY);
mGuiScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_GUI_KEY);
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().unbindService(mSyncthingServiceConnection);
}
/**
* Handles ActionBar back selected.
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(getActivity());
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Sends the updated value to {@link }RestApi}, and sets it as the summary
* for EditTextPreference.
*/
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
if (preference instanceof EditTextPreference) {
String value = (String) o;
preference.setSummary(value);
EditTextPreference etp = (EditTextPreference) preference;
if (etp.getEditText().getInputType() == InputType.TYPE_CLASS_NUMBER) {
o = Integer.parseInt((String) o);
}
}
if (preference.equals(mStopNotCharging) || preference.equals(mStopMobileData)) {
mSyncthingService.updateState();
}
else if (mOptionsScreen.findPreference(preference.getKey()) != null) {
mSyncthingService.getApi().setValue(RestApi.TYPE_OPTIONS, preference.getKey(), o,
preference.getKey().equals("ListenAddress"), getActivity());
}
else if (mGuiScreen.findPreference(preference.getKey()) != null) {
mSyncthingService.getApi().setValue(
RestApi.TYPE_GUI, preference.getKey(), o, false, getActivity());
}
return true;
}
}

View file

@ -19,6 +19,7 @@ import android.util.Pair;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.gui.MainActivity; import com.nutomic.syncthingandroid.gui.MainActivity;
import com.nutomic.syncthingandroid.gui.SettingsActivity; import com.nutomic.syncthingandroid.gui.SettingsActivity;
import com.nutomic.syncthingandroid.gui.SettingsFragment;
import com.nutomic.syncthingandroid.util.ConfigXml; import com.nutomic.syncthingandroid.util.ConfigXml;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
@ -409,7 +410,9 @@ public class SyncthingService extends Service {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
activity.finish(); activity.finish();
activity.startActivity(new Intent(activity, SettingsActivity.class)); Intent intent = new Intent(activity, SettingsActivity.class)
.setAction(SettingsActivity.ACTION_APP_SETTINGS_FRAGMENT);
activity.startActivity(intent);
} }
}) })
.setNegativeButton(R.string.exit, .setNegativeButton(R.string.exit,

View file

@ -1,16 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item <item
android:id="@+id/create" android:id="@+id/create"
android:title="@string/add" android:title="@string/add"
android:showAsAction="always" /> app:showAsAction="always" />
<item <item
android:id="@+id/share_node_id" android:id="@+id/share_node_id"
android:icon="@android:drawable/ic_menu_share" android:icon="@android:drawable/ic_menu_share"
android:title="@string/share_node_id" android:title="@string/share_node_id"
android:showAsAction="always" /> app:showAsAction="always" />
</menu> </menu>

View file

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item <item
android:id="@+id/create" android:id="@+id/create"
android:title="@string/create" android:title="@string/create"
android:showAsAction="always" /> app:showAsAction="always" />
</menu> </menu>

View file

@ -76,7 +76,7 @@
<!-- Title for announce server status --> <!-- Title for announce server status -->
<string name="announce_server">Announce Server</string> <string name="announce_server">Announce Server</string>
<!-- RepoSettingsActivity --> <!-- RepoSettingsFragment -->
<!-- Setting title --> <!-- Setting title -->
@ -100,10 +100,10 @@
<!-- Setting title --> <!-- Setting title -->
<string name="delete_repo">Delete Repository</string> <string name="delete_repo">Delete Repository</string>
<!-- Title for RepoSettingsActivity in create mode --> <!-- Title for RepoSettingsFragment in create mode -->
<string name="create_repo">Create Repository</string> <string name="create_repo">Create Repository</string>
<!-- Title for RepoSettingsActivity in edit mode --> <!-- Title for RepoSettingsFragment in edit mode -->
<string name="edit_repo">Edit Repository</string> <string name="edit_repo">Edit Repository</string>
<!-- Menu item to confirm repo creation --> <!-- Menu item to confirm repo creation -->
@ -121,7 +121,7 @@
<!-- Toast shown when selecting 'nodes' if no nodes have been added --> <!-- Toast shown when selecting 'nodes' if no nodes have been added -->
<string name="no_nodes">Please connect a node first.</string> <string name="no_nodes">Please connect a node first.</string>
<!-- NodeSettingsActivity --> <!-- NodeSettingsFragment -->
<!-- Setting title --> <!-- Setting title -->
@ -139,13 +139,13 @@
<!-- Setting title --> <!-- Setting title -->
<string name="delete_node">Delete Node</string> <string name="delete_node">Delete Node</string>
<!-- Title for NodeSettingsActivity in create mode --> <!-- Title for NodeSettingsFragment in create mode -->
<string name="add_node">Add Node</string> <string name="add_node">Add Node</string>
<!-- Menu item to confirm adding a node --> <!-- Menu item to confirm adding a node -->
<string name="add">Add</string> <string name="add">Add</string>
<!-- Title for NodeSettingsActivity in edit mode --> <!-- Title for NodeSettingsFragment in edit mode -->
<string name="edit_node">Edit Node</string> <string name="edit_node">Edit Node</string>
<!-- Dialog shown when attempting to delete a node --> <!-- Dialog shown when attempting to delete a node -->
@ -185,7 +185,7 @@ This app is currently in Alpha state, and you may experience bugs, performance p
There is currently no special handling for mobile data, so it may use up your data volume if active.\n\n\ There is currently no special handling for mobile data, so it may use up your data volume if active.\n\n\
Please report any problems you encounter.</string> Please report any problems you encounter.</string>
<!-- SettingsActivity --> <!-- SettingsFragment -->
<!-- Activity title --> <!-- Activity title -->