Browse Source

Merge pull request #46 from emanuele45/master

couple of issues
Norv 13 years ago
parent
commit
d454abc2b3
41 changed files with 645 additions and 244 deletions
  1. 1 1
      Sources/Admin.php
  2. 33 0
      Sources/Display.php
  3. 3 3
      Sources/Load.php
  4. 1 1
      Sources/ManageBoards.php
  5. 84 58
      Sources/ManageMembergroups.php
  6. 15 15
      Sources/ManagePermissions.php
  7. 1 0
      Sources/ManagePosts.php
  8. 1 0
      Sources/ManageServer.php
  9. 1 1
      Sources/ManageSmileys.php
  10. 6 6
      Sources/MessageIndex.php
  11. 172 2
      Sources/Printpage.php
  12. 4 0
      Sources/Profile-View.php
  13. 1 1
      Sources/Subs.php
  14. 5 3
      Sources/Themes.php
  15. 57 15
      Themes/default/Display.template.php
  16. 12 2
      Themes/default/ManageBoards.template.php
  17. 95 67
      Themes/default/ManageMembergroups.template.php
  18. 29 8
      Themes/default/Printpage.template.php
  19. 1 0
      Themes/default/Profile.template.php
  20. 2 1
      Themes/default/Settings.template.php
  21. 3 3
      Themes/default/Themes.template.php
  22. 3 0
      Themes/default/css/admin.css
  23. 1 2
      Themes/default/css/index.css
  24. 1 1
      Themes/default/index.template.php
  25. 6 0
      Themes/default/languages/Admin.english.php
  26. 1 0
      Themes/default/languages/Errors.english.php
  27. 11 11
      Themes/default/languages/Help.english.php
  28. 2 1
      Themes/default/languages/ManageSettings.english.php
  29. 1 0
      Themes/default/languages/Profile.english.php
  30. 0 2
      Themes/default/languages/Reports.english.php
  31. 8 0
      Themes/default/scripts/admin.js
  32. 1 1
      Themes/default/scripts/script.js
  33. 6 2
      Themes/default/scripts/topic.js
  34. 60 26
      Themes/penguin/Display.template.php
  35. 1 0
      Themes/penguin/Profile.template.php
  36. 1 0
      Themes/penguin/Settings.template.php
  37. 3 0
      Themes/penguin/css/admin.css
  38. 1 2
      Themes/penguin/css/index.css
  39. 8 0
      Themes/penguin/scripts/admin.js
  40. 2 8
      other/install.php
  41. 1 1
      other/install_2-1_mysql.sql

+ 1 - 1
Sources/Admin.php

@@ -167,7 +167,7 @@ function AdminMain()
 					'label' => $txt['theme_current_settings'],
 					'label' => $txt['theme_current_settings'],
 					'file' => 'Themes.php',
 					'file' => 'Themes.php',
 					'function' => 'ThemesMain',
 					'function' => 'ThemesMain',
-					'custom_url' => $scripturl . '?action=admin;area=theme;sa=settings;th=' . $settings['theme_id'],
+					'custom_url' => $scripturl . '?action=admin;area=theme;sa=list;th=' . $settings['theme_id'],
 					'icon' => 'current_theme.png',
 					'icon' => 'current_theme.png',
 				),
 				),
 				'theme' => array(
 				'theme' => array(

+ 33 - 0
Sources/Display.php

@@ -1042,6 +1042,7 @@ function Display()
 	$context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
 	$context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
 
 
 	$context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
 	$context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
+	$context['can_print'] = empty($modSettings['disable_print_topic']);
 
 
 	// Start this off for quick moderation - it will be or'd for each post.
 	// Start this off for quick moderation - it will be or'd for each post.
 	$context['can_remove_post'] = allowedTo('delete_any') || (allowedTo('delete_replies') && $context['user']['started']);
 	$context['can_remove_post'] = allowedTo('delete_any') || (allowedTo('delete_replies') && $context['user']['started']);
@@ -1063,6 +1064,38 @@ function Display()
 		checkSubmitOnce('register');
 		checkSubmitOnce('register');
 		$context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
 		$context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
 		$context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
 		$context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
+		if ($options['display_quick_reply'] == 3 && $context['can_reply'])
+		{
+			// Needed for the editor and message icons.
+			require_once($sourcedir . '/Subs-Editor.php');
+
+			// Now create the editor.
+			$editorOptions = array(
+				'id' => 'message',
+				'value' => '',
+				'labels' => array(
+					'post_button' => $txt['post'],
+				),
+				// add height and width for the editor
+				'height' => '175px',
+				'width' => '100%',
+				// We do XML preview here.
+				'preview_type' => 0,
+			);
+			create_control_richedit($editorOptions);
+
+			// Store the ID.
+			$context['post_box_name'] = $editorOptions['id'];
+
+			$context['attached'] = '';
+			$context['make_poll'] = isset($_REQUEST['poll']);
+
+			// Message icons - customized icons are off?
+			$context['icons'] = getMessageIcons($board);
+
+			if (!empty($context['icons']))
+				$context['icons'][count($context['icons']) - 1]['is_last'] = true;
+		}
 	}
 	}
 }
 }
 
 

+ 3 - 3
Sources/Load.php

@@ -678,7 +678,7 @@ function loadBoard()
 
 
 		if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin'])
 		if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin'])
 			$board_info['error'] = 'access';
 			$board_info['error'] = 'access';
-		if (count(array_intersect($user_info['groups'], $board_info['deny_groups'])) != 0 && !$user_info['is_admin'])
+		if (!empty($modSettings['deny_boards_access']) && count(array_intersect($user_info['groups'], $board_info['deny_groups'])) != 0 && !$user_info['is_admin'])
 			$board_info['error'] = 'access';
 			$board_info['error'] = 'access';
 
 
 		// Build up the linktree.
 		// Build up the linktree.
@@ -702,7 +702,7 @@ function loadBoard()
 	$context['current_board'] = $board;
 	$context['current_board'] = $board;
 
 
 	// Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
 	// Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
-	if (!empty($board_info['error']) && ($board_info['error'] != 'access' || !$user_info['is_mod']))
+	if (!empty($board_info['error']) && (!empty($modSettings['deny_boards_access']) || $board_info['error'] != 'access' || !$user_info['is_mod']))
 	{
 	{
 		// The permissions and theme need loading, just to make sure everything goes smoothly.
 		// The permissions and theme need loading, just to make sure everything goes smoothly.
 		loadPermissions();
 		loadPermissions();
@@ -1813,7 +1813,7 @@ function loadTemplate($template_name, $style_sheets = array(), $fatal = true)
 			loadLanguage('Errors');
 			loadLanguage('Errors');
 			echo '
 			echo '
 <div class="alert errorbox">
 <div class="alert errorbox">
-	<a href="', $scripturl . '?action=admin;area=theme;sa=settings;th=1;' . $context['session_var'] . '=' . $context['session_id'], '" class="alert">', $txt['theme_dir_wrong'], '</a>
+	<a href="', $scripturl . '?action=admin;area=theme;sa=list;th=1;' . $context['session_var'] . '=' . $context['session_id'], '" class="alert">', $txt['theme_dir_wrong'], '</a>
 </div>';
 </div>';
 		}
 		}
 
 

+ 1 - 1
Sources/ManageBoards.php

@@ -402,7 +402,7 @@ function EditBoard()
 		// Some things that need to be setup for a new board.
 		// Some things that need to be setup for a new board.
 		$curBoard = array(
 		$curBoard = array(
 			'member_groups' => array(0, -1),
 			'member_groups' => array(0, -1),
-			'deny_group' => array(),
+			'deny_groups' => array(),
 			'category' => (int) $_REQUEST['cat']
 			'category' => (int) $_REQUEST['cat']
 		);
 		);
 		$context['board_order'] = array();
 		$context['board_order'] = array();

+ 84 - 58
Sources/ManageMembergroups.php

@@ -499,23 +499,30 @@ function AddMembergroup()
 		}
 		}
 
 
 		// Make sure all boards selected are stored in a proper array.
 		// Make sure all boards selected are stored in a proper array.
-		$_POST['boardaccess'] = empty($_POST['boardaccess']) || !is_array($_POST['boardaccess']) ? array() : $_POST['boardaccess'];
+		$accesses = empty($_POST['boardaccess']) || !is_array($_POST['boardaccess']) ? array() : $_POST['boardaccess'];
-		foreach ($_POST['boardaccess'] as $key => $value)
+		$changed_boards['allow'] = array();
-			$_POST['boardaccess'][$key] = (int) $value;
+		$changed_boards['deny'] = array();
-
+		$changed_boards['ignore'] = array();
-		// Only do this if they have special access requirements.
+		foreach ($accesses as $group_id => $action)
-		if (!empty($_POST['boardaccess']))
+			$changed_boards[$action][] = (int) $group_id;
-			$smcFunc['db_query']('', '
+
-				UPDATE {db_prefix}boards
+		foreach (array('allow', 'deny') as $board_action)
-				SET member_groups = CASE WHEN member_groups = {string:blank_string} THEN {string:group_id_string} ELSE CONCAT(member_groups, {string:comma_group}) END
+		{
-				WHERE id_board IN ({array_int:board_list})',
+			// Only do this if they have special access requirements.
-				array(
+			if (!empty($changed_boards[$board_action]))
-					'board_list' => $_POST['boardaccess'],
+				$smcFunc['db_query']('', '
-					'blank_string' => '',
+					UPDATE {db_prefix}boards
-					'group_id_string' => (string) $id_group,
+					SET {raw:column} = CASE WHEN {raw:column} = {string:blank_string} THEN {string:group_id_string} ELSE CONCAT({raw:column}, {string:comma_group}) END
-					'comma_group' => ',' . $id_group,
+					WHERE id_board IN ({array_int:board_list})',
-				)
+					array(
-			);
+						'board_list' => $changed_boards[$board_action],
+						'blank_string' => '',
+						'group_id_string' => (string) $id_group,
+						'comma_group' => ',' . $id_group,
+						'column' => $board_action == 'allow' ? 'member_groups' : 'deny_member_groups',
+					)
+				);
+		}
 
 
 		// If this is joinable then set it to show group membership in people's profiles.
 		// If this is joinable then set it to show group membership in people's profiles.
 		if (empty($modSettings['show_group_membership']) && $_POST['group_type'] > 1)
 		if (empty($modSettings['show_group_membership']) && $_POST['group_type'] > 1)
@@ -540,6 +547,9 @@ function AddMembergroup()
 	$context['undefined_group'] = !isset($_REQUEST['postgroup']) && !isset($_REQUEST['generalgroup']);
 	$context['undefined_group'] = !isset($_REQUEST['postgroup']) && !isset($_REQUEST['generalgroup']);
 	$context['allow_protected'] = allowedTo('admin_forum');
 	$context['allow_protected'] = allowedTo('admin_forum');
 
 
+	if (!empty($modSettings['deny_boards_access']))
+		loadLanguage('ManagePermissions');
+
 	$result = $smcFunc['db_query']('', '
 	$result = $smcFunc['db_query']('', '
 		SELECT id_group, group_name
 		SELECT id_group, group_name
 		FROM {db_prefix}membergroups
 		FROM {db_prefix}membergroups
@@ -588,7 +598,8 @@ function AddMembergroup()
 			'id' => $row['id_board'],
 			'id' => $row['id_board'],
 			'name' => $row['name'],
 			'name' => $row['name'],
 			'child_level' => $row['child_level'],
 			'child_level' => $row['child_level'],
-			'selected' => false
+			'allow' => false,
+			'deny' => false
 		);
 		);
 
 
 	}
 	}
@@ -648,6 +659,10 @@ function EditMembergroup()
 
 
 	$_REQUEST['group'] = isset($_REQUEST['group']) && $_REQUEST['group'] > 0 ? (int) $_REQUEST['group'] : 0;
 	$_REQUEST['group'] = isset($_REQUEST['group']) && $_REQUEST['group'] > 0 ? (int) $_REQUEST['group'] : 0;
 
 
+	if (!empty($modSettings['deny_boards_access']))
+		loadLanguage('ManagePermissions');
+
+
 	// Make sure this group is editable.
 	// Make sure this group is editable.
 	if (!empty($_REQUEST['group']))
 	if (!empty($_REQUEST['group']))
 	{
 	{
@@ -744,48 +759,57 @@ function EditMembergroup()
 		// Time to update the boards this membergroup has access to.
 		// Time to update the boards this membergroup has access to.
 		if ($_REQUEST['group'] == 2 || $_REQUEST['group'] > 3)
 		if ($_REQUEST['group'] == 2 || $_REQUEST['group'] > 3)
 		{
 		{
-			$_POST['boardaccess'] = empty($_POST['boardaccess']) || !is_array($_POST['boardaccess']) ? array() : $_POST['boardaccess'];
+			$accesses = empty($_POST['boardaccess']) || !is_array($_POST['boardaccess']) ? array() : $_POST['boardaccess'];
-			foreach ($_POST['boardaccess'] as $key => $value)
+			$changed_boards['allow'] = array();
-				$_POST['boardaccess'][$key] = (int) $value;
+			$changed_boards['deny'] = array();
-
+			$changed_boards['ignore'] = array();
-			// Find all board this group is in, but shouldn't be in.
+			foreach ($accesses as $group_id => $action)
-			$request = $smcFunc['db_query']('', '
+				$changed_boards[$action][] = (int) $group_id;
-				SELECT id_board, member_groups
+
-				FROM {db_prefix}boards
+			foreach (array('allow', 'deny') as $board_action)
-				WHERE FIND_IN_SET({string:current_group}, member_groups) != 0' . (empty($_POST['boardaccess']) ? '' : '
+			{
-					AND id_board NOT IN ({array_int:board_access_list})'),
+				// Find all board this group is in, but shouldn't be in.
-				array(
+				$request = $smcFunc['db_query']('', '
-					'current_group' => (int) $_REQUEST['group'],
+					SELECT id_board, {raw:column}
-					'board_access_list' => $_POST['boardaccess'],
+					FROM {db_prefix}boards
-				)
+					WHERE FIND_IN_SET({string:current_group}, {raw:column}) != 0' . (empty($changed_boards[$board_action]) ? '' : '
-			);
+						AND id_board NOT IN ({array_int:board_access_list})'),
-			while ($row = $smcFunc['db_fetch_assoc']($request))
-				$smcFunc['db_query']('', '
-					UPDATE {db_prefix}boards
-					SET member_groups = {string:member_group_access}
-					WHERE id_board = {int:current_board}',
-					array(
-						'current_board' => $row['id_board'],
-						'member_group_access' => implode(',', array_diff(explode(',', $row['member_groups']), array($_REQUEST['group']))),
-					)
-				);
-			$smcFunc['db_free_result']($request);
-
-			// Add the membergroup to all boards that hadn't been set yet.
-			if (!empty($_POST['boardaccess']))
-				$smcFunc['db_query']('', '
-					UPDATE {db_prefix}boards
-					SET member_groups = CASE WHEN member_groups = {string:blank_string} THEN {string:group_id_string} ELSE CONCAT(member_groups, {string:comma_group}) END
-					WHERE id_board IN ({array_int:board_list})
-						AND FIND_IN_SET({int:current_group}, member_groups) = 0',
 					array(
 					array(
-						'board_list' => $_POST['boardaccess'],
-						'blank_string' => '',
 						'current_group' => (int) $_REQUEST['group'],
 						'current_group' => (int) $_REQUEST['group'],
-						'group_id_string' => (string) (int) $_REQUEST['group'],
+						'board_access_list' => $changed_boards[$board_action],
-						'comma_group' => ',' . $_REQUEST['group'],
+						'column' => $board_action == 'allow' ? 'member_groups' : 'deny_member_groups',
 					)
 					)
 				);
 				);
+				while ($row = $smcFunc['db_fetch_assoc']($request))
+					$smcFunc['db_query']('', '
+						UPDATE {db_prefix}boards
+						SET {raw:column} = {string:member_group_access}
+						WHERE id_board = {int:current_board}',
+						array(
+							'current_board' => $row['id_board'],
+							'member_group_access' => implode(',', array_diff(explode(',', $row['member_groups']), array($_REQUEST['group']))),
+							'column' => $board_action == 'allow' ? 'member_groups' : 'deny_member_groups',
+						)
+					);
+				$smcFunc['db_free_result']($request);
+
+				// Add the membergroup to all boards that hadn't been set yet.
+				if (!empty($changed_boards[$board_action]))
+					$smcFunc['db_query']('', '
+						UPDATE {db_prefix}boards
+						SET {raw:column} = CASE WHEN {raw:column} = {string:blank_string} THEN {string:group_id_string} ELSE CONCAT({raw:column}, {string:comma_group}) END
+						WHERE id_board IN ({array_int:board_list})
+							AND FIND_IN_SET({int:current_group}, {raw:column}) = 0',
+						array(
+							'board_list' => $changed_boards[$board_action],
+							'blank_string' => '',
+							'current_group' => (int) $_REQUEST['group'],
+							'group_id_string' => (string) (int) $_REQUEST['group'],
+							'comma_group' => ',' . $_REQUEST['group'],
+							'column' => $board_action == 'allow' ? 'member_groups' : 'deny_member_groups',
+						)
+					);
+			}
 		}
 		}
 
 
 		// Remove everyone from this group!
 		// Remove everyone from this group!
@@ -1032,7 +1056,8 @@ function EditMembergroup()
 	if ($_REQUEST['group'] == 2 || $_REQUEST['group'] > 3)
 	if ($_REQUEST['group'] == 2 || $_REQUEST['group'] > 3)
 	{
 	{
 		$request = $smcFunc['db_query']('', '
 		$request = $smcFunc['db_query']('', '
-			SELECT b.id_cat, c.name as cat_name, b.id_board, b.name, b.child_level, FIND_IN_SET({string:current_group}, b.member_groups) != 0 AS can_access
+			SELECT b.id_cat, c.name as cat_name, b.id_board, b.name, b.child_level,
+			FIND_IN_SET({string:current_group}, b.member_groups) != 0 AS can_access, FIND_IN_SET({string:current_group}, b.deny_member_groups) != 0 AS cannot_access
 			FROM {db_prefix}boards AS b
 			FROM {db_prefix}boards AS b
 				LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
 				LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
 			ORDER BY board_order',
 			ORDER BY board_order',
@@ -1056,7 +1081,8 @@ function EditMembergroup()
 				'id' => $row['id_board'],
 				'id' => $row['id_board'],
 				'name' => $row['name'],
 				'name' => $row['name'],
 				'child_level' => $row['child_level'],
 				'child_level' => $row['child_level'],
-				'selected' => !(empty($row['can_access']) || $row['can_access'] == 'f'),
+				'allow' => !(empty($row['can_access']) || $row['can_access'] == 'f'),
+				'deny' => !(empty($row['cannot_access']) || $row['cannot_access'] == 'f'),
 			);
 			);
 		}
 		}
 		$smcFunc['db_free_result']($request);
 		$smcFunc['db_free_result']($request);

+ 15 - 15
Sources/ManagePermissions.php

@@ -1672,24 +1672,24 @@ function loadAllPermissions($loadType = 'classic')
 			}
 			}
 		}
 		}
 		ksort($context['permissions'][$permissionType]['columns']);
 		ksort($context['permissions'][$permissionType]['columns']);
-	}
 
 
-	// Check we don't leave any empty groups - and mark hidden ones as such.
+		// Check we don't leave any empty groups - and mark hidden ones as such.
-	foreach ($context['permissions'][$permissionType]['columns'] as $column => $groups)
+		foreach ($context['permissions'][$permissionType]['columns'] as $column => $groups)
-		foreach ($groups as $id => $group)
+			foreach ($groups as $id => $group)
-		{
-			if (empty($group['permissions']))
-				unset($context['permissions'][$permissionType]['columns'][$column][$id]);
-			else
 			{
 			{
-				$foundNonHidden = false;
+				if (empty($group['permissions']))
-				foreach ($group['permissions'] as $permission)
+					unset($context['permissions'][$permissionType]['columns'][$column][$id]);
-					if (empty($permission['hidden']))
+				else
-						$foundNonHidden = true;
+				{
-				if (!$foundNonHidden)
+					$foundNonHidden = false;
-					$context['permissions'][$permissionType]['columns'][$column][$id]['hidden'] = true;
+					foreach ($group['permissions'] as $permission)
+						if (empty($permission['hidden']))
+							$foundNonHidden = true;
+					if (!$foundNonHidden)
+						$context['permissions'][$permissionType]['columns'][$column][$id]['hidden'] = true;
+				}
 			}
 			}
-		}
+	}
 }
 }
 
 
 /**
 /**

+ 1 - 0
Sources/ManagePosts.php

@@ -357,6 +357,7 @@ function ModifyTopicSettings($return_config = false)
 			array('int', 'oldTopicDays', 'postinput' => $txt['manageposts_days'], 'subtext' => $txt['oldTopicDays_zero']),
 			array('int', 'oldTopicDays', 'postinput' => $txt['manageposts_days'], 'subtext' => $txt['oldTopicDays_zero']),
 			array('int', 'defaultMaxTopics', 'postinput' => $txt['manageposts_topics']),
 			array('int', 'defaultMaxTopics', 'postinput' => $txt['manageposts_topics']),
 			array('int', 'defaultMaxMessages', 'postinput' => $txt['manageposts_posts']),
 			array('int', 'defaultMaxMessages', 'postinput' => $txt['manageposts_posts']),
+			array('check', 'disable_print_topic'),
 		'',
 		'',
 			// Hot topics (etc)...
 			// Hot topics (etc)...
 			array('int', 'hotTopicPosts', 'postinput' => $txt['manageposts_posts']),
 			array('int', 'hotTopicPosts', 'postinput' => $txt['manageposts_posts']),

+ 1 - 0
Sources/ManageServer.php

@@ -465,6 +465,7 @@ function ModifyLoadBalancingSettings($return_config = false)
 		'loadavg_allunread' => '2.0',
 		'loadavg_allunread' => '2.0',
 		'loadavg_unreadreplies' => '3.5',
 		'loadavg_unreadreplies' => '3.5',
 		'loadavg_show_posts' => '2.0',
 		'loadavg_show_posts' => '2.0',
+		'loadavg_userstats' => '10.0',
 		'loadavg_bbc' => '30.0',
 		'loadavg_bbc' => '30.0',
 		'loadavg_forum' => '40.0',
 		'loadavg_forum' => '40.0',
 	);
 	);

+ 1 - 1
Sources/ManageSmileys.php

@@ -782,7 +782,7 @@ function EditSmileys()
 	$context[$context['admin_menu_name']]['current_subsection'] = 'editsmileys';
 	$context[$context['admin_menu_name']]['current_subsection'] = 'editsmileys';
 
 
 	// Submitting a form?
 	// Submitting a form?
-	if (isset($_POST['smiley_save']))
+	if (isset($_POST['smiley_save']) || isset($_POST['smiley_action']))
 	{
 	{
 		checkSession();
 		checkSession();
 
 

+ 6 - 6
Sources/MessageIndex.php

@@ -359,7 +359,7 @@ function MessageIndex()
 			SELECT
 			SELECT
 				t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board,
 				t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board,
 				' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from,
 				' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from,
-				t.id_last_msg, t.approved, t.unapproved_posts, ml.poster_time AS last_poster_time,
+				t.id_last_msg, t.approved, t.unapproved_posts, t.id_redirect_topic, ml.poster_time AS last_poster_time,
 				ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon,
 				ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon,
 				ml.poster_name AS last_member_name, ml.id_member AS last_id_member,
 				ml.poster_name AS last_member_name, ml.id_member AS last_id_member,
 				IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg,
 				IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg,
@@ -490,8 +490,8 @@ function MessageIndex()
 					'preview' => $row['first_body'],
 					'preview' => $row['first_body'],
 					'icon' => $row['first_icon'],
 					'icon' => $row['first_icon'],
 					'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.png',
 					'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.png',
-					'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0',
+					'href' => $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . '.0',
-					'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['first_subject'] . '</a>'
+					'link' => '<a href="' . $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']). '.0">' . $row['first_subject'] . '</a>'
 				),
 				),
 				'last_post' => array(
 				'last_post' => array(
 					'id' => $row['id_last_msg'],
 					'id' => $row['id_last_msg'],
@@ -508,8 +508,8 @@ function MessageIndex()
 					'preview' => $row['last_body'],
 					'preview' => $row['last_body'],
 					'icon' => $row['last_icon'],
 					'icon' => $row['last_icon'],
 					'icon_url' => $settings[$context['icon_sources'][$row['last_icon']]] . '/post/' . $row['last_icon'] . '.png',
 					'icon_url' => $settings[$context['icon_sources'][$row['last_icon']]] . '/post/' . $row['last_icon'] . '.png',
-					'href' => $scripturl . '?topic=' . $row['id_topic'] . ($user_info['is_guest'] ? ('.' . (!empty($options['view_newest_first']) ? 0 : ((int) (($row['num_replies']) / $context['pageindex_multiplier'])) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg']) : (($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new')),
+					'href' => $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . ($user_info['is_guest'] ? ('.' . (!empty($options['view_newest_first']) ? 0 : ((int) (($row['num_replies']) / $context['pageindex_multiplier'])) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg']) : (($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new')),
-					'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($user_info['is_guest'] ? ('.' . (!empty($options['view_newest_first']) ? 0 : ((int) (($row['num_replies']) / $context['pageindex_multiplier'])) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg']) : (($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new')) . '" ' . ($row['num_replies'] == 0 ? '' : 'rel="nofollow"') . '>' . $row['last_subject'] . '</a>'
+					'link' => '<a href="' . $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . ($user_info['is_guest'] ? ('.' . (!empty($options['view_newest_first']) ? 0 : ((int) (($row['num_replies']) / $context['pageindex_multiplier'])) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg']) : (($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new')) . '" ' . ($row['num_replies'] == 0 ? '' : 'rel="nofollow"') . '>' . $row['last_subject'] . '</a>'
 				),
 				),
 				'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']),
 				'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']),
 				'is_locked' => !empty($row['locked']),
 				'is_locked' => !empty($row['locked']),
@@ -523,7 +523,7 @@ function MessageIndex()
 				'new' => $row['new_from'] <= $row['id_msg_modified'],
 				'new' => $row['new_from'] <= $row['id_msg_modified'],
 				'new_from' => $row['new_from'],
 				'new_from' => $row['new_from'],
 				'newtime' => $row['new_from'],
 				'newtime' => $row['new_from'],
-				'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new',
+				'new_href' => $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . '.msg' . $row['new_from'] . '#new',
 				'pages' => $pages,
 				'pages' => $pages,
 				'replies' => comma_format($row['num_replies']),
 				'replies' => comma_format($row['num_replies']),
 				'views' => comma_format($row['num_views']),
 				'views' => comma_format($row['num_views']),

+ 172 - 2
Sources/Printpage.php

@@ -29,20 +29,28 @@ if (!defined('SMF'))
 function PrintTopic()
 function PrintTopic()
 {
 {
 	global $topic, $txt, $scripturl, $context, $user_info;
 	global $topic, $txt, $scripturl, $context, $user_info;
-	global $board_info, $smcFunc, $modSettings;
+	global $board_info, $smcFunc, $modSettings, $settings;
 
 
 	// Redirect to the boardindex if no valid topic id is provided.
 	// Redirect to the boardindex if no valid topic id is provided.
 	if (empty($topic))
 	if (empty($topic))
 		redirectexit();
 		redirectexit();
 
 
+	if (!empty($modSettings['disable_print_topic']))
+	{
+		unset($_REQUEST['action']);
+		$context['theme_loaded'] = false;
+		fatal_lang_error('feature_disabled', false);
+	}
+
 	// Whatever happens don't index this.
 	// Whatever happens don't index this.
 	$context['robot_no_index'] = true;
 	$context['robot_no_index'] = true;
 
 
 	// Get the topic starter information.
 	// Get the topic starter information.
 	$request = $smcFunc['db_query']('', '
 	$request = $smcFunc['db_query']('', '
-		SELECT m.poster_time, IFNULL(mem.real_name, m.poster_name) AS poster_name
+		SELECT mem.id_member, m.poster_time, IFNULL(mem.real_name, m.poster_name) AS poster_name, t.id_poll
 		FROM {db_prefix}messages AS m
 		FROM {db_prefix}messages AS m
 			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
 			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
+			LEFT JOIN {db_prefix}topics as t ON (t.id_first_msg = m.id_msg)
 		WHERE m.id_topic = {int:current_topic}
 		WHERE m.id_topic = {int:current_topic}
 		ORDER BY m.id_msg
 		ORDER BY m.id_msg
 		LIMIT 1',
 		LIMIT 1',
@@ -56,6 +64,168 @@ function PrintTopic()
 	$row = $smcFunc['db_fetch_assoc']($request);
 	$row = $smcFunc['db_fetch_assoc']($request);
 	$smcFunc['db_free_result']($request);
 	$smcFunc['db_free_result']($request);
 
 
+	if (!empty($row['id_poll']))
+	{
+		loadLanguage('Post');
+		// Get the question and if it's locked.
+		$request = $smcFunc['db_query']('', '
+			SELECT
+				p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.change_vote,
+				p.guest_vote, p.id_member, IFNULL(mem.real_name, p.poster_name) AS poster_name, p.num_guest_voters, p.reset_poll
+			FROM {db_prefix}polls AS p
+				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = p.id_member)
+			WHERE p.id_poll = {int:id_poll}
+			LIMIT 1',
+			array(
+				'id_poll' => $row['id_poll'],
+			)
+		);
+		$pollinfo = $smcFunc['db_fetch_assoc']($request);
+		$smcFunc['db_free_result']($request);
+
+		$request = $smcFunc['db_query']('', '
+			SELECT COUNT(DISTINCT id_member) AS total
+			FROM {db_prefix}log_polls
+			WHERE id_poll = {int:id_poll}
+				AND id_member != {int:not_guest}',
+			array(
+				'id_poll' => $row['id_poll'],
+				'not_guest' => 0,
+			)
+		);
+		list ($pollinfo['total']) = $smcFunc['db_fetch_row']($request);
+		$smcFunc['db_free_result']($request);
+
+		// Total voters needs to include guest voters
+		$pollinfo['total'] += $pollinfo['num_guest_voters'];
+
+		// Get all the options, and calculate the total votes.
+		$request = $smcFunc['db_query']('', '
+			SELECT pc.id_choice, pc.label, pc.votes, IFNULL(lp.id_choice, -1) AS voted_this
+			FROM {db_prefix}poll_choices AS pc
+				LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_choice = pc.id_choice AND lp.id_poll = {int:id_poll} AND lp.id_member = {int:current_member} AND lp.id_member != {int:not_guest})
+			WHERE pc.id_poll = {int:id_poll}',
+			array(
+				'current_member' => $user_info['id'],
+				'id_poll' => $row['id_poll'],
+				'not_guest' => 0,
+			)
+		);
+		$pollOptions = array();
+		$realtotal = 0;
+		$pollinfo['has_voted'] = false;
+		while ($row = $smcFunc['db_fetch_assoc']($request))
+		{
+			censorText($row['label']);
+			$pollOptions[$row['id_choice']] = $row;
+			$realtotal += $row['votes'];
+			$pollinfo['has_voted'] |= $row['voted_this'] != -1;
+		}
+		$smcFunc['db_free_result']($request);
+
+		// If this is a guest we need to do our best to work out if they have voted, and what they voted for.
+		if ($user_info['is_guest'] && $pollinfo['guest_vote'] && allowedTo('poll_vote'))
+		{
+			if (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $row['id_poll'] . ',') !== false)
+			{
+				// ;id,timestamp,[vote,vote...]; etc
+				$guestinfo = explode(';', $_COOKIE['guest_poll_vote']);
+				// Find the poll we're after.
+				foreach ($guestinfo as $i => $guestvoted)
+				{
+					$guestvoted = explode(',', $guestvoted);
+					if ($guestvoted[0] == $row['id_poll'])
+						break;
+				}
+				// Has the poll been reset since guest voted?
+				if ($pollinfo['reset_poll'] > $guestvoted[1])
+				{
+					// Remove the poll info from the cookie to allow guest to vote again
+					unset($guestinfo[$i]);
+					if (!empty($guestinfo))
+						$_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo);
+					else
+						unset($_COOKIE['guest_poll_vote']);
+				}
+				else
+				{
+					// What did they vote for?
+					unset($guestvoted[0], $guestvoted[1]);
+					foreach ($pollOptions as $choice => $details)
+					{
+						$pollOptions[$choice]['voted_this'] = in_array($choice, $guestvoted) ? 1 : -1;
+						$pollinfo['has_voted'] |= $pollOptions[$choice]['voted_this'] != -1;
+					}
+					unset($choice, $details, $guestvoted);
+				}
+				unset($guestinfo, $guestvoted, $i);
+			}
+		}
+
+		$context['user']['started'] = $user_info['id'] == $row['id_member'] && !$user_info['is_guest'];
+		// Set up the basic poll information.
+		$context['poll'] = array(
+			'id' => $row['id_poll'],
+			'image' => 'normal_' . (empty($pollinfo['voting_locked']) ? 'poll' : 'locked_poll'),
+			'question' => parse_bbc($pollinfo['question']),
+			'total_votes' => $pollinfo['total'],
+			'change_vote' => !empty($pollinfo['change_vote']),
+			'is_locked' => !empty($pollinfo['voting_locked']),
+			'options' => array(),
+			'lock' => allowedTo('poll_lock_any') || ($context['user']['started'] && allowedTo('poll_lock_own')),
+			'edit' => allowedTo('poll_edit_any') || ($context['user']['started'] && allowedTo('poll_edit_own')),
+			'allowed_warning' => $pollinfo['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($pollOptions), $pollinfo['max_votes'])) : '',
+			'is_expired' => !empty($pollinfo['expire_time']) && $pollinfo['expire_time'] < time(),
+			'expire_time' => !empty($pollinfo['expire_time']) ? timeformat($pollinfo['expire_time']) : 0,
+			'has_voted' => !empty($pollinfo['has_voted']),
+			'starter' => array(
+				'id' => $pollinfo['id_member'],
+				'name' => $row['poster_name'],
+				'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'],
+				'link' => $pollinfo['id_member'] == 0 ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $row['poster_name'] . '</a>'
+			)
+		);
+
+		// Make the lock and edit permissions defined above more directly accessible.
+		$context['allow_lock_poll'] = $context['poll']['lock'];
+		$context['allow_edit_poll'] = $context['poll']['edit'];
+
+		// You're allowed to view the results if:
+		// 1. you're just a super-nice-guy, or
+		// 2. anyone can see them (hide_results == 0), or
+		// 3. you can see them after you voted (hide_results == 1), or
+		// 4. you've waited long enough for the poll to expire. (whether hide_results is 1 or 2.)
+		$context['allow_poll_view'] = allowedTo('moderate_board') || $pollinfo['hide_results'] == 0 || ($pollinfo['hide_results'] == 1 && $context['poll']['has_voted']) || $context['poll']['is_expired'];
+
+		// Calculate the percentages and bar lengths...
+		$divisor = $realtotal == 0 ? 1 : $realtotal;
+
+		// Determine if a decimal point is needed in order for the options to add to 100%.
+		$precision = $realtotal == 100 ? 0 : 1;
+
+		// Now look through each option, and...
+		foreach ($pollOptions as $i => $option)
+		{
+			// First calculate the percentage, and then the width of the bar...
+			$bar = round(($option['votes'] * 100) / $divisor, $precision);
+			$barWide = $bar == 0 ? 1 : floor(($bar * 8) / 3);
+
+			// Now add it to the poll's contextual theme data.
+			$context['poll']['options'][$i] = array(
+				'id' => 'options-' . $i,
+				'percent' => $bar,
+				'votes' => $option['votes'],
+				'voted_this' => $option['voted_this'] != -1,
+				'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'right' : 'left') . '.png" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.png" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'left' : 'right') . '.png" alt="" /></span>',
+				// Note: IE < 8 requires us to set a width on the container, too.
+				'bar_ndt' => $bar > 0 ? '<div class="bar" style="width: ' . ($bar * 3.5 + 4) . 'px;"><div style="width: ' . $bar * 3.5 . 'px;"></div></div>' : '',
+				'bar_width' => $barWide,
+				'option' => parse_bbc($option['label']),
+				'vote_button' => '<input type="' . ($pollinfo['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($pollinfo['max_votes'] > 1 ? 'check' : 'radio') . '" />'
+			);
+		}
+	}
+
 	// Lets "output" all that info.
 	// Lets "output" all that info.
 	loadTemplate('Printpage');
 	loadTemplate('Printpage');
 	$context['template_layers'] = array('print');
 	$context['template_layers'] = array('print');

+ 4 - 0
Sources/Profile-View.php

@@ -625,6 +625,10 @@ function statPanel($memID)
 
 
 	$context['page_title'] = $txt['statPanel_showStats'] . ' ' . $user_profile[$memID]['real_name'];
 	$context['page_title'] = $txt['statPanel_showStats'] . ' ' . $user_profile[$memID]['real_name'];
 
 
+	// Is the load average too high to allow searching just now?
+	if (!empty($context['load_average']) && !empty($modSettings['loadavg_userstats']) && $context['load_average'] >= $modSettings['loadavg_userstats'])
+		fatal_lang_error('loadavg_userstats_disabled', false);
+
 	// General user statistics.
 	// General user statistics.
 	$timeDays = floor($user_profile[$memID]['total_time_logged_in'] / 86400);
 	$timeDays = floor($user_profile[$memID]['total_time_logged_in'] / 86400);
 	$timeHours = floor(($user_profile[$memID]['total_time_logged_in'] % 86400) / 3600);
 	$timeHours = floor(($user_profile[$memID]['total_time_logged_in'] % 86400) / 3600);

+ 1 - 1
Sources/Subs.php

@@ -2571,7 +2571,7 @@ function redirectexit($setLocation = '', $refresh = false)
 	if (!empty($modSettings['queryless_urls']) && (empty($context['server']['is_cgi']) || ini_get('cgi.fix_pathinfo') == 1 || @get_cfg_var('cgi.fix_pathinfo') == 1) && (!empty($context['server']['is_apache']) || !empty($context['server']['is_lighttpd']) || !empty($context['server']['is_litespeed'])))
 	if (!empty($modSettings['queryless_urls']) && (empty($context['server']['is_cgi']) || ini_get('cgi.fix_pathinfo') == 1 || @get_cfg_var('cgi.fix_pathinfo') == 1) && (!empty($context['server']['is_apache']) || !empty($context['server']['is_lighttpd']) || !empty($context['server']['is_litespeed'])))
 	{
 	{
 		if (defined('SID') && SID != '')
 		if (defined('SID') && SID != '')
-			$setLocation = preg_replace('/^' . preg_quote($scripturl, '/') . '\?(?:' . SID . '(?:;|&|&amp;))((?:board|topic)=[^#]+?)(#[^"]*?)?$/e', "\$scripturl . '/' . strtr('\$1', '&;=', '//,') . '.html\$2?' . SID", $setLocation);
+			$setLocation = preg_replace('/^' . preg_quote($scripturl, '/') . '\?(?:' . SID . '(?:;|&|&amp;))((?:board|topic)=[^#]+?)(#[^"]*?)?$/e', "\$scripturl . '/' . strtr('\$1', '&;=', '//,') . '.html?' . SID . '\$2'", $setLocation);
 		else
 		else
 			$setLocation = preg_replace('/^' . preg_quote($scripturl, '/') . '\?((?:board|topic)=[^#"]+?)(#[^"]*?)?$/e', "\$scripturl . '/' . strtr('\$1', '&;=', '//,') . '.html\$2'", $setLocation);
 			$setLocation = preg_replace('/^' . preg_quote($scripturl, '/') . '\?((?:board|topic)=[^#"]+?)(#[^"]*?)?$/e', "\$scripturl . '/' . strtr('\$1', '&;=', '//,') . '.html\$2'", $setLocation);
 	}
 	}

+ 5 - 3
Sources/Themes.php

@@ -61,7 +61,6 @@ function ThemesMain()
 		'admin' => 'ThemeAdmin',
 		'admin' => 'ThemeAdmin',
 		'list' => 'ThemeList',
 		'list' => 'ThemeList',
 		'reset' => 'SetThemeOptions',
 		'reset' => 'SetThemeOptions',
-		'settings' => 'SetThemeSettings',
 		'options' => 'SetThemeOptions',
 		'options' => 'SetThemeOptions',
 		'install' => 'ThemeInstall',
 		'install' => 'ThemeInstall',
 		'remove' => 'RemoveTheme',
 		'remove' => 'RemoveTheme',
@@ -198,6 +197,9 @@ function ThemeList()
 	loadLanguage('Admin');
 	loadLanguage('Admin');
 	isAllowedTo('admin_forum');
 	isAllowedTo('admin_forum');
 
 
+	if (isset($_REQUEST['th']))
+		return SetThemeSettings();
+
 	if (isset($_POST['save']))
 	if (isset($_POST['save']))
 	{
 	{
 		checkSession();
 		checkSession();
@@ -693,7 +695,7 @@ function SetThemeOptions()
  * - loads the Admin language file.
  * - loads the Admin language file.
  * - calls ThemeAdmin() if no theme is specified. (the theme center.)
  * - calls ThemeAdmin() if no theme is specified. (the theme center.)
  * - requires admin_forum permission.
  * - requires admin_forum permission.
- * - accessed with ?action=admin;area=theme;sa=settings&th=xx.
+ * - accessed with ?action=admin;area=theme;sa=list&th=xx.
  */
  */
 function SetThemeSettings()
 function SetThemeSettings()
 {
 {
@@ -803,7 +805,7 @@ function SetThemeSettings()
 		// Invalidate the cache.
 		// Invalidate the cache.
 		updateSettings(array('settings_updated' => time()));
 		updateSettings(array('settings_updated' => time()));
 
 
-		redirectexit('action=admin;area=theme;sa=settings;th=' . $_GET['th'] . ';' . $context['session_var'] . '=' . $context['session_id']);
+		redirectexit('action=admin;area=theme;sa=list;th=' . $_GET['th'] . ';' . $context['session_var'] . '=' . $context['session_id']);
 	}
 	}
 
 
 	$context['sub_template'] = 'set_settings';
 	$context['sub_template'] = 'set_settings';

+ 57 - 15
Themes/default/Display.template.php

@@ -164,7 +164,7 @@ function template_main()
 		'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']) . '\');"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
 		'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']) . '\');"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
 		'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
 		'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
 		'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0'),
 		'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0'),
-		'print' => array('text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="new_win nofollow"', 'url' => $scripturl . '?action=printpage;topic=' . $context['current_topic'] . '.0'),
+		'print' => array('test' => 'can_print', 'text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="new_win nofollow"', 'url' => $scripturl . '?action=printpage;topic=' . $context['current_topic'] . '.0'),
 	);
 	);
 
 
 	// Allow adding new buttons easily.
 	// Allow adding new buttons easily.
@@ -703,14 +703,14 @@ function template_main()
 				<div class="cat_bar">
 				<div class="cat_bar">
 					<h3 class="catbg">
 					<h3 class="catbg">
 						<span class="ie6_header floatright">
 						<span class="ie6_header floatright">
-							<a href="javascript:oQuickReply.swap();"><img src="', $settings['images_url'], '/', $options['display_quick_reply'] == 2 ? 'collapse' : 'expand', '.png" alt="+" id="quickReplyExpand" class="icon" />		</a>
+							<a href="javascript:oQuickReply.swap();"><img src="', $settings['images_url'], '/', $options['display_quick_reply'] > 1 ? 'collapse' : 'expand', '.png" alt="+" id="quickReplyExpand" class="icon" /></a>
 						</span>
 						</span>
 						<span>
 						<span>
 							<a href="javascript:oQuickReply.swap();">', $txt['quick_reply'], '</a>
 							<a href="javascript:oQuickReply.swap();">', $txt['quick_reply'], '</a>
 						</span>
 						</span>
 					</h3>
 					</h3>
 				</div>
 				</div>
-				<div id="quickReplyOptions"', $options['display_quick_reply'] == 2 ? '' : ' style="display: none"', '>
+				<div id="quickReplyOptions"', $options['display_quick_reply'] > 1 ? '' : ' style="display: none"', '>
 					<span class="upperframe"><span></span></span>
 					<span class="upperframe"><span></span></span>
 					<div class="roundframe">
 					<div class="roundframe">
 						<p class="smalltext lefttext">', $txt['quick_reply_desc'], '</p>
 						<p class="smalltext lefttext">', $txt['quick_reply_desc'], '</p>
@@ -730,31 +730,72 @@ function template_main()
 							<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
 							<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
 							<input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />';
 							<input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />';
 
 
-			// Guests just need more.
+		// Guests just need more.
-			if ($context['user']['is_guest'])
+		if ($context['user']['is_guest'])
-				echo '
+			echo '
 							<strong>', $txt['name'], ':</strong> <input type="text" name="guestname" value="', $context['name'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" />
 							<strong>', $txt['name'], ':</strong> <input type="text" name="guestname" value="', $context['name'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" />
 							<strong>', $txt['email'], ':</strong> <input type="text" name="email" value="', $context['email'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" /><br />';
 							<strong>', $txt['email'], ':</strong> <input type="text" name="email" value="', $context['email'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" /><br />';
 
 
-			// Is visual verification enabled?
+		// Is visual verification enabled?
-			if ($context['require_verification'])
+		if ($context['require_verification'])
-				echo '
+			echo '
 							<strong>', $txt['verification'], ':</strong>', template_control_verification($context['visual_verification_id'], 'quick_reply'), '<br />';
 							<strong>', $txt['verification'], ':</strong>', template_control_verification($context['visual_verification_id'], 'quick_reply'), '<br />';
 
 
+		if ($options['display_quick_reply'] < 3)
+		{
 			echo '
 			echo '
 							<div class="quickReplyContent">
 							<div class="quickReplyContent">
 								<textarea cols="600" rows="7" name="message" tabindex="', $context['tabindex']++, '"></textarea>
 								<textarea cols="600" rows="7" name="message" tabindex="', $context['tabindex']++, '"></textarea>
-							</div>
+							</div>';
+		}
+		else
+		{
+			// Show the actual posting area...
+			if ($context['show_bbc'])
+			{
+				echo '
+							<div id="bbcBox_message"></div>';
+			}
+
+			// What about smileys?
+			if (!empty($context['smileys']['postform']) || !empty($context['smileys']['popup']))
+				echo '
+							<div id="smileyBox_message"></div>';
+
+			echo '
+							', template_control_richedit($context['post_box_name'], 'smileyBox_message', 'bbcBox_message'), '
+							<script type="text/javascript"><!-- // --><![CDATA[
+								function insertQuoteFast(messageid)
+								{
+									if (window.XMLHttpRequest)
+										getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + \'action=quotefast;quote=\' + messageid + \';xml;pb=', $context['post_box_name'], ';mode=\' + (oEditorHandle_', $context['post_box_name'], '.bRichTextEnabled ? 1 : 0), onDocReceived);
+									else
+										reqWin(smf_prepareScriptUrl(smf_scripturl) + \'action=quotefast;quote=\' + messageid + \';pb=', $context['post_box_name'], ';mode=\' + (oEditorHandle_', $context['post_box_name'], '.bRichTextEnabled ? 1 : 0), 240, 90);
+									return false;
+								}
+								function onDocReceived(XMLDoc)
+								{
+									var text = \'\';
+									for (var i = 0, n = XMLDoc.getElementsByTagName(\'quote\')[0].childNodes.length; i < n; i++)
+										text += XMLDoc.getElementsByTagName(\'quote\')[0].childNodes[i].nodeValue;
+									oEditorHandle_', $context['post_box_name'], '.insertText(text, false, true);
+
+									ajax_indicator(false);
+								}
+							// ]]></script>';
+
+		}
+		echo '
 							<div class="padding">
 							<div class="padding">
 								<hr class="hrcolor" />
 								<hr class="hrcolor" />
 								<input type="submit" name="post" value="', $txt['post'], '" onclick="return submitThisOnce(this);" accesskey="s" tabindex="', $context['tabindex']++, '" class="button_submit" />
 								<input type="submit" name="post" value="', $txt['post'], '" onclick="return submitThisOnce(this);" accesskey="s" tabindex="', $context['tabindex']++, '" class="button_submit" />
 								<input type="submit" name="preview" value="', $txt['preview'], '" onclick="return submitThisOnce(this);" accesskey="p" tabindex="', $context['tabindex']++, '" class="button_submit" />';
 								<input type="submit" name="preview" value="', $txt['preview'], '" onclick="return submitThisOnce(this);" accesskey="p" tabindex="', $context['tabindex']++, '" class="button_submit" />';
 
 
-			if ($context['show_spellchecking'])
+		if ($context['show_spellchecking'])
-				echo '
+			echo '
 								<input type="button" value="', $txt['spell_check'], '" onclick="spellCheck(\'postmodify\', \'message\');" tabindex="', $context['tabindex']++, '" class="button_submit" />';
 								<input type="button" value="', $txt['spell_check'], '" onclick="spellCheck(\'postmodify\', \'message\');" tabindex="', $context['tabindex']++, '" class="button_submit" />';
 
 
-			echo '
+		echo '
 								<br class="clear_right" />
 								<br class="clear_right" />
 							</div>
 							</div>
 						</form>
 						</form>
@@ -779,7 +820,7 @@ function template_main()
 	if (!empty($options['display_quick_reply']))
 	if (!empty($options['display_quick_reply']))
 		echo '
 		echo '
 					var oQuickReply = new QuickReply({
 					var oQuickReply = new QuickReply({
-						bDefaultCollapsed: ', !empty($options['display_quick_reply']) && $options['display_quick_reply'] == 2 ? 'false' : 'true', ',
+						bDefaultCollapsed: ', !empty($options['display_quick_reply']) && $options['display_quick_reply'] > 1 ? 'false' : 'true', ',
 						iTopicId: ', $context['current_topic'], ',
 						iTopicId: ', $context['current_topic'], ',
 						iStart: ', $context['start'], ',
 						iStart: ', $context['start'], ',
 						sScriptUrl: smf_scripturl,
 						sScriptUrl: smf_scripturl,
@@ -788,7 +829,8 @@ function template_main()
 						sImageId: "quickReplyExpand",
 						sImageId: "quickReplyExpand",
 						sImageCollapsed: "collapse.png",
 						sImageCollapsed: "collapse.png",
 						sImageExpanded: "expand.png",
 						sImageExpanded: "expand.png",
-						sJumpAnchor: "quickreply"
+						sJumpAnchor: "quickreply",
+						bIsFull: ', !empty($options['display_quick_reply']) && $options['display_quick_reply'] > 2 ? 'true' : 'false', '
 					});';
 					});';
 
 
 	if (!empty($options['display_quick_mod']) && $options['display_quick_mod'] == 1 && $context['can_remove_post'])
 	if (!empty($options['display_quick_mod']) && $options['display_quick_mod'] == 1 && $context['can_remove_post'])

+ 12 - 2
Themes/default/ManageBoards.template.php

@@ -405,12 +405,15 @@ function template_modify_board()
 
 
 	if (empty($modSettings['deny_boards_access']))
 	if (empty($modSettings['deny_boards_access']))
 		echo '
 		echo '
-							<em>', $txt['check_all'], '</em> <input type="checkbox" class="input_check" onclick="invertAll(this, this.form, \'groups[\');" /><br />
+							<span class="select_all_box">
+								<em>', $txt['check_all'], '</em> <input type="checkbox" class="input_check" onclick="invertAll(this, this.form, \'groups[\');" />
+							</span>
+							<br />
 							<br />
 							<br />
 						</dd>';
 						</dd>';
 	else
 	else
 		echo '
 		echo '
-								<tr>
+								<tr class="select_all_box">
 									<td>
 									<td>
 									</td>
 									</td>
 									<td>
 									<td>
@@ -440,6 +443,13 @@ function template_modify_board()
 							<div id="moderator_container"></div>
 							<div id="moderator_container"></div>
 						</dd>
 						</dd>
 					</dl>
 					</dl>
+					<script type="text/javascript"><!-- // --><![CDATA[
+						$(document).ready(function () {
+							$(".select_all_box").each(function () {
+								$(this).removeClass(\'select_all_box\');
+							});
+						});
+					// ]]></script>
 					<hr class="hrcolor" />';
 					<hr class="hrcolor" />';
 
 
 	if (empty($context['board']['is_recycle']) && empty($context['board']['topics']))
 	if (empty($context['board']['is_recycle']) && empty($context['board']['topics']))

+ 95 - 67
Themes/default/ManageMembergroups.template.php

@@ -114,44 +114,17 @@ function template_new_group()
 							</fieldset>
 							</fieldset>
 						</dd>';
 						</dd>';
 	}
 	}
+
 	echo '
 	echo '
 						<dt>
 						<dt>
 							<strong>', $txt['membergroups_new_board'], ':</strong>', $context['post_group'] ? '<br />
 							<strong>', $txt['membergroups_new_board'], ':</strong>', $context['post_group'] ? '<br />
 							<span class="smalltext" style="font-weight: normal">' . $txt['membergroups_new_board_post_groups'] . '</span>' : '', '
 							<span class="smalltext" style="font-weight: normal">' . $txt['membergroups_new_board_post_groups'] . '</span>' : '', '
 						</dt>
 						</dt>
-						<dd>
+						<dd>';
-							<fieldset id="visible_boards">
-								<legend>', $txt['membergroups_new_board_desc'], '</legend>
-								<ul class="ignoreboards floatleft">';
 
 
-	foreach ($context['categories'] as $category)
+	template_add_edit_group_boards_list(false);
-	{
-		echo '
-									<li class="category">
-										<a href="javascript:void(0);" onclick="selectBoards([', implode(', ', $category['child_ids']), '], \'new_group\'); return false;">', $category['name'], '</a>
-									<ul>';
-
-		foreach ($category['boards'] as $board)
-		{
-			echo '
-										<li class="board" style="margin-', $context['right_to_left'] ? 'right' : 'left', ': ', $board['child_level'], 'em;">
-											<input type="checkbox" name="boardaccess[]" id="brd', $board['id'], '" value="', $board['id'], '" ', $board['selected'] ? ' checked="checked" disabled="disabled"' : '', ' class="input_check" /> <label for="brd', $board['id'], '">', $board['name'], '</label>
-										</li>';
-		}
-
-		echo '
-									</ul>
-								</li>';
-	}
-
-	echo '
-							</ul>
-							<br class="clear" />';
 
 
 	echo '
 	echo '
-								<br />
-								<input type="checkbox" id="checkall_check" class="input_check" onclick="invertAll(this, this.form, \'boardaccess\');" /> <label for="checkall_check"><em>', $txt['check_all'], '</em></label>
-							</fieldset>
 						</dd>
 						</dd>
 					</dl>
 					</dl>
 					<hr class="hrcolor" />
 					<hr class="hrcolor" />
@@ -327,44 +300,9 @@ function template_edit_group()
 							<strong>', $txt['membergroups_new_board'], ':</strong>', $context['group']['is_post_group'] ? '<br />
 							<strong>', $txt['membergroups_new_board'], ':</strong>', $context['group']['is_post_group'] ? '<br />
 							<span class="smalltext">' . $txt['membergroups_new_board_post_groups'] . '</span>' : '', '
 							<span class="smalltext">' . $txt['membergroups_new_board_post_groups'] . '</span>' : '', '
 						</dt>
 						</dt>
-						<dd>
+						<dd>';
-							<fieldset id="visible_boards" style="width: 95%;">
+		template_add_edit_group_boards_list();
-								<legend><a href="javascript:void(0);" onclick="document.getElementById(\'visible_boards\').style.display = \'none\';document.getElementById(\'visible_boards_link\').style.display = \'block\'; return false;">', $txt['membergroups_new_board_desc'], '</a></legend>
-								<ul class="ignoreboards floatleft">';
-
-		foreach ($context['categories'] as $category)
-		{
-			echo '
-									<li class="category">
-										<a href="javascript:void(0);" onclick="selectBoards([', implode(', ', $category['child_ids']), '], \'groupForm\'); return false;">', $category['name'], '</a>
-										<ul>';
-
-			foreach ($category['boards'] as $board)
-			{
-				echo '
-											<li class="board" style="margin-', $context['right_to_left'] ? 'right' : 'left', ': ', $board['child_level'], 'em;">
-												<input type="checkbox" name="boardaccess[]" id="brd', $board['id'], '" value="', $board['id'], '" ', $board['selected'] ? ' checked="checked"' : '', ' class="input_check" /> <label for="brd', $board['id'], '">', $board['name'], '</label>
-											</li>';
-			}
-
-			echo '
-										</ul>
-									</li>';
-		}
-
-		echo '
-								</ul>
-								<br class="clear" />';
-
 		echo '
 		echo '
-								<br />
-								<input type="checkbox" id="checkall_check" class="input_check" onclick="invertAll(this, this.form, \'boardaccess\');" /> <label for="checkall_check"><em>', $txt['check_all'], '</em></label>
-							</fieldset>
-							<a href="javascript:void(0);" onclick="document.getElementById(\'visible_boards\').style.display = \'block\'; document.getElementById(\'visible_boards_link\').style.display = \'none\'; return false;" id="visible_boards_link" style="display: none;">[ ', $txt['membergroups_select_visible_boards'], ' ]</a>
-							<script type="text/javascript"><!-- // --><![CDATA[
-								document.getElementById("visible_boards_link").style.display = "";
-								document.getElementById("visible_boards").style.display = "none";
-							// ]]></script>
 						</dd>';
 						</dd>';
 	}
 	}
 	echo '
 	echo '
@@ -431,6 +369,96 @@ function template_edit_group()
 		// ]]></script>';
 		// ]]></script>';
 }
 }
 
 
+function template_add_edit_group_boards_list($collapse = true)
+{
+	global $context, $txt, $modSettings;
+	echo '
+							<fieldset id="visible_boards">
+								<legend>', $txt['membergroups_new_board_desc'], '</legend>
+								<ul class="ignoreboards floatleft">';
+
+	foreach ($context['categories'] as $category)
+	{
+		if (empty($modSettings['deny_boards_access']))
+			echo '
+									<li class="category">
+										<a href="javascript:void(0);" onclick="selectBoards([', implode(', ', $category['child_ids']), '], \'new_group\'); return false;"><strong>', $category['name'], '</strong></a>
+									<ul style="width:100%">';
+		else
+			echo '
+									<li class="category">
+										<strong>', $category['name'], '</strong>
+										<span class="select_all_box">
+											<em style="margin-left:5em;">', $txt['all_boards_in_cat'], ': </em>
+											<select onchange="select_in_category(', $category['id'], ', this, [', implode(',', array_keys($category['boards'])), ']);">
+												<option>---</option>
+												<option value="allow">', $txt['board_perms_allow'], '</option>
+												<option value="ignore">', $txt['board_perms_ignore'], '</option>
+												<option value="deny">', $txt['board_perms_deny'], '</option>
+											</select>
+										</span>
+										<ul style="width:100%" id="boards_list_', $category['id'], '">';
+
+		foreach ($category['boards'] as $board)
+		{
+			if (empty($modSettings['deny_boards_access']))
+				echo '
+										<li class="board" style="margin-', $context['right_to_left'] ? 'right' : 'left', ': ', $board['child_level'], 'em;">
+											<input type="checkbox" name="boardaccess[', $board['id'], ']" id="brd', $board['id'], '" value="\'allow\'" ', $board['allow'] ? ' checked="checked"' : '', ' class="input_check" /> <label for="brd', $board['id'], '">', $board['name'], '</label>
+										</li>';
+			else
+				echo '
+											<li class="board" style="width:100%">
+												<span style="margin-', $context['right_to_left'] ? 'right' : 'left', ': ', $board['child_level'], 'em;">', $board['name'], ': </span>
+												<span style="width:50%;float:right">
+													<input type="radio" name="boardaccess[', $board['id'], ']" id="allow_brd', $board['id'], '" value="allow" ', $board['allow'] ? ' checked="checked"' : '', ' class="input_check" /> <label for="allow_brd', $board['id'], '">', $txt['permissions_option_on'], '</label>
+													<input type="radio" name="boardaccess[', $board['id'], ']" id="ignore_brd', $board['id'], '" value="ignore" ', !$board['allow'] && !$board['deny'] ? ' checked="checked"' : '', ' class="input_check" /> <label for="ignore_brd', $board['id'], '">', $txt['permissions_option_off'], '</label>
+													<input type="radio" name="boardaccess[', $board['id'], ']" id="deny_brd', $board['id'], '" value="deny" ', $board['deny'] ? ' checked="checked"' : '', ' class="input_check" /> <label for="deny_brd', $board['id'], '">', $txt['permissions_option_deny'], '</label>
+												</span>
+											</li>';
+		}
+
+		echo '
+									</ul>
+								</li>';
+	}
+
+	echo '
+							</ul>
+							<br class="clear" />';
+
+	if (empty($modSettings['deny_boards_access']))
+		echo '
+								<br />
+								<input type="checkbox" id="checkall_check" class="input_check" onclick="invertAll(this, this.form, \'boardaccess\');" /> <label for="checkall_check"><em>', $txt['check_all'], '</em></label>
+							</fieldset>';
+	else
+		echo '
+								<br />
+								<span class="select_all_box">
+									<em>', $txt['all'], ': </em>
+									<input type="radio" name="select_all" id="allow_all" class="input_radio" onclick="selectAllRadio(this, this.form, \'boardaccess\', \'allow\');" /> <label for="allow_all">', $txt['board_perms_allow'], '</label>
+									<input type="radio" name="select_all" id="ignore_all" class="input_radio" onclick="selectAllRadio(this, this.form, \'boardaccess\', \'ignore\');" /> <label for="ignore_all">', $txt['board_perms_ignore'], '</label>
+									<input type="radio" name="select_all" id="deny_all" class="input_radio" onclick="selectAllRadio(this, this.form, \'boardaccess\', \'deny\');" /> <label for="deny_all">', $txt['board_perms_deny'], '</label>
+								</span>
+							</fieldset>
+							<script type="text/javascript"><!-- // --><![CDATA[
+								$(document).ready(function () {
+									$(".select_all_box").each(function () {
+										$(this).removeClass(\'select_all_box\');
+									});
+								});
+							// ]]></script>';
+
+	if ($collapse)
+		echo '
+							<a href="javascript:void(0);" onclick="document.getElementById(\'visible_boards\').style.display = \'block\'; document.getElementById(\'visible_boards_link\').style.display = \'none\'; return false;" id="visible_boards_link" style="display: none;">[ ', $txt['membergroups_select_visible_boards'], ' ]</a>
+							<script type="text/javascript"><!-- // --><![CDATA[
+								document.getElementById("visible_boards_link").style.display = "";
+								document.getElementById("visible_boards").style.display = "none";
+							// ]]></script>';
+}
+
 // Templating for viewing the members of a group.
 // Templating for viewing the members of a group.
 function template_group_members()
 function template_group_members()
 {
 {

+ 29 - 8
Themes/default/Printpage.template.php

@@ -50,13 +50,13 @@ function template_print_above()
 				padding: 0;
 				padding: 0;
 				list-style: none;
 				list-style: none;
 			}
 			}
-			dt.postheader
+			div.postheader, #poll_data
 			{
 			{
 				border: solid #000;
 				border: solid #000;
 				border-width: 1px 0;
 				border-width: 1px 0;
 				padding: 4px 0;
 				padding: 4px 0;
 			}
 			}
-			dd.postbody
+			div.postbody
 			{
 			{
 				margin: 1em 0 2em 2em;
 				margin: 1em 0 2em 2em;
 			}
 			}
@@ -98,27 +98,48 @@ function template_print_above()
 				color: black;
 				color: black;
 				background-color: black;
 				background-color: black;
 			}
 			}
+			.voted
+			{
+				font-weight: bold;
+			}
 		</style>
 		</style>
 	</head>
 	</head>
 	<body>
 	<body>
 		<h1 id="title">', $context['forum_name_html_safe'], '</h1>
 		<h1 id="title">', $context['forum_name_html_safe'], '</h1>
 		<h2 id="linktree">', $context['category_name'], ' => ', (!empty($context['parent_boards']) ? implode(' => ', $context['parent_boards']) . ' => ' : ''), $context['board_name'], ' => ', $txt['topic_started'], ': ', $context['poster_name'], ' ', $txt['search_on'], ' ', $context['post_time'], '</h2>
 		<h2 id="linktree">', $context['category_name'], ' => ', (!empty($context['parent_boards']) ? implode(' => ', $context['parent_boards']) . ' => ' : ''), $context['board_name'], ' => ', $txt['topic_started'], ': ', $context['poster_name'], ' ', $txt['search_on'], ' ', $context['post_time'], '</h2>
-		<dl id="posts">';
+		<div id="posts">';
 }
 }
 
 
 function template_main()
 function template_main()
 {
 {
 	global $context, $settings, $options, $txt;
 	global $context, $settings, $options, $txt;
 
 
+	if (!empty($context['poll']))
+	{
+		echo '
+			<div id="poll_data">', $txt['poll'], '
+				<div class="question">', $txt['poll_question'], ': <strong>', $context['poll']['question'], '</strong>';
+
+		$options = 1;
+		foreach ($context['poll']['options'] as $option)
+			echo '
+					<div class="', $option['voted_this'] ? 'voted' : '', '">', $txt['option'], ' ', $options++, ': <strong>', $option['option'], '</strong>
+						', $context['allow_poll_view'] ? $txt['votes'] . ': ' . $option['votes'] . '' : '', '
+					</div>';
+
+		echo '
+			</div>';
+	}
+
 	foreach ($context['posts'] as $post)
 	foreach ($context['posts'] as $post)
 		echo '
 		echo '
-			<dt class="postheader">
+			<div class="postheader">
 				', $txt['title'], ': <strong>', $post['subject'], '</strong><br />
 				', $txt['title'], ': <strong>', $post['subject'], '</strong><br />
 				', $txt['post_by'], ': <strong>', $post['member'], '</strong> ', $txt['search_on'], ' <strong>', $post['time'], '</strong>
 				', $txt['post_by'], ': <strong>', $post['member'], '</strong> ', $txt['search_on'], ' <strong>', $post['time'], '</strong>
-			</dt>
+			</div>
-			<dd class="postbody">
+			<div class="postbody">
 				', $post['body'], '
 				', $post['body'], '
-			</dd>';
+			</div>';
 }
 }
 
 
 function template_print_below()
 function template_print_below()
@@ -126,7 +147,7 @@ function template_print_below()
 	global $context, $settings, $options;
 	global $context, $settings, $options;
 
 
 	echo '
 	echo '
-		</dl>
+		</div>
 		<div id="footer" class="smalltext">
 		<div id="footer" class="smalltext">
 			', theme_copyright(), '
 			', theme_copyright(), '
 		</div>
 		</div>

+ 1 - 0
Themes/default/Profile.template.php

@@ -1668,6 +1668,7 @@ function template_profile_theme_settings()
 									<option value="0"', empty($context['member']['options']['display_quick_reply']) ? ' selected="selected"' : '', '>', $txt['display_quick_reply1'], '</option>
 									<option value="0"', empty($context['member']['options']['display_quick_reply']) ? ' selected="selected"' : '', '>', $txt['display_quick_reply1'], '</option>
 									<option value="1"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 1 ? ' selected="selected"' : '', '>', $txt['display_quick_reply2'], '</option>
 									<option value="1"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 1 ? ' selected="selected"' : '', '>', $txt['display_quick_reply2'], '</option>
 									<option value="2"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 2 ? ' selected="selected"' : '', '>', $txt['display_quick_reply3'], '</option>
 									<option value="2"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 2 ? ' selected="selected"' : '', '>', $txt['display_quick_reply3'], '</option>
+									<option value="3"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 3 ? ' selected="selected"' : '', '>', $txt['display_quick_reply4'], '</option>
 								</select>
 								</select>
 							</dd>
 							</dd>
 							<dt>
 							<dt>

+ 2 - 1
Themes/default/Settings.template.php

@@ -130,7 +130,8 @@ function template_options()
 			'options' => array(
 			'options' => array(
 				0 => $txt['display_quick_reply1'],
 				0 => $txt['display_quick_reply1'],
 				1 => $txt['display_quick_reply2'],
 				1 => $txt['display_quick_reply2'],
-				2 => $txt['display_quick_reply3']
+				2 => $txt['display_quick_reply3'],
+				3 => $txt['display_quick_reply4']
 			),
 			),
 			'default' => true,
 			'default' => true,
 		),
 		),

+ 3 - 3
Themes/default/Themes.template.php

@@ -214,7 +214,7 @@ function template_list_themes()
 		echo '
 		echo '
 			<div class="title_bar">
 			<div class="title_bar">
 				<h3 class="titlebg">
 				<h3 class="titlebg">
-					<span class="floatleft"><strong><a href="', $scripturl, '?action=admin;area=theme;th=', $theme['id'], ';', $context['session_var'], '=', $context['session_id'], ';sa=settings">', $theme['name'], '</a></strong>', !empty($theme['version']) ? ' <em>(' . $theme['version'] . ')</em>' : '', '</span>';
+					<span class="floatleft"><strong><a href="', $scripturl, '?action=admin;area=theme;th=', $theme['id'], ';', $context['session_var'], '=', $context['session_id'], ';sa=list">', $theme['name'], '</a></strong>', !empty($theme['version']) ? ' <em>(' . $theme['version'] . ')</em>' : '', '</span>';
 
 
 			// You *cannot* delete the default theme. It's important!
 			// You *cannot* delete the default theme. It's important!
 			if ($theme['id'] != 1)
 			if ($theme['id'] != 1)
@@ -434,7 +434,7 @@ function template_set_settings()
 
 
 	echo '
 	echo '
 	<div id="admincenter">
 	<div id="admincenter">
-		<form action="', $scripturl, '?action=admin;area=theme;sa=settings;th=', $context['theme_settings']['theme_id'], '" method="post" accept-charset="', $context['character_set'], '">
+		<form action="', $scripturl, '?action=admin;area=theme;sa=list;th=', $context['theme_settings']['theme_id'], '" method="post" accept-charset="', $context['character_set'], '">
 			<div class="title_bar">
 			<div class="title_bar">
 				<h3 class="titlebg">
 				<h3 class="titlebg">
 					<span class="ie6_header floatleft"><a href="', $scripturl, '?action=helpadmin;help=theme_settings" onclick="return reqWin(this.href);" class="help"><img src="', $settings['images_url'], '/helptopics.png" alt="', $txt['help'], '" class="icon" /></a> ', $txt['theme_settings'], ' - ', $context['theme_settings']['name'], '</span>
 					<span class="ie6_header floatleft"><a href="', $scripturl, '?action=helpadmin;help=theme_settings" onclick="return reqWin(this.href);" class="help"><img src="', $settings['images_url'], '/helptopics.png" alt="', $txt['help'], '" class="icon" /></a> ', $txt['theme_settings'], ' - ', $context['theme_settings']['name'], '</span>
@@ -772,7 +772,7 @@ function template_installed()
 			<span class="topslice"><span></span></span>
 			<span class="topslice"><span></span></span>
 			<div class="content">
 			<div class="content">
 				<p>
 				<p>
-					<a href="', $scripturl, '?action=admin;area=theme;sa=settings;th=', $context['installed_theme']['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $context['installed_theme']['name'], '</a> ', $txt['theme_installed_message'], '
+					<a href="', $scripturl, '?action=admin;area=theme;sa=list;th=', $context['installed_theme']['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $context['installed_theme']['name'], '</a> ', $txt['theme_installed_message'], '
 				</p>
 				</p>
 				<p>
 				<p>
 					<a href="', $scripturl, '?action=admin;area=theme;sa=admin;', $context['session_var'], '=', $context['session_id'], '">', $txt['back'], '</a>
 					<a href="', $scripturl, '?action=admin;area=theme;sa=admin;', $context['session_var'], '=', $context['session_id'], '">', $txt['back'], '</a>

+ 3 - 0
Themes/default/css/admin.css

@@ -288,6 +288,9 @@ pre.file_content {
 	border-bottom: 1px dotted #000;
 	border-bottom: 1px dotted #000;
 	cursor: help;
 	cursor: help;
 }
 }
+.select_all_box {
+	display:none;
+}
 
 
 /* Styles for the manage members section.
 /* Styles for the manage members section.
 ------------------------------------------------- */
 ------------------------------------------------- */

+ 1 - 2
Themes/default/css/index.css

@@ -1947,7 +1947,6 @@ img.smiley {
 	width: 635px;
 	width: 635px;
 	max-width: 100%;
 	max-width: 100%;
 	min-width: 100%;
 	min-width: 100%;
-	margin: 0.25em 0 1em 0;
 }
 }
 /* The jump to box */
 /* The jump to box */
 #display_jump_to {
 #display_jump_to {
@@ -2771,7 +2770,7 @@ img.centericon {
 .ignoreboards {
 .ignoreboards {
 	margin: 0 2%;
 	margin: 0 2%;
 	padding: 0;
 	padding: 0;
-	width: 45%;
+	width: 90%;
 }
 }
 .ignoreboards a {
 .ignoreboards a {
 	font-weight: bold;
 	font-weight: bold;

+ 1 - 1
Themes/default/index.template.php

@@ -636,4 +636,4 @@ function template_css()
 	<link rel="stylesheet" type="text/css" href="', $filename, '" />';
 	<link rel="stylesheet" type="text/css" href="', $filename, '" />';
 }
 }
 
 
-?>
+?>

+ 6 - 0
Themes/default/languages/Admin.english.php

@@ -526,6 +526,7 @@ $txt['oldTopicDays'] = 'Time before topic is warned as old on reply';
 $txt['oldTopicDays_zero'] = '0 to disable';
 $txt['oldTopicDays_zero'] = '0 to disable';
 $txt['defaultMaxTopics'] = 'Number of topics per page in the message index';
 $txt['defaultMaxTopics'] = 'Number of topics per page in the message index';
 $txt['defaultMaxMessages'] = 'Number of posts per page in a topic page';
 $txt['defaultMaxMessages'] = 'Number of posts per page in a topic page';
+$txt['disable_print_topic'] = 'Disable print topic feature';
 $txt['hotTopicPosts'] = 'Number of posts for a hot topic';
 $txt['hotTopicPosts'] = 'Number of posts for a hot topic';
 $txt['hotTopicVeryPosts'] = 'Number of posts for a very hot topic';
 $txt['hotTopicVeryPosts'] = 'Number of posts for a very hot topic';
 $txt['enableAllMessages'] = 'Max topic size to show &quot;All&quot; posts';
 $txt['enableAllMessages'] = 'Max topic size to show &quot;All&quot; posts';
@@ -659,4 +660,9 @@ $txt['hooks_disable_legend_disabled'] = 'the hook exists but has been disabled';
 $txt['hooks_disable_legend_missing'] = 'the hook has not been found';
 $txt['hooks_disable_legend_missing'] = 'the hook has not been found';
 $txt['hooks_reset_filter'] = 'Reset filter';
 $txt['hooks_reset_filter'] = 'Reset filter';
 
 
+$txt['board_perms_allow'] = 'Allow';
+$txt['board_perms_ignore'] = 'Ignore';
+$txt['board_perms_deny'] = 'Deny';
+$txt['all_boards_in_cat'] = 'All boards in this category';
+
 ?>
 ?>

+ 1 - 0
Themes/default/languages/Errors.english.php

@@ -346,6 +346,7 @@ $txt['loadavg_allunread_disabled'] = 'The server\'s resources are temporarily un
 $txt['loadavg_unreadreplies_disabled'] = 'The server is currently under high stress.  Please try again shortly.';
 $txt['loadavg_unreadreplies_disabled'] = 'The server is currently under high stress.  Please try again shortly.';
 $txt['loadavg_show_posts_disabled'] = 'Please try again later.  This member\'s posts are not currently available due to high load on the server.';
 $txt['loadavg_show_posts_disabled'] = 'Please try again later.  This member\'s posts are not currently available due to high load on the server.';
 $txt['loadavg_unread_disabled'] = 'The server\'s resources are temporarily under too high a demand to list out the topics you have not read.';
 $txt['loadavg_unread_disabled'] = 'The server\'s resources are temporarily under too high a demand to list out the topics you have not read.';
+$txt['loadavg_userstats_disabled'] = 'Please try again later.  This member\'s statistics are not currently available due to high load on the server.';
 
 
 $txt['cannot_edit_permissions_inherited'] = 'You cannot edit inherited permissions directly, you must either edit the parent group or edit the membergroup inheritance.';
 $txt['cannot_edit_permissions_inherited'] = 'You cannot edit inherited permissions directly, you must either edit the parent group or edit the membergroup inheritance.';
 
 

+ 11 - 11
Themes/default/languages/Help.english.php

@@ -17,21 +17,21 @@ $helptxt['manage_boards'] = '
 		<li>
 		<li>
 			<strong>Sports</strong>
 			<strong>Sports</strong>
 			&nbsp;- A &quot;category&quot;
 			&nbsp;- A &quot;category&quot;
-		</li>
-		<ul class="normallist">
-			<li>
-				<strong>Baseball</strong>
-				&nbsp;- A board under the category of &quot;Sports&quot;
-			</li>
 			<ul class="normallist">
 			<ul class="normallist">
 				<li>
 				<li>
-					<strong>Stats</strong>
+					<strong>Baseball</strong>
-					&nbsp;- A child board under the board of &quot;Baseball&quot;
+					&nbsp;- A board under the category of &quot;Sports&quot;
+					<ul class="normallist">
+						<li>
+							<strong>Stats</strong>
+							&nbsp;- A child board under the board of &quot;Baseball&quot;
+						</li>
+					</ul>
 				</li>
 				</li>
+				<li><strong>Football</strong>
+				&nbsp;- A board under the category of &quot;Sports&quot;</li>
 			</ul>
 			</ul>
-			<li><strong>Football</strong>
+		</li>
-			&nbsp;- A board under the category of &quot;Sports&quot;</li>
-		</ul>
 	</ul>
 	</ul>
 	Categories allow you to break down the board into broad topics (&quot;Cars,
 	Categories allow you to break down the board into broad topics (&quot;Cars,
 	Sports&quot;), and the &quot;Boards&quot; under them are the actual topics under which
 	Sports&quot;), and the &quot;Boards&quot; under them are the actual topics under which

+ 2 - 1
Themes/default/languages/ManageSettings.english.php

@@ -3,7 +3,7 @@
 
 
 global $scripturl;
 global $scripturl;
 
 
-$txt['modSettings_desc'] = 'This page allows you to change the settings of features and basic options in your forum.  Please see the <a href="' . $scripturl . '?action=admin;area=theme;sa=settings;th=%1$s;%3$s=%2$s">theme settings</a> for more options.  Click the help icons for more information about a setting.';
+$txt['modSettings_desc'] = 'This page allows you to change the settings of features and basic options in your forum.  Please see the <a href="' . $scripturl . '?action=admin;area=theme;sa=list;th=%1$s;%3$s=%2$s">theme settings</a> for more options.  Click the help icons for more information about a setting.';
 $txt['security_settings_desc'] = 'This page allows you to set options specifically related to the security and moderation of your forum, including anti-spam options.';
 $txt['security_settings_desc'] = 'This page allows you to set options specifically related to the security and moderation of your forum, including anti-spam options.';
 $txt['modification_settings_desc'] = 'This page contains settings added by any modifications to your forum';
 $txt['modification_settings_desc'] = 'This page contains settings added by any modifications to your forum';
 
 
@@ -147,6 +147,7 @@ $txt['loadavg_search'] = 'Threshold to disabling search';
 $txt['loadavg_allunread'] = 'Threshold to disabling all unread topics';
 $txt['loadavg_allunread'] = 'Threshold to disabling all unread topics';
 $txt['loadavg_unreadreplies'] = 'Threshold to disabling unread replies';
 $txt['loadavg_unreadreplies'] = 'Threshold to disabling unread replies';
 $txt['loadavg_show_posts'] = 'Threshold to disabling showing user posts';
 $txt['loadavg_show_posts'] = 'Threshold to disabling showing user posts';
+$txt['loadavg_userstats'] = 'Threshold to disabling showing user statistics';
 $txt['loadavg_bbc'] = 'Threshold to disabling BBC formating when showing posts';
 $txt['loadavg_bbc'] = 'Threshold to disabling BBC formating when showing posts';
 $txt['loadavg_forum'] = 'Threshold to disabling the forum <strong>completely</strong>';
 $txt['loadavg_forum'] = 'Threshold to disabling the forum <strong>completely</strong>';
 $txt['loadavg_disabled_windows'] = '<span class="error">Load balancing support is not available on Windows.</span>';
 $txt['loadavg_disabled_windows'] = '<span class="error">Load balancing support is not available on Windows.</span>';

+ 1 - 0
Themes/default/languages/Profile.english.php

@@ -290,6 +290,7 @@ $txt['display_quick_reply'] = 'Use quick reply on topic display: ';
 $txt['display_quick_reply1'] = 'don\'t show at all';
 $txt['display_quick_reply1'] = 'don\'t show at all';
 $txt['display_quick_reply2'] = 'show, off by default';
 $txt['display_quick_reply2'] = 'show, off by default';
 $txt['display_quick_reply3'] = 'show, on by default';
 $txt['display_quick_reply3'] = 'show, on by default';
+$txt['display_quick_reply4'] = 'show full editor, on by default';
 $txt['display_quick_mod'] = 'Show quick-moderation as ';
 $txt['display_quick_mod'] = 'Show quick-moderation as ';
 $txt['display_quick_mod_none'] = 'don\'t show.';
 $txt['display_quick_mod_none'] = 'don\'t show.';
 $txt['display_quick_mod_check'] = 'checkboxes.';
 $txt['display_quick_mod_check'] = 'checkboxes.';

+ 0 - 2
Themes/default/languages/Reports.english.php

@@ -21,8 +21,6 @@ $txt['results'] = 'Results';
 
 
 // Board permissions
 // Board permissions
 $txt['board_perms_permission'] = 'Permission';
 $txt['board_perms_permission'] = 'Permission';
-$txt['board_perms_allow'] = 'Allow';
-$txt['board_perms_deny'] = 'Deny';
 $txt['board_perms_name_announce_topic'] = 'Announce topic';
 $txt['board_perms_name_announce_topic'] = 'Announce topic';
 $txt['board_perms_name_approve_posts'] = 'Approve posts';
 $txt['board_perms_name_approve_posts'] = 'Approve posts';
 $txt['board_perms_name_delete_any'] = 'Delete any posts';
 $txt['board_perms_name_delete_any'] = 'Delete any posts';

+ 8 - 0
Themes/default/scripts/admin.js

@@ -599,4 +599,12 @@ function repeatString(sString, iTime)
 		return '';
 		return '';
 	else
 	else
 		return sString + repeatString(sString, iTime - 1);
 		return sString + repeatString(sString, iTime - 1);
+}
+
+function select_in_category(cat_id, elem, brd_list)
+{
+	for (var brd in brd_list)
+		document.getElementById(elem.value + '_brd' + brd_list[brd]).checked = true;
+
+	elem.selectedIndex = 0;
 }
 }

+ 1 - 1
Themes/default/scripts/script.js

@@ -533,7 +533,7 @@ function selectRadioByName(oRadioGroup, sName)
 function selectAllRadio(oInvertCheckbox, oForm, sMask, sValue)
 function selectAllRadio(oInvertCheckbox, oForm, sMask, sValue)
 {
 {
 	for (var i = 0; i < oForm.length; i++)
 	for (var i = 0; i < oForm.length; i++)
-		if (oForm[i].name.substr(0, sMask.length) == sMask && oForm[i].value == sValue)
+		if (oForm[i].name != undefined && oForm[i].name.substr(0, sMask.length) == sMask && oForm[i].value == sValue)
 			oForm[i].checked = true;
 			oForm[i].checked = true;
 }
 }
 
 

+ 6 - 2
Themes/default/scripts/topic.js

@@ -123,6 +123,7 @@ function QuickReply(oOptions)
 {
 {
 	this.opt = oOptions;
 	this.opt = oOptions;
 	this.bCollapsed = this.opt.bDefaultCollapsed;
 	this.bCollapsed = this.opt.bDefaultCollapsed;
+	this.bIsFull = this.opt.bIsFull;
 }
 }
 
 
 // When a user presses quote, put it in the quick reply box (if expanded).
 // When a user presses quote, put it in the quick reply box (if expanded).
@@ -143,7 +144,10 @@ QuickReply.prototype.quote = function (iMessageId, xDeprecated)
 		if (window.XMLHttpRequest)
 		if (window.XMLHttpRequest)
 		{
 		{
 			ajax_indicator(true);
 			ajax_indicator(true);
-			getXMLDocument(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=quotefast;quote=' + iMessageId + ';xml', this.onQuoteReceived);
+			if (this.bIsFull)
+				insertQuoteFast(iMessageId);
+			else
+				getXMLDocument(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=quotefast;quote=' + iMessageId + ';xml', this.onQuoteReceived);
 		}
 		}
 		// Or with a smart popup!
 		// Or with a smart popup!
 		else
 		else
@@ -176,7 +180,7 @@ QuickReply.prototype.onQuoteReceived = function (oXMLDoc)
 QuickReply.prototype.swap = function ()
 QuickReply.prototype.swap = function ()
 {
 {
 	document.getElementById(this.opt.sImageId).src = this.opt.sImagesUrl + "/" + (this.bCollapsed ? this.opt.sImageCollapsed : this.opt.sImageExpanded);
 	document.getElementById(this.opt.sImageId).src = this.opt.sImagesUrl + "/" + (this.bCollapsed ? this.opt.sImageCollapsed : this.opt.sImageExpanded);
-	document.getElementById(this.opt.sContainerId).style.display = this.bCollapsed ? '' : 'none';
+	$('#' + this.opt.sContainerId).slideToggle();
 
 
 	this.bCollapsed = !this.bCollapsed;
 	this.bCollapsed = !this.bCollapsed;
 }
 }

+ 60 - 26
Themes/penguin/Display.template.php

@@ -159,7 +159,7 @@ function template_main()
 
 
 	// Build the normal button array.
 	// Build the normal button array.
 	$normal_buttons = array(
 	$normal_buttons = array(
-		'print' => array('text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="new_win nofollow"', 'url' => $scripturl . '?action=printpage;topic=' . $context['current_topic'] . '.0'),
+		'print' => array('test' => 'can_print', 'text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="new_win nofollow"', 'url' => $scripturl . '?action=printpage;topic=' . $context['current_topic'] . '.0'),
 		'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0'),
 		'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0'),
 		'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
 		'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
 		'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']) . '\');"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
 		'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']) . '\');"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']),
@@ -174,8 +174,6 @@ function template_main()
 	// Allow adding new buttons easily.
 	// Allow adding new buttons easily.
 	call_integration_hook('integrate_display_buttons', array(&$normal_buttons));
 	call_integration_hook('integrate_display_buttons', array(&$normal_buttons));
 
 
-	// Show the page index... "Pages: [1]".
-
 	// Show the topic information - icon, subject, etc.
 	// Show the topic information - icon, subject, etc.
 	echo '
 	echo '
 			<div id="forumposts">
 			<div id="forumposts">
@@ -519,7 +517,7 @@ function template_main()
 									// Show a checkbox for quick moderation?
 									// Show a checkbox for quick moderation?
 									if (!empty($options['display_quick_mod']) && $options['display_quick_mod'] == 1 && $message['can_remove'])
 									if (!empty($options['display_quick_mod']) && $options['display_quick_mod'] == 1 && $message['can_remove'])
 										echo '
 										echo '
-											<li class="inline_mod_check" style="display: none;" id="in_topic_mod_check_', $message['id'], '"><label for="fukn_pita_bastard_', $message['id'], '">Select post&nbsp;</label></li>';
+											<li class="inline_mod_check" style="display: none;" id="in_topic_mod_check_', $message['id'], '"><label for="in_topic_mod_check_', $message['id'], '">Select post&nbsp;</label></li>';
 										echo '
 										echo '
 											<li><a href="', $scripturl, '?action=', !empty($message['member']['is_guest']) ? 'trackip' : 'profile;area=tracking;sa=ip;u=' . $message['member']['id'], ';searchip=', $message['member']['ip'], '" class="ip_link">', $message['member']['ip'], '</a></li>
 											<li><a href="', $scripturl, '?action=', !empty($message['member']['is_guest']) ? 'trackip' : 'profile;area=tracking;sa=ip;u=' . $message['member']['id'], ';searchip=', $message['member']['ip'], '" class="ip_link">', $message['member']['ip'], '</a></li>
 										</ul>
 										</ul>
@@ -603,12 +601,12 @@ function template_main()
 				<div class="cat_bar">
 				<div class="cat_bar">
 					<h3 class="catbg">
 					<h3 class="catbg">
 						<a href="javascript:oQuickReply.swap();" id="QuickReply_swap">
 						<a href="javascript:oQuickReply.swap();" id="QuickReply_swap">
-							<img src="', $settings['images_url'], '/', $options['display_quick_reply'] == 2 ? 'upshrink' : 'upshrink2', '.png" alt="+" id="quickReplyExpand" class="icon floatright" />
+							<img src="', $settings['images_url'], '/', $options['display_quick_reply'] > 1 ? 'upshrink' : 'upshrink2', '.png" alt="+" id="quickReplyExpand" class="icon floatright" />
 						</a>
 						</a>
 						<a href="javascript:oQuickReply.swap();">', $txt['quick_reply'], '</a>
 						<a href="javascript:oQuickReply.swap();">', $txt['quick_reply'], '</a>
 					</h3>
 					</h3>
 				</div>
 				</div>
-				<div id="quickReplyOptions"', $options['display_quick_reply'] == 2 ? '' : ' style="display: none"', '>
+				<div id="quickReplyOptions"', $options['display_quick_reply'] > 1 ? '' : ' style="display: none"', '>
 					<div class="roundframe">
 					<div class="roundframe">
 						<p class="smalltext lefttext">', $txt['quick_reply_desc'], '</p>
 						<p class="smalltext lefttext">', $txt['quick_reply_desc'], '</p>
 						', $context['is_locked'] ? '<p class="alert smalltext">' . $txt['quick_reply_warning'] . '</p>' : '',
 						', $context['is_locked'] ? '<p class="alert smalltext">' . $txt['quick_reply_warning'] . '</p>' : '',
@@ -627,23 +625,66 @@ function template_main()
 							<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
 							<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
 							<input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />';
 							<input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />';
 
 
-			// Guests just need more.
+		// Guests just need more.
-			if ($context['user']['is_guest'])
+		if ($context['user']['is_guest'])
-				echo '
+			echo '
 							<strong>', $txt['name'], ':</strong> <input type="text" name="guestname" value="', $context['name'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" />
 							<strong>', $txt['name'], ':</strong> <input type="text" name="guestname" value="', $context['name'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" />
 							<strong>', $txt['email'], ':</strong> <input type="text" name="email" value="', $context['email'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" /><br />';
 							<strong>', $txt['email'], ':</strong> <input type="text" name="email" value="', $context['email'], '" size="25" class="input_text" tabindex="', $context['tabindex']++, '" /><br />';
 
 
-			// Is visual verification enabled?
+		// Is visual verification enabled?
-			if ($context['require_verification'])
+		if ($context['require_verification'])
-				echo '
+			echo '
 							<strong>', $txt['verification'], ':</strong>', template_control_verification($context['visual_verification_id'], 'quick_reply'), '<br />';
 							<strong>', $txt['verification'], ':</strong>', template_control_verification($context['visual_verification_id'], 'quick_reply'), '<br />';
 
 
+		if ($options['display_quick_reply'] < 3)
+		{
 			echo '
 			echo '
 							<div class="quickReplyContent">
 							<div class="quickReplyContent">
 								<textarea class ="expand_test" cols="" rows="" name="message" tabindex="', $context['tabindex']++, '"></textarea>
 								<textarea class ="expand_test" cols="" rows="" name="message" tabindex="', $context['tabindex']++, '"></textarea>
-							</div>
+							</div>';
+		}
+		else
+		{
+			// Show the actual posting area...
+			if ($context['show_bbc'])
+			{
+				echo '
+								<div id="bbcBox_message"></div>';
+			}
+
+			// What about smileys?
+			if (!empty($context['smileys']['postform']) || !empty($context['smileys']['popup']))
+				echo '
+								<div id="smileyBox_message"></div>';
+
+			echo '
+							', template_control_richedit($context['post_box_name'], 'smileyBox_message', 'bbcBox_message'), '
+								<script type="text/javascript"><!-- // --><![CDATA[
+									function insertQuoteFast(messageid)
+									{
+										if (window.XMLHttpRequest)
+											getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + \'action=quotefast;quote=\' + messageid + \';xml;pb=', $context['post_box_name'], ';mode=\' + (oEditorHandle_', $context['post_box_name'], '.bRichTextEnabled ? 1 : 0), onDocReceived);
+										else
+											reqWin(smf_prepareScriptUrl(smf_scripturl) + \'action=quotefast;quote=\' + messageid + \';pb=', $context['post_box_name'], ';mode=\' + (oEditorHandle_', $context['post_box_name'], '.bRichTextEnabled ? 1 : 0), 240, 90);
+										return false;
+									}
+									function onDocReceived(XMLDoc)
+									{
+										var text = \'\';
+										for (var i = 0, n = XMLDoc.getElementsByTagName(\'quote\')[0].childNodes.length; i < n; i++)
+											text += XMLDoc.getElementsByTagName(\'quote\')[0].childNodes[i].nodeValue;
+										oEditorHandle_', $context['post_box_name'], '.insertText(text, false, true);
+
+										ajax_indicator(false);
+									}
+								// ]]></script>';
+
+		}
+		echo '
+							<div class="padding">
 								<input type="submit" name="post" value="', $txt['post'], '" onclick="return submitThisOnce(this);" accesskey="s" tabindex="', $context['tabindex']++, '" class="button_submit" />
 								<input type="submit" name="post" value="', $txt['post'], '" onclick="return submitThisOnce(this);" accesskey="s" tabindex="', $context['tabindex']++, '" class="button_submit" />
-								<input type="submit" name="preview" value="', $txt['preview'], '" onclick="return submitThisOnce(this);" accesskey="p" tabindex="', $context['tabindex']++, '" class="button_submit" />';
+								<input type="submit" name="preview" value="', $txt['preview'], '" onclick="return submitThisOnce(this);" accesskey="p" tabindex="', $context['tabindex']++, '" class="button_submit" />
+							</div>';
 
 
 			if ($context['show_spellchecking'])
 			if ($context['show_spellchecking'])
 				echo '
 				echo '
@@ -668,10 +709,10 @@ function template_main()
 				<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/topic.js"></script>
 				<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/topic.js"></script>
 				<script type="text/javascript"><!-- // --><![CDATA[';
 				<script type="text/javascript"><!-- // --><![CDATA[';
 
 
-/*	if (!empty($options['display_quick_reply']))
+	if (!empty($options['display_quick_reply']))
 		echo '
 		echo '
 					var oQuickReply = new QuickReply({
 					var oQuickReply = new QuickReply({
-						bDefaultCollapsed: ', !empty($options['display_quick_reply']) && $options['display_quick_reply'] == 2 ? 'false' : 'true', ',
+						bDefaultCollapsed: ', !empty($options['display_quick_reply']) && $options['display_quick_reply'] > 1 ? 'false' : 'true', ',
 						iTopicId: ', $context['current_topic'], ',
 						iTopicId: ', $context['current_topic'], ',
 						iStart: ', $context['start'], ',
 						iStart: ', $context['start'], ',
 						sScriptUrl: smf_scripturl,
 						sScriptUrl: smf_scripturl,
@@ -680,9 +721,10 @@ function template_main()
 						sImageId: "quickReplyExpand",
 						sImageId: "quickReplyExpand",
 						sImageCollapsed: "upshrink.png",
 						sImageCollapsed: "upshrink.png",
 						sImageExpanded: "upshrink2.png",
 						sImageExpanded: "upshrink2.png",
-						sJumpAnchor: "quickreply"
+						sJumpAnchor: "quickreply",
+						bIsFull: ', !empty($options['display_quick_reply']) && $options['display_quick_reply'] > 2 ? 'true' : 'false', '
 					});';
 					});';
-*/
+
 	if (!empty($options['display_quick_mod']) && $options['display_quick_mod'] == 1 && $context['can_remove_post'])
 	if (!empty($options['display_quick_mod']) && $options['display_quick_mod'] == 1 && $context['can_remove_post'])
 		echo '
 		echo '
 					var oInTopicModeration = new InTopicModeration({
 					var oInTopicModeration = new InTopicModeration({
@@ -801,15 +843,7 @@ function template_main()
 	}
 	}
 
 
 	echo '
 	echo '
-
 		$(document).ready(function(){
 		$(document).ready(function(){
-			$("#quickReplyOptions").hide();
-			$("#QuickReply_swap").show();
-
-			$("#QuickReply_swap").click(function(){
-				$("#quickReplyOptions").slideToggle();
-			});
-
 			$("li a.quote_button, li a.modify_button, li a.modify_inline, a.topic_reply_title").bt(jQuery.bt.options = {positions: "top, bottom"});
 			$("li a.quote_button, li a.modify_button, li a.modify_inline, a.topic_reply_title").bt(jQuery.bt.options = {positions: "top, bottom"});
 		});
 		});
 
 

+ 1 - 0
Themes/penguin/Profile.template.php

@@ -1628,6 +1628,7 @@ function template_profile_theme_settings()
 									<option value="0"', empty($context['member']['options']['display_quick_reply']) ? ' selected="selected"' : '', '>', $txt['display_quick_reply1'], '</option>
 									<option value="0"', empty($context['member']['options']['display_quick_reply']) ? ' selected="selected"' : '', '>', $txt['display_quick_reply1'], '</option>
 									<option value="1"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 1 ? ' selected="selected"' : '', '>', $txt['display_quick_reply2'], '</option>
 									<option value="1"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 1 ? ' selected="selected"' : '', '>', $txt['display_quick_reply2'], '</option>
 									<option value="2"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 2 ? ' selected="selected"' : '', '>', $txt['display_quick_reply3'], '</option>
 									<option value="2"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 2 ? ' selected="selected"' : '', '>', $txt['display_quick_reply3'], '</option>
+									<option value="3"', !empty($context['member']['options']['display_quick_reply']) && $context['member']['options']['display_quick_reply'] == 3 ? ' selected="selected"' : '', '>', $txt['display_quick_reply4'], '</option>
 								</select>
 								</select>
 							</dd>
 							</dd>
 							<dt>
 							<dt>

+ 1 - 0
Themes/penguin/Settings.template.php

@@ -131,6 +131,7 @@ function template_options()
 				0 => $txt['display_quick_reply1'],
 				0 => $txt['display_quick_reply1'],
 				1 => $txt['display_quick_reply2'],
 				1 => $txt['display_quick_reply2'],
 				2 => $txt['display_quick_reply3']
 				2 => $txt['display_quick_reply3']
+				3 => $txt['display_quick_reply4']
 			),
 			),
 			'default' => true,
 			'default' => true,
 		),
 		),

+ 3 - 0
Themes/penguin/css/admin.css

@@ -316,6 +316,9 @@ pre.file_content {
 	border-bottom: 1px dotted #000;
 	border-bottom: 1px dotted #000;
 	cursor: help;
 	cursor: help;
 }
 }
+.select_all_box {
+	display:none;
+}
 
 
 /* Styles for the manage members section.
 /* Styles for the manage members section.
 ------------------------------------------------- */
 ------------------------------------------------- */

+ 1 - 2
Themes/penguin/css/index.css

@@ -1848,7 +1848,6 @@ img.smiley {
 	width: 635px;
 	width: 635px;
 	max-width: 100%;
 	max-width: 100%;
 	min-width: 100%;
 	min-width: 100%;
-	margin: 10px 0;
 }
 }
 /* The jump to box */
 /* The jump to box */
 #display_jump_to {
 #display_jump_to {
@@ -2672,7 +2671,7 @@ img.centericon {
 .ignoreboards {
 .ignoreboards {
 	margin: 0 2%;
 	margin: 0 2%;
 	padding: 0;
 	padding: 0;
-	width: 45%;
+	width: 90%;
 }
 }
 .ignoreboards a {
 .ignoreboards a {
 	font-weight: bold;
 	font-weight: bold;

+ 8 - 0
Themes/penguin/scripts/admin.js

@@ -599,4 +599,12 @@ function repeatString(sString, iTime)
 		return '';
 		return '';
 	else
 	else
 		return sString + repeatString(sString, iTime - 1);
 		return sString + repeatString(sString, iTime - 1);
+}
+
+function select_in_category(cat_id, elem, brd_list)
+{
+	for (var brd in brd_list)
+	{
+		document.getElementById(elem.value + '_brd' + brd_list[brd]).checked = true;
+	}
 }
 }

+ 2 - 8
other/install.php

@@ -912,7 +912,6 @@ function ForumSettings()
 
 
 	// Check if the database sessions will even work.
 	// Check if the database sessions will even work.
 	$incontext['test_dbsession'] = ini_get('session.auto_start') != 1;
 	$incontext['test_dbsession'] = ini_get('session.auto_start') != 1;
-	$incontext['utf8_should_work'] = stripos(PHP_OS, 'win') === false;
 	$incontext['utf8_default'] = $databases[$db_type]['utf8_default'];
 	$incontext['utf8_default'] = $databases[$db_type]['utf8_default'];
 	$incontext['utf8_required'] = $databases[$db_type]['utf8_required'];
 	$incontext['utf8_required'] = $databases[$db_type]['utf8_required'];
 
 
@@ -2437,19 +2436,14 @@ function template_forum_settings()
 					<input type="checkbox" name="dbsession" id="dbsession_check" checked="checked" class="input_check" /> <label for="dbsession_check">', $txt['install_settings_dbsession_title'], '</label><br />
 					<input type="checkbox" name="dbsession" id="dbsession_check" checked="checked" class="input_check" /> <label for="dbsession_check">', $txt['install_settings_dbsession_title'], '</label><br />
 					<div style="font-size: smaller; margin-bottom: 2ex;">', $incontext['test_dbsession'] ? $txt['install_settings_dbsession_info1'] : $txt['install_settings_dbsession_info2'], '</div>
 					<div style="font-size: smaller; margin-bottom: 2ex;">', $incontext['test_dbsession'] ? $txt['install_settings_dbsession_info1'] : $txt['install_settings_dbsession_info2'], '</div>
 				</td>
 				</td>
-			</tr>';
+			</tr>
-
-	if ($incontext['utf8_should_work'])
-		echo '
 			<tr>
 			<tr>
 				<td valign="top" class="textbox">', $txt['install_settings_utf8'], ':</td>
 				<td valign="top" class="textbox">', $txt['install_settings_utf8'], ':</td>
 				<td>
 				<td>
 					<input type="checkbox" name="utf8" id="utf8_check"', $incontext['utf8_default'] ? ' checked="checked"' : '', ' class="input_check"', $incontext['utf8_required'] ? ' disabled="disabled"' : '', ' /> <label for="utf8_check">', $txt['install_settings_utf8_title'], '</label><br />
 					<input type="checkbox" name="utf8" id="utf8_check"', $incontext['utf8_default'] ? ' checked="checked"' : '', ' class="input_check"', $incontext['utf8_required'] ? ' disabled="disabled"' : '', ' /> <label for="utf8_check">', $txt['install_settings_utf8_title'], '</label><br />
 					<div style="font-size: smaller; margin-bottom: 2ex;">', $txt['install_settings_utf8_info'], '</div>
 					<div style="font-size: smaller; margin-bottom: 2ex;">', $txt['install_settings_utf8_info'], '</div>
 				</td>
 				</td>
-			</tr>';
+			</tr>
-
-	echo '
 			<tr>
 			<tr>
 				<td valign="top" class="textbox">', $txt['install_settings_stats'], ':</td>
 				<td valign="top" class="textbox">', $txt['install_settings_stats'], ':</td>
 				<td>
 				<td>

+ 1 - 1
other/install_2-1_mysql.sql

@@ -989,7 +989,7 @@ CREATE TABLE {$db_prefix}log_reported (
   id_member mediumint(8) unsigned NOT NULL default '0',
   id_member mediumint(8) unsigned NOT NULL default '0',
   membername varchar(255) NOT NULL default '',
   membername varchar(255) NOT NULL default '',
   subject varchar(255) NOT NULL default '',
   subject varchar(255) NOT NULL default '',
-  body text NOT NULL,
+  body mediumtext NOT NULL,
   time_started int(10) NOT NULL default '0',
   time_started int(10) NOT NULL default '0',
   time_updated int(10) NOT NULL default '0',
   time_updated int(10) NOT NULL default '0',
   num_reports mediumint(6) NOT NULL default '0',
   num_reports mediumint(6) NOT NULL default '0',