Index: branches/5.1.x/admin/system_presets/simple/form_submissions_formsubs.php
===================================================================
--- branches/5.1.x/admin/system_presets/simple/form_submissions_formsubs.php	(revision 13822)
+++ branches/5.1.x/admin/system_presets/simple/form_submissions_formsubs.php	(revision 13823)
@@ -1,43 +1,43 @@
 <?php
 
 	defined('FULL_PATH') or die('restricted access!');
 
 	// toolbar buttons
 	$remove_buttons = Array (
 //		list of forms
-//		'formsubs_list' => Array ('edit', 'delete', 'dbl-click'),
+//		'formsubs_list' => Array ('edit', 'delete', 'view', 'dbl-click'),
 
 //		editing form
 //		'formsubs_view' => Array ('select', 'cancel', 'prev', 'next'),
 	);
 
 	// fields to hide
 	$hidden_fields = Array (
 		/* 'FormSubmissionId', 'FormId', 'SubmissionTime', */
 	);
 
 	// virtual fields to hide
 	$virtual_hidden_fields = Array (
 
 	);
 
 	// fields to make required (dynamic required fields won't work if this is uncommented)
 //	$required_fields = Array (
 //		/* 'FormSubmissionId', 'FormId', 'SubmissionTime', */
 //	);
 
 	// virtual fields to make required
 	$virtual_required_fields = Array (
 
 	);
 
 	// tabs during editing
 	$hide_edit_tabs = Array (
 
 	);
 
 	// hide columns in grids
 	$hide_columns = Array (
 //		submission columns
 //		'Default' => Array ('FormSubmissionId', 'SubmissionTime'),
 	);
Index: branches/5.1.x/core/units/forms/form_submissions/form_submissions_eh.php
===================================================================
--- branches/5.1.x/core/units/forms/form_submissions/form_submissions_eh.php	(revision 13822)
+++ branches/5.1.x/core/units/forms/form_submissions/form_submissions_eh.php	(revision 13823)
@@ -1,268 +1,292 @@
 <?php
 /**
 * @version	$Id$
 * @package	In-Portal
 * @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
 * the GNU General Public License, and as distributed it includes
 * or is derivative of works licensed under the GNU General Public License
 * or other free or open source software licenses.
 * See http://www.in-portal.org/license for copyright notices and details.
 */
 
 	defined('FULL_PATH') or die('restricted access!');
 
 	class FormSubmissionsEventHandler extends kDBEventHandler {
 
 		function CheckPermission(&$event)
 		{
 			if (!$this->Application->isAdmin) {
 				if ($event->Name == 'OnCreate') {
 					// anybody can submit forms on front
 					return true;
 				}
 			}
 
 			$section = $event->getSection();
 			$form_id = $this->Application->GetVar('form_id');
 
 			$event->setEventParam('PermSection', $section . ':' . $form_id);
 
 			return parent::CheckPermission($event);
 		}
 
 		/**
 		 * Always allow to view feedback form
 		 *
 		 */
 		function mapPermissions()
 		{
 			parent::mapPermissions();
 
 			$permissions = Array(
 				'OnItemBuild' => Array ('self' => true),
 				'OnEdit' => Array ('self' => 'view', 'subitem' => 'view'),
 			);
 
 			$this->permMapping = array_merge($this->permMapping, $permissions);
 		}
 
 		/**
 		 * Returns filter block based on field element type
 		 *
 		 * @param string $element_type
 		 * @return string
 		 */
 		function _getFilterBlock($element_type)
 		{
 			$mapping = Array (
 				'text' => 'grid_like_filter',
 				'select' => 'grid_options_filter',
 				'radio' => 'grid_options_filter',
 				'checkbox' => 'grid_options_filter',
 				'password' => 'grid_like_filter',
 				'textarea' => 'grid_like_filter',
 				'label' => 'grid_like_filter',
 			);
 
 			return $mapping[$element_type];
 		}
 
 		function OnBuildFormFields(&$event)
 		{
 			$form_id = $this->Application->GetVar('form_id');
 			if (!$form_id) return ;
 
 			$conf_fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
 			$conf_grids = $this->Application->getUnitOption($event->Prefix, 'Grids');
 
 			$helper =& $this->Application->recallObject('InpCustomFieldsHelper');
 			/* @var $helper InpCustomFieldsHelper */
 
 			$sql = 'SELECT *
 					FROM ' . TABLE_PREFIX . 'FormFields
 					WHERE FormId = ' . (int)$form_id . '
 					ORDER BY Priority DESC';
 			$fields = $this->Conn->Query($sql, 'FormFieldId');
 
 			$use_options = Array ('radio', 'select', 'checkbox');
 			$check_visibility = $this->Application->LoggedIn() && !$this->Application->isAdminUser;
 
 			foreach ($fields as $field_id => $options) {
 				$field_visible = $check_visibility ? $options['Visibility'] == FORM_FIELD_EVERYONE : true;
 				$field_options = Array('type' => 'string', 'default' => $options['DefaultValue']);
 
 				if ($options['Required'] && $field_visible) {
 					$field_options['required'] = 1;
 				}
 
 				if ($options['Validation'] == 1) {
 					$field_options['formatter'] = 'kFormatter';
 					$field_options['regexp'] = '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i';
 				}
 
 				if ($options['DisplayInGrid']) {
 					$title = $options['Prompt'];
 
 					if (substr($title, 0, 1) == '+') {
 						$this->Application->Phrases->AddCachedPhrase('form_col_title' . $field_id, substr($title, 1));
 						$title = 'form_col_title' . $field_id;
 					}
 
 					$conf_grids['Default']['Fields']['fld_' . $field_id] = Array (
 						'title' => $title, 'no_special' => 1, 'nl2br' => 1, 'first_chars' => 200,
 						'filter_block' => $this->_getFilterBlock($options['ElementType'])
 					);
 
 					if ($options['Validation'] == 1) {
 						$conf_grids['Default']['Fields']['fld_' . $field_id]['data_block'] = 'grid_email_td';
 					}
 				}
 
 				if ($options['ElementType'] == 'checkbox' && !$options['ValueList']) {
 					// fix case, when user haven't defined any options for checkbox
 					$options['ValueList'] = '1=la_Yes||0=la_No';
 				}
 
 				if (in_array($options['ElementType'], $use_options) && $options['ValueList']) {
 					// field type can have options and user have defined them too
 					$field_options['options'] = $helper->GetValuesHash( $options['ValueList'] );
 					$field_options['formatter'] = 'kOptionsFormatter';
 				}
 
 				if ($options['ElementType'] == 'password') {
 					$field_options['formatter'] = 'kPasswordFormatter';
 					$field_options['encryption_method'] = 'plain';
 					$field_options['verify_field'] = 'fld_' . $field_id . '_verify';
 				}
 
 				$conf_fields['fld_' . $field_id] = $field_options;
 			}
 
 			$this->Application->setUnitOption($event->Prefix, 'Fields', $conf_fields);
 			$this->Application->setUnitOption($event->Prefix, 'Grids', $conf_grids);
 		}
 
 		function SetCustomQuery(&$event)
 		{
 			$object =& $event->getObject();
 			$form_id = $this->Application->GetVar('form_id');
 			$object->addFilter('form_filter','%1$s.FormId = '.$form_id);
 		}
 
 		/**
 		 * Allows user to see it's last feedback form data
 		 *
 		 * @param kEvent $event
 		 * @return int
 		 */
 		function getPassedID(&$event)
 		{
 			if ($event->Special == 'last') {
 				// allow user to see his last submitted form
 				return $this->Application->RecallVar('last_submission_id');
 			}
 
 			if ($this->Application->isAdminUser) {
 				// don't check ids in admin
 				return parent::getPassedID($event);
 			}
 
 			// no way to see other user's form submission by giving it's ID directly in url
 			return 0;
 		}
 
 		/**
 		 * Creates new form submission from Front-End
 		 *
 		 * @param kEvent $event
 		 */
 		function OnCreate(&$event)
 		{
 			parent::OnCreate($event);
 
 			if ($event->status != erSUCCESS) {
 				return ;
 			}
 
 			$object =& $event->getObject();
 			/* @var $object kDBItem */
 
 			// allows user to view only it's last submission
 			$this->Application->StoreVar('last_submission_id', $object->GetID());
 
 			$this->Application->EmailEventAdmin('FORM.SUBMITTED');
 //			$this->Application->EmailEventUser('FORM.SUBMITTED', null, 'to_email' => '');
 
 			$event->SetRedirectParam('opener', 's');
 			$event->SetRedirectParam('m_cat_id', 0);
 
 			$theme =& $this->Application->recallObject('theme.current');
 			/* @var $theme kDBItem */
 
 			$template = $this->Application->GetVar('success_template');
 			$alias_template = $theme->GetField('TemplateAliases', $template);
 
 			$event->redirect = $alias_template ? $alias_template : $template;
 		}
 
 		/**
 		 * Processes Captcha code
 		 *
 		 * @param kEvent $event
 		 */
 		function OnBeforeItemCreate(&$event)
 		{
 			parent::OnBeforeItemCreate($event);
 
 			$object =& $event->getObject();
 			/* @var $object kDBItem */
 
 			$object->SetDBField('IPAddress', $_SERVER['REMOTE_ADDR']);
 			$object->SetDBField('ReferrerURL', $_SERVER['HTTP_REFERER']);
 
 			$form_submission_helper =& $this->Application->recallObject('FormSubmissionHelper');
 			/* @var $form_submission_helper FormSubmissionHelper */
 
 			$form =& $form_submission_helper->getForm($object);
 
 			// validate captcha code
 			if ($form->GetDBField('UseSecurityImage') && !$this->Application->LoggedIn()) {
 				$captcha_helper =& $this->Application->recallObject('CaptchaHelper');
 				/* @var $captcha_helper kCaptchaHelper */
 
 				$captcha_helper->validateCode($event, false);
 			}
 		}
 
 		/**
 		 * Passes form_id, when using "Prev"/"Next" toolbar buttons
 		 *
 		 * @param kEvent $event
 		 */
 		function OnPreSaveAndGo(&$event)
 		{
 			parent::OnPreSaveAndGo($event);
 
 			if ($event->status == erSUCCESS) {
 				$event->SetRedirectParam('pass', 'm,form,formsubs');
 			}
 		}
 
 		/**
 		 * Saves edited item in temp table and goes
 		 * to passed tabs, by redirecting to it with OnPreSave event
 		 *
 		 * @param kEvent $event
 		 */
 		function OnPreSaveAndGoToTab(&$event)
 		{
 			parent::OnPreSaveAndGoToTab($event);
 
 			if ($event->status == erSUCCESS) {
 				$event->SetRedirectParam('pass', 'm,form,formsubs');
 			}
 		}
+
+		/**
+		 * Set's new perpage for grid
+		 *
+		 * @param kEvent $event
+		 */
+		function OnSetPerPage(&$event)
+		{
+			parent::OnSetPerPage($event);
+
+			$event->SetRedirectParam('pass', 'm,form,' . $event->getPrefixSpecial());
+		}
+
+		/**
+		 * Occurs when page is changed (only for hooking)
+		 *
+		 * @param kEvent $event
+		 */
+		function OnSetPage(&$event)
+		{
+			parent::OnSetPage($event);
+
+			$event->SetRedirectParam('pass', 'm,form,' . $event->getPrefixSpecial());
+		}
 	}
\ No newline at end of file
Index: branches/5.1.x/core/units/forms/form_submissions/form_submissions_config.php
===================================================================
--- branches/5.1.x/core/units/forms/form_submissions/form_submissions_config.php	(revision 13822)
+++ branches/5.1.x/core/units/forms/form_submissions/form_submissions_config.php	(revision 13823)
@@ -1,154 +1,154 @@
 <?php
 /**
 * @version	$Id$
 * @package	In-Portal
 * @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
 * the GNU General Public License, and as distributed it includes
 * or is derivative of works licensed under the GNU General Public License
 * or other free or open source software licenses.
 * See http://www.in-portal.org/license for copyright notices and details.
 */
 
 	defined('FULL_PATH') or die('restricted access!');
 
 	$config =	Array(
 					'Prefix'			=>	'formsubs',
 					'ItemClass'			=>	Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
 					'ListClass'			=>	Array('class'=>'kDBList','file'=>'','build_event'=>'OnListBuild'),
 					'EventHandlerClass'	=>	Array('class'=>'FormSubmissionsEventHandler','file'=>'form_submissions_eh.php','build_event'=>'OnBuild'),
 					'TagProcessorClass' =>	Array('class'=>'FormSubmissionTagProcessor', 'file' => 'form_submission_tp.php', 'build_event'=>'OnBuild'),
 					'AutoLoad'			=>	true,
 					'QueryString'		=>	Array(
 												1 => 'id',
 												2 => 'Page',
 												3 => 'PerPage',
 												4 => 'event',
 											),
 
 					'Hooks'				=>	Array(
 											Array(
 												'Mode' => hAFTER,
 												'Conditional' => false,
 												'HookToPrefix' => '',
 												'HookToSpecial' => '*',
 												'HookToEvent' => Array('OnAfterConfigRead'),
 												'DoPrefix' => '',
 												'DoSpecial' => '',
 												'DoEvent' => 'OnBuildFormFields',
 											),
 
 											// Captcha processing
 											Array (
 												'Mode' => hAFTER,
 												'Conditional' => false,
 												'HookToPrefix' => '',
 												'HookToSpecial' => '*',
 												'HookToEvent' => Array('OnAfterConfigRead'),
 												'DoPrefix' => 'captcha',
 												'DoSpecial' => '*',
 												'DoEvent' => 'OnPrepareCaptcha',
 											),
 										),
 
 					'TitlePresets' => Array(
 						'default' => Array(
 							'new_status_labels'		=> Array('form'=>'!la_title_Adding_Form!'),
 							'edit_status_labels'	=> Array('form'=>'!la_title_Editing_Form!'),
 						),
 
 						'formsubs_list' => Array (
 							'prefixes' =>	Array('form', 'formsubs_List'),
 							'format' =>	"!la_title_FormSubmissions! '#form_titlefield#'",
-							'toolbar_buttons' => Array ('edit', 'delete', 'dbl-click'),
+							'toolbar_buttons' => Array ('edit', 'delete', 'view', 'dbl-click'),
 						),
 
 						'formsubs_view' => Array(
 							'prefixes' => Array('formsubs'),
 							'format' => "!la_title_ViewingFormSubmission!",
 							'toolbar_buttons' => Array ('select', 'cancel', 'prev', 'next'),
 						),
 
 						'submission_edit_logs' => Array (
 							'prefixes' => Array ('formsubs', 'submission-log_List'),
 							'format' => "!la_title_ViewingFormSubmission! - !la_title_Messages! (#submission-log_recordcount#)"
 						),
 
 						'submission_log_edit' => Array (
 							'new_status_labels' => Array ('submission-log' => '!la_title_NewReply!'),
 							'edit_status_labels' => Array ('submission-log' => '!la_title_ViewingReply!'),
 
 							'prefixes' => Array ('submission-log'), 'format' => "!la_title_ViewingFormSubmission! - #submission-log_status#"
 						),
 					),
 
 					'EditTabPresets' => Array (
 						'Default' => Array (
 							Array ('title' => 'la_tab_General', 't' => 'submissions/submission_view', 'priority' => 1),
 							Array ('title' => 'la_tab_Messages', 't' => 'submissions/submission_edit_logs', 'priority' => 2),
 						),
 					),
 
 					'PermSection'		=>	Array('main' => 'in-portal:submissions'),
 
 					'IDField'			=>	'FormSubmissionId',
 					/*'TitleField'		=>	'Name',*/
 					'StatusField' => Array ('LogStatus'),
 					'TableName'			=>	TABLE_PREFIX.'FormSubmissions',
 					'ListSQLs'	=>	Array(
 							''=>'	SELECT %1$s.* %2$s FROM %1$s',
 						), // key - special, value - list select sql
 					'ItemSQLs'	=>	Array(
 								''=>'SELECT %1$s.* %2$s FROM %1$s',
 						),
 
 					/*'ForeignKey'	=>	'FormId',
 					'ParentTableKey' => 'FormId',
 					'ParentPrefix' => 'form',
 					'AutoDelete'	=>	true,
 					'AutoClone'	=> true,*/
 
 					'SubItems' => Array ('submission-log', 'draft'),
 
 					'ListSortings'	=> 	Array(
 						'' => Array(
 							'Sorting' => Array('SubmissionTime' => 'desc'),
 						)
 					),
 
 					'Fields' => Array(
 						'FormSubmissionId' => Array('type' => 'int', 'not_null' => 1,'default' => 0),
 						'FormId' => Array('type' => 'int','not_null' => '1','default' => 0),
 						'SubmissionTime' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'),
 						'IPAddress' => Array ('type' => 'string', 'max_len' => 15, 'not_null' => 1, 'default' => ''),
 						'ReferrerURL' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
 
 						'LogStatus' => Array (
 							'type' => 'int',
 							'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_opt_Replied', 2 => 'la_opt_NotReplied', 3 => 'la_opt_NewEmail', 4 => 'la_opt_Bounce'), 'use_phrases' => 1,
 							'not_null' => 1, 'required' => 1, 'default' => 2
 						),
 
 		    			'LastUpdatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL),
 		    			'Notes' => Array ('type' => 'string', 'default' => NULL),
 					),
 					'VirtualFields'	=>	Array(
 					),
 					'CalculatedFields'	=>	Array(
 					),
 					'Grids'	=> Array(
 						'Default'		=>	Array(
 							'Icons' => Array('default' => 'icon16_item.png', 1 => 'icon16_replied.gif', 2 => 'icon16_not_replied.gif', 3 => 'icon16_new_email.gif', 4 => 'icon16_bounce.gif'),
 							'Fields' => Array(
 								'FormSubmissionId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'sort_field' => 'FormFieldId', 'filter_block' => 'grid_range_filter', 'width' => 60 ),
 								'SubmissionTime' => Array( 'title'=>'la_prompt_SumbissionTime', 'filter_block' => 'grid_date_range_filter', 'width' => 145 ),
 								'IPAddress' => Array ('title' => 'la_col_IPAddress', 'filter_block' => 'grid_like_filter', 'width' => 100 ),
       							'ReferrerURL' => Array ('title' => 'la_col_ReferrerURL', 'filter_block' => 'grid_like_filter', 'first_chars' => 100, 'width' => 200 ),
       							'LogStatus' => Array ('title' => 'la_col_Status', 'filter_block' => 'grid_options_filter', 'width' => 100 ),
 								'LastUpdatedOn' => Array ('title' => 'la_col_LastUpdatedOn', 'filter_block' => 'grid_date_range_filter', 'width' => 145 ),
 							),
 						),
 					),
 	);
\ No newline at end of file
Index: branches/5.1.x/core/admin_templates/submissions/submissions_list.tpl
===================================================================
--- branches/5.1.x/core/admin_templates/submissions/submissions_list.tpl	(revision 13822)
+++ branches/5.1.x/core/admin_templates/submissions/submissions_list.tpl	(revision 13823)
@@ -1,49 +1,61 @@
 <inp2:m_include t="incs/header" />
 
 <inp2:m_Get var="form_id" result_to_var="form_id"/>
 <inp2:m_RenderElement name="combined_header" prefix="formsubs" section="in-portal:submissions:$form_id" pagination="1" title_preset="formsubs_list" />
 
 <!-- ToolBar -->
 <table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%">
 <tbody>
 	<tr>
   	<td>
   		<script type="text/javascript">
   			//do not rename - this function is used in default grid for double click!
   			function edit()
   			{
   				// don't use temp tables, since we can receive user replies while reviewing form submission
   				std_edit_temp_item('formsubs', 'submissions/submission_view');
   			}
 
   			var a_toolbar = new ToolBar();
 
 				a_toolbar.AddButton( new ToolBarButton('edit', '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>', edit) );
 
 				a_toolbar.AddButton( new ToolBarSeparator('sep3') );
 
 				a_toolbar.AddButton( new ToolBarButton('delete', '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
 						function() {
 							std_delete_items('formsubs')
 						} ) );
 
+				a_toolbar.AddButton( new ToolBarSeparator('sep2') );
+
+				a_toolbar.AddButton(
+					new ToolBarButton(
+						'view',
+						'<inp2:m_phrase label="la_ToolTip_View" escape="1"/>',
+						function(id) {
+							show_viewmenu(a_toolbar,'view');
+						}
+					)
+				);
+
 				a_toolbar.Render();
 			</script>
 		</td>
 
 		<inp2:m_RenderElement name="search_main_toolbar" prefix="formsubs" grid="Default"/>
 	</tr>
 </tbody>
 </table>
 
 
 <inp2:m_DefineElement name="grid_email_td">
 	<a href="mailto:<inp2:Field field="$field" />"><inp2:Field field="$field"/></a>
 </inp2:m_DefineElement>
 
 <inp2:m_RenderElement name="grid" PrefixSpecial="formsubs" IdField="FormSubmissionId" grid="Default"/>
 <script type="text/javascript">
 	Grids['formsubs'].SetDependantToolbarButtons( new Array('edit','delete') );
 </script>
 
 <inp2:m_include t="incs/footer"/>
\ No newline at end of file