Fixed bug #10086: Core uses deprecated function t3lib_db->sql()
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_tceforms.php
index 4a6316a..a34250d 100755 (executable)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -214,7 +214,7 @@ class t3lib_TCEforms        {
        var $loadMD5_JS=1;
        var $prevBorderStyle='[nothing here...]';       // Something unique...
        var $allowUpload=0;                             // If set direct upload fields will be shown
-       var $titleLen=15;                                       // @deprecated: $BE_USER->uc['titleLen'] but what is default??
+       var $titleLen=15;                                       // @deprecated since TYPO3 4.1: $BE_USER->uc['titleLen'] but what is default??
        var $defaultLanguageData = array();     // Array where records in the default language is stored. (processed by transferdata)
        var $defaultLanguageData_diff = array();        // Array where records in the default language is stored (raw without any processing. used for making diff)
        var $additionalPreviewLanguageData = array();
@@ -230,7 +230,6 @@ class t3lib_TCEforms        {
        var $localizationMode='';                       // If true, the forms are rendering only localization relevant fields of the records.
        var $fieldOrder='';                                     // Overrule the field order set in TCA[types][showitem], eg for tt_content this value, 'bodytext,image', would make first the 'bodytext' field, then the 'image' field (if set for display)... and then the rest in the old order.
        var $doPrintPalette=1;                          // If set to false, palettes will NEVER be rendered.
-       var $dividers2tabs=0;                           // Will be set to TCA[ctrl][dividers2tabs]
 
        /**
         * Set to initialized clipboard object; Then the element browser will offer a link to paste in records from clipboard.
@@ -292,6 +291,7 @@ class t3lib_TCEforms        {
        var $requiredFields=array();                            // Used to register input-field names, which are required. (Done during rendering of the fields). This information is then used later when the JavaScript is made.
        var $requiredAdditional=array();                        // Used to register input-field names, which are required an have additional requirements (e.g. like a date/time must be positive integer). The information of this array is merged with $this->requiredFields later.
        var $requiredElements=array();                          // Used to register the min and max number of elements for selectorboxes where that apply (in the "group" type for instance)
+       var $requiredNested=array();                            // Used to determine where $requiredFields or $requiredElements are nested (in Tabs or IRRE)
        var $renderDepth=0;                                                     // Keeps track of the rendering depth of nested records.
        var $savedSchemes=array();                                      // Color scheme buffer.
        var $dynNestedStack = array();                          // holds the path an element is nested in (e.g. required for RTEhtmlarea)
@@ -301,6 +301,7 @@ class t3lib_TCEforms        {
        var $additionalJS_pre = array();                        // Additional JavaScript, printed before the form
        var $additionalJS_post = array();                       // Additional JavaScript printed after the form
        var $additionalJS_submit = array();                     // Additional JavaScript executed on submit; If you set "OK" variable it will raise an error about RTEs not being loaded and offer to block further submission.
+       var $additionalJS_delete = array();                     // Additional JavaScript executed when section element is deleted. This is neceessary, for example, to correctly clean up HTMLArea RTE (bug #8232)
 
        /**
         * Instance of t3lib_tceforms_inline
@@ -355,11 +356,14 @@ class t3lib_TCEforms      {
                        'text' => array('cols', 'rows', 'wrap'),
                        'check' => array('cols', 'showIfRTE'),
                        'select' => array('size', 'autoSizeMax', 'maxitems', 'minitems'),
-                       'group' => array('size', 'autoSizeMax', 'max_size', 'show_thumbs', 'maxitems', 'minitems'),
-                       'inline' => array('appearance', 'foreign_label', 'foreign_selector', 'foreign_unique', 'maxitems', 'minitems', 'size', 'autoSizeMax', 'symmetric_label'),
+                       'group' => array('size', 'autoSizeMax', 'max_size', 'show_thumbs', 'maxitems', 'minitems', 'disable_controls'),
+                       'inline' => array('appearance', 'behaviour', 'foreign_label', 'foreign_selector', 'foreign_unique', 'maxitems', 'minitems', 'size', 'autoSizeMax', 'symmetric_label'),
                );
 
-               $this->inline = t3lib_div::makeInstance('t3lib_TCEforms_inline');
+                       // Create instance of t3lib_TCEforms_inline only if this a non-IRRE-AJAX call:
+               if (!isset($GLOBALS['ajaxID']) || strpos($GLOBALS['ajaxID'], 't3lib_TCEforms_inline::')!==0) {
+                       $this->inline = t3lib_div::makeInstance('t3lib_TCEforms_inline');
+               }
 
                        // Prepare user defined objects (if any) for hooks which extend this function:
                $this->hookObjectsMainFields = array();
@@ -391,7 +395,7 @@ class t3lib_TCEforms        {
                $this->edit_showFieldHelp = $BE_USER->uc['edit_showFieldHelp'];
 
                $this->edit_docModuleUpload = $BE_USER->uc['edit_docModuleUpload'];
-               $this->titleLen = $BE_USER->uc['titleLen'];             // @deprecated
+               $this->titleLen = $BE_USER->uc['titleLen'];             // @deprecated since TYPO3 4.1
 
                $this->inline->init($this);
        }
@@ -496,8 +500,8 @@ class t3lib_TCEforms        {
                                // Load the full TCA for the table.
                        t3lib_div::loadTCA($table);
 
-                       // Loads the dividers2tabs from the $TCA
-                       $this->dividers2tabs = $TCA[$table]['ctrl']['dividers2tabs'];
+                               // Get dividers2tabs setting from TCA of the current table:
+                       $dividers2tabs =& $TCA[$table]['ctrl']['dividers2tabs'];
 
                                // Load the description content for the table.
                        if ($this->edit_showFieldHelp || $this->doLoadTableDescr($table))       {
@@ -523,7 +527,7 @@ class t3lib_TCEforms        {
                                                // If TCEforms will render a tab menu in the next step, push the name to the tab stack:
                                        $tabIdentString = '';
                                        $tabIdentStringMD5 = '';
-                                       if (strstr($itemList, '--div--') !== false && $this->enableTabMenu && $this->dividers2tabs) {
+                                       if (strstr($itemList, '--div--') !== false && $this->enableTabMenu && $dividers2tabs) {
                                                $tabIdentString = 'TCEforms:'.$table.':'.$row['uid'];
                                                $tabIdentStringMD5 = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId($tabIdentString);
                                                        // Remember that were currently working on the general tab:
@@ -571,7 +575,7 @@ class t3lib_TCEforms        {
                                                                if ($cc>0)      {
                                                                        $out_array[$out_sheet][$out_pointer].=$this->getDivider();
 
-                                                                       if ($this->enableTabMenu && $this->dividers2tabs)       {
+                                                                       if ($this->enableTabMenu && $dividers2tabs) {
                                                                                $this->wrapBorder($out_array[$out_sheet],$out_pointer);
                                                                                        // Remove last tab entry from the dynNestedStack:
                                                                                $out_sheet++;
@@ -654,7 +658,7 @@ class t3lib_TCEforms        {
                                if ($content) {
                                        // Wrap content (row) with table-tag, otherwise tab/sheet will be disabled (see getdynTabMenu() )
                                        $content = '<table border="0" cellspacing="0" cellpadding="0" width="100%">'.$content.'</table>';
-                               }
+                               }
                                $parts[$idx] = array(
                                        'label' => $out_array_meta[$idx]['title'],
                                        'content' => $content,
@@ -665,8 +669,8 @@ class t3lib_TCEforms        {
                        if (count($parts) > 1) {
                                        // Unset the current level of tab menus:
                                $this->popFromDynNestedStack('tab', $tabIdentStringMD5.'-'.($out_sheet+1));
-
-                               $output = $this->getDynTabMenu($parts, $tabIdentString);
+                               $dividersToTabsBehaviour = (isset($TCA[$table]['ctrl']['dividers2tabs']) ? $TCA[$table]['ctrl']['dividers2tabs'] : 1);
+                               $output = $this->getDynTabMenu($parts, $tabIdentString, $dividersToTabsBehaviour);
 
                        } else {
                                        // If there is only one tab/part there is no need to wrap it into the dynTab code
@@ -740,7 +744,7 @@ class t3lib_TCEforms        {
         * @param       string          Optional Link text for activating a palette (when palettes does not have another form element to belong to).
         * @return      string          HTML code.
         */
-       function getPaletteFields($table,$row,$palette,$header='',$itemList='',$collapsedHeader='')     {
+       function getPaletteFields($table,$row,$palette,$header='',$itemList='',$collapsedHeader=NULL)   {
                if (!$this->doPrintPalette)     {
                        return '';
                }
@@ -756,9 +760,19 @@ class t3lib_TCEforms       {
                                                $this->palFieldTemplateHeader
                                        );
                        }
+
                        $collapsed = $this->isPalettesCollapsed($table,$palette);
+
+                       $thePalIcon = '';
+                       if ($collapsed && $collapsedHeader !== NULL) {
+                               list($thePalIcon,) = $this->wrapOpenPalette('<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/options.gif','width="18" height="16"').' border="0" title="'.htmlspecialchars($this->getLL('l_moreOptions')).'" alt="" />',$table,$row,$palette,1);
+                               $thePalIcon = '<span style="margin-left: 20px;">' . $thePalIcon . $collapsedHeader . '</span>';
+                       }
+
+                       $paletteHtml = $this->wrapPaletteField($this->printPalette($parts), $table, $row ,$palette, $collapsed);
+
                        $out .= $this->intoTemplate(
-                                       array('PALETTE' => $this->wrapPaletteField($this->printPalette($parts), $table, $row ,$palette, $collapsed)),
+                                       array('PALETTE' => $thePalIcon . $paletteHtml),
                                        $this->palFieldTemplate
                                );
                }
@@ -961,6 +975,13 @@ class t3lib_TCEforms       {
        function getSingleField_SW($table,$field,$row,&$PA)     {
                $PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type'];       // Using "form_type" locally in this script
 
+               // Hook: getSingleField_beforeRender
+               foreach ($this->hookObjectsSingleField as $hookObject) {
+                       if (method_exists($hookObject, 'getSingleField_beforeRender')) {
+                               $hookObject->getSingleField_beforeRender($table, $field, $row, $PA);
+                       }
+               }
+
                switch($PA['fieldConf']['config']['form_type']) {
                        case 'input':
                                $item = $this->getSingleField_typeInput($table,$field,$row,$PA);
@@ -1065,7 +1086,7 @@ class t3lib_TCEforms      {
                foreach ($evalList as $func) {
                        switch ($func) {
                                case 'required':
-                                       $this->requiredFields[$table.'_'.$row['uid'].'_'.$field]=$PA['itemFormElName'];
+                                       $this->registerRequiredProperty('field', $table.'_'.$row['uid'].'_'.$field, $PA['itemFormElName']);
                                                // Mark this field for date/time disposal:
                                        if (array_intersect($evalList, array('date', 'datetime', 'time'))) {
                                                 $this->requiredAdditional[$PA['itemFormElName']]['isPositiveNumber'] = true;
@@ -1098,12 +1119,11 @@ class t3lib_TCEforms    {
                                $checkSetValue = gmdate('Y');
                        }
                        $cOnClick = 'typo3form.fieldGet('.$paramsList.',1,\''.$checkSetValue.'\');'.implode('',$PA['fieldChangeFunc']);
-                       $item.='<input type="checkbox"'.$this->insertDefStyle('check').' name="'.$PA['itemFormElName'].'_cb" onclick="'.htmlspecialchars($cOnClick).'" />';
+                       $item .= '<input type="checkbox" class="' . $this->formElStyleClassValue('check', TRUE) . ' alignToInputText" name="' . $PA['itemFormElName'] . '_cb" onclick="' . htmlspecialchars($cOnClick) . '" />';
                }
-               if((in_array('date',$evalList) || in_array('datetime',$evalList)) && $PA['itemFormElValue']>0){
+               if ((in_array('date',$evalList) || in_array('datetime',$evalList)) && $PA['itemFormElValue']>0){
                                // Add server timezone offset to UTC to our stored date
-                       $hoursOffset = date('O',$PA['itemFormElValue'])/100;
-                       $PA['itemFormElValue'] += ($hoursOffset*60*60);
+                       $PA['itemFormElValue'] += date('Z', $PA['itemFormElValue']);
                }
 
                $PA['fieldChangeFunc'] = array_merge(array('typo3form.fieldGet'=>'typo3form.fieldGet('.$paramsList.');'), $PA['fieldChangeFunc']);
@@ -1242,6 +1262,27 @@ class t3lib_TCEforms     {
                                        $class = ' class="'.implode(' ',$classes).'"';
                                } else $class='';
 
+                               $evalList = t3lib_div::trimExplode(',',$config['eval'],1);
+                               foreach ($evalList as $func) {
+                                       switch ($func) {
+                                               case 'required':
+                                                       $this->registerRequiredProperty('field', $table.'_'.$row['uid'].'_'.$field, $PA['itemFormElName']);
+                                                       break;
+                                               default:
+                                                       if (substr($func, 0, 3) == 'tx_')       {
+                                                               // Pair hook to the one in t3lib_TCEmain::checkValue_input_Eval() and t3lib_TCEmain::checkValue_text_Eval()
+                                                               $evalObj = t3lib_div::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$func].':&'.$func);
+                                                               if (is_object($evalObj) && method_exists($evalObj, 'deevaluateFieldValue'))     {
+                                                                       $_params = array(
+                                                                               'value' => $PA['itemFormElValue']
+                                                                       );
+                                                                       $PA['itemFormElValue'] = $evalObj->deevaluateFieldValue($_params);
+                                                               }
+                                                       }
+                                                       break;
+                                       }
+                               }
+
                                $iOnChange = implode('',$PA['fieldChangeFunc']);
                                $item.= '
                                                        <textarea name="'.$PA['itemFormElName'].'"'.$formWidthText.$class.' rows="'.$rows.'" wrap="'.$wrap.'" onchange="'.htmlspecialchars($iOnChange).'"'.$PA['onFocus'].'>'.
@@ -1313,7 +1354,7 @@ class t3lib_TCEforms      {
                                $cBID = $PA['itemFormElID'].'_'.$c;
                                $item.= ($c>0?'<br />':'').
                                                '<input type="checkbox"'.$this->insertDefStyle('check').' value="1" name="'.$cBName.'"'.$cBP.$PA['onFocus'].$disabled.' id="'.$cBID.'" />'.
-                                               htmlspecialchars($p[0]);
+                                               $this->wrapLabels('<label for="'.$cBID.'">'.htmlspecialchars($p[0]).'</label>');
                        }
                }
                if (!$disabled) {
@@ -1384,9 +1425,21 @@ class t3lib_TCEforms     {
                $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
 
                        // Getting the selector box items from the system
-               $selItems = $this->addSelectOptionsToItemArray($this->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->setTSconfig($table,$row),$field);
-               $selItems = $this->addItems($selItems,$PA['fieldTSConfig']['addItems.']);
-               if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
+               $selItems = $this->addSelectOptionsToItemArray(
+                       $this->initItemArray($PA['fieldConf']),
+                       $PA['fieldConf'],
+                       $this->setTSconfig($table, $row),
+                       $field
+               );
+                       // Possibly filter some items:
+               $keepItemsFunc = create_function('$value', 'return $value[1];');
+               $selItems = t3lib_div::keepItemsInArray($selItems, $PA['fieldTSConfig']['keepItems'], $keepItemsFunc);
+                       // Possibly add some items:
+               $selItems = $this->addItems($selItems, $PA['fieldTSConfig']['addItems.']);
+                       // Process items by a user function:
+               if (isset($config['itemsProcFunc']) && $config['itemsProcFunc']) {
+                       $selItems = $this->procItems($selItems, $PA['fieldTSConfig']['itemsProcFunc.'], $config, $table, $row, $field);
+               }
 
                        // Possibly remove some items:
                $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
@@ -1471,6 +1524,7 @@ class t3lib_TCEforms      {
                $selicons = array();
                $onlySelectedIconShown = 0;
                $size = intval($config['size']);
+               $selectedStyle = ''; // Style set on <select/>
 
                $disabled = '';
                if($this->renderReadonly || $config['readOnly'])  {
@@ -1489,6 +1543,7 @@ class t3lib_TCEforms      {
                } else $suppressIcons = 0;
 
                        // Traverse the Array of selector box items:
+               $optGroupStart = array();
                foreach($selItems as $p)        {
                        $sM = (!strcmp($PA['itemFormElValue'],$p[1])?' selected="selected"':'');
                        if ($sM)        {
@@ -1499,23 +1554,36 @@ class t3lib_TCEforms    {
                                // Getting style attribute value (for icons):
                        if ($config['iconsInOptionTags'])       {
                                $styleAttrValue = $this->optionTagStyle($p[2]);
+                               if ($sM) {
+                                       list($selectIconFile,$selectIconInfo) = $this->getIcon($p[2]);
+                                               if (!empty($selectIconInfo)) {
+                                                       $selectedStyle = ' style="background-image: url('.$selectIconFile.'); background-repeat: no-repeat; background-position: 0% 50%; padding: 1px; padding-left: 24px; -webkit-background-size: 0;"';
+                                               }
+                               }
                        }
 
                                // Compiling the <option> tag:
                        if (!($p[1] != $PA['itemFormElValue'] && is_array($uniqueIds) && in_array($p[1], $uniqueIds))) {
                                if(!strcmp($p[1],'--div--')) {
-                                       if($optGroupOpen) { // Closing last optgroup before next one starts
-                                               $opt[]='</optgroup>';
-                                       }
-                                       $opt[]= '<optgroup label="'.t3lib_div::deHSCentities(htmlspecialchars($p[0])).'"'.
-                                                       ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
-                                                       ' class="c-divider">';
-                                       $optGroupOpen = true;
+                                       $optGroupStart[0] = $p[0];
+                                       $optGroupStart[1] = $styleAttrValue;
+
                                } else {
+                                       if (count($optGroupStart)) {
+                                               if($optGroupOpen) { // Closing last optgroup before next one starts
+                                                       $opt[]='</optgroup>' . "\n";
+                                               }
+                                               $opt[]= '<optgroup label="'.t3lib_div::deHSCentities(htmlspecialchars($optGroupStart[0])).'"'.
+                                                               ($optGroupStart[1] ? ' style="'.htmlspecialchars($optGroupStart[1]).'"' : '').
+                                                               ' class="c-divider">' . "\n";
+                                               $optGroupOpen = true;
+                                               $c--;
+                                               $optGroupStart = array();
+                                       }
                                        $opt[]= '<option value="'.htmlspecialchars($p[1]).'"'.
                                                        $sM.
                                                        ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
-                                                       '>'.t3lib_div::deHSCentities(htmlspecialchars($p[0])).'</option>';
+                                                       '>'.t3lib_div::deHSCentities(htmlspecialchars($p[0])).'</option>' . "\n";
                                }
                        }
 
@@ -1548,11 +1616,12 @@ class t3lib_TCEforms    {
                if(!$disabled) {
                        $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_selIconVal" value="'.htmlspecialchars($sI).'" />';        // MUST be inserted before the selector - else is the value of the hiddenfield here mysteriously submitted...
                }
-               $item.= '<select name="'.$PA['itemFormElName'].'"'.
-                                       $this->insertDefStyle('select').
-                                       ($size?' size="'.$size.'"':'').
-                                       ' onchange="'.htmlspecialchars($sOnChange).'"'.
-                                       $PA['onFocus'].$disabled.'>';
+               $item .= '<select' . $selectedStyle . ' name="' . $PA['itemFormElName'] . '"' .
+                                       ($config['iconsInOptionTags'] ? ' class="icon-select"' : '') .
+                                       $this->insertDefStyle('select') .
+                                       ($size ? ' size="' . $size . '"' : '') .
+                                       ' onchange="' . htmlspecialchars($sOnChange) . '"' .
+                                       $PA['onFocus'] . $disabled . '>';
                $item.= implode('',$opt);
                $item.= '</select>';
 
@@ -1615,18 +1684,22 @@ class t3lib_TCEforms    {
                                if (!strcmp($p[1],'--div--'))   {
                                        if (count($setAll))     {
                                                        $tRows[] = '
-                                                               <tr>
-                                                                       <td colspan="2">'.
-                                                                       '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
-                                                                       htmlspecialchars($this->getLL('l_setAllCheckboxes')).
-                                                                       '</a></td>
+                                                               <tr class="c-header-checkbox-controls">
+                                                                       <td colspan="3">' .
+                                                                               '<a href="#" onclick="' . htmlspecialchars(implode('', $setAll).' return false;') . '">' .
+                                                                               htmlspecialchars($this->getLL('l_checkAll')) .
+                                                                               '</a>
+                                                                               <a href="#" onclick="' . htmlspecialchars(implode('', $unSetAll).' return false;').'">' .
+                                                                               htmlspecialchars($this->getLL('l_uncheckAll')) .
+                                                                               '</a>
+                                                                       </td>
                                                                </tr>';
                                                        $setAll = array();
                                        }
 
                                        $tRows[] = '
                                                <tr class="c-header">
-                                                       <td colspan="2">'.htmlspecialchars($p[0]).'</td>
+                                                       <td colspan="3">'.htmlspecialchars($p[0]).'</td>
                                                </tr>';
                                } else {
                                                // Selected or not by default:
@@ -1643,17 +1716,39 @@ class t3lib_TCEforms    {
                                        }
 
                                                // Compile row:
-                                       $onClickCell = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=!'.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked;';
-                                       $onClick = 'this.attributes.getNamedItem("class").nodeValue = '.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked ? "c-selectedItem" : "";';
-                                       $setAll[] = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=1;';
+                                       $rowId = uniqid('select_checkbox_row_');
+                                       $onClickCell = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=!' . $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked;';
+                                       $onClick = 'this.attributes.getNamedItem("class").nodeValue = ' . $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked ? "c-selectedItem" : "c-unselectedItem";';
+                                       $setAll[] = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=1;';
+                                       $setAll[] .= '$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');$(\'' . $rowId . '\').addClassName(\'c-selectedItem\');';
+                                       $unSetAll[] = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=0;';
+                                       $unSetAll[] .= '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').addClassName(\'c-unselectedItem\');';
+                                       $restoreCmd[] = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=' . ($sM ? 1 : 0) . ';' .
+                                                               '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');' .
+                                                               '$(\'' . $rowId . '\').addClassName(\'c-' . ($sM ? '' : 'un') . 'selectedItem\');';
+
+                                       $hasHelp = ($p[3] !='');
+
+                                       $label = t3lib_div::deHSCentities(htmlspecialchars($p[0]));
+                                       $help = $hasHelp ? '<span class="typo3-csh-inline show-right"><span class="header">' . $label . '</span>' .
+                                               '<span class="paragraph">' . $GLOBALS['LANG']->hscAndCharConv(nl2br(trim(htmlspecialchars($p[3]))), false) . '</span></span>' : '';
+
+                                       if ($hasHelp && $this->edit_showFieldHelp == 'icon') {
+                                               $helpIcon  = '<a class="typo3-csh-link" href="#">';
+                                               $helpIcon .= '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/helpbubble.gif', 'width="14" height="14"');
+                                               $helpIcon .= ' hspace="2" border="0" class="absmiddle"' . ($GLOBALS['CLIENT']['FORMSTYLE'] ? ' style="cursor:help;"' : '') . ' alt="" />' . $help;
+                                               $helpIcon .= '</a>';
+                                               $help = $helpIcon;
+                                       }
+
                                        $tRows[] = '
-                                               <tr class="'.($sM ? 'c-selectedItem' : '').'" onclick="'.htmlspecialchars($onClick).'" style="cursor: pointer;">
-                                                       <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($p[1]).'"'.$sM.' onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].' /></td>
+                                               <tr id="' . $rowId . '" class="'.($sM ? 'c-selectedItem' : 'c-unselectedItem').'" onclick="'.htmlspecialchars($onClick).'" style="cursor: pointer;">
+                                                       <td width="12"><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($p[1]).'"'.$sM.' onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].' /></td>
                                                        <td class="c-labelCell" onclick="'.htmlspecialchars($onClickCell).'">'.
                                                                ($selIconFile ? '<img src="'.$selIconFile.'" '.$selIconInfo[3].' vspace="2" border="0" class="absmiddle" style="margin-right: 4px;" alt="" />' : '').
-                                                               t3lib_div::deHSCentities(htmlspecialchars($p[0])).
-                                                               (strcmp($p[3],'') ? '<br/><p class="c-descr">'.nl2br(trim(htmlspecialchars($p[3]))).'</p>' : '').
+                                                               $label .
                                                                '</td>
+                                                               <td class="c-descr" onclick="'.htmlspecialchars($onClickCell).'">' . (strcmp($p[3],'') ? $help : '') . '</td>
                                                </tr>';
                                        $c++;
                                }
@@ -1662,11 +1757,15 @@ class t3lib_TCEforms    {
                                // Remaining checkboxes will get their set-all link:
                        if (count($setAll))     {
                                        $tRows[] = '
-                                               <tr>
-                                                       <td colspan="2">'.
-                                                       '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
-                                                       htmlspecialchars($this->getLL('l_setAllCheckboxes')).
-                                                       '</a></td>
+                                               <tr class="c-header-checkbox-controls">
+                                                       <td colspan="3">'.
+                                                               '<a href="#" onclick="' . htmlspecialchars(implode('', $setAll).' return false;') . '">' .
+                                                               htmlspecialchars($this->getLL('l_checkAll')) .
+                                                               '</a>
+                                                               <a href="#" onclick="' . htmlspecialchars(implode('', $unSetAll).' return false;') . '">' .
+                                                               htmlspecialchars($this->getLL('l_uncheckAll')) .
+                                                               '</a>
+                                                       </td>
                                                </tr>';
                        }
                }
@@ -1680,17 +1779,23 @@ class t3lib_TCEforms    {
                                                        <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($theNoMatchValue).'" checked="checked" onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].$disabled.' /></td>
                                                        <td class="c-labelCell">'.
                                                                t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))).
-                                                               '</td>
+                                                               '</td><td>&nbsp;</td>
                                                </tr>');
                                $c++;
                        }
                }
 
                        // Add an empty hidden field which will send a blank value if all items are unselected.
-               $item.='<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="" />';
+               $item .= '<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']) . '" value="" />';
 
+                       // Add revert icon
+               if (is_array($restoreCmd)) {
+                       $item .= '<a href="#" onclick="' . implode('', $restoreCmd).' return false;' . '">' .
+                               '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/undo.gif','width="13" height="12"') . ' title="' .
+                               htmlspecialchars($this->getLL('l_revertSelection')) . '" alt="" />' .'</a>';
+               }
                        // Implode rows in table:
-               $item.= '
+               $item .= '
                        <table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-select-checkbox">'.
                                implode('',$tRows).'
                        </table>
@@ -1799,7 +1904,7 @@ class t3lib_TCEforms      {
                                        </td>
                                        <td valign="top">
                                        <a href="#" onclick="'.htmlspecialchars($this->elName($PA['itemFormElName'].'[]').'.selectedIndex=-1;'.implode('',$restoreCmd).' return false;').'">'.
-                                               '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/history.gif','width="13" height="12"').' title="'.htmlspecialchars($this->getLL('l_revertSelection')).'" alt="" />'.
+                                               '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/undo.gif','width="13" height="12"').' title="'.htmlspecialchars($this->getLL('l_revertSelection')).'" alt="" />'.
                                                '</a>
                                        </td>
                                </tr>
@@ -1841,13 +1946,19 @@ class t3lib_TCEforms    {
                $minitems = t3lib_div::intInRange($config['minitems'],0);
 
                        // Register the required number of elements:
-               $this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
+               $this->registerRequiredProperty('range', $PA['itemFormElName'], array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field));
 
                        // Get "removeItems":
                $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
 
+                       // Get the array with selected items:
+               $itemArray = t3lib_div::trimExplode(',', $PA['itemFormElValue'], 1);
+
+                       // Possibly filter some items:
+               $keepItemsFunc = create_function('$value', '$parts=explode(\'|\',$value,2); return rawurldecode($parts[0]);');
+               $itemArray = t3lib_div::keepItemsInArray($itemArray, $PA['fieldTSConfig']['keepItems'], $keepItemsFunc);
+
                        // Perform modification of the selected items array:
-               $itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
                foreach($itemArray as $tk => $tv) {
                        $tvP = explode('|',$tv,2);
                        $evalValue = rawurldecode($tvP[0]);
@@ -1936,8 +2047,8 @@ class t3lib_TCEforms      {
                $maxitems = t3lib_div::intInRange($config['maxitems'],0);
                if (!$maxitems) $maxitems=100000;
                $minitems = t3lib_div::intInRange($config['minitems'],0);
-               $allowed = $config['allowed'];
-               $disallowed = $config['disallowed'];
+               $allowed = trim($config['allowed']);
+               $disallowed = trim($config['disallowed']);
 
                $disabled = '';
                if($this->renderReadonly || $config['readOnly'])  {
@@ -1945,7 +2056,7 @@ class t3lib_TCEforms      {
                }
 
                $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'"'.$disabled.' />';
-               $this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
+               $this->registerRequiredProperty('range', $PA['itemFormElName'], array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field));
                $info='';
 
                        // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/.
@@ -2022,22 +2133,50 @@ class t3lib_TCEforms    {
                                        if ($this->edit_docModuleUpload)        $item.='<input type="file" name="'.$PA['itemFormElName_file'].'"'.$this->formWidth().' size="60" />';
                                }
                        break;
+                       case 'folder':  // If the element is of the internal type "folder":
+
+                                       // array of folder items:
+                               $itemArray = t3lib_div::trimExplode(',', $PA['itemFormElValue'], 1);
+
+                                       // Creating the element:
+                               $params = array(
+                                       'size'              => $size,
+                                       'dontShowMoveIcons' => ($maxitems <= 1),
+                                       'autoSizeMax'       => t3lib_div::intInRange($config['autoSizeMax'], 0),
+                                       'maxitems'          => $maxitems,
+                                       'style'             => isset($config['selectedListStyle']) ?
+                                                       ' style="'.htmlspecialchars($config['selectedListStyle']).'"'
+                                               :       ' style="'.$this->defaultMultipleSelectorStyle.'"',
+                                       'info'              => $info,
+                                       'readOnly'          => $disabled
+                               );
+
+                               $item.= $this->dbFileIcons(
+                                       $PA['itemFormElName'],
+                                       'folder',
+                                       '',
+                                       $itemArray,
+                                       '',
+                                       $params,
+                                       $PA['onFocus']
+                               );
+                       break;
                        case 'db':      // If the element is of the internal type "db":
 
                                        // Creating string showing allowed types:
-                               $tempFT = t3lib_div::trimExplode(',',$allowed,1);
-                               if (!strcmp(trim($tempFT[0]),'*'))      {
+                               $tempFT = t3lib_div::trimExplode(',', $allowed, true);
+                               if (!strcmp(trim($tempFT[0]), '*')) {
+                                       $onlySingleTableAllowed = false;
                                        $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
                                                        htmlspecialchars($this->getLL('l_allTables')).
                                                        '</span><br />';
-                               } else {
-                                       while(list(,$theT)=each($tempFT))       {
-                                               if ($theT)      {
-                                                       $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
-                                                                       t3lib_iconWorks::getIconImage($theT,array(),$this->backPath,'align="top"').
-                                                                       htmlspecialchars($this->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])).
-                                                                       '</span><br />';
-                                               }
+                               } elseif ($tempFT) {
+                                       $onlySingleTableAllowed = (count($tempFT) == 1);
+                                       foreach ($tempFT as $theT) {
+                                               $info.= '<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;' .
+                                                               t3lib_iconWorks::getIconImage($theT, array(), $this->backPath, 'align="top"') .
+                                                               htmlspecialchars($this->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])) .
+                                                               '</span><br />';
                                        }
                                }
 
@@ -2050,6 +2189,10 @@ class t3lib_TCEforms     {
                                foreach($temp_itemArray as $dbRead)     {
                                        $recordParts = explode('|',$dbRead);
                                        list($this_table,$this_uid) = t3lib_BEfunc::splitTable_Uid($recordParts[0]);
+                                       // For the case that no table was found and only a single table is defined to be allowed, use that one:
+                                       if (!$this_table && $onlySingleTableAllowed) {
+                                               $this_table = $allowed;
+                                       }
                                        $itemArray[] = array('table'=>$this_table, 'id'=>$this_uid);
                                        if (!$disabled && $show_thumbs) {
                                                $rr = t3lib_BEfunc::getRecordWSOL($this_table,$this_uid);
@@ -2293,7 +2436,8 @@ class t3lib_TCEforms      {
                                }
 
                                if (is_array($dataStructArray['sheets']))       {
-                                       $item.= $this->getDynTabMenu($tabParts,'TCEFORMS:flexform:'.$PA['itemFormElName'].$PA['_lang']);
+                                       $dividersToTabsBehaviour = (isset($GLOBALS['TCA'][$table]['ctrl']['dividers2tabs']) ? $GLOBALS['TCA'][$table]['ctrl']['dividers2tabs'] : 1);
+                                       $item.= $this->getDynTabMenu($tabParts, 'TCEFORMS:flexform:'.$PA['itemFormElName'].$PA['_lang'], $dividersToTabsBehaviour);
                                } else {
                                        $item.= $sheetContent;
                                }
@@ -2393,6 +2537,8 @@ class t3lib_TCEforms      {
                                                        // If it's a "section" containing other elements:
                                                if ($value['section'])  {
 
+                                                               // Load script.aculo.us if flexform sections can be moved by drag'n'drop:
+                                                       $this->loadJavascriptLib('contrib/scriptaculous/scriptaculous.js');
                                                                // Render header of section:
                                                        $output.= '<div class="bgColor2"><strong>'.$theTitle.'</strong></div>';
 
@@ -2433,6 +2579,10 @@ class t3lib_TCEforms     {
                                                                // Traversing possible types of new content in the section:
                                                        $newElementsLinks = array();
                                                        foreach($value['el'] as $nnKey => $nCfg)        {
+                                                               $additionalJS_post_saved = $this->additionalJS_post;
+                                                               $this->additionalJS_post = array();
+                                                               $additionalJS_submit_saved = $this->additionalJS_submit;
+                                                               $this->additionalJS_submit = array();
                                                                $newElementTemplate = $this->getSingleField_typeFlex_draw(
                                                                        array($nnKey => $nCfg),
                                                                        array(),
@@ -2446,7 +2596,17 @@ class t3lib_TCEforms     {
                                                                );
 
                                                                        // Makes a "Add new" link:
-                                                               $onClickInsert = 'new Insertion.Bottom($("'.$idTagPrefix.'"), unescape("'.rawurlencode($newElementTemplate).'").replace(/'.$idTagPrefix.'-/g,"'.$idTagPrefix.'-idx"+Math.floor(Math.random()*100000+1)+"-")); setActionStatus("'.$idTagPrefix.'"); return false;';      // Maybe there is a better way to do this than store the HTML for the new element in rawurlencoded format - maybe it even breaks with certain charsets? But for now this works...
+                                                               $var = uniqid('idvar');
+                                                               $replace = 'replace(/' . $idTagPrefix . '-/g,"' . $idTagPrefix . '"+' . $var . '+"-")';
+                                                               $onClickInsert = 'var ' . $var . ' = "' . $idTagPrefix . '-idx"+(new Date()).getTime();';
+                                                               // Do not replace $isTagPrefix in setActionStatus() because it needs section id!
+                                                               $onClickInsert .= 'new Insertion.Bottom($("'.$idTagPrefix.'"), unescape("'.rawurlencode($newElementTemplate).'").' . $replace . '); setActionStatus("'.$idTagPrefix.'");';
+                                                               $onClickInsert .= 'eval(unescape("' . rawurlencode(implode(';', $this->additionalJS_post)) . '").' . $replace . ');';
+                                                               $onClickInsert .= 'TBE_EDITOR.addActionChecks("submit", unescape("' . rawurlencode(implode(';', $this->additionalJS_submit)) . '").' . $replace . ');';
+                                                               $onClickInsert .= 'return false;';
+                                                               // Kasper's comment (kept for history): Maybe there is a better way to do this than store the HTML for the new element in rawurlencoded format - maybe it even breaks with certain charsets? But for now this works...
+                                                               $this->additionalJS_post = $additionalJS_post_saved;
+                                                               $this->additionalJS_submit = $additionalJS_submit_saved;
                                                                $newElementsLinks[]= '<a href="#" onclick="'.htmlspecialchars($onClickInsert).'"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/new_el.gif','width="11" height="12"').' alt="New" title="New" align="absmiddle" />'.htmlspecialchars(t3lib_div::fixed_lgd_cs($this->sL($nCfg['tx_templavoila']['title']),30)).'</a>';
                                                        }
 
@@ -2463,15 +2623,15 @@ class t3lib_TCEforms    {
 
                                                        <div id="'.$idTagPrefix.'" style="padding-left: 20px;">'.implode('',$tRows).'</div>';
                                                        $output.= $mayRestructureFlexforms ? '<div style="padding: 10px 5px 5px 20px;"><b>Add new:</b> '.implode(' | ',$newElementsLinks).'</div>' : '';
-                                                       // If it's a container:
                                                } else {
+                                                       // It is a container
 
                                                        $toggleIcon_open = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/pil2down.gif','width="12" height="7"').' hspace="2" alt="Open" title="Open" />';
                                                        $toggleIcon_close = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/pil2right.gif','width="7" height="12"').' hspace="2" alt="Close" title="Close" />';
 
                                                                // Create on-click actions.
-                                               #       $onClickCopy = 'new Insertion.After($("'.$idTagPrefix.'"), getOuterHTML("'.$idTagPrefix.'").replace(/'.$idTagPrefix.'-/g,"'.$idTagPrefix.'-copy"+Math.floor(Math.random()*100000+1)+"-")); return false;';      // Copied elements doesn't work (well) in Safari while they do in Firefox and MSIE! UPDATE: It turned out that copying doesn't work for any browser, simply because the data from the copied form never gets submitted to the server for some reason! So I decided to simply disable copying for now. If it's requested by customers we can look to enable it again and fix the issue. There is one un-fixable problem though; Copying an element like this will violate integrity if files are attached inside that element because the file reference doesn't get an absolute path prefixed to it which would be required to have TCEmain generate a new copy of the file.
-                                                       $onClickRemove = 'if (confirm("Are you sure?")){$("'.$idTagPrefix.'").hide();setActionStatus("'.$idPrefix.'");} return false;';
+                                                       //$onClickCopy = 'new Insertion.After($("'.$idTagPrefix.'"), getOuterHTML("'.$idTagPrefix.'").replace(/'.$idTagPrefix.'-/g,"'.$idTagPrefix.'-copy"+Math.floor(Math.random()*100000+1)+"-")); return false;';    // Copied elements doesn't work (well) in Safari while they do in Firefox and MSIE! UPDATE: It turned out that copying doesn't work for any browser, simply because the data from the copied form never gets submitted to the server for some reason! So I decided to simply disable copying for now. If it's requested by customers we can look to enable it again and fix the issue. There is one un-fixable problem though; Copying an element like this will violate integrity if files are attached inside that element because the file reference doesn't get an absolute path prefixed to it which would be required to have TCEmain generate a new copy of the file.
+                                                       $onClickRemove = 'if (confirm("Are you sure?")){/*###REMOVE###*/;$("'.$idTagPrefix.'").hide();setActionStatus("'.$idPrefix.'");} return false;';
                                                        $onClickToggle = 'flexFormToggle("'.$idTagPrefix.'"); return false;';
 
                                                        $onMove = 'flexFormSortable("'.$idPrefix.'")';
@@ -2502,6 +2662,7 @@ class t3lib_TCEforms      {
                                                        $actionFieldName = '_ACTION_FLEX_FORM'.$PA['itemFormElName'].$s[0].'][_ACTION]['.$s[1];
 
                                                                // Putting together the container:
+                                                       $this->additionalJS_delete = array();
                                                        $output.= '
                                                                <div id="'.$idTagPrefix.'" class="bgColor2">
                                                                        <input id="'.$idTagPrefix.'-action" type="hidden" name="'.htmlspecialchars($actionFieldName).'" value=""/>
@@ -2521,6 +2682,7 @@ class t3lib_TCEforms      {
                                                                        </div>
                                                                        <input id="'.$idTagPrefix.'-toggleClosed" type="hidden" name="'.htmlspecialchars('data['.$table.']['.$row['uid'].']['.$field.']'.$formPrefix.'[_TOGGLE]').'" value="'.($toggleClosed?1:0).'" />
                                                                </div>';
+                                                       $output = str_replace('/*###REMOVE###*/', t3lib_div::slashJS(htmlspecialchars(implode('', $this->additionalJS_delete))), $output);
                                                                        // NOTICE: We are saving the toggle-state directly in the flexForm XML and "unauthorized" according to the data structure. It means that flexform XML will report unclean and a cleaning operation will remove the recorded togglestates. This is not a fatal problem. Ideally we should save the toggle states in meta-data but it is much harder to do that. And this implementation was easy to make and with no really harmful impact.
                                                }
 
@@ -2962,7 +3124,7 @@ class t3lib_TCEforms      {
                                }
                                        // Override TCA field config by remaining TSconfig['config']:
                                if (count($TSconfig['config'])) {
-                                       $fieldConfig = array_merge($fieldConfig, $TSconfig['config']);
+                                       $fieldConfig = t3lib_div::array_merge_recursive_overrule($fieldConfig, $TSconfig['config']);
                                }
                        }
                }
@@ -3096,7 +3258,7 @@ class t3lib_TCEforms      {
                                $t8Tools = t3lib_div::makeInstance('t3lib_transl8tools');
                                $tInfo = $t8Tools->translationInfo($lookUpTable,intval($rec[$TCA[$table]['ctrl']['transOrigPointerField']]),$prL['uid']);
                                if (is_array($tInfo['translations'][$prL['uid']]))      {
-                                       $this->additionalPreviewLanguageData[$table.':'.$rec['uid']][$prL['uid']] = t3lib_BEfunc::getRecordWSOL($lookUpTable, intval($tInfo['translations'][$prL['uid']]['uid']));
+                                       $this->additionalPreviewLanguageData[$table.':'.$rec['uid']][$prL['uid']] = t3lib_BEfunc::getRecordWSOL($table, intval($tInfo['translations'][$prL['uid']]['uid']));
                                }
                        }
                }
@@ -3146,16 +3308,21 @@ class t3lib_TCEforms    {
                        $dLVal = t3lib_BEfunc::getProcessedValue($table,$field,$this->defaultLanguageData[$table.':'.$row['uid']][$field],0,1);
                        $fCfg = $GLOBALS['TCA'][$table]['columns'][$field];
 
-                       if (strcmp($dLVal,''))  {
-                               $item.='<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table,$row,0).$this->previewFieldValue($dLVal,$fCfg).'&nbsp;</div>';
-                       }
+                               // Don't show content if it's for IRRE child records:
+                       if ($fCfg['config']['type']!='inline') {
+                               if (strcmp($dLVal,''))  {
+                                       $item.='<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table,$row,0).$this->previewFieldValue($dLVal,$fCfg).'&nbsp;</div>';
+                               }
 
-                       $prLang = $this->getAdditionalPreviewLanguages();
-                       foreach($prLang as $prL)        {
-                               $dlVal = t3lib_BEfunc::getProcessedValue($table,$field,$this->additionalPreviewLanguageData[$table.':'.$row['uid']][$prL['uid']][$field],0,1);
-                               $item.= '<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table,$row,'v'.$prL['ISOcode']).$this->previewFieldValue($dlVal, $fCfg).'&nbsp;</div>';
-                       }
+                               $prLang = $this->getAdditionalPreviewLanguages();
+                               foreach($prLang as $prL)        {
+                                       $dlVal = t3lib_BEfunc::getProcessedValue($table,$field,$this->additionalPreviewLanguageData[$table.':'.$row['uid']][$prL['uid']][$field],0,1);
 
+                                       if(strcmp($dlVal, '')) {
+                                               $item.= '<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table, $row, 'v'.$prL['ISOcode']).$this->previewFieldValue($dlVal, $fCfg).'&nbsp;</div>';
+                                       }
+                               }
+                       }
                }
 
                return $item;
@@ -3289,6 +3456,7 @@ class t3lib_TCEforms      {
                                        }
                                break;
                                case 'file':
+                               case 'folder':
                                        while(list(,$pp)=each($itemArray))      {
                                                $pParts = explode('|',$pp);
                                                $uidList[]=$pUid=$pTitle = $pParts[0];
@@ -3386,7 +3554,6 @@ class t3lib_TCEforms      {
                                        <td>'.$this->wrapLabels($params['headers']['selector']).'</td>
                                        <td></td>
                                        <td></td>
-                                       <td></td>
                                        <td>'.($params['thumbnails'] ? $this->wrapLabels($params['headers']['items']) : '').'</td>
                                </tr>':'').
                        '
@@ -3395,12 +3562,11 @@ class t3lib_TCEforms    {
                                        $selector.
                                        ($params['noList'] ? '' : '<br />'.$this->wrapLabels($params['info'])) .
                                '</td>
-                               <td valign="top">'.
+                               <td valign="top" class="icons">'.
                                        implode('<br />',$icons['L']).'</td>
-                               <td valign="top">'.
+                               <td valign="top" class="icons">'.
                                        implode('<br />',$icons['R']).'</td>
-                               <td><img src="clear.gif" width="5" height="1" alt="" /></td>
-                               <td valign="top">'.
+                               <td valign="top" class="thumbnails">'.
                                        $this->wrapLabels($params['thumbnails']).
                                '</td>
                        </tr>
@@ -3821,7 +3987,7 @@ class t3lib_TCEforms      {
         * @param       string          The string which - if empty - will become the no-title string.
         * @param       array           Array with wrappin parts for the no-title output (in keys [0]/[1])
         * @return      string
-        * @deprecated
+        * @deprecated since TYPO3 4.1
         */
        function noTitle($str,$wrapParts=array())       {
                return strcmp($str,'') ? $str : $wrapParts[0].'['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title').']'.$wrapParts[1];
@@ -3982,11 +4148,12 @@ class t3lib_TCEforms    {
         *
         * @param       array           Parts for the tab menu, fed to template::getDynTabMenu()
         * @param       string          ID string for the tab menu
+        * @param       integer         If set to '1' empty tabs will be removed, If set to '2' empty tabs will be disabled
         * @return      string          HTML for the menu
         */
-       function getDynTabMenu($parts, $idString) {
-               if (is_object($GLOBALS['TBE_TEMPLATE']))        {
-                       return $GLOBALS['TBE_TEMPLATE']->getDynTabMenu($parts, $idString, 0, FALSE, 50, 1, FALSE, 1, $this->dividers2tabs);
+       function getDynTabMenu($parts, $idString, $dividersToTabsBehaviour = 1) {
+               if (is_object($GLOBALS['TBE_TEMPLATE'])) {
+                       return $GLOBALS['TBE_TEMPLATE']->getDynTabMenu($parts, $idString, 0, false, 50, 1, false, 1, $dividersToTabsBehaviour);
                } else {
                        $output = '';
                        foreach($parts as $singlePad)   {
@@ -4730,7 +4897,7 @@ class t3lib_TCEforms      {
                                        'title' => $fieldTitle
                                )));
                                $aOnClick = 'vHWin=window.open(\''.$this->backPath.'view_help.php?ffID=' . $params . '\',\'viewFieldHelp\',\'height=400,width=600,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;';
-                               return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
+                               return '<a href="#" class="typo3-csh-link" onclick="'.htmlspecialchars($aOnClick).'">'.
                                                '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/helpbubble.gif','width="14" height="14"').' hspace="2" border="0" class="absmiddle"'.($GLOBALS['CLIENT']['FORMSTYLE']?' style="cursor:help;"':'').' alt="" />'.
                                                '</a>';
                        }
@@ -4929,18 +5096,18 @@ class t3lib_TCEforms    {
 
                if (!$update) {
                        if ($this->loadMD5_JS) {
-                               $jsFile[] =     '<script type="text/javascript" src="'.$this->backPath.'md5.js"></script>';
+                               $this->loadJavascriptLib('md5.js');
                        }
 
-                       $jsFile[] = '<script type="text/javascript" src="'.$this->backPath.'contrib/prototype/prototype.js"></script>';
-                       $jsFile[] = '<script type="text/javascript" src="'.$this->backPath.'contrib/scriptaculous/scriptaculous.js"></script>';
-                       $jsFile[] =     '<script type="text/javascript" src="'.$this->backPath.'../t3lib/jsfunc.evalfield.js"></script>';
-                       $jsFile[] =     '<script type="text/javascript" src="'.$this->backPath.'jsfunc.tbe_editor.js"></script>';
+                       $this->loadJavascriptLib('contrib/prototype/prototype.js');
+                       $this->loadJavascriptLib('../t3lib/jsfunc.evalfield.js');
+                       // @TODO: Change to loadJavascriptLib(), but fix "TS = new typoScript()" issue first - see bug #9494
+                       $jsFile[] = '<script type="text/javascript" src="'.$this->backPath.'jsfunc.tbe_editor.js"></script>';
 
                                // if IRRE fields were processed, add the JavaScript functions:
                        if ($this->inline->inlineCount) {
-                               $jsFile[] = '<script src="'.$this->backPath.'contrib/scriptaculous/scriptaculous.js" type="text/javascript"></script>';
-                               $jsFile[] = '<script src="'.$this->backPath.'../t3lib/jsfunc.inline.js" type="text/javascript"></script>';
+                               $this->loadJavascriptLib('contrib/scriptaculous/scriptaculous.js');
+                               $this->loadJavascriptLib('../t3lib/jsfunc.inline.js');
                                $out .= '
                                inline.setPrependFormFieldNames("'.$this->inline->prependNaming.'");
                                inline.setNoTitleString("'.addslashes(t3lib_BEfunc::getNoRecordTitle(true)).'");
@@ -5034,23 +5201,30 @@ class t3lib_TCEforms    {
                        TBE_EDITOR.labels.refresh_login = '.$GLOBALS['LANG']->JScharCode($this->getLL('m_refresh_login')).';
                        TBE_EDITOR.labels.onChangeAlert = '.$GLOBALS['LANG']->JScharCode($this->getLL('m_onChangeAlert')).';
                        evalFunc.USmode = '.($GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat']?'1':'0').';
+                       TBE_EDITOR.backend_interface = "'.$GLOBALS['BE_USER']->uc['interfaceSetup'].'";
                        ';
                }
 
                        // add JS required for inline fields
                if (count($this->inline->inlineData)) {
                        $out .= '
-                       inline.addToDataArray('.t3lib_div::array2json($this->inline->inlineData).');
+                       inline.addToDataArray(' . json_encode($this->inline->inlineData) . ');
+                       ';
+               }
+                       // Registered nested elements for tabs or inline levels:
+               if (count($this->requiredNested)) {
+                       $out .= '
+                       TBE_EDITOR.addNested(' . json_encode($this->requiredNested) . ');
                        ';
                }
                        // elements which are required or have a range definition:
                if (count($elements)) {
                        $out .= '
-                       TBE_EDITOR.addElements('.t3lib_div::array2json($elements).');
-                       TBE_EDITOR.initRequired()
+                       TBE_EDITOR.addElements(' . json_encode($elements) . ');
+                       TBE_EDITOR.initRequired();
                        ';
                }
-                       // $this->additionalJS_post:
+                       // $this->additionalJS_submit:
                if ($this->additionalJS_submit) {
                        $additionalJS_submit = implode('', $this->additionalJS_submit);
                        $additionalJS_submit = str_replace("\r", '', $additionalJS_submit);
@@ -5067,8 +5241,8 @@ class t3lib_TCEforms      {
 
                        // Regular direct output:
                if (!$update) {
-                       $spacer = chr(10).chr(9);
-                       $out  = $spacer.implode($spacer, $jsFile).t3lib_div::wrapJS($out);
+                       $spacer = chr(10) . chr(9);
+                       $out  = $spacer . implode($spacer, $jsFile) . t3lib_div::wrapJS($out);
                }
 
                return $out;
@@ -5334,6 +5508,18 @@ class t3lib_TCEforms     {
                return $out;
        }
 
+       /**
+        * Includes a javascript library that exists in the core /typo3/ directory. The
+        * backpath is automatically applied.
+        * This method acts as wrapper for $GLOBALS['SOBE']->doc->loadJavascriptLib($lib).
+        *
+        * @param       string          $lib: Library name. Call it with the full path like "contrib/prototype/prototype.js" to load it
+        * @return      void
+        */
+       public function loadJavascriptLib($lib) {
+               $GLOBALS['SOBE']->doc->loadJavascriptLib($lib);
+       }
+
 
 
 
@@ -5806,8 +5992,63 @@ class t3lib_TCEforms     {
                if ($skipFirst) {
                        array_shift($result);
                }
-               return ($json ? t3lib_div::array2json($result) : $result);
+               return ($json ? json_encode($result) : $result);
+       }
+
+       /**
+        * Takes care of registering properties in requiredFields and requiredElements.
+        * The current hierarchy of IRRE and/or Tabs is stored. Thus, it is possible to determine,
+        * which required field/element was filled incorrectly and show it, even if the Tab or IRRE
+        * level is hidden.
+        *
+        * @param       string          $type: Type of requirement ('field' or 'range')
+        * @param       string          $name: The name of the form field
+        * @param       mixed           $value: For type 'field' string, for type 'range' array
+        * @return      void
+        */
+       protected function registerRequiredProperty($type, $name, $value) {
+               if ($type == 'field' && is_string($value)) {
+                       $this->requiredFields[$name] = $value;
+                               // requiredFields have name/value swapped! For backward compatibility we keep this:
+                       $itemName = $value;
+               } elseif ($type == 'range' && is_array($value)) {
+                       $this->requiredElements[$name] = $value;
+                       $itemName = $name;
+               }
+                       // Set the situation of nesting for the current field:
+               $this->registerNestedElement($itemName);
+       }
+
+       /**
+        * Sets the current situation of nested tabs and inline levels for a given element.
+        *
+        * @param       string          $itemName: The element the nesting should be stored for
+        * @param       boolean         $setLevel: Set the reverse level lookup - default: true
+        * @return      void
+        */
+       protected function registerNestedElement($itemName, $setLevel=true) {
+               $dynNestedStack = $this->getDynNestedStack();
+               if (count($dynNestedStack) && preg_match('/^(.+\])\[(\w+)\]$/', $itemName, $match)) {
+                       array_shift($match);
+                       $this->requiredNested[$itemName] = array(
+                               'parts' => $match,
+                               'level' => $dynNestedStack,
+                       );
+               }
        }
+
+       /**
+        * Insert additional style sheet link
+        *
+        * @param       string          $key: some key identifying the style sheet
+        * @param       string          $href: uri to the style sheet file
+        * @param       string          $title: value for the title attribute of the link element
+        * @return      string          $relation: value for the rel attribute of the link element
+        * @return      void
+        */
+       public function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
+               $GLOBALS['SOBE']->doc->addStyleSheet($key, $href, $title, $relation);
+        }
 }
 
 
@@ -5886,9 +6127,39 @@ class t3lib_TCEforms_FE extends t3lib_TCEforms {
                <td nowrap="nowrap" bgcolor="#F6F2E6"><font face="verdana" size="1" color="black"><b>###FIELD_HEADER###</b></font></td>
        </tr>   ';
        }
+
+       /**
+        * Includes a javascript library that exists in the core /typo3/ directory. The
+        * backpath is automatically applied.
+        * This method adds the library to $GLOBALS['TSFE']->additionalHeaderData[$lib].
+        *
+        * @param       string          $lib: Library name. Call it with the full path like "contrib/prototype/prototype.js" to load it
+        * @return      void
+        */
+       public function loadJavascriptLib($lib) {
+               if (!isset($GLOBALS['TSFE']->additionalHeaderData[$lib])) {
+                       $GLOBALS['TSFE']->additionalHeaderData[$lib] = '<script type="text/javascript" src="' . $this->backPath . $lib . '"></script>';
+               }
+       }
+
+       /**
+        * Insert additional style sheet link
+        *
+        * @param       string          $key: some key identifying the style sheet
+        * @param       string          $href: uri to the style sheet file
+        * @param       string          $title: value for the title attribute of the link element
+        * @return      string          $relation: value for the rel attribute of the link element
+        * @return      void
+        */
+       public function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
+               if (!isset($GLOBALS['TSFE']->additionalHeaderData[$key])) {
+                       $GLOBALS['TSFE']->additionalHeaderData[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '"' . ($title ? (' title="' . $title . '"') : '') . ' />';
+               }
+        }
 }
 
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms.php']) {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms.php']);
 }
+
 ?>