Fixed bug #16622: PageTree - Milestone 2 Release (Thanks to Stefan Galinski + Peter...
authorSteffen Kamper <info@sk-typo3.de>
Wed, 1 Dec 2010 11:50:08 +0000 (11:50 +0000)
committerSteffen Kamper <info@sk-typo3.de>
Wed, 1 Dec 2010 11:50:08 +0000 (11:50 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@9713 709f56b5-9817-0410-a4d7-c38de5d9e867

28 files changed:
ChangeLog
typo3/sysext/pagetree/classes/class.tx_pagetree_commands.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/class.tx_pagetree_node.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/class.tx_pagetree_stateprovider.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/contextmenu/class.tx_pagetree_contextmenu_action.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php [new file with mode: 0644]
typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php [new file with mode: 0644]
typo3/sysext/pagetree/components/pagetree/javascript/Ext.ux.plugins.TreePanelStateful.js [new file with mode: 0644]
typo3/sysext/pagetree/components/pagetree/javascript/actions.js [new file with mode: 0644]
typo3/sysext/pagetree/components/pagetree/javascript/contextmenu.js
typo3/sysext/pagetree/components/pagetree/javascript/contextmenuactions.js [deleted file]
typo3/sysext/pagetree/components/pagetree/javascript/deletiondropzone.js
typo3/sysext/pagetree/components/pagetree/javascript/featurepanel.js
typo3/sysext/pagetree/components/pagetree/javascript/overrides.js [new file with mode: 0644]
typo3/sysext/pagetree/components/pagetree/javascript/pageactions.js [deleted file]
typo3/sysext/pagetree/components/pagetree/javascript/pagetree.js
typo3/sysext/pagetree/components/pagetree/javascript/tree.js
typo3/sysext/pagetree/ext_autoload.php
typo3/sysext/pagetree/ext_emconf.php
typo3/sysext/pagetree/ext_localconf.php
typo3/sysext/pagetree/ext_tables.php
typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php [deleted file]
typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_pagetree.php [deleted file]
typo3/sysext/pagetree/locallang_pagetree.xml

index fb91df9..f99409e 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 2010-12-01  Steffen Kamper  <steffen@typo3.org>
 
+       * Fixed bug #16622: PageTree - Milestone 2 Release (Thanks to Stefan Galinski + Peter Foerger)
        * Fixed bug #16621: Stabilize the Context Menu API (Thanks to Stefan Galinski)
        * Fixed bug #16463: Bug: Custom configured modules can't be enabled for non-admins (Thanks to Bastian Waidelich)
        * Fixed bug #16091: ExtDirect calls get cached with domain resulting in "unable to connect to the server" exceptions (Thanks to Andreas Kiessling)
diff --git a/typo3/sysext/pagetree/classes/class.tx_pagetree_commands.php b/typo3/sysext/pagetree/classes/class.tx_pagetree_commands.php
new file mode 100644 (file)
index 0000000..ebd95de
--- /dev/null
@@ -0,0 +1,244 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Page Tree and Context Menu Commands
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+final class tx_pagetree_Commands {
+       /**
+        * Visibly the page
+        *
+        * @param tx_pagetree_Node $nodeData
+        * @return void
+        */
+       public static function visiblyNode(tx_pagetree_Node $node) {
+               $data['pages'][$node->getId()]['hidden'] = 0;
+               self::processTceCmdAndDataMap(array(), $data);
+       }
+
+       /**
+        * Hide the page
+        *
+        * @param tx_pagetree_Node $nodeData
+        * @return void
+        */
+       public static function disableNode(tx_pagetree_Node $node) {
+               $data['pages'][$node->getId()]['hidden'] = 1;
+               self::processTceCmdAndDataMap(array(), $data);
+       }
+
+       /**
+        * Delete the page
+        *
+        * @param tx_pagetree_Node $nodeData
+        * @return void
+        */
+       public static function deleteNode(tx_pagetree_Node $node) {
+               $cmd['pages'][$node->getId()]['delete'] = 1;
+               self::processTceCmdAndDataMap($cmd);
+       }
+
+       /**
+        * Restore the page
+        *
+        * @param tx_pagetree_Node $nodeData
+        * @return void
+        */
+       public static function restoreNode(tx_pagetree_Node $node) {
+               $cmd['pages'][$node->getId()]['undelete'] = 1;
+               self::processTceCmdAndDataMap($cmd);
+       }
+
+       /**
+        * Updates the node label
+        *
+        * @param tx_pagetree_Node $nodeData
+        * @param string $updatedLabel
+        * @return void
+        */
+       public static function updateNodeLabel(tx_pagetree_Node $node, $updatedLabel) {
+               $updatedLabel = str_replace($node->getPrefix(), '', $updatedLabel);
+               $data['pages'][$node->getId()][$node->getTextSourceField()] = $updatedLabel;
+               self::processTceCmdAndDataMap(array(), $data);
+       }
+
+       /**
+        * Copies a page and returns the id of the new page
+        *
+        * Node: Use a negative target id to specify a sibling target else the parent is used
+        *
+        * @param tx_pagetree_Node $sourceNode
+        * @param int $targetId
+        * @return int
+        */
+       public static function copyNode(tx_pagetree_Node $sourceNode, $targetId) {
+               $cmd['pages'][$sourceNode->getId()]['copy'] = $targetId;
+               $returnValue = self::processTceCmdAndDataMap($cmd);
+
+               return $returnValue['pages'][$sourceNode->getId()];
+       }
+
+       /**
+        * Moves a page
+        *
+        * Node: Use a negative target id to specify a sibling target else the parent is used
+        *
+        * @param tx_pagetree_Node $sourceNode
+        * @param int $targetId
+        * @return void
+        */
+       public static function moveNode(tx_pagetree_Node $sourceNode, $targetId) {
+               $cmd['pages'][$sourceNode->getId()]['move'] = $targetId;
+               self::processTceCmdAndDataMap($cmd);
+       }
+
+       /**
+        * Creates a page of the given doktype and returns the id of the created page
+        *
+        * @param tx_pagetree_Node $parentNode
+        * @param int $targetId
+        * @param int $pageType
+        * @return int
+        */
+       public static function createNode(tx_pagetree_Node $parentNode, $targetId, $pageType) {
+               $placeholder = 'NEW12345';
+               $data['pages'][$placeholder] = array(
+                       'pid' => $parentNode->getId(),
+                       'doktype' => $pageType,
+                       'title' => $GLOBALS['LANG']->sL('LLL:EXT:pagetree/locallang_pagetree.xml:defaultTitle', TRUE),
+               );
+               $newPageId = self::processTceCmdAndDataMap(array(), $data);
+               $node = self::getNode($newPageId[$placeholder]);
+
+               if ($parentNode->getId() !== $targetId) {
+                       self::moveNode($node, $targetId);
+               }
+
+               return $newPageId[$placeholder];
+       }
+
+       /**
+        * Process TCEMAIN commands and data maps
+        *
+        * Command Map:
+        * Used for moving, recover, remove and some more operations.
+        *
+        * Data Map:
+        * Used for creating and updating records,
+        *
+        * This API contains all necessary access checks.
+        *
+        * @param array $cmd
+        * @param array $data
+        * @throws Exception if an error happened while the TCE processing
+        * @return array
+        */
+       protected static function processTceCmdAndDataMap(array $cmd, array $data = array()) {
+               /** @var $tce t3lib_TCEmain */
+               $tce = t3lib_div::makeInstance('t3lib_TCEmain');
+               $tce->stripslashes_values = 0;
+               $tce->start($data, $cmd);
+
+               if (count($cmd)) {
+                       $tce->process_cmdmap();
+                       $returnValues = $tce->copyMappingArray_merged;
+               } elseif (count($data)) {
+                       $tce->process_datamap();
+                       $returnValues = $tce->substNEWwithIDs;
+               }
+
+                       // check errors
+               if (count($tce->errorLog)) {
+                       throw new Exception(implode(chr(10), $tce->errorLog));
+               }
+
+               return $returnValues;
+       }
+
+       /**
+        * Returns a node from the given node id
+        *
+        * @param int $nodeId
+        * @return tx_pagetree_Node
+        */
+       public static function getNode($nodeId) {
+               $record = self::getNodeRecord($nodeId);
+               return self::getNewNode($record);
+       }
+
+       /**
+        * Returns a node record from a given id
+        *
+        * @param int $nodeId
+        * @return array
+        */
+       public static function getNodeRecord($nodeId) {
+               return t3lib_BEfunc::getRecordWSOL('pages', $nodeId, '*', '', TRUE);
+       }
+
+       /**
+        * Creates a node with the given record information's
+        *
+        * @param array $record
+        * @return tx_pagetree_Node
+        */
+       public static function getNewNode($record) {
+               $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+               $addIdAsPrefix = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
+
+               /** @var $subNode tx_pagetree_Node */
+               $subNode = t3lib_div::makeInstance('tx_pagetree_Node');
+               $subNode->setRecord($record);
+               $subNode->setId($record['uid']);
+               $subNode->setQTip('ID: ' . $record['uid']);
+
+               $field = 'title';
+               $text = $record['title'];
+               if ($useNavTitle && trim($record['nav_title']) !== '') {
+                       $field = 'nav_title';
+                       $text = $record['nav_title'];
+               }
+
+               $prefix = ($addIdAsPrefix ? '[' . $record['uid'] . '] ' : '');
+               $subNode->setText($text, $field, $prefix);
+
+               if ($record['uid'] !== 0) {
+                       $spriteIconCode = t3lib_iconWorks::getSpriteIconForRecord('pages', $record);
+               } else {
+                       $spriteIconCode = t3lib_iconWorks::getSpriteIcon('apps-pagetree-root');
+               }
+               $subNode->setSpriteIconCode($spriteIconCode);
+
+               return $subNode;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php b/typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php
new file mode 100644 (file)
index 0000000..9ee93eb
--- /dev/null
@@ -0,0 +1,198 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Abstract Tree Data Provider
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
+       /**
+        * Returns the root node
+        *
+        * Not used for the page tree, because the multiple domains/roots feature
+        *
+        * @return t3lib_tree_Node
+        */
+       public function getRoot() {
+               return NULL;
+       }
+
+       /**
+        * Fetches the sub-nodes of the given node
+        *
+        * @param t3lib_tree_Node $node
+        * @return t3lib_tree_NodeCollection
+        */
+        public function getNodes(t3lib_tree_Node $node) {
+               /** @var $nodeCollection tx_pagetree_NodeCollection */
+               $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+               $subpages = $this->getSubpages($node->getId());
+               if (!is_array($subpages) || !count($subpages)) {
+                       return $nodeCollection;
+               }
+
+               foreach ($subpages as $subpage) {
+                       $subpage = t3lib_befunc::getRecordWSOL('pages', $subpage['uid'], '*', '', TRUE);
+
+                       $subNode = tx_pagetree_Commands::getNewNode($subpage);
+                       $childNodes = $this->getNodes($subNode);
+                       $subNode->setChildNodes($childNodes);
+
+                       $nodeCollection->append($subNode);
+               }
+
+               return $nodeCollection;
+       }
+
+       /**
+        * Returns a node collection of filtered nodes
+        *
+        * @param string $searchFilter
+        * @return void
+        */
+       public function getFilteredNodes($searchFilter) {
+               /** @var $nodeCollection tx_pagetree_NodeCollection */
+               $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+               $subpages = $this->getSubpages(-1, $searchFilter);
+               if (!is_array($subpages) || !count($subpages)) {
+                       return $nodeCollection;
+               }
+
+               foreach ($subpages as $subpage) {
+                       $rootline = array_reverse(t3lib_BEfunc::BEgetRootLine($subpage['uid']));
+                       array_shift($rootline);
+                       $reference = $nodeCollection;
+
+                       foreach ($rootline as $rootlineElement) {
+                               if ($reference->offsetExists($rootlineElement['uid'])) {
+                                       /** @var $node tx_pagetree_Node */
+                                       $node = $reference->offsetGet($rootlineElement['uid']);
+                                       $reference = $node->getChildNodes();
+                                       continue;
+                               }
+
+                               /** @var $childCollection tx_pagetree_NodeCollection */
+                               $childCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+                               $node = tx_pagetree_Commands::getNewNode($rootlineElement);
+                               $node->setExpanded(TRUE);
+                               $node->setChildNodes($childCollection);
+                               $node->setLeaf(FALSE);
+                               $node->setText(str_replace(
+                                       $searchFilter,
+                                       '<strong class="pagetree-highlight">' . $searchFilter . '</strong>',
+                                       $node->getText()
+                               ));
+
+                               $reference->offsetSet($rootlineElement['uid'], $node);
+                               $reference = $childCollection;
+                       }
+               }
+
+               return $nodeCollection;
+       }
+
+       /**
+        * Returns the page tree mounts for the current user
+        *
+        * @return array
+        */
+       public function getTreeMounts() {
+               /** @var $nodeCollection tx_pagetree_NodeCollection */
+               $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+               $webmountIds = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
+               if (empty($webmountIds)) {
+                       return $nodeCollection;
+               }
+
+               foreach ($webmountIds as $webmount) {
+                       if ($webmount === 0) {
+                               $sitename = 'TYPO3';
+                               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] !== '') {
+                                       $sitename = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
+                               }
+
+                               $record = array(
+                                       'uid' => 0,
+                                       'title' => $sitename,
+                               );
+                               $subNode = tx_pagetree_Commands::getNewNode($record);
+                               $subNode->setEditableLable(FALSE);
+                               $subNode->setType('root');
+                       } else {
+                               $record = t3lib_BEfunc::getRecordWSOL('pages', $webmount, '*', '', TRUE);
+                               $subNode = tx_pagetree_Commands::getNewNode($record);
+                       }
+
+                       $childNodes = $this->getNodes($subNode);
+                       $subNode->setChildNodes($childNodes);
+
+                       $nodeCollection->append($subNode);
+               }
+
+               return $nodeCollection;
+       }
+
+       /**
+        * Returns all sub-pages of a given id
+        *
+        * @param int $id
+        * @param string $searchFilter
+        * @return array
+        */
+       protected function getSubpages($id, $searchFilter = '') {
+               $where = $GLOBALS['BE_USER']->getPagePermsClause(1)
+                       . t3lib_BEfunc::deleteClause('pages')
+                       . t3lib_BEfunc::versioningPlaceholderClause('pages');
+
+               if (is_numeric($id) && $id >= 0) {
+                       $where .= ' AND pid= ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(intval($id), 'pages');
+               }
+
+               if ($searchFilter !== '') {
+                       $where .= ' AND title LIKE ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchFilter . '%', 'pages');
+               }
+
+               $subpages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+                       'uid', 'pages', $where, '', 'sorting', '', 'uid'
+               );
+
+               return $subpages;
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/class.tx_pagetree_node.php b/typo3/sysext/pagetree/classes/class.tx_pagetree_node.php
new file mode 100644 (file)
index 0000000..f9d85ee
--- /dev/null
@@ -0,0 +1,630 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Node designated for the page tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_Node extends t3lib_tree_Node {
+       /**
+        * Node type
+        *
+        * @var string
+        */
+       protected $type = 'page';
+
+       /**
+        * Leaf Node Indicator
+        *
+        * @var bool
+        */
+       protected $leaf = TRUE;
+
+       /**
+        * Expanded Node Indicator
+        *
+        * @var bool
+        */
+       protected $expanded = FALSE;
+
+       /**
+        * Label
+        *
+        * @var string
+        */
+       protected $text = '';
+
+       /**
+        * Prefix text of the label
+        *
+        * @var string
+        */
+       protected $prefix = '';
+
+       /**
+        * CSS Class
+        *
+        * @var string
+        */
+       protected $cls = '';
+
+       /**
+        * Quick Tip
+        *
+        * @var string
+        */
+       protected $qtip = '';
+
+       /**
+        * Sprite Icon HTML
+        *
+        * @var string
+        */
+       protected $spriteIconCode = '';
+
+       /**
+        * Text source field (title, nav_title, ...)
+        *
+        * @var string
+        */
+       protected $t3TextSourceField = '';
+
+       /**
+        * Callback action on a node click
+        *
+        * @var string
+        */
+       protected $t3CallbackAction = 'TYPO3.Components.PageTree.PageActions.singleClick';
+
+       /**
+        * Indicator if the copy mode is activated
+        *
+        * @var bool
+        */
+       protected $t3InCopyMode = FALSE;
+
+       /**
+        * Indicator if the cut mode is activated
+        *
+        * @var bool
+        */
+       protected $t3InCutMode = FALSE;
+
+       /**
+        * Database record (not serialized or merged into the result array!)
+        *
+        * @var array
+        */
+       protected $record = array();
+
+       /**
+        * Context Info
+        *
+        * @var array
+        */
+       protected $contextInfo = array();
+
+       /**
+        * Cached access rights to save some performance
+        *
+        * @var array
+        */
+       protected $cachedAccessRights = array();
+
+       /**
+        * Indicator if the label is editable
+        *
+        * @var bool
+        */
+       protected $editableLabel = TRUE;
+
+       /**
+        * Set's the node type
+        *
+        * @param string $type
+        * @return void
+        */
+       public function setType($type) {
+               $this->type = $type;
+       }
+
+       /**
+        * Returns the node type
+        *
+        * @return string
+        */
+       public function getType() {
+               return $this->type;
+       }
+
+       /**
+        * Sets the leaf node indicator
+        *
+        * @param bool $isLeaf
+        * @return void
+        */
+       public function setLeaf($isLeaf) {
+               $this->leaf = $isLeaf;
+       }
+
+       /**
+        * Returns if the node is a leaf node
+        *
+        * @return bool
+        */
+       public function isLeafNode() {
+               return $this->leaf;
+       }
+
+       /**
+        * Sets the expanded indicator
+        *
+        * @param bool $expanded
+        * @return void
+        */
+       public function setExpanded($expanded) {
+               $this->expanded = $expanded;
+       }
+
+       /**
+        * Returns the expanded indicator
+        *
+        * @return bool
+        */
+       public function isExpanded() {
+               return $this->expanded;
+       }
+
+       /**
+        * Sets the label of the node with the source field and the prefix
+        *
+        * @param string $text
+        * @param string $textSourceField
+        * @param string $prefix
+        * @return void
+        */
+       public function setText($text, $textSourceField = 'title', $prefix = '') {
+               $this->text = $text;
+               $this->t3TextSourceField = $textSourceField;
+               $this->prefix = $prefix;
+       }
+
+       /**
+        * Returns the label
+        *
+        * @return string
+        */
+       public function getText() {
+               return $this->text;
+       }
+
+       /**
+        * Returns the source field of the label
+        *
+        * @return string
+        */
+       public function getTextSourceField() {
+               return $this->t3TextSourceField;
+       }
+
+       /**
+        * Sets the paste copy indicator
+        *
+        * @param boolean $inCopyMode
+        * @return void
+        */
+       public function setInCopyMode($inCopyMode) {
+               $this->t3InCopyMode = $inCopyMode;
+       }
+
+       /**
+        * Returns the copy mode indicator
+        * 
+        * @return bool
+        */
+       public function isInCopyMode() {
+               return $this->t3InCopyMode;
+       }
+
+       /**
+        * Sets the paste cut indicator
+        *
+        * @param boolean $inCutMode
+        * @return void
+        */
+       public function setInCutMode($inCutMode) {
+               $this->t3InCutMode = $inCutMode;
+       }
+
+       /**
+        * Returns the cut mode indicator
+        *
+        * @return bool
+        */
+       public function isInCutMode() {
+               return $this->t3InCutMode;
+       }
+
+       /**
+        * Returns the prefix text of the label
+        *
+        * @return string
+        */
+       public function getPrefix() {
+               return $this->prefix;
+       }
+
+       /**
+        * Sets the css class(es)
+        *
+        * @param string $class
+        * @return void
+        */
+       public function setCls($class) {
+               $this->cls = $class;
+       }
+
+       /**
+        * Returns the css class(es)
+        *
+        * @return string
+        */
+       public function getCls() {
+               return $this->cls;
+       }
+
+       /**
+        * Sets the quick tip
+        *
+        * @param string $qtip
+        * @return void
+        */
+       public function setQTip($qtip) {
+               $this->qtip = $qtip;
+       }
+
+       /**
+        * Returns the quick tip
+        *
+        * @return string
+        */
+       public function getQTip() {
+               return $this->qtip;
+       }
+
+       /**
+        * Sets the sprite icon code
+        *
+        * @param string $spriteIcon
+        * @return void
+        */
+       public function setSpriteIconCode($spriteIcon) {
+               $this->spriteIconCode = $spriteIcon;
+       }
+
+       /**
+        * Returns the sprite icon code
+        *
+        * @return string
+        */
+       public function getSpriteIconCode() {
+               return $this->spriteIconCode;
+       }
+
+       /**
+        * Sets the callback action
+        *
+        * @param string $callbackAction
+        * @return void
+        */
+       public function setCallbackAction($callbackAction) {
+               $this->t3CallbackAction = $callbackAction;
+       }
+
+       /**
+        * Returns the callback action
+        *
+        * @return string
+        */
+       public function getCallbackAction() {
+               return $this->t3CallbackAction;
+       }
+
+       /**
+        * Sets the indicator if the label is editable
+        *
+        * @param bool $labelIsEditable
+        * @return void
+        */
+       public function setEditableLable($labelIsEditable) {
+               $this->editableLabel = $labelIsEditable;
+       }
+
+       /**
+        * Returns the editable label indicator
+        *
+        * @return bool
+        */
+       public function isLabelEditable() {
+               return $this->editableLabel;
+       }
+
+       /**
+        * Sets the database record array
+        *
+        * @param array $record
+        * @return void
+        */
+       public function setRecord($record) {
+               $this->record = $record;
+       }
+
+       /**
+        * Returns the database record array
+        *
+        * @return array
+        */
+       public function getRecord() {
+               return $this->record;
+       }
+
+       /**
+        * Sets the context info
+        *
+        * @param array $contextInfo
+        * @return void
+        */
+       public function setContextInfo($contextInfo) {
+               $this->contextInfo = $contextInfo;
+       }
+
+       /**
+        * Returns the context info
+        *
+        * @return array
+        */
+       public function getContextInfo() {
+               return (array) $this->contextInfo;
+       }
+
+       /**
+        * Sets the child nodes collection
+        *
+        * @param t3lib_tree_NodeCollection $childNodes
+        * @return void
+        */
+       public function setChildNodes(t3lib_tree_NodeCollection $childNodes) {
+               parent::setChildNodes($childNodes);
+
+               if ($childNodes->count()) {
+                       $this->setLeaf(FALSE);                  
+               }
+       }
+
+       /**
+        * Checks if the user may create pages below the given page
+        *
+        * @return void
+        */
+       protected function canCreate() {
+               if (!isset($this->cachedAccessRights['create'])) {
+                       $this->cachedAccessRights['create'] =
+                               $GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 8);
+               }
+
+               return $this->cachedAccessRights['create'];
+       }
+
+       /**
+        * Checks if the user has editing rights
+        *
+        * @return void
+        */
+       protected function canEdit() {
+               if (!isset($this->cachedAccessRights['edit'])) {
+                       $this->cachedAccessRights['edit'] =
+                               $GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 2);
+               }
+
+               return $this->cachedAccessRights['edit'];
+       }
+
+       /**
+        * Checks if the user has the right to delete the page
+        *
+        * @return void
+        */
+       protected function canRemove()  {
+               if (!isset($this->cachedAccessRights['remove'])) {
+                       $this->cachedAccessRights['remove'] =
+                               $GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 4);
+
+                       if (!$this->isLeafNode() && !$GLOBALS['BE_USER']->uc['recursiveDelete']) {
+                               $this->cachedAccessRights['remove'] = FALSE;
+                       }
+               }
+
+               return $this->cachedAccessRights['remove'];
+       }
+
+       /**
+        * Checks if the page can be disabled
+        *
+        * @return void
+        */
+       public function canBeDisabledAndEnabled() {
+               return $this->canEdit($this->record);
+       }
+
+       /**
+        * Checks if the page is allowed to can be cut
+        *
+        * @return void
+        */
+       public function canBeCut() {
+               return $this->canEdit($this->record);
+       }
+
+       /**
+        * Checks if the page is allowed to be edited
+        *
+        * @return void
+        */
+       public function canBeEdited() {
+               return $this->canEdit($this->record);
+       }
+
+       /**
+        * Checks if the page is allowed to be copied
+        *
+        * @return void
+        */
+       public function canBeCopied() {
+               return $this->canCreate($this->record);
+       }
+
+       /**
+        * Checks if there can be new pages created
+        *
+        * @return void
+        */
+       public function canCreateNewPages() {
+               return $this->canCreate($this->record);
+       }
+
+       /**
+        * Checks if the page is allowed to be removed
+        *
+        * @return void
+        */
+       public function canBeRemoved() {
+               return $this->canRemove($this->record);
+       }
+
+       /**
+        * Checks if the page is allowed to show history
+        *
+        * @return void
+        */
+       public function canShowHistory() {
+               return TRUE;
+       }
+
+       /**
+        * Checks if the page is allowed to be viewed
+        *
+        * @return void
+        */
+       public function canBeViewed() {
+               return TRUE;
+       }
+
+       /**
+        * Checks if the page is allowed to show info
+        *
+        * @return void
+        */
+       public function canShowInfo() {
+               return TRUE;
+       }
+
+       /**
+        * Checks if the page is allowed to be a temporary mount point
+        *
+        * @return void
+        */
+       public function canBeTemporaryMountPoint() {
+               return TRUE;
+       }
+
+       /**
+        * Returns the node in an array representation that can be used for serialization
+        *
+        * @return array
+        */
+       public function toArray() {
+               $arrayRepresentation = array(
+                       'serializeClassName' => get_class($this),
+                       'id' => $this->getId(),
+                       'type' => $this->getType(),
+                       'leaf' => $this->isLeafNode(),
+                       'label' => $this->getText(),
+                       'text' => $this->getPrefix() . $this->getText(),
+                       'cls' => $this->getCls(),
+                       'prefix' => $this->getPrefix(),
+                       'qtip' => $this->getQTip(),
+                       'expanded' => $this->isExpanded(),
+                       'spriteIconCode' => $this->getSpriteIconCode(),
+                       't3TextSourceField' => $this->getTextSourceField(),
+                       't3CallbackAction' => $this->getCallbackAction(),
+                       't3InCopyMode' => $this->isInCopyMode(),
+                       't3InCutMode' => $this->isInCutMode(),
+                       't3ContextInfo' => $this->getContextInfo(),
+                       'editable' => $this->isLabelEditable(),
+               );
+               $arrayRepresentation['nodeData'] = $arrayRepresentation;
+
+               $arrayRepresentation['children'] = '';
+               if ($this->hasChildNodes()) {
+                       $arrayRepresentation['children'] = $this->childNodes->toArray();
+               }
+
+               return $arrayRepresentation;
+       }
+
+       /**
+        * Sets data of the node by a given data array
+        *
+        * @param array $data
+        * @return void
+        */
+       public function dataFromArray($data) {
+               parent::dataFromArray($data);
+
+               $this->setType($data['type']);
+               $this->setLeaf($data['leaf']);
+               $this->setText($data['label'], $data['t3TextSourceField'], $data['prefix']);
+               $this->setCls($data['cls']);
+               $this->setQTip($data['qtip']);
+               $this->setExpanded($data['expanded']);
+               $this->setCallbackAction($data['t3CallbackAction']);
+               $this->setSpriteIconCode($data['spriteIconCode']);
+               $this->setInCopyMode($data['t3InCopyMode']);
+               $this->setInCutMode($data['t3InCutMode']);
+               $this->setContextInfo($data['t3ContextInfo']);
+               $this->setEditableLable($data['editable']);
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_node.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_node.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php b/typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php
new file mode 100644 (file)
index 0000000..0915190
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Tree Node Collection
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_NodeCollection extends t3lib_tree_NodeCollection {
+       /**
+        * Returns the collection in an array representation for e.g. serialization
+        *
+        * @return array
+        */
+       public function toArray() {
+               $arrayRepresentation = parent::toArray();
+               unset($arrayRepresentation['serializeClassName']);
+               return $arrayRepresentation;
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/class.tx_pagetree_stateprovider.php b/typo3/sysext/pagetree/classes/class.tx_pagetree_stateprovider.php
new file mode 100644 (file)
index 0000000..710e0cf
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Abstract State Provider
+ *
+ * @TODO Needs to be implemented
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_StateProvider {
+       /**
+        * Sets the current tree state
+        * @return void
+        */
+       public function setState() {
+
+       }
+
+       /**
+        * Returns the last tree state
+        * @return string
+        */
+       public function getState() {
+               return '';
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_stateprovider.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_stateprovider.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/contextmenu/class.tx_pagetree_contextmenu_action.php b/typo3/sysext/pagetree/classes/contextmenu/class.tx_pagetree_contextmenu_action.php
new file mode 100644 (file)
index 0000000..5ed1f8f
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Context Menu Action for the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_ContextMenu_Action extends t3lib_contextmenu_Action {
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_action.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_action.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php b/typo3/sysext/pagetree/classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php
new file mode 100644 (file)
index 0000000..145a1ff
--- /dev/null
@@ -0,0 +1,221 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Context Menu Data Provider for the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_ContextMenu_DataProvider extends t3lib_contextmenu_AbstractDataProvider {
+       /**
+        * Old Context Menu Options (access mapping)
+        *
+        * @var array
+        */
+       protected $contextMenuMapping = array(
+               // @todo should be used (compatibility)
+               'view' => 'canBeViewed',
+               'edit' => 'canBeEdited',
+               'new' => 'canCreateNewPages',
+               'info' => 'canShowInfo',
+               'copy' => 'canBeCopied',
+               'cut' => 'canBeCut',
+               'paste' => 'canBePasted',
+               'move_wizard' => 'canBeMoved',
+               'new_wizard' => 'dsfdsfdsf',
+               'mount_as_treeroot' => 'canBeTemporaryMountPoint',
+               'hide' => 'canBeDisabled',
+               'delete' => 'canBeRemoved',
+               'history' => 'canShowHistory',
+       );
+
+       /**
+        * Returns the actions for the node
+        *
+        * @param tx_pagetree_Node $node
+        * @return t3lib_contextmenu_ActionCollection
+        */
+       public function getActionsForNode(t3lib_tree_Node $node) {
+               $contextMenuActions = $this->getNextContextMenuLevel($this->getConfiguration(), $node);
+
+               return $contextMenuActions;
+       }
+
+       /**
+        * Evaluates a given display condition and returns true if the condition matches
+        *
+        * Examples:
+        * getContextInfo|inCutMode:1 || isInCopyMode:1
+        * isLeafNode:1
+        * isLeafNode:1 && isInCutMode:1
+        *
+        * @param tx_pagetree_Node $node
+        * @param string $displayCondition
+        * @return boolean
+        */
+       protected function evaluateDisplayCondition(tx_pagetree_Node $node, $displayCondition) {
+               if ($displayCondition === '') {
+                       return TRUE;
+               }
+
+                       // parse condition string
+               $conditions = array();
+               preg_match_all('/(.+?)(>=|<=|!=|=|>|<)(.+?)(\|\||&&|$)/is', $displayCondition, $conditions);
+
+               $lastResult = FALSE;
+               $chainType = '';
+               $amountOfConditions = count($conditions[0]);
+               for ($i = 0; $i < $amountOfConditions; ++$i) {
+                               // check method for existence
+                       $method = trim($conditions[1][$i]);
+                       list($method, $index) = explode('|', $method);
+                       if (!method_exists($node, $method)) {
+                               continue;
+                       }
+
+                               // fetch compare value
+                       $returnValue = call_user_func(array($node, $method));
+                       if (is_array($returnValue)) {
+                               $returnValue = $returnValue[$index];
+                       }
+
+                               // compare fetched and expected values
+                       $operator = trim($conditions[2][$i]);
+                       $expected = trim($conditions[3][$i]);
+                       if ($operator === '=') {
+                               $returnValue = ($returnValue == $expected);
+                       } elseif ($operator === '>') {
+                               $returnValue = ($returnValue > $expected);
+                       } elseif ($operator === '<') {
+                               $returnValue = ($returnValue < $expected);
+                       } elseif ($operator === '>=') {
+                               $returnValue = ($returnValue >= $expected);
+                       } elseif ($operator === '<=') {
+                               $returnValue = ($returnValue <= $expected);
+                       } elseif ($operator === '!=') {
+                               $returnValue = ($returnValue != $expected);
+                       } else {
+                               $returnValue = FALSE;
+                               $lastResult = FALSE;
+                       }
+
+                               // chain last result and the current if requested
+                       if ($chainType === '||') {
+                               $lastResult = ($lastResult || $returnValue);
+                       } elseif ($chainType === '&&') {
+                               $lastResult = ($lastResult && $returnValue);
+                       } else {
+                               $lastResult = $returnValue;
+                       }
+
+                               // save chain type for the next condition
+                       $chainType = trim($conditions[4][$i]);
+               }
+
+               return $lastResult;
+       }
+
+       /**
+        * Returns the next context menu level
+        *
+        * @param array $actions
+        * @param tx_pagetree_Node $node
+        * @param int $level
+        * @return t3lib_contextmenu_ActionCollection
+        */
+       protected function getNextContextMenuLevel(array $actions, tx_pagetree_Node $node, $level = 0) {
+               /** @var $actionCollection t3lib_contextmenu_ActionCollection */
+               $actionCollection = t3lib_div::makeInstance('t3lib_contextmenu_ActionCollection');
+
+               if ($level > 5) {
+                       return $actionCollection;
+               }
+
+               $type = '';
+               foreach ($actions as $index => $actionConfiguration) {
+                       if (substr($index, -1) !== '.') {
+                               $type = $actionConfiguration;
+                               if ($type !== 'DIVIDER') {
+                                       continue;
+                               }
+                       }
+
+                       if (!in_array($type, array('DIVIDER', 'SUBMENU', 'ITEM'))) {
+                               continue;
+                       }
+
+                       /** @var $action tx_pagetree_ContextMenu_Action */
+                       $action = t3lib_div::makeInstance('tx_pagetree_ContextMenu_Action');
+                       $action->setId($index);
+
+                       if ($type === 'DIVIDER') {
+                               $action->setType('divider');
+                       } else {
+                               if (isset($actionConfiguration['displayCondition'])
+                                       && trim($actionConfiguration['displayCondition']) !== ''
+                                       && !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])
+                               ) {
+                                       unset($action);
+                                       continue;
+                               }
+
+                               if ($type === 'SUBMENU') {
+                                       $label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
+                                       $action->setType('submenu');
+                                       $action->setChildActions(
+                                               $this->getNextContextMenuLevel($actionConfiguration, $node, ++$level)
+                                       );
+                               } else {
+                                       $label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
+                                       $action->setType('action');
+                                       $action->setCallbackAction($actionConfiguration['callbackAction']);
+                               }
+
+                               $action->setLabel($label);
+                               if (isset($actionConfiguration['icon']) && trim($actionConfiguration['icon']) !== '') {
+                                       $action->setIcon($actionConfiguration['icon']);
+                               } elseif (isset($actionConfiguration['spriteIcon'])) {
+                                       $action->setClass(
+                                               t3lib_iconWorks::getSpriteIconClasses($actionConfiguration['spriteIcon'])
+                                       );
+                               }
+                       }
+
+                       $actionCollection->append($action);
+               }
+
+               return $actionCollection;
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_dataprovider.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_dataprovider.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php b/typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php
new file mode 100644 (file)
index 0000000..f2d279e
--- /dev/null
@@ -0,0 +1,380 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Commands for the Page tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_ExtDirect_Commands {
+       /**
+        * Visibly the page
+        *
+        * @param stdClass $nodeData
+        * @return array
+        */
+       public function visiblyNode($nodeData) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       tx_pagetree_Commands::visiblyNode($node);
+                       $newNode = tx_pagetree_Commands::getNode($node->getId());
+                       $newNode->setLeaf($node->isLeafNode());
+                       $returnValue = $newNode->toArray();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'error' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Hide the page
+        *
+        * @param stdClass $nodeData
+        * @return array
+        */
+       public function disableNode($nodeData) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       tx_pagetree_Commands::disableNode($node);
+                       $newNode = tx_pagetree_Commands::getNode($node->getId());
+                       $newNode->setLeaf($node->isLeafNode());
+                       $returnValue = $newNode->toArray();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Delete the page
+        *
+        * @param stdClass $nodeData
+        * @return array
+        */
+       public function deleteNode($nodeData) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       tx_pagetree_Commands::deleteNode($node);
+                       $returnValue = array();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+
+       }
+
+       /**
+        * Restore the page
+        *
+        * @param stdClass $nodeData
+        * @return array
+        */
+       public function restoreNode($nodeData) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       tx_pagetree_Commands::restoreNode($node);
+                       $newNode = tx_pagetree_Commands::getNode($node->getId());
+                       $returnValue = $newNode->toArray();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Updates the given field with a new text value, may be used to inline update
+        * the title field in the new page tree
+        *
+        * @param stdClass $nodeData
+        * @param string $updatedLabel
+        * @return array
+        */
+       public function updateLabel($nodeData, $updatedLabel) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       tx_pagetree_Commands::updateNodeLabel($node, $updatedLabel);
+                       $returnValue = array();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Moves the source node directly as the first child of the destination node
+        *
+        * @param stdClass $nodeData
+        * @param int $destination
+        * @return array
+        */
+       public function moveNodeToFirstChildOfDestination($nodeData, $destination) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       tx_pagetree_Commands::moveNode($node, $destination);
+                       $returnValue = array();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Moves the source node directly after the destination node
+        *
+        * @param stdClass $nodeData
+        * @param int $destination
+        * @return void
+        */
+       public function moveNodeAfterDestination($nodeData, $destination) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       tx_pagetree_Commands::moveNode($node, -$destination);
+                       $returnValue = array();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Copies the source node directly as the first child of the destination node and
+        * returns the created node.
+        *
+        * @param stdClass $nodeData
+        * @param int $destination
+        * @return array
+        */
+       public function copyNodeToFirstChildOfDestination($nodeData, $destination) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       $newPageId = tx_pagetree_Commands::copyNode($node, $destination);
+                       $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Copies the source node directly after the destination node and returns the
+        * created node.
+        *
+        * @param stdClass $nodeData
+        * @param int $destination
+        * @return array
+        */
+       public function copyNodeAfterDestination($nodeData, $destination) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               try {
+                       $newPageId = tx_pagetree_Commands::copyNode($node, -$destination);
+                       $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Inserts a new node as the first child node of the destination node and returns the created node.
+        *
+        * @param stdClass $parentNodeData
+        * @param int $pageType
+        * @return array
+        */
+       public function insertNodeToFirstChildOfDestination($parentNodeData, $pageType) {
+               /** @var $parentNode tx_pagetree_Node */
+               $parentNode = t3lib_div::makeInstance('tx_pagetree_Node', (array) $parentNodeData);
+
+               try {
+                       $newPageId = tx_pagetree_Commands::createNode($parentNode, $parentNode->getId(), $pageType);
+                       $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Inserts a new node directly after the destination node and returns the created node.
+        *
+        * @param stdClass $parentNodeData
+        * @param int $destination
+        * @param int $pageType
+        * @return array
+        */
+       public function insertNodeAfterDestination($parentNodeData, $destination, $pageType) {
+               /** @var $parentNode tx_pagetree_Node */
+               $parentNode = t3lib_div::makeInstance('tx_pagetree_Node', (array) $parentNodeData);
+
+               try {
+                       $newPageId = tx_pagetree_Commands::createNode($parentNode, -$destination, $pageType);
+                       $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+               } catch (Exception $exception) {
+                       $returnValue = array(
+                                'success' => FALSE,
+                                'message' => $exception->getMessage(),
+                        );
+               }
+
+               return $returnValue;
+       }
+
+       /**
+        * Returns the view link of a given node
+        *
+        * @param stdClass $nodeData
+        * @param string $workspacePreview
+        * @return string
+        */
+       public static function getViewLink($nodeData, $workspacePreview) {
+               // @TODO use the hook to get the needed information's
+
+
+//             $viewScriptPreviewEnabled  = '/' . TYPO3_mainDir . 'mod/user/ws/wsol_preview.php?id=';
+//             $viewScriptPreviewDisabled = '/index.php?id=';
+//
+//                     // check alternate Domains
+//             $rootLine = t3lib_BEfunc::BEgetRootLine($id);
+//             if ($rootLine) {
+//                     $parts = parse_url(t3lib_div::getIndpEnv('TYPO3_SITE_URL'));
+//                     if (t3lib_BEfunc::getDomainStartPage($parts['host'], $parts['path'])) {
+//                             $preUrl_temp = t3lib_BEfunc::firstDomainRecord($rootLine);
+//                     }
+//             }
+//             $preUrl = ($preUrl_temp ? (t3lib_div::getIndpEnv('TYPO3_SSL') ?
+//                     'https://' : 'http://') . $preUrl_temp : '' . '..');
+//
+//                     // Look if a fixed preview language should be added:
+//             $viewLanguageOrder = $GLOBALS['BE_USER']->getTSConfigVal('options.view.languageOrder');
+//             if (strlen($viewLanguageOrder)) {
+//                     $suffix = '';
+//
+//                             // Find allowed languages (if none, all are allowed!)
+//                     if (!$GLOBALS['BE_USER']->user['admin'] &&
+//                             strlen($GLOBALS['BE_USER']->groupData['allowed_languages'])) {
+//                             $allowed_languages = array_flip(explode(',', $GLOBALS['BE_USER']->groupData['allowed_languages']));
+//                     }
+//
+//                             // Traverse the view order, match first occurrence
+//                     $lOrder = t3lib_div::intExplode(',',$viewLanguageOrder);
+//                     foreach($lOrder as $langUid)    {
+//                             if (is_array($allowed_languages) && count($allowed_languages)) {
+//                                     if (isset($allowed_languages[$langUid])) {      // Choose if set.
+//                                             $suffix = '&L='.$langUid;
+//                                             break;
+//                                     }
+//                             } else {        // All allowed since no lang. are listed.
+//                                     $suffix = '&L='.$langUid;
+//                                     break;
+//                             }
+//                     }
+//
+//                             // Add it:
+//                     $addGetVars.= $suffix;
+//             }
+//
+//             $urlPreviewEnabled  = $preUrl . $viewScriptPreviewEnabled . $id . $addGetVars;
+//             $urlPreviewDisabled = $preUrl . $viewScriptPreviewDisabled . $id . $addGetVars;
+//
+//             if ($workspacePreview) {
+//                     return $urlPreviewEnabled;
+//             } else {
+//                     return $urlPreviewDisabled;
+//             }
+
+//             $javascriptLink = t3lib_BEfunc::viewOnClick($id);
+//             debug($javascriptLink);
+
+               return 'http://linux-schmie.de/wp-content/uploads/2010/07/Baustelle.png';
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php b/typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php
new file mode 100644 (file)
index 0000000..98c3f0f
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Context Menu of the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_ExtDirect_ContextMenu extends t3lib_contextmenu_extdirect_ContextMenu {
+       /**
+        * Sets the data provider
+        *
+        * @return void
+        */
+       protected function initDataProvider() {
+               /** @var $dataProvider tx_pagetree_ContextMenu_DataProvider */
+               $dataProvider = t3lib_div::makeInstance('tx_pagetree_ContextMenu_DataProvider');
+               $dataProvider->setContextMenuType('table.pages');
+               $this->setDataProvider($dataProvider);
+       }
+
+       /**
+        * Returns the actions for the given node information's
+        *
+        * @param stdClass $node
+        * @return array
+        */
+       public function getActionsForNodeArray($nodeData) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+               $node->setRecord(tx_pagetree_Commands::getNodeRecord($node->getId()));
+
+               $this->initDataProvider();
+               $actionCollection = $this->dataProvider->getActionsForNode($node);
+
+               return $actionCollection->toArray();
+       }
+}
+
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php b/typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php
new file mode 100644 (file)
index 0000000..170bb00
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Data Provider of the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_ExtDirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree {
+       /**
+        * Sets the data provider
+        *
+        * @return void
+        */
+       protected function initDataProvider() {
+               /** @var $dataProvider tx_pagetree_DataProvider */
+               $dataProvider = t3lib_div::makeInstance('tx_pagetree_DataProvider');
+               $this->setDataProvider($dataProvider);
+       }
+
+       /**
+        * Data Provider
+        *
+        * @return tx_pagetree_DataProvider
+        */
+       protected $dataProvider = NULL;
+
+       /**
+        * Returns the root node of the tree
+        *
+        * Not used for the page tree, because the multiple domains/roots feature
+        *
+        * @return array
+        */
+       public function getRoot() {
+               return array();
+       }
+
+       /**
+        * Fetches the next tree level
+        *
+        * @param int $nodeId
+        * @param stdClass $nodeData
+        * @return array
+        */
+       public function getNextTreeLevel($nodeId, $nodeData) {
+               $this->initDataProvider();
+
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               if ($nodeId === 'root') {
+                       $nodeCollection = $this->dataProvider->getTreeMounts();
+               } else {
+                       $nodeCollection = $this->dataProvider->getNodes($node);
+               }
+
+               return $nodeCollection->toArray();
+       }
+
+       /**
+        * Returns a tree that only contains elements that match the given search string
+        *
+        * @param string $searchFilter
+        * @return array
+        */
+       public function getFilteredTree($searchFilter) {
+               $this->initDataProvider();
+
+               $nodeCollection = $this->dataProvider->getFilteredNodes($searchFilter);
+
+               return $nodeCollection->toArray();
+       }
+
+       /**
+        * Returns the localized list of doktypes to display
+        *
+        * Note: The list can be filtered by the user typoscript
+        * option "options.pageTree.doktypesToShowInNewPageDragArea".
+        *
+        * @return array
+        */
+       public function getNodeTypes() {
+               $doktypes = t3lib_div::trimExplode(
+                       ',', $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.doktypesToShowInNewPageDragArea')
+               );
+
+               $output = array();
+               foreach ($doktypes as $doktype) {
+                       $label = $GLOBALS['LANG']->sL('LLL:EXT:pagetree/locallang_pagetree.xml:page.doktype.' . $doktype, TRUE);
+                       $spriteIcon = $this->getSpriteIconClasses($GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][$doktype]);
+
+                       $output[] = array(
+                               'nodeType' => $doktype,
+                               'cls' => 'topPanel-button ' . $spriteIcon,
+                               'title' => $label,
+                               'tooltip' => $label,
+                       );
+               }
+
+               return $output;
+       }
+
+       /**
+        * Returns the sprite icon classes for a given icon
+        *
+        * @param string $icon
+        * @return string
+        */
+       public function getSpriteIconClasses($icon) {
+               return t3lib_iconWorks::getSpriteIconClasses($icon);
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/components/pagetree/javascript/Ext.ux.plugins.TreePanelStateful.js b/typo3/sysext/pagetree/components/pagetree/javascript/Ext.ux.plugins.TreePanelStateful.js
new file mode 100644 (file)
index 0000000..cd30afc
--- /dev/null
@@ -0,0 +1,314 @@
+/******************************************************************
+ * @class Ext.ux.plugins.TreePanelStateful
+ * @extends Ext.util.Observable
+
+ * @constructor
+ * var treePanel = new Ext.ux.TreePanel({
+ ...add TreePanel options
+ plugins:new Ext.ux.plugins.TreePanelStateful()
+ });
+ *****************************************************************/
+Ext.namespace('Ext.ux.plugins');
+
+Ext.ux.plugins.TreePanelStateful = function(config) {
+       Ext.apply(this, config);
+};
+
+Ext.extend(Ext.ux.plugins.TreePanelStateful, Ext.util.Observable, {
+       treePanel: null,
+       init: function(treePanel) {
+               this.treePanel = treePanel;
+               Ext.apply(treePanel, {
+                       // internal variables
+                       taskId: '',
+                       ignoreCookie: false,
+                       startQueryClicked: false,
+                       nodeAttrs: {},
+                       oldParentNodeAttrs: {},
+                       newParentNodeAttrs: {},
+
+                       //CookieProvider - hold state of TreePanel
+                       cp: null,
+
+                       //TreePanel state - simple array
+                       state: null,
+
+                       //stateful option set to true
+                       stateful: true,
+
+                       //Last selected node
+                       lastSelectedNode: null,
+
+                       //Function which saves TreePanel state
+                       saveState : function(newState) {
+                               this.state = newState;
+                               this.cp.set('TreePanelStateful_' + treePanel.taskId, this.state);
+                       },
+
+                       //Function which restores TreePanel state
+                       restoreState : function(defaultPath) {
+                               if (!treePanel.ignoreCookie) {
+                                       var stateToRestore = this.state;
+
+                                       if (this.state.length == 0) {
+                                               var newState = new Array(defaultPath);
+                                               this.saveState(newState);
+                                               this.expandPath(defaultPath);
+                                               return;
+                                       }
+
+                                       for (var i = 0; i < stateToRestore.length; ++i) {
+                                               // activate all path strings from the state
+                                               try {
+                                                       var path = stateToRestore[i];
+                                                       this.expandPath(path);
+                                               }
+                                               catch(e) {
+                                                       // ignore invalid path, seems to be remove in the datamodel
+                                                       // TODO fix state at this point
+                                               }
+                                       }
+                               }
+                       },
+
+                       /***** Events which cause TreePanel to remember its state
+                        * click, expandnode, collapsenode, load, textchange,
+                        * remove, render
+                        ********************************************************/
+                       stateEvents: [{
+                               click: {
+                                       fn: function(node) {
+                                               this.cp.set('LastSelectedNodePath_' + treePanel.taskId, node.getPath());
+                                               this.cp.set('LastSelectedNodeId_' + treePanel.taskId, node.id);
+                                       }
+                               },
+                               expandnode: {
+                                       fn: function(node) {
+                                               var currentPath = node.getPath();
+                                               var newState = new Array();
+
+                                               for (var i = 0; i < this.state.length; ++i) {
+                                                       var path = this.state[i];
+
+                                                       if (currentPath.indexOf(path) == -1) {
+                                                               // this path does not already exist
+                                                               newState.push(path);
+                                                       }
+                                               }
+
+                                               // now ad the new path
+                                               newState.push(currentPath);
+                                               this.saveState(newState);
+                                       }
+                               },
+                               collapsenode: {
+                                       fn: function(node) {
+                                               var parentNode;
+                                               if (node.id == this.root.id) {
+                                                       return;
+                                               }
+
+                                               var closedPath = node.getPath();
+                                               var newState = new Array();
+
+                                               for (var i = 0; i < this.state.length; ++i) {
+                                                       var path = this.state[i];
+                                                       if (path.indexOf(closedPath) == -1) {
+                                                               // this path is not a subpath of the closed path
+                                                               newState.push(path);
+                                                       }
+                                                       else {
+                                                               if (path == closedPath) {
+                                                                       parentNode = node.parentNode;
+
+                                                                       if (parentNode.id != this.root.id) {
+                                                                               newState.push(parentNode.getPath());
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               if (newState.length == 0) {
+                                                       parentNode = node.parentNode;
+                                                       newState.push((parentNode == null ? this.pathSeparator : parentNode.getPath()));
+                                               }
+
+                                               this.saveState(newState);
+                                       }
+                               },
+                               load: {
+                                       fn: function(node) {
+                                               var lastSelectedNodePath = this.cp.get('LastSelectedNodePath_' + treePanel.taskId);
+                                               var lastSelectedNodeId = this.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+
+                                               var rootNode = this.getRootNode();
+                                               if (node.id == rootNode.id == lastSelectedNodeId) {
+                                                       this.selectPath(lastSelectedNodePath);
+                                                       node.fireEvent('click', node);
+                                                       return;
+                                               }
+
+                                               if (node.id == lastSelectedNodeId) {
+                                                       node.fireEvent('click', node);
+                                               } else {
+                                                       var childNode = node.findChild('id', lastSelectedNodeId);
+
+                                                       if (childNode && childNode.isLeaf()) {
+                                                               childNode.ensureVisible();
+                                                               this.selectPath(lastSelectedNodePath);
+                                                               childNode.fireEvent('click', childNode);
+                                                       }
+                                                       else if (childNode && !childNode.isLeaf()) {
+                                                               this.selectPath(lastSelectedNodePath);
+                                                               childNode.fireEvent('click', childNode);
+                                                       }
+                                               }
+                                       }
+                               },
+                               textchange: {
+                                       fn: function(node, text, oldText) {
+                                               var lastSelectedNodePath = this.cp.get('LastSelectedNodePath_' + treePanel.taskId);
+                                               if (lastSelectedNodePath) {
+                                                       return;
+                                               }
+                                               
+                                               var newSelectedNodePath = lastSelectedNodePath.replace(oldText, text);
+
+                                               this.cp.set('LastSelectedNodePath_' + treePanel.taskId, newSelectedNodePath);
+
+                                               this.expandPath(node.getPath());
+                                               this.selectPath(node.getPath());
+                                       }
+                               },
+                               remove: {
+                                       fn: function(tree, parentNode, node) {
+                                               var lastSelectedNodeId = this.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+                                               if (!tree.movingNode) {
+                                                       if (node.id == lastSelectedNodeId) {
+                                                               this.cp.set('LastSelectedNodePath_' + treePanel.taskId, parentNode.getPath());
+                                                               this.cp.set('LastSelectedNodeId_' + treePanel.taskId, parentNode.id);
+                                                       }
+
+                                                       this.cp.set('DeletedNodeParent_' + treePanel.taskId + '_' + node.id, parentNode.id);
+                                                       this.cp.set('DeletedNode_' + treePanel.taskId + '_' + node.id, node.id);
+
+                                                       if (tree.deleteWithChildren)
+                                                               this.cp.set('DeletedNodeWithChildren_' + treePanel.taskId + '_' + node.id, "true");
+
+                                                       tree.deleteWithChildren = false;
+                                               }
+                                       }
+                               },
+                               movenode: {
+                                       fn: function(tree, node, oldParent, newParent) {
+                                               var lastSelectedNodeId = this.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+                                               if (node.id == lastSelectedNodeId) {
+                                                       this.cp.set('LastSelectedNodePath_' + treePanel.taskId, newParent.getPath());
+                                                       this.cp.set('LastSelectedNodeId_' + treePanel.taskId, newParent.id);
+                                               }
+
+                                               this.cp.set('MovedNodeOldParent_' + treePanel.taskId + '_' + node.id, oldParent.id);
+                                               this.cp.set('MovedNodeNewParent_' + treePanel.taskId + '_' + node.id, newParent.id);
+                                               this.cp.set('MovedNode_' + treePanel.taskId + '_' + node.id, node.id);
+                                       }
+                               }
+                       }]
+               });
+
+               if (!treePanel.stateful) {
+                       treePanel.stateful = true;
+               }
+
+               if (!treePanel.cp) {
+                       treePanel.cp = new Ext.state.CookieProvider({expires: null});
+               }
+
+               if (!treePanel.lastSelectedNode) {
+                       var cookieLastSelectedNode = treePanel.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+
+                       if (!cookieLastSelectedNode) {
+                               treePanel.lastSelectedNode = treePanel.root;
+                       }
+                       else {
+                               treePanel.lastSelectedNode = cookieLastSelectedNode;
+                       }
+               }
+
+               if (!treePanel.state) {
+                       var cookieState = treePanel.cp.get('TreePanelStateful_' + treePanel.taskId);
+
+                       if (!cookieState) {
+                               treePanel.state = new Array();
+                       }
+                       else {
+                               treePanel.state = cookieState;
+                       }
+               }
+
+               treePanel.restoreState(treePanel.root.getPath());
+       },
+       updateState: function(treePanel, parentNode, node) {
+               if (!treePanel.ignoreCookie && !treePanel.startQueryClicked) {
+                       /*
+                        * Check for deleted nodes.
+                        */
+                       var deletedNode = treePanel.getNodeById(treePanel.cp.get('DeletedNode_' + this.treePanel.taskId + '_' + node.id));
+
+                       if (deletedNode != undefined) {
+                               var deleteWithChildren = treePanel.cp.get('DeletedNodeWithChildren_' + this.treePanel.taskId + '_' + node.id);
+
+                               if (deleteWithChildren === "true")
+                                       treePanel.deleteWithChildren = true;
+
+                               deletedNode.remove();
+
+                               if (!parentNode.hasChildNodes())
+                                       parentNode.expand();
+                       }
+                       else {
+                               /*
+                                * Check for moved nodes.
+                                */
+                               treePanel.movingNode = true;
+
+                               var movedNode = treePanel.getNodeById(treePanel.cp.get('MovedNode_' + treePanel.taskId + '_' + node.id));
+
+                               if (movedNode != undefined) {
+                                       var oldParentNode = treePanel.getNodeById(treePanel.cp.get('MovedNodeOldParent_' + treePanel.taskId + '_' + node.id));
+                                       var newParentNode = treePanel.getNodeById(treePanel.cp.get('MovedNodeNewParent_' + treePanel.taskId + '_' + node.id));
+
+                                       if (oldParentNode != undefined && newParentNode != undefined) {
+                                               oldParentNode.removeChild(node);
+                                               newParentNode.appendChild(node);
+                                               newParentNode.lastChild = node;
+
+                                               if (treePanel.nodeAttrs.indexOf(node.attributes.id) === -1) {
+                                                       treePanel.nodeAttrs.push(node.id);
+                                                       treePanel.oldParentNodeAttrs.push(oldParentNode.id);
+                                                       treePanel.newParentNodeAttrs.push(newParentNode.id);
+                                               }
+                                               else {
+                                                       treePanel.nodeAttrs[treePanel.nodeAttrs.indexOf(node.attributes.id)] = node.id;
+                                                       treePanel.oldParentNodeAttrs[treePanel.nodeAttrs.indexOf(node.attributes.id)] = oldParentNode.id;
+                                                       treePanel.newParentNodeAttrs[treePanel.nodeAttrs.indexOf(node.attributes.id)] = newParentNode.id;
+                                               }
+                                               treePanel.gridModified = true;
+                                       }
+                               }
+
+                               treePanel.movingNode = false;
+                       }
+               }
+               else {
+                       treePanel.cp.clear('TreePanelStateful_' + treePanel.taskId);
+                       treePanel.cp.clear('LastSelectedNodePath_' + treePanel.taskId);
+                       treePanel.cp.clear('LastSelectedNodeId_' + treePanel.taskId);
+                       treePanel.cp.clear('DeletedNodeParent_' + treePanel.taskId + '_' + node.id);
+                       treePanel.cp.clear('DeletedNode_' + treePanel.taskId + '_' + node.id);
+                       treePanel.cp.clear('DeletedNodeWithChildren_' + treePanel.taskId + '_' + node.id);
+                       treePanel.cp.clear('MovedNodeOldParent_' + treePanel.taskId + '_' + node.id);
+                       treePanel.cp.clear('MovedNodeNewParent_' + treePanel.taskId + '_' + node.id);
+                       treePanel.cp.clear('MovedNode_' + treePanel.taskId + '_' + node.id);
+               }
+       }
+});
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/components/pagetree/javascript/actions.js b/typo3/sysext/pagetree/components/pagetree/javascript/actions.js
new file mode 100644 (file)
index 0000000..6717196
--- /dev/null
@@ -0,0 +1,205 @@
+Ext.namespace('TYPO3.Components.PageTree');
+
+TYPO3.Components.PageTree.Actions = {
+       evaluateResponse: function(response) {
+               if (response.success === false) {
+                       TYPO3.Flashmessage.display(4, 'Exception', response.message);
+                       return false;
+               }
+
+               return true;
+       },
+
+       removeNode: function(node) {
+               TYPO3.Components.PageTree.Commands.deleteNode(
+                       node.attributes.nodeData,
+                       function(response) {
+                               if (this.evaluateResponse(response)) {
+                                       node.remove();
+                               }
+                       },
+                       this
+               );
+       },
+
+       restoreNode: function(node) {
+               TYPO3.Components.PageTree.Commands.restoreNode(node.attributes.nodeData);
+       },
+
+       stub: function() {
+               alert('Just a Stub! Don\'t Panic!');
+       },
+
+       viewPage: function(node) {
+               TYPO3.Components.PageTree.Commands.getViewLink(
+                       node.attributes.nodeData,
+                       (TYPO3.configuration.workspaceFrontendPreviewEnabled && TYPO3.configuration.currentWorkspace != 0),
+                       function(result) {
+                               openUrlInWindow(result, 'typo3-contextMenu-view');
+                       }
+               );
+       },
+
+       editPageProperties: function(node) {
+               TYPO3.Backend.ContentContainer.setUrl(
+                       'alt_doc.php?edit[pages][' + node.attributes.id + ']=edit'
+               );
+       },
+
+       newPageWizard: function(node) {
+               TYPO3.Backend.ContentContainer.setUrl(
+                       'db_new.php?id=' + node.attributes.id + '&pagesOnly=1'
+               );
+       },
+
+       openInfoPopUp: function(node) {
+               launchView('pages', node.attributes.id);
+       },
+
+       openHistoryPopUp: function(node) {
+               TYPO3.Backend.ContentContainer.setUrl(
+                       'show_rechis.php?element=pages:' + node.attributes.id
+               );
+       },
+
+       enableCutMode: function(node, pageTree) {
+               this.disableCopyMode(node, pageTree);
+               node.attributes.nodeData.t3InCutMode = true;
+               pageTree.tree.t3ContextInfo.inCutMode = true;
+               pageTree.tree.t3ContextNode = node;
+       },
+
+       disableCutMode: function(node, pageTree) {
+               this.releaseCutAndCopyModes(pageTree);
+               node.attributes.nodeData.t3InCutMode = false;
+       },
+
+       enableCopyMode: function(node, pageTree) {
+               this.disableCutMode(node, pageTree);
+               node.attributes.nodeData.t3InCopyMode = true;
+               pageTree.tree.t3ContextInfo.inCopyMode = true;
+               pageTree.tree.t3ContextNode = node;
+       },
+
+       disableCopyMode: function(node, pageTree) {
+               this.releaseCutAndCopyModes(pageTree);
+               node.attributes.nodeData.t3InCopyMode = false;
+       },
+
+       pasteIntoNode: function(node, pageTree) {
+               this.releaseCutAndCopyModes(pageTree);
+               this.stub();
+       },
+
+       pasteAfterNode: function(node, pageTree) {
+               this.releaseCutAndCopyModes(pageTree);
+               this.stub();
+       },
+
+       releaseCutAndCopyModes: function(pageTree) {
+               pageTree.tree.t3ContextInfo.inCutMode = false;
+               pageTree.tree.t3ContextInfo.inCopyMode = false;
+
+               if (pageTree.tree.t3ContextNode) {
+                       pageTree.tree.t3ContextNode.attributes.nodeData.t3InCutMode = false;
+                       pageTree.tree.t3ContextNode.attributes.nodeData.t3InCopyMode = false;
+                       pageTree.tree.t3ContextNode = null;
+               }
+       },
+
+       moveNodeToFirstChildOfDestination: function(node, newParent) {
+               TYPO3.Components.PageTree.Commands.moveNodeToFirstChildOfDestination(
+                       node.attributes.nodeData,
+                       newParent
+               );
+       },
+
+       moveNodeAfterDestination: function(node, newParent) {
+               TYPO3.Components.PageTree.Commands.moveNodeAfterDestination(
+                       node.attributes.nodeData,
+                       newParent
+               );
+       },
+
+       insertNodeAfterDestination: function(node, callback) {
+               TYPO3.Components.PageTree.Commands.insertNodeAfterDestination(
+                       node.parentNode.attributes.nodeData,
+                       node.previousSibling.id,
+                       node.serverNodeType,
+                       callback.createDelegate(node)
+               );
+       },
+
+       insertNodeToFirstChildOfDestination: function(node, callback) {
+               TYPO3.Components.PageTree.Commands.insertNodeToFirstChildOfDestination(
+                       node.parentNode.attributes.nodeData,
+                       node.serverNodeType,
+                       callback.createDelegate(node)
+               );
+       },
+
+       copyNodeToFirstChildOfDestination: function(node, callback) {
+               TYPO3.Components.PageTree.Commands.copyNodeToFirstChildOfDestination(
+                       node.attributes.nodeData,
+                       node.parentNode.id,
+                       callback.createDelegate(node)
+               );
+       },
+
+       copyNodeAfterDestination: function(node, callback) {
+               TYPO3.Components.PageTree.Commands.copyNodeAfterDestination(
+                       node.attributes.nodeData,
+                       node.previousSibling.id,
+                       callback.createDelegate(node)
+               );
+       },
+
+       enablePage: function(node) {
+               TYPO3.Components.PageTree.Commands.visiblyNode(
+                       node.attributes.nodeData,
+                       function(response) {
+                               if (this.evaluateResponse(response)) {
+                                       this.updateNode(node, response);
+                               }
+                       },
+                       this
+               );
+       },
+
+       disablePage: function(node) {
+               TYPO3.Components.PageTree.Commands.disableNode(
+                       node.attributes.nodeData,
+                       function(response) {
+                               if (this.evaluateResponse(response)) {
+                                       this.updateNode(node, response);
+                               }
+                       },
+                       this
+               );
+       },
+
+       updateNode: function(node, updatedNode) {
+               updatedNode.uiProvider = TYPO3.Components.PageTree.PageTreeUI;
+               var newTreeNode = new Ext.tree.TreeNode(updatedNode);
+               node.parentNode.replaceChild(newTreeNode, node);
+               newTreeNode.getOwnerTree().refreshNode(newTreeNode);
+       },
+
+       singleClick: function(node) {
+               TYPO3.Backend.ContentContainer.setUrl(
+                       TS.PATH_typo3 + currentSubScript + '?id=' + node.attributes.id
+               );
+       },
+
+       saveTitle: function(node, newText, oldText) {
+               if (newText === oldText) {
+                       return;
+               }
+
+               TYPO3.Components.PageTree.Commands.updateLabel(
+                       node.editNode.attributes.nodeData,
+                       newText,
+                       this.evaluateResponse
+               );
+       }
+};
\ No newline at end of file
index e6e57b2..0a8d86e 100644 (file)
@@ -1,47 +1,41 @@
 Ext.namespace('TYPO3.Components.PageTree');
 
 TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
-       dataRecord: null,
+       node: null,
+       pageTree: null,
        id: 'typo3-pagetree-contextmenu',
+
        listeners: {
                itemclick: {
-                       scope: this,
                        fn: function (item) {
-                               if (item.callbackAction != undefined) {
-                                       eval(item.callbackAction + '(item.parentMenu.dataRecord, item.attributes)');
-                               }
+                this.pageTree.commandProvider[item.callbackAction](
+                                       item.parentMenu.node,
+                                       item.parentMenu.pageTree
+                               );
                        }
                }
        },
 
-
        /**
-        * Fill menu with menu items.
-        *
-        * @param dataRecord
-        * The data record to bind to the menu.
-        * MUST contain "attributes.actions" as an array defining the allowed actions for the current item.
+        * Fill menu with menu items and returns the number of context menu items
         *
+        * @param node
+        * @param pageTree
         * @param contextMenuConfiguration
-        * Context menu configuration. See Ext.MenuItem for properties.
-        * Additionally, the following two properties have to exist:
-        * - callback: Callback method to be called when the click happens. Gets two parameters: the dataRecord, and item.attributes.
-        * - action: The name of the action
-        *
-        * @return the number of menu items in the first level.
+        * @return int
         */
-       fillWithMenuItems: function(dataRecord, contextMenuConfiguration) {
-               this.dataRecord = dataRecord;
-               this.dataRecord.attributes.actions = Ext.toArray(this.dataRecord.attributes.actions);
-               //
+       fillWithMenuItems: function(node, pageTree, contextMenuConfiguration) {
+               this.node = node;
+               this.pageTree = pageTree;
+
                var components = this.preProcessContextMenuConfiguration(contextMenuConfiguration);
 
                if (components.length) {
                        for (var component in components) {
-                               if (components[component] == '-') {
+                               if (components[component] === '-') {
                                        this.addSeparator();
                                } else {
-                                       if (typeof components[component] == 'object') {
+                                       if (typeof components[component] === 'object') {
                                                this.addItem(components[component]);
                                        }
                                }
@@ -65,51 +59,61 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
                var modulesInsideGroup = false;
                var subMenus = 0;
                for (var singleAction in contextMenuConfiguration) {
-                       if (singleAction.indexOf('--submenu') != -1) {
+                       if (contextMenuConfiguration[singleAction]['type'] === 'submenu') {
                                var subMenuComponents = this.preProcessContextMenuConfiguration(
-                                               contextMenuConfiguration[singleAction],
-                                               level + 1
-                                               );
+                                       contextMenuConfiguration[singleAction]['childActions'],
+                                       level + 1
+                               );
 
                                if (subMenuComponents.length) {
                                        var subMenu = new TYPO3.Components.PageTree.ContextMenu({
                                                id: this.id + '-sub' + ++subMenus,
                                                items: subMenuComponents,
-                                               dataRecord: this.dataRecord
+                                               node: this.node,
+                                               pageTree: this.pageTree
                                        });
 
                                        components[index++] = {
-                                               text: contextMenuConfiguration[singleAction]['text'],
+                                               text: contextMenuConfiguration[singleAction]['label'],
                                                cls: 'contextMenu-subMenu',
                                                menu: subMenu
                                        };
                                }
+                       } else if (contextMenuConfiguration[singleAction]['type'] === 'divider') {
+                               if (modulesInsideGroup) {
+                                       components[index++] = '-';
+                                       modulesInsideGroup = false;
+                               }
                        } else {
-                               if (singleAction.indexOf('--divider') != -1) {
-                                       if (modulesInsideGroup) {
-                                               components[index++] = '-';
-                                               modulesInsideGroup = false;
-                                       }
-                               } else {
-                                       modulesInsideGroup = true;
+                               modulesInsideGroup = true;
+
+                               if (typeof contextMenuConfiguration[singleAction] === 'object') {
+                                       var component = {
+                                               'text': contextMenuConfiguration[singleAction]['label'],
+                                               'icon': contextMenuConfiguration[singleAction]['icon'],
+                                               'iconCls': contextMenuConfiguration[singleAction]['class'],
+                                               'callbackAction': contextMenuConfiguration[singleAction]['callbackAction']
+                                       };
 
-                                       if (typeof contextMenuConfiguration[singleAction] == 'object') {
-                                               var component = contextMenuConfiguration[singleAction];
-                                               component.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
-                                                               '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}">',
-                                                               '<span class="{hrefTarget}">',
+                                       component.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
+                                               '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}">',
+                                                       '<span class="{hrefTarget}">',
                                                                '<img src="{icon}" class="x-menu-item-icon {iconCls}" unselectable="on" />',
-                                                               '</span>',
-                                                               '<span class="x-menu-item-text">{text}</span>',
-                                                               '</a>'
-                                                               );
+                                                       '</span>',
+                                                       '<span class="x-menu-item-text">{text}</span>',
+                                               '</a>'
+                                       );
 
-                                               components[index++] = component;
-                                       }
+                                       components[index++] = component;
                                }
                        }
                }
 
+                       // remove divider if it's the last item of the context menu
+               if (components.last() === '-') {
+                       components[components.length - 1] = '';
+               }
+
                return components;
        }
 });
diff --git a/typo3/sysext/pagetree/components/pagetree/javascript/contextmenuactions.js b/typo3/sysext/pagetree/components/pagetree/javascript/contextmenuactions.js
deleted file mode 100644 (file)
index f53dc68..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-Ext.namespace('TYPO3.Components.PageTree');
-
-TYPO3.Components.PageTree.ContextMenuActions = {
-       removeNode: function(node) {
-               if (node.parentNode) {
-                       node.remove();
-               }
-       },
-
-       stub: function() {
-               alert('Just a Stub! Don\'t Panic!');
-       },
-
-       viewPage: function(node) {
-               TYPO3.Components.PageTree.DataProvider.getViewLink(
-                               node.id,
-                               (TYPO3.configuration.workspaceFrontendPreviewEnabled && TYPO3.configuration.currentWorkspace != 0),
-                                 function(result) {
-                                         openUrlInWindow(result, 'typo3-contextMenu-view');
-                                 }
-                               );
-       },
-
-       editPageProperties: function(node) {
-               TYPO3.Backend.ContentContainer.setUrl(
-                               'alt_doc.php?edit[pages][' + node.attributes.properties.realId + ']=edit'
-                               );
-       },
-
-       newPageWizard: function(node) {
-               TYPO3.Backend.ContentContainer.setUrl(
-                               'db_new.php?id=' + node.attributes.properties.realId + '&pagesOnly=1'
-                               );
-       },
-
-       openInfoPopUp: function(node) {
-               launchView('pages', node.attributes.properties.realId);
-       },
-
-       openHistoryPopUp: function(node) {
-               TYPO3.Backend.ContentContainer.setUrl(
-                               'show_rechis.php?element=pages:' + node.attributes.properties.realId
-                               );
-       },
-
-       enablePage: function(node) {
-               this.tooglePageVisibility(node, false);
-       },
-
-       disablePage: function(node) {
-               this.tooglePageVisibility(node, true);
-       },
-
-       tooglePageVisibility: function(node, enabled) {
-               TYPO3.Components.PageTree.DataProvider.tooglePageVisibility(
-                               node.id,
-                               enabled,
-                                  function(updatedNodeFromServer) {
-                                          updatedNodeFromServer.uiProvider = TYPO3.Components.PageTree.PageTreeUI;
-                                          var newTreeNode = new Ext.tree.TreeNode(updatedNodeFromServer);
-                                          node.parentNode.replaceChild(newTreeNode, node);
-                                  }
-                               );
-       }
-};
\ No newline at end of file
index 3c0c833..46372a2 100644 (file)
@@ -18,13 +18,13 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
                                (new Ext.dd.DropTarget(this.getEl(), {
                                        notifyDrop: function(ddProxy, e, n) {
                                                var node = n.node;
-                                               // TODO: Permission checking again
 
                                                var dropZoneBody = Ext.get(this.el.query('.x-panel-body')[0]);
                                                dropZoneBody.update('You just deleted "' + node.text + '"<span class="undelete" style="text-decoration: underline;">Undelete</span>');
+
                                                Ext.get(dropZoneBody.query('.undelete')[0]).on('click', function() {
-                                                       filteringTree.dataProvider.undeleteNode(node.id);
-                                                       filteringTree.refreshTree();
+                                                       filteringTree.commandProvider.restoreNode(node, filteringTree);
+                                                       filteringTree.tree.refreshTree();
                                                        this.update('<strong>Restored</strong>');  // TODO: LOCALIZE
 
                                                }.createDelegate(dropZoneBody, [node.id, filteringTree]));
@@ -37,8 +37,7 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
                                                };
                                                fadeOutFn.defer(5000, dropZoneBody);
 
-                                               filteringTree.dataProvider.deleteNode(node.id);
-                                               node.remove();
+                                               node.ownerTree.pageTree.commandProvider.removeNode(node, node.ownerTree);
                                        },
                                        ddGroup: 'TreeDD',
                                        overClass: 'dd-delete-over'
index 825a8fb..abb702e 100644 (file)
@@ -173,8 +173,10 @@ TYPO3.Components.PageTree.FeaturePanel = Ext.extend(Ext.Panel, {
                        // Only call the server if the server implements getNodeTypes();
                        this.pageTree.dataProvider.getNodeTypes(function(response) {
                                var length = response.length;
+                               var item = null;
                                for (var i = 0; i < length; ++i) {
-                                       newNodeToolbar.addItem(response[i]);
+                                       item = new Ext.Toolbar.Button(response[i]);
+                                       newNodeToolbar.addItem(item);
                                }
                                newNodeToolbar.doLayout();
                        });
@@ -182,7 +184,6 @@ TYPO3.Components.PageTree.FeaturePanel = Ext.extend(Ext.Panel, {
 
                this.pageTree.dataProvider.getSpriteIconClasses('actions-page-new', function(result) {
                        var topPanelButton = new Ext.Button({
-                               //text: 'filter',
                                cls: 'topPanel-button ' + result
                        });
 
@@ -191,7 +192,7 @@ TYPO3.Components.PageTree.FeaturePanel = Ext.extend(Ext.Panel, {
        },
 
        /**
-        * Adds a language selection menu to the topbar
+        * Adds a language selection menu to the top bar
         * @internal
         */
        addLanguageSelection: function() {
@@ -217,9 +218,9 @@ TYPO3.Components.PageTree.FeaturePanel = Ext.extend(Ext.Panel, {
                        var topPanelButton = new Ext.Button({
                                cls: 'topPanel-button ' + result,
                                listeners: {
-                                       scope: this.pageTree,
+                                       scope: this.pageTree.tree,
                                        'click': {
-                                               fn: this.pageTree.refreshTree
+                                               fn: this.pageTree.tree.refreshTree
                                        }
                                }
                        });
diff --git a/typo3/sysext/pagetree/components/pagetree/javascript/overrides.js b/typo3/sysext/pagetree/components/pagetree/javascript/overrides.js
new file mode 100644 (file)
index 0000000..06b43f0
--- /dev/null
@@ -0,0 +1,84 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Override TreeNodeUI
+ */
+
+Ext.namespace('TYPO3.Components.PageTree');
+
+TYPO3.Components.PageTree.PageTreeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+       // private
+       // This method is taken from ExtJS sources. Modifications are marked with // START TYPO3-MODIFICATION
+       renderElements : function(n, a, targetNode, bulkRender) {
+               // add some indent caching, this helps performance when rendering a large tree
+               this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
+               var cb = typeof a.checked === 'boolean';
+               var href = a.href ? a.href : Ext.isGecko ? "" : "#";
+               var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
+                       '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
+                       '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
+                       // START TYPO3-MODIFICATION
+                       a.spriteIconCode,
+                       '<span class="prefixText">', a.prefixText, '</span>',
+                       // END TYPO3-MODIFICATION
+                       cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
+                       '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
+                       a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
+                       '<ul class="x-tree-node-ct" style="display:none;"></ul>',
+                       "</li>"].join('');
+
+               var nel;
+               if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
+                       this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
+               } else {
+                       this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
+               }
+
+               this.elNode = this.wrap.childNodes[0];
+               this.ctNode = this.wrap.childNodes[1];
+               var cs = this.elNode.childNodes;
+               this.indentNode = cs[0];
+               this.ecNode = cs[1];
+               this.iconNode = cs[2];
+               // START TYPO3-MODIFICATION
+               Ext.fly(this.iconNode).on('click', function(event) {
+                       this.getOwnerTree().openContextMenu(this, event); // calling the context-menu event doesn't work!'
+                       event.stopEvent();
+               }, n);
+               // Index from 3 to 4 incremented!
+               var index = 4;
+               // STOP TYPO3-MODIFICATION
+               if (cb) {
+                       this.checkbox = cs[3];
+                       // fix for IE6
+                       this.checkbox.defaultChecked = this.checkbox.checked;
+                       index++;
+               }
+               this.anchor = cs[index];
+               this.textNode = cs[index].firstChild;
+       }
+});
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/components/pagetree/javascript/pageactions.js b/typo3/sysext/pagetree/components/pagetree/javascript/pageactions.js
deleted file mode 100644 (file)
index 7c16b08..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * This is a library of callback actions for the page tree.
- */
-
-Ext.namespace('TYPO3.Components.PageTree');
-
-TYPO3.Components.PageTree.PageActions = {
-       singleClick: function(node) {
-               TYPO3.Backend.ContentContainer.setUrl(
-                       TS.PATH_typo3 + currentSubScript + '?id=' + node.attributes.properties.realId
-               );
-       },
-
-       saveTitle: function(node, newText, oldText) {
-               if (newText == oldText) {
-                       return;
-               }
-
-               node = node.editNode;
-               TYPO3.Components.PageTree.DataProvider.setPageTitle(
-                       node.id,
-                       newText,
-                       node.attributes.properties.textSourceField,
-                       Ext.emptyFn
-               );
-       }
-};
\ No newline at end of file
index 2412aad..7027fa6 100644 (file)
@@ -1,81 +1,34 @@
-Ext.namespace('TYPO3.Components.PageTree');
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
 
 /**
- * This is the TreeNodeUI for the FilteringTree. This is the class which renders
- * the tree nodes.
- * The below modifications add another span tag around the icon for better skinning,
- * and a prefix text which is displayed in front of the real "text" contents.
- * Because the "text" property can be edited inline, the "prefixText" is used to
- * prepend the editable text.
+ * TYPO3 Page Tree Application
  */
-TYPO3.Components.PageTree.PageTreeUI = function() {
-       TYPO3.Components.PageTree.PageTreeUI.superclass.constructor.apply(this, arguments);
-};
-Ext.extend(TYPO3.Components.PageTree.PageTreeUI, Ext.tree.TreeNodeUI, {
-       // private
-       // This method is taken from ExtJS sources. Modifications are marked with // START TYPO3-MODIFICATION
-       renderElements : function(n, a, targetNode, bulkRender) {
-               // add some indent caching, this helps performance when rendering a large tree
-               this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
-               var cb = typeof a.checked == 'boolean';
-               var href = a.href ? a.href : Ext.isGecko ? "" : "#";
-               var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
-                       '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
-                       '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
-                       // START TYPO3-MODIFICATION
-                       a.spriteIconCode,
-                       '<span class="prefixText">', a.prefixText, '</span>',
-                       // END TYPO3-MODIFICATION
-                       cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
-                       '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
-                       a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
-                       '<ul class="x-tree-node-ct" style="display:none;"></ul>',
-                       "</li>"].join('');
-
-               var nel;
-               if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
-                       this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
-               } else {
-                       this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
-               }
-
-               this.elNode = this.wrap.childNodes[0];
-               this.ctNode = this.wrap.childNodes[1];
-               var cs = this.elNode.childNodes;
-               this.indentNode = cs[0];
-               this.ecNode = cs[1];
-               this.iconNode = cs[2];
-               // START TYPO3-MODIFICATION
-               Ext.fly(this.iconNode).on('click', function(event) {
-                       this.getOwnerTree().openContextMenu(this, event); // calling the context-menu event doesn't work!'
-                       event.stopEvent();
-               }, n);
-               // Index from 3 to 4 incremented!
-               var index = 4;
-               // STOP TYPO3-MODIFICATION
-               if (cb) {
-                       this.checkbox = cs[3];
-                       // fix for IE6
-                       this.checkbox.defaultChecked = this.checkbox.checked;
-                       index++;
-               }
-               this.anchor = cs[index];
-               this.textNode = cs[index].firstChild;
-       },
 
-       // private
-       // Overwriting the double click event, because we don't want to collapse or expand nodes
-       // by this event
-       onDblClick : function(e) {
-               if (this.disabled) {
-                       return;
-               }
-
-               if (this.fireEvent('beforedblclick', this.node, e) !== false) {
-                       this.fireEvent('dblclick', this.node, e);
-               }
-       }
-});
+Ext.namespace('TYPO3.Components.PageTree');
 
 TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
        id: 'typo3-pagetree',
@@ -85,6 +38,8 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
        topPanel: null,
 
        dataProvider: null,
+       commandProvider : null,
+       contextMenuDataProvider: null,
 
        contextMenuConfiguration: null,
 
@@ -92,9 +47,12 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 
        initComponent: function() {
                this.dataProvider = TYPO3.Components.PageTree.DataProvider;
+               this.commandProvider = TYPO3.Components.PageTree.Actions;
+               this.contextMenuDataProvider = TYPO3.Components.PageTree.ContextMenuDataProvider;
 
                this.tree = new TYPO3.Components.PageTree.Tree({
-                       pageTree: this
+                       pageTree: this,
+                       plugins: new Ext.ux.plugins.TreePanelStateful()
                });
 
                this.topPanel = new TYPO3.Components.PageTree.FeaturePanel({
@@ -123,10 +81,6 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
                TYPO3.Components.PageTree.App.superclass.initComponent.apply(this, arguments);
        },
 
-       refreshTree: function() {
-               this.tree.root.reload();
-       },
-
        /**
         * Initialize the inline editor for the given tree.
         *
@@ -135,16 +89,26 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
         */
        addInlineEditorFeature: function(tree) {
                var treeEditor = new Ext.tree.TreeEditor(
-                               tree, {
-                       cancelOnEsc: true,
-                       completeOnEnter: true,
-                       ignoreNoChange: true,
-                       editDelay: 250,
-                       shadow: false
-               }
-                               );
+                       tree, {
+                               ignoreNoChange: true,
+                               editDelay: 250,
+                               shadow: false
+                       }
+               );
 
-               treeEditor.addListener('complete', TYPO3.Components.PageTree.PageActions.saveTitle, this);
+       treeEditor.on({
+                       beforestartedit: {
+                               scope: this,
+                               fn: function(treeEditor) {
+                                       // @todo treeEditor.editNode.attributes.label should be used as editable label
+                               }
+                       },
+
+                       complete: {
+                               scope: this,
+                               fn: this.commandProvider.saveTitle
+                       }
+       });
        },
 
        addNodeCopyPasteFeature: function(tree) {
@@ -165,10 +129,10 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
                // This event is ONLY called on move, NOT on copy, insert or delete.
                tree.addListener('movenode', function(tree, movedNode, oldParent, newParent, position) {
                        if (position == 0) {
-                               this.dataProvider.moveNodeToFirstChildOfDestination(movedNode.id, newParent.id);
+                               this.commandProvider.moveNodeToFirstChildOfDestination(movedNode, newParent.id);
                        } else {
                                var previousSibling = newParent.childNodes[position - 1];
-                               this.dataProvider.moveNodeAfterDestination(movedNode.id, previousSibling.id);
+                               this.commandProvider.moveNodeAfterDestination(movedNode, previousSibling.id);
                        }
                }, this);
 
@@ -217,12 +181,12 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
                                de.dropNode.disable();
                                if (de.dropNode.previousSibling) {
                                        // We have previous sibling, so we want to add the record AFTER the previous sibling
-                                       this.dataProvider.insertNodeAfterDestination(de.dropNode.parentNode.id, de.dropNode.previousSibling.id, de.dropNode.serverNodeType, callback.createDelegate(de.dropNode));
+                                       this.commandProvider.insertNodeAfterDestination(de.dropNode, callback);
                                } else {
                                        if (de.dropNode.parentNode) {
                                                // We do not have a previous sibling, but a parent node. Thus, we add the node as the first child
                                                // of the parent.
-                                               this.dataProvider.insertNodeToFirstChildOfDestination(de.dropNode.parentNode.id, de.dropNode.serverNodeType, callback.createDelegate(de.dropNode));
+                                               this.commandProvider.insertNodeToFirstChildOfDestination(de.dropNode, callback);
                                        } else {
                                                // Should not happen!
                                        }
@@ -233,12 +197,12 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
                                        de.dropNode.disable();
                                        if (de.dropNode.previousSibling) {
                                                // We have previous sibling, so we want to add the record AFTER the previous sibling
-                                               this.dataProvider.copyNodeAfterDestination(de.dropNode.id, de.dropNode.previousSibling.id, callback.createDelegate(de.dropNode));
+                                               this.commandProvider.copyNodeAfterDestination(de.dropNode, callback);
                                        } else {
                                                if (de.dropNode.parentNode) {
                                                        // We do not have a previous sibling, but a parent node. Thus, we add the node as the first child
                                                        // of the parent.
-                                                       this.dataProvider.copyNodeToFirstChildOfDestination(de.dropNode.id, de.dropNode.parentNode, callback.createDelegate(de.dropNode));
+                                                       this.commandProvider.copyNodeToFirstChildOfDestination(de.dropNode, callback);
                                                } else {
                                                        // Should not happen!
                                                }
@@ -247,8 +211,8 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
                        }
                }, this);
 
-               // SECTION: Key Handlers
-               new Ext.KeyMap(document, {
+               // SECTION: Key Handlers        
+               (new Ext.KeyMap(document, {
                        key: Ext.EventObject.CONTROL,
                        fn: function() {
                                this.isControlPressed = true;
@@ -259,9 +223,9 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
                                }
                        },
                        scope: this
-               }, 'keydown');
+               }, 'keydown'));
 
-               new Ext.KeyMap(document, {
+               (new Ext.KeyMap(document, {
                        key: Ext.EventObject.CONTROL,
                        fn: function() {
                                this.isControlPressed = false;
@@ -271,7 +235,7 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
                                }
                        },
                        scope: this
-               }, 'keyup');
+               }, 'keyup'));
        }
 });
 
index e5d6adb..672b916 100644 (file)
@@ -1,3 +1,33 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * TYPO3 Page Tree Panel
+ */
+
 Ext.namespace('TYPO3.Components.PageTree');
 
 TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
@@ -9,6 +39,12 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
                ddGroup: 'TreeDD'
        },
 
+       t3ContextNode: null,
+       t3ContextInfo: {
+               inCopyMode: false,
+               inCutMode: false
+       },
+
        rootVisible: false,
        pageTree: null,
        contextMenuConfiguration: null,
@@ -23,7 +59,7 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 
                this.loader = new Ext.tree.TreeLoader({
                        directFn: this.pageTree.dataProvider.getNextTreeLevel,
-                       paramOrder: 'rootline',
+                       paramOrder: 'attributes',
 
                        baseAttrs: {
                                uiProvider: 't3'
@@ -33,38 +69,25 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
                                t3: TYPO3.Components.PageTree.PageTreeUI,
                                rootNodeProvider: Ext.tree.TreeNodeUI
                        },
-
-                       // The below method fixes a stupid bug of ExtJS / PHP JSON:
-                       // ExtJS expects the "expanded" attribute to be "true", and
-                       // it compares it with ===.
-                       // PHP json_encode submits a "1" if the value is true - thus,
-                       // the expanded property is not correctly evaluated by ExtJS.
-                       // Below, we do a loose type checking, and if it matches, we
-                       // set the JavaScript value "true". This circumvents the bug.
+                       
                        createNode: function(attr) {
-                               if (attr.expanded) {
-                                       attr.expanded = true;
+                               if (attr.id == 0) {
+                                       attr.id = 'siteRootNode';
                                }
+
                                return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
                        },
 
                        listeners: {
-                               // We always have to transmit the rootline to the server.
                                beforeload: function(treeLoader, node) {
-                                       treeLoader.baseParams.rootline = node.getPath();
+                                       treeLoader.baseParams.attributes = node.attributes;
                                },
-                               load: function(treeLoader, node) {
-                                       // Helper function
-                                       var expandTransmittedNodesRecursively = function(node) {
-                                               var numberOfSubNodes = node.childNodes.length;
-                                               if (numberOfSubNodes > 0) {
-                                                       node.expand(false, false);
-                                               }
-                                               for (var i = 0; i < numberOfSubNodes; i++) {
-                                                       expandTransmittedNodesRecursively(node.childNodes[i]);
-                                               }
-                                       };
-                                       expandTransmittedNodesRecursively(node);
+
+                               load: {
+                                       scope: this,
+                                       fn: function(treeLoader, node) {
+                                               this.restoreState(node.getPath());
+                                       }
                                }
                        }
                });
@@ -75,70 +98,73 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
        // shows the context menu and creates it if it's not already done
        openContextMenu: function(node, event) {
                node.select();
-               var contextMenu = node.getOwnerTree().contextMenu;
-               contextMenu.removeAll();
 
-               var numberOfElementsInside = contextMenu.fillWithMenuItems(node, this.contextMenuConfiguration);
-               if (numberOfElementsInside > 0) {
-                       contextMenu.showAt(event.getXY());
-               }
-       },
+               var attributes = { t3ContextInfo: node.ownerTree.t3ContextInfo };
+               attributes = Ext.apply(node.attributes.nodeData, attributes);
 
-       listeners: {
-               // SECTION Contextmenu
-               // After rendering of the tree, we start the preloading of the context
-               // menu configuration
-               afterrender: {
-                       fn: function(tree) {
-                               if (tree.contextMenuConfiguration == null) {
-                                       this.pageTree.dataProvider.getContextMenuConfiguration(
-                                               function(result) {
-                                                       tree.contextMenuConfiguration = result;
-                                               }
-                                       );
+               this.pageTree.contextMenuDataProvider.getActionsForNodeArray(
+                       attributes,
+                       function(result) {
+                               var contextMenu = node.getOwnerTree().contextMenu;
+                               contextMenu.removeAll();
+
+                               var numberOfElementsInside = contextMenu.fillWithMenuItems(node, this.pageTree, result);
+                               if (numberOfElementsInside > 0) {
+                                       contextMenu.showAt(event.getXY());
                                }
-                       }
-               },
+                       },
+                       this
+               );
+       },
+
+       refreshTree: function() {
+               this.getLoader().load(this.root);
+       },
 
+       refreshNode: function(node) {
+               this.getLoader().load(node);
+       },
+
+       listeners: {
                // this event triggers the context menu
                contextmenu: {
+                       scope: this,
                        fn: function(node, event) {
                                node.getOwnerTree().openContextMenu(node, event);
                        }
                },
 
-               // SECTION Tree State Remember
-               expandnode: {
-                       fn: function (node) {
-                               this.pageTree.dataProvider.registerExpandedNode(node.getPath());
-                       }
-               },
-
-               collapsenode: {
-                       fn: function(node) {
-                               this.pageTree.dataProvider.registerCollapsedNode(node.getPath());
-                       }
-               },
-
-               // calls a given single click callback for the tree
+                       // calls a given single click callback for the tree
                click: {
-                       fn: function (node, event) {
-                               if (this.doubleClickEventActive) {
-                                       this.doubleClickEventActive = false;
+                       fn: function(node, event) {
+                               if (this.clicksRegistered === 2) {
+                                       this.clicksRegistered = 0;
                                        event.stopEvent();
-                               } else {
-                                       eval(node.attributes.properties.clickCallback + '(node)');
+                                       return false;
                                }
+
+                               this.clicksRegistered = 0;
+                               this.pageTree.commandProvider.singleClick(node);
                        },
                        delay: 400
                },
 
-               // seems to prevent some internal issues with the double-click for the tree editor
-               dblclick: {
+                       // needed or the label edit will never work
+               beforedblclick: {
                        fn: function() {
-                               this.doubleClickEventActive = true;
                                return false;
                        }
+               },
+
+               beforeclick: {
+                       fn: function(node, event) {
+                               if (!this.clicksRegistered && this.getSelectionModel().isSelected(node)) {
+                                       node.fireEvent('click', node, event);
+                                       ++this.clicksRegistered;
+                                       return false;
+                               }
+                               ++this.clicksRegistered;
+                       }
                }
        }
 });
index 402ccf3..93fe086 100644 (file)
@@ -2,11 +2,16 @@
 
 $extensionPath = t3lib_extMgm::extPath('pagetree');
 return array(
-       'tx_pagetree_abstracttree' => $extensionPath . 'classes/class.tx_pagetree_abstracttree.php',
-       'tx_pagetree_pagetree' => $extensionPath . 'classes/class.tx_pagetree_pagetree.php',
-       'tx_contextmenu_contextmenu' => $extensionPath . 'classes/class.tx_contextmenu_contextmenu.php',
-       'tx_pagetree_dataprovider_pagetree' => $extensionPath . 'extdirect/dataproviderclass.tx_pagetree_dataprovider_pagetree.php',
-       'tx_pagetree_dataprovider_abstracttree' => $extensionPath . 'extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php',
+       'tx_pagetree_extdirect_tree' => $extensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_tree.php',
+       'tx_pagetree_extdirect_commands' => $extensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_commands.php',
+       'tx_pagetree_extdirect_contextmenu' => $extensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php',
+       'tx_pagetree_dataprovider' => $extensionPath . 'classes/class.tx_pagetree_dataprovider.php',
+       'tx_pagetree_node' => $extensionPath . 'classes/class.tx_pagetree_node.php',
+       'tx_pagetree_nodecollection' => $extensionPath . 'classes/class.tx_pagetree_nodecollection.php',
+       'tx_pagetree_stateprovider' => $extensionPath . 'classes/class.tx_pagetree_stateprovider.php',
+       'tx_pagetree_commands' => $extensionPath . 'classes/class.tx_pagetree_commands.php',
+       'tx_pagetree_contextmenu_action' => $extensionPath . 'classes/contextmenu/class.tx_pagetree_contextmenu_action.php',
+       'tx_pagetree_contextmenu_dataprovider' => $extensionPath . 'classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php',
 );
 
 ?>
\ No newline at end of file
index a8cb002..df865b2 100644 (file)
@@ -3,7 +3,7 @@
 ########################################################################
 # Extension Manager/Repository config file for ext "pagetree".
 #
-# Auto generated 16-11-2010 23:35
+# Auto generated 01-12-2010 12:27
 #
 # Manual updates:
 # Only the data in the array - everything else is removed by next
@@ -32,8 +32,8 @@ $EM_CONF[$_EXTKEY] = array(
        'author_company' => '',
        'CGLcompliance' => '',
        'CGLcompliance_note' => '',
-       'version' => '1.0.0',
-       '_md5_values_when_last_written' => 'a:19:{s:16:"ext_autoload.php";s:4:"c92c";s:12:"ext_icon.gif";s:4:"39bd";s:17:"ext_localconf.php";s:4:"a736";s:14:"ext_tables.php";s:4:"1e9f";s:25:"locallang_contextmenu.xml";s:4:"72dd";s:22:"locallang_pagetree.xml";s:4:"cd10";s:44:"classes/class.tx_contextmenu_contextmenu.php";s:4:"d8ab";s:42:"classes/class.tx_pagetree_abstracttree.php";s:4:"fc36";s:38:"classes/class.tx_pagetree_pagetree.php";s:4:"a142";s:36:"components/pagetree/css/pagetree.css";s:4:"9764";s:45:"components/pagetree/javascript/contextmenu.js";s:4:"3661";s:52:"components/pagetree/javascript/contextmenuactions.js";s:4:"89bd";s:50:"components/pagetree/javascript/deletiondropzone.js";s:4:"a924";s:46:"components/pagetree/javascript/featurepanel.js";s:4:"7c58";s:45:"components/pagetree/javascript/pageactions.js";s:4:"83f9";s:42:"components/pagetree/javascript/pagetree.js";s:4:"0786";s:38:"components/pagetree/javascript/tree.js";s:4:"4a3e";s:70:"extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php";s:4:"bfef";s:66:"extdirect/dataprovider/class.tx_pagetree_dataprovider_pagetree.php";s:4:"3eb3";}',
+       'version' => '1.1.0',
+       '_md5_values_when_last_written' => 'a:30:{s:16:"ext_autoload.php";s:4:"b480";s:12:"ext_icon.gif";s:4:"39bd";s:17:"ext_localconf.php";s:4:"d1c7";s:14:"ext_tables.php";s:4:"7d74";s:25:"locallang_contextmenu.xml";s:4:"72dd";s:22:"locallang_pagetree.xml";s:4:"1265";s:38:"classes/class.tx_pagetree_commands.php";s:4:"7371";s:42:"classes/class.tx_pagetree_dataprovider.php";s:4:"eb8e";s:34:"classes/class.tx_pagetree_node.php";s:4:"b0a7";s:44:"classes/class.tx_pagetree_nodecollection.php";s:4:"a52a";s:43:"classes/class.tx_pagetree_stateprovider.php";s:4:"e0ab";s:60:"classes/contextmenu/class.tx_pagetree_contextmenu_action.php";s:4:"efa8";s:66:"classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php";s:4:"9ad1";s:58:"classes/extdirect/class.tx_pagetree_extdirect_commands.php";s:4:"eade";s:61:"classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php";s:4:"c7bc";s:54:"classes/extdirect/class.tx_pagetree_extdirect_tree.php";s:4:"b483";s:43:"components/pagetree/pagetree-application.js";s:4:"46be";s:43:"components/pagetree/pagetree-contextmenu.js";s:4:"bfad";s:39:"components/pagetree/pagetree-factory.js";s:4:"d503";s:41:"components/pagetree/pagetree-overrides.js";s:4:"1552";s:36:"components/pagetree/pagetree-tree.js";s:4:"b338";s:36:"components/pagetree/css/pagetree.css";s:4:"9764";s:66:"components/pagetree/javascript/Ext.ux.plugins.TreePanelStateful.js";s:4:"c062";s:41:"components/pagetree/javascript/actions.js";s:4:"3a05";s:45:"components/pagetree/javascript/contextmenu.js";s:4:"0424";s:50:"components/pagetree/javascript/deletiondropzone.js";s:4:"c21f";s:46:"components/pagetree/javascript/featurepanel.js";s:4:"d398";s:43:"components/pagetree/javascript/overrides.js";s:4:"f231";s:42:"components/pagetree/javascript/pagetree.js";s:4:"46d5";s:38:"components/pagetree/javascript/tree.js";s:4:"9dfa";}',
        'constraints' => array(
                'depends' => array(
                        'cms' => '',
index eb0f715..ed0a681 100644 (file)
@@ -3,13 +3,12 @@ if (!defined('TYPO3_MODE')) {
        die ('Access denied.');
 }
 
-       // pagetree user default configuration
+       // context menu user default configuration
 $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
-       options.pageTree.doktypesToShowInNewPageDragArea = 1,3,4,6,7,199,254
-';
+       options.pageTree {
+               doktypesToShowInNewPageDragArea = 1,3,4,6,7,199,254
+       }
 
-       // contextmenu user default configuration
-$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
        options.contextMenu {
                defaults {
                }
@@ -19,9 +18,9 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                100 = ITEM
                                100 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.viewPage
-                                       outerIcon = actions-document-view
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.viewPage
+                                       spriteIcon = actions-document-view
+                                       displayCondition = canBeViewed != 0
+                                       callbackAction = viewPage
                                }
 
                                200 = DIVIDER
@@ -29,41 +28,41 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                300 = ITEM
                                300 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.disablePage
-                                       outerIcon = actions-edit-hide
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.disablePage
+                                       spriteIcon = actions-edit-hide
+                                       displayCondition = getRecord|hidden = 0 && canBeDisabledAndEnabled != 0
+                                       callbackAction = disablePage
                                }
 
                                400 = ITEM
                                400 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.enablePage
-                                       outerIcon = actions-edit-unhide
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.enablePage
+                                       spriteIcon = actions-edit-unhide
+                                       displayCondition = getRecord|hidden = 1 && canBeDisabledAndEnabled != 0
+                                       callbackAction = enablePage
                                }
 
                                500 = ITEM
                                500 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.editPageProperties
-                                       outerIcon = actions-document-open
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.editPageProperties
+                                       spriteIcon = actions-document-open
+                                       displayCondition = canBeEdited != 0
+                                       callbackAction = editPageProperties
                                }
 
                                600 = ITEM
                                600 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.info
-                                       outerIcon = actions-document-info
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.openInfoPopUp
+                                       spriteIcon = actions-document-info
+                                       displayCondition = canShowInfo != 0
+                                       callbackAction = openInfoPopUp
                                }
 
                                700 = ITEM
                                700 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.history
-                                       outerIcon = apps-pagetree-page-default+status-overlay-timing
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.openHistoryPopUp
+                                       spriteIcon = actions-document-history-open
+                                       displayCondition = canShowHistory != 0
+                                       callbackAction = openHistoryPopUp
                                }
 
                                800 = DIVIDER
@@ -75,9 +74,9 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                        100 = ITEM
                                        100 {
                                                label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.newPage
-                                               outerIcon = actions-document-new
-                                               icon =
-                                               callbackAction = TYPO3.Components.PageTree.ContextMenuActions.newPageWizard
+                                               spriteIcon = actions-document-new
+                                               displayCondition = canCreateNewPages != 0
+                                               callbackAction = newPageWizard
                                        }
 
                                        200 = DIVIDER
@@ -85,43 +84,59 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                        300 = ITEM
                                        300 {
                                                label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
-                                               outerIcon = actions-edit-cut
-                                               icon =
-                                               callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+                                               spriteIcon = actions-edit-cut
+                                               displayCondition = isInCutMode = 0 && canBeCut != 0
+                                               callbackAction = enableCutMode
                                        }
 
                                        400 = ITEM
                                        400 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
-                                               outerIcon = actions-edit-copy
-                                               icon =
-                                               callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
+                                               spriteIcon = actions-edit-cut-release
+                                               displayCondition = isInCutMode = 1 && canBeCut != 0
+                                               callbackAction = disableCutMode
                                        }
 
                                        500 = ITEM
                                        500 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoPage
-                                               outerIcon = actions-document-paste-after
-                                               icon =
-                                               callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
+                                               spriteIcon = actions-edit-copy
+                                               displayCondition = isInCopyMode = 0 && canBeCopied != 0
+                                               callbackAction = enableCopyMode
                                        }
 
                                        600 = ITEM
                                        600 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteAfterPage
-                                               outerIcon = actions-document-paste-into
-                                               icon =
-                                               callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
+                                               spriteIcon = actions-edit-copy-release
+                                               displayCondition = isInCopyMode = 1 && canBeCopied != 0
+                                               callbackAction = disableCopyMode
                                        }
 
-                                       700 = DIVIDER
+                                       700 = ITEM
+                                       700 {
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoPage
+                                               spriteIcon = actions-document-paste-after
+                                               displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1
+                                               callbackAction = pasteIntoNode
+                                       }
 
                                        800 = ITEM
                                        800 {
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteAfterPage
+                                               spriteIcon = actions-document-paste-into
+                                               displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1
+                                               callbackAction = pasteAfterNode
+                                       }
+
+                                       900 = DIVIDER
+
+                                       1000 = ITEM
+                                       1000 {
                                                label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.deletePage
-                                               outerIcon = actions-edit-delete
-                                               icon =
-                                               callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+                                               spriteIcon = actions-edit-delete
+                                               displayCondition = canBeRemoved != 0
+                                               callbackAction = removeNode
                                        }
                                }
 
@@ -132,9 +147,9 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                        100 = ITEM
                                        100 {
                                                label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.tempMountPoint
-                                               outerIcon = actions-system-extension-documentation
-                                               icon =
-                                               callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+                                               spriteIcon = actions-system-extension-documentation
+                                               displayCondition = canBeTemporaryMountPoint != 0
+                                               callbackAction = stub
                                        }
                                }
                        }
@@ -145,33 +160,29 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                100 = ITEM
                                100 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.renameFolder
-                                       outerIcon = actions-edit-rename
-                                       icon =
-                                       callbackAction = TYPO3.Widget.ContextMenu.FolderActions.renameFolder
+                                       spriteIcon = actions-edit-rename
+                                       callbackAction = renameFolder
                                }
 
                                200 = ITEM
                                200 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.uploadFilesToFolder
-                                       outerIcon = actions-edit-upload
-                                       icon =
-                                       callbackAction = TYPO3.Widget.ContextMenu.FolderActions.uploadFilesToFolder
+                                       spriteIcon = actions-edit-upload
+                                       callbackAction = uploadFilesToFolder
                                }
 
                                300 = ITEM
                                300 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.createFolder
-                                       outerIcon = actions-edit-add
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.createFolder
+                                       spriteIcon = actions-edit-add
+                                       callbackAction = createFolder
                                }
 
                                400 = ITEM
                                400 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.folderInfo
-                                       outerIcon = actions-document-info
-                                       icon =
-                                       callbackAction = TYPO3.Widget.ContextMenu.FolderActions.openInfoPopUp
+                                       spriteIcon = actions-document-info
+                                       callbackAction = openInfoPopUp
                                }
 
                                500 = DIVIDER
@@ -179,25 +190,22 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                600 = ITEM
                                600 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyFolder
-                                       outerIcon = actions-edit-copy
-                                       icon =
-                                       callbackAction = TYPO3.Widget.ContextMenu.FolderActions.copyFolder
+                                       spriteIcon = actions-edit-copy
+                                       callbackAction = copyFolder
                                }
 
                                700 = ITEM
                                700 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutFolder
-                                       outerIcon = actions-edit-cut
-                                       icon =
-                                       callbackAction = TYPO3.Widget.ContextMenu.FolderActions.cutFolder
+                                       spriteIcon = actions-edit-cut
+                                       callbackAction = cutFolder
                                }
 
                                800 = ITEM
                                800 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoFolder
-                                       outerIcon = actions-document-paste-after
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.pasteIntoFolder
+                                       spriteIcon = actions-document-paste-after
+                                       callbackAction = pasteIntoFolder
                                }
 
                                900 = DIVIDER
@@ -205,9 +213,8 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
                                1000 = ITEM
                                1000 {
                                        label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.deleteFolder
-                                       outerIcon = actions-edit-delete
-                                       icon =
-                                       callbackAction = TYPO3.Components.PageTree.ContextMenuActions.deleteFolder
+                                       spriteIcon = actions-edit-delete
+                                       callbackAction = deleteFolder
                                }
                        }
                }
index 1919394..0d2b94e 100644 (file)
@@ -14,8 +14,17 @@ if (TYPO3_MODE === 'BE') {
                ));
        }
 
-       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']['TYPO3.Components.PageTree.DataProvider'] =
-               t3lib_extMgm::extPath($_EXTKEY) . 'extdirect/dataprovider/class.tx_pagetree_dataprovider_pagetree.php:tx_pagetree_dataprovider_Pagetree';
+       $absoluteExtensionPath = t3lib_extMgm::extPath($_EXTKEY);
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'] = array_merge(
+               $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'], array(
+                       'TYPO3.Components.PageTree.DataProvider' =>
+                               $absoluteExtensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_tree.php:tx_pagetree_ExtDirect_Tree',
+                       'TYPO3.Components.PageTree.Commands' =>
+                               $absoluteExtensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_tree.php:tx_pagetree_ExtDirect_Commands',
+                       'TYPO3.Components.PageTree.ContextMenuDataProvider' =>
+                               $absoluteExtensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php:tx_pagetree_ExtDirect_ContextMenu',
+               )
+       );
 }
 
 ?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php b/typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php
deleted file mode 100644 (file)
index c1d2782..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-<?php
-/***************************************************************
- *  Copyright notice
- *
- *  (c) 2009 Sebastian Kurfuerst
- *  All rights reserved
- *
- *  This script is part of the TYPO3 project. The TYPO3 project is
- *  free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The GNU General Public License can be found at
- *  http://www.gnu.org/copyleft/gpl.html.
- *  A copy is found in the textfile GPL.txt and important notices to the license
- *  from the author is found in LICENSE.txt distributed with these scripts.
- *
- *
- *  This script is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-/**
- * Abstract tree dataprovider
- *
- * @author     Sebastian Kurfuerst <sebastian@typo3.org>
- * @package    TYPO3
- */
-abstract class tx_pagetree_dataprovider_AbstractTree {
-
-       protected $treeName;
-
-       /**
-        * Fetches the Items for the next level of the tree
-        *
-        * @param mixed The ID of the tree node
-        * @param string The rootline of the element
-        * @return array The next level tree elements
-        */
-       public function getNextTreeLevel($id, $rootline) {
-               // Load UC
-               $GLOBALS['BE_USER']->backendSetUC();
-               $treeState =& $GLOBALS['BE_USER']->uc['treeState'][$this->treeName];
-
-               $records = $this->getRecordsForNextTreeLevel($this->decodeTreeNodeId($id));
-               $results = array();
-               foreach ($records as $record) {
-                       $singleResult = $this->prepareRecordForResultList($record, $rootline);
-                       $rootlineOfSubElement = $rootline;
-                       // the rootline functionality is completely nonsense and should be replaced completely
-                       if ($singleResult['id']) {
-                               $rootlineOfSubElement = $rootline . '/' . $singleResult['id'];
-                       }
-                       if (isset($treeState[$rootlineOfSubElement])) {
-                               $singleResult['expanded'] = true;
-                               $singleResult['children'] = $this->getNextTreeLevel($singleResult['id'], $rootlineOfSubElement);
-                       }
-
-                       $results[] = $singleResult;
-               }
-               return $results;
-       }
-
-       /**
-        * Prepares the records for the result list & fetches the actions
-        *
-        * @param array $record The record to be prepared
-        * @param string $rootline The rootline of the record
-        * @return array The prepared result
-        */
-       protected function prepareRecordForResultList($record, $rootline = '') {
-               $currentResult = $this->getTreeNodePropertiesForRecord($record, $rootline);
-               $currentResult['actions'] = $this->getActionsForRecord($record);
-               return $currentResult;
-       }
-
-       /**
-        * Saves the current expanded state of the tree to the user settings
-        *
-        * @param string $rootline The current rootline
-        */
-       public function registerExpandedNode($rootline) {
-               $GLOBALS['BE_USER']->backendSetUC();
-               $treeState =& $GLOBALS['BE_USER']->uc['treeState'][$this->treeName];
-               $treeState[$rootline] = TRUE;
-               $GLOBALS['BE_USER']->writeUC();
-       }
-
-       /**
-        * Saves the current collapsed state of the tree to the user settings
-        *
-        * @param string $rootline The current rootline
-        */
-       public function registerCollapsedNode($rootline) {
-               $GLOBALS['BE_USER']->backendSetUC();
-               $treeState =& $GLOBALS['BE_USER']->uc['treeState'][$this->treeName];
-               if (isset($treeState[$rootline])) {
-                       unset($treeState[$rootline]);
-               }
-               $GLOBALS['BE_USER']->writeUC();
-       }
-
-
-       /**
-        * Encode node id and its rootline into an global unique identifier even if the same
-        * node id is used a couple of times (webmounts, filemount, ...)
-        *
-        * @param string $id node id
-        * @param string $rootline rootline / path include base-node like webmount-id/filemount-name
-        */
-       protected function encodeTreeNodeId($id, $rootline) {
-               if ($rootline == '/root') {
-                       return $this->idEncode($id);
-               } else {
-                       list(, , $mountpoint) = explode('/', $rootline);
-                       return 'mp' . $this->idEncode($mountpoint) . '-' . $this->idEncode($id);
-               }
-       }
-
-       /**
-        * Decodes the id of the tree node
-        *
-        * @param string $id The ID string
-        * @return int
-        */
-       protected function decodeTreeNodeId($id) {
-               if (strpos($id, 'mp') === 0) {
-                       // everything _INSIDE_ a mountpage
-                       // mp is in there, extract the ID!
-                       list(, $id) = explode('-', $id);
-                       return $this->idDecode($id);
-               } else {
-                       // /root, and /root/XXX (mountpage)
-                       return $id;
-               }
-       }
-
-       /**
-        * Encodes an id, this one just does an intval, if you need
-        * something more implement your own method
-        * @return the encoded ID
-        */
-       protected function idEncode($id) {
-               return intval($id);
-       }
-
-       /**
-        * Decodes an id, this one just does an intval, if you need
-        * something more implement your own method
-        * @return the decoded ID
-        */
-       protected function idDecode($id) {
-               return intval($id);
-       }
-
-       /**
-        * Get Label
-        *
-        * @param string $label label name
-        * @return string the localized label string
-        */
-       protected function getLabel($label) {
-               return $GLOBALS['LANG']->sL($label, TRUE);
-       }
-
-       /**
-        * Get Icon for Context Menu
-        *
-        * @param string $icon Icon name
-        * @return string Returns part of the img tag like ' src="[backPath][src]" [wHattribs]'
-        */
-       protected function getIcon($icon) {
-
-               return $icon;
-       }
-
-       /**
-        * Fetches a filtered tree
-        *
-        * @param string $searchString The string to search for
-        *
-        */
-       abstract public function getFilteredTree($searchString);
-
-       /**
-        * Fetches the records for the next tree level (subpages or subdirectories f.e.)
-        *
-        * @return array a multidimensional array of records to be displayed in the tree on the next level, including the metainformation for the record
-        */
-       abstract protected function getRecordsForNextTreeLevel($id);
-
-       /**
-        * gets a record, and MUST return an array with the following properties:
-        * - id (UNIQUE id)
-        * - leaf (boolean) - FALSE, if it has child records
-        * - text - the title of the node in the tree
-        * additionally, you can specify any of the Ext.tree.TreeNode properties, except "attributes".
-        */
-       abstract protected function getTreeNodePropertiesForRecord($record, $rootline);
-
-
-       /**
-        * Get an array of actions which can be performed with this single record. Used for the context menu.
-        */
-       abstract protected function getActionsForRecord($record);
-
-       /**
-        * Generates the context menu items which can be toogled on/off by the record actions.
-        * You need to define them inside a hash array with the fields "text" and "callback".
-        * @see getActionsForRecord
-        */
-       abstract public function getContextMenuConfiguration();
-}
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php']) {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php']);
-}
-
-?>
\ No newline at end of file
diff --git a/typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_pagetree.php b/typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_pagetree.php
deleted file mode 100644 (file)
index e507308..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-<?php
-/***************************************************************
- *  Copyright notice
- *
- *  (c) 2009 Sebastian Kurfuerst
- *  All rights reserved
- *
- *  This script is part of the TYPO3 project. The TYPO3 project is
- *  free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The GNU General Public License can be found at
- *  http://www.gnu.org/copyleft/gpl.html.
- *  A copy is found in the textfile GPL.txt and important notices to the license
- *  from the author is found in LICENSE.txt distributed with these scripts.
- *
- *
- *  This script is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-class tx_pagetree_dataprovider_Pagetree extends tx_pagetree_dataprovider_AbstractTree {
-       public $enableIcons = TRUE;
-       public $backPath = '';
-       protected $treeName = 'pages';
-
-       /**
-        * PageTree
-        *
-        * @var tx_pagetree_Pagetree
-        */
-       protected $pageTree;
-
-       public function __construct() {
-               $this->pageTree = t3lib_div::makeInstance('tx_pagetree_Pagetree');
-
-               if ($GLOBALS['BE_USER']->uc['noMenuMode']
-                       && strcmp($GLOBALS['BE_USER']->uc['noMenuMode'], 'icons')
-               ) {
-                       $this->enableIcons = FALSE;
-               }
-       }
-
-       public function moveNodeToFirstChildOfDestination($movedNode, $destination) {
-               $movedNode = $this->decodeTreeNodeId($movedNode);
-               $destination = $this->decodeTreeNodeId($destination);
-
-               $uid = intval($movedNode);
-               $destination = intval($destination);
-               $this->pageTree->move($uid, $destination);
-       }
-
-       public function moveNodeAfterDestination($movedNode, $destination) {
-               $movedNode = $this->decodeTreeNodeId($movedNode);
-               $destination = $this->decodeTreeNodeId($destination);
-
-               $uid = intval($movedNode);
-               $destination = intval($destination);
-               $this->pageTree->move($uid, -$destination);
-       }
-
-       public function copyNodeToFirstChildOfDestination($copiedNode, $destination) {
-               $copiedNode = $this->decodeTreeNodeId($copiedNode);
-               $destination = $this->decodeTreeNodeId($destination);
-
-               $uid = intval($copiedNode);
-               $destination = intval($destination);
-               $newPageId = $this->pageTree->copy($uid, $destination);
-
-               return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
-       }
-
-       public function copyNodeAfterDestination($copiedNode, $destination) {
-               $copiedNode = $this->decodeTreeNodeId($copiedNode);
-               $destination = $this->decodeTreeNodeId($destination);
-
-               $uid = intval($copiedNode);
-               $destination = intval($destination);
-
-               $newPageId = $this->pageTree->copy($uid, -$destination);
-
-               return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
-       }
-
-       public function insertNodeToFirstChildOfDestination($parentNode, $pageType) {
-               $parentNode = intval($this->decodeTreeNodeId($parentNode));
-
-               $newPageId = $this->pageTree->create($parentNode, $parentNode, $pageType);
-               return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
-       }
-
-       public function insertNodeAfterDestination($parentNode, $destination, $pageType) {
-               $parentNode = intval($this->decodeTreeNodeId($parentNode));
-               $destination = intval($this->decodeTreeNodeId($destination));
-
-               $newPageId = $this->pageTree->create($parentNode, -$destination, $pageType);
-               return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
-       }
-
-
-       public function deleteNode($nodeId) {
-               $id = $this->decodeTreeNodeId($nodeId);
-               $this->pageTree->remove($id);
-       }
-
-       public function undeleteNode($nodeId) {
-               $id = $this->decodeTreeNodeId($nodeId);
-               $this->pageTree->restore($id);
-       }
-
-       protected function getWholeRecordForIdAndPrepareItForResultList($newNode) {
-               $resultRow = t3lib_BEfunc::getRecordWSOL(
-                       'pages',
-                       $newNode,
-                       $fields = '*',
-                       $where = '',
-                       $useDeleteClause = TRUE,
-                       $GLOBALS['BE_USER']->uc['currentPageTreeLanguage']
-               );
-               return $this->prepareRecordForResultList($resultRow);
-       }
-
-       public function getFilteredTree($searchString) {
-               $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
-                       'uid',
-                       'pages',
-                               'title LIKE ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchString . '%', 'pages') .
-                                               t3lib_BEfunc::deleteClause('pages') .
-                                               t3lib_BEfunc::versioningPlaceholderClause('pages') . ' AND ' .
-                                               $GLOBALS['BE_USER']->getPagePermsClause(1)
-               );
-
-               $result = array();
-               foreach ($records as $singleRecord) {
-                       $rootline = t3lib_BEfunc::BEgetRootLine($singleRecord['uid']);
-                       $rootline = array_reverse($rootline);
-                       array_shift($rootline);
-                       $currentNode = &$result; // what the fuck? Who codes such unmaintainable stuff?
-
-                       foreach ($rootline as $rootlineElement) {
-                               $rootlineElement['_subpages'] = 1;
-                               if (isset($currentNode[$rootlineElement['uid']])) {
-                                       $currentNode = &$currentNode[$rootlineElement['uid']]['children'];
-                               }
-                               else {
-                                       $currentNode[$rootlineElement['uid']] = $this->prepareRecordForResultList($rootlineElement);
-                                       $currentNode[$rootlineElement['uid']]['text'] = preg_replace('/(' .
-                                                       preg_quote($searchString, '/') . ')/i', '<strong class="highlight">$1</strong>',
-                                               $currentNode[$rootlineElement['uid']]['text']);
-
-
-                                       $currentNode[$rootlineElement['uid']]['children'] = array();
-                                       $currentNode = &$currentNode[$rootlineElement['uid']]['children'];
-                               }
-                       }
-               }
-               $this->convertChildrenToUnnamedArray($result);
-               return $result;
-       }
-
-       private function convertChildrenToUnnamedArray(&$array) {
-               $array = array_values($array);
-               foreach ($array as &$value) {
-                       if (isset($value['children']) && is_array($value['children'])) {
-                               $this->convertChildrenToUnnamedArray($value['children']);
-                       }
-               }
-       }
-
-       protected function getRecordsForNextTreeLevel($id) {
-               if ($id === 'root') {
-                       return $this->pageTree->getTreeMounts();
-               } else {
-                       return $this->pageTree->getSubPages($id);
-               }
-       }
-
-       protected function getTreeNodePropertiesForRecord($record, $rootline) {
-               if ($this->pageTree->getTsConfigOptionForPagetree('showNavTitle')) {
-                       $fields = array('nav_title', 'title');
-               } else {
-                       $fields = array('title', 'nav_title');
-               }
-
-               $textSourceField = '';
-               foreach ($fields as $field) {
-                       if (!empty($record[$field])) {
-                               $text = $record[$field];
-                               $textSourceField = $field;
-                               break;
-                       }
-               }
-
-               $languageOverlayIcon = '';
-               if ($record['_PAGES_OVERLAY']) {
-                       $currentTreeLanguage = intval($GLOBALS['BE_USER']->uc['currentPageTreeLanguage']);
-                       $languageRecord = $this->getLanguage($currentTreeLanguage);
-                       $languageShortcut = $this->getLanguageShortcutFromFile($languageRecord['flag']);
-                       $languageOverlayIcon = t3lib_iconWorks::getSpriteIcon(
-                               'flags-' . $languageShortcut . '-overlay'
-                       );
-                       unset($languageRecord, $languageShortcut);
-               }
-
-               if ($record['uid'] !== 0) {
-                       $spriteIconCode = t3lib_iconWorks::getSpriteIconForRecord(
-                               'pages',
-                               $record,
-                               array(
-                                       'html' => $languageOverlayIcon,
-                               )
-                       );
-               } else {
-                       $spriteIconCode = t3lib_iconWorks::getSpriteIcon('apps-pagetree-root');
-               }
-               return array(
-                       'record' => $record,
-                       'id' => $this->encodeTreeNodeId($record['uid'], $rootline),
-                       'qtip' => 'ID: ' . $record['uid'],
-                       'leaf' => $record['_subpages'] == 0,
-                       'text' => $text,
-                       'prefixText' => $this->getPrefixForDisplayedTitle($record), // This is the prefix before the title string
-                       'spriteIconCode' => $spriteIconCode,
-                       '_meta' => array('numSubPages' => $record['_subpages']),
-                       'properties' => array(
-                               'clickCallback' => 'TYPO3.Components.PageTree.PageActions.singleClick',
-                               'textSourceField' => $textSourceField,
-                               'realId' => $record['uid']
-                       )
-               );
-       }
-
-       public function getSpriteIconClasses($icon) {
-               return t3lib_iconWorks::getSpriteIconClasses($icon);
-       }
-
-       // @todo respect tsconfig options
-       protected function getActionsForRecord($record) {
-               return $record['_actions'];
-       }
-
-       protected function getPrefixForDisplayedTitle($row) {
-               $prefix = '';
-
-               if ($this->pageTree->getTsConfigOptionForPagetree('showPageIdWithTitle')) {
-                       $prefix .= $row['uid'];
-               }
-               return $prefix;
-       }
-
-       public function getPageInformation($pageId, $fields) {
-               return $this->pageTree->getPageInformationForGivenFields($pageId, $fields);
-       }
-
-       protected function getNextContextMenuLevel($typoScriptConfiguration, $level) {
-               if ($level > 5) {
-                       return array();
-               }
-
-               $type = '';
-               $contextMenuItems = array();
-               foreach ($typoScriptConfiguration as $index => $typoScriptItem) {
-                       $hash = md5(microtime());
-
-                       if (substr($index, -1) === '.') {
-                               switch ($type) {
-                                       case 'SUBMENU':
-                                               $contextMenuItems['--submenu-' . $hash . '--'] =
-                                                               $this->getNextContextMenuLevel($typoScriptItem, ++$level);
-
-                                               $contextMenuItems['--submenu-' . $hash . '--']['text'] =
-                                                               $this->getLabel($typoScriptItem['label']);
-                                               break;
-
-                                       case 'ITEM':
-                                               // transform icon and text
-                                               $contextMenuItems[$index] = array(
-                                                       'text' => $this->getLabel($typoScriptItem['label'])
-                                               );
-
-                                               // push additional attributes
-                                               $contextMenuItems[$index] = array_merge(
-                                                       $typoScriptItem,
-                                                       $contextMenuItems[$index]
-                                               );
-
-                                               if ($this->enableIcons) {
-                                                       if (!empty($typoScriptItem['icon'])) {
-                                                               $contextMenuItems[$index]['icon'] =
-                                                                               $this->getIcon($typoScriptItem['icon']);
-                                                       } elseif (isset($typoScriptItem['outerIcon'])) {
-                                                               $contextMenuItems[$index] = array_merge(
-                                                                       $contextMenuItems[$index],
-                                                                       $this->getIconClassFromIcon($typoScriptItem['outerIcon'])
-                                                               );
-                                                       }
-                                               } else {
-                                                       $contextMenuItems[$index]['icon'] = '';
-                                               }
-                                               break;
-
-                                       default:
-                                               break;
-                               }
-                       } else {
-                               $type = $typoScriptItem;
-
-                               // add divider
-                               if ($type === 'DIVIDER') {
-                                       $contextMenuItems['--divider-' . $hash . '--'] = array(
-                                               'action' => 'divider'
-                                       );
-                               }
-                       }
-               }
-
-               return $contextMenuItems;
-       }
-
-       public function getContextMenuConfiguration() {
-               // @TODO defaults must be considered
-               $contextMenuItemTypoScriptConfiguration = $GLOBALS['BE_USER']->getTSConfig(
-                       'options.contextMenu.table.pages.items'
-               );
-               $contextMenuItemTypoScriptConfiguration = $contextMenuItemTypoScriptConfiguration['properties'];
-
-               $contextMenuItems = $this->getNextContextMenuLevel(
-                       $contextMenuItemTypoScriptConfiguration,
-                       0
-               );
-               return $contextMenuItems;
-       }
-
-       /**
-        * Fetches the attributes for an action inside the context menu.
-        * @todo optimize to prevent much useless ajax calls...
-        *
-        * @param int $id page uid
-        * @param string $menuItemId clickmenu item identifier
-        */
-       public function getAttributesForContextMenu($id, $menuItemId) {
-               $this->decodeTreeNodeId($id);
-
-               switch ($menuItemId) {
-                       default:
-                               $attributes = array();
-                               break;
-               }
-
-               return $attributes;
-       }
-
-       /**
-        * Helper function to generate the neede css classes for img display with overlay
-        *
-        * @param string $icon icon identifier
-        */
-       protected function getIconClassFromIcon($icon) {
-               return array(
-                       //                      'hrefTarget' => $iconClass[0], // href target is used as a small hack for the template function of the menu.Item
-                       'iconCls' => $this->getSpriteIconClasses($icon)
-               );
-       }
-
-       /**
-        * Returns the page view link
-        *
-        * @param int $id page id
-        * @param unknown $workspacePreview ???
-        * @return string
-        */
-       public function getViewLink($id, $workspacePreview) {
-               $id = $this->decodeTreeNodeId($id);
-               return $this->pageTree->getViewLink($id, $workspacePreview);
-       }
-
-       /**
-        *
-        * @param string $id page id (can be numerical or like "mp-12" in case of mount-points ,...)
-        * @param string $title
-        * @param string $textSourceField
-        */
-       public function setPageTitle($id, $title, $textSourceField) {
-               $id = $this->decodeTreeNodeId($id);
-               $this->pageTree->updateTextInputField($id, $title, $textSourceField);
-       }
-
-       /**
-        * Enables or disables a page and returns the new node
-        *
-        * @param string $id page id (can be numerical or like "mp-12" in case of mount-points ,...)
-        * @param boolean $enabled true for enabling and false for disabling
-        * @return array new node
-        */
-       public function tooglePageVisibility($id, $enabled) {
-               $id = $this->decodeTreeNodeId($id);
-               $this->pageTree->updateTextInputField($id, $enabled, 'hidden');
-
-               $node = $this->getWholeRecordForIdAndPrepareItForResultList($id);
-               return $node;
-       }
-
-       /**
-        * Returns the localized list of doktypes to display
-        *
-        * see User TSconfig: options.pageTree.doktypesToShowInNewPageDragArea
-        */
-       public function getNodeTypes() {
-               $doktypes = t3lib_div::trimExplode(
-                       ',',
-                       $this->pageTree->getTsConfigOptionForPagetree('doktypesToShowInNewPageDragArea')
-               );
-
-               $output = array();
-               foreach ($doktypes as $doktype) {
-                       $label = $this->getLabel('LLL:EXT:pagetree/locallang_pagetree.xml:page.doktype.' . $doktype);
-                       $output[] = array(
-                               'nodeType' => $doktype,
-                               'title' => $label,
-                               'cls' => 'topPanel-button ' . $this->getSpriteIconClasses(
-                                       $GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][$doktype]
-                               ),
-                       );
-               }
-               return $output;
-       }
-
-       /**
-        * Returns the language shortcut from a language file
-        *
-        * @param string $file language flag with or without the related directory
-        * @return mixed language shortcut or boolean false
-        */
-       protected function getLanguageShortcutFromFile($file) {
-               if (strpos($file, '/') !== FALSE) {
-                       $file = basename($file);
-               }
-
-               return substr($file, 0, strrpos($file, '.'));
-       }
-
-       /**
-        * Returns a language record defined by the id parameter
-        *
-        * @param int $uid language id
-        * @return array
-        */
-       protected function getLanguage($uid) {
-               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
-                       'flag',
-                       'sys_language',
-                               'pid=0 AND uid=' . $uid .
-                                               t3lib_BEfunc::deleteClause('sys_language')
-               );
-
-               $record = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
-               $GLOBALS['TYPO3_DB']->sql_free_result($res);
-
-               return $record;
-       }
-
-       /**
-        * Returns an array of system languages with parameters based on the properties
-        * of Ext.Button.
-        *
-        * @return array
-        */
-       public function getLanguages() {
-               $languageRecords = t3lib_befunc::getSystemLanguages();
-
-               $output = array();
-               foreach ($languageRecords as $languageRecord) {
-                       $languageShortcut = $this->getLanguageShortcutFromFile($languageRecord[2]);
-                       if ($languageShortcut === FALSE) {
-                               $languageShortcut = 'europeanunion';
-                       }
-
-                       $output[] = array(
-                               'language' => $languageRecord[1],
-                               'languageShortcut' => $languageShortcut,
-                               'cls' => 'topPanel-button ' .
-                                               $this->getSpriteIconClasses('flags-' . $languageShortcut),
-                       );
-               }
-
-               return $output;
-       }
-
-       /**
-        * Returns the european flag sprite icon css classes
-        *
-        * @TODO What if a flag is added to the core, but isn't inside the sprite?
-        * @return string
-        */
-       public function getIconForCurrentLanguage() {
-               $currentTreeLanguage = intval($GLOBALS['BE_USER']->uc['currentPageTreeLanguage']);
-
-               $icon = 'flags-europeanunion';
-               if ($currentTreeLanguage !== 0) {
-                       $languageRecord = $this->getLanguage($currentTreeLanguage);
-                       $icon = 'flags-' . $this->getLanguageShortcutFromFile($languageRecord['flag']);
-               }
-
-               return $this->getSpriteIconClasses($icon);
-       }
-
-       /**
-        * Saves the given language id into the backend user configuration array
-        *
-        * @param int $languageId
-        * @return void
-        */
-       public function saveCurrentTreeLanguage($languageId) {
-               $GLOBALS['BE_USER']->backendSetUC();
-               $GLOBALS['BE_USER']->uc['currentPageTreeLanguage'] = intval($languageId);
-               $GLOBALS['BE_USER']->writeUC();
-       }
-}
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.t3lib_tree_dataprovider_pagetree.php']) {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.t3lib_tree_dataprovider_pagetree.php']);
-}
-
-?>
index 4033063..52b5f4e 100644 (file)
@@ -14,6 +14,7 @@
                        <label index="page.doktype.7">Mountpoint</label>
                        <label index="page.doktype.199">Spacer</label>
                        <label index="page.doktype.254">Sysfolder</label>
+                       <label index="defaultTitle">[Default Title]</label>
                </languageKey>
        </data>
 </T3locallang>