Merged new PageTree (version for TYPO3 4.5 Beta 3)
authorSteffen Kamper <info@sk-typo3.de>
Wed, 22 Dec 2010 01:15:40 +0000 (01:15 +0000)
committerSteffen Kamper <info@sk-typo3.de>
Wed, 22 Dec 2010 01:15:40 +0000 (01:15 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@9874 709f56b5-9817-0410-a4d7-c38de5d9e867

20 files changed:
ChangeLog
typo3/sysext/pagetree/classes/class.tx_pagetree_commands.php
typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php
typo3/sysext/pagetree/classes/class.tx_pagetree_node.php
typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php
typo3/sysext/pagetree/classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php
typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php
typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php
typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php
typo3/sysext/pagetree/components/pagetree/css/pagetree.css
typo3/sysext/pagetree/components/pagetree/javascript/actions.js
typo3/sysext/pagetree/components/pagetree/javascript/contextmenu.js
typo3/sysext/pagetree/components/pagetree/javascript/deletiondropzone.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/locallang_contextmenu.xml
typo3/sysext/pagetree/locallang_pagetree.xml

index e35c023..469148c 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,8 @@
 
 2010-12-21  Steffen Kamper  <steffen@typo3.org>
 
+       * Merged new PageTree (version for TYPO3 4.5 Beta 3)
+       * Fixed bug #16804: Bug/Prerequisite for the new pagetree: refresh pageTree with updateSignal, use new shortcuts in JS (Thanks to Stefan Galinski)
        * Fixed bug #16803: Bug/Prerequisite for the new pagetree: Extend getRecordWSOL with possibility to unset workspace move pointers (Thanks to Susanne Moog)
        * Fixed bug #16802: iFramePanel needs function to detect id in URL
 
@@ -27,7 +29,6 @@
 
 2010-12-19  Steffen Gebert  <steffen@steffen-gebert.de>
 
-       * Follow-up to #16804: Bug/Prerequisite for the new pagetree: refresh pageTree with updateSignal, use new shortcuts in JS (Thanks to Stefan Galinski)
        * Follow-up to #16779: t3lib_cache_backend_RedisBackendTest causes t3lib_db_PreparedStatementTest tests to fail (Thanks to Oliver Klee)
        * Fixed bug #16777: Test failure in t3lib_extmgmTest if tests are located in typo3_src/tests/ instead of tests/ (Thanks to Oliver Klee)
        * Fixed bug #16790: Typo in topbar CSS
index ebd95de..a5ea371 100644 (file)
@@ -40,7 +40,7 @@ final class tx_pagetree_Commands {
         * @return void
         */
        public static function visiblyNode(tx_pagetree_Node $node) {
-               $data['pages'][$node->getId()]['hidden'] = 0;
+               $data['pages'][$node->getWorkspaceId()]['hidden'] = 0;
                self::processTceCmdAndDataMap(array(), $data);
        }
 
@@ -51,7 +51,7 @@ final class tx_pagetree_Commands {
         * @return void
         */
        public static function disableNode(tx_pagetree_Node $node) {
-               $data['pages'][$node->getId()]['hidden'] = 1;
+               $data['pages'][$node->getWorkspaceId()]['hidden'] = 1;
                self::processTceCmdAndDataMap(array(), $data);
        }
 
@@ -70,11 +70,16 @@ final class tx_pagetree_Commands {
         * Restore the page
         *
         * @param tx_pagetree_Node $nodeData
+        * @param int $targetId
         * @return void
         */
-       public static function restoreNode(tx_pagetree_Node $node) {
+       public static function restoreNode(tx_pagetree_Node $node, $targetId) {
                $cmd['pages'][$node->getId()]['undelete'] = 1;
                self::processTceCmdAndDataMap($cmd);
+
+               if ($node->getId() !== $targetId) {
+                       self::moveNode($node, $targetId);
+               }
        }
 
        /**
@@ -85,8 +90,7 @@ final class tx_pagetree_Commands {
         * @return void
         */
        public static function updateNodeLabel(tx_pagetree_Node $node, $updatedLabel) {
-               $updatedLabel = str_replace($node->getPrefix(), '', $updatedLabel);
-               $data['pages'][$node->getId()][$node->getTextSourceField()] = $updatedLabel;
+               $data['pages'][$node->getWorkspaceId()][$node->getTextSourceField()] = $updatedLabel;
                self::processTceCmdAndDataMap(array(), $data);
        }
 
@@ -131,14 +135,14 @@ final class tx_pagetree_Commands {
        public static function createNode(tx_pagetree_Node $parentNode, $targetId, $pageType) {
                $placeholder = 'NEW12345';
                $data['pages'][$placeholder] = array(
-                       'pid' => $parentNode->getId(),
+                       'pid' => $parentNode->getWorkspaceId(),
                        '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) {
+               if ($parentNode->getWorkspaceId() !== $targetId) {
                        self::moveNode($node, $targetId);
                }
 
@@ -166,6 +170,7 @@ final class tx_pagetree_Commands {
                $tce = t3lib_div::makeInstance('t3lib_TCEmain');
                $tce->stripslashes_values = 0;
                $tce->start($data, $cmd);
+               $tce->copyTree = t3lib_div::intInRange($GLOBALS['BE_USER']->uc['copyLevels'], 0, 100);
 
                if (count($cmd)) {
                        $tce->process_cmdmap();
@@ -187,21 +192,80 @@ final class tx_pagetree_Commands {
         * Returns a node from the given node id
         *
         * @param int $nodeId
+        * @param boolean $unsetMovePointers
         * @return tx_pagetree_Node
         */
-       public static function getNode($nodeId) {
-               $record = self::getNodeRecord($nodeId);
+       public static function getNode($nodeId, $unsetMovePointers = TRUE) {
+               $record = self::getNodeRecord($nodeId, $unsetMovePointers);
                return self::getNewNode($record);
        }
 
        /**
+        * Returns the mount point path
+        *
+        * @static
+        * @return void
+        */
+       public static function getMountPointPath() {
+               $temporaryMountPoint = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']);
+               if (!$temporaryMountPoint) {
+                       return '';
+               }
+
+               $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+               $rootline = array_reverse(t3lib_BEfunc::BEgetRootLine($temporaryMountPoint));
+               array_shift($rootline);
+
+               $path = array();
+               foreach ($rootline as $rootlineElement) {
+                       $record = tx_pagetree_Commands::getNodeRecord($rootlineElement['uid']);
+
+                       $text = $record['title'];
+                       if ($useNavTitle && trim($record['nav_title']) !== '') {
+                               $text = $record['nav_title'];
+                       }
+
+                       $path[] = $text;
+               }
+
+               return '/' . implode('/', $path);
+       }
+
+       /**
         * Returns a node record from a given id
         *
         * @param int $nodeId
+        * @param boolean $unsetMovePointers
         * @return array
         */
-       public static function getNodeRecord($nodeId) {
-               return t3lib_BEfunc::getRecordWSOL('pages', $nodeId, '*', '', TRUE);
+       public static function getNodeRecord($nodeId, $unsetMovePointers = TRUE) {
+               $record = t3lib_BEfunc::getRecordWSOL('pages', $nodeId, '*', '', TRUE, $unsetMovePointers);
+               return $record;
+       }
+
+       /**
+        * Returns the first configured domain name for a page
+        *
+        * @static
+        * @param integer $uid
+        * @return string
+        */
+       public static function getDomainName($uid) {
+               $whereClause = $GLOBALS['TYPO3_DB']->quoteStr(
+                       'pid=' . intval($uid) . t3lib_BEfunc::deleteClause('sys_domain') .
+                               t3lib_BEfunc::BEenableFields('sys_domain'),
+                       'sys_domain'
+               );
+
+               $domain = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
+                       'domainName',
+                       'sys_domain',
+                       $whereClause,
+                       '',
+                       'sorting'
+               );
+
+               return htmlspecialchars($domain['domainName']);
        }
 
        /**
@@ -210,15 +274,21 @@ final class tx_pagetree_Commands {
         * @param array $record
         * @return tx_pagetree_Node
         */
-       public static function getNewNode($record) {
+       public static function getNewNode($record, $mountPoint = 0) {
                $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
                $addIdAsPrefix = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
+               $addDomainName = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showDomainNameWithTitle');
 
                /** @var $subNode tx_pagetree_Node */
                $subNode = t3lib_div::makeInstance('tx_pagetree_Node');
                $subNode->setRecord($record);
-               $subNode->setId($record['uid']);
+               $subNode->setCls($record['_CSSCLASS']);
                $subNode->setQTip('ID: ' . $record['uid']);
+               $subNode->setType('pages');
+
+               $subNode->setId($record['uid']);
+               $subNode->setMountPoint($mountPoint);
+               $subNode->setWorkspaceId(($record['_ORIG_uid'] ? $record['_ORIG_uid'] : $record['uid']));
 
                $field = 'title';
                $text = $record['title'];
@@ -227,8 +297,15 @@ final class tx_pagetree_Commands {
                        $text = $record['nav_title'];
                }
 
+               $suffix = '';
+               if ($addDomainName) {
+                       $domain = self::getDomainName($record['uid']);
+                       $suffix = ($domain !== '' ? ' [' . $domain . ']' : '');
+               }
+
                $prefix = ($addIdAsPrefix ? '[' . $record['uid'] . '] ' : '');
-               $subNode->setText($text, $field, $prefix);
+               $subNode->setText($text, $field, $prefix, $suffix);
+               $subNode->setEditableText($text);
 
                if ($record['uid'] !== 0) {
                        $spriteIconCode = t3lib_iconWorks::getSpriteIconForRecord('pages', $record);
@@ -237,6 +314,14 @@ final class tx_pagetree_Commands {
                }
                $subNode->setSpriteIconCode($spriteIconCode);
 
+               if (!$subNode->canCreateNewPages() || intval($record['t3ver_state']) === 2) {
+                       $subNode->setIsDropTarget(FALSE);
+               }
+
+               if (!$subNode->canBeEdited() || !$subNode->canBeRemoved() || intval($record['t3ver_state']) === 2) {
+                       $subNode->setDraggable(FALSE);
+               }
+
                return $subNode;
        }
 }
index 9ee93eb..ae06c14 100644 (file)
  */
 class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
        /**
-        * Returns the root node
+        * Node limit that should be loaded for this request per mount
+        *
+        * @var int
+        */
+       protected $nodeLimit = 500;
+
+       /**
+        * Current amount of nodes
         *
-        * Not used for the page tree, because the multiple domains/roots feature
+        * @var int
+        */
+       protected $nodeCounter = 0;
+
+       /**
+        * Returns the root node
         *
         * @return t3lib_tree_Node
         */
        public function getRoot() {
-               return NULL;
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node');
+               $node->setId('root');
+               $node->setExpanded(true);
+
+               return $node;
        }
 
        /**
         * Fetches the sub-nodes of the given node
         *
         * @param t3lib_tree_Node $node
+        * @param int $mountPoint
+        * @param int $level internally used variable as a recursion limiter
         * @return t3lib_tree_NodeCollection
         */
-        public function getNodes(t3lib_tree_Node $node) {
+        public function getNodes(t3lib_tree_Node $node, $mountPoint = 0, $level = 0) {
                /** @var $nodeCollection tx_pagetree_NodeCollection */
                $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+               if ($level >= 99) {
+                       return $nodeCollection;
+               }
 
                $subpages = $this->getSubpages($node->getId());
                if (!is_array($subpages) || !count($subpages)) {
@@ -60,11 +82,19 @@ class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
                }
 
                foreach ($subpages as $subpage) {
-                       $subpage = t3lib_befunc::getRecordWSOL('pages', $subpage['uid'], '*', '', TRUE);
+                       $subpage = t3lib_befunc::getRecordWSOL('pages', $subpage['uid'], '*', '', TRUE, TRUE);
+                       if (!$subpage) {
+                               continue;
+                       }
 
-                       $subNode = tx_pagetree_Commands::getNewNode($subpage);
-                       $childNodes = $this->getNodes($subNode);
-                       $subNode->setChildNodes($childNodes);
+                       $subNode = tx_pagetree_Commands::getNewNode($subpage, $mountPoint);
+                       if ($this->nodeCounter < $this->nodeLimit) {
+                               $childNodes = $this->getNodes($subNode, $mountPoint, $level + 1);
+                               $subNode->setChildNodes($childNodes);
+                               $this->nodeCounter += $childNodes->count();
+                       } else {
+                               $subNode->setLeaf(!$this->hasNodeSubPages($subNode->getId()));
+                       }
 
                        $nodeCollection->append($subNode);
                }
@@ -75,10 +105,14 @@ class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
        /**
         * Returns a node collection of filtered nodes
         *
+        * @param int $nodeId
         * @param string $searchFilter
+        * @param int $mountPoint
         * @return void
         */
-       public function getFilteredNodes($searchFilter) {
+       public function getFilteredNodes($nodeId, $searchFilter, $mountPoint = 0) {
+               $nodeId = intval($nodeId);
+               
                /** @var $nodeCollection tx_pagetree_NodeCollection */
                $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
 
@@ -92,10 +126,23 @@ class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
                        array_shift($rootline);
                        $reference = $nodeCollection;
 
+                       $inFilteredRootline = FALSE;
                        foreach ($rootline as $rootlineElement) {
+                               if (intval($rootlineElement['pid']) === $nodeId) {
+                                       $inFilteredRootline = TRUE;
+                               }
+
+                               if (!$inFilteredRootline) {
+                                       continue;
+                               }
+
+                               $rootlineElement = tx_pagetree_Commands::getNodeRecord($rootlineElement['uid']);
                                if ($reference->offsetExists($rootlineElement['uid'])) {
                                        /** @var $node tx_pagetree_Node */
                                        $node = $reference->offsetGet($rootlineElement['uid']);
+                                       $node->setExpanded(TRUE);
+                                       $node->setLeaf(FALSE);
+
                                        $reference = $node->getChildNodes();
                                        continue;
                                }
@@ -103,15 +150,15 @@ class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
                                /** @var $childCollection tx_pagetree_NodeCollection */
                                $childCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
 
-                               $node = tx_pagetree_Commands::getNewNode($rootlineElement);
-                               $node->setExpanded(TRUE);
+                               $node = tx_pagetree_Commands::getNewNode($rootlineElement, $mountPoint);
                                $node->setChildNodes($childCollection);
-                               $node->setLeaf(FALSE);
-                               $node->setText(str_replace(
-                                       $searchFilter,
-                                       '<strong class="pagetree-highlight">' . $searchFilter . '</strong>',
+
+                               $text = preg_replace(
+                                       '/(' . $searchFilter . ')/i',
+                                       '<span class="typo3-pagetree-filteringTree-highlight">$1</span>',
                                        $node->getText()
-                               ));
+                               );
+                               $node->setText($text, $node->getTextSourceField(), $node->getPrefix());
 
                                $reference->offsetSet($rootlineElement['uid'], $node);
                                $reference = $childCollection;
@@ -124,17 +171,30 @@ class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
        /**
         * Returns the page tree mounts for the current user
         *
+        * Note: If you add the search filter parameter, the nodes will be filtered by this string.
+        *
+        * @param string $searchFilter
         * @return array
         */
-       public function getTreeMounts() {
+       public function getTreeMounts($searchFilter = '') {
                /** @var $nodeCollection tx_pagetree_NodeCollection */
                $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
 
-               $webmountIds = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
-               if (empty($webmountIds)) {
+               $isTemporaryMountPoint = FALSE;
+               $webmountIds = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']);
+               if (!$webmountIds) {
+                       $webmountIds = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
+                       $webmountIds = array_unique($webmountIds);
+               } else {
+                       $isTemporaryMountPoint = TRUE;
+                       $webmountIds = array($webmountIds);
+               }
+
+               if (!count($webmountIds)) {
                        return $nodeCollection;
                }
 
+               $class = (count($webmountIds) <= 1 ? 'typo3-pagetree-node-notExpandable' : '');
                foreach ($webmountIds as $webmount) {
                        if ($webmount === 0) {
                                $sitename = 'TYPO3';
@@ -147,16 +207,33 @@ class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
                                        'title' => $sitename,
                                );
                                $subNode = tx_pagetree_Commands::getNewNode($record);
-                               $subNode->setEditableLable(FALSE);
-                               $subNode->setType('root');
+                               $subNode->setLabelIsEditable(FALSE);
                        } else {
                                $record = t3lib_BEfunc::getRecordWSOL('pages', $webmount, '*', '', TRUE);
-                               $subNode = tx_pagetree_Commands::getNewNode($record);
+                               if (!$record) {
+                                       continue;
+                               }
+
+                               $subNode = tx_pagetree_Commands::getNewNode($record, $webmount);
                        }
 
-                       $childNodes = $this->getNodes($subNode);
-                       $subNode->setChildNodes($childNodes);
+                       if ($webmount === 0 || $isTemporaryMountPoint) {
+                               $subNode->setType('pages_root');
+                       }
+
+                       $subNode->setExpanded(TRUE);
+                       $subNode->setDraggable(FALSE);
+                       $subNode->setIsDropTarget(FALSE);
+                       $subNode->setCls($class);
+
+                       if ($searchFilter === '') {
+                               $childNodes = $this->getNodes($subNode, $webmount);
+                       } else {
+                               $childNodes = $this->getFilteredNodes(intval($record['uid']), $searchFilter, $webmount);
+                               $subNode->setExpanded(TRUE);
+                       }
 
+                       $subNode->setChildNodes($childNodes);
                        $nodeCollection->append($subNode);
                }
 
@@ -164,35 +241,75 @@ class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
        }
 
        /**
-        * Returns all sub-pages of a given id
+        * Returns the where clause for fetching pages
         *
         * @param int $id
         * @param string $searchFilter
-        * @return array
+        * @return string
         */
-       protected function getSubpages($id, $searchFilter = '') {
-               $where = $GLOBALS['BE_USER']->getPagePermsClause(1)
-                       . t3lib_BEfunc::deleteClause('pages')
-                       t3lib_BEfunc::versioningPlaceholderClause('pages');
+       protected function getWhereClause($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');
+                       $searchFilter = $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchFilter . '%', 'pages');
+                       $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+
+                       if ($useNavTitle) {
+                               $where .= ' AND (nav_title LIKE ' . $searchFilter .
+                                       ' OR (nav_title = "" && title LIKE ' . $searchFilter . '))';
+                       } else {
+                               $where .= ' AND title LIKE ' . $searchFilter;
+                       }
                }
 
+               return $where;
+       }
+
+       /**
+        * Returns all sub-pages of a given id
+        *
+        * @param int $id
+        * @param string $searchFilter
+        * @return array
+        */
+       protected function getSubpages($id, $searchFilter = '') {
+               $where = $this->getWhereClause($id, $searchFilter);
                $subpages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
                        'uid', 'pages', $where, '', 'sorting', '', 'uid'
                );
 
                return $subpages;
        }
+
+       /**
+        * Returns true if the node has child's
+        *
+        * @param int $id
+        * @return bool
+        */
+       protected function hasNodeSubPages($id) {
+               $where = $this->getWhereClause($id);
+               $subpage = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
+                       'uid', 'pages', $where, '', 'sorting', '', 'uid'
+               );
+
+               $returnValue = TRUE;
+               if (!$subpage['uid']) {
+                       $returnValue = FALSE;
+               }
+
+               return $returnValue;
+       }
 }
 
-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']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php']);
 }
 
 ?>
\ No newline at end of file
index f9d85ee..e34c865 100644 (file)
  * @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();
-
+class tx_pagetree_Node extends t3lib_tree_ExtDirect_Node {
        /**
         * Cached access rights to save some performance
         *
@@ -139,293 +41,55 @@ class tx_pagetree_Node extends t3lib_tree_Node {
        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
+        * Workspace Overlay Id
         *
-        * @return string
+        * @var int
         */
-       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;
-       }
+       protected $workspaceId = 0;
 
        /**
-        * Returns the callback action
+        * Mount Point Id
         *
-        * @return string
+        * @var int
         */
-       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;
-       }
+       protected $mountPoint = 0;
 
        /**
-        * Sets the database record array
+        * Set's the original id of the element
         *
-        * @param array $record
+        * @param int $workspaceId
         * @return void
         */
-       public function setRecord($record) {
-               $this->record = $record;
+       public function setWorkspaceId($workspaceId) {
+               $this->workspaceId = intval($workspaceId);
        }
 
        /**
-        * Returns the database record array
+        * Returns the original id of the element
         *
-        * @return array
+        * @return int
         */
-       public function getRecord() {
-               return $this->record;
+       public function getWorkspaceId() {
+               return $this->workspaceId;
        }
 
        /**
-        * Sets the context info
+        * Sets the mount point id
         *
-        * @param array $contextInfo
+        * @param int $mountPoint
         * @return void
         */
-       public function setContextInfo($contextInfo) {
-               $this->contextInfo = $contextInfo;
-       }
-
-       /**
-        * Returns the context info
-        *
-        * @return array
-        */
-       public function getContextInfo() {
-               return (array) $this->contextInfo;
+       public function setMountPoint($mountPoint) {
+               $this->mountPoint = $mountPoint;
        }
 
        /**
-        * Sets the child nodes collection
+        * Returns the mount point id
         *
-        * @param t3lib_tree_NodeCollection $childNodes
-        * @return void
+        * @return int
         */
-       public function setChildNodes(t3lib_tree_NodeCollection $childNodes) {
-               parent::setChildNodes($childNodes);
-
-               if ($childNodes->count()) {
-                       $this->setLeaf(FALSE);                  
-               }
+       public function getMountPoint() {
+               return $this->mountPoint;
        }
 
        /**
@@ -489,7 +153,7 @@ class tx_pagetree_Node extends t3lib_tree_Node {
         * @return void
         */
        public function canBeCut() {
-               return $this->canEdit($this->record);
+               return $this->canEdit($this->record) && intval($this->record['t3ver_state']) !== 2;
        }
 
        /**
@@ -507,7 +171,7 @@ class tx_pagetree_Node extends t3lib_tree_Node {
         * @return void
         */
        public function canBeCopied() {
-               return $this->canCreate($this->record);
+               return $this->canCreate($this->record) && intval($this->record['t3ver_state']) !== 2;
        }
 
        /**
@@ -525,7 +189,25 @@ class tx_pagetree_Node extends t3lib_tree_Node {
         * @return void
         */
        public function canBeRemoved() {
-               return $this->canRemove($this->record);
+               return $this->canRemove($this->record) && intval($this->record['t3ver_state']) !== 2;
+       }
+
+       /**
+        * Checks if something can be pasted into the node
+        *
+        * @return bool
+        */
+       public function canBePastedInto() {
+               return intval($this->record['t3ver_state']) !== 2;
+       }
+
+       /**
+        * Checks if something can be pasted after the node
+        *
+        * @return bool
+        */
+       public function canBePastedAfter() {
+               return intval($this->record['t3ver_state']) !== 2;
        }
 
        /**
@@ -570,31 +252,14 @@ class tx_pagetree_Node extends t3lib_tree_Node {
         * @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();
-               }
+               $arrayRepresentation = parent::toArray();
+
+               $arrayRepresentation['id'] = 'mp-' . $this->getMountPoint() . '-' . $this->getId();
+               $arrayRepresentation['realId'] = $this->getId();
+               $arrayRepresentation['nodeData']['id'] = $this->getId();
+               $arrayRepresentation['nodeData']['mountPoint'] = $this->getMountPoint();
+               $arrayRepresentation['nodeData']['workspaceId'] = $this->getWorkspaceId();
+               $arrayRepresentation['nodeData']['serializeClassName'] = get_class($this);
 
                return $arrayRepresentation;
        }
@@ -607,24 +272,13 @@ class tx_pagetree_Node extends t3lib_tree_Node {
         */
        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']);
+               $this->setWorkspaceId($data['workspaceId']);
+               $this->setMountPoint($data['mountPoint']);
        }
 }
 
-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']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_node.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_node.php']);
 }
 
 ?>
\ No newline at end of file
index 0915190..70097bc 100644 (file)
@@ -45,8 +45,8 @@ class tx_pagetree_NodeCollection extends t3lib_tree_NodeCollection {
        }
 }
 
-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']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php']);
 }
 
 ?>
\ No newline at end of file
index 145a1ff..2303c9e 100644 (file)
@@ -25,6 +25,8 @@
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+// @TODO the most functionality should be moved to the parent data provider class
+
 /**
  * Context Menu Data Provider for the Page Tree
  *
  */
 class tx_pagetree_ContextMenu_DataProvider extends t3lib_contextmenu_AbstractDataProvider {
        /**
+        * List of actions that are generally disabled
+        *
+        * @var array
+        */
+       protected $disableItems = array();
+
+       /**
         * Old Context Menu Options (access mapping)
         *
+        * Note: Only option with different namings are mapped!
+        *
         * @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',
+       protected $legacyContextMenuMapping = array(
+               'hide' => 'disable',
+               'paste' => 'pasteInto,pasteAfter',
+               'mount_as_treeroot' => 'mountAsTreeroot',
        );
 
        /**
+        * Fetches the items that should be disabled from the context menu
+        *
+        * @return array
+        */
+       protected function getDisableActions() {
+               $tsConfig = $GLOBALS['BE_USER']->getTSConfig(
+                       'options.contextMenu.' . $this->getContextMenuType() . '.disableItems'
+               );
+
+               $disableItems = array();
+               if (trim($tsConfig['value']) !== '') {
+                       $disableItems = t3lib_div::trimExplode(',', $tsConfig['value']);
+               }
+
+               $tsConfig = $GLOBALS['BE_USER']->getTSConfig('options.contextMenu.pageTree.disableItems');
+               $oldDisableItems = array();
+               if (trim($tsConfig['value']) !== '') {
+                       $oldDisableItems = t3lib_div::trimExplode(',', $tsConfig['value']);
+               }
+
+               $additionalItems = array();
+               foreach ($oldDisableItems as $item) {
+                       if (!isset($this->legacyContextMenuMapping[$item])) {
+                               $additionalItems[] = $item;
+                               continue;
+                       }
+
+                       if (strpos($this->legacyContextMenuMapping[$item], ',')) {
+                               $actions = t3lib_div::trimExplode(',', $this->legacyContextMenuMapping[$item]);
+                               $additionalItems = array_merge($additionalItems, $actions);
+                       } else {
+                               $additionalItems[] = $item;
+                       }
+               }
+
+               return array_merge($disableItems, $additionalItems);
+       }
+
+       /**
         * 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);
+               $this->disableItems = $this->getDisableActions();
+               $configuration = $this->getConfiguration();
+               $contextMenuActions = array();
+               if (is_array($configuration)) {
+                       $contextMenuActions = $this->getNextContextMenuLevel($configuration, $node);
+               }
 
                return $contextMenuActions;
        }
@@ -177,9 +221,11 @@ class tx_pagetree_ContextMenu_DataProvider extends t3lib_contextmenu_AbstractDat
                        if ($type === 'DIVIDER') {
                                $action->setType('divider');
                        } else {
-                               if (isset($actionConfiguration['displayCondition'])
-                                       && trim($actionConfiguration['displayCondition']) !== ''
-                                       && !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])
+                               if (in_array($actionConfiguration['name'], $this->disableItems)
+                                       || (isset($actionConfiguration['displayCondition'])
+                                               && trim($actionConfiguration['displayCondition']) !== ''
+                                               && !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])
+                                       )
                                ) {
                                        unset($action);
                                        continue;
@@ -207,7 +253,8 @@ class tx_pagetree_ContextMenu_DataProvider extends t3lib_contextmenu_AbstractDat
                                }
                        }
 
-                       $actionCollection->append($action);
+                       $actionCollection->offsetSet($level . intval($index), $action);
+                       $actionCollection->ksort();
                }
 
                return $actionCollection;
index f2d279e..3d48bc9 100644 (file)
@@ -43,6 +43,9 @@ class tx_pagetree_ExtDirect_Commands {
                /** @var $node tx_pagetree_Node */
                $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
 
+               /** @var $dataProvider tx_pagetree_DataProvider */
+               $dataProvider = t3lib_div::makeInstance('tx_pagetree_DataProvider');
+
                try {
                        tx_pagetree_Commands::visiblyNode($node);
                        $newNode = tx_pagetree_Commands::getNode($node->getId());
@@ -68,6 +71,9 @@ class tx_pagetree_ExtDirect_Commands {
                /** @var $node tx_pagetree_Node */
                $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
 
+               /** @var $dataProvider tx_pagetree_DataProvider */
+               $dataProvider = t3lib_div::makeInstance('tx_pagetree_DataProvider');
+
                try {
                        tx_pagetree_Commands::disableNode($node);
                        $newNode = tx_pagetree_Commands::getNode($node->getId());
@@ -95,7 +101,15 @@ class tx_pagetree_ExtDirect_Commands {
 
                try {
                        tx_pagetree_Commands::deleteNode($node);
+
                        $returnValue = array();
+                       if ($GLOBALS['BE_USER']->workspace) {
+                               $record = tx_pagetree_Commands::getNodeRecord($node->getId());
+                               if ($record['_ORIG_uid']) {
+                                       $newNode = tx_pagetree_Commands::getNewNode($record);
+                                       $returnValue = $newNode->toArray();
+                               }
+                       }
                } catch (Exception $exception) {
                        $returnValue = array(
                                 'success' => FALSE,
@@ -104,21 +118,21 @@ class tx_pagetree_ExtDirect_Commands {
                }
 
                return $returnValue;
-
        }
 
        /**
         * Restore the page
         *
         * @param stdClass $nodeData
+        * @param int $destination
         * @return array
         */
-       public function restoreNode($nodeData) {
+       public function restoreNode($nodeData, $destination) {
                /** @var $node tx_pagetree_Node */
                $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
 
                try {
-                       tx_pagetree_Commands::restoreNode($node);
+                       tx_pagetree_Commands::restoreNode($node, $destination);
                        $newNode = tx_pagetree_Commands::getNode($node->getId());
                        $returnValue = $newNode->toArray();
                } catch (Exception $exception) {
@@ -157,6 +171,21 @@ class tx_pagetree_ExtDirect_Commands {
        }
 
        /**
+        * Sets a temporary mount point
+        *
+        * @param stdClass $nodeData
+        * @return array
+        */
+       public static function setTemporaryMountPoint($nodeData) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+               $GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint'] = $node->getId();
+               $GLOBALS['BE_USER']->writeUC($GLOBALS['BE_USER']->uc);
+
+               return tx_pagetree_Commands::getMountPointPath();
+       }
+
+       /**
         * Moves the source node directly as the first child of the destination node
         *
         * @param stdClass $nodeData
@@ -169,7 +198,9 @@ class tx_pagetree_ExtDirect_Commands {
 
                try {
                        tx_pagetree_Commands::moveNode($node, $destination);
-                       $returnValue = array();
+                       $newNode = tx_pagetree_Commands::getNode($node->getId(), FALSE);
+                       $newNode->setLeaf($node->isLeafNode());
+                       $returnValue = $newNode->toArray();
                } catch (Exception $exception) {
                        $returnValue = array(
                                 'success' => FALSE,
@@ -193,7 +224,9 @@ class tx_pagetree_ExtDirect_Commands {
 
                try {
                        tx_pagetree_Commands::moveNode($node, -$destination);
-                       $returnValue = array();
+                       $newNode = tx_pagetree_Commands::getNode($node->getId(), FALSE);
+                       $newNode->setLeaf($node->isLeafNode());
+                       $returnValue = $newNode->toArray();
                } catch (Exception $exception) {
                        $returnValue = array(
                                 'success' => FALSE,
@@ -216,9 +249,14 @@ class tx_pagetree_ExtDirect_Commands {
                /** @var $node tx_pagetree_Node */
                $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
 
+               /** @var $dataProvider tx_pagetree_DataProvider */
+               $dataProvider = t3lib_div::makeInstance('tx_pagetree_DataProvider');
+
                try {
                        $newPageId = tx_pagetree_Commands::copyNode($node, $destination);
-                       $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+                       $newNode = tx_pagetree_Commands::getNode($newPageId);
+                       $newNode->setLeaf($node->isLeafNode());
+                       $returnValue = $newNode->toArray();
                } catch (Exception $exception) {
                        $returnValue = array(
                                 'success' => FALSE,
@@ -241,9 +279,14 @@ class tx_pagetree_ExtDirect_Commands {
                /** @var $node tx_pagetree_Node */
                $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
 
+               /** @var $dataProvider tx_pagetree_DataProvider */
+               $dataProvider = t3lib_div::makeInstance('tx_pagetree_DataProvider');
+
                try {
                        $newPageId = tx_pagetree_Commands::copyNode($node, -$destination);
-                       $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+                       $newNode = tx_pagetree_Commands::getNode($newPageId);
+                       $newNode->setLeaf($node->isLeafNode());
+                       $returnValue = $newNode->toArray();
                } catch (Exception $exception) {
                        $returnValue = array(
                                 'success' => FALSE,
@@ -307,74 +350,21 @@ class tx_pagetree_ExtDirect_Commands {
         * 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';
+       public static function getViewLink($nodeData) {
+               /** @var $node tx_pagetree_Node */
+               $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+               $javascriptLink = t3lib_BEfunc::viewOnClick($node->getId());
+               preg_match('/window\.open\(\'([^\']+)\'/i', $javascriptLink, $match);
+
+               return $match[1];
        }
 }
 
-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']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php']);
 }
 
 ?>
\ No newline at end of file
index 98c3f0f..3691712 100644 (file)
@@ -41,7 +41,6 @@ class tx_pagetree_ExtDirect_ContextMenu extends t3lib_contextmenu_extdirect_Cont
        protected function initDataProvider() {
                /** @var $dataProvider tx_pagetree_ContextMenu_DataProvider */
                $dataProvider = t3lib_div::makeInstance('tx_pagetree_ContextMenu_DataProvider');
-               $dataProvider->setContextMenuType('table.pages');
                $this->setDataProvider($dataProvider);
        }
 
@@ -57,15 +56,20 @@ class tx_pagetree_ExtDirect_ContextMenu extends t3lib_contextmenu_extdirect_Cont
                $node->setRecord(tx_pagetree_Commands::getNodeRecord($node->getId()));
 
                $this->initDataProvider();
+               $this->dataProvider->setContextMenuType('table.' . $node->getType());
                $actionCollection = $this->dataProvider->getActionsForNode($node);
 
-               return $actionCollection->toArray();
+               if ($actionCollection instanceof t3lib_contextmenu_ActionCollection) {
+                       $actions = $actionCollection->toArray();
+               }
+
+               return $actions;
        }
 }
 
 
-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']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php']);
 }
 
 ?>
\ No newline at end of file
index 170bb00..71f7394 100644 (file)
@@ -54,12 +54,13 @@ class tx_pagetree_ExtDirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree
        /**
         * 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();
+               $this->initDataProvider();
+               $node = $this->dataProvider->getRoot();
+
+               return $node->toArray();
        }
 
        /**
@@ -87,13 +88,21 @@ class tx_pagetree_ExtDirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree
        /**
         * Returns a tree that only contains elements that match the given search string
         *
+        * @param int $nodeId
         * @param string $searchFilter
         * @return array
         */
-       public function getFilteredTree($searchFilter) {
-               $this->initDataProvider();
+       public function getFilteredTree($nodeId, $searchFilter) {
+               if ($searchFilter === '') {
+                       return array();
+               }
 
-               $nodeCollection = $this->dataProvider->getFilteredNodes($searchFilter);
+               $this->initDataProvider();
+               if ($nodeId === 'root') {
+                       $nodeCollection = $this->dataProvider->getTreeMounts($searchFilter);
+               } else {
+                       $nodeCollection = $this->dataProvider->getFilteredNodes($nodeId, $searchFilter);
+               }
 
                return $nodeCollection->toArray();
        }
@@ -112,13 +121,22 @@ class tx_pagetree_ExtDirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree
                );
 
                $output = array();
+               $allowedDoktypes = t3lib_div::trimExplode(',', $GLOBALS['BE_USER']->groupData['pagetypes_select']);
+               $isAdmin = $GLOBALS['BE_USER']->isAdmin();
                foreach ($doktypes as $doktype) {
+                       if (!$isAdmin && !in_array($doktype, $allowedDoktypes)) {
+                               continue;
+                       }
+
                        $label = $GLOBALS['LANG']->sL('LLL:EXT:pagetree/locallang_pagetree.xml:page.doktype.' . $doktype, TRUE);
-                       $spriteIcon = $this->getSpriteIconClasses($GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][$doktype]);
+                       $spriteIcon = t3lib_iconWorks::getSpriteIconClasses(
+                               $GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][$doktype]
+                       );
 
                        $output[] = array(
                                'nodeType' => $doktype,
-                               'cls' => 'topPanel-button ' . $spriteIcon,
+                               'cls' => 'typo3-pagetree-topPanel-button',
+                               'iconCls' => $spriteIcon,
                                'title' => $label,
                                'tooltip' => $label,
                        );
@@ -128,18 +146,65 @@ class tx_pagetree_ExtDirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree
        }
 
        /**
-        * Returns the sprite icon classes for a given icon
+        * Returns
         *
-        * @param string $icon
         * @return string
         */
-       public function getSpriteIconClasses($icon) {
-               return t3lib_iconWorks::getSpriteIconClasses($icon);
+       public function getIndicators() {
+               /** @var $indicatorProvider tx_pagetree_Indicator */
+               $indicatorProvider = t3lib_div::makeInstance('tx_pagetree_indicator');
+               $indicatorHtml = implode(' ', $indicatorProvider->getAllIndicators());
+               return ($indicatorHtml ? $indicatorHtml : '');
+       }
+
+       /**
+        * Returns the language labels, sprites and configuration options for the pagetree
+        *
+        * @return void
+        */
+       public function loadResources() {
+               $file = 'LLL:EXT:pagetree/locallang_pagetree.xml:';
+               $configuration = array(
+                       'LLL' => array(
+                               'copyHint' => $GLOBALS['LANG']->sL($file . 'copyHint', TRUE),
+                               'fakeNodeHint' => $GLOBALS['LANG']->sL($file . 'fakeNodeHint', TRUE),
+                               'activeFilterMode' => $GLOBALS['LANG']->sL($file . 'activeFilterMode', TRUE),
+                               'dropToRemove' => $GLOBALS['LANG']->sL($file . 'dropToRemove', TRUE),
+                               'dropZoneElementRemoved' => $GLOBALS['LANG']->sL($file . 'dropZoneElementRemoved', TRUE),
+                               'dropZoneElementRestored' => $GLOBALS['LANG']->sL($file . 'dropZoneElementRestored', TRUE),
+                               'treeStructure' => $GLOBALS['LANG']->sL($file . 'treeStructure', TRUE),
+                               'temporaryMountPointIndicatorInfo' => $GLOBALS['LANG']->sl(
+                                       'LLL:EXT:lang/locallang_core.xml:labels.temporaryDBmount',
+                                       TRUE
+                               ),
+                       ),
+
+                       'Configuration' => array(
+                               'hideFilter' => $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.hideFilter'),
+                               'disableIconLinkToContextmenu' => $GLOBALS['BE_USER']->getTSConfigVal(
+                                       'options.pageTree.disableIconLinkToContextmenu'
+                               ),
+                               'indicator' => $this->getIndicators(),
+                               'temporaryMountPoint' => tx_pagetree_Commands::getMountPointPath(),
+                       ),
+
+                       'Sprites' => array(
+                               'Filter' => t3lib_iconWorks::getSpriteIconClasses('actions-system-tree-search-open'),
+                               'NewNode' => t3lib_iconWorks::getSpriteIconClasses('actions-page-new'),
+                               'Refresh' => t3lib_iconWorks::getSpriteIconClasses('actions-system-refresh'),
+                               'InputClear' => t3lib_iconWorks::getSpriteIconClasses('actions-input-clear'),
+                               'TrashCan' => t3lib_iconWorks::getSpriteIconClasses('actions-edit-delete'),
+                               'TrashCanRestore' => t3lib_iconWorks::getSpriteIconClasses('actions-edit-restore'),
+                               'Info' => t3lib_iconWorks::getSpriteIconClasses('actions-document-info'),
+                       )
+               );
+
+               return $configuration;
        }
 }
 
-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']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php']);
 }
 
 ?>
\ No newline at end of file
index 2f8f2ea..44bd0bc 100644 (file)
-
 #typo3-pagetree-treeContainer {
-       margin-bottom: 60px;
-       padding-bottom: 10px;
+       margin: 10px 0 45px 0;
        height: 100%;
 }
 
-#typo3-pagetree .topPanel-button {
+#typo3-pagetree-tree .x-panel-body,
+#typo3-pagetree-filteringTree .x-panel-body {
+       overflow-y: hidden !important;
+}
+
+#typo3-pagetree-indicatorBar {
+       padding: 49px 0 0 0;
+       min-height: 10px;
+}
+
+.typo3-pagetree-indicatorBar-item p {
+       padding: 5px 10px;
+       line-height: 25px;
+}
+
+#typo3-pagetree-indicatorBar-filter p,
+#typo3-pagetree-indicatorBar-temporaryMountPoint p {
+       padding: 10px 35px;
+}
+
+#typo3-pagetree-indicatorBar-temporaryMountPoint p {
+       line-height: 13px;
+}
+
+#typo3-pagetree-indicatorBar-temporaryMountPoint,
+#typo3-pagetree-indicatorBar-filter {
+       background-color: #EAF7FF;
+       border-bottom: 1px solid #C5DBE6;
+       color: #4C73A1;
+}
+
+.typo3-pagetree-indicatorBar-item .typo3-pagetree-indicatorBar-item-leftIcon {
+       left: 10px;
+       top: 16px;
+       cursor: pointer;
+       position: absolute;
+}
+
+.typo3-pagetree-indicatorBar-item .typo3-pagetree-indicatorBar-item-rightIcon {
+       right: 10px;
+       top: 16px;
+       cursor: pointer;
+       position: absolute;
+}
+
+#typo3-pagetree-indicatorBar-indicatorTitle {
+       background-color: #ffec97;
+       font-weight: bold;
+}
+
+#typo3-pagetree-indicatorBar-indicatorTitle span {
+       margin-right: 10px;
+}
+
+#typo3-pagetree .x-panel-tbar {
+       padding: 0;
+       margin: 0;
+       background-color: #585858;
+       border: none;
+}
+
+#typo3-pagetree .x-toolbar,
+.typo3-pagetree-topPanel-item .x-toolbar {
+       padding-bottom: 0;
+       background: none;
+       border: none;
+}
+
+#typo3-pagetree-topPanel {
+       height: 60px;
+       position: fixed;
+       z-index: 20;
+}
+
+#typo3-pagetree-topPanel .x-toolbar-left {
+       height: 20px;
+}
+
+.typo3-pagetree-topPanel-button {
        margin: 0 5px 0 0;
-       display: inline-block;
+       padding: 1px 2px;
+       height: 18px;
+       background: none;
+       border: none;
+}
+
+#typo3-pagetree-topPanel .x-btn-pressed {
+       background-image: url('../icons/gfx/toolbar_item_active_bg.png');
+}
+
+.typo3-pagetree-topPanel-button button {
        height: 16px;
-       overflow: hidden;
-       position: relative;
        width: 16px;
+       border: none;
 }
 
-#typo3-pagetree #topPanel .x-btn,
-#typo3-pagetree #topPanel .x-btn-over {
-       background: none;
-       border: none;
+#typo3-pagetree .typo3-pagetree-topPanel-item {
+       background-color: #F0F0F0;
+       border-bottom: 2px solid #C9C9C9;
+}
+
+.typo3-pagetree-topPanel-item {
+       padding: 4px 3px 0 3px;
+       height: 23px;
+}
+
+#typo3-pagetree-topPanel-filter {
+       border: 1px solid #AEAEAE;
+       height: 16px;
+       width: 98% !important;
+       padding: 1px 0 1px 2px;
+       -moz-box-shadow: inset 0 1px 4px #AEAEAE;
+       -ms-box-shadow: inset 0 1px 4px #AEAEAE;
+       -webkit-box-shadow: inset 0 1px 4px #AEAEAE;
+       box-shadow: inset 0 2px 1px #AEAEAE;
+}
+
+#typo3-pagetree-topPanel-filterWrap .x-form-field-trigger-wrap {
+       width: 100% !important;
+       margin: 0 20px 0 0;
+}
+
+#typo3-pagetree-topPanel-filterWrap .t3-icon-input-clear {
+       right: 2%;
+}
+
+.typo3-pagetree-topPanel-item .x-form-trigger {
+       margin: 4px 0 0;
 }
 
 #typo3-pagetree .x-tree .x-panel-body {
        background: none;
 }
 
-/*#typo3-navigationContainer .x-panel-body {
-       -moz-box-shadow: inset -2px 0 1px #C4C4C4;
-       -ms-box-shadow: inset -2px 0 1px #C4C4C4;
-       -webkit-box-shadow: inset -2px 0 1px #C4C4C4;
-       box-shadow: inset -2px 0 1px #C4C4C4;
+#typo3-pagetree .typo3-pagetree-filteringTree-highlight {
+       background-color: #F48E0C;
+       color: #FFF;
+       padding: 0;
 }
 
-#typo3-pagetree #topPanel {
-       -moz-box-shadow: inset -2px 0 0 #414141;
-       -ms-box-shadow: inset -2px 0 0 #414141;
-       -webkit-box-shadow: inset -2px 0 0 #414141;
-       box-shadow: inset -2px 0 0 #414141;
-}*/
-
 #typo3-pagetree .x-tree-node .x-tree-node-el {
-       border-bottom: 1px solid transparent;
-       border-left: 1px solid transparent;
        border-top: 1px solid transparent;
+       border-bottom: 1px solid transparent;
        margin-right: 0;
 }
 
-#typo3-pagetree .x-tree-node .x-tree-node-over {
-       background-color: #F8F8F8;
-       margin-right: 4px;
-}
-
 #typo3-pagetree .x-tree-node .x-tree-node-over,
 #typo3-pagetree .x-tree-node .x-tree-selected {
        background-color: #F8F8F8;
        border-bottom: 1px solid #D7D7D7;
-       border-left: 1px solid #D7D7D7;
        border-top: 1px solid #D7D7D7;
 }
 
+.x-tree-lines .typo3-pagetree-node-notExpandable .x-tree-ec-icon {
+       visibility: hidden;
+}
+
+.x-tree-lines .typo3-pagetree-node-notExpandable ul .x-tree-ec-icon {
+       visibility: visible;
+}
+
+.x-tree-node-el {
+       height: 18px;
+       line-height: 18px;
+}
+
+.x-tree-lines .x-tree-elbow-end,
+.x-tree-lines .x-tree-elbow-end-minus,
+.x-tree-lines .x-tree-elbow-end-plus,
+.x-tree-lines .x-tree-elbow-line,
+.x-tree-lines .x-tree-elbow,
+.x-tree-lines .x-tree-elbow-plus,
+.x-tree-lines .x-tree-elbow-minus {
+       height: 20px;
+       background-repeat: repeat-y;
+       background-position: 0 1px;
+}
+
+.x-tree-lines .x-tree-elbow-minus {
+       background-image: url('../icons/gfx/ol/minus.gif');
+}
+
+.x-tree-lines .x-tree-elbow-plus {
+       background-image: url('../icons/gfx/ol/plus.gif');
+}
+
+.x-tree-lines .x-tree-elbow-end {
+       background: url('../icons/gfx/ol/joinbottom.gif') left top no-repeat;
+}
+
+.x-tree-lines .x-tree-elbow-end-minus {
+       background: url('../icons/gfx/ol/minusbottom.gif') left top no-repeat;
+}
+
+.x-tree-lines .x-tree-elbow-end-plus {
+       background: url('../icons/gfx/ol/plusbottom.gif') left top no-repeat;
+}
+
+.x-tree-lines .x-tree-elbow-line {
+       background-image: url('../icons/gfx/ol/line.gif');
+}
+
+.x-tree-lines .x-tree-elbow {
+       background-image: url('../icons/gfx/ol/join.gif');
+}
+
 #typo3-pagetree .x-tree-node .x-tree-drag-insert-above {
        border-top-color: #686868;
 }
        border-bottom-color: #686868;
 }
 
-#typo3-pagetree .x-panel-tbar {
-       padding: 0;
-       margin: 0;
+.x-tree-node a, .x-dd-drag-ghost a {
+       display: inline-block;
+       vertical-align: -1px;
+       font-size: 11px;
+}
+
+#typo3-pagetree-deletionDropZone {
+       position: fixed;
+       bottom: 0;
+       color: #FFF;
        background-color: #585858;
-       border: none;
+       -moz-box-shadow: inset 0 2px 5px #414141;
+       -ms-box-shadow: inset 0 2px 5px #414141;
+       -webkit-box-shadow: inset 0 2px 5px #414141;
+       box-shadow: inset 0 2px 5px #414141;
 }
 
-#typo3-pagetree .x-toolbar {
-       background: none;
+#typo3-pagetree-deletionDropZone p {
+       padding: 5px;
+       height: 25px;
+       line-height: 25px;
+}
+
+#typo3-pagetree-deletionDropZone-text {
+       padding: 0 0 0 5px;
+       font-size: .9em;
+}
+
+.typo3-pagetree-indicatorBar-item .x-panel-body,
+#typo3-pagetree-topPanel .typo3-pagetree-topPanel-item,
+#typo3-navigationContainer:first-child:first-child {
+       -moz-box-shadow: inset -2px 0 1px #C4C4C4;
+       -ms-box-shadow: inset -2px 0 1px #C4C4C4;
+       -webkit-box-shadow: inset -2px 0 1px #C4C4C4;
+       box-shadow: inset -2px 0 1px #C4C4C4;
+}
+
+#typo3-pagetree .x-panel-tbar,
+#typo3-pagetree-deletionDropZone .x-panel-body {
+       -moz-box-shadow: inset -2px 0 1px #414141;
+       -ms-box-shadow: inset -2px 0 1px #414141;
+       -webkit-box-shadow: inset -2px 0 1px #414141;
+       box-shadow: inset -2px 0 1px #414141;
+}
+
+#typo3-pagetree span.t3-icon {
+       margin-bottom: 2px;
+}
+
+#typo3-pagetree .typo3-pagetree-topPanel-button {
        border: none;
+       border-radius: 0;
+       margin-right: 1px;
+       margin-top: -2px;
+       padding: 2px 3px;
 }
 
-#typo3-pagetree .typo3-pagetree-topbar-item,
-#typo3-pagetree .typo3-pagetree-topbar-item div {
-       background-color: #DADADA;
+#typo3-pagetree .typo3-pagetree-topPanel-button button {
+       vertical-align:middle;
 }
 
-#typo3-pagetree .typo3-pagetree-topbar-item {
-       padding: 5px 3px 0 3px;
-       height: 22px;
+#typo3-pagetree .ver-element,
+#typo3-pagetree .ver-versions,
+#typo3-pagetree .ver-page {
+       background-color: #ffec97;
 }
 
-#typo3-pagetree-topPanel-filter {
-       height: 14px;
+#typo3-pagetree .x-tree-node-over.ver-element,
+#typo3-pagetree .x-tree-node-over.ver-versions,
+#typo3-pagetree .x-tree-node-over.ver-page,
+#typo3-pagetree .x-tree-selected.ver-element,
+#typo3-pagetree .x-tree-selected.ver-versions,
+#typo3-pagetree .x-tree-selected.ver-page {
+       background-color: #fefae2;
 }
 
-#typo3-pagetree-deletionDropZone {
-       padding: 5px;
-       width: 100%;
-       position: fixed;
-       bottom: 0;
+#typo3-pagetree-topPanel-defaultPanel {
+       color: #A2AAB8;
+       padding-left: 6px;
+       line-height: 18px;
 }
 
-#typo3-pagetree-deletionDropZone,
-#typo3-pagetree-deletionDropZone .x-panel-body {
-       background-color: #DADADA;
+#typo3-pagetree-topPanel-item-newNode .x-btn-over {
+       background: inherit;
 }
+
+#typo3-pagetree-topPanel-button-refresh,
+#typo3-pagetree-topPanel-button-refresh.x-btn-over {
+       background: inherit;
+}
\ No newline at end of file
index 6717196..cbf7678 100644 (file)
@@ -1,6 +1,46 @@
+/***************************************************************
+*  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!
+***************************************************************/
 Ext.namespace('TYPO3.Components.PageTree');
 
+/**
+ * @class TYPO3.Components.PageTree.Actions
+ *
+ * Actions dedicated for the page tree
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
 TYPO3.Components.PageTree.Actions = {
+       /**
+        * Evaluates a response from an ext direct call and shows a flash message
+        * if it was an exceptional result
+        *
+        * @param {Object} response
+        * @return {Boolean}
+        */
        evaluateResponse: function(response) {
                if (response.success === false) {
                        TYPO3.Flashmessage.display(4, 'Exception', response.message);
@@ -10,196 +50,589 @@ TYPO3.Components.PageTree.Actions = {
                return true;
        },
 
-       removeNode: function(node) {
+       /**
+        * Releases the cut and copy mode from the context menu
+        *
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       releaseCutAndCopyModes: function(tree) {
+               tree.t3ContextInfo.inCutMode = false;
+               tree.t3ContextInfo.inCopyMode = false;
+
+               if (tree.t3ContextNode) {
+                       tree.t3ContextNode.attributes.nodeData.t3InCutMode = false;
+                       tree.t3ContextNode.attributes.nodeData.t3InCopyMode = false;
+                       tree.t3ContextNode = null;
+               }
+       },
+
+       /**
+        * Updates an existing node with the given alternative. The new tree node
+        * is returned afterwards.
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {Boolean} isExpanded
+        * @param {Object} updatedNode
+        * @return {Ext.tree.TreeNode}
+        */
+       updateNode: function(node, isExpanded, updatedNode) {
+               updatedNode.uiProvider = node.ownerTree.uiProvider;
+               var newTreeNode = new Ext.tree.TreeNode(updatedNode);
+
+               node.parentNode.replaceChild(newTreeNode, node);
+               newTreeNode.ownerTree.refreshNode(newTreeNode, function() {
+                       newTreeNode.parentNode.expand(false, false);
+                       if (isExpanded) {
+                               newTreeNode.expand(false, false);
+                       } else {
+                               newTreeNode.collapse(false, false);
+                       }
+               });
+
+               return newTreeNode;
+       },
+
+       /**
+        * Removes a node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       removeNode: function(node, tree) {
                TYPO3.Components.PageTree.Commands.deleteNode(
                        node.attributes.nodeData,
                        function(response) {
                                if (this.evaluateResponse(response)) {
-                                       node.remove();
+                                       if (tree.getSelectionModel().getSelectedNode().id === node.id) {
+                                               this.singleClick(node.parentNode, tree);
+                                       }
+
+                                               // the node may not be removed in workspace mode
+                                       if (top.TYPO3.configuration.inWorkspace && response.id) {
+                                               this.updateNode(node, node.isExpanded(), response);
+                                       } else {
+                                               node.remove();
+                                       }
+                               }
+                       },
+                       this
+               );
+       },
+
+       /**
+        * Restores a given node and moves it to the given destination inside the tree. Use this
+        * method if you want to add it as the first child of the destination.
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @param {Ext.tree.TreeNode} destination
+        * @return {void}
+        */
+       restoreNodeToFirstChildOfDestination: function(node, tree, destination) {
+               TYPO3.Components.PageTree.Commands.restoreNode(
+                       node.attributes.nodeData,
+                       destination.attributes.nodeData.id,
+                       function(updatedNode) {
+                               if (this.evaluateResponse(updatedNode)) {
+                                       var newTreeNode = new Ext.tree.TreeNode(
+                                               Ext.apply(node.attributes, updatedNode)
+                                       );
+                                       destination.insertBefore(newTreeNode, destination.firstChild);
+                               }
+                       },
+                       this
+               );
+       },
+
+       /**
+        * Restores a given node and moves it to the given destination inside the tree. Use this
+        * method if you want to add the node after the destination node.
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @param {Ext.tree.TreeNode} destination
+        * @return {void}
+        */
+       restoreNodeAfterDestination: function(node, tree, destination) {
+               TYPO3.Components.PageTree.Commands.restoreNode(
+                       node.attributes.nodeData,
+                       -destination.attributes.nodeData.id,
+                       function(updatedNode) {
+                               if (this.evaluateResponse(updatedNode)) {
+                                       var newTreeNode = new Ext.tree.TreeNode(
+                                               Ext.apply(node.attributes, updatedNode)
+                                       );
+                                       destination.parentNode.insertBefore(newTreeNode, destination.nextSibling);
                                }
                        },
                        this
                );
        },
 
-       restoreNode: function(node) {
-               TYPO3.Components.PageTree.Commands.restoreNode(node.attributes.nodeData);
+       /**
+        * Collapses a whole tree branch
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
+       collapseBranch: function(node) {
+               node.collapseChildNodes(true);
+               node.collapse();
        },
 
-       stub: function() {
-               alert('Just a Stub! Don\'t Panic!');
+       /**
+        * Expands a whole tree branch
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
+       expandBranch: function(node) {
+               node.expand();
+               node.expandChildNodes(true);
        },
 
+       /**
+        * Opens a popup windows for previewing the given node/page
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
        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');
+                               openUrlInWindow(result, 'typo3ContextMenuView');
                        }
                );
        },
 
+       /**
+        * Creates a temporary tree mount point
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       mountAsTreeRoot: function(node, tree) {
+               TYPO3.Components.PageTree.Commands.setTemporaryMountPoint(
+                       node.attributes.nodeData,
+                       function(response) {
+                               if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) {
+                                       TYPO3.Backend.NavigationContainer.PageTree.removeIndicator(
+                                               TYPO3.Backend.NavigationContainer.PageTree.temporaryMountPointInfoIndicator
+                                       );
+                               }
+
+                               TYPO3.Components.PageTree.Configuration.temporaryMountPoint = response;
+                               TYPO3.Backend.NavigationContainer.PageTree.addTemporaryMountPointIndicator();
+
+                               var selectedNode = TYPO3.Backend.NavigationContainer.PageTree.getSelected();
+                               tree.stateId = 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint;
+                               tree.refreshTree(function() {
+                                       var nodeIsSelected = false;
+                                       if (selectedNode) {
+                                               nodeIsSelected = TYPO3.Backend.NavigationContainer.PageTree.select(
+                                                       selectedNode.attributes.nodeData.id
+                                               );
+                                       }
+
+                                       var node = (nodeIsSelected ? TYPO3.Backend.NavigationContainer.PageTree.getSelected() : null);
+                                       if (node) {
+                                               this.singleClick(node, tree);
+                                       } else {
+                                               this.singleClick(tree.getRootNode().firstChild, tree);
+                                       }
+                               }, this);
+                       },
+                       this
+               );
+       },
+
+       /**
+        * Opens the edit page properties dialog
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
        editPageProperties: function(node) {
+               node.select();
                TYPO3.Backend.ContentContainer.setUrl(
-                       'alt_doc.php?edit[pages][' + node.attributes.id + ']=edit'
+                       'alt_doc.php?edit[pages][' + node.attributes.nodeData.id + ']=edit'
                );
        },
 
+       /**
+        * Opens the new page wizard
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
        newPageWizard: function(node) {
+               node.select();
                TYPO3.Backend.ContentContainer.setUrl(
-                       'db_new.php?id=' + node.attributes.id + '&pagesOnly=1'
+                       'db_new.php?id=' + node.attributes.nodeData.id + '&pagesOnly=1'
                );
        },
 
+       /**
+        * Opens the info popup
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
        openInfoPopUp: function(node) {
-               launchView('pages', node.attributes.id);
+               launchView('pages', node.attributes.nodeData.id);
        },
 
+       /**
+        * Opens the history popup
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
        openHistoryPopUp: function(node) {
+               node.select();
                TYPO3.Backend.ContentContainer.setUrl(
-                       'show_rechis.php?element=pages:' + node.attributes.id
+                       'show_rechis.php?element=pages:' + node.attributes.nodeData.id
                );
        },
 
-       enableCutMode: function(node, pageTree) {
-               this.disableCopyMode(node, pageTree);
+       /**
+        * Opens the export .t3d file dialog
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
+       exportT3d: function(node) {
+               node.select();
+               TYPO3.Backend.ContentContainer.setUrl(
+                       'sysext/impexp/app/index.php?tx_impexp[action]=export&' +
+                               'id=0&tx_impexp[pagetree][id]=' + node.attributes.nodeData.id +
+                               '&tx_impexp[pagetree][levels]=' + node.attributes.nodeData.id +
+                               '&tx_impexp[pagetree][tables][]=_ALL'
+               );
+       },
+
+       /**
+        * Opens the import .t3d file dialog
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
+       importT3d: function(node) {
+               node.select();
+               TYPO3.Backend.ContentContainer.setUrl(
+                       'sysext/impexp/app/index.php?id=' + node.attributes.nodeData.id +
+                               '&table=pages&tx_impexp[action]=import'
+               );
+       },
+
+       /**
+        * Enables the cut mode of a node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       enableCutMode: function(node, tree) {
+               this.disableCopyMode(node, tree);
                node.attributes.nodeData.t3InCutMode = true;
-               pageTree.tree.t3ContextInfo.inCutMode = true;
-               pageTree.tree.t3ContextNode = node;
+               tree.t3ContextInfo.inCutMode = true;
+               tree.t3ContextNode = node;
        },
 
-       disableCutMode: function(node, pageTree) {
-               this.releaseCutAndCopyModes(pageTree);
+       /**
+        * Disables the cut mode of a node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       disableCutMode: function(node, tree) {
+               this.releaseCutAndCopyModes(tree);
                node.attributes.nodeData.t3InCutMode = false;
        },
 
-       enableCopyMode: function(node, pageTree) {
-               this.disableCutMode(node, pageTree);
+       /**
+        * Enables the copy mode of a node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       enableCopyMode: function(node, tree) {
+               this.disableCutMode(node, tree);
                node.attributes.nodeData.t3InCopyMode = true;
-               pageTree.tree.t3ContextInfo.inCopyMode = true;
-               pageTree.tree.t3ContextNode = node;
+               tree.t3ContextInfo.inCopyMode = true;
+               tree.t3ContextNode = node;
        },
 
-       disableCopyMode: function(node, pageTree) {
-               this.releaseCutAndCopyModes(pageTree);
+       /**
+        * Disables the copy mode of a node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       disableCopyMode: function(node, tree) {
+               this.releaseCutAndCopyModes(tree);
                node.attributes.nodeData.t3InCopyMode = false;
        },
 
-       pasteIntoNode: function(node, pageTree) {
-               this.releaseCutAndCopyModes(pageTree);
-               this.stub();
-       },
+       /**
+        * Pastes the cut/copy context node into the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       pasteIntoNode: function(node, tree) {
+               if (!tree.t3ContextNode) {
+                       return;
+               }
 
-       pasteAfterNode: function(node, pageTree) {
-               this.releaseCutAndCopyModes(pageTree);
-               this.stub();
+               if (tree.t3ContextInfo.inCopyMode) {
+                       var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes);
+                       newNode.id = 'fakeNode';
+                       node.insertBefore(newNode, node.childNodes[0]);
+                       node.attributes.nodeData.t3InCopyMode = false;
+                       this.copyNodeToFirstChildOfDestination(newNode, tree);
+
+               } else if (tree.t3ContextInfo.inCutMode) {
+                       node.appendChild(tree.t3ContextNode);
+                       node.attributes.nodeData.t3InCutMode = false;
+                       this.moveNodeToFirstChildOfDestination(node, tree);
+               }
        },
 
-       releaseCutAndCopyModes: function(pageTree) {
-               pageTree.tree.t3ContextInfo.inCutMode = false;
-               pageTree.tree.t3ContextInfo.inCopyMode = false;
+       /**
+        * Pastes a cut/copy context node after the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       pasteAfterNode: function(node, tree) {
+               if (!tree.t3ContextNode) {
+                       return;
+               }
+
+               if (tree.t3ContextInfo.inCopyMode) {
+                       var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes);
+                       newNode.id = 'fakeNode';
+                       node.parentNode.insertBefore(newNode, node.nextSibling);
+                       node.attributes.nodeData.t3InCopyMode = false;
+                       this.copyNodeAfterDestination(newNode, tree);
 
-               if (pageTree.tree.t3ContextNode) {
-                       pageTree.tree.t3ContextNode.attributes.nodeData.t3InCutMode = false;
-                       pageTree.tree.t3ContextNode.attributes.nodeData.t3InCopyMode = false;
-                       pageTree.tree.t3ContextNode = null;
+               } else if (tree.t3ContextInfo.inCutMode) {
+                       node.parentNode.insertBefore(tree.t3ContextNode, node.nextSibling);
+                       node.attributes.nodeData.t3InCutMode = false;
+                       this.moveNodeAfterDestination(node, tree);
                }
        },
 
-       moveNodeToFirstChildOfDestination: function(node, newParent) {
-               TYPO3.Components.PageTree.Commands.moveNodeToFirstChildOfDestination(
-                       node.attributes.nodeData,
-                       newParent
+       /**
+        * Moves the current tree context node after the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       moveNodeAfterDestination: function(node, tree) {
+               TYPO3.Components.PageTree.Commands.moveNodeAfterDestination(
+                       tree.t3ContextNode.attributes.nodeData,
+                       node.attributes.nodeData.id,
+                       function(response) {
+                               if (this.evaluateResponse(response) && tree.t3ContextNode) {
+                                       this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
+                               }
+                               this.releaseCutAndCopyModes(tree);
+                       },
+                       this
                );
        },
 
-       moveNodeAfterDestination: function(node, newParent) {
-               TYPO3.Components.PageTree.Commands.moveNodeAfterDestination(
-                       node.attributes.nodeData,
-                       newParent
+       /**
+        * Moves the current tree context node as the first child of the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       moveNodeToFirstChildOfDestination: function(node, tree) {
+               TYPO3.Components.PageTree.Commands.moveNodeToFirstChildOfDestination(
+                       tree.t3ContextNode.attributes.nodeData,
+                       node.attributes.nodeData.id,
+                       function(response) {
+                               if (this.evaluateResponse(response) && tree.t3ContextNode) {
+                                       this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
+                               }
+                               this.releaseCutAndCopyModes(tree);
+                       },
+                       this
                );
        },
 
-       insertNodeAfterDestination: function(node, callback) {
+       /**
+        * Inserts a new node after the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       insertNodeAfterDestination: function(node, tree) {
                TYPO3.Components.PageTree.Commands.insertNodeAfterDestination(
-                       node.parentNode.attributes.nodeData,
-                       node.previousSibling.id,
-                       node.serverNodeType,
-                       callback.createDelegate(node)
+                       tree.t3ContextNode.attributes.nodeData,
+                       node.previousSibling.attributes.nodeData.id,
+                       tree.t3ContextInfo.serverNodeType,
+                       function(response) {
+                               if (this.evaluateResponse(response)) {
+                                       this.updateNode(node, node.isExpanded(), response);
+                               }
+                               this.releaseCutAndCopyModes(tree);
+                       },
+                       this
                );
        },
 
-       insertNodeToFirstChildOfDestination: function(node, callback) {
+       /**
+        * Inserts a new node as the first child of the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       insertNodeToFirstChildOfDestination: function(node, tree) {
                TYPO3.Components.PageTree.Commands.insertNodeToFirstChildOfDestination(
-                       node.parentNode.attributes.nodeData,
-                       node.serverNodeType,
-                       callback.createDelegate(node)
+                       tree.t3ContextNode.attributes.nodeData,
+                       tree.t3ContextInfo.serverNodeType,
+                       function(response) {
+                               if (this.evaluateResponse(response)) {
+                                       node = this.updateNode(node, true, response);
+                               }
+                               this.releaseCutAndCopyModes(tree);
+                       },
+                       this
                );
        },
 
-       copyNodeToFirstChildOfDestination: function(node, callback) {
-               TYPO3.Components.PageTree.Commands.copyNodeToFirstChildOfDestination(
-                       node.attributes.nodeData,
-                       node.parentNode.id,
-                       callback.createDelegate(node)
+       /**
+        * Copies the current tree context node after the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       copyNodeAfterDestination: function(node, tree) {
+               TYPO3.Components.PageTree.Commands.copyNodeAfterDestination(
+                       tree.t3ContextNode.attributes.nodeData,
+                       node.previousSibling.attributes.nodeData.id,
+                       function(response) {
+                               if (this.evaluateResponse(response)) {
+                                       this.updateNode(node, true, response);
+                               }
+                               this.releaseCutAndCopyModes(tree);
+                       },
+                       this
                );
        },
 
-       copyNodeAfterDestination: function(node, callback) {
-               TYPO3.Components.PageTree.Commands.copyNodeAfterDestination(
-                       node.attributes.nodeData,
-                       node.previousSibling.id,
-                       callback.createDelegate(node)
+       /**
+        * Copies the current tree context node as the first child of the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       copyNodeToFirstChildOfDestination: function(node, tree) {
+               TYPO3.Components.PageTree.Commands.copyNodeToFirstChildOfDestination(
+                       tree.t3ContextNode.attributes.nodeData,
+                       node.parentNode.attributes.nodeData.id,
+                       function(response) {
+                               if (this.evaluateResponse(response)) {
+                                       this.updateNode(node, true, response);
+                               }
+                               this.releaseCutAndCopyModes(tree);
+                       },
+                       this
                );
        },
 
+       /**
+        * Visibilizes a page
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
        enablePage: function(node) {
                TYPO3.Components.PageTree.Commands.visiblyNode(
                        node.attributes.nodeData,
                        function(response) {
                                if (this.evaluateResponse(response)) {
-                                       this.updateNode(node, response);
+                                       this.updateNode(node, node.isExpanded(), response);
                                }
                        },
                        this
                );
        },
 
+       /**
+        * Disables a page
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @return {void}
+        */
        disablePage: function(node) {
                TYPO3.Components.PageTree.Commands.disableNode(
                        node.attributes.nodeData,
                        function(response) {
                                if (this.evaluateResponse(response)) {
-                                       this.updateNode(node, response);
+                                       this.updateNode(node, node.isExpanded(), 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);
-       },
+       /**
+        * Reloads the content frame with the current module and node id
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       singleClick: function(node, tree) {
+               var separator = '?';
+               if (currentSubScript.indexOf('?') !== -1) {
+                       separator = '&';
+               }
 
-       singleClick: function(node) {
+               node.select();
+               tree.stateHash['lastSelectedNode'] = node.id;
                TYPO3.Backend.ContentContainer.setUrl(
-                       TS.PATH_typo3 + currentSubScript + '?id=' + node.attributes.id
+                       TS.PATH_typo3 + currentSubScript + separator + 'id=' + node.attributes.nodeData.id
                );
        },
 
+       /**
+        * Updates the title of a node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {String} newText
+        * @param {String} oldText
+        * @return {void}
+        */
        saveTitle: function(node, newText, oldText) {
-               if (newText === oldText) {
-                       return;
-               }
+               this.singleClick(node.editNode, node.editNode.ownerTree);
 
-               TYPO3.Components.PageTree.Commands.updateLabel(
-                       node.editNode.attributes.nodeData,
-                       newText,
-                       this.evaluateResponse
-               );
+               if (newText !== oldText) {
+                       TYPO3.Components.PageTree.Commands.updateLabel(
+                               node.editNode.attributes.nodeData,
+                               newText,
+                               this.evaluateResponse
+                       );
+               }
        }
 };
\ No newline at end of file
index 0a8d86e..b9a36ca 100644 (file)
@@ -1,10 +1,66 @@
+/***************************************************************
+*  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!
+***************************************************************/
 Ext.namespace('TYPO3.Components.PageTree');
 
+/**
+ * @class TYPO3.Components.PageTree.ContextMenu
+ *
+ * Context menu implementation
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.menu.Menu
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
 TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
+       /**
+        * Context menu node
+        *
+        * @cfg {Ext.tree.TreeNode}
+        */
        node: null,
+
+       /**
+        * Page Tree
+        *
+        * @cfg {TYPO3.Components.PageTree.Tree}
+        */
        pageTree: null,
+
+       /**
+        * Component Id
+        *
+        * @type {String}
+        */
        id: 'typo3-pagetree-contextmenu',
 
+       /**
+        * Listeners
+        *
+        * The itemclick event triggers the configured single click action
+        */
        listeners: {
                itemclick: {
                        fn: function (item) {
@@ -17,36 +73,37 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
        },
 
        /**
-        * Fill menu with menu items and returns the number of context menu items
+        * Fills the menu with the actions
         *
-        * @param node
-        * @param pageTree
-        * @param contextMenuConfiguration
-        * @return int
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} pageTree
+        * @param {Object} contextMenuConfiguration
+        * @return {void}
         */
-       fillWithMenuItems: function(node, pageTree, contextMenuConfiguration) {
+       fill: 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] === '-') {
                                        this.addSeparator();
-                               } else {
-                                       if (typeof components[component] === 'object') {
-                                               this.addItem(components[component]);
-                                       }
+                               } else if (typeof components[component] === 'object') {
+                                       this.addItem(components[component]);
                                }
                        }
                }
-               return components.length;
        },
 
-       // Private
-       // recursively parses the context menu actions array and generates the
-       // components for the context menu including separators/dividers and sub menus
+       /**
+        * Parses the context menu actions array recursively and generates the
+        * components for the context menu including separators/dividers and sub menus
+        *
+        * @param {Object} contextMenuConfiguration
+        * @param {int} level
+        * @return {Object}
+        */
        preProcessContextMenuConfiguration: function(contextMenuConfiguration, level) {
                level = level || 0;
                if (level > 5) {
index 46372a2..fc53829 100644 (file)
+/***************************************************************
+*  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!
+***************************************************************/
 Ext.namespace('TYPO3.Components.PageTree');
 
 /**
- * Main filtering tree widget
+ * @class TYPO3.Components.PageTree.DeletionDropZone
+ *
+ * Deletion Drop Zone
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.Panel
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
 TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
+       /**
+        * Component Id
+        *
+        * @type {String}
+        */
        id: 'typo3-pagetree-deletionDropZone',
+
+       /**
+        * Border
+        *
+        * @type {Boolean}
+        */
        border: true,
-       height: 50,
-       html: '<strong>Drag a page into this drop zone to delete it</strong>',
 
-       pageTree: null,
+       /**
+        * Command Provider
+        *
+        * @cfg {Object}
+        */
+       commandProvider: null,
+
+       /**
+        * Drag and Drop Group
+        *
+        * @cfg {String}
+        */
+       ddGroup: '',
+
+       /**
+        * Page Tree
+        *
+        * @cfg {TYPO3.Components.PageTree.Tree}
+        */
+       tree: null,
+
+       /**
+        * Removed node had a previous sibling
+        *
+        * @type {Boolean}
+        */
+       isPreviousSibling: false,
 
+       /**
+        * Removed node
+        *
+        * @type {Ext.tree.TreeNode}
+        */
+       previousNode: null,
+
+       /**
+        * Click Handler for the recovery text
+        *
+        * @type {Function}
+        */
+       textClickHandler: null,
+
+       /**
+        * Listeners
+        *
+        * The "afterrender" event creates the drop zone
+        */
        listeners: {
                afterrender: {
                        fn: function() {
-                               var filteringTree = this.pageTree;
-                               (new Ext.dd.DropTarget(this.getEl(), {
-                                       notifyDrop: function(ddProxy, e, n) {
-                                               var node = n.node;
-
-                                               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.commandProvider.restoreNode(node, filteringTree);
-                                                       filteringTree.tree.refreshTree();
-                                                       this.update('<strong>Restored</strong>');  // TODO: LOCALIZE
-
-                                               }.createDelegate(dropZoneBody, [node.id, filteringTree]));
-
-                                               var fadeOutFn = function() {
-                                                       this.animate({opacity: {to: 0}}, 1, function(dropZoneBody) {
-                                                               dropZoneBody.update('<strong>DropZone</strong>'); // TODO
-                                                               dropZoneBody.setStyle('opacity', 1);
-                                                       });
-                                               };
-                                               fadeOutFn.defer(5000, dropZoneBody);
-
-                                               node.ownerTree.pageTree.commandProvider.removeNode(node, node.ownerTree);
-                                       },
-                                       ddGroup: 'TreeDD',
-                                       overClass: 'dd-delete-over'
-                               }));
-
-                               // TODO: Show drop zone only if currently dragging
+                               this.createDropZone();
                        }
                }
+       },
+
+       /**
+        * Initializes the component
+        *
+        * @return {void}
+        */
+       initComponent: function() {
+               this.html = '<p><span id="' + this.id + '-icon" class="' +
+                       TYPO3.Components.PageTree.Sprites.TrashCan +
+                       '">&nbsp;</span><span id="' + this.id + '-text">' +
+                       TYPO3.Components.PageTree.LLL.dropToRemove + '</span></p>';
+
+               TYPO3.Components.PageTree.DeletionDropZone.superclass.initComponent.apply(this, arguments);
+       },
+
+       /**
+        * Creates the drop zone and it's functionality
+        *
+        * @return {void}
+        */
+       createDropZone: function() {
+               (new Ext.dd.DropTarget(this.getEl(), {
+                       ddGroup: this.ddGroup,
+
+                       notifyDrop: function(ddProxy, e, n) {
+                               var node = n.node;
+                               if (!node) {
+                                       return;
+                               }
+
+                               var tree = node.ownerTree;
+                               if (this.textClickHandler) {
+                                       this.toOriginState(false);
+                               }
+
+                               if (!top.TYPO3.configuration.inWorkspace) {
+                                       this.updateText(TYPO3.Components.PageTree.LLL.dropZoneElementRemoved);
+                                       this.updateIcon(TYPO3.Components.PageTree.Sprites.TrashCanRestore);
+
+                                       (function() {
+                                               if (this.textClickHandler) {
+                                                       this.toOriginState();
+                                               }
+                                       }).defer(5000, this);
+
+                                       this.textClickHandler = this.restoreNode.createDelegate(this, [node, tree]);
+                                       Ext.get(this.id + '-text').on('click', this.textClickHandler);
+
+                                       this.isPreviousSibling = false;
+                                       this.previousNode = node.parentNode;
+                                       if (node.previousSibling) {
+                                               this.previousNode = node.previousSibling;
+                                               this.isPreviousSibling = true;
+                                       }
+                               }
+
+                               node.ownerTree.commandProvider.removeNode(node, tree);
+                       }.createDelegate(this)
+               }));
+       },
+
+       /**
+        * Updates the drop zone text label
+        *
+        * @param {String} text
+        * @param {Boolean} animate
+        * @return {void}
+        */
+       updateText: function(text, animate) {
+               animate = animate || false;
+
+               var elementText = Ext.get(this.id + '-text');
+               if (animate) {
+                       elementText.animate({opacity: {to: 0}}, 1, function(elementText) {
+                               elementText.update(text);
+                               elementText.setStyle('opacity', 1);
+                       });
+               } else {
+                       elementText.update(text);
+               }
+       },
+
+       /**
+        * Updates the drop zone icon with another sprite icon
+        *
+        * @param {String} classes
+        * @return {void}
+        */
+       updateIcon: function(classes) {
+               var icon = Ext.get(this.id + '-icon');
+               icon.set({
+                       'class': classes
+               });
+       },
+
+       /**
+        * Resets the drop zone to the initial state
+        *
+        * @param {Boolean} animate
+        * @return {void}
+        */
+       toOriginState: function(animate) {
+               if (animate !== false) {
+                       animate = true;
+               }
+
+               this.updateText(TYPO3.Components.PageTree.LLL.dropToRemove, animate);
+               this.updateIcon(TYPO3.Components.PageTree.Sprites.TrashCan);
+               Ext.get(this.id + '-text').un('click', this.textClickHandler);
+               this.previousNode = this.textClickHandler = null;
+               this.isPreviousSibling = false;
+       },
+
+       /**
+        * Restores the last removed node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @return {void}
+        */
+       restoreNode: function(node, tree) {
+               if (this.isPreviousSibling) {
+                       this.commandProvider.restoreNodeAfterDestination(node, tree, this.previousNode);
+               } else {
+                       this.commandProvider.restoreNodeToFirstChildOfDestination(node, tree, this.previousNode);
+               }
+               this.updateText(TYPO3.Components.PageTree.LLL.dropZoneElementRestored);
+
+               (function() {
+                       if (this.textClickHandler) {
+                               this.toOriginState();
+                       }
+               }).defer(3000, this);
        }
 });
 
index 672b916..06001b5 100644 (file)
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
 
 /**
- * TYPO3 Page Tree Panel
+ * @class TYPO3.Components.PageTree.Tree
+ *
+ * Generic Tree Panel
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.tree.TreePanel
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-
-Ext.namespace('TYPO3.Components.PageTree');
-
 TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
-       id: 'typo3-pagetree-tree',
+       /**
+        * Border
+        *
+        * @type {Boolean}
+        */
        border: false,
 
+       /**
+        * Indicates if the root node is visible
+        *
+        * @type {Boolean}
+        */
+       rootVisible: false,
+
+       /**
+        * Enable the drag and drop feature
+        *
+        * @cfg {Boolean}
+        */
        enableDD: true,
-       dragConfig: {
-               ddGroup: 'TreeDD'
+
+       /**
+        * Drag and Drop Group
+        *
+        * @cfg {String}
+        */
+       ddGroup: '',
+
+       /**
+        * Indicates if the label should be editable
+        *
+        * @cfg {Boolean}
+        */
+       labelEdit: true,
+
+       /**
+        * User Interface Provider
+        *
+        * @cfg {Ext.tree.TreeNodeUI}
+        */
+       uiProvider: null,
+
+       /**
+        * Data Provider
+        *
+        * @cfg {Object}
+        */
+       treeDataProvider: null,
+
+       /**
+        * Command Provider
+        *
+        * @cfg {Object}
+        */
+       commandProvider : null,
+
+       /**
+        * Context menu provider
+        *
+        * @cfg {Object}
+        */
+       contextMenuProvider: null,
+
+       /**
+        * Root Node Configuration
+        *
+        * @type {Object}
+        */
+       rootNodeConfig: {
+               id: 'root',
+               expanded: true
        },
 
+       /**
+        * Indicator if the control key is pressed
+        *
+        * @type {Boolean}
+        */
+       isControlPressed: false,
+
+       /**
+        * Context Node
+        *
+        * @type {Ext.tree.TreeNode}
+        */
        t3ContextNode: null,
+
+       /**
+        * Context Information
+        *
+        * @type {Object}
+        */
        t3ContextInfo: {
                inCopyMode: false,
                inCutMode: false
        },
 
-       rootVisible: false,
-       pageTree: null,
-       contextMenuConfiguration: null,
+       /**
+        * Listeners
+        *
+        * Event handlers that handle click events and synchronizes the label edit,
+        * double click and single click events in a useful way.
+        */
+       listeners: {
+                       // single click handler that only triggers after a delay to let the double click event
+                       // a possibility to be executed (needed for label edit)
+               click: {
+                       fn: function(node, event) {
+                               if (this.clicksRegistered === 2) {
+                                       this.clicksRegistered = 0;
+                                       event.stopEvent();
+                                       return false;
+                               }
+
+                               this.clicksRegistered = 0;
+                               if (this.commandProvider.singleClick) {
+                                       this.commandProvider.singleClick(node, this);
+                               }
+                       },
+                       delay: 400
+               },
+
+                       // prevent the expanding / collapsing on double click
+               beforedblclick: {
+                       fn: function() {
+                               return false;
+                       }
+               },
 
+                       // prevents label edit on a selected node
+               beforeclick: {
+                       fn: function(node, event) {
+                               if (!this.clicksRegistered && this.getSelectionModel().isSelected(node)) {
+                                       node.fireEvent('click', node, event);
+                                       ++this.clicksRegistered;
+                                       return false;
+                               }
+                               ++this.clicksRegistered;
+                       }
+               }
+       },
+
+       /**
+        * Initializes the component
+        *
+        * @return {void}
+        */
        initComponent: function() {
-               this.contextMenu = new TYPO3.Components.PageTree.ContextMenu({});
+               if (!this.uiProvider) {
+                       this.uiProvider = TYPO3.Components.PageTree.PageTreeNodeUI;
+               }
 
-               this.root = new Ext.tree.AsyncTreeNode({
-                       expanded: true,
-                       id: 'root'
-               });
+               this.root = new Ext.tree.AsyncTreeNode(this.rootNodeConfig);
+               this.addTreeLoader();
 
+               if (this.labelEdit) {
+                       this.enableInlineEditor();
+               }
+
+               if (this.enableDD) {
+                       this.dragConfig = {ddGroup: this.ddGroup};
+                       this.enableDragAndDrop();
+               }
+
+               if (this.contextMenuProvider) {
+                       this.enableContextMenu();
+               }
+
+               TYPO3.Components.PageTree.Tree.superclass.initComponent.apply(this, arguments);
+       },
+
+       /**
+        * Refreshes the tree
+        *
+        * @param {Function} callback
+        * @param {Object} scope
+        * return {void}
+        */
+       refreshTree: function(callback, scope) {
+               this.refreshNode(this.root, callback, scope);
+       },
+
+       /**
+        * Refreshes a given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {Function} callback
+        * @param {Object} scope
+        * return {void}
+        */
+       refreshNode: function(node, callback, scope) {
+               if (this.inRefreshingMode) {
+                       return;
+               }
+
+               scope = scope || node;
+               this.inRefreshingMode = true;
+               var loadCallback = function(node) {
+                       node.ownerTree.inRefreshingMode = false;
+                       if (node.ownerTree.restoreState) {
+                               node.ownerTree.restoreState(node.getPath());
+                       }
+               };
+
+               if (callback) {
+                       loadCallback = callback.createSequence(loadCallback);
+               }
+
+               this.getLoader().load(node, loadCallback, scope);
+       },
+
+       /**
+        * Adds a tree loader implementation that uses the directFn feature
+        *
+        * return {void}
+        */
+       addTreeLoader: function() {
                this.loader = new Ext.tree.TreeLoader({
-                       directFn: this.pageTree.dataProvider.getNextTreeLevel,
+                       directFn: this.treeDataProvider.getNextTreeLevel,
                        paramOrder: 'attributes',
-
                        baseAttrs: {
-                               uiProvider: 't3'
+                               uiProvider: this.uiProvider
                        },
 
-                       uiProviders: {
-                               t3: TYPO3.Components.PageTree.PageTreeUI,
-                               rootNodeProvider: Ext.tree.TreeNodeUI
-                       },
-                       
+                               // an id can never be zero in ExtJS, but this is needed
+                               // for the root line feature or it will never be working!
                        createNode: function(attr) {
                                if (attr.id == 0) {
                                        attr.id = 'siteRootNode';
@@ -80,91 +271,216 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 
                        listeners: {
                                beforeload: function(treeLoader, node) {
-                                       treeLoader.baseParams.attributes = node.attributes;
-                               },
-
-                               load: {
-                                       scope: this,
-                                       fn: function(treeLoader, node) {
-                                               this.restoreState(node.getPath());
-                                       }
+                                       node.ownerTree.previousOpenedStateHash = {};
+                                       treeLoader.baseParams.attributes = node.attributes.nodeData;
                                }
                        }
                });
+       },
 
-               TYPO3.Components.PageTree.Tree.superclass.initComponent.apply(this, arguments);
+       /**
+        * Enables the context menu feature
+        *
+        * return {void}
+        */
+       enableContextMenu: function() {
+               this.contextMenu = new TYPO3.Components.PageTree.ContextMenu();
+
+               this.on('contextmenu', function(node, event) {
+                       this.openContextMenu(node, event);
+               });
        },
 
-       // shows the context menu and creates it if it's not already done
+       /**
+        * Open a context menu for the given node
+        *
+        * @param {Ext.tree.TreeNode} node
+        * @param {Ext.EventObject} event
+        * return {void}
+        */
        openContextMenu: function(node, event) {
-               node.select();
-
-               var attributes = { t3ContextInfo: node.ownerTree.t3ContextInfo };
-               attributes = Ext.apply(node.attributes.nodeData, attributes);
+               var attributes = Ext.apply(node.attributes.nodeData, {
+                       t3ContextInfo: node.ownerTree.t3ContextInfo
+               });
 
-               this.pageTree.contextMenuDataProvider.getActionsForNodeArray(
+               this.contextMenuProvider.getActionsForNodeArray(
                        attributes,
-                       function(result) {
-                               var contextMenu = node.getOwnerTree().contextMenu;
-                               contextMenu.removeAll();
+                       function(configuration) {
+                               this.contextMenu.removeAll();
+                               this.contextMenu.fill(node, this, configuration);
+                               if (this.contextMenu.items.length) {
+                                       this.contextMenu.showAt(event.getXY());
 
-                               var numberOfElementsInside = contextMenu.fillWithMenuItems(node, this.pageTree, result);
-                               if (numberOfElementsInside > 0) {
-                                       contextMenu.showAt(event.getXY());
                                }
                        },
                        this
                );
        },
 
-       refreshTree: function() {
-               this.getLoader().load(this.root);
+       /**
+        * Initialize the inline editor for the given tree.
+        *
+        * @return {void}
+        */
+       enableInlineEditor: function() {
+               (new TYPO3.Components.PageTree.TreeEditor(this));
        },
 
-       refreshNode: function(node) {
-               this.getLoader().load(node);
-       },
+       /**
+        * Enables the drag and drop feature
+        *
+        * return {void}
+        */
+       enableDragAndDrop: function() {
+                       // init proxy element
+               this.on('startdrag', this.initDDProxyElement, this);
 
-       listeners: {
-               // this event triggers the context menu
-               contextmenu: {
-                       scope: this,
-                       fn: function(node, event) {
-                               node.getOwnerTree().openContextMenu(node, event);
-                       }
-               },
+                       // node is moved
+               this.on('movenode', this.moveNode, this);
 
-                       // calls a given single click callback for the tree
-               click: {
-                       fn: function(node, event) {
-                               if (this.clicksRegistered === 2) {
-                                       this.clicksRegistered = 0;
-                                       event.stopEvent();
-                                       return false;
-                               }
-
-                               this.clicksRegistered = 0;
-                               this.pageTree.commandProvider.singleClick(node);
-                       },
-                       delay: 400
-               },
+                       // new node is created/copied
+               this.on('beforenodedrop', this.beforeDropNode, this);
+               this.on('nodedrop', this.dropNode, this);
 
-                       // needed or the label edit will never work
-               beforedblclick: {
+                       // listens on the ctrl key to toggle the copy mode
+               (new Ext.KeyMap(document, {
+                       key: Ext.EventObject.CONTROL,
+                       scope: this,
+                       buffer: 250,
                        fn: function() {
-                               return false;
+                               if (this.dragZone.dragging && this.copyHint) {
+                                       this.shouldCopyNode = !this.shouldCopyNode;
+                                       this.copyHint.toggle();
+                               }
                        }
-               },
+               }, 'keydown'));
 
-               beforeclick: {
-                       fn: function(node, event) {
-                               if (!this.clicksRegistered && this.getSelectionModel().isSelected(node)) {
-                                       node.fireEvent('click', node, event);
-                                       ++this.clicksRegistered;
-                                       return false;
+                       // listens on the escape key to stop the dragging
+               (new Ext.KeyMap(document, {
+                       key: Ext.EventObject.ESC,
+                       scope: this,
+                       buffer: 250,
+                       fn: function(event) {
+                               if (this.dragZone.dragging) {
+                                       Ext.dd.DragDropMgr.stopDrag(event);
+                                       this.dragZone.onInvalidDrop(event);
                                }
-                               ++this.clicksRegistered;
                        }
+               }, 'keydown'));
+       },
+
+       /**
+        * Adds the copy hint to the proxy element
+        *
+        * @return {void}
+        */
+       initDDProxyElement: function() {
+               this.shouldCopyNode = false;
+               this.copyHint = new Ext.Element(document.createElement('div'))
+                       .addClass(this.id + '-copyHelp');
+               this.copyHint.dom.appendChild(document.createTextNode(TYPO3.Components.PageTree.LLL.copyHint));
+               this.copyHint.setVisibilityMode(Ext.Element.DISPLAY);
+
+               this.dragZone.proxy.ghost.dom.appendChild(this.copyHint.dom);
+       },
+
+       /**
+        * Creates a Fake Node
+        *
+        * This must be done to prevent the calling of the moveNode event.
+        *
+        * @param {object} dragElement
+        */
+       beforeDropNode: function(dragElement) {
+               if (dragElement.data && dragElement.data.item && dragElement.data.item.shouldCreateNewNode) {
+                       this.t3ContextInfo.serverNodeType = dragElement.data.item.nodeType;
+                       dragElement.dropNode = new Ext.tree.TreeNode({
+                               text: TYPO3.Components.PageTree.LLL.fakeNodeHint,
+                               leaf: true,
+                               isInsertedNode: true
+                       });
+
+                               // fix incorrect cancel value
+                       dragElement.cancel = false;
+
+               } else if (this.shouldCopyNode) {
+                       var attributes = dragElement.dropNode.attributes;
+                       attributes.isCopiedNode = true;
+                       attributes.id = 'fakeNode';
+                       dragElement.dropNode = new Ext.tree.TreeNode(attributes);
+               }
+
+               return true;
+       },
+
+       /**
+        * Differentiate between the copy and insert event
+        *
+        * @param {Ext.tree.TreeDropZone} dragElement
+        * return {void}
+        */
+       dropNode: function(dragElement) {
+               if (dragElement.dropNode.attributes.isInsertedNode) {
+                       dragElement.dropNode.attributes.isInsertedNode = false;
+                       this.insertNode(dragElement.dropNode);
+               } else if (dragElement.dropNode.attributes.isCopiedNode) {
+                       dragElement.dropNode.attributes.isCopiedNode = false;
+                       this.copyNode(dragElement.dropNode)
+               }
+       },
+
+       /**
+        * Moves a node
+        *
+        * @param {TYPO3.Components.PageTree.Tree} tree
+        * @param {Ext.tree.TreeNode} movedNode
+        * @param {Ext.tree.TreeNode} oldParent
+        * @param {Ext.tree.TreeNode} newParent
+        * @param {int} position
+        * return {void}
+        */
+       moveNode: function(tree, movedNode, oldParent, newParent, position) {
+               tree.t3ContextNode = movedNode;
+
+               if (position === 0) {
+                       this.commandProvider.moveNodeToFirstChildOfDestination(newParent, tree);
+               } else {
+                       var previousSiblingNode = newParent.childNodes[position - 1];
+                       this.commandProvider.moveNodeAfterDestination(previousSiblingNode, tree);
+               }
+       },
+
+       /**
+        * Inserts a node
+        *
+        * @param {Ext.tree.TreeNode} movedNode
+        * return {void}
+        */
+       insertNode: function(movedNode) {
+               this.t3ContextNode = movedNode.parentNode;
+
+               movedNode.disable();
+               if (movedNode.previousSibling) {
+                       this.commandProvider.insertNodeAfterDestination(movedNode, this);
+               } else {
+                       this.commandProvider.insertNodeToFirstChildOfDestination(movedNode, this);
+               }
+       },
+
+       /**
+        * Copies a node
+        *
+        * @param {Ext.tree.TreeNode} movedNode
+        * return {void}
+        */
+       copyNode: function(movedNode) {
+               this.t3ContextNode = movedNode;
+
+               movedNode.disable();
+               if (movedNode.previousSibling) {
+                       this.commandProvider.copyNodeAfterDestination(movedNode, this);
+               } else {
+                       this.commandProvider.copyNodeToFirstChildOfDestination(movedNode, this);
                }
        }
 });
index 93fe086..eab8ab0 100644 (file)
@@ -7,11 +7,13 @@ return array(
        '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',
+       't3lib_tree_extdirect_node' => $extensionPath . 'classes/class.t3lib_tree_extdirect_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',
+       'tx_pagetree_indicator' => $extensionPath . 'classes/class.tx_pagetree_indicator.php',
+       'tx_pagetree_indicatorprovider' => $extensionPath . 'classes/interface.tx_pagetree_indicatorprovider.php',
 );
 
 ?>
\ No newline at end of file
index f9954df..a594e49 100644 (file)
@@ -3,7 +3,7 @@
 ########################################################################
 # Extension Manager/Repository config file for ext "pagetree".
 #
-# Auto generated 01-12-2010 12:53
+# Auto generated 22-12-2010 01:41
 #
 # 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.1.0',
-       '_md5_values_when_last_written' => 'a:25:{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: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";}',
+       'version' => '1.5.0',
+       '_md5_values_when_last_written' => 'a:39:{s:16:"ext_autoload.php";s:4:"2721";s:12:"ext_icon.gif";s:4:"39bd";s:17:"ext_localconf.php";s:4:"f0ff";s:14:"ext_tables.php";s:4:"c9f3";s:25:"locallang_contextmenu.xml";s:4:"51fc";s:22:"locallang_pagetree.xml";s:4:"ee91";s:16:"pagetree_ie6.css";s:4:"c0ab";s:43:"classes/class.t3lib_tree_extdirect_node.php";s:4:"ba8b";s:38:"classes/class.tx_pagetree_commands.php";s:4:"b0ba";s:42:"classes/class.tx_pagetree_dataprovider.php";s:4:"37bc";s:39:"classes/class.tx_pagetree_indicator.php";s:4:"7ca2";s:34:"classes/class.tx_pagetree_node.php";s:4:"dca7";s:44:"classes/class.tx_pagetree_nodecollection.php";s:4:"2ef6";s:51:"classes/interface.tx_pagetree_indicatorprovider.php";s:4:"4218";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:"73ef";s:58:"classes/extdirect/class.tx_pagetree_extdirect_commands.php";s:4:"3f19";s:61:"classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php";s:4:"1f34";s:54:"classes/extdirect/class.tx_pagetree_extdirect_tree.php";s:4:"6ce5";s:36:"components/pagetree/css/pagetree.css";s:4:"7a6b";s:56:"components/pagetree/icons/gfx/toolbar_item_active_bg.png";s:4:"f8c0";s:41:"components/pagetree/icons/gfx/ol/join.gif";s:4:"84b4";s:47:"components/pagetree/icons/gfx/ol/joinbottom.gif";s:4:"e279";s:41:"components/pagetree/icons/gfx/ol/line.gif";s:4:"2961";s:42:"components/pagetree/icons/gfx/ol/minus.gif";s:4:"20e3";s:48:"components/pagetree/icons/gfx/ol/minusbottom.gif";s:4:"8dbc";s:41:"components/pagetree/icons/gfx/ol/plus.gif";s:4:"bad0";s:47:"components/pagetree/icons/gfx/ol/plusbottom.gif";s:4:"7e6e";s:56:"components/pagetree/javascript/Ext.ux.state.TreePanel.js";s:4:"e505";s:41:"components/pagetree/javascript/actions.js";s:4:"c330";s:37:"components/pagetree/javascript/app.js";s:4:"d974";s:45:"components/pagetree/javascript/contextmenu.js";s:4:"3c6c";s:50:"components/pagetree/javascript/deletiondropzone.js";s:4:"eece";s:47:"components/pagetree/javascript/filteringtree.js";s:4:"3b4b";s:44:"components/pagetree/javascript/loadorder.txt";s:4:"fcba";s:40:"components/pagetree/javascript/nodeui.js";s:4:"4414";s:42:"components/pagetree/javascript/toppanel.js";s:4:"16f1";s:38:"components/pagetree/javascript/tree.js";s:4:"ce38";s:44:"components/pagetree/javascript/treeeditor.js";s:4:"fde9";}',
        'constraints' => array(
                'depends' => array(
                        'cms' => '',
index ed0a681..1a54d50 100644 (file)
@@ -3,6 +3,29 @@ if (!defined('TYPO3_MODE')) {
        die ('Access denied.');
 }
 
+       // special context menu actions for the import/export module
+if (t3lib_extMgm::isLoaded('impexp')) {
+       $importExportActions = '
+               9000 = DIVIDER
+
+               9100 = ITEM
+               9100 {
+                       name = exportT3d
+                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.exportT3d
+                       spriteIcon = actions-document-export-t3d
+                       callbackAction = exportT3d
+               }
+
+               9200 = ITEM
+               9200 {
+                       name = importT3d
+                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.importT3d
+                       spriteIcon = actions-document-import-t3d
+                       callbackAction = importT3d
+               }
+       ';
+}
+
        // context menu user default configuration
 $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
        options.pageTree {
@@ -10,214 +33,223 @@ $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
        }
 
        options.contextMenu {
-               defaults {
-               }
-
                table {
-                       pages.items {
-                               100 = ITEM
-                               100 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.viewPage
-                                       spriteIcon = actions-document-view
-                                       displayCondition = canBeViewed != 0
-                                       callbackAction = viewPage
-                               }
+                       pages_root {
+                               disableItems =
 
-                               200 = DIVIDER
-
-                               300 = ITEM
-                               300 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.disablePage
-                                       spriteIcon = actions-edit-hide
-                                       displayCondition = getRecord|hidden = 0 && canBeDisabledAndEnabled != 0
-                                       callbackAction = disablePage
-                               }
+                               items {
+                                       100 = ITEM
+                                       100 {
+                                               name = view
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.viewPage
+                                               spriteIcon = actions-document-view
+                                               displayCondition = canBeViewed != 0
+                                               callbackAction = viewPage
+                                       }
 
-                               400 = ITEM
-                               400 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.enablePage
-                                       spriteIcon = actions-edit-unhide
-                                       displayCondition = getRecord|hidden = 1 && canBeDisabledAndEnabled != 0
-                                       callbackAction = enablePage
-                               }
+                                       200 = ITEM
+                                       200 {
+                                               name = new
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.newPage
+                                               spriteIcon = actions-document-new
+                                               displayCondition = canCreateNewPages != 0
+                                               callbackAction = newPageWizard
+                                       }
 
-                               500 = ITEM
-                               500 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.editPageProperties
-                                       spriteIcon = actions-document-open
-                                       displayCondition = canBeEdited != 0
-                                       callbackAction = editPageProperties
-                               }
+                                       300 = DIVIDER
 
-                               600 = ITEM
-                               600 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.info
-                                       spriteIcon = actions-document-info
-                                       displayCondition = canShowInfo != 0
-                                       callbackAction = openInfoPopUp
-                               }
+                                       400 = ITEM
+                                       400 {
+                                               name = history
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.history
+                                               spriteIcon = actions-document-history-open
+                                               displayCondition = canShowHistory != 0
+                                               callbackAction = openHistoryPopUp
+                                       }
 
-                               700 = ITEM
-                               700 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.history
-                                       spriteIcon = actions-document-history-open
-                                       displayCondition = canShowHistory != 0
-                                       callbackAction = openHistoryPopUp
+                                       ' . $importExportActions . '
                                }
+                       }
 
-                               800 = DIVIDER
-
-                               900 = SUBMENU
-                               900 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPasteActions
+                       pages {
+                               disableItems =
 
+                               items {
                                        100 = ITEM
                                        100 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.newPage
-                                               spriteIcon = actions-document-new
-                                               displayCondition = canCreateNewPages != 0
-                                               callbackAction = newPageWizard
+                                               name = view
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.viewPage
+                                               spriteIcon = actions-document-view
+                                               displayCondition = canBeViewed != 0
+                                               callbackAction = viewPage
                                        }
 
                                        200 = DIVIDER
 
                                        300 = ITEM
                                        300 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
-                                               spriteIcon = actions-edit-cut
-                                               displayCondition = isInCutMode = 0 && canBeCut != 0
-                                               callbackAction = enableCutMode
+                                               name = disable
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.disablePage
+                                               spriteIcon = actions-edit-hide
+                                               displayCondition = getRecord|hidden = 0 && canBeDisabledAndEnabled != 0
+                                               callbackAction = disablePage
                                        }
 
                                        400 = ITEM
                                        400 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
-                                               spriteIcon = actions-edit-cut-release
-                                               displayCondition = isInCutMode = 1 && canBeCut != 0
-                                               callbackAction = disableCutMode
+                                               name = enable
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.enablePage
+                                               spriteIcon = actions-edit-unhide
+                                               displayCondition = getRecord|hidden = 1 && canBeDisabledAndEnabled != 0
+                                               callbackAction = enablePage
                                        }
 
                                        500 = ITEM
                                        500 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
-                                               spriteIcon = actions-edit-copy
-                                               displayCondition = isInCopyMode = 0 && canBeCopied != 0
-                                               callbackAction = enableCopyMode
+                                               name = edit
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.editPageProperties
+                                               spriteIcon = actions-document-open
+                                               displayCondition = canBeEdited != 0
+                                               callbackAction = editPageProperties
                                        }
 
                                        600 = ITEM
                                        600 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
-                                               spriteIcon = actions-edit-copy-release
-                                               displayCondition = isInCopyMode = 1 && canBeCopied != 0
-                                               callbackAction = disableCopyMode
+                                               name = info
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.info
+                                               spriteIcon = actions-document-info
+                                               displayCondition = canShowInfo != 0
+                                               callbackAction = openInfoPopUp
                                        }
 
                                        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
+                                               name = history
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.history
+                                               spriteIcon = actions-document-history-open
+                                               displayCondition = canShowHistory != 0
+                                               callbackAction = openHistoryPopUp
                                        }
 
-                                       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
+                                       800 = DIVIDER
+
+                                       900 = SUBMENU
+                                       900 {
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPasteActions
+
+                                               100 = ITEM
+                                               100 {
+                                                       name = new
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.newPage
+                                                       spriteIcon = actions-document-new
+                                                       displayCondition = canCreateNewPages != 0
+                                                       callbackAction = newPageWizard
+                                               }
+
+                                               200 = DIVIDER
+
+                                               300 = ITEM
+                                               300 {
+                                                       name = cut
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
+                                                       spriteIcon = actions-edit-cut
+                                                       displayCondition = isInCutMode = 0 && canBeCut != 0
+                                                       callbackAction = enableCutMode
+                                               }
+
+                                               400 = ITEM
+                                               400 {
+                                                       name = cut
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
+                                                       spriteIcon = actions-edit-cut-release
+                                                       displayCondition = isInCutMode = 1 && canBeCut != 0
+                                                       callbackAction = disableCutMode
+                                               }
+
+                                               500 = ITEM
+                                               500 {
+                                                       name = copy
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
+                                                       spriteIcon = actions-edit-copy
+                                                       displayCondition = isInCopyMode = 0 && canBeCopied != 0
+                                                       callbackAction = enableCopyMode
+                                               }
+
+                                               600 = ITEM
+                                               600 {
+                                                       name = copy
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
+                                                       spriteIcon = actions-edit-copy-release
+                                                       displayCondition = isInCopyMode = 1 && canBeCopied != 0
+                                                       callbackAction = disableCopyMode
+                                               }
+
+                                               700 = ITEM
+                                               700 {
+                                                       name = pasteInto
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoPage
+                                                       spriteIcon = actions-document-paste-after
+                                                       displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1 && canBePastedInto != 0
+                                                       callbackAction = pasteIntoNode
+                                               }
+
+                                               800 = ITEM
+                                               800 {
+                                                       name = pasteAfter
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteAfterPage
+                                                       spriteIcon = actions-document-paste-into
+                                                       displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1 && canBePastedAfter != 0
+                                                       callbackAction = pasteAfterNode
+                                               }
+
+                                               900 = DIVIDER
+
+                                               1000 = ITEM
+                                               1000 {
+                                                       name = delete
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.deletePage
+                                                       spriteIcon = actions-edit-delete
+                                                       displayCondition = canBeRemoved != 0
+                                                       callbackAction = removeNode
+                                               }
                                        }
 
-                                       900 = DIVIDER
-
-                                       1000 = ITEM
+                                       1000 = SUBMENU
                                        1000 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.deletePage
-                                               spriteIcon = actions-edit-delete
-                                               displayCondition = canBeRemoved != 0
-                                               callbackAction = removeNode
-                                       }
-                               }
-
-                               1000 = SUBMENU
-                               1000 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.branchActions
-
-                                       100 = ITEM
-                                       100 {
-                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.tempMountPoint
-                                               spriteIcon = actions-system-extension-documentation
-                                               displayCondition = canBeTemporaryMountPoint != 0
-                                               callbackAction = stub
+                                               label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.branchActions
+
+                                               100 = ITEM
+                                               100 {
+                                                       name = mountAsTreeroot
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.tempMountPoint
+                                                       spriteIcon = actions-system-extension-documentation
+                                                       displayCondition = canBeTemporaryMountPoint != 0
+                                                       callbackAction = mountAsTreeRoot
+                                               }
+
+                                               200 = DIVIDER
+
+                                               300 = ITEM
+                                               300 {
+                                                       name = expandBranch
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.expandBranch
+                                                       displayCondition =
+                                                       callbackAction = expandBranch
+                                               }
+
+                                               400 = ITEM
+                                               400 {
+                                                       name = collapseBranch
+                                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.collapseBranch
+                                                       displayCondition =
+                                                       callbackAction = collapseBranch
+                                               }
+
+                                               ' . $importExportActions . '
                                        }
                                }
                        }
                }
-
-               files {
-                       items {
-                               100 = ITEM
-                               100 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.renameFolder
-                                       spriteIcon = actions-edit-rename
-                                       callbackAction = renameFolder
-                               }
-
-                               200 = ITEM
-                               200 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.uploadFilesToFolder
-                                       spriteIcon = actions-edit-upload
-                                       callbackAction = uploadFilesToFolder
-                               }
-
-                               300 = ITEM
-                               300 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.createFolder
-                                       spriteIcon = actions-edit-add
-                                       callbackAction = createFolder
-                               }
-
-                               400 = ITEM
-                               400 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.folderInfo
-                                       spriteIcon = actions-document-info
-                                       callbackAction = openInfoPopUp
-                               }
-
-                               500 = DIVIDER
-
-                               600 = ITEM
-                               600 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyFolder
-                                       spriteIcon = actions-edit-copy
-                                       callbackAction = copyFolder
-                               }
-
-                               700 = ITEM
-                               700 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutFolder
-                                       spriteIcon = actions-edit-cut
-                                       callbackAction = cutFolder
-                               }
-
-                               800 = ITEM
-                               800 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoFolder
-                                       spriteIcon = actions-document-paste-after
-                                       callbackAction = pasteIntoFolder
-                               }
-
-                               900 = DIVIDER
-
-                               1000 = ITEM
-                               1000 {
-                                       label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.deleteFolder
-                                       spriteIcon = actions-edit-delete
-                                       callbackAction = deleteFolder
-                               }
-                       }
-               }
        }
 ';
 
index 0d2b94e..b159697 100644 (file)
@@ -6,7 +6,7 @@ if (!defined('TYPO3_MODE')) {
 if (TYPO3_MODE === 'BE') {
        $modules = array(
                'web_layout', 'web_view', 'web_list', 'web_info', 'web_perm', 'web_func', 'web_ts',
-               'web_WorkspacesWorkspaces', 'web_txrecyclerM1', 'web_txversionM1'
+               'web_txrecyclerM1', 'web_txversionM1'
        );
        foreach ($modules as $module) {
                t3lib_extMgm::addNavigationComponent($module, 'typo3-pagetree', array(
@@ -27,4 +27,4 @@ if (TYPO3_MODE === 'BE') {
        );
 }
 
-?>
\ No newline at end of file
+?>
index 6c87d29..58fed04 100644 (file)
                        <label index="cm.tempMountPoint">Mount as treeroot</label>
                        <label index="cm.branchActions">Branch Actions</label>
                        <label index="cm.copyPasteActions">Page Actions</label>
-                       
-                       <label index="cm.renameFolder">Rename</label>
-                       <label index="cm.uploadFilesToFolder">Upload Files</label>
-                       <label index="cm.createFolder">Create New Folder</label>
-                       <label index="cm.folderInfo">Folder Info</label>
-                       <label index="cm.copyFolder">Copy</label>
-                       <label index="cm.cutFolder">Cut</label>
-                       <label index="cm.pasteIntoFolder">Paste</label>
-                       <label index="cm.deleteFolder">Delete</label>
+                       <label index="cm.exportT3d">Export to .t3d</label>
+                       <label index="cm.importT3d">Import from .t3d</label>
+                       <label index="cm.collapseBranch">Collapse Branch</label>
+                       <label index="cm.expandBranch">Expand Branch</label>
                </languageKey>
        </data>
 </T3locallang>
index 52b5f4e..d3e22c5 100644 (file)
                        <label index="page.doktype.199">Spacer</label>
                        <label index="page.doktype.254">Sysfolder</label>
                        <label index="defaultTitle">[Default Title]</label>
+                       <label index="copyHint">Press Ctrl to copy.</label>
+                       <label index="fakeNodeHint">Please Wait...</label>
+                       <label index="activeFilterMode">Active Filtering Mode</label>
+                       <label index="dropToRemove">Drop here to delete</label>
+                       <label index="dropZoneElementRemoved">Click here to undelete</label>
+                       <label index="dropZoneElementRestored">Page restored</label>
+                       <label index="treeStructure">Tree structure of the website</label>
                </languageKey>
        </data>
 </T3locallang>