From 17ac1ec87c24ef75b181bbe9659f0150894f711e Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 8 Sep 2016 14:22:08 +0200
Subject: [PATCH] Countless UI fixes regarding Chatlist/Identity/Network
 editing

---
 .../libquassel/client/IdentityManager.java    |   2 +-
 .../syncables/types/impl/Identity.java        |  68 ++++++++++-
 .../chatlist/ChatListCreateActivity.java      |   2 +-
 .../chatlist/ChatListEditActivity.java        | 115 +++++++++++++-----
 .../identity/IdentityCreateActivity.java      |   2 +-
 .../identity/IdentityEditActivity.java        | 112 ++++++++++++-----
 .../identity/IdentityListActivity.java        |   6 +-
 .../nick/IdentityNickListActivity.java        |   2 +-
 .../network/NetworkCreateActivity.java        |   2 +-
 .../network/NetworkEditActivity.java          | 112 ++++++++++++-----
 .../network/NetworkListActivity.java          |   6 +-
 .../server/NetworkServerEditActivity.java     |   2 +-
 .../server/NetworkServerListActivity.java     |   2 +-
 .../main/res/menu/{editor.xml => confirm.xml} |   0
 app/src/main/res/menu/confirm_delete.xml      |  35 ++++++
 15 files changed, 359 insertions(+), 109 deletions(-)
 rename app/src/main/res/menu/{editor.xml => confirm.xml} (100%)
 create mode 100644 app/src/main/res/menu/confirm_delete.xml

diff --git a/app/src/main/java/de/kuschku/libquassel/client/IdentityManager.java b/app/src/main/java/de/kuschku/libquassel/client/IdentityManager.java
index 89f925752..d64ddf136 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/IdentityManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/IdentityManager.java
@@ -69,7 +69,7 @@ public class IdentityManager {
     }
 
     public void removeIdentity(@IntRange(from = 0) int id) {
-        identities.remove(id);
+        identityList.remove(identities.remove(id));
     }
 
     @Nullable
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java
index 8928e6e73..e09ce649c 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java
@@ -415,4 +415,70 @@ public class Identity extends AIdentity {
         super.init(objectName, provider, client);
         client.identityManager().createIdentity(this);
     }
-}
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof Identity)) return false;
+
+        Identity identity = (Identity) o;
+
+        if (id != identity.id) return false;
+        if (awayNickEnabled != identity.awayNickEnabled) return false;
+        if (awayReasonEnabled != identity.awayReasonEnabled) return false;
+        if (autoAwayEnabled != identity.autoAwayEnabled) return false;
+        if (autoAwayTime != identity.autoAwayTime) return false;
+        if (autoAwayReasonEnabled != identity.autoAwayReasonEnabled) return false;
+        if (detachAwayEnabled != identity.detachAwayEnabled) return false;
+        if (detachAwayReasonEnabled != identity.detachAwayReasonEnabled) return false;
+        if (name != null ? !name.equals(identity.name) : identity.name != null) return false;
+        if (realName != null ? !realName.equals(identity.realName) : identity.realName != null)
+            return false;
+        if (nicks != null ? !nicks.equals(identity.nicks) : identity.nicks != null) return false;
+        if (awayNick != null ? !awayNick.equals(identity.awayNick) : identity.awayNick != null)
+            return false;
+        if (awayReason != null ? !awayReason.equals(identity.awayReason) : identity.awayReason != null)
+            return false;
+        if (autoAwayReason != null ? !autoAwayReason.equals(identity.autoAwayReason) : identity.autoAwayReason != null)
+            return false;
+        if (detachAwayReason != null ? !detachAwayReason.equals(identity.detachAwayReason) : identity.detachAwayReason != null)
+            return false;
+        if (ident != null ? !ident.equals(identity.ident) : identity.ident != null) return false;
+        if (kickReason != null ? !kickReason.equals(identity.kickReason) : identity.kickReason != null)
+            return false;
+        if (partReason != null ? !partReason.equals(identity.partReason) : identity.partReason != null)
+            return false;
+        if (quitReason != null ? !quitReason.equals(identity.quitReason) : identity.quitReason != null)
+            return false;
+        if (sslKey != null ? !sslKey.equals(identity.sslKey) : identity.sslKey != null)
+            return false;
+        return sslCert != null ? sslCert.equals(identity.sslCert) : identity.sslCert == null;
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (realName != null ? realName.hashCode() : 0);
+        result = 31 * result + (nicks != null ? nicks.hashCode() : 0);
+        result = 31 * result + (awayNick != null ? awayNick.hashCode() : 0);
+        result = 31 * result + (awayNickEnabled ? 1 : 0);
+        result = 31 * result + (awayReason != null ? awayReason.hashCode() : 0);
+        result = 31 * result + (awayReasonEnabled ? 1 : 0);
+        result = 31 * result + (autoAwayEnabled ? 1 : 0);
+        result = 31 * result + autoAwayTime;
+        result = 31 * result + (autoAwayReason != null ? autoAwayReason.hashCode() : 0);
+        result = 31 * result + (autoAwayReasonEnabled ? 1 : 0);
+        result = 31 * result + (detachAwayEnabled ? 1 : 0);
+        result = 31 * result + (detachAwayReason != null ? detachAwayReason.hashCode() : 0);
+        result = 31 * result + (detachAwayReasonEnabled ? 1 : 0);
+        result = 31 * result + (ident != null ? ident.hashCode() : 0);
+        result = 31 * result + (kickReason != null ? kickReason.hashCode() : 0);
+        result = 31 * result + (partReason != null ? partReason.hashCode() : 0);
+        result = 31 * result + (quitReason != null ? quitReason.hashCode() : 0);
+        result = 31 * result + (sslKey != null ? sslKey.hashCode() : 0);
+        result = 31 * result + (sslCert != null ? sslCert.hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListCreateActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListCreateActivity.java
index 67f6280fa..5c4476bce 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListCreateActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListCreateActivity.java
@@ -101,7 +101,7 @@ public class ChatListCreateActivity extends BoundActivity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListEditActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListEditActivity.java
index 3671bb75e..c959371bf 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListEditActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/chatlist/ChatListEditActivity.java
@@ -31,6 +31,8 @@ import android.widget.CheckBox;
 import android.widget.EditText;
 import android.widget.Spinner;
 
+import com.afollestad.materialdialogs.MaterialDialog;
+
 import butterknife.Bind;
 import butterknife.ButterKnife;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
@@ -105,56 +107,105 @@ public class ChatListEditActivity extends BoundActivity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm_delete, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
+    @Override
+    public void onBackPressed() {
+        if (hasChanged()) {
+            new MaterialDialog.Builder(this)
+                    .content("You have made changes, do you wish to save them?")
+                    .positiveText("Yes")
+                    .negativeText("No")
+                    .positiveColor(context.themeUtil().res.colorAccent)
+                    .negativeColor(context.themeUtil().res.colorForeground)
+                    .onPositive((dialog, which) -> {
+                        save();
+                        super.onBackPressed();
+                    })
+                    .onNegative((dialog, which) -> super.onBackPressed())
+                    .show();
+        } else {
+            super.onBackPressed();
+        }
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
+            case R.id.action_delete: {
+                new MaterialDialog.Builder(this)
+                        .content(String.format("Are you sure you want to delete \"%s\"?", config.bufferViewName()))
+                        .positiveText("Yes")
+                        .negativeText("No")
+                        .positiveColor(context.themeUtil().res.colorAccent)
+                        .negativeColor(context.themeUtil().res.colorForeground)
+                        .onPositive((dialog, which) -> {
+                            finish();
+                            context.client().bufferViewManager().deleteBufferView(config.bufferViewId());
+                        })
+                        .build()
+                        .show();
+            } return true;
             case R.id.action_confirm: {
-                if (config != null) {
-                    String name = this.name.getText().toString();
-                    if (!Objects.equals(name, config.bufferViewName()))
-                        config.setBufferViewName(name);
+                save();
+                finish();
+            }
+            return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
 
-                    if (config.networkId() != (int) network.getSelectedItemId())
-                        config.setNetworkId((int) network.getSelectedItemId());
+    private void save() {
+        if (config != null) {
+            String name = this.name.getText().toString();
+            if (!Objects.equals(name, config.bufferViewName()))
+                config.setBufferViewName(name);
 
-                    if (config.minimumActivity() != QBufferViewConfig.MinimumActivity.fromId((int) minimumActivity.getSelectedItemId()))
-                        config.setMinimumActivity(QBufferViewConfig.MinimumActivity.fromId((int) minimumActivity.getSelectedItemId()));
+            if (config.networkId() != (int) network.getSelectedItemId())
+                config.setNetworkId((int) network.getSelectedItemId());
 
-                    int allowedBufferTypes = config.allowedBufferTypes();
-                    config.setBufferTypeAllowed(BufferInfo.Type.CHANNEL, this.showChannels.isChecked());
-                    config.setBufferTypeAllowed(BufferInfo.Type.QUERY, this.showQueries.isChecked());
-                    if (config.allowedBufferTypes() != allowedBufferTypes)
-                        config.setAllowedBufferTypes(allowedBufferTypes);
+            if (config.minimumActivity() != QBufferViewConfig.MinimumActivity.fromId((int) minimumActivity.getSelectedItemId()))
+                config.setMinimumActivity(QBufferViewConfig.MinimumActivity.fromId((int) minimumActivity.getSelectedItemId()));
 
-                    boolean hideInactiveChats = this.hideInactiveChats.isChecked();
-                    if (hideInactiveChats != config.hideInactiveBuffers())
-                        config.setHideInactiveBuffers(hideInactiveChats);
+            int allowedBufferTypes = config.allowedBufferTypes();
+            config.setBufferTypeAllowed(BufferInfo.Type.CHANNEL, this.showChannels.isChecked());
+            config.setBufferTypeAllowed(BufferInfo.Type.QUERY, this.showQueries.isChecked());
+            if (config.allowedBufferTypes() != allowedBufferTypes)
+                config.setAllowedBufferTypes(allowedBufferTypes);
 
-                    boolean hideInactiveNetworks = this.hideInactiveNetworks.isChecked();
-                    if (hideInactiveNetworks != config.hideInactiveNetworks())
-                        config.setHideInactiveNetworks(hideInactiveNetworks);
+            boolean hideInactiveChats = this.hideInactiveChats.isChecked();
+            if (hideInactiveChats != config.hideInactiveBuffers())
+                config.setHideInactiveBuffers(hideInactiveChats);
 
-                    boolean addAutomatically = this.addAutomatically.isChecked();
-                    if (addAutomatically != config.addNewBuffersAutomatically())
-                        config.setAddNewBuffersAutomatically(addAutomatically);
+            boolean hideInactiveNetworks = this.hideInactiveNetworks.isChecked();
+            if (hideInactiveNetworks != config.hideInactiveNetworks())
+                config.setHideInactiveNetworks(hideInactiveNetworks);
 
-                    boolean sortAlphabetically = this.sortAlphabetically.isChecked();
-                    if (sortAlphabetically != config.sortAlphabetically())
-                        config.setSortAlphabetically(sortAlphabetically);
+            boolean addAutomatically = this.addAutomatically.isChecked();
+            if (addAutomatically != config.addNewBuffersAutomatically())
+                config.setAddNewBuffersAutomatically(addAutomatically);
 
-                    finish();
-                }
-            }
-            return true;
-            default:
-                return super.onOptionsItemSelected(item);
+            boolean sortAlphabetically = this.sortAlphabetically.isChecked();
+            if (sortAlphabetically != config.sortAlphabetically())
+                config.setSortAlphabetically(sortAlphabetically);
         }
     }
 
+    private boolean hasChanged() {
+        return !Objects.equals(name.getText().toString(), config.bufferViewName()) ||
+                config.networkId() != (int) network.getSelectedItemId() ||
+                config.minimumActivity() != QBufferViewConfig.MinimumActivity.fromId((int) minimumActivity.getSelectedItemId()) ||
+                config.isBufferTypeAllowed(BufferInfo.Type.CHANNEL) != this.showChannels.isChecked() ||
+                config.isBufferTypeAllowed(BufferInfo.Type.QUERY) != this.showQueries.isChecked() ||
+                this.hideInactiveChats.isChecked() != config.hideInactiveBuffers() ||
+                this.hideInactiveNetworks.isChecked() != config.hideInactiveNetworks() ||
+                this.addAutomatically.isChecked() != config.addNewBuffersAutomatically() ||
+                this.sortAlphabetically.isChecked() != config.sortAlphabetically();
+    }
+
     @Override
     protected void onConnected() {
         networkSpinnerAdapter.setNetworkManager(context.client().networkManager());
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityCreateActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityCreateActivity.java
index 8a2f582ca..4c329fb24 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityCreateActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityCreateActivity.java
@@ -133,7 +133,7 @@ public class IdentityCreateActivity extends BoundActivity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityEditActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityEditActivity.java
index c352ce24b..467ca0827 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityEditActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityEditActivity.java
@@ -33,6 +33,8 @@ import android.widget.Button;
 import android.widget.CompoundButton;
 import android.widget.EditText;
 
+import com.afollestad.materialdialogs.MaterialDialog;
+
 import java.util.ArrayList;
 
 import butterknife.Bind;
@@ -139,56 +141,104 @@ public class IdentityEditActivity extends BoundActivity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm_delete, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
+    @Override
+    public void onBackPressed() {
+        if (hasChanged(build())) {
+            new MaterialDialog.Builder(this)
+                    .content("You have made changes, do you wish to save them?")
+                    .positiveText("Yes")
+                    .negativeText("No")
+                    .positiveColor(context.themeUtil().res.colorAccent)
+                    .negativeColor(context.themeUtil().res.colorForeground)
+                    .onPositive((dialog, which) -> {
+                        save();
+                        super.onBackPressed();
+                    })
+                    .onNegative((dialog, which) -> super.onBackPressed())
+                    .show();
+        } else {
+            super.onBackPressed();
+        }
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
+            case R.id.action_delete: {
+                new MaterialDialog.Builder(this)
+                        .content(String.format("Are you sure you want to delete \"%s\"?", identity.identityName()))
+                        .positiveText("Yes")
+                        .negativeText("No")
+                        .positiveColor(context.themeUtil().res.colorAccent)
+                        .negativeColor(context.themeUtil().res.colorForeground)
+                        .onPositive((dialog, which) -> {
+                            finish();
+                            context.client().removeIdentity(identity.id());
+                        })
+                        .build()
+                        .show();
+            } return true;
             case R.id.action_confirm: {
-                if (identity != null) {
-                    Identity newIdentity = Identity.createDefault();
-                    newIdentity._copyFrom(identity);
+                save();
+                finish();
+            } return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    private void save() {
+        Identity after = build();
+        if (hasChanged(after))
+            identity.update(after);
+    }
+
+    private boolean hasChanged(Identity identity) {
+        return this.identity != null && identity != null && !this.identity.equals(identity);
+    }
 
-                    if (!identity.identityName().equals(identityName.getText().toString()))
-                        newIdentity._setIdentityName(identityName.getText().toString());
+    private Identity build() {
+        if (identity == null) {
+            return null;
+        } else {
+            Identity newIdentity = Identity.createDefault();
+            newIdentity._copyFrom(identity);
 
-                    if (!identity.realName().equals(realName.getText().toString()))
-                        newIdentity._setRealName(realName.getText().toString());
+            if (!identity.identityName().equals(identityName.getText().toString()))
+                newIdentity._setIdentityName(identityName.getText().toString());
 
-                    if (!identity.ident().equals(ident.getText().toString()))
-                        newIdentity._setIdent(ident.getText().toString());
+            if (!identity.realName().equals(realName.getText().toString()))
+                newIdentity._setRealName(realName.getText().toString());
 
-                    if (!identity.nicks().equals(nickList))
-                        newIdentity._setNicks(nickList);
+            if (!identity.ident().equals(ident.getText().toString()))
+                newIdentity._setIdent(ident.getText().toString());
 
-                    if (!identity.kickReason().equals(kickReason.getText().toString()))
-                        newIdentity._setKickReason(kickReason.getText().toString());
+            if (!identity.nicks().equals(nickList))
+                newIdentity._setNicks(nickList);
 
-                    if (!identity.partReason().equals(partReason.getText().toString()))
-                        newIdentity._setPartReason(partReason.getText().toString());
+            if (!identity.kickReason().equals(kickReason.getText().toString()))
+                newIdentity._setKickReason(kickReason.getText().toString());
 
-                    if (!identity.quitReason().equals(quitReason.getText().toString()))
-                        newIdentity._setQuitReason(quitReason.getText().toString());
+            if (!identity.partReason().equals(partReason.getText().toString()))
+                newIdentity._setPartReason(partReason.getText().toString());
 
-                    if (!identity.awayReason().equals(awayReason.getText().toString()))
-                        newIdentity._setAwayReason(awayReason.getText().toString());
+            if (!identity.quitReason().equals(quitReason.getText().toString()))
+                newIdentity._setQuitReason(quitReason.getText().toString());
 
-                    if (!identity.detachAwayEnabled() == useAwayOnDetach.isChecked())
-                        newIdentity._setDetachAwayEnabled(useAwayOnDetach.isChecked());
+            if (!identity.awayReason().equals(awayReason.getText().toString()))
+                newIdentity._setAwayReason(awayReason.getText().toString());
 
-                    if (!identity.detachAwayReason().equals(awayOnDetachReason.getText().toString()))
-                        newIdentity._setDetachAwayReason(awayOnDetachReason.getText().toString());
+            if (!identity.detachAwayEnabled() == useAwayOnDetach.isChecked())
+                newIdentity._setDetachAwayEnabled(useAwayOnDetach.isChecked());
 
-                    if (!newIdentity.equals(identity))
-                        identity.update(newIdentity);
+            if (!identity.detachAwayReason().equals(awayOnDetachReason.getText().toString()))
+                newIdentity._setDetachAwayReason(awayOnDetachReason.getText().toString());
 
-                    finish();
-                }
-            } return true;
-            default:
-                return super.onOptionsItemSelected(item);
+            return newIdentity;
         }
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityListActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityListActivity.java
index 38635e93c..6cd15a9ac 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityListActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/IdentityListActivity.java
@@ -55,7 +55,7 @@ public class IdentityListActivity extends BoundActivity {
     @Bind(R.id.toolbar)
     Toolbar toolbar;
 
-    ChatListAdapter adapter;
+    IdentityAdapter adapter;
     OnQIdentityClickListener clickListener = identity -> {
         if (identity != null) {
             Intent intent = new Intent(this, IdentityEditActivity.class);
@@ -72,7 +72,7 @@ public class IdentityListActivity extends BoundActivity {
 
         list.setLayoutManager(new LinearLayoutManager(this));
         list.setItemAnimator(new DefaultItemAnimator());
-        adapter = new ChatListAdapter();
+        adapter = new IdentityAdapter();
         list.setAdapter(adapter);
 
         add.setOnClickListener(view -> {
@@ -99,7 +99,7 @@ public class IdentityListActivity extends BoundActivity {
         void onClick(QIdentity network);
     }
 
-    private class ChatListAdapter extends RecyclerView.Adapter<IdentityViewHolder> {
+    private class IdentityAdapter extends RecyclerView.Adapter<IdentityViewHolder> {
         IdentityManager manager;
         AdapterUICallbackWrapper wrapper = new AdapterUICallbackWrapper(this);
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/nick/IdentityNickListActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/nick/IdentityNickListActivity.java
index 198ad8257..031130854 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/nick/IdentityNickListActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/identity/nick/IdentityNickListActivity.java
@@ -129,7 +129,7 @@ public class IdentityNickListActivity extends BoundActivity implements OnStartDr
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkCreateActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkCreateActivity.java
index 202bf3a09..cb56db012 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkCreateActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkCreateActivity.java
@@ -235,7 +235,7 @@ public class NetworkCreateActivity extends BoundActivity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkEditActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkEditActivity.java
index 2e240b49c..563bb1ff3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkEditActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkEditActivity.java
@@ -37,6 +37,8 @@ import android.widget.CompoundButton;
 import android.widget.EditText;
 import android.widget.Spinner;
 
+import com.afollestad.materialdialogs.MaterialDialog;
+
 import java.util.Arrays;
 import java.util.List;
 
@@ -228,51 +230,97 @@ public class NetworkEditActivity extends BoundActivity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm_delete, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
+    @Override
+    public void onBackPressed() {
+        if (hasChanged(build())) {
+            new MaterialDialog.Builder(this)
+                    .content("You have made changes, do you wish to save them?")
+                    .positiveText("Yes")
+                    .negativeText("No")
+                    .positiveColor(context.themeUtil().res.colorAccent)
+                    .negativeColor(context.themeUtil().res.colorForeground)
+                    .onPositive((dialog, which) -> {
+                        save();
+                        super.onBackPressed();
+                    })
+                    .onNegative((dialog, which) -> super.onBackPressed())
+                    .show();
+        } else {
+            super.onBackPressed();
+        }
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
+            case R.id.action_delete: {
+                new MaterialDialog.Builder(this)
+                        .content(String.format("Are you sure you want to delete \"%s\"?", network.networkName()))
+                        .positiveText("Yes")
+                        .negativeText("No")
+                        .positiveColor(context.themeUtil().res.colorAccent)
+                        .negativeColor(context.themeUtil().res.colorForeground)
+                        .onPositive((dialog, which) -> {
+                            finish();
+                            context.client().removeNetwork(network.networkId());
+                        })
+                        .build()
+                        .show();
+            } return true;
             case R.id.action_confirm: {
-                NetworkInfo networkInfo = this.network.networkInfo();
-                if (networkInfo != null) {
-                    NetworkInfo after = new NetworkInfo(
-                            networkInfo.networkId(),
-                            networkName.getText().toString(),
-                            (int) identity.getSelectedItemId(),
-                            useCustomCodecs.isChecked() ? this.codecForServer.getText().toString() : null,
-                            useCustomCodecs.isChecked() ? this.codecForEncoding.getText().toString() : null,
-                            useCustomCodecs.isChecked() ? this.codecForDecoding.getText().toString() : null,
-                            serverList == null ? networkInfo.serverList() : serverList,
-                            networkInfo.useRandomServer(),
-                            //FIXME: IMPLEMENT
-                            networkInfo.perform(),
-                            useAutoIdentify.isChecked(),
-                            autoIdentifyService.getText().toString(),
-                            autoIdentifyPassword.getText().toString(),
-                            useSasl.isChecked(),
-                            saslAccount.getText().toString(),
-                            saslPassword.getText().toString(),
-                            useAutoReconnect.isChecked(),
-                            NumberHelper.parseInt(autoReconnectInterval.getText().toString(), 0),
-                            NumberHelper.parseShort(autoReconnectRetries.getText().toString(), (short) 0),
-                            unlimitedAutoReconnectRetries.isChecked(),
-                            rejoinChannels.isChecked()
-                    );
-
-                    if (!Objects.equals(networkInfo, after))
-                        network.setNetworkInfo(after);
-
-                    finish();
-                }
+                save();
+                finish();
             } return true;
             default:
                 return super.onOptionsItemSelected(item);
         }
     }
 
+    private void save() {
+        NetworkInfo info = build();
+        if (hasChanged(info))
+            network.setNetworkInfo(info);
+    }
+
+    private boolean hasChanged(NetworkInfo info) {
+        return network != null && network.networkInfo() != null && info != null && !Objects.equals(network.networkInfo(), info);
+    }
+
+    private NetworkInfo build() {
+        NetworkInfo networkInfo = this.network.networkInfo();
+        if (networkInfo == null) {
+            return null;
+        } else {
+            return new NetworkInfo(
+                    networkInfo.networkId(),
+                    networkName.getText().toString(),
+                    (int) identity.getSelectedItemId(),
+                    useCustomCodecs.isChecked() ? this.codecForServer.getText().toString() : null,
+                    useCustomCodecs.isChecked() ? this.codecForEncoding.getText().toString() : null,
+                    useCustomCodecs.isChecked() ? this.codecForDecoding.getText().toString() : null,
+                    serverList == null ? networkInfo.serverList() : serverList,
+                    networkInfo.useRandomServer(),
+                    //FIXME: IMPLEMENT
+                    networkInfo.perform(),
+                    useAutoIdentify.isChecked(),
+                    autoIdentifyService.getText().toString(),
+                    autoIdentifyPassword.getText().toString(),
+                    useSasl.isChecked(),
+                    saslAccount.getText().toString(),
+                    saslPassword.getText().toString(),
+                    useAutoReconnect.isChecked(),
+                    NumberHelper.parseInt(autoReconnectInterval.getText().toString(), 0),
+                    NumberHelper.parseShort(autoReconnectRetries.getText().toString(), (short) 0),
+                    unlimitedAutoReconnectRetries.isChecked(),
+                    rejoinChannels.isChecked()
+            );
+        }
+    }
+
     @Override
     protected void onConnected() {
         spinnerAdapter.setIdentityManager(context.client().identityManager());
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkListActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkListActivity.java
index 1ff3434c6..de5251792 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkListActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/NetworkListActivity.java
@@ -55,7 +55,7 @@ public class NetworkListActivity extends BoundActivity {
     @Bind(R.id.toolbar)
     Toolbar toolbar;
 
-    ChatListAdapter adapter;
+    NetworkAdapter adapter;
     OnQNetworkClickListener clickListener = network -> {
         if (network != null) {
             Intent intent = new Intent(this, NetworkEditActivity.class);
@@ -72,7 +72,7 @@ public class NetworkListActivity extends BoundActivity {
 
         list.setLayoutManager(new LinearLayoutManager(this));
         list.setItemAnimator(new DefaultItemAnimator());
-        adapter = new ChatListAdapter();
+        adapter = new NetworkAdapter();
         list.setAdapter(adapter);
 
         add.setOnClickListener(view -> {
@@ -99,7 +99,7 @@ public class NetworkListActivity extends BoundActivity {
         void onClick(QNetwork network);
     }
 
-    private class ChatListAdapter extends RecyclerView.Adapter<NetworkViewHolder> {
+    private class NetworkAdapter extends RecyclerView.Adapter<NetworkViewHolder> {
         NetworkManager manager;
         AdapterUICallbackWrapper wrapper = new AdapterUICallbackWrapper(this);
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerEditActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerEditActivity.java
index 7cb8e7c85..eb2e7846f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerEditActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerEditActivity.java
@@ -158,7 +158,7 @@ public class NetworkServerEditActivity extends BoundActivity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerListActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerListActivity.java
index 3cb32d334..1de6ee000 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerListActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/network/server/NetworkServerListActivity.java
@@ -104,7 +104,7 @@ public class NetworkServerListActivity extends BoundActivity implements OnStartD
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.editor, menu);
+        getMenuInflater().inflate(R.menu.confirm, menu);
         return super.onCreateOptionsMenu(menu);
     }
 
diff --git a/app/src/main/res/menu/editor.xml b/app/src/main/res/menu/confirm.xml
similarity index 100%
rename from app/src/main/res/menu/editor.xml
rename to app/src/main/res/menu/confirm.xml
diff --git a/app/src/main/res/menu/confirm_delete.xml b/app/src/main/res/menu/confirm_delete.xml
new file mode 100644
index 000000000..d45a6de75
--- /dev/null
+++ b/app/src/main/res/menu/confirm_delete.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ QuasselDroid - Quassel client for Android
+  ~ Copyright (C) 2016 Janne Koschinski
+  ~ Copyright (C) 2016 Ken Børge Viktil
+  ~ Copyright (C) 2016 Magnus Fjell
+  ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify it
+  ~ under the terms of the GNU General Public License as published by the Free
+  ~ Software Foundation, either version 3 of the License, or (at your option)
+  ~ any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License along
+  ~ with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/action_delete"
+        android:icon="@drawable/ic_delete"
+        android:title="Delete"
+        app:showAsAction="always"/>
+    <item
+        android:id="@+id/action_confirm"
+        android:icon="@drawable/ic_check"
+        android:title="Save"
+        app:showAsAction="always"/>
+</menu>
\ No newline at end of file
-- 
GitLab