Browse Source

Back navigation fixed now.

Alexander Brakowski 10 years ago
parent
commit
cc96bcc728

+ 10 - 0
res/drawable/profile_protocol_badge.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+	<item android:bottom="4px">
+		<shape android:shape="rectangle">
+			<solid android:color="@color/light_grey" />
+			<corners android:radius="6dp" />
+		</shape>
+	</item>
+</selector>

+ 50 - 2
res/layout/profile_manager_list_item.xml

@@ -103,7 +103,7 @@
 	        android:visibility="visible"
 	        android:layout_marginLeft="20dp"/>
 
-	    <ImageView
+		<ImageView
 	        android:layout_width="48dp"
 	        android:layout_height="48dp"
 	        android:id="@+id/profile_manager_item_image"
@@ -112,6 +112,54 @@
 	        android:layout_alignParentLeft="true"
 	        android:layout_alignParentStart="true" android:scaleType="centerInside"/>
 
+		<de.tudarmstadt.informatik.hostage.ui2.layouts.FlowLayout
+				xmlns:f="http://schemas.android.com/apk/res/de.tudarmstadt.informatik.hostage"
+				android:orientation="horizontal"
+				android:layout_width="fill_parent"
+				android:layout_height="fill_parent"
+				android:layout_alignParentBottom="true"
+				android:layout_below="@+id/profile_manager_item_text"
+				android:padding="10dp"
+				f:horizontalSpacing="10dip"
+				f:verticalSpacing="10dip"
+				android:layout_alignRight="@+id/profile_manager_item_text" android:layout_alignEnd="@+id/profile_manager_item_text">
+			<TextView
+					android:layout_width="wrap_content"
+					android:layout_height="wrap_content"
+					android:textAppearance="?android:attr/textAppearanceSmall"
+					android:text="HTTP"
+					style="@style/ProfileManagerListBadge"
+					android:id="@+id/textView" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView2" android:layout_gravity="center_vertical"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView11" android:layout_gravity="bottom"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView3" android:layout_gravity="center_vertical"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView10" android:layout_gravity="bottom"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView4" android:layout_gravity="center_vertical"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView5" android:layout_gravity="center_vertical"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView9" android:layout_gravity="center_vertical"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView8" android:layout_gravity="bottom"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView6" android:layout_gravity="center_vertical"
+			          android:layout_marginLeft="10dp"/>
+			<TextView style="@style/ProfileManagerListBadge" android:layout_width="wrap_content" android:layout_height="wrap_content"
+			          android:textAppearance="?android:attr/textAppearanceSmall" android:text="HTTP" android:id="@+id/textView7" android:layout_gravity="center_vertical"
+			          android:layout_marginLeft="10dp"/>
+		</de.tudarmstadt.informatik.hostage.ui2.layouts.FlowLayout>
 	</RelativeLayout>
-
 </FrameLayout>

+ 1 - 0
res/values-de/strings.xml

@@ -21,6 +21,7 @@
 
     <string name="information">Information</string>
     <string name="wifi_not_connected_msg">Sie sind nicht mit einem WLAN Netzwerk verbunden. \n\nBitte verbinden sie sich mit einem, bevor sie HosTaGe starten.</string>
+	<string name="profile_no_services_msg">Das aktive Profil scheint keine Dienste zu überwachen.\n\nBitte aktivieren Sie Dienste in dem aktiven Profil.</string>
 
     <string name="monitor_current_connection">Überwache aktuelle Verbindung</string>
     <string name="active_profile">Aktives Profil: </string>

+ 14 - 0
res/values/attrs.xml

@@ -46,4 +46,18 @@
         <attr name="swipeDrawableUnchecked" format="reference"/>
     </declare-styleable>
 
+	<declare-styleable name="FlowLayout">
+		<attr name="horizontalSpacing" format="dimension"/>
+		<attr name="verticalSpacing" format="dimension"/>
+		<attr name="orientation" format="enum">
+			<enum name="horizontal" value="0"/>
+			<enum name="vertical" value="1"/>
+		</attr>
+		<attr name="debugDraw" format="boolean" />
+	</declare-styleable>
+	<declare-styleable name="FlowLayout_LayoutParams">
+		<attr name="layout_newLine" format="boolean"/>
+		<attr name="layout_horizontalSpacing" format="dimension"/>
+		<attr name="layout_verticalSpacing" format="dimension"/>
+	</declare-styleable>
 </resources>

+ 1 - 0
res/values/strings.xml

@@ -21,6 +21,7 @@
 
     <string name="information">Information</string>
     <string name="wifi_not_connected_msg">You are not connected to a WiFi network. \n\nPlease connect to one, before trying to activate HosTaGe.</string>
+	<string name="profile_no_services_msg">The current active protocol does not seem to monitor any services.\n\nPlease activate some services to monitor in the profile.</string>
 
     <string name="monitor_current_connection">Monitor current connection</string>
     <string name="active_profile">Active profile: </string>

+ 9 - 0
res/values/styles.xml

@@ -42,4 +42,13 @@
 		<item name="android:ellipsize">none</item>
 		<item name="android:padding">4dp</item>
 	</style>
+
+	<style name="ProfileManagerListBadge">
+		<item name="android:paddingTop">4dp</item>
+		<item name="android:paddingBottom">4dp</item>
+		<item name="android:paddingLeft">4dp</item>
+		<item name="android:paddingRight">4dp</item>
+		<item name="android:background">@drawable/profile_protocol_badge</item>
+		<item name="android:textColor">#FFFFFFFF</item>
+	</style>
 </resources>

+ 1 - 0
src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java

@@ -392,6 +392,7 @@ public final class HelperUtils {
 	}
 
 	public static boolean isWifiConnected(Context context){
+		if(context == null) return false;
 		ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
 		NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
 

+ 101 - 40
src/de/tudarmstadt/informatik/hostage/ui2/activity/MainActivity.java

@@ -45,8 +45,10 @@ import de.tudarmstadt.informatik.hostage.ui2.fragment.ServicesFragment;
 import de.tudarmstadt.informatik.hostage.ui2.fragment.SettingsFragment;
 import de.tudarmstadt.informatik.hostage.ui2.fragment.StatisticsFragment;
 import de.tudarmstadt.informatik.hostage.ui2.fragment.ThreatMapFragment;
+import de.tudarmstadt.informatik.hostage.ui2.fragment.interfaces.UpNavigatible;
 import de.tudarmstadt.informatik.hostage.ui2.fragment.opengl.ThreatIndicatorGLRenderer;
 import de.tudarmstadt.informatik.hostage.ui2.model.DrawerListItem;
+import de.tudarmstadt.informatik.hostage.ui2.model.ServicesListItem;
 
 /**
  * @author Alexander Brakowski
@@ -298,13 +300,32 @@ public class MainActivity extends Activity {
 
 		if(item.getItemId() == android.R.id.home){
 			if(!mDrawerToggle.isDrawerIndicatorEnabled()){
-				if(getFragmentManager().getBackStackEntryCount() > 0) {
-					getFragmentManager().popBackStackImmediate();
-					this.mDisplayedFragment = getFragmentManager().findFragmentById(R.id.content_frame);
-					this.mInvalidMenuItem = true;
+				if(!(this.mDisplayedFragment instanceof UpNavigatible)) {
+					mDrawerToggle.setDrawerIndicatorEnabled(true);
+					return true;
+				}
+
+				UpNavigatible upNav = (UpNavigatible) this.mDisplayedFragment;
+
+				getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
+				Fragment frag = null;
+
+				try{
+					frag = (Fragment) upNav.getUpFragment().newInstance();
+				} catch (InstantiationException e) {
+					Log.i(null, "Could not create new instance of fragment");
+				} catch (IllegalAccessException e) {
+					Log.i(null, "Could not create new instance of fragment");
+				}
+
+				if(frag != null) this.injectFragment(frag);
+
+				if(!(this.mDisplayedFragment instanceof UpNavigatible) || !((UpNavigatible) this.mDisplayedFragment).isUpNavigatible()){
+					mDrawerToggle.setDrawerIndicatorEnabled(true);
+				} else {
+					mDrawerToggle.setDrawerIndicatorEnabled(false);
 				}
 
-				if(getCurrentFragment().getTag() != null) mDrawerToggle.setDrawerIndicatorEnabled(true);
 				return true;
 			}
 		}
@@ -341,27 +362,30 @@ public class MainActivity extends Activity {
 		return this.mDisplayedFragment;
 	}
 
+	public void setDrawerIndicatorEnabled(boolean val){
+		mDrawerToggle.setDrawerIndicatorEnabled(val);
+	}
+
 	public void displayView(int position) {
-		if(mSelectedMenuItem != null && position == mSelectedMenuItem.value && !mInvalidMenuItem) {
+		MainMenuItem menuItemPosition = MainMenuItem.create(position);
+
+		if(this.mDisplayedFragment != null && this.mDisplayedFragment.getClass() == menuItemPosition.getKlass()) {
 			mDrawerLayout.closeDrawer(mDrawerList);
 			return;
 		}
 
-        // DONT OPEN SAME VIEW AGAIN
-		mInvalidMenuItem = false;
-		MainMenuItem menuItemPosition = mSelectedMenuItem = MainMenuItem.create(position);
-
         Fragment fragment = null;
 
-		// set orientation fixed to portrait in home fragment
-		if(menuItemPosition == MainMenuItem.HOME){
-			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT | ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
-		} else {
-			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
+		try {
+			fragment = (Fragment) menuItemPosition.getKlass().newInstance();
+		} catch (InstantiationException e) {
+			Log.i(menuItemPosition.getKlass().toString(), "Could not create new instance of fragment");
+		} catch (IllegalAccessException e) {
+			Log.i(menuItemPosition.getKlass().toString(), "Could not create new instance of fragment");
 		}
 
-        // update the main content by replacing fragments
-		switch (menuItemPosition) {
+		// update the main content by replacing fragments
+		/*switch (menuItemPosition) {
 			case HOME:
 				fragment = new HomeFragment();
 				break;
@@ -394,11 +418,11 @@ public class MainActivity extends Activity {
 				break;
 			default:
 				break;
-		}
+		}*/
 
 		if (fragment != null) {
 			// update selected item and title, then close the drawer if needed
-            injectFragment(fragment, false, menuItemPosition);
+            injectFragment(fragment);//, false, menuItemPosition);
 
 		    mDrawerList.setItemChecked(position, true);
 		    mDrawerList.setSelection(position);
@@ -409,29 +433,53 @@ public class MainActivity extends Activity {
 	}
 
 	public void injectFragment(Fragment fragment, boolean enableBack){
-		injectFragment(fragment, enableBack, null);
+		injectFragment(fragment);
 	}
 
-	public void injectFragment(Fragment fragment, boolean enableBack, Object tagObj){
-		if(enableBack){
-			mDrawerToggle.setDrawerIndicatorEnabled(false);
+	public void injectFragment(Fragment fragment){
+		// set orientation fixed to portrait in home fragment
+		if(fragment instanceof UpNavigatible){
+			UpNavigatible upFrag = (UpNavigatible) fragment;
+			if(upFrag.getUpFragment() == null){
+				upFrag.setUpFragment(this.mDisplayedFragment.getClass());
+			}
+			if(upFrag.isUpNavigatible()){
+				mDrawerToggle.setDrawerIndicatorEnabled(false);
+			}
 		}
 
-		String tag = (tagObj == null ? null : tagObj.toString());
+		configureFragment(fragment);
 
 		FragmentManager fragmentManager = getFragmentManager();
 		FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-		fragmentTransaction.replace(R.id.content_frame, fragment, tag);
+		fragmentTransaction.replace(R.id.content_frame, fragment, fragment.getClass().getName());
 
-		fragmentTransaction.addToBackStack(tag);
+		fragmentTransaction.addToBackStack(fragment.getClass().getName());
 
 		fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
 		fragmentTransaction.commit();
 
 		this.mDisplayedFragment = fragment;
-		
-		if(tagObj == null){
-			this.mInvalidMenuItem = true;
+	}
+
+	private void configureFragment(){
+		configureFragment(this.mDisplayedFragment);
+	}
+
+	private void configureFragment(Fragment fragment){
+		if(fragment == null) return;
+
+		if(fragment instanceof HomeFragment){
+			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT | ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
+		} else {
+			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
+		}
+
+		if(fragment instanceof StatisticsFragment ||
+				fragment instanceof RecordOverviewFragment){
+
+			Intent intent = this.getIntent();
+			intent.removeExtra(LogFilter.LOG_FILTER_INTENT_KEY);
 		}
 	}
 
@@ -442,8 +490,13 @@ public class MainActivity extends Activity {
 		} else {
 			super.onBackPressed();
 			this.mDisplayedFragment = getFragmentManager().findFragmentById(R.id.content_frame);
-			this.mInvalidMenuItem = true;
-			if(getCurrentFragment().getTag() != null) mDrawerToggle.setDrawerIndicatorEnabled(true);
+			configureFragment();
+
+			if(!(this.mDisplayedFragment instanceof UpNavigatible) || !((UpNavigatible) this.mDisplayedFragment).isUpNavigatible()){
+				mDrawerToggle.setDrawerIndicatorEnabled(true);
+			} else {
+				mDrawerToggle.setDrawerIndicatorEnabled(false);
+			}
 		}
 	}
 
@@ -520,27 +573,35 @@ public class MainActivity extends Activity {
 	}
 
 	public enum MainMenuItem {
-        HOME(0),
-        THREAT_MAP(1),
-        RECORDS(2),
-		STATISTICS(3),
-        SERVICES(4),
-        PROFILE_MANAGER(5),
-        SETTINGS(6),
-        APPLICATION_INFO(7);
+        HOME(0, HomeFragment.class),
+        THREAT_MAP(1, ThreatMapFragment.class),
+        RECORDS(2, RecordOverviewFragment.class),
+		STATISTICS(3, StatisticsFragment.class),
+        SERVICES(4, ServicesFragment.class),
+        PROFILE_MANAGER(5, ProfileManagerFragment.class),
+        SETTINGS(6, SettingsFragment.class),
+        APPLICATION_INFO(7, AboutFragment.class);
 
         private int value;
+		private Class<?> klass;
 
-        private MainMenuItem(int value) {
+        private MainMenuItem(int value, Class<?> klass) {
             this.value = value;
+            this.klass = klass;
         }
+
         static public MainMenuItem create(int value){
             if (value < 0 || value  >= MainMenuItem.values().length) return MainMenuItem.HOME;
             return  MainMenuItem.values()[value];
         }
+
 		public int getValue() {
 			return value;
 		}
+
+		public Class<?> getKlass(){
+			return this.klass;
+		}
     }
 
 	private class DrawerItemClickListener implements ListView.OnItemClickListener {

+ 2 - 1
src/de/tudarmstadt/informatik/hostage/ui2/fragment/ConnectionInfoDialogFragment.java

@@ -74,8 +74,9 @@ public class ConnectionInfoDialogFragment extends DialogFragment {
 				RecordOverviewFragment recordOverviewFragment = new RecordOverviewFragment();
 				recordOverviewFragment.setFilter(filter);
 				recordOverviewFragment.setGroupKey("ESSID");
+				recordOverviewFragment.setUpNavigatible(true);
 
-				MainActivity.getInstance().injectFragment(recordOverviewFragment, false, MainActivity.MainMenuItem.RECORDS);
+				MainActivity.getInstance().injectFragment(recordOverviewFragment);
 			}
 		});
 		builder.setNegativeButton(R.string.close, null);

+ 32 - 5
src/de/tudarmstadt/informatik/hostage/ui2/fragment/HomeFragment.java

@@ -270,16 +270,39 @@ public class HomeFragment extends Fragment {
 					    setStateNotConnected();
 				    } else {
 					    if(isChecked){
+						    boolean protocolActivated = false;
 						    if(ProfileManager.getInstance().getCurrentActivatedProfile() == null){
 							    for(String protocol: getResources().getStringArray(R.array.protocols)){
-								    if(!MainActivity.getInstance().getHoneyService().isRunning(protocol)) MainActivity.getInstance().getHoneyService().startListener(protocol);
+								    if(!MainActivity.getInstance().getHoneyService().isRunning(protocol)){
+									    MainActivity.getInstance().getHoneyService().startListener(protocol);
+									    protocolActivated = true;
+								    }
 							    }
 						    } else {
 							    for(String protocol: ProfileManager.getInstance().getCurrentActivatedProfile().getActiveProtocols()){
-								    if(!MainActivity.getInstance().getHoneyService().isRunning(protocol)) MainActivity.getInstance().getHoneyService().startListener(protocol);
+								    if(!MainActivity.getInstance().getHoneyService().isRunning(protocol)) {
+									    MainActivity.getInstance().getHoneyService().startListener(protocol);
+									    protocolActivated = true;
+								    }
 							    }
 						    }
-						    setStateActive();
+
+						    if(protocolActivated){
+						        setStateActive();
+						    } else {
+							    new AlertDialog.Builder(getActivity())
+									    .setTitle(R.string.information)
+									    .setMessage(R.string.profile_no_services_msg)
+									    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+										    public void onClick(DialogInterface dialog, int which) {
+
+										    }
+									    })
+									    .setIcon(android.R.drawable.ic_dialog_info)
+									    .show();
+
+							    setStateNotActive();
+						    }
 					    } else {
 						    if(MainActivity.getInstance().getHoneyService() != null && MainActivity.getInstance().isServiceRunning()){
 							    MainActivity.getInstance().getHoneyService().stopListeners();
@@ -308,13 +331,17 @@ public class HomeFragment extends Fragment {
 	@Override
 	public void onStop(){
 		super.onStop();
-		mHomeSwitchConnection.setOnCheckedChangeListener(null);
+
+		unregisterBroadcastReceiver();
+		//mHomeSwitchConnection.setOnCheckedChangeListener(null);
 	}
 
 	@Override
 	public void onStart(){
 		super.onStart();
-		mHomeSwitchConnection.setOnCheckedChangeListener(switchChangeListener);
+		registerBroadcastReceiver();
+		updateUI();
+		//mHomeSwitchConnection.setOnCheckedChangeListener(switchChangeListener);
 	}
 
 	@Override

+ 19 - 0
src/de/tudarmstadt/informatik/hostage/ui2/fragment/PreferenceHostageFrament.java

@@ -5,10 +5,13 @@ import android.os.Bundle;
 import android.preference.EditTextPreference;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
 
 import java.util.HashMap;
 
 import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
+import de.tudarmstadt.informatik.hostage.ui2.fragment.interfaces.UpNavigatible;
 
 /**
  * @author Alexander Brakowski
@@ -71,6 +74,22 @@ public class PreferenceHostageFrament extends PreferenceFragment implements Shar
 		super.onPause();
 	}
 
+/*	@Override
+	public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+		super.onPreferenceTreeClick(preferenceScreen, preference);
+
+		if (preference instanceof PreferenceScreen) {
+			if(MainActivity.getInstance().mDisplayedFragment != null && MainActivity.getInstance().mDisplayedFragment instanceof UpNavigatible){
+				((UpNavigatible) MainActivity.getInstance().mDisplayedFragment).setUpNavigatible(true);
+				((UpNavigatible) MainActivity.getInstance().mDisplayedFragment).setUpFragment(SettingsFragment.class);
+				MainActivity.getInstance().setDrawerIndicatorEnabled(false);
+				return true;
+			}
+		}
+
+		return false;
+	}*/
+
 	@Override
 	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
 		updatePreferenceSummary(key);

+ 26 - 1
src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java

@@ -38,6 +38,7 @@ import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
 import de.tudarmstadt.informatik.hostage.ui2.adapter.RecordListAdapter;
 import de.tudarmstadt.informatik.hostage.ui2.dialog.ChecklistDialog;
 import de.tudarmstadt.informatik.hostage.ui2.dialog.DateTimeDialogFragment;
+import de.tudarmstadt.informatik.hostage.ui2.fragment.interfaces.UpNavigatible;
 import de.tudarmstadt.informatik.hostage.ui2.model.ExpandableListItem;
 import de.tudarmstadt.informatik.hostage.ui2.popup.AbstractPopup;
 import de.tudarmstadt.informatik.hostage.ui2.popup.AbstractPopupItem;
@@ -45,7 +46,8 @@ import de.tudarmstadt.informatik.hostage.ui2.popup.SimplePopupItem;
 import de.tudarmstadt.informatik.hostage.ui2.popup.SimplePopupTable;
 import de.tudarmstadt.informatik.hostage.ui2.popup.SplitPopupItem;
 
-public class RecordOverviewFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener, DateTimeDialogFragment.DateTimeDialogFragmentListener {
+public class RecordOverviewFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener, DateTimeDialogFragment.DateTimeDialogFragmentListener,
+		UpNavigatible {
 	static final String SELECTED_KEY = "Selected";
 	static final String OTHERS_KEY = "Other";
 
@@ -788,4 +790,27 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
         }
 
     }
+
+	private Class<?> upFragment;
+	private boolean isUpNavigatible = false;
+
+	@Override
+	public Class<?> getUpFragment() {
+		return upFragment;
+	}
+
+	@Override
+	public void setUpFragment( Class<?> upFragment) {
+		this.upFragment = upFragment;
+	}
+
+	@Override
+	public boolean isUpNavigatible() {
+		return isUpNavigatible;
+	}
+
+	@Override
+	public void setUpNavigatible(boolean isUpNavigatible) {
+		this.isUpNavigatible = isUpNavigatible;
+	}
 }

+ 24 - 1
src/de/tudarmstadt/informatik/hostage/ui2/fragment/SettingsFragment.java

@@ -10,12 +10,13 @@ import android.widget.TextView;
 
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
+import de.tudarmstadt.informatik.hostage.ui2.fragment.interfaces.UpNavigatible;
 
 /**
  * @author Alexander Brakowski
  * @created 24.02.14 23:37
  */
-public class SettingsFragment extends Fragment {
+public class SettingsFragment extends Fragment implements UpNavigatible {
 	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
 		super.onCreateView(inflater, container, savedInstanceState);
 		getActivity().setTitle(getResources().getString(R.string.drawer_settings));
@@ -49,4 +50,26 @@ public class SettingsFragment extends Fragment {
 		FragmentManager manager = this.getFragmentManager();
 		manager.beginTransaction().replace(R.id.settings_fragment_container, new PreferenceHostageFrament()).commit();
 	}
+
+	private Class<?> upFrag;
+	private boolean isUpNav = false;
+	@Override
+	public Class<?> getUpFragment() {
+		return upFrag;
+	}
+
+	@Override
+	public void setUpFragment(Class<?> upFragment) {
+		this.upFrag = upFragment;
+	}
+
+	@Override
+	public boolean isUpNavigatible() {
+		return isUpNav;
+	}
+
+	@Override
+	public void setUpNavigatible(boolean isUpNavigatible) {
+		isUpNav = isUpNavigatible;
+	}
 }

+ 2 - 1
src/de/tudarmstadt/informatik/hostage/ui2/fragment/StatisticsFragment.java

@@ -1450,11 +1450,12 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
 
         if (fm != null){
             RecordOverviewFragment newFragment = new RecordOverviewFragment();
+	        newFragment.setUpNavigatible(true);
             newFragment.setFilter(filter);
 
             if (sortKey != null && sortKey.length() != 0) newFragment.setGroupKey(sortKey);
 
-            MainActivity.getInstance().injectFragment(newFragment, true, MainActivity.MainMenuItem.RECORDS);
+            MainActivity.getInstance().injectFragment(newFragment);
 
         }
 

+ 14 - 0
src/de/tudarmstadt/informatik/hostage/ui2/fragment/interfaces/UpNavigatible.java

@@ -0,0 +1,14 @@
+package de.tudarmstadt.informatik.hostage.ui2.fragment.interfaces;
+
+import android.app.Fragment;
+
+/**
+ * @author Alexander Brakowski
+ * @created 12.03.14 16:20
+ */
+public interface UpNavigatible {
+	public Class<?> getUpFragment();
+	public void setUpFragment(Class<?> upFragment);
+	public boolean isUpNavigatible();
+	public void setUpNavigatible(boolean isUpNavigatible);
+}

+ 326 - 0
src/de/tudarmstadt/informatik/hostage/ui2/layouts/FlowLayout.java

@@ -0,0 +1,326 @@
+package de.tudarmstadt.informatik.hostage.ui2.layouts;
+
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import de.tudarmstadt.informatik.hostage.R;
+
+public class FlowLayout extends ViewGroup {
+	public static final int HORIZONTAL = 0;
+	public static final int VERTICAL = 1;
+	private int horizontalSpacing = 0;
+	private int verticalSpacing = 0;
+	private int orientation = 0;
+	private boolean debugDraw = false;
+
+	public FlowLayout(Context context) {
+		super(context);
+
+		this.readStyleParameters(context, null);
+	}
+
+	public FlowLayout(Context context, AttributeSet attributeSet) {
+		super(context, attributeSet);
+
+		this.readStyleParameters(context, attributeSet);
+	}
+
+	public FlowLayout(Context context, AttributeSet attributeSet, int defStyle) {
+		super(context, attributeSet, defStyle);
+
+		this.readStyleParameters(context, attributeSet);
+	}
+
+	@Override
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+		int sizeWidth = MeasureSpec.getSize(widthMeasureSpec) - this.getPaddingRight() - this.getPaddingLeft();
+		int sizeHeight = MeasureSpec.getSize(heightMeasureSpec) - this.getPaddingTop() - this.getPaddingBottom();
+
+		int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
+		int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
+
+		int size;
+		int mode;
+
+		if (orientation == HORIZONTAL) {
+			size = sizeWidth;
+			mode = modeWidth;
+		} else {
+			size = sizeHeight;
+			mode = modeHeight;
+		}
+
+		int lineThicknessWithSpacing = 0;
+		int lineThickness = 0;
+		int lineLengthWithSpacing = 0;
+		int lineLength;
+
+		int prevLinePosition = 0;
+
+		int controlMaxLength = 0;
+		int controlMaxThickness = 0;
+
+		final int count = getChildCount();
+		for (int i = 0; i < count; i++) {
+			final View child = getChildAt(i);
+			if (child.getVisibility() == GONE) {
+				continue;
+			}
+
+			LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+			child.measure(
+					getChildMeasureSpec(widthMeasureSpec, this.getPaddingLeft() + this.getPaddingRight(), lp.width),
+					getChildMeasureSpec(heightMeasureSpec, this.getPaddingTop() + this.getPaddingBottom(), lp.height)
+			);
+
+			int hSpacing = this.getHorizontalSpacing(lp);
+			int vSpacing = this.getVerticalSpacing(lp);
+
+			int childWidth = child.getMeasuredWidth();
+			int childHeight = child.getMeasuredHeight();
+
+			int childLength;
+			int childThickness;
+			int spacingLength;
+			int spacingThickness;
+
+			if (orientation == HORIZONTAL) {
+				childLength = childWidth;
+				childThickness = childHeight;
+				spacingLength = hSpacing;
+				spacingThickness = vSpacing;
+			} else {
+				childLength = childHeight;
+				childThickness = childWidth;
+				spacingLength = vSpacing;
+				spacingThickness = hSpacing;
+			}
+
+			lineLength = lineLengthWithSpacing + childLength;
+			lineLengthWithSpacing = lineLength + spacingLength;
+
+			boolean newLine = lp.newLine || (mode != MeasureSpec.UNSPECIFIED && lineLength > size);
+			if (newLine) {
+				prevLinePosition = prevLinePosition + lineThicknessWithSpacing;
+
+				lineThickness = childThickness;
+				lineLength = childLength;
+				lineThicknessWithSpacing = childThickness + spacingThickness;
+				lineLengthWithSpacing = lineLength + spacingLength;
+			}
+
+			lineThicknessWithSpacing = Math.max(lineThicknessWithSpacing, childThickness + spacingThickness);
+			lineThickness = Math.max(lineThickness, childThickness);
+
+			int posX;
+			int posY;
+			if (orientation == HORIZONTAL) {
+				posX = getPaddingLeft() + lineLength - childLength;
+				posY = getPaddingTop() + prevLinePosition;
+			} else {
+				posX = getPaddingLeft() + prevLinePosition;
+				posY = getPaddingTop() + lineLength - childHeight;
+			}
+			lp.setPosition(posX, posY);
+
+			controlMaxLength = Math.max(controlMaxLength, lineLength);
+			controlMaxThickness = prevLinePosition + lineThickness;
+		}
+
+        /* need to take paddings into account */
+		if (orientation == HORIZONTAL) {
+			controlMaxLength += getPaddingLeft() + getPaddingRight();
+			controlMaxThickness += getPaddingBottom() + getPaddingTop();
+		} else {
+			controlMaxLength += getPaddingBottom() + getPaddingTop();
+			controlMaxThickness += getPaddingLeft() + getPaddingRight();
+		}
+
+		if (orientation == HORIZONTAL) {
+			this.setMeasuredDimension(resolveSize(controlMaxLength, widthMeasureSpec), resolveSize(controlMaxThickness, heightMeasureSpec));
+		} else {
+			this.setMeasuredDimension(resolveSize(controlMaxThickness, widthMeasureSpec), resolveSize(controlMaxLength, heightMeasureSpec));
+		}
+	}
+
+	private int getVerticalSpacing(LayoutParams lp) {
+		int vSpacing;
+		if (lp.verticalSpacingSpecified()) {
+			vSpacing = lp.verticalSpacing;
+		} else {
+			vSpacing = this.verticalSpacing;
+		}
+		return vSpacing;
+	}
+
+	private int getHorizontalSpacing(LayoutParams lp) {
+		int hSpacing;
+		if (lp.horizontalSpacingSpecified()) {
+			hSpacing = lp.horizontalSpacing;
+		} else {
+			hSpacing = this.horizontalSpacing;
+		}
+		return hSpacing;
+	}
+
+	@Override
+	protected void onLayout(boolean changed, int l, int t, int r, int b) {
+		final int count = getChildCount();
+		for (int i = 0; i < count; i++) {
+			View child = getChildAt(i);
+			LayoutParams lp = (LayoutParams) child.getLayoutParams();
+			child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight());
+		}
+	}
+
+	@Override
+	protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+		boolean more = super.drawChild(canvas, child, drawingTime);
+		this.drawDebugInfo(canvas, child);
+		return more;
+	}
+
+	@Override
+	protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+		return p instanceof LayoutParams;
+	}
+
+	@Override
+	protected LayoutParams generateDefaultLayoutParams() {
+		return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+	}
+
+	@Override
+	public LayoutParams generateLayoutParams(AttributeSet attributeSet) {
+		return new LayoutParams(getContext(), attributeSet);
+	}
+
+	@Override
+	protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+		return new LayoutParams(p);
+	}
+
+	private void readStyleParameters(Context context, AttributeSet attributeSet) {
+		TypedArray a = context.obtainStyledAttributes(attributeSet, R.styleable.FlowLayout);
+		try {
+			horizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 0);
+			verticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 0);
+			orientation = a.getInteger(R.styleable.FlowLayout_orientation, HORIZONTAL);
+			debugDraw = a.getBoolean(R.styleable.FlowLayout_debugDraw, false);
+		} finally {
+			a.recycle();
+		}
+	}
+
+	private void drawDebugInfo(Canvas canvas, View child) {
+		if (!debugDraw) {
+			return;
+		}
+
+		Paint childPaint = this.createPaint(0xffffff00);
+		Paint layoutPaint = this.createPaint(0xff00ff00);
+		Paint newLinePaint = this.createPaint(0xffff0000);
+
+		LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+		if (lp.horizontalSpacing > 0) {
+			float x = child.getRight();
+			float y = child.getTop() + child.getHeight() / 2.0f;
+			canvas.drawLine(x, y, x + lp.horizontalSpacing, y, childPaint);
+			canvas.drawLine(x + lp.horizontalSpacing - 4.0f, y - 4.0f, x + lp.horizontalSpacing, y, childPaint);
+			canvas.drawLine(x + lp.horizontalSpacing - 4.0f, y + 4.0f, x + lp.horizontalSpacing, y, childPaint);
+		} else if (this.horizontalSpacing > 0) {
+			float x = child.getRight();
+			float y = child.getTop() + child.getHeight() / 2.0f;
+			canvas.drawLine(x, y, x + this.horizontalSpacing, y, layoutPaint);
+			canvas.drawLine(x + this.horizontalSpacing - 4.0f, y - 4.0f, x + this.horizontalSpacing, y, layoutPaint);
+			canvas.drawLine(x + this.horizontalSpacing - 4.0f, y + 4.0f, x + this.horizontalSpacing, y, layoutPaint);
+		}
+
+		if (lp.verticalSpacing > 0) {
+			float x = child.getLeft() + child.getWidth() / 2.0f;
+			float y = child.getBottom();
+			canvas.drawLine(x, y, x, y + lp.verticalSpacing, childPaint);
+			canvas.drawLine(x - 4.0f, y + lp.verticalSpacing - 4.0f, x, y + lp.verticalSpacing, childPaint);
+			canvas.drawLine(x + 4.0f, y + lp.verticalSpacing - 4.0f, x, y + lp.verticalSpacing, childPaint);
+		} else if (this.verticalSpacing > 0) {
+			float x = child.getLeft() + child.getWidth() / 2.0f;
+			float y = child.getBottom();
+			canvas.drawLine(x, y, x, y + this.verticalSpacing, layoutPaint);
+			canvas.drawLine(x - 4.0f, y + this.verticalSpacing - 4.0f, x, y + this.verticalSpacing, layoutPaint);
+			canvas.drawLine(x + 4.0f, y + this.verticalSpacing - 4.0f, x, y + this.verticalSpacing, layoutPaint);
+		}
+
+		if (lp.newLine) {
+			if (orientation == HORIZONTAL) {
+				float x = child.getLeft();
+				float y = child.getTop() + child.getHeight() / 2.0f;
+				canvas.drawLine(x, y - 6.0f, x, y + 6.0f, newLinePaint);
+			} else {
+				float x = child.getLeft() + child.getWidth() / 2.0f;
+				float y = child.getTop();
+				canvas.drawLine(x - 6.0f, y, x + 6.0f, y, newLinePaint);
+			}
+		}
+	}
+
+	private Paint createPaint(int color) {
+		Paint paint = new Paint();
+		paint.setAntiAlias(true);
+		paint.setColor(color);
+		paint.setStrokeWidth(2.0f);
+		return paint;
+	}
+
+	public static class LayoutParams extends ViewGroup.LayoutParams {
+		private static int NO_SPACING = -1;
+		private int x;
+		private int y;
+		private int horizontalSpacing = NO_SPACING;
+		private int verticalSpacing = NO_SPACING;
+		private boolean newLine = false;
+
+		public LayoutParams(Context context, AttributeSet attributeSet) {
+			super(context, attributeSet);
+			this.readStyleParameters(context, attributeSet);
+		}
+
+		public LayoutParams(int width, int height) {
+			super(width, height);
+		}
+
+		public LayoutParams(ViewGroup.LayoutParams layoutParams) {
+			super(layoutParams);
+		}
+
+		public boolean horizontalSpacingSpecified() {
+			return horizontalSpacing != NO_SPACING;
+		}
+
+		public boolean verticalSpacingSpecified() {
+			return verticalSpacing != NO_SPACING;
+		}
+
+		public void setPosition(int x, int y) {
+			this.x = x;
+			this.y = y;
+		}
+
+		private void readStyleParameters(Context context, AttributeSet attributeSet) {
+			TypedArray a = context.obtainStyledAttributes(attributeSet, R.styleable.FlowLayout_LayoutParams);
+			try {
+				horizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_LayoutParams_layout_horizontalSpacing, NO_SPACING);
+				verticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_LayoutParams_layout_verticalSpacing, NO_SPACING);
+				newLine = a.getBoolean(R.styleable.FlowLayout_LayoutParams_layout_newLine, false);
+			} finally {
+				a.recycle();
+			}
+		}
+	}
+}