Index: config_defaults_inc.php
===================================================================
--- config_defaults_inc.php	(revision 5305)
+++ config_defaults_inc.php	(working copy)
@@ -1427,6 +1427,7 @@
 	$g_db_table['mantis_custom_field_string_table']    = '%db_table_prefix%_custom_field_string%db_table_suffix%';
 	$g_db_table['mantis_upgrade_table']					= '%db_table_prefix%_upgrade%db_table_suffix%';
 	$g_db_table['mantis_filters_table']					= '%db_table_prefix%_filters%db_table_suffix%';
+	$g_db_table['mantis_filters_my_view_table']	= '%db_table_prefix%_filters_my_view%db_table_suffix%';
 	$g_db_table['mantis_sponsorship_table']				= '%db_table_prefix%_sponsorship%db_table_suffix%';
 	$g_db_table['mantis_tokens_table']					= '%db_table_prefix%_tokens%db_table_suffix%';
 	$g_db_table['mantis_project_hierarchy_table']		= '%db_table_prefix%_project_hierarchy%db_table_suffix%';
@@ -1756,20 +1757,42 @@
 	# Boxes to be shown and their order
 	# A box that is not to be shown can have its value set to 0
 	$g_my_view_boxes = array (
-		'assigned'      => '1',
-		'unassigned'    => '2',
-		'reported'      => '3',
-		'resolved'      => '4',
-		'recent_mod'	=> '5',
-		'monitored'		=> '6',
-		'feedback'		=> '0',
-		'verify'		=> '0'
+		FILTER_ASSIGNED,
+		FILTER_UNASSIGNED,
+		FILTER_REPORTED,
+		FILTER_RESOLVED,
+		FILTER_RECENT_MOD,
+		FILTER_MONITORED,
+		// FILTER_FEEDBACK,
+		// FILTER_VERIFY,
 	);
 
+	# Allows you to set a custom "My View" on an access level basis
+	# To do this, set the key of the first dimension to the access level, then
+	# make the value an array of filters. For example:
+	# $g_my_view_access_boxes = array (
+	# 	ADMINISTRATOR => array(
+	#		FILTER_UNASSIGNED,
+	#		FILTER_ASSIGNED
+	#	),
+	#   REPORTER => array(
+	#		FILTER_REPORTED,
+	#		FILTER_MONITORED
+	#	)
+	# );
+	$g_my_view_access_boxes = array (
+ 	);
+
+	# threshold needed to customize the 'My View' screen
+	$g_custom_my_view_threshold = ANYBODY;
+ 	
 	# Toggle whether 'My View' boxes are shown in a fixed position (i.e. adjacent boxes start at the same vertical position)
 	$g_my_view_boxes_fixed_position = ON;
 
+	# Toggle whether 'My View' boxes are shown in a fixed position (i.e. adjacent boxes start at the same vertical position)
+	$g_my_view_boxes_fixed_position = ON;
 
+
 	######################
 	# RSS Feeds
 	######################
Index: core/constant_inc.php
===================================================================
--- core/constant_inc.php	(revision 5305)
+++ core/constant_inc.php	(working copy)
@@ -354,6 +354,16 @@
 	define( 'FILTER_POSITION_BOTTOM',			2 );
 	define( 'FILTER_POSITION_BOTH',				3 );  // FILTER_POSITION_TOP | FILTER_POSITION_BOTTOM (bitwise OR)
 
+	# Default Filters
+	define( 'FILTER_ASSIGNED',					-1 );
+	define( 'FILTER_RECENT_MOD',				-2 );
+	define( 'FILTER_REPORTED',					-3 );
+	define( 'FILTER_RESOLVED',					-4 );
+	define( 'FILTER_UNASSIGNED',				-5 );
+	define( 'FILTER_MONITORED',					-6 );
+	define( 'FILTER_FEEDBACK',					-7 );
+	define( 'FILTER_VERIFY',					-8 );
+
 	# Flags for settings E-mail categories
 	define( 'EMAIL_CATEGORY_PROJECT_CATEGORY',	1);
 
Index: core/filter_api.php
===================================================================
--- core/filter_api.php	(revision 5305)
+++ core/filter_api.php	(working copy)
@@ -3371,8 +3371,612 @@
 		# all of our filter values are now guaranteed to be there, and correct.
 		return $p_filter_arr;
 	}
+	
+	# Returns an array of the pre-defined filters
+	function filter_get_predefined ( $p_filter = false ) {
+		static $cache;
 
+		if (!isset($cache)) {
 
+			$t_bug_resolved_status_threshold = config_get( 'bug_resolved_status_threshold' );
+			$t_hide_status_default = config_get( 'hide_status_default' );
+			$t_default_show_changed = config_get( 'default_show_changed' );
+			$t_current_user_id = auth_get_current_user_id();
+
+			$cache = array();
+
+			$cache[ FILTER_ASSIGNED ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => META_FILTER_ANY ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'handler_id'		=> Array ( '0' => $t_current_user_id ),
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => $t_bug_resolved_status_threshold ),
+							'user_monitor'		=> Array ( '0' => META_FILTER_ANY )
+						),
+					'name' => lang_get( 'my_view_title_assigned' ),
+					'url' => 'handler_id=' . $t_current_user_id . '&amp;hide_status=' . $t_bug_resolved_status_threshold,
+					'id' => FILTER_ASSIGNED
+				);
+
+			$cache[ FILTER_RECENT_MOD ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => META_FILTER_ANY ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'handler_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => META_FILTER_NONE ),
+							'user_monitor'		=> Array ( '0' => META_FILTER_ANY )
+						),
+					'name' => lang_get( 'my_view_title_recent_mod' ),
+					'url' => 'hide_status=none',
+					'id' => FILTER_RECENT_MOD
+				);
+
+			$cache[ FILTER_REPORTED ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => META_FILTER_ANY ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => $t_current_user_id ),
+							'handler_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'sort'			=> 'last_updated',
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => $t_hide_status_default ),
+							'user_monitor'		=> Array ( '0' => META_FILTER_ANY )
+						),
+					'name' => lang_get( 'my_view_title_reported' ),
+					'url' => 'reporter_id=' . $t_current_user_id . '&amp;hide_status=' . $t_hide_status_default,
+					'id' => FILTER_REPORTED
+				);
+
+			$cache[ FILTER_RESOLVED ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => $t_bug_resolved_status_threshold ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'handler_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => $t_hide_status_default ),
+							'user_monitor'		=> Array ( '0' => META_FILTER_ANY )
+						),
+					'name' => lang_get( 'my_view_title_resolved' ),
+					'url' => 'show_status=' . $t_bug_resolved_status_threshold . '&amp;hide_status=' . $t_bug_resolved_status_threshold,
+					'id' => FILTER_RESOLVED
+				);
+
+			$cache[ FILTER_UNASSIGNED ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => META_FILTER_ANY ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'handler_id'		=> Array ( '0' => META_FILTER_NONE ),
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => $t_hide_status_default ),
+							'user_monitor'		=> Array ( '0' => META_FILTER_ANY )
+						),
+					'name' => lang_get( 'my_view_title_unassigned' ),
+					'url' => 'handler_id=[none]' . '&amp;hide_status=' . $t_hide_status_default,
+					'id' => FILTER_UNASSIGNED
+				);
+
+			$cache[ FILTER_MONITORED ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => META_FILTER_ANY ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'handler_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => $t_hide_status_default ),
+							'user_monitor'		=> Array ( '0' => $t_current_user_id )
+						),
+					'name' => lang_get( 'my_view_title_monitored' ),
+					'url' => 'user_monitor=' . $t_current_user_id . '&amp;hide_status=' . $t_hide_status_default,
+					'id' => FILTER_MONITORED
+				);
+
+
+			$cache[ FILTER_FEEDBACK ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => FEEDBACK ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => $t_current_user_id ),
+							'handler_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => $t_hide_status_default ),
+							'user_monitor'		=> Array ( '0' => META_FILTER_ANY )
+						),
+					'name' => lang_get( 'my_view_title_feedback' ),
+					'url' => 'reporter_id=' . $t_current_user_id . '&amp;show_status=' . FEEDBACK . '&amp;hide_status=' . $t_hide_status_default,
+					'id' => FILTER_FEEDBACK
+				);
+
+			$cache[ FILTER_VERIFY ] = array(
+					'filter' => array(
+							'show_category'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_severity'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_status'		=> Array ( '0' => $t_bug_resolved_status_threshold ),
+							'highlight_changed'	=> $t_default_show_changed,
+							'reporter_id'		=> Array ( '0' => $t_current_user_id ),
+							'handler_id'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_resolution'	=> Array ( '0' => META_FILTER_ANY ),
+							'show_build'		=> Array ( '0' => META_FILTER_ANY ),
+							'show_version'		=> Array ( '0' => META_FILTER_ANY ),
+							'hide_status'		=> Array ( '0' => $t_hide_status_default ),
+							'user_monitor'		=> Array ( '0' => META_FILTER_ANY )
+						),
+					'name' => lang_get( 'my_view_title_verify' ),
+					'url' => 'reporter_id=' . $t_current_user_id . '&amp;show_status=' . $t_bug_resolved_status_threshold,
+					'id' => FILTER_VERIFY
+				);
+
+		}
+
+		if (is_bool($p_filter) || empty($p_filter))
+			return $cache;
+		else if (array_key_exists($p_filter, $cache))
+			return $cache[ $p_filter ];
+		else
+			return false;
+
+	}
+
+	# Returns an array of the default filters for my view
+	function filter_get_default_my_view ( $p_project_id = ALL_PROJECTS ) {
+
+		$t_current_user_id = auth_get_current_user_id();
+
+		# Pull the list of My View boxes per access level
+		$t_access_boxes = config_get( 'my_view_access_boxes' );
+		$t_user_level = access_get_project_level( $p_project_id );
+
+		# If they don't have a custom view by access level, give them the default
+		if (array_key_exists($t_user_level, $t_access_boxes))
+			$t_config_boxes = $t_access_boxes[ $t_user_level ];
+		else
+			$t_config_boxes = config_get( 'my_view_boxes' );
+
+
+		$return = array();
+
+		foreach ($t_config_boxes AS $box) {
+
+			# if box is less than 0, that means it's a predefined box
+			if ($box < 0) {
+				$return[ $box ] = filter_get_predefined( $box );
+			}
+
+			# otherwise, we need to get this filter from the database
+			else {
+				$return[ $box ] = filter_get_row( $box );
+				if (!$return[ $box ])
+					unset ($return[ $box ]);
+				else
+					$return[ $box ]['filter'] = filter_deserialize( $return[ $box ]['filter_string'] );
+			}
+		}
+
+		# don't display "Assigned to Me" bugs to users that bugs can't be assigned to
+		if ( current_user_is_anonymous() || user_get_assigned_open_bug_count( $t_current_user_id, $p_project_id ) == 0 )
+			unset( $return[FILTER_ASSIGNED] );
+
+		# don't display "Monitored by Me" bugs to users that can't monitor bugs
+		if ( current_user_is_anonymous() OR !access_has_project_level( config_get( 'monitor_bug_threshold' ), $p_project_id, $t_current_user_id ) )
+			unset( $return[FILTER_MONITORED] );
+
+
+		# don't display "Reported by Me" bugs to users that can't report bugs
+		if ( current_user_is_anonymous() || !access_has_project_level( config_get( 'report_bug_threshold' ), $p_project_id, $t_current_user_id ) ) {
+			unset( $return[FILTER_REPORTED] );
+			unset( $return[FILTER_FEEDBACK] );
+			unset( $return[FILTER_VERIFY] );
+		}
+
+		return $return;
+	}
+
+	# Returns a list of filters specific to a user for their my_view page
+	function filter_db_get_my_view ( $p_user_id = false ) {
+
+		if (is_bool($p_user_id) || empty($p_user_id))
+			$p_user_id = auth_get_current_user_id();
+
+		$t_filters_my_view_table    = db_get_table( 'mantis_filters_my_view_table' );
+		$t_filters_table            = db_get_table( 'mantis_filters_table' );
+
+		$t_user_id = db_prepare_int( $p_user_id );
+
+		$query = "SELECT *
+
+					FROM $t_filters_my_view_table
+					  AS FMV
+
+			   LEFT JOIN $t_filters_table
+					  AS FM
+					  ON FMV.filter_id = FM.id
+
+				   WHERE FMV.user_id = $t_user_id
+					 AND ( "
+
+					 # If the user doesn't have access rights to stored queries, return only predefined filters
+					 .(access_has_project_level( config_get( 'stored_query_use_threshold' ) )?"FM.id IS NOT NULL OR ":"")
+
+					 ." FMV.filter_id < 0 )
+				ORDER BY FMV.sequence ASC";
+
+		$result = db_query( $query );
+		$query_count = db_num_rows( $result );
+
+		if ($query_count <= 0)
+			return array();
+
+		$t_filter_arr = array();
+
+		for ( $i = 0; $i < $query_count; $i++ ) {
+			$row = db_fetch_array( $result );
+
+			# if it is less than 0, that means it is a predefined filter
+			if (intval($row['filter_id']) < 0) {
+				$t_filter_arr[ intval($row['filter_id']) ] = filter_get_predefined( intval($row['filter_id']) );
+			}
+			else {
+				$t_filter_arr[ intval($row['filter_id']) ] = $row;
+				$t_filter_arr[ intval($row['filter_id']) ]['filter'] = filter_deserialize( $row['filter_string'] );
+			}
+
+			// Perform some sequence cleanup
+			if ($row['sequence'] != $i + 1)
+				filter_set_filter_sequence( $i + 1, $row['filter_id'], $t_user_id );
+
+			$t_filter_arr[ intval($row['filter_id']) ]['sequence'] = $i + 1;
+		}
+
+		return $t_filter_arr;
+	}
+
+	# Returns the next sequence value for a user
+	function filter_get_next_sequence ( $p_user_id ) {
+
+		$t_filters_my_view_table    = db_get_table( 'mantis_filters_my_view_table' );
+		$t_user_id = db_prepare_int( $p_user_id );
+
+		$query = "SELECT MAX(sequence) AS max
+					FROM $t_filters_my_view_table
+				   WHERE user_id = ". $t_user_id;
+
+		$result = db_query($query);
+		$row = db_fetch_array( $result );
+
+		return intval($row['max']) + 1;
+	}
+
+	# Returns boolean whether a filter exists
+	# $p_predefined allows you to set whether or not a predefined filter ID will return true or not
+	function filter_exists ( $p_filter_id, $p_user_id = null, $p_project_id = null, $p_predefined = true) {
+
+		# If less than zero, it must be a predefined filter ID
+		if ($p_filter_id < 0) {
+			if ($p_predefined && filter_get_predefined($p_filter_id))
+				return true;
+			else
+				return false;
+		}
+
+		# I used filter_cache_row instead of filter_get_row so I can control the errors
+		$filter = filter_cache_row( $p_filter_id, false );
+
+		if (!$filter)
+			return false;
+
+		else if (!is_null($p_user_id) && $p_user_id != $filter['user_id'])
+			return false;
+
+		else if (!is_null($p_project_id) && $p_project_id != $filter['project_id'])
+			return false;
+
+		return true;
+	}
+
+	# Removes a filter from a users 'My View'
+	function filter_remove_from_my_view ( $p_filter_id, $p_user_id = null ) {
+
+		if ( empty($p_user_id) || is_bool($p_user_id) )
+			$p_user_id = auth_get_current_user_id();
+
+		$t_filters_my_view_table    = db_get_table( 'mantis_filters_my_view_table' );
+
+		$c_user_id		= db_prepare_int( $p_user_id );
+		$c_filter_id	= db_prepare_int( $p_filter_id );
+
+		# First, we need to get the sequence of this filter so we can adjust order
+		$query = "SELECT sequence
+					FROM $t_filters_my_view_table
+				   WHERE filter_id = $c_filter_id
+					 AND user_id = $c_user_id
+				   LIMIT 1";
+
+		$result = db_query($query);
+
+		if (db_num_rows( $result ) <= 0)
+			return true;
+
+		$t_sequence = db_fetch_array( $result );
+		$t_sequence = db_prepare_int($t_sequence['sequence']);
+
+		$query = "DELETE FROM $t_filters_my_view_table
+						WHERE filter_id = $c_filter_id
+						  AND user_id = $c_user_id
+						LIMIT 1";
+
+		db_query($query);
+
+		$query = "UPDATE $t_filters_my_view_table
+					 SET sequence = sequence - 1
+				   WHERE sequence > $t_sequence
+					 AND user_id = $c_user_id";
+
+		db_query( $query );
+
+		return true;
+	}
+
+	# adds a new filter to a users 'My View'
+	function filter_add_to_my_view ($p_filter_id, $p_user_id = null) {
+
+		if ( empty($p_user_id) || is_bool($p_user_id) )
+			$p_user_id = auth_get_current_user_id();
+
+		$c_filter_id		= db_prepare_int( $p_filter_id );
+		$c_user_id			= db_prepare_int( $p_user_id );
+
+		# We can't add a non-existent filter
+		if ( !filter_exists( $c_filter_id, $c_user_id ) )
+			return false;
+
+		$t_filters_my_view_table    = db_get_table( 'mantis_filters_my_view_table' );
+
+		$query = "INSERT INTO $t_filters_my_view_table
+						  SET filter_id = $c_filter_id,
+							  user_id = $c_user_id,
+							  sequence = ". filter_get_next_sequence( $c_user_id );
+
+		db_query( $query );
+
+		return true;
+
+	}
+
+	# updates the sequence for a filter
+	function filter_set_filter_sequence ($p_sequence, $p_filter_id, $p_user_id = null) {
+
+		if ( empty($p_user_id) || is_bool($p_user_id) )
+			$p_user_id = auth_get_current_user_id();
+
+		$c_filter_id		= db_prepare_int( $p_filter_id );
+		$c_user_id			= db_prepare_int( $p_user_id );
+		$c_sequence			= db_prepare_int( $p_sequence );
+
+		$t_filters_my_view_table    = db_get_table( 'mantis_filters_my_view_table' );
+
+		$query = "UPDATE $t_filters_my_view_table
+					 SET sequence = $c_sequence
+				   WHERE filter_id = $c_filter_id
+					 AND user_id = $c_user_id
+				   LIMIT 1";
+
+		db_query( $query );
+
+	}
+
+	# Prints a select box for adding filters
+	function print_filter_my_view_inactive ( $p_show_empty = true ) {
+
+		$p_user_id = auth_get_current_user_id();
+
+		# Get the filters the user currently displays on their My View
+		$t_active = array_keys( filter_db_get_my_view() );
+
+		# Get all the predefined filters, then weed out the ones they have already set
+		$t_predefined = filter_get_predefined();
+		foreach ($t_predefined AS $key => $filter) {
+			if (in_array($key, $t_active))
+				unset($t_predefined[$key]);
+			else
+				$t_predefined[ $key ] = $filter['name'];
+		}
+
+		if ( access_has_project_level( config_get( 'stored_query_use_threshold' ) ) ) {
+
+			# Get all the available filters, then weed out the ones already in use
+			$t_available = filter_db_get_available_queries( ALL_PROJECTS, $p_user_id );
+			foreach ($t_available AS $key => $filter) {
+				if (in_array($key, $t_active))
+					unset($t_available[$key]);
+			}
+
+		} else {
+			$t_available = array();
+		}
+
+		# If both lists are empty, don't show the form unless they want us to
+		if (count($t_predefined) <= 0 && count($t_available) <= 0 && !$p_show_empty)
+			return;
+
+		?>
+		<form action="account_my_view_add.php" method="post">
+		<select name="filter_id">
+			<?php
+
+			if (count($t_available) > 0) {
+				echo "<optgroup label='". lang_get('custom_filters') ."'>";
+
+				foreach ($t_available AS $f_key => $f_title) {
+					echo "<option value='". $f_key ."'>" . string_display_line($f_title) . "</option>";
+				}
+				echo "</optgroup>";
+			}
+
+			if (count($t_predefined) > 0) {
+				echo "<optgroup label='". lang_get('predefined_filters') ."'>";
+
+				foreach ($t_predefined AS $f_key => $f_title) {
+					echo "<option value='". $f_key ."'>". string_display_line($f_title) ."</option>";
+				}
+				echo "</optgroup>";
+			}
+
+			?>
+		</select>
+		<input type="submit" class="button" value="<?php echo lang_get('add_my_view_filter'); ?>" />
+		</form>
+		<?php
+	}
+
+	# Prints a my view box from a set of query results
+	function print_filter_my_view_box ( $p_title, $p_page_number, $p_per_page, $p_custom_filter,
+										$p_project_id, $p_user_id, $p_show_sticky = null, $p_url = null, $p_show_empty = TRUE ) {
+
+		$t_page_count = 0;
+		$t_bug_count = 0;
+
+		# Run the filter query
+		$result = filter_get_bug_rows( $p_page_number, $p_per_page, $t_page_count, $t_bug_count,
+									$p_custom_filter, $p_project_id, $p_user_id, $p_show_sticky );
+
+		if (count($result) == 0 && !$p_show_empty)
+			return;
+
+		if (is_null($p_url))
+			$p_url = filter_get_url( $p_custom_filter );
+
+		$t_icon_path = config_get( 'icon_path' );
+		$t_update_bug_threshold = config_get( 'update_bug_threshold' );
+
+		?>
+		<table class="width100" cellspacing="1">
+			<tr>
+				<td class="form-title" colspan="2">
+					<a class="subtle" href="<?php echo $p_url; ?>"><?php echo string_display_line($p_title); ?></a>
+					[<a class="subtle" href="<?php echo $p_url; ?>" target="_blank">^</a>]
+					( <?php echo string_display_line(project_get_name( $p_project_id )); ?> )
+					<?php
+						if ( count( $result ) > 0 ) {
+							$v_start = $p_per_page * ($p_page_number - 1) + 1;
+							$v_end   = $v_start + count( $result ) - 1;
+						} else {
+							$v_start = 0;
+							$v_end   = 0;
+						}
+						echo "($v_start - $v_end / $t_bug_count)";
+					?>
+				</td>
+			</tr>
+			<?php
+			foreach ($result AS $row) {
+
+				?>
+				<tr bgcolor="<?php echo get_status_color($row['status']) ?>">
+
+					<td class="center">
+						<span class="small">
+						<?php
+							print_bug_link( $row['id'] );
+
+							echo '<br />';
+
+							if ( !bug_is_readonly( $row['id'] ) && access_has_bug_level( $t_update_bug_threshold, $row['id'] ) ) {
+								echo '<a href="' . string_get_bug_update_url( $row['id'] ) . '"><img border="0" src="' . $t_icon_path . 'update.png' . '" alt="' . lang_get( 'update_bug_button' ) . '" /></a>';
+							}
+
+							if ( ON == config_get( 'show_priority_text' ) ) {
+								print_formatted_priority_string( $row['status'], $row['priority'] );
+							} else {
+								print_status_icon( $row['priority'] );
+							}
+
+							$t_attachment_count = 0;
+							if (  ( file_can_view_bug_attachments( $row['id'] ) ) ) {
+							   $t_attachment_count = file_bug_attachment_count( $row['id'] );
+							}
+
+							if ( 0 < $t_attachment_count ) {
+								echo '<a href="' . string_get_bug_view_url( $row['id'] ) . '#attachments">';
+								echo '<img border="0" src="' . $t_icon_path . 'attachment.png' . '"';
+								echo ' alt="' . lang_get( 'attachment_alt' ) . '"';
+								echo ' title="' . $t_attachment_count . ' ' . lang_get( 'attachments' ) . '"';
+								echo ' />';
+								echo '</a>';
+							}
+							if ( VS_PRIVATE == $row['view_state'] ) {
+								echo '<img src="' . $t_icon_path . 'protected.gif" width="8" height="15" alt="' . lang_get( 'private' ) . '" />';
+							}
+						?>
+						</span>
+					</td>
+					<td class="left" valign="top" width="100%">
+						<span class="small">
+						<?php
+
+							echo string_attribute( $row['summary'] )
+								.'<br />';
+							# show project name if viewing 'all projects' or bug is in subproject
+							if ( ON == config_get( 'show_bug_project_links' ) &&
+								helper_get_current_project() != $row['project_id'] ) {
+								echo '['. project_get_name($row['project_id']) .'] ';
+							}
+
+							echo string_display( $row['category'] );
+
+							$t_last_updated = date( config_get( 'normal_date_format' ), $row['last_updated'] );
+
+							if ( $row['last_updated'] > strtotime( '-'. $p_custom_filter['highlight_changed'] .' hours' ) ) {
+								echo ' - <b>' . $t_last_updated . '</b>';
+							} else {
+								echo ' - ' . $t_last_updated;
+							}
+
+						?>
+						</span>
+					</td>
+				</tr>
+				<?php
+			}
+			?>
+		</table>
+
+		<?
+
+	}
+
 	/**
 	 * The following functions each print out an individual filter field.
 	 * They are derived from view_filters_page.php
Index: core/html_api.php
===================================================================
--- core/html_api.php	(revision 5305)
+++ core/html_api.php	(working copy)
@@ -841,6 +841,7 @@
 	function print_account_menu( $p_page='' ) {
 		$t_account_page 				= 'account_page.php';
 		$t_account_prefs_page 			= 'account_prefs_page.php';
+		$t_account_my_view_page 		= 'account_my_view_page.php';
 		$t_account_profile_menu_page 	= 'account_prof_menu_page.php';
 		$t_account_sponsor_page			= 'account_sponsor_page.php';
 		$t_account_manage_columns_page	= 'account_manage_columns_page.php';
@@ -852,6 +853,9 @@
 			case $t_account_prefs_page:
 				$t_account_prefs_page = '';
 				break;
+			case $t_account_my_view_page: 
+				$t_account_my_view_page = ''; 
+				break;				
 			case $t_account_profile_menu_page:
 				$t_account_profile_menu_page 	= '';
 				break;
@@ -865,6 +869,8 @@
 
 		print_bracket_link( $t_account_page, lang_get( 'account_link' ) );
 		print_bracket_link( $t_account_prefs_page, lang_get( 'change_preferences_link' ) );
+		if (access_has_global_level(config_get('custom_my_view_threshold')))
+			print_bracket_link( $t_account_my_view_page, lang_get( 'my_view_link' ) );
 		print_bracket_link( $t_account_manage_columns_page, lang_get( 'manage_columns_config' ) );
 
 		if ( access_has_project_level( config_get( 'add_profile_threshold' ) ) ) {
Index: lang/strings_english.txt
===================================================================
--- lang/strings_english.txt	(revision 5305)
+++ lang/strings_english.txt	(working copy)
@@ -1528,4 +1528,9 @@
 #account_view_page.php
 $s_view_account_title = 'User Information';
 
+# Custom Filtering
+$s_add_my_view_filter = 'Add Filter to My View';
+$s_my_view_filters = 'My View Filters';
+$s_predefined_filters = 'Predefined Filters';
+$s_custom_filters = 'Custom Filters';
 ?>
Index: my_view_page.php
===================================================================
--- my_view_page.php	(revision 5305)
+++ my_view_page.php	(working copy)
@@ -29,6 +29,7 @@
 	require_once( $t_core_path . 'compress_api.php' );
 	require_once( $t_core_path . 'filter_api.php' );
 	require_once( $t_core_path . 'last_visited_api.php' );
+	require_once( $t_core_path . 'icon_api.php' );
 
 	auth_ensure_user_authenticated();
 
@@ -55,11 +56,6 @@
 	$t_bug_count = null;
 	$t_page_count = null;
 
-	$t_boxes = config_get( 'my_view_boxes' );
-	asort ($t_boxes);
-	reset ($t_boxes);
-	#print_r ($t_boxes);
-
 	$t_project_id = helper_get_current_project();
 ?>
 
@@ -79,88 +75,115 @@
 ?>
 
 <?php
-	$t_number_of_boxes = count ( $t_boxes );
 	$t_boxes_position = config_get( 'my_view_boxes_fixed_position' );
+	$t_custom_my_view_threshold = config_get('custom_my_view_threshold');
+
+	# Make sure they have access to define a custom 'my view'
+	if (access_has_global_level($t_custom_my_view_threshold)) {
+		# Get the list of custom my_view filters
+		$t_filters = filter_db_get_my_view( $t_current_user_id, TRUE );
+
+		# If they set no custom filters, then get the default view
+		if (count($t_filters) <= 0)
+			$t_filters = filter_get_default_my_view( $t_project_id );
+
+	}	else {
+		$t_filters = filter_get_default_my_view( $t_project_id );
+	}
+
+	$t_number_of_boxes = count($t_filters);
+
 	$t_counter = 0;
 
-	while (list ($t_box_title, $t_box_display) = each ($t_boxes)) {
-		# don't display bugs that are set as 0
-		if ($t_box_display == 0) {
-			$t_number_of_boxes = $t_number_of_boxes - 1;
-		}
+	foreach ($t_filters AS $filter) {
+		$t_counter++;
 
-		# don't display "Assigned to Me" bugs to users that bugs can't be assigned to
-		else if ( $t_box_title == 'assigned' && ( current_user_is_anonymous() OR user_get_assigned_open_bug_count( $t_current_user_id, $t_project_id ) == 0 ) ) {
-			$t_number_of_boxes = $t_number_of_boxes - 1;
-		}
+		# If the filter is for a specific project, only use that project
+		if (array_key_exists('project_id', $filter) && $filter['project_id'] != 0)
+			$t_filter_project_id = $filter['project_id'];
+		else
+			$t_filter_project_id = $t_project_id;
 
-		# don't display "Monitored by Me" bugs to users that can't monitor bugs
-		else if ( $t_box_title == 'monitored' && ( current_user_is_anonymous() OR !access_has_project_level( config_get( 'monitor_bug_threshold' ), $t_project_id, $t_current_user_id ) ) ) {
-			$t_number_of_boxes = $t_number_of_boxes - 1;
-		}
+		if ( ON == $t_boxes_position ) {
+			# for even box number start new row and column
+			if ( 1 == $t_counter %2 ) {
+				echo '<tr><td valign="top" width="50%">';
 
-		# don't display "Reported by Me" bugs to users that can't report bugs
-		else if ( in_array( $t_box_title, array( 'reported', 'feedback', 'verify' ) ) && 
-				( current_user_is_anonymous() OR !access_has_project_level( config_get( 'report_bug_threshold' ), $t_project_id, $t_current_user_id ) ) ) {
-			$t_number_of_boxes = $t_number_of_boxes - 1;
-		}
+				print_filter_my_view_box(
+						$filter['name'],
+						$f_page_number,
+						$t_per_page,
+						$filter['filter'],
+						$t_filter_project_id,
+						$t_current_user_id,
+						null,
+						array_key_exists('url', $filter)?"view_all_set.php?type=1&amp;temporary=y&amp;". $filter['url']:null
+					);
+				echo '</td>';
+			}
 
-		# display the box
-		else {
-			$t_counter++;
+			# for odd box number only start new column
+			elseif ( 0 == $t_counter %2 ) {
+				echo '<td valign="top" width="50%">';
 
-			# check the style of displaying boxes - fixed (ie. each box in a separate table cell) or not
-			if ( ON == $t_boxes_position ) {
-				# for even box number start new row and column
-				if ( 1 == $t_counter%2 ) {
-					echo '<tr><td valign="top" width="50%">';
-					include( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'my_view_inc.php' );
-					echo '</td>';
-				}
+				print_filter_my_view_box(
+						$filter['name'],
+						$f_page_number,
+						$t_per_page,
+						$filter['filter'],
+						$t_filter_project_id,
+						$t_current_user_id,
+						null,
+						array_key_exists('url', $filter)?"view_all_set.php?type=1&amp;temporary=y&amp;". $filter['url']:null
+					);
 
-				# for odd box number only start new column
-				elseif ( 0 == $t_counter%2 ) {
-					echo '<td valign="top" width="50%">';
-					include( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'my_view_inc.php' );
-					echo '</td></tr>';
-				}
+				echo '</td></tr>';
+			}
 
-				# for odd number of box display one empty table cell in second column
-				if ( ( $t_counter == $t_number_of_boxes ) && 1 == $t_counter%2 ) {
-					echo '<td valign="top" width="50%"></td></tr>';
-				}
+			# for odd number of box display one empty table cell in second column
+			if ( ( $t_counter == $t_number_of_boxes ) && 1 == $t_counter ) {
+				echo '<td valign="top" width="50%"></td></tr>';
 			}
-			else if ( OFF == $t_boxes_position ) {
-				# start new table row and column for first box
-				if ( 1 == $t_counter ) {
-					echo '<tr><td valign="top" width="50%">';
-				}
 
-				# start new table column for the second half of boxes
-				if ( $t_counter == ceil ($t_number_of_boxes/2) + 1 ) {
-					echo '<td valign="top" width="50%">';
-				}
+		}
+	else {
+			# start new table row and column for first box
+			if ( 1 == $t_counter ) {
+				echo '<tr><td valign="top" width="50%">';
+			}
 
-				# display the required box
-				include( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'my_view_inc.php' );
-				echo '<br />';
+			# start new table column for the second half of boxes
+			if ( $t_counter == ceil ($t_number_of_boxes/2) + 1 ) {
+				echo '<td valign="top" width="50%">';
+			}
 
-				# close the first column for first half of boxes
-				if ( $t_counter == ceil ($t_number_of_boxes/2) ) {
-					echo '</td>';
-				}
+			# display the required box
 
-				# close the table row after all of the boxes
-				if ( $t_counter == $t_number_of_boxes ) {
-					echo '</td></tr>';
-				}
+			print_filter_my_view_box(
+					$filter['name'],
+					$f_page_number,
+					$t_per_page,
+					$filter['filter'],
+					$t_filter_project_id,
+					$t_current_user_id,
+					null,
+					array_key_exists('url', $filter)?"view_all_set.php?type=1&amp;temporary=y&amp;". $filter['url']:null
+				);
+
+			echo '<br />';
+
+			# close the first column for first half of boxes
+			if ( $t_counter == ceil ($t_number_of_boxes/2) ) {
+				echo '</td>';
 			}
+
+			# close the table row after all of the boxes
+			if ( $t_counter == $t_number_of_boxes ) {
+				echo '</td></tr>';
+			}
 		}
 	}
 
-?>
-
-<?php
 	if ( $t_status_legend_position == STATUS_LEGEND_POSITION_BOTTOM || $t_status_legend_position == STATUS_LEGEND_POSITION_BOTH ) {
 		echo '<tr>';
 		echo '<td colspan="2">';
