Index: t3lib/class.t3lib_befunc.php =================================================================== --- t3lib/class.t3lib_befunc.php (revision 9392) +++ t3lib/class.t3lib_befunc.php (working copy) @@ -617,7 +617,8 @@ 't3ver_wsid' => $val['t3ver_wsid'], 't3ver_state' => $val['t3ver_state'], 't3ver_swapmode' => $val['t3ver_swapmode'], - 't3ver_stage' => $val['t3ver_stage'] + 't3ver_stage' => $val['t3ver_stage'], + 'be_layout' => $val['be_layout'] ); if (isset($val['_ORIG_pid'])) { $output[$c]['_ORIG_pid'] = $val['_ORIG_pid']; @@ -645,7 +646,7 @@ $row = $getPageForRootline_cache[$ident]; } else { $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( - 'pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_swapmode,t3ver_stage', + 'pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_swapmode,t3ver_stage,be_layout', 'pages', 'uid=' . intval($uid) . ' ' . self::deleteClause('pages') . ' ' . @@ -4577,4 +4578,4 @@ return $configuration; } } -?> \ No newline at end of file +?> Index: t3lib/stddb/tables.sql =================================================================== --- t3lib/stddb/tables.sql (revision 9392) +++ t3lib/stddb/tables.sql (working copy) @@ -215,6 +215,8 @@ alias varchar(32) DEFAULT '' NOT NULL, l18n_cfg tinyint(4) DEFAULT '0' NOT NULL, fe_login_mode tinyint(4) DEFAULT '0' NOT NULL, + be_layout int(10) DEFAULT '0' NOT NULL, + be_layout_next_level int(10) DEFAULT '0' NOT NULL, PRIMARY KEY (uid), KEY t3ver_oid (t3ver_oid,t3ver_wsid), KEY parent (pid,sorting,deleted,hidden), Index: t3lib/stddb/tbl_be.php =================================================================== --- t3lib/stddb/tbl_be.php (revision 9392) +++ t3lib/stddb/tbl_be.php (working copy) @@ -702,7 +702,6 @@ ); - /** * System filemounts - Defines filepaths on the server which can be mounted for users so they can upload and manage files online by eg. the Filelist module */ Index: t3lib/stddb/tbl_pages.php =================================================================== --- t3lib/stddb/tbl_pages.php (revision 9392) +++ t3lib/stddb/tbl_pages.php (working copy) @@ -6,7 +6,7 @@ $TCA['pages'] = array( 'ctrl' => $TCA['pages']['ctrl'], 'interface' => array( - 'showRecordFieldList' => 'doktype,title,alias,hidden,starttime,endtime,fe_group,url,target,no_cache,shortcut,keywords,description,abstract,newUntil,lastUpdated,cache_timeout', + 'showRecordFieldList' => 'doktype,title,alias,hidden,starttime,endtime,fe_group,url,target,no_cache,shortcut,keywords,description,abstract,newUntil,lastUpdated,cache_timeout,be_layout,be_layout_next_level', 'maxDBListItems' => 30, 'maxSingleDBListItems' => 50, ), @@ -732,6 +732,40 @@ ), ), ), + 'be_layout' => array ( + 'exclude' => 1, + 'label' => 'LLL:EXT:cms/locallang_tca.xml:pages.be_layout', + 'config' => array ( + 'type' => 'select', + 'foreign_table' => 'be_layouts', + 'foreign_table_where' => 'AND ( ( ###PAGE_TSCONFIG_ID### = 0 AND ###STORAGE_PID### = 0 ) OR ( be_layouts.pid = ###PAGE_TSCONFIG_ID### OR be_layouts.pid = ###STORAGE_PID### ) ) AND be_layouts.hidden = 0', + 'items' => array ( + array ('', 0), + array ('none', -1) + ), + 'selicon_cols' => 5, + 'size' => 1, + 'maxitems' => 1, + 'default' => '' + ) + ), + 'be_layout_next_level' => array ( + 'exclude' => 1, + 'label' => 'LLL:EXT:cms/locallang_tca.xml:pages.be_layout_next_level', + 'config' => array ( + 'type' => 'select', + 'foreign_table' => 'be_layouts', + 'foreign_table_where' => 'AND ( ( ###PAGE_TSCONFIG_ID### = 0 AND ###STORAGE_PID### = 0 ) OR ( be_layouts.pid = ###PAGE_TSCONFIG_ID### OR be_layouts.pid = ###STORAGE_PID### ) ) AND be_layouts.hidden = 0', + 'items' => array ( + array ('', 0), + array ('none', -1) + ), + 'selicon_cols' => 5, + 'size' => 1, + 'maxitems' => 1, + 'default' => '' + ) + ) ), 'types' => array( // normal @@ -915,6 +949,9 @@ '7' => array( 'showitem' => 'is_siteroot', ), + '8' => array( + 'showitem' => 'be_layout_next_level' + ), 'standard' => array( 'showitem' => 'doktype;LLL:EXT:cms/locallang_tca.xml:pages.doktype_formlabel', 'canNotCollapse' => 1, @@ -972,7 +1009,7 @@ 'canNotCollapse' => 1, ), 'layout' => array( - 'showitem' => 'layout;LLL:EXT:cms/locallang_tca.xml:pages.layout_formlabel, newUntil;LLL:EXT:cms/locallang_tca.xml:pages.newUntil_formlabel', + 'showitem' => 'layout;LLL:EXT:cms/locallang_tca.xml:pages.layout_formlabel, newUntil;LLL:EXT:cms/locallang_tca.xml:pages.newUntil_formlabel, --linebreak--, be_layout;LLL:EXT:cms/locallang_tca.xml:pages.be_layout_formlabel, be_layout_next_level;LLL:EXT:cms/locallang_tca.xml:pages.be_layout_next_level_formlabel', 'canNotCollapse' => 1, ), 'module' => array( @@ -1014,8 +1051,8 @@ 'config' => array( 'showitem' => 'TSconfig;LLL:EXT:cms/locallang_tca.xml:pages.TSconfig_formlabel', 'canNotCollapse' => 1, - ), - ), + ) + ) ); @@ -1048,7 +1085,7 @@ --div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.access, starttime, endtime, fe_group, extendToSubpages, --div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.options, - TSconfig;;6;nowrap;4-4-4, storage_pid;;7, l18n_cfg, + TSconfig;;6;nowrap;4-4-4, storage_pid;;7, l18n_cfg, be_layout;;8, --div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.extended, '); // adding doktype 2 ("Advanced") @@ -1062,7 +1099,7 @@ --div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.access, starttime, endtime, fe_login_mode, fe_group, extendToSubpages, --div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.options, - TSconfig;;6;nowrap;6-6-6, storage_pid;;7, l18n_cfg, module, content_from_pid, + TSconfig;;6;nowrap;6-6-6, storage_pid;;7, l18n_cfg, module, content_from_pid, be_layout;;8, --div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.extended, '); } Index: typo3/sysext/cms/class.tx_cms_be_layout.php =================================================================== --- typo3/sysext/cms/class.tx_cms_be_layout.php (revision 0) +++ typo3/sysext/cms/class.tx_cms_be_layout.php (revision 0) @@ -0,0 +1,89 @@ +addColPosListLayoutItems ( $params['row']['pid'], $params['items'] ); + } + + function addColPosListLayoutItems ( $pageId, $items ){ + $layout = $this->getSelectedBackendLayout($pageId); + if( $layout && $layout['__items'] ){ + $items = $layout['__items']; + } + return $items; + } + + function getColPosListItemsParsed ( $id ){ + + $tsConfig = t3lib_BEfunc::getModTSconfig( $id ,'TCEFORM.tt_content.colPos'); + $tcaConfig = $GLOBALS['TCA']['tt_content']['columns']['colPos']['config']; + + $TCEForms = t3lib_div::makeInstance( 't3lib_TCEForms' ); + $tcaItems = $tcaConfig['items']; + $tcaItems = $TCEForms->addItems($tcaItems, $tsConfig['properties']['addItems.']); + if (isset($tcaConfig['itemsProcFunc']) && $tcaConfig['itemsProcFunc']) { + $tcaItems = $this->addColPosListLayoutItems ($id , $tcaItems ) ; + } + foreach ( t3lib_div::trimExplode(',',$tsConfig['properties']['removeItems'],1) as $removeId ){ + unset( $tcaItems[$removeId] ); + } + return $tcaItems; + } + + function getSelectedBackendLayout($id) { + $rootline = t3lib_BEfunc::BEgetRootLine($id); + $backendLayoutUid = null; + for ($i = count($rootline); $i > 0; $i--) { + $res = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,be_layout,be_layout_next_level','pages','uid='.intval($rootline[$i]['uid'])); + $page = $res[0]; + if (intval($page['be_layout_next_level']) > 0 && $page['uid'] != $id ) { + $backendLayoutUid = intval($page['be_layout_next_level']); + break; + } else if (intval($page['be_layout']) > 0) { + $backendLayoutUid = intval($page['be_layout']); + break; + } + } + $backendLayout = null; + if ($backendLayoutUid){ + $res = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*','be_layouts','uid='.$backendLayoutUid ); + if ($res){ + $backendLayout = $res[0]; + $parser = t3lib_div::makeInstance('t3lib_TSparser'); + $parser->parse($backendLayout['config']); + $backendLayout['__config'] = $parser->setup; + $backendLayout['__items'] = array(); + $backendLayout['__colPosList'] = array(); + + // create items and colPosList + if ( $backendLayout['__config']['be_layout.'] && $backendLayout['__config']['be_layout.']['rows.'] ){ + foreach( $backendLayout['__config']['be_layout.']['rows.'] as $row){ + if ( true && count($row['columns.'])){ + foreach ( $row['columns.'] as $column) { + if ( true ){ + $backendLayout['__items'][] = array ( + $column['name'], + $column['colPos'], + null + ); + $backendLayout['__colPosList'][] = $column['colPos']; + } + } + } + } + } + + } + } + return $backendLayout; + } + +} + +?> Index: typo3/sysext/cms/ext_tables.php =================================================================== --- typo3/sysext/cms/ext_tables.php (revision 9392) +++ typo3/sysext/cms/ext_tables.php (working copy) @@ -24,7 +24,7 @@ // Add allowed records to pages: - t3lib_extMgm::allowTableOnStandardPages('pages_language_overlay,tt_content,sys_template,sys_domain'); +t3lib_extMgm::allowTableOnStandardPages('pages_language_overlay,tt_content,sys_template,sys_domain,be_layouts'); // ****************************************************************** @@ -256,4 +256,29 @@ ); +// ****************************************************************** +// layouts +// ****************************************************************** +$TCA['be_layouts'] = array ( + 'ctrl' => array ( + 'title' => 'LLL:EXT:cms/locallang_tca.xml:be_layouts', + 'label' => 'title', + 'tstamp' => 'tstamp', + 'crdate' => 'crdate', + 'cruser_id' => 'cruser_id', + 'versioningWS' => TRUE, + 'origUid' => 't3_origuid', + 'sortby' => 'sorting', + 'delete' => 'deleted', + 'enablecolumns' => array ( + 'disabled' => 'hidden', + ), + 'dynamicConfigFile' => t3lib_extMgm::extPath($_EXTKEY).'tbl_cms.php', + 'iconfile' => 'be_layout.gif', + 'selicon_field' => 'icon', + 'selicon_field_path' => 'uploads/media', + 'thumbnail' => 'resources', + ) +); + ?> \ No newline at end of file Index: typo3/sysext/cms/ext_tables.sql =================================================================== --- typo3/sysext/cms/ext_tables.sql (revision 9392) +++ typo3/sysext/cms/ext_tables.sql (working copy) @@ -436,3 +436,34 @@ KEY parent (pid,sorting), KEY language (l18n_parent,sys_language_uid) ); + +# +# Table structure for table 'be_layouts' +# +CREATE TABLE be_layouts ( + uid int(11) NOT NULL auto_increment, + pid int(11) DEFAULT '0' NOT NULL, + t3ver_oid int(11) DEFAULT '0' NOT NULL, + t3ver_id int(11) DEFAULT '0' NOT NULL, + t3ver_wsid int(11) DEFAULT '0' NOT NULL, + t3ver_label varchar(255) DEFAULT '' NOT NULL, + t3ver_state tinyint(4) DEFAULT '0' NOT NULL, + t3ver_stage tinyint(4) DEFAULT '0' NOT NULL, + t3ver_count int(11) DEFAULT '0' NOT NULL, + t3ver_tstamp int(11) DEFAULT '0' NOT NULL, + t3ver_move_id int(11) DEFAULT '0' NOT NULL, + t3_origuid int(11) DEFAULT '0' NOT NULL, + tstamp int(11) unsigned DEFAULT '0' NOT NULL, + crdate int(11) unsigned DEFAULT '0' NOT NULL, + cruser_id int(11) unsigned DEFAULT '0' NOT NULL, + hidden tinyint(4) unsigned DEFAULT '0' NOT NULL, + deleted tinyint(4) DEFAULT '0' NOT NULL, + sorting int(11) unsigned DEFAULT '0' NOT NULL, + title varchar(255) DEFAULT '' NOT NULL, + description text NOT NULL, + config text NOT NULL, + icon text NOT NULL, + PRIMARY KEY (uid), + KEY parent (pid), + KEY t3ver_oid (t3ver_oid,t3ver_wsid) +); \ No newline at end of file Index: typo3/sysext/cms/layout/class.tx_cms_layout.php =================================================================== --- typo3/sysext/cms/layout/class.tx_cms_layout.php (revision 9392) +++ typo3/sysext/cms/layout/class.tx_cms_layout.php (working copy) @@ -138,6 +138,7 @@ 'showInfo' => 1, // Boolean: Display info-marks or not 'showCommands' => 1, // Boolean: Display up/down arrows and edit icons for tt_content records 'single' => 1, // Boolean: If set, the content of column(s) $this->tt_contentConfig['showSingleCol'] is shown in the total width of the page + 'showAsGrid' => 0, // Boolean: If set, the content of columns is shown in grid 'showSingleCol' => 0, // The column(s) to show if single mode (under each other) 'languageCols' => 0, 'languageMode' => 0, @@ -392,6 +393,29 @@ } /** + * Returns the backend layout which should be used for this page. + * + * @param integer $id: Uid of the current + * @return integer The Uid of the backend layout record + */ + function getSelectedBackendLayoutUid($id) { + $rootline = t3lib_BEfunc::BEgetRootLine($id); + $backendLayoutUid = null; + for ($i = count($rootline); $i > 0; $i--) { + $res = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,be_layout,be_layout_next_level','pages','uid='.intval($rootline[$i]['uid'])); + $page = $res[0]; + if (intval($page['be_layout_next_level']) > 0 && $page['uid'] != $id ) { + $backendLayoutUid = intval($page['be_layout_next_level']); + break; + } else if (intval($page['be_layout']) > 0) { + $backendLayoutUid = intval($page['be_layout']); + break; + } + } + return $backendLayoutUid; + } + + /** * Renders Content Elements from the tt_content table from page id * * @param integer Page id @@ -493,41 +517,109 @@ // Add new-icon link, header: $newP = $this->newContentElementOnClick($id,$key,$lP); - $head[$key].= $this->tt_content_drawColHeader(t3lib_BEfunc::getProcessedValue('tt_content','colPos',$key), ($this->doEdit&&count($rowArr)?'&edit[tt_content]['.$editUidList.']=edit'.$pageTitleParamForAltDoc:''), $newP); + $colTitle = t3lib_BEfunc::getProcessedValue('tt_content','colPos',$key); + /** + * @mficzel + * @todo get complete title from tca inclusive ts config manipulations by user func and tsConfig + */ + $tcaItems = t3lib_div::callUserFunction( 'EXT:cms/class.tx_cms_be_layout.php:tx_cms_be_layout->getColPosListItemsParsed' , $id, $this ); + foreach( $tcaItems as $item) { + if ( $item[1] == $key) { + $colTitle = $GLOBALS['LANG']->sL( $item[0] ); + } + } + $head[$key].= $this->tt_content_drawColHeader($colTitle , ($this->doEdit&&count($rowArr)?'&edit[tt_content]['.$editUidList.']=edit'.$pageTitleParamForAltDoc:''), $newP); $editUidList = ''; } // For EACH column, fit the rendered content into a table cell: $out=''; - foreach($cList as $k => $key) { - if (!$k) { - $out.= ' - '; - } else { - $out.= ' - - - '; + + if ($this->tt_contentConfig['showAsGrid']) { + $backendLayoutUid = $this->getSelectedBackendLayoutUid($id); + $backendLayoutRecord = t3lib_BEfunc::getRecord('be_layouts', intval($backendLayoutUid)); + if (empty($backendLayoutRecord['config'])) { + // TODO: show a message that no layout was found + $this->tt_contentConfig['showAsGrid'] = 0; } - $out.= ' - ' . $head[$key] . $content[$key] . ''; + } - // Storing content for use if languageMode is set: - if ($this->tt_contentConfig['languageMode']) { - $languageColumn[$key][$lP] = $head[$key].$content[$key]; - if (!$this->defLangBinding) { - $languageColumn[$key][$lP].='

'.$this->newLanguageButton($this->getNonTranslatedTTcontentUids($defLanguageCount[$key],$id,$lP),$lP); + if (!$this->tt_contentConfig['showAsGrid']) { + foreach($cList as $k => $key) { + + if (!$k) { + $out.= ' + '; + } else { + $out.= ' + + + '; } + $out.= ' + ' . $head[$key] . $content[$key] . ''; + + // Storing content for use if languageMode is set: + if ($this->tt_contentConfig['languageMode']) { + $languageColumn[$key][$lP] = $head[$key].$content[$key]; + if (!$this->defLangBinding) { + $languageColumn[$key][$lP].='

'.$this->newLanguageButton($this->getNonTranslatedTTcontentUids($defLanguageCount[$key],$id,$lP),$lP); + } + } } - } - // Wrap the cells into a table row: - $out = ' + // Wrap the cells into a table row: + $out = ' '.$out.'
'; + } else { + // GRID VIEW: + + // initialize TS parser to parse config to array + $parser = t3lib_div::makeInstance('t3lib_TSparser'); + $parser->parse($backendLayoutRecord['config']); + + $grid .= '
'; + + // add colgroups + $colCount = intval($parser->setup['be_layout.']['colCount']); + $grid .= ''; + for ($i = 0; $i < $colCount; $i++) { + $grid .= ''; + } + $grid .= ''; + + // cycle through rows + if(count($parser->setup['be_layout.']['rows.'])) { + foreach ($parser->setup['be_layout.']['rows.'] as $rowConfig) { + $grid .= ''; + + // and colummns + if(count($rowConfig['columns.'])) { + foreach ($rowConfig['columns.'] as $columnConfig) { + + // which tt_content colPos should be displayed inside this cell + $columnKey = intval($columnConfig['colPos']); + + // render the grid cell + $grid .= ''; + } + } + $grid .= ''; + } + } + $out .= $grid.'
'; + $grid .= $head[$columnKey] . $content[$columnKey] . '
'; + } + // CSH: $out.= t3lib_BEfunc::cshItem($this->descrTable,'columns_multi',$GLOBALS['BACK_PATH']); } @@ -2480,7 +2572,7 @@ $lines[]=''; $lines[]=array($LANG->getLL('pI_hitsPeriod').':',t3lib_BEfunc::date($rrow2[0]).' - '.t3lib_BEfunc::date($rrow2[1]).' ('.t3lib_BEfunc::calcAge($rrow2[1]-$rrow2[0],$this->agePrefixes).')'); - $lines[]=array($LANG->getLL('pI_hitsTotal').':',$rrow[0]); + $lines[]=array($LANG->getLL('pI_hitsTotal').':',$rrow2[0]); // Last 10 days Index: typo3/sysext/cms/layout/db_layout.php =================================================================== --- typo3/sysext/cms/layout/db_layout.php (revision 9392) +++ typo3/sysext/cms/layout/db_layout.php (working copy) @@ -322,7 +322,8 @@ 0 => $LANG->getLL('m_function_0'), 1 => $LANG->getLL('m_function_1'), 2 => $LANG->getLL('m_function_2'), - 3 => $LANG->getLL('pageInformation') + 3 => $LANG->getLL('pageInformation'), + 4 => $LANG->getLL('gridView') ), 'language' => array( 0 => $LANG->getLL('m_default') @@ -535,10 +536,17 @@ // Find columns $modTSconfig_SHARED = t3lib_BEfunc::getModTSconfig($this->id,'mod.SHARED'); // SHARED page-TSconfig settings. $this->colPosList = strcmp(trim($this->modTSconfig['properties']['tt_content.']['colPos_list']),'') ? trim($this->modTSconfig['properties']['tt_content.']['colPos_list']) : $modTSconfig_SHARED['properties']['colPos_list']; - $this->colPosList = strcmp($this->colPosList,'')?$this->colPosList:'1,0,2,3'; - $this->colPosList = implode(',',array_unique(t3lib_div::intExplode(',',$this->colPosList))); // Removing duplicates, if any + if( !strcmp($this->colPosList,'') ) { + $beLayout = t3lib_div::callUserFunction( 'EXT:cms/class.tx_cms_be_layout.php:tx_cms_be_layout->getSelectedBackendLayout' , $this->id, $this ); + if(count($beLayout['__colPosList'])) { + $this->colPosList = implode(',', $beLayout['__colPosList']); + } + } + if( !strcmp($this->colPosList, '') ){ + $this->colPosList = '1,0,2,3'; + } + $this->colPosList = implode(',', array_unique(t3lib_div::intExplode(',',$this->colPosList))); // Removing duplicates, if any - // Render the primary module content: if ($this->MOD_SETTINGS['function']==0) { $body = $this->renderQuickEdit(); // QuickEdit @@ -1026,10 +1034,16 @@ $dblist->tt_contentConfig['showInfo'] = 1; // Boolean: Display info-marks or not $dblist->tt_contentConfig['single'] = 0; // Boolean: If set, the content of column(s) $this->tt_contentConfig['showSingleCol'] is shown in the total width of the page + if ($this->MOD_SETTINGS['function'] == 4) { + // grid view + $dblist->tt_contentConfig['showAsGrid'] = 1; + } + // Setting up the tt_content columns to show: if (is_array($TCA['tt_content']['columns']['colPos']['config']['items'])) { $colList = array(); - foreach($TCA['tt_content']['columns']['colPos']['config']['items'] as $temp) { + $tcaItems = t3lib_div::callUserFunction( 'EXT:cms/class.tx_cms_be_layout.php:tx_cms_be_layout->getColPosListItemsParsed' , $this->id, $this ); + foreach($tcaItems as $temp) { $colList[] = $temp[1]; } } else { // ... should be impossible that colPos has no array. But this is the fallback should it make any sense: @@ -1372,4 +1386,4 @@ $SOBE->main(); $SOBE->printContent(); -?> \ No newline at end of file +?> Index: typo3/sysext/cms/layout/locallang.xml =================================================================== --- typo3/sysext/cms/layout/locallang.xml (revision 9392) +++ typo3/sysext/cms/layout/locallang.xml (working copy) @@ -57,6 +57,7 @@ + @@ -84,4 +85,4 @@ - \ No newline at end of file + Index: typo3/sysext/cms/layout/res/grideditor.css =================================================================== --- typo3/sysext/cms/layout/res/grideditor.css (revision 0) +++ typo3/sysext/cms/layout/res/grideditor.css (revision 0) @@ -0,0 +1,134 @@ +* { + padding: 0; + margin: 0; + position: relative; +} + +body, html { + height: 100%; + width: 100%; +} + +div.typo3-noDoc { + width: 98%; + height: 90%; + margin: 0; + padding: 5px; +} + +table#outer_container td, table#editor td { + vertical-align: middle; +} + +table#outer_container td.editor_cell { + height: 100%; +} + +table.editor { + border-right: 1px gray dashed; + border-bottom: 1px gray dashed; +} + +table.editor td { + border-top: 1px gray dashed; + border-left: 1px gray dashed; + text-align: center; + z-index: 2000; + background-color: white; + min-height: 100px; +} + +div#editor { + height: 100%; +} + +div.cell_container { + width: 60px; + height: 60px; + position: relative; + left: 50%; + margin-left: -30px; + opacity: 0.3; +} + +div.cell_container:hover { + opacity: 1; +} + +.link_expand_right, .link_shrink_left, .link_expand_down, .link_shrink_up, .link_editor { + display: block; + position: absolute; + width: 14px; + height: 32px; + z-index: 1100; +} + +.link_expand_down, .link_shrink_up { + width: 32px; + height: 14px; +} + +.link_expand_right { + background-image: url(t3grid-editor-right-inactive.png); + left: 46px; + top: 14px; +} + +.link_expand_right:hover { + background-image: url(t3grid-editor-right.png); +} + + +.link_shrink_left { + background-image: url(t3grid-editor-left-inactive.png); + left: 0px; + top: 14px; +} + +.link_shrink_left:hover { + background-image: url(t3grid-editor-left.png); +} + +.link_expand_down { + background-image: url(t3grid-editor-down-inactive.png); + left: 14px; + top: 46px; +} + +.link_expand_down:hover { + background-image: url(t3grid-editor-down.png); +} + +.link_shrink_up { + background-image: url(t3grid-editor-up-inactive.png); + left: 14px; + top: 0px; +} + +.link_shrink_up:hover { + background-image: url(t3grid-editor-up.png); +} + +.link_editor { + background-image: url(t3grid-edit-inactive.png); + width: 32px; + height: 32px; + left: 14px; + top: 14px; +} + +.link_editor:hover { + background-image: url(t3grid-edit.png); +} + +.question { + background-image: url(t3grid-layer-icon-help.png) !important; +} + +.save { + background-image: url(t3grid-layer-icon-save.png) !important; +} + +.cancel { + background-image: url(t3grid-layer-icon-close.png) !important; +} Index: typo3/sysext/cms/layout/res/grideditor.js =================================================================== --- typo3/sysext/cms/layout/res/grideditor.js (revision 0) +++ typo3/sysext/cms/layout/res/grideditor.js (revision 0) @@ -0,0 +1,568 @@ +/** + * A JavaScript object to handle, edit, draw and export a grid. The grid is basically + * a table with some colspan and rowspan. Each cell can additionally hold a name and + * column. + * + * @author Thomas Hempel + */ +Ext.namespace('TYPO3.Backend.t3Grid'); + +TYPO3.Backend.t3Grid = Ext.extend(Ext.Component, { + /* + colCount: 0, + rowCount: 0, + data: [], + nameLabel: '', + columnLabel: '', + */ + constructor: function(config) { + + config = Ext.apply({ + colCount: config.colCount, + rowCount: config.rowCount, + data: config.data, + nameLabel: config.nameLabel, + columnLabel: config.columnLabel, + targetElement: config.targetElement + }, config); + + TYPO3.Backend.t3Grid.superclass.constructor.call(this, config); + }, + + /** + * Adds a row below the grid + */ + addRow: function() { + var newRow = []; + for (var i = 0; i < this.colCount; i++) { + newRow[i] = {spanned:false,rowspan:1,colspan:1}; + } + this.data.push(newRow); + this.rowCount++; + }, + + /** + * Removes the last row of the grid and adjusts all cells that might be effected + * by that change. (Removing colspans) + * + * @returns void + */ + removeRow: function() { + if (this.rowCount <= 1) return false; + var newData = []; + for (var rowIndex = 0; rowIndex < this.rowCount-1; rowIndex++) { + newData.push(this.data[rowIndex]); + } + + // fix rowspan in former last row + for (var colIndex = 0; colIndex < this.colCount; colIndex++) { + if (this.data[this.rowCount-1][colIndex].spanned == true) { + this.findUpperCellWidthRowspanAndDecreaseByOne(colIndex,this.rowCount-1); + } + } + + this.data = newData; + this.rowCount--; + }, + + /** + * Takes a cell and looks above it if there are any cells that have colspans that + * spanns into the given cell. This is used when a row was removed from the grid + * to make sure that no cell with wrong colspans exists in the grid. + * + * @param col integer + * @param row integer + * @return void + */ + findUpperCellWidthRowspanAndDecreaseByOne: function(col,row) { + var upperCell = this.getCell(col, row-1); + if (!upperCell) return false; + + if (upperCell.spanned == true) { + this.findUpperCellWidthRowspanAndDecreaseByOne(col, row-1); + } else { + if (upperCell.rowspan > 1) { + this.removeRowspan(col, row-1); + } + } + }, + + /** + * Removes the outermost right column from the grid. + * + * @return void + */ + removeColumn: function() { + if (this.colCount <= 1) return false; + var newData = []; + + for (var rowIndex = 0; rowIndex < this.rowCount; rowIndex++) { + var newRow = []; + for (colIndex = 0; colIndex < this.colCount-1; colIndex++) { + newRow.push(this.data[rowIndex][colIndex]); + } + if (this.data[rowIndex][this.colCount-1].spanned == true) { + this.findLeftCellWidthColspanAndDecreaseByOne(this.colCount-1, rowIndex); + } + newData.push(newRow); + } + + this.data = newData; + this.colCount--; + }, + + /** + * Checks if there are any cells on the left side of a given cell with a + * rowspan that spans over the given cell. + * + * @param col integer + * @param row integer + * @return void + */ + findLeftCellWidthColspanAndDecreaseByOne: function(col,row) { + var leftCell = this.getCell(col-1, row); + if (!leftCell) return false; + + if (leftCell.spanned == true) { + this.findLeftCellWidthColspanAndDecreaseByOne(col-1, row); + } else { + if (leftCell.colspan > 1) { + this.removeColspan(col-1, row); + } + } + }, + + /** + * Adds a column at the right side of the grid. + * + * @return void + */ + addColumn: function() { + for (var rowIndex = 0; rowIndex < this.rowCount; rowIndex++) { + this.data[rowIndex].push({spanned:false,rowspan:1,colspan:1,name:this.colCount+'x'+rowIndex}); + } + this.colCount++; + }, + + /** + * Draws the grid as table into a given container. + * It also adds all needed links and bindings to the cells to make it editable. + * + * @return void + */ + drawTable: function() { + var domHelper = Ext.DomHelper; + var newTable = {tag:'table',children:[],id:'base',border:'0',width:'100%',height:'100%','class':'editor',cellspacing:'0',cellpadding:'0'}; + + var colgroups = {tag:'colgroup',children:[]}; + for (var col = 0; col < this.colCount; col++) { + colgroups.children.push({tag:'col',style:'width:'+parseInt(100/this.colCount)+'%'}); + } + newTable.children.push(colgroups); + + for (var row = 0; row < this.rowCount; row++) { + var rowData = this.data[row]; + if (rowData.length == 0) continue; + + var rowSpec = {tag: 'tr', children:[]}; + + for (var col = 0; col < this.colCount; col++) { + var cell = this.data[row][col]; + if (cell.spanned == true) { + continue; + } + + + var cellHtml = '
'; + if (this.cellCanSpanRight(col, row)) cellHtml += ''; + if (this.cellCanShrinkLeft(col, row)) cellHtml += ''; + if (this.cellCanSpanDown(col, row)) cellHtml += ''; + if (this.cellCanShrinkUp(col, row)) cellHtml += ''; + cellHtml += '
'; + + cellHtml += '
Name: '+(cell.name ? cell.name : 'not set')+'
Column: '+((parseInt(cell.column) === false) ? 'not set' : cell.column)+'
'; + + // create cells + var child = { + tag: 'td', + height: parseInt(100/this.rowCount)*cell.rowspan+'%', + width: parseInt(100/this.colCount)*cell.colspan+'%', + html: cellHtml + }; + if (cell.colspan > 1) { + child.colspan = cell.colspan; + } + if (cell.rowspan > 1) { + child.rowspan = cell.rowspan; + } + rowSpec.children.push(child); + } + + newTable.children.push(rowSpec); + + } + + domHelper.overwrite(Ext.Element.get(this.targetElement), newTable); + this.bindLinks(); + }, + + /** + * Sets the name of a certain grid element. + * + * @param newName string + * @param col integer + * @param row integer + * + * @return boolean + */ + setName: function(newName, col, row) { + var cell = this.getCell(col, row); + if (!cell) return false; + cell.name = newName; + return true; + }, + + /** + * Sets the column field for a certain grid element. This is NOT the column of the + * element itself. + * + * @param newColumn integer + * @param col integer + * @param row integer + * + * @return boolean + */ + setColumn: function(newColumn, col, row) { + var cell = this.getCell(col, row); + if (!cell) return false; + cell.column = newColumn; + return true; + }, + + /** + * Searches for all a tags with certain classes and binds some actions to them. + * + * @return void + */ + bindLinks: function() { + for (var row = 0; row < this.rowCount; row++) { + for (var col = 0; col < this.colCount; col++) { + // span right + var el = Ext.Element.get('r_'+col+'_'+row); + if (el) { + el.addListener('click', function(e, sender, params) { + this.addColspan(params.colIndex, params.rowIndex); + this.drawTable(); + }, this, {stopEvent:true, colIndex:col, rowIndex:row}); + } + + // reduce to left + var el = Ext.Element.get('l_'+col+'_'+row); + if (el) { + el.addListener('click', function(e, sender, params) { + this.removeColspan(params.colIndex, params.rowIndex); + this.drawTable(); + }, this, {stopEvent:true, colIndex:col, rowIndex:row}); + } + + // span down + var el = Ext.Element.get('d_'+col+'_'+row); + if (el) { + el.addListener('click', function(e, sender, params) { + this.addRowspan(params.colIndex, params.rowIndex); + this.drawTable(); + }, this, {stopEvent:true, colIndex:col, rowIndex:row}); + } + + // reduce up + var el = Ext.Element.get('u_'+col+'_'+row); + if (el) { + el.addListener('click', function(e, sender, params) { + this.removeRowspan(params.colIndex, params.rowIndex); + this.drawTable(); + }, this, {stopEvent:true, colIndex:col, rowIndex:row}); + } + + // edit + var el = Ext.Element.get('e_'+col+'_'+row); + if (el) { + el.addListener('click', function(e, sender, params) { + this.showOptions(sender, params.colIndex, params.rowIndex); + }, this, {stopEvent:true, colIndex:col, rowIndex:row}); + } + } + } + }, + + /** + * Creates an ExtJs Window with two input fields and shows it. On save, the data + * is written into the grid element. + * + * @param sender DOM-object (the link) + * @param col integer + * @param row integer + */ + showOptions: function(sender, col, row) { + var win; + sender = Ext.get('base'); + var cell = this.getCell(col, row); + if (!cell) return false; + + if(!win){ + var fieldName = new Ext.form.TextField({ + fieldLabel: TYPO3.lang.name, + name: 'name', + width: 200, + value: cell.name, + tabIndex: 1 + }); + + var fieldColumn = new Ext.form.NumberField({ + fieldLabel: TYPO3.lang.column, + name: 'column', + width: 50, + value: cell.column, + tabIndex: 2 + }); + + + win = new Ext.Window({ + layout: 'fit', + title: TYPO3.lang.title, + width: '50%', + modal: true, + closable: true, + resizable: false, + + items: [{ + xtype: 'fieldset', + autoHeight: true, + autoWidth: true, + labelWidth: 100, + border: false, + + items: [fieldName, fieldColumn] + }], + + buttons: [{ + iconCls:'save', + text: TYPO3.lang.save, + handler: function(fieldName, fieldColumn, col, row) { + t3Grid.setName(fieldName.getValue(), col, row); + t3Grid.setColumn(fieldColumn.getValue(), col, row); + win.close(); + t3Grid.drawTable(); + }.createDelegate(this, [fieldName, fieldColumn, col, row]) + }] + }); + } + win.show(this); + }, + + /** + * Returns a cell element from the grid. + * + * @param col integer + * @param row integer + * return Object + */ + getCell: function(col, row) { + if (col > this.colCount-1) return false; + if (row > this.rowCount-1) return false; + return this.data[row][col]; + }, + + /** + * Checks wether a cell can span to the right or not. A cell can span to the right + * if it is not in the last column and if there is no cell beside it that is + * already overspanned by some other cell. + * + * @param col integer + * @param row integer + * + * @return boolean + */ + cellCanSpanRight: function(col, row) { + if (col == this.colCount-1) { + return false; + } + + var cell = this.getCell(col, row); + if (cell.rowspan > 1) { + for (var rowIndex = row; rowIndex < row+cell.rowspan; rowIndex++) { + var checkCell = this.getCell(col+cell.colspan, rowIndex); + if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + } else { + var checkCell = this.getCell(col+cell.colspan, row); + if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + + return true; + }, + + /** + * Checks wether a cell can span down or not. + * + * @param col integer + * @param row integer + * + * @return boolean + */ + cellCanSpanDown: function(col, row) { + if (row == this.rowCount-1) { + return false; + } + + var cell = this.getCell(col, row); + if (cell.colspan > 1) { + // we have to check all cells on the right side for the complete colspan + for (var colIndex = col; colIndex < col+cell.colspan; colIndex++) { + var checkCell = this.getCell(colIndex, row+cell.rowspan); + if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + } else { + var checkCell = this.getCell(col, row+cell.rowspan); + if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + + return true; + }, + + /** + * Checks if a cell can shrink to the left. It can shrink if the colspan of the + * cell is bigger than 1. + * + * @param col integr + * @param row integer + * + * @return boolean + */ + cellCanShrinkLeft: function(col, row) { + return (this.data[row][col].colspan > 1); + }, + + /** + * Returns if a cell can shrink up. This is the case if a cell has at least + * a rowspan of 2. + * + * @param col integr + * @param row integer + * + * @return boolean + */ + cellCanShrinkUp: function(col, row) { + return (this.data[row][col].rowspan > 1); + }, + + /** + * Adds a colspan to a grid element. + * + * @param col integr + * @param row integer + */ + addColspan: function(col, row) { + var cell = this.getCell(col, row); + if (!cell || !this.cellCanSpanRight(col, row)) return false; + + for (var rowIndex = row; rowIndex < row+cell.rowspan; rowIndex++) { + this.data[rowIndex][col+cell.colspan].spanned = true; + } + cell.colspan += 1; + }, + + /** + * Adds a rowspan to grid element. + * + * @param col integr + * @param row integer + * + * @return void + */ + addRowspan: function(col, row) { + var cell = this.getCell(col, row); + if (!cell || !this.cellCanSpanDown(col, row)) return false; + + for (var colIndex = col; colIndex < col+cell.colspan; colIndex++) { + this.data[row+cell.rowspan][colIndex].spanned = true; + } + cell.rowspan += 1; + }, + + /** + * Removes a colspan from a grid element. + * + * @param col integr + * @param row integer + * + * @return void + */ + removeColspan: function(col, row) { + var cell = this.getCell(col, row); + if (!cell || !this.cellCanShrinkLeft(col, row)) return false; + + cell.colspan -= 1; + for (var rowIndex = row; rowIndex < row+cell.rowspan; rowIndex++) { + this.data[rowIndex][col+cell.colspan].spanned = false; + } + }, + + /** + * Removes a rowspan from a grid element. + * + * @param col integr + * @param row integer + * + * @return void + */ + removeRowspan: function(col, row) { + var cell = this.getCell(col, row); + if (!cell || !this.cellCanShrinkUp(col, row)) return false; + + cell.rowspan -= 1; + for (var colIndex = col; colIndex < col+cell.colspan; colIndex++) { + this.data[row+cell.rowspan][colIndex].spanned = false; + } + }, + + /** + * Exports the current grid to a TypoScript notation that can be read by the + * page module and is human readable. + * + * @return string + */ + export2LayoutRecord: function() { + var result = "be_layout {\n\tcolCount = "+this.colCount+"\n\trowCount = "+this.rowCount+ "\n\trows {\n"; + for (var row = 0; row < this.rowCount; row++) { + result += "\t\t"+(row+1)+" {\n"; + result += "\t\t\tcolumns {\n"; + colIndex = 0; + for (var col = 0; col < this.colCount; col++) { + var cell = this.getCell(col, row); + if (cell && !cell.spanned) { + colIndex++; + result += "\t\t\t\t"+(colIndex)+" {\n"; + result += "\t\t\t\t\tname = "+((!cell.name) ? col+"x"+row : cell.name)+"\n"; + if (cell.colspan > 1) result += "\t\t\t\t\tcolspan = "+cell.colspan+"\n"; + if (cell.rowspan > 1) result += "\t\t\t\t\trowspan = "+cell.rowspan+"\n"; + if (typeof(cell.column) === 'number') result += "\t\t\t\t\tcolPos = "+cell.column+"\n"; + result += "\t\t\t\t}\n"; + } + + } + result += "\t\t\t}\n"; + result += "\t\t}\n"; + } + + result += "\t}\n}\n"; + return result; + } +}); Index: typo3/sysext/cms/layout/res/pagemodul.css =================================================================== --- typo3/sysext/cms/layout/res/pagemodul.css (revision 0) +++ typo3/sysext/cms/layout/res/pagemodul.css (revision 0) @@ -0,0 +1,211 @@ +table.typo3-page-colHeader tr.colHeader td { + background-color: #B8BEC9; + background-image: url(../icons/gfx/shortcut_background.gif); + background-repeat: repeat-x; + padding-bottom: 2px; + padding-top: 2px; +} + +table.typo3-page-colHeader tr.colHeader td div { + text-align: center; + color: #333; + padding-top: 2px; +} + +table.typo3-page-colHeader tr.colHeader td div a.left { + float: left; +} +table.typo3-page-colHeader tr.colHeader td div a.right { + float: right; +} + +table.typo3-page-ceHeader tr.ceHeader td { + background-color: #B8BEC9; + background-image: url('../icons/gfx/alt_menu_mainitem_bg.gif'); + background-repeat: repeat-x; + color: #fff; +} + +div.normal-element { + border-left: 1px solid #D7DBE2; + border-right: 1px solid #D7DBE2; + border-bottom: 1px solid #D7DBE2; + padding: 2px; + min-height: 24px; + background-color: #E4E5F0; + overflow: hidden; +} +table.typo3-page-colHeader{ + margin-bottom: 5px; +} + +div.contentElement{ + position: relative; +} + +table.typo3-page-langMode div.contentElement{ + padding-bottom: 26px; +} + +table.typo3-page-cols div.contentElement{ + padding-bottom: 26px; +} + +td.gridCell{ + padding-left: 5px; + padding-right: 5px; +} + +div.contentElement div{ + padding-top: 0px; +} + +div.contentElement table tbody tr td.ttContentHeaderWrapper{ + height: 25px; + background-color: #adb5c0; + padding: 2px; +} + +div.contentElement *{ + opacity:0.9;filter:alpha(opacity=90); +} + +div.contentElement.active *{ + opacity:1.0;filter:alpha(opacity=100); +} + +table.typo3-page-ceFooter tr td{ + padding-top: 5px; + padding-bottom: 5px; +} + +tr.colSubHeader td{ + padding-top: 5px; + padding-bottom: 5px; +} + +div#typo3-inner-docbody div table{ + border: 0px; +} + +div#typo3-inner-docbody td.colContent{ + padding-left: 10px; + padding-right: 10px; + border: solid 1px; + border-color: #ccc; +} + +table.typo3-page-colHeader tbody tr.colHeader td.bgColor2{ + background-color: #aeb5c1; + background-image: url(''); +} + +img.languageFlag{ + opacity:0.8;filter:alpha(opacity=80); +} + +div.dropZone{ + height: 25px; + width: 100%; + visibility: hidden; +} + +div.dropZoneHighlight{ + border: dotted 1px; + border-color: #b5bcc7; + height: 23px; + text-align: center; + min-width: 150px; +} + +div.dropZone.active { + visibility: visible; + background-color: #ead2b7; + opacity:1.0;filter:alpha(opacity=100); +} + +div.dropZone.validDrop{ + background-color: #ff8700; +} + +div.columnDropZone{ + bottom: 0px; + margin-top: -30px; +} + +div.contentElementDropZoneAfter{ + position: absolute; + bottom: 0px; + margin-bottom: 0px; +} + +div.ttContentHeader{ + padding: 0px; + margin: 0px; + position: relative; +} + +div.ttContentHeader div.left{ + position: absolute; + left: 1px; + top: 2px; +} + +div.ttContentHeader div.right{ + position: absolute; + right: 1px; + top: 2px; +} + +.displayNone{ + display: none; +} + +.onDrag{ + border: solid 1px; + border-color: #cb2409; + width: 150px; + overflow: hidden; +} + +div.gridContainer { +} + +table.gridTable { + margin: -1px; + table-layout: fixed; +} + +.td.gridCell { + background-color: #efeff4; + height: 100%; + padding: 5px +} + +div.gridContainerNotEditable { + background-image: url(/typo3/sysext/cms/layout/res/grid.png); + border: 1px #bfbfc3 solid; + height: 100%; + padding: 0px 4px; + vertical-align: middle; + text-align: center; + color: gray; + font-weight: bold +} + +div.loadingSpinner { + position: absolute; + top: 0px; + left: 0px; + right: 0px; + bottom: 0px; + background-color: #fff; + z-index: 9999; +} + +span.dropMessage{ + display: block; + color: #fff; + font-weight: bold; + margin-top: 5px; +} Index: typo3/sysext/cms/layout/res/typo3.pageModule.js =================================================================== --- typo3/sysext/cms/layout/res/typo3.pageModule.js (revision 0) +++ typo3/sysext/cms/layout/res/typo3.pageModule.js (revision 0) @@ -0,0 +1,357 @@ + +var typo3pageModule = { + placeholder: null, + el: null, + idCache: {}, + spinner: null, + + /** + * Initialization + */ + init: function(){ + typo3pageModule.enableHighlighting(); + typo3pageModule.registerDragAndDrop(); + }, + + /** + * Each id param contains the id of the element and its language. + * + * Example: ttContent_4711_1 + * + * To use them on the client side they need to be split. This method + * splits the string in to a id and language part and caches it. + */ + _parseIdString: function(elementPart,idString){ + if(typo3pageModule.idCache[idString] == null){ + idArray = idString.replace(elementPart,'').split('_'); + var res = { + id: idArray[0], + language: idArray[1] + }; + + typo3pageModule.idCache[idString] = res; + } + + return typo3pageModule.idCache[idString]; + }, + + /** + * Appends a loading spinner to the body. + * + */ + showSpinner: function(){ + typo3pageModule.spinner = new Element('div'); + Ext.get(typo3pageModule.spinner).addClass('loadingSpinner').fadeIn({ endOpacity: .75, duration: 1}); + + Ext.select('body').appendChild(typo3pageModule.spinner); + }, + /** + * Removes the loading spinner from the body. + */ + hideSpinner: function(){ + Ext.get(typo3pageModule.spinner).fadeOut({ endOpacity: 1.0, duration: 1}).remove(); + }, + /** + * This method is used as an event handler when the + * user hovers the headline of an content element. + */ + enableContentHeader: function(e,t){ + var parent = Ext.get(t).findParent('div.contentElement',null,true); + parent.child('div.ttContentHeader').show(); + parent.addClass('active') + }, + + /** + * This method is used as event handler to hide the headline of + * an content element when the mouse of the user leaves the + * header of the content element. + */ + disableContentHeader: function(e,t){ + var parent = Ext.get(t).findParent('div.contentElement',null,true); + parent.child('div.ttContentHeader').hide(); + parent.removeClass('active'); + + }, + + /** + * This method is used to bind the higlighting function "enableContentHeader" + * to the mouseenter event and the "disableContentHeader" to the mouselease event. + */ + enableHighlighting: function(){ + Ext.select('div.contentElement').on('mouseenter',typo3pageModule.enableContentHeader,typo3pageModule).on('mouseleave',typo3pageModule.disableContentHeader,typo3pageModule); + }, + + /** + * This method is used to unbind the higlighting function "enableContentHeader" + * from the mouseenter event and the "disableContentHeader" from the mouselease event. + */ + disableHighlighting: function(){ + Ext.select('div.contentElement').un('mouseenter',typo3pageModule.enableContentHeader,typo3pageModule).un('mouseleave',typo3pageModule.disableContentHeader,typo3pageModule); + }, + + /** + * This method is used to create the draggable items and the drop zones. + * + * The method additionaly add eventhandler methods and passes the to the + * draggable object. + */ + registerDragAndDrop: function(){ + var overrides = { + // Called the instance the element is dragged. + b4StartDrag: typo3pageModule.b4StartDrag, + onInvalidDrop: typo3pageModule.invalidDrop, + endDrag: typo3pageModule.moveToDropTargetAndEnrich, + onDragDrop: typo3pageModule.handleElementDrop, + onDragEnter: typo3pageModule.enableDropZone, + onDragOut: typo3pageModule.disableDropZone + }; + + Ext.select('div.contentElement').each(function(el){ + var parsedId = typo3pageModule._parseIdString('ttContent_',el.dom.id); + var dd = new Ext.dd.DD(el, 'contentelements_' + parsedId.language, { isTarget : false}); + Ext.apply(dd, overrides); + }); + + Ext.select('div.columnDropZone').each(function(el){ + var parsedId = typo3pageModule._parseIdString('contentElementGroup_',el.parent().id); + var target = new Ext.dd.DDTarget(el,'contentelements_' + parsedId.language); + }); + Ext.select('div.contentElementDropZoneAfter').each(function(el){ + var parsedId = typo3pageModule._parseIdString('contentElementGroup_',el.parent().parent().id); + var target = new Ext.dd.DDTarget(el,'contentelements_' + parsedId.language); + }); + }, + + /** + * This method is used to higlight all drop zones for a certain + * language. + * + * @param int uid of the language + */ + highlightLanguageDropZones: function(languageId){ + Ext.select('div.dropZone.language_'+languageId).each(function(el){ + el.addClass('active'); + }); + + Ext.select('table.typo3-page-ceFooter').each( + function(el){ el.hide(); } + ); + }, + + /** + * This method unhighlights all drop zones. + */ + unhighlightAllDropZones: function(){ + Ext.select('div.dropZone').each(function(el){ + el.removeClass('active'); + }); + Ext.select('table.typo3-page-ceFooter').each( + function(el){ el.show(); } + ); + }, + + /** + * When an element is dragged a few layers will be hidden + * and the z-index will be increased to bring the element + * to the front. + * + * @param Ext.Element element + */ + reduceDraggedElement: function(element){ + element.select('table.typo3-page-ceHeader').addClass('displayNone'); + element.select('span.exampleContent').addClass('displayNone'); + element.select('div.contentElementDropZoneAfter').addClass('displayNone'); + element.addClass('onDrag'); + + var footerTable = element.select('table.typo3-page-ceFooter'); + if(footerTable != null){ + footerTable.addClass('displayNone'); + } + + var colSubHeader = element.select('tr.colSubHeader td'); + if(colSubHeader != null){ + colSubHeader.addClass('displayNone'); + } + + element.setStyle('z-index',999); + }, + + /** + * This method is used to display all hidden layers of a dragged + * element to bring it to the state before the dragging was started. + * + * @param Ext.Element element + */ + enrichDraggedElement: function(element){ + Ext.get(typo3pageModule.placeholder).remove(); + + element.select('table.typo3-page-ceHeader').removeClass('displayNone'); + element.select('span.exampleContent').removeClass('displayNone'); + element.select('div.contentElementDropZoneAfter').removeClass('displayNone'); + element.setStyle('z-index',null); + element.removeClass('onDrag'); + var footerTable = element.select('table.typo3-page-ceFooter'); + if(footerTable != null){ footerTable.removeClass('displayNone'); } + }, + + + /** + * Handler method for invalid drops. + */ + invalidDrop: function() { + // Set a flag to invoke the animated repair + this.invalidDrop = true; + }, + + /** + * Handler method before dragging starts. + */ + b4StartDrag: function(x,y) { + //disable the menubar highlighting during dragging + typo3pageModule.disableHighlighting(); + + // Cache the drag element + if (!this.el) { this.el = Ext.get(this.getEl()); } + + //Cache the original XY Coordinates of the element, we'll use this later. + this.originalXY = this.el.getXY(); + + //move the draggable item to the mouse position + this.setDelta(0,0); + + //highlight dropable targets + var parsedId = typo3pageModule._parseIdString('ttContent_',this.el.id); + typo3pageModule.highlightLanguageDropZones(parsedId.language); + + //calculate width and height before reducing + var heightBefore = this.el.getHeight(); + var widthBefore = this.el.getWidth(); + + //make some layers of the draggable element invisible + typo3pageModule.reduceDraggedElement(this.el); + + //caluclate height after reducing + var heightAfter = this.el.getHeight(); + var widthAfter = this.el.getWidth(); + + //create a placeholder for the dragged element + typo3pageModule.placeholder = new Element('div'); + typo3pageModule.placeholder.setStyle({position: 'relative', height: heightBefore - heightAfter+ 'px', width: widthBefore - widthAfter+ 'px'}); + + //insert placeholder before the dragged element + Ext.get(typo3pageModule.placeholder).insertAfter(this.el.prev()); + }, + /** + * Handler method for "endDrag" event. + * Used to move the element to the prev. position when + * the element has been droppen on an invalid location. + */ + moveToDropTargetAndEnrich: function() { + // Invoke the animation if the invalidDrop flag is set to true + + if (this.invalidDrop === true) { + var animCfgObj = { + easing : null, + duration : 0, + scope : this, + callback : function() { + // Remove the position attribute + this.el.dom.style.position = ''; + this.el.dom.style.left = 0; + this.el.dom.style.top = 0; + } + }; + + // Apply the repair animation + this.el.moveTo(this.originalXY[0], this.originalXY[1],animCfgObj); + typo3pageModule.enrichDraggedElement(this.el); + delete this.invalidDrop; + } + typo3pageModule.unhighlightAllDropZones(); + typo3pageModule.enableHighlighting(); + }, + + /** + * Event handler to process a valid drop. + */ + handleElementDrop: function(evtObj, targetElId) { + // Wrap the drop target element with Ext.Element + var dropEl = Ext.get(targetElId); + + // Perform the node move only if the drag element's + // parent is not the same as the drop target + if (this.el.dom.parentNode.id != targetElId) { + // Move the element + typo3pageModule.enrichDraggedElement(this.el); + + var ttContentParsedId = typo3pageModule._parseIdString('ttContent_',this.el.id); + var rowParsedId = typo3pageModule._parseIdString('contentElementGroup_',dropEl.findParent('div.contentElementGroup').id); + + if(dropEl.hasClass('contentElementDropZoneAfter')){ + var dropZoneAfterParsedId = typo3pageModule._parseIdString('contentElementDropZoneAfter_',dropEl.id); + var idBehind = dropZoneAfterParsedId.id; + this.el.insertAfter(dropEl.parent()); + } + if(dropEl.hasClass('columnDropZone')){ + var idBehind = pageId; + this.el.insertAfter(dropEl); + } + + var url = pageModuleMoveUrl.replace(/###MOVE_AFTER###/,idBehind).replace(/###MOVE_ITEM###/, ttContentParsedId.id ).replace(/###COL_POS###/,rowParsedId.id); + + typo3pageModule.showSpinner(); + + Ext.Ajax.request({ + url: url, + success: function(response, opts) { + typo3pageModule.hideSpinner(); + window.location.reload(); + }, + failure: function(response, opts) { alert('server-side failure with status code ' + response.status); } + }); + + // Remove the drag invitation + this.onDragOut(evtObj, targetElId); + + // Clear the styles + this.el.dom.style.position =''; + this.el.dom.style.top = ''; + this.el.dom.style.left = ''; + } + else { + // This was an invalid drop, initiate a repair + this.onInvalidDrop(); + } + }, + + /** + * This method is called when an element has been drag over a valid drop zone. + * It highlights the drop zone to indicate to the user, that he can drop an item here. + * + * @param event + * @param string idString of the target element. + */ + enableDropZone: function(evtObj, targetElId) { + if (targetElId != this.el.dom.parentNode.id) { + var dropEl = Ext.get(targetElId); + dropEl.addClass('validDrop'); + } + }, + /** + * This method is called when an element is removed from a dropZone. + * + * @param event + * @param string idString of the target element. + */ + disableDropZone: function(evtObj, targetElId) { + if (targetElId != this.el.dom.parentNode.id) { + + var dropEl = Ext.get(targetElId); + dropEl.removeClass('validDrop'); + } + } +} + +Event.observe(window, 'load', function() { + typo3pageModule.init(); +}); Index: typo3/sysext/cms/layout/wizard_be_layout.php =================================================================== --- typo3/sysext/cms/layout/wizard_be_layout.php (revision 0) +++ typo3/sysext/cms/layout/wizard_be_layout.php (revision 0) @@ -0,0 +1,285 @@ +includeLLFile('EXT:lang/locallang_wizards.xml'); + +/** + * Script Class for grid wizard + * + * @author T3UXW09 Team1 + * @package TYPO3 + * @subpackage core + */ +class SC_wizard_be_layout { + + // GET vars: + var $P; // Wizard parameters, coming from TCEforms linking to the wizard. + + /** + * document template object + * + * @var smallDoc + */ + var $doc; + var $content; // Accumulated content. + + + /** + * Initialises the Class + * + * @return void + */ + function init() { + + + // Setting GET vars (used in frameset script): + $this->P = t3lib_div::_GP('P', 1); + + //data[layouts][2][config] + $this->formName = $this->P['formName']; + $this->fieldName = $this->P['itemName']; + $this->md5ID = $this->P['md5ID']; + $uid = intval($this->P['uid']); + + // Initialize document object: + $this->doc = t3lib_div::makeInstance('noDoc'); + $this->doc->backPath = $GLOBALS['BACK_PATH']; + + $pageRenderer = $this->doc->getPageRenderer(); + $pageRenderer->addJsFile($GLOBALS['BACK_PATH'] . TYPO3_MOD_PATH . 'res/grideditor.js'); + $pageRenderer->addJsInlineCode('storeData', ' + function storeData(data) { + if (parent.opener && parent.opener.document && parent.opener.document.' . $this->formName . ' && parent.opener.document.' . $this->formName . '["' . $this->fieldName . '"]) { + parent.opener.document.' . $this->formName . '["' . $this->fieldName . '"].value = data; + parent.opener.TBE_EDITOR.fieldChanged("be_layouts","' . $uid . '","config","data[be_layouts][' . $uid . '][config]"); + } + } + '); + + $languageLabels = array( + 'save' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_wizards.xml:grid_labelSave', 1), + 'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_wizards.xml:grid_windowTitle', 1), + 'name' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_wizards.xml:grid_labelName', 1), + 'column' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_wizards.xml:grid_labelColumn', 1) + ); + $pageRenderer->addInlineLanguageLabelArray($languageLabels); + + // select record + $record = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows($this->P['field'], $this->P['table'], 'uid=' . intval($this->P['uid'])); + if (trim($record[0][$this->P['field']]) == '') { + $t3GridData = "[[{colspan:1,rowspan:1,spanned:false,name:''}]]"; + $colCount = 1; + $rowCount = 1; + } else { + + // load TS parser + $parser = t3lib_div::makeInstance('t3lib_TSparser'); + $parser->parse($record[0][$this->P['field']]); + $data = $parser->setup['be_layout.']; + $t3GridData = '['; + $colCount = $data['colCount']; + $rowCount = $data['rowCount']; + $dataRows = $data['rows.']; + $spannedMatrix = array(); + + for ($i = 1; $i <= $rowCount; $i++) { + $rowString = ''; + for ($j = 1; $j <= $colCount; $j++) { + if ($j == 1) { + $row = array_shift($dataRows); + $columns = $row['columns.']; + $rowString = '['; + $cells = array(); + } + if (!$spannedMatrix[$i][$j]) { + if (is_array($columns) && count($columns)) { + $column = array_shift($columns); + $cellString = '{'; + $cellData = array(); + if (isset($column['colspan'])) { + $cellData[] = 'colspan:' . intval($column['colspan']); + if (isset($column['rowspan'])) { + for ($spanRow = 0; $spanRow < intval($column['rowspan']); $spanRow++) { + for ($spanColumn = 0; $spanColumn < intval($column['colspan']); $spanColumn++) { + $spannedMatrix[$i + $spanRow][$j + $spanColumn] = 1; + } + } + } else { + for ($spanColumn = 0; $spanColumn < intval($column['colspan']); $spanColumn++) { + $spannedMatrix[$i][$j + $spanColumn] = 1; + } + } + } else { + $cellData[] = 'colspan:1'; + if (isset($column['rowspan'])) { + for ($spanRow = 0; $spanRow < intval($column['rowspan']); $spanRow++) { + $spannedMatrix[$i + $spanRow][$j] = 1; + } + } + } + if (isset($column['rowspan'])) { + $cellData[] = 'rowspan:' . intval($column['rowspan']); + } else { + $cellData[] = 'rowspan:1'; + } + if (isset($column['name'])) { + $cellData[] = 'name:\'' . $column['name'] . '\''; + } + if (isset($column['colPos'])) { + $cellData[] = 'column:' . $column['colPos']; + } + + $cellString .= implode(',', $cellData) . '}'; + $cells[] = $cellString; + + } + } else { + $cells[] = '{colspan:1,rowspan:1,spanned:1}'; + } + } + $rowString .= implode(',', $cells); + if ($rowString) { + $rowString .= ']'; + } + $rows[] = $rowString; + ksort($spannedMatrix[$i]); + } + + $t3GridData .= implode(',', $rows) . ']'; + + + } + + $this->doc->JScode .= ' + + '; + + + $this->doc->styleSheetFile_post = TYPO3_MOD_PATH . 'res/grideditor.css'; + $this->doc->styleSheetFile2 = 'sysext/t3skin/stylesheets/extjs/xtheme-t3skin.css'; + } + + /** + * Main Method, rendering either colorpicker or frameset depending on ->showPicker + * + * @return void + */ + function main() { + + $content .= '' . + t3lib_iconWorks::getSpriteIcon('actions-document-save') . ''; + + $content .= '' . + t3lib_iconWorks::getSpriteIcon('actions-document-save-close') . ''; + + $content .= '' . + t3lib_iconWorks::getSpriteIcon('actions-document-close') . ''; + + + $content .= $this->doc->spacer(10); + + $content .= ' + + + + + + + + +
+
+
+
+ + +
+ + + +
+ + + + + + +
+ '; + + $this->content = $content; + } + + /** + * Returnes the sourcecode to the browser + * + * @return void + */ + function printContent() { + echo $this->doc->render( + 'Grid wizard', + $this->content + ); + } + +} + + +if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/wizard_be_layout.php']) { + include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/wizard_be_layout.php']); +} + + +// Make instance: +$SOBE = t3lib_div::makeInstance('SC_wizard_be_layout'); +$SOBE->init(); +$SOBE->main(); +$SOBE->printContent(); + +?> Index: typo3/sysext/cms/locallang_tca.xml =================================================================== --- typo3/sysext/cms/locallang_tca.xml (revision 9392) +++ typo3/sysext/cms/locallang_tca.xml (working copy) @@ -151,6 +151,8 @@ + + @@ -201,6 +203,12 @@ + + + + + + Index: typo3/sysext/cms/tbl_cms.php =================================================================== --- typo3/sysext/cms/tbl_cms.php (revision 9392) +++ typo3/sysext/cms/tbl_cms.php (working copy) @@ -996,5 +996,81 @@ ) ); +// ****************************************************************** +// be_layouts +// ****************************************************************** +/** + * @todo add lll + */ +$TCA['be_layouts'] = array( + 'ctrl' => $TCA['be_layouts']['ctrl'], + 'interface' => array( + 'showRecordFieldList' => 'title,config,description,hidden,icon' + ), + 'columns' => array( + 'title' => array( + 'label' => 'LLL:EXT:cms/locallang_tca.xml:be_layouts.title', + 'config' => array( + 'type' => 'input', + 'size' => '25', + 'max' => '256', + 'eval' => 'required' + ) + ), + 'description' => array( + 'label' => 'LLL:EXT:cms/locallang_tca.xml:be_layouts.description', + 'config' => array( + 'type' => 'text', + 'rows' => '5', + 'cols' => '25', + ) + ), + 'config' => array( + 'label' => 'LLL:EXT:cms/locallang_tca.xml:be_layouts.config', + 'config' => array( + 'type' => 'text', + 'rows' => '5', + 'cols' => '25', + 'wizards' => Array( + '_PADDING' => 4, + 0 => Array( + 'title' => 'LLL:EXT:cms/locallang_tca.xml:be_layouts.wizard', + 'type' => 'popup', + 'icon' => t3lib_extMgm::extRelPath('cms').'layout/wizard_be_layout.png', + 'script' => t3lib_extMgm::extRelPath('cms').'layout/wizard_be_layout.php', + 'JSopenParams' => 'height=800,width=800,status=0,menubar=0,scrollbars=0', + ), + ), + ) + ), + 'hidden' => array( + 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.disable', + 'exclude' => 1, + 'config' => array( + 'type' => 'check', + 'default' => '0' + ) + ), + 'icon' => array( + 'label' => 'LLL:EXT:cms/locallang_tca.xml:be_layouts.icon', + 'exclude' => 1, + 'config' => array( + 'type' => 'group', + 'internal_type' => 'file', + 'allowed' => 'jpg,gif,png', + 'uploadfolder' => 'uploads/media', + 'show_thumbs' => 1, + 'size' => 1, + 'maxitems' => 1 + ) + ), + ), + 'types' => array( + '1' => array('showitem' => ' + hidden,title;;1;;2-2-2, icon, description, config' + ) + ) +); + ?> \ No newline at end of file Index: typo3/sysext/cms/tbl_tt_content.php =================================================================== --- typo3/sysext/cms/tbl_tt_content.php (revision 9392) +++ typo3/sysext/cms/tbl_tt_content.php (working copy) @@ -297,6 +297,7 @@ 'label' => 'LLL:EXT:cms/locallang_ttc.xml:colPos', 'config' => array( 'type' => 'select', + 'itemsProcFunc' => 'EXT:cms/class.tx_cms_be_layout.php:tx_cms_be_layout->colPosListItemProcFunc', 'items' => array( array( 'LLL:EXT:cms/locallang_ttc.xml:colPos.I.0', @@ -1174,7 +1175,7 @@ array( '8', '8', - ), + ), array( '9', '9', @@ -1658,10 +1659,10 @@ 'showitem' => 'CType', ), 'header' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, - --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.headers;headers, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.headers;headers, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1669,12 +1670,12 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'text' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, bodytext;LLL:EXT:cms/locallang_ttc.xml:bodytext_formlabel;;richtext:rte_transform[flag=rte_enabled|mode=ts_css], rte_enabled;LLL:EXT:cms/locallang_ttc.xml:rte_enabled_formlabel, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1683,7 +1684,7 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'textpic' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, bodytext;Text;;richtext:rte_transform[flag=rte_enabled|mode=ts_css], @@ -1691,8 +1692,8 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.images, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.imagefiles;imagefiles, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.imagelinks;imagelinks, - --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.image_accessibility;image_accessibility, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.image_accessibility;image_accessibility, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1709,7 +1710,7 @@ --palette--;LLL:EXT:cms/locallang.xml:palette.imagefiles;imagefiles, --palette--;LLL:EXT:cms/locallang.xml:palette.imagelinks;imagelinks, --palette--;LLL:EXT:cms/locallang.xml:palette.image_accessibility;image_accessibility, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1719,11 +1720,11 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'bullets' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, bodytext;LLL:EXT:cms/locallang_ttc.xml:bodytext.ALT.bulletlist_formlabel;;nowrap, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1732,11 +1733,11 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'table' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, bodytext;LLL:EXT:cms/locallang_ttc.xml:bodytext.ALT.table_formlabel;;nowrap:wizards[table], - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1746,11 +1747,11 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'splash' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.textbox;textbox, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1758,11 +1759,11 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'uploads' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, --palette--;LLL:EXT:cms/locallang_ttc.xml:media;uploads, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1775,7 +1776,7 @@ --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.media, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.multimediafiles;multimediafiles, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1787,7 +1788,7 @@ --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.media, pi_flexform; ;, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1797,15 +1798,15 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'script' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, header;LLL:EXT:cms/locallang_ttc.xml:header.ALT.script_formlabel, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.script, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.script, select_key;LLL:EXT:cms/locallang_ttc.xml:select_key.ALT.script_formlabel, pages;LLL:EXT:cms/locallang_ttc.xml:pages.ALT.script_formlabel, bodytext;LLL:EXT:cms/locallang_ttc.xml:bodytext.ALT.script_formlabel;;nowrap, imagecaption;LLL:EXT:cms/locallang_ttc.xml:imagecaption.ALT.script_formlabel, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1813,11 +1814,11 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'menu' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, - --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, - --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.menu;menu, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, + --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.menu;menu, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1825,24 +1826,24 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'mailform' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, bodytext;LLL:EXT:cms/locallang_ttc.xml:bodytext.ALT.mailform_formlabel;;nowrap:wizards[forms], - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.frames;frames, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.behaviour, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.mailform;mailform, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'search' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1852,10 +1853,10 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'login' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1865,11 +1866,11 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'shortcut' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, header;LLL:EXT:cms/locallang_ttc.xml:header.ALT.shortcut_formlabel, records;LLL:EXT:cms/locallang_ttc.xml:records_formlabel, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1877,19 +1878,19 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'list' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.plugin, - list_type;LLL:EXT:cms/locallang_ttc.xml:list_type_formlabel, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + list_type;LLL:EXT:cms/locallang_ttc.xml:list_type_formlabel, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.frames;frames, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.behaviour, select_key;LLL:EXT:cms/locallang_ttc.xml:select_key_formlabel, - pages;LLL:EXT:cms/locallang_ttc.xml:pages.ALT.list_formlabel, + pages;LLL:EXT:cms/locallang_ttc.xml:pages.ALT.list_formlabel, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', 'subtype_value_field' => 'list_type', 'subtypes_excludelist' => array( @@ -1910,10 +1911,10 @@ ), ), 'div' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, header;LLL:EXT:cms/locallang_ttc.xml:header.ALT.div_formlabel, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -1921,11 +1922,11 @@ --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.extended', ), 'html' => array( - 'showitem' => + 'showitem' => '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, header;LLL:EXT:cms/locallang_ttc.xml:header.ALT.html_formlabel, bodytext;LLL:EXT:cms/locallang_ttc.xml:bodytext.ALT.html_formlabel;;nowrap, - --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, + --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access, --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance, @@ -2012,11 +2013,11 @@ 'image_settings' => array( 'showitem' => 'imagewidth;LLL:EXT:cms/locallang_ttc.xml:imagewidth_formlabel, imageheight;LLL:EXT:cms/locallang_ttc.xml:imageheight_formlabel, imageborder;LLL:EXT:cms/locallang_ttc.xml:imageborder_formlabel, --linebreak--, image_compression;LLL:EXT:cms/locallang_ttc.xml:image_compression_formlabel, image_effects;LLL:EXT:cms/locallang_ttc.xml:image_effects_formlabel, image_frames;LLL:EXT:cms/locallang_ttc.xml:image_frames_formlabel', 'canNotCollapse' => 1, - ), + ), 'imageblock' => array( 'showitem' => 'imageorient;LLL:EXT:cms/locallang_ttc.xml:imageorient_formlabel, imagecols;LLL:EXT:cms/locallang_ttc.xml:imagecols_formlabel, --linebreak--, image_noRows;LLL:EXT:cms/locallang_ttc.xml:image_noRows_formlabel, imagecaption_position;LLL:EXT:cms/locallang_ttc.xml:imagecaption_position_formlabel', 'canNotCollapse' => 1, - ), + ), 'uploads' => array( 'showitem' => 'select_key;LLL:EXT:cms/locallang_ttc.xml:select_key.ALT.uploads_formlabel, --linebreak--, media;LLL:EXT:cms/locallang_ttc.xml:media.ALT.uploads_formlabel, imagecaption;LLL:EXT:cms/locallang_ttc.xml:imagecaption.ALT.uploads_formlabel;;nowrap', 'canNotCollapse' => 1, @@ -2024,19 +2025,19 @@ 'mailform' => array( 'showitem' => 'pages;LLL:EXT:cms/locallang_ttc.xml:pages.ALT.forms, --linebreak--, subheader;LLL:EXT:cms/locallang_ttc.xml:subheader.ALT.mailform_formlabel', 'canNotCollapse' => 1, - ), + ), 'searchform' => array( 'showitem' => 'pages;LLL:EXT:cms/locallang_ttc.xml:pages.ALT.searchform', 'canNotCollapse' => 1, - ), + ), 'loginform' => array( 'showitem' => 'pages;LLL:EXT:cms/locallang_ttc.xml:pages.ALT.loginform', 'canNotCollapse' => 1, - ), + ), 'menu' => array( 'showitem' => 'menu_type;LLL:EXT:cms/locallang_ttc.xml:menu_type_formlabel, --linebreak--, pages;LLL:EXT:cms/locallang_ttc.xml:pages.ALT.menu_formlabel', 'canNotCollapse' => 1, - ), + ), 'visibility' => array( 'showitem' => 'hidden;LLL:EXT:cms/locallang_ttc.xml:hidden_formlabel, sectionIndex;LLL:EXT:cms/locallang_ttc.xml:sectionIndex_formlabel, linkToTop;LLL:EXT:cms/locallang_ttc.xml:linkToTop_formlabel', 'canNotCollapse' => 1, @@ -2056,7 +2057,7 @@ 'tablelayout' => array ( 'showitem' => 'table_bgColor;LLL:EXT:cms/locallang_ttc.xml:table_bgColor_formlabel, table_border;LLL:EXT:cms/locallang_ttc.xml:table_border_formlabel, table_cellspacing;LLL:EXT:cms/locallang_ttc.xml:table_cellspacing_formlabel, table_cellpadding;LLL:EXT:cms/locallang_ttc.xml:table_cellpadding_formlabel', 'canNotCollapse' => 1, - ), + ), 'uploadslayout' => array ( 'showitem' => 'filelink_size;LLL:EXT:cms/locallang_ttc.xml:filelink_size_formlabel', 'canNotCollapse' => 1, @@ -2065,4 +2066,4 @@ ); -?> \ No newline at end of file +?> Index: typo3/sysext/lang/locallang_wizards.xml =================================================================== --- typo3/sysext/lang/locallang_wizards.xml (revision 9392) +++ typo3/sysext/lang/locallang_wizards.xml (working copy) @@ -75,6 +75,10 @@ + + + + \ No newline at end of file