Index: t3lib/tceforms/class.t3lib_tceforms_flexforms.php
===================================================================
--- t3lib/tceforms/class.t3lib_tceforms_flexforms.php	(Revision 0)
+++ t3lib/tceforms/class.t3lib_tceforms_flexforms.php	(Revision 0)
@@ -0,0 +1,269 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Kai Vogel (kai.vogel(at)speedprogs.de)
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+
+/**
+ * Contains FlexForm manipulation methods as part of the TCEforms
+ *
+ * @author Kai Vogel <kai.vogel(at)speedprogs.de>
+ */
+class t3lib_TCEforms_Flexforms extends t3lib_TCEforms {
+
+	/**
+	 * Options that will be removed from config after creating items for a select to prevent double parsing
+	 *
+	 * @var array
+	 */
+	protected $removeSelectConfig = array(
+		'itemsProcFunc',
+		'foreign_table',
+		'foreign_table_where',
+		'foreign_table_prefix',
+		'foreign_table_loadIcons',
+		'neg_foreign_table',
+		'neg_foreign_table_where',
+		'neg_foreign_table_prefix',
+		'neg_foreign_table_loadIcons',
+		'neg_foreign_table_imposeValueField',
+		'fileFolder',
+		'fileFolder_extList',
+		'fileFolder_recursions',
+		'MM',
+		'MM_opposite_field',
+		'MM_match_fields',
+		'MM_insert_fields',
+		'MM_table_where',
+		'MM_hasUidField',
+		'special',
+	);
+
+	/**
+	 * Modify the Data Structure of a FlexForm field via TSconfig and group access lists
+	 *
+	 * @param   array     The data structure of the FlexForm field
+	 * @param   string    The table name of the record
+	 * @param   string    The field name
+	 * @param   array     The record data
+	 * @return  array     Modified FlexForm DS
+	 * @see t3lib_TCEforms::getSingleField_typeFlex()
+	 */
+	public function modifyFlexFormDS(array $dataStruct, $table, $tableField, array $tableRow) {
+		$singleSheet = (!isset($dataStruct['sheets']) || !is_array($dataStruct['sheets']));
+		$metaConf    = (!empty($dataStruct['meta']) ? $dataStruct['meta'] : array());
+		$sheetConf   = array();
+
+			// Get extension key from record data
+		if (!$extKey = t3lib_extMgm::getExtensionKeyByPluginRecord($tableRow)) {
+			return $dataStruct;
+		}
+
+			// Get field configuration from page TSConfig
+		$TSconfig = $this->setTSconfig($table, $tableRow);
+		if (!empty($TSconfig['pi_flexform'][$extKey . '.'])) {
+			$sheetConf = t3lib_div::removeDotsFromTS($TSconfig['pi_flexform'][$extKey . '.']);
+		};
+
+			// Get exclude fields from group access lists
+		if (!empty($GLOBALS['BE_USER']->groupData['non_exclude_fields'])) {
+			$excludeFields = t3lib_div::trimExplode(',', $GLOBALS['BE_USER']->groupData['non_exclude_fields']);
+			foreach ($excludeFields as $field) {
+				if (strpos($field, $extKey) !== FALSE) {
+					list(, $sheetName, $fieldName) = explode(';', $field);
+					$sheetConf[$sheetName][$fieldName] = array('disabled' => TRUE);
+				}
+			}
+		}
+
+			// Load complete DS, including external file references
+		$dataStruct = t3lib_div::resolveAllSheetsInDS($dataStruct);
+
+			// Modify flexform sheets
+		foreach ($dataStruct['sheets'] as $sheetName => $sheet) {
+			if (empty($sheet['ROOT']['el']) || !is_array($sheet['ROOT']['el']) || empty($sheetConf[$sheetName])) {
+				continue;
+			}
+
+				// Remove whole sheet (tab) if disabled
+			if (!empty($sheetConf[$sheetName]['disabled'])) {
+				unset($dataStruct['sheets'][$sheetName]);
+				continue;
+			}
+
+				// Rename sheet (tab)
+			if (!empty($sheetConf[$sheetName]['title'])) {
+				$dataStruct['sheets'][$sheetName]['ROOT']['TCEforms']['sheetTitle'] = $sheetConf[$sheetName]['title'];
+			}
+
+				// Modify all configured fields in sheet
+			$dataStruct['sheets'][$sheetName]['ROOT']['el'] = $this->modifySingleFlexFormSheet(
+				$sheet['ROOT']['el'],
+				$sheetConf[$sheetName],
+				$table,
+				$tableField,
+				$tableRow
+			);
+
+				// Remove empty sheet (tab)
+			if (empty($dataStruct['sheets'][$sheetName]['ROOT']['el'])) {
+				unset($dataStruct['sheets'][$sheetName]);
+			}
+		}
+
+			// Recover single flexform structure
+		if ($singleSheet && isset($dataStruct['sheets']['sDEF'])) {
+			$dataStruct = $dataStruct['sheets']['sDEF'];
+		}
+
+			// Recover meta configuration
+		if (!empty($metaConf)) {
+			$dataStruct['meta'] = $metaConf;
+		}
+
+		return $dataStruct;
+	}
+
+	/**
+	 * Modify a single FlexForm sheet according to given configuration
+	 *
+	 * @param   array     Flexform sheet to manipulate
+	 * @param   array     Sheet configuration
+	 * @param   string    The table name
+	 * @param   string    The field name
+	 * @param   array     The record data
+	 * @return  array     Modified sheet
+	 * @see t3lib_TCEforms_flex::modifyFlexFormDS()
+	 */
+	public function modifySingleFlexFormSheet(array $sheet, array $sheetConf, $table, $tableField, array $tableRow) {
+		if (empty($sheet) || empty($sheetConf) || empty($table) || empty($tableField) || empty($tableRow)) {
+			return $sheet;
+		}
+
+			// Modify configured fields
+		foreach ($sheetConf as $fieldName => $fieldConf) {
+			if (empty($sheet[$fieldName]) || !is_array($fieldConf)) {
+				continue;
+			}
+
+			$field       = $sheet[$fieldName];
+			$removeItems = (!empty($fieldConf['removeItems']) ? t3lib_div::trimExplode(',', $fieldConf['removeItems'], TRUE) : array());
+			$keepItems   = (!empty($fieldConf['keepItems'])   ? t3lib_div::trimExplode(',', $fieldConf['keepItems'], TRUE)   : array());
+			$renameItems = (!empty($fieldConf['altLabels']) && is_array($fieldConf['altLabels']) ? $fieldConf['altLabels']   : array());
+			$addItems    = (!empty($fieldConf['addItems'])  && is_array($fieldConf['addItems'])  ? $fieldConf['addItems']    : array());
+
+			unset($fieldConf['removeItems']);
+			unset($fieldConf['keepItems']);
+			unset($fieldConf['altLabels']);
+			unset($fieldConf['addItems']);
+
+				// Remove excluded fields
+			if (!empty($fieldConf['disabled'])) {
+				unset($sheet[$fieldName]);
+				continue;
+			}
+
+				// Manipulate field
+			if (!empty($field['TCEforms']) && is_array($field['TCEforms'])) {
+				$sheet[$fieldName]['TCEforms'] = t3lib_div::array_merge_recursive_overrule($field['TCEforms'], $fieldConf);
+			}
+
+				// Manipulate select items
+			if (empty($field['TCEforms']['config']['type']) || $field['TCEforms']['config']['type'] != 'select') {
+				continue;
+			}
+
+				// Getting the selector box items from system
+			$selItems = $this->addSelectOptionsToItemArray(
+				$this->initItemArray($field['TCEforms']),
+				$field['TCEforms'],
+				$this->setTSconfig($table, $tableRow),
+				$tableField
+			);
+
+				// Possibly filter some items
+			$keepItemsFunc = create_function('$value', 'return $value[1];');
+			$selItems = t3lib_div::keepItemsInArray($selItems, $keepItems, $keepItemsFunc);
+
+				// Possibly add some items
+			$selItems = $this->addItems($selItems, $addItems);
+
+				// Process items by a user function
+			if (!empty($field['TCEforms']['config']['itemsProcFunc'])) {
+				$selItems = $this->procItems(
+					$selItems,
+					$fieldConf['config'],
+					$field['TCEforms']['config'],
+					$table,
+					$tableRow,
+					$tableField
+				);
+			}
+
+				// Remove special configuration options after creating items to prevent double parsing
+			foreach ($this->removeSelectConfig as $option) {
+				unset($field['TCEforms']['config'][$option]);
+			}
+
+				// Rename and remove items in select
+			if ((!empty($removeItems) || !empty($renameItems)) && !empty($selItems) && is_array($selItems)) {
+				foreach ($selItems as $itemKey => $itemConf) {
+						// Option has no key, no manipulation possible
+					if (!isset($itemConf[1])) {
+						continue;
+					}
+
+						// Remove
+					foreach ($removeItems as $removeKey => $removeValue) {
+						if (strcasecmp($removeValue, $itemConf[1]) == 0) {
+							unset($selItems[$itemKey]);
+							unset($removeItems[$removeKey]);
+						}
+					}
+
+						// Rename
+					foreach ($renameItems as $renameKey => $renameValue) {
+						if (strcasecmp($renameKey, $itemConf[1]) == 0) {
+							$selItems[$itemKey][0] = $renameValue;
+							unset($renameItems[$renameKey]);
+						}
+					}
+				}
+			}
+
+			$field['TCEforms']['config']['items'] = $selItems;
+			$sheet[$fieldName] = $field;
+		}
+
+		return $sheet;
+	}
+
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_flexforms.php']) {
+	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_flexforms.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/stddb/tbl_be.php
===================================================================
--- t3lib/stddb/tbl_be.php	(Revision 9325)
+++ t3lib/stddb/tbl_be.php	(Arbeitskopie)
@@ -570,6 +570,7 @@
 				'maxitems' => 1000,
 				'autoSizeMax' => 50,
 				'renderMode' => $GLOBALS['TYPO3_CONF_VARS']['BE']['accessListRenderMode'],
+				'itemListStyle' => 'width:500px',
 			)
 		),
 		'explicit_allowdeny' => array(
Index: t3lib/class.t3lib_tceforms.php
===================================================================
--- t3lib/class.t3lib_tceforms.php	(Revision 9325)
+++ t3lib/class.t3lib_tceforms.php	(Arbeitskopie)
@@ -2468,6 +2468,13 @@
 			// Data Structure:
 		$dataStructArray = t3lib_BEfunc::getFlexFormDS($PA['fieldConf']['config'],$row,$table);
 
+			// Manipulate Flexform DS via TSConfig and group access lists
+		if (is_array($dataStructArray)) {
+			$flexFormHelper = t3lib_div::makeInstance('t3lib_TCEforms_Flexforms');
+			$dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row);
+			unset($flexFormHelper);
+		}
+
 			// Get data structure:
 		if (is_array($dataStructArray))	{
 
Index: t3lib/class.t3lib_extmgm.php
===================================================================
--- t3lib/class.t3lib_extmgm.php	(Revision 9325)
+++ t3lib/class.t3lib_extmgm.php	(Arbeitskopie)
@@ -114,7 +114,29 @@
 final class t3lib_extMgm {
 	protected static $extensionKeyMap;
 
+	/**
+	 * Speaking extension name stack
+	 *
+	 * @var array
+	 */
+	protected static $extensionNameMap;
 
+	/**
+	 * Remap table for FlexForm extension keys
+	 *
+	 * @var array
+	 */
+	protected static $realExtKeys = array(
+		'2'     => 'tt_board',
+		'3'     => 'tt_guest',
+		'4'     => 'tt_board',
+		'5'     => 'tt_products',
+		'9'     => 'tt_news',
+		'table' => 'css_styled_content',
+		'media' => 'cms',
+	);
+
+
 	/**************************************
 	 *
 	 * PATHS and other evaluation
@@ -240,6 +262,61 @@
 	}
 
 	/**
+	 * Returns the real extension key like 'tt_news' from a plugin table row
+	 * Usage: 1
+	 *
+	 * @param	array		Record data
+	 * @return	mixed		Real extension key (string) or false (boolean) if something went wrong
+	 */
+	public static function getExtensionKeyByPluginRecord(array $row) {
+		$dbFields = array('list_type', 'CType', 'pi_flexform');
+
+			// Search in record for extension key
+		foreach ($dbFields as $field) {
+			if (empty($row[$field])) {
+				continue;
+			}
+
+				// Get real extension key
+			if (!$rowKey = self::remapFlexFormExtKey($row[$field])) {
+				return FALSE;
+			}
+
+				// Check if extension key exists
+			foreach (array_keys($GLOBALS['TYPO3_LOADED_EXT']) as $extKey) {
+				if (strpos($rowKey, $extKey) !== FALSE) {
+					return $extKey;
+				}
+			}
+		}
+
+		return FALSE;
+	}
+
+	/**
+	 * Remap FlexForm extension keys with real keys
+	 * Usage: 2
+	 *
+	 * @param	string		Registered FlexForm extension key
+	 * @return	mixed		Real extension key (string) or false (boolean) if something went wrong
+	 */
+	public static function remapFlexFormExtKey($extKey) {
+		if (empty($extKey) || !is_string($extKey)) {
+			return FALSE;
+		}
+
+		$extKey = str_replace(array(',list', '*', ','), '', $extKey);
+
+			// Remap key
+		if (!empty($extKey) && !empty(self::$realExtKeys[$extKey])) {
+			return self::$realExtKeys[$extKey];
+		}
+
+			// No mapping required
+		return $extKey;
+	}
+
+	/**
 	 * Retrieves the version of an installed extension.
 	 * If the extension is not installed, this function returns an empty string.
 	 *
@@ -261,13 +338,53 @@
 		return $EM_CONF[$key]['version'];
 	}
 
+	/**
+	 * Get speaking extension name by key
+	 * Usage: 1
+	 *
+	 * @param	string		Extension key
+	 * @return	mixed		Real extension name (string) or false (boolean) if something went wrong
+	 */
+	public static function getExtensionName($extKey) {
+		if (empty($extKey) || !is_string($extKey)) {
+			return FALSE;
+		}
 
+			// Check stack first
+		if (!empty(self::$extensionNameMap[$extKey])) {
+			return self::$extensionNameMap[$extKey];
+		}
 
+			// Now try to get from TCA
+		if (!empty($GLOBALS['TCA'][$extKey]['ctrl']['title'])) {
+			return self::$extensionNameMap[$extKey] = $GLOBALS['LANG']->sl($GLOBALS['TCA'][$extKey]['ctrl']['title']);
+		}
 
+			// Finally try to get extension name from ext_emconf.php
+		$fileName = self::extPath($extKey) . 'ext_emconf.php';
+		if (!empty($fileName) && @is_file($fileName)) {
+			$_EXTKEY = $extKey;
+			$EM_CONF = array();
+			include_once($fileName);
 
+			if (!empty($EM_CONF[$extKey]['title'])) {
+				return self::$extensionNameMap[$extKey] = $EM_CONF[$extKey]['title'];
+			}
+		}
 
+		return FALSE;
+	}
 
+	/**
+	 * Clears the extension name map.
+	 *
+	 * @return	void
+	 */
+	public static function clearExtensionNameMap() {
+		self::$extensionNameMap = array();
+	}
 
+
 	/**************************************
 	 *
 	 *	 Adding BACKEND features
Index: t3lib/class.t3lib_transferdata.php
===================================================================
--- t3lib/class.t3lib_transferdata.php	(Revision 9325)
+++ t3lib/class.t3lib_transferdata.php	(Arbeitskopie)
@@ -498,6 +498,14 @@
 
 				// Get current value array:
 			$dataStructArray = t3lib_BEfunc::getFlexFormDS($fieldConfig['config'],$row,$table);
+
+				// Manipulate Flexform DS via TSConfig and group access lists
+			if (is_array($dataStructArray)) {
+				$flexFormHelper = t3lib_div::makeInstance('t3lib_TCEforms_Flexforms');
+				$dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row);
+				unset($flexFormHelper);
+			}
+
 			if (is_array($dataStructArray))	{
 				$currentValueArray['data'] = $this->renderRecord_flexProc_procInData($currentValueArray['data'],$dataStructArray,array($data,$fieldConfig,$TSconfig,$table,$row,$field));
 
Index: t3lib/class.t3lib_befunc.php
===================================================================
--- t3lib/class.t3lib_befunc.php	(Revision 9325)
+++ t3lib/class.t3lib_befunc.php	(Arbeitskopie)
@@ -752,11 +752,11 @@
 	}
 
 	/**
-	 * Returns an array with the exclude-fields as defined in TCA
+	 * Returns an array with the exclude-fields as defined in TCA and FlexForms
 	 * Used for listing the exclude-fields in be_groups forms
 	 * Usage: 2 (t3lib_tceforms + t3lib_transferdata)
 	 *
-	 * @return	array		Array of arrays with excludeFields (fieldname, table:fieldname) from all TCA entries
+	 * @return	array		Array of arrays with excludeFields (fieldname, table:fieldname) from all TCA entries and from FlexForms (fieldname, tt_content:extkey;sheetname;fieldname)
 	 */
 	public static function getExcludeFields() {
 		global $TCA;
@@ -779,6 +779,46 @@
 				}
 			}
 		}
+			// All FlexForm fields
+		$flexForms = self::getRegisteredFlexForms();
+		foreach ($flexForms as $extKey => $dataStruct) {
+			$extName = t3lib_extMgm::getExtensionName($extKey);
+				// Check for file reference
+			if (!is_array($dataStruct)) {
+				$file = t3lib_div::getFileAbsFileName(str_ireplace('FILE:', '', $dataStruct));
+				if ($file && @is_file($file)) {
+					$dataStruct = t3lib_div::getUrl($file);
+				}
+				$dataStruct = t3lib_div::xml2array($dataStruct);
+				if (!is_array($dataStruct)) {
+					continue;
+				}
+			}
+				// Get flexform content
+			$dataStruct = t3lib_div::resolveAllSheetsInDS($dataStruct);
+			if (empty($dataStruct['sheets']) || !is_array($dataStruct['sheets'])) {
+				continue;
+			}
+				// Get all fields in sheet
+			foreach ($dataStruct['sheets'] as $sheetName => $sheet) {
+				if (empty($sheet['ROOT']['el']) || !is_array($sheet['ROOT']['el'])) {
+					continue;
+				}
+				foreach ($sheet['ROOT']['el'] as $fieldName => $field) {
+						// Use only excludeable fields (not implemented yet because no flexform uses this until now)
+					/*if (empty($field['TCEforms']['exclude']) {
+						continue;
+					}*/
+					$fieldLabel = (!empty($field['TCEforms']['label']) ? $GLOBALS['LANG']->sl($field['TCEforms']['label']) : $fieldName);
+					$fieldIdent = 'tt_content:' . $extKey . ';' . $sheetName . ';' . $fieldName;
+					$theExcludeArray[] = array($extName . ': ' . $fieldLabel, $fieldIdent);
+				}
+			}
+		}
+
+			// Sort fields by label
+		usort($theExcludeArray, array(t3lib_div, 'compareArraysByFirstValue'));
+
 		return $theExcludeArray;
 	}
 
@@ -1212,11 +1252,46 @@
 		return $dataStructArray;
 	}
 
+	/**
+	 * Returns all registered FlexForm definitions per extension key
+	 * Usage: 1
+	 *
+	 * @return	mixed		The data structures were found and returned as an array with extension key as keys
+	 * @see t3lib_BEfunc::getExcludeFields()
+	 */
+	public static function getRegisteredFlexForms() {
+		if (empty($GLOBALS['TYPO3_LOADED_EXT']) || empty($GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds'])) {
+			return array();
+		}
 
+		$extKeys = array_keys($GLOBALS['TYPO3_LOADED_EXT']);
+		$result  = array();
 
+			// Get loaded flexforms
+		$loadedForms = $GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds'];
+		unset($loadedForms['default']);
 
+			// Get extensions with registered flexform
+		if (is_array($loadedForms)) {
+			foreach ($loadedForms as $flexKey => $dataStruct) {
+					// Get extension key
+				if (!$flexKey = t3lib_extMgm::remapFlexFormExtKey($flexKey)) {
+					continue;
+				}
 
+				// Check if extension key exists
+				foreach ($extKeys as $extKey) {
+					if (strpos($flexKey, $extKey) !== FALSE) {
+						$result[$extKey] = $dataStruct;
+						unset($extKeys[$extKey]);
+						break;
+					}
+				}
+			}
+		}
 
+		return $result;
+	}
 
 
 
Index: t3lib/core_autoload.php
===================================================================
--- t3lib/core_autoload.php	(Revision 9325)
+++ t3lib/core_autoload.php	(Arbeitskopie)
@@ -132,6 +132,7 @@
 	't3lib_matchcondition_backend' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_backend.php',
 	't3lib_matchcondition_frontend' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_frontend.php',
 	't3lib_pdohelper' => PATH_t3lib . 'class.t3lib_pdohelper.php',
+	't3lib_tceforms_flexforms' => PATH_t3lib . 'tceforms/class.t3lib_tceforms_flexforms.php',
 	't3lib_tceforms_suggest' => PATH_t3lib . 'tceforms/class.t3lib_tceforms_suggest.php',
 	't3lib_tceforms_suggest_defaultreceiver' => PATH_t3lib . 'tceforms/class.t3lib_tceforms_suggest_defaultreceiver.php',
 	't3lib_utility_client' => PATH_t3lib . 'utility/class.t3lib_utility_client.php',
Index: t3lib/class.t3lib_div.php
===================================================================
--- t3lib/class.t3lib_div.php	(Revision 9325)
+++ t3lib/class.t3lib_div.php	(Arbeitskopie)
@@ -2207,12 +2207,31 @@
 		return TRUE;
 	}
 
+	/**
+	 * Compare two arrays by their first value
+	 * Usage: 1
+	 *
+	 * @param	array		First array
+	 * @param	array		Second array
+	 * @return	integer		Negative int if first array is lower, zero if both are identical, and positive if second is higher
+	 */
+	public static function compareArraysByFirstValue(array $array1, array $array2) {
+		$array1 = reset($array1);
+		$array2 = reset($array2);
 
+		if (is_string($array1) && is_string($array2)) {
+			return strcasecmp($array1, $array2);
+		}
 
+		return 0;
+	}
 
 
 
 
+
+
+
 	/*************************
 	 *
 	 * HTML/XML PROCESSING
