Merge of extension manager for 4.5.0 - see ChangeLog in em for details
authorsteffenk <steffenk@709f56b5-9817-0410-a4d7-c38de5d9e867>
Wed, 23 Feb 2011 13:22:07 +0000 (13:22 +0000)
committersteffenk <steffenk@709f56b5-9817-0410-a4d7-c38de5d9e867>
Wed, 23 Feb 2011 13:22:07 +0000 (13:22 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@10595 709f56b5-9817-0410-a4d7-c38de5d9e867

27 files changed:
ChangeLog
typo3/sysext/em/ChangeLog
typo3/sysext/em/classes/class.tx_em_extensionmanager.php
typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php
typo3/sysext/em/classes/extensions/class.tx_em_extensions_list.php
typo3/sysext/em/classes/index.php
typo3/sysext/em/classes/settings/class.tx_em_settings.php
typo3/sysext/em/classes/tools/class.tx_em_tools.php
typo3/sysext/em/ext_autoload.php
typo3/sysext/em/ext_emconf.php
typo3/sysext/em/language/locallang.xml
typo3/sysext/em/res/css/editor.css
typo3/sysext/em/res/css/t3_em.css
typo3/sysext/em/res/js/em_app.js
typo3/sysext/em/res/js/em_components.js
typo3/sysext/em/res/js/em_files.js
typo3/sysext/em/res/js/em_languages.js
typo3/sysext/em/res/js/em_locallist.js
typo3/sysext/em/res/js/em_repositorylist.js
typo3/sysext/em/res/js/em_settings.js
typo3/sysext/em/res/js/ux/RowPanelExpander.js
typo3/sysext/em/res/js/ux/filter/Filter.js
typo3/sysext/em/res/js/ux/filter/ListFilter.js
typo3/sysext/em/res/js/ux/filter/NumericFilter.js
typo3/sysext/em/res/js/ux/filter/StringFilter.js
typo3/sysext/em/res/js/ux/menu/ListMenu.js
typo3/sysext/em/res/js/ux/menu/RangeMenu.js

index 48d5564..3c7304b 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
 
 2011-02-23  Steffen Kamper  <steffen@typo3.org>
 
+       * Merge of extension manager for 4.5.0 - see ChangeLog in em for details
        * Fixed bug #17520: Pagetree - Locked records are not indicated anymore (Thanks to Stefan Galinski)
        * Fixed bug #17702: Directly open "inline edit" of page title after creating a new page with drag and drop in the pagetree (Thanks to Stefan Galinski)
 
index 617b84d..c20d665 100644 (file)
@@ -1,4 +1,45 @@
-2011-02-07  Steffen Kamper  <steffen@typo3.org>
+2011-02-23  Steffen Kamper  <steffen@typo3.org>
+
+       * cleaned em_conf
+       * corrected initial settings with no saved extension configuration
+       * file editor - disable functions until they are proofed completely
+
+2011-02-20  Steffen Kamper  <steffen@typo3.org>
+
+       * move interface to correct place
+
+2011-02-19  Steffen Kamper  <steffen@typo3.org>
+
+       * Fixed file creation / node creation
+       * Fixed bug #13180 Hardcoded Labels for Extension State and in menu "Filters"
+       * Fixed bug #13183 Saving Settings uses hardcoded labels
+       * Fixed bug #13179 Order in "Udate EM_CONF" is not ideal
+       * Fixed bug #13181 Unreplaced variable in headline when editing a repository
+       * Fixed bug #13182 Updating a repository gives wrong flash message
+       * Fixed bug #13178 GUI partly hidden with 1024x768 pixels and less
+       * Fixed bug #13177 Button "Refresh" in Extension > Details > Files misses tooltip
+       * Many fixes for FileEditor
+       * Use interface for renderHook
+       * Fixed bug #13164 EM GUI does not use translations
+
+2011-02-11  Steffen Kamper  <steffen@typo3.org>
+
+       * Fixed file saving, file diff, prepared file creation/moveing
+
+2011-02-10  Steffen Kamper  <steffen@typo3.org>
+
+       * Fixed bug #17538: EM gets instantiated before XCLASS definition (Thanks to Jesper Paardekooper)
+
+2011-02-09  Steffen Kamper  <steffen@typo3.org>
+
+       * Prompt for save with new file load
+       * Small fixes for init configuration in fileeditor
+       * Prevent file actions before a file is loaded
+       * Simplified codemirror configuration
+       * Use mixed parser for php files for correct parsing
+       * Fixed change of parser in file editor
+
+2011-02-08  Steffen Kamper  <steffen@typo3.org>
 
        * CGL spaces=>tabs, raised ext version to 4.5.1, cleaned em_conf
        * fix docPath in link generation for documentation
index 2078529..4543e74 100644 (file)
@@ -140,16 +140,18 @@ class tx_em_ExtensionManager {
 
 
                        // Localization
-               $labels = tx_em_Tools::getArrayFromLocallang(t3lib_extMgm::extPath('em', 'language/locallang.xml'));
+               $labels = array();
+               $this->pageRenderer->addInlineLanguageLabelFile(t3lib_extMgm::extPath('em', 'language/locallang.xml'));
                $labels['yes'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
                $labels['no'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
-
+               $this->pageRenderer->addInlineLanguageLabelArray($labels);
 
                $globalSettings = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['em']);
-               if (!isset($globalSettings)) {
+               if (!is_array($globalSettings)) {
                        $globalSettings = array(
                                'displayMyExtensions' => 0,
-                               'selectedLanguages' => array()
+                               'selectedLanguages' => array(),
+                               'inlineToWindow' => 1,
                        );
                }
                $settings = $this->parentObject->MOD_SETTINGS;
@@ -166,6 +168,15 @@ class tx_em_ExtensionManager {
 
                $allowRepositoryUpdate = !intval($GLOBALS['BE_USER']->getTSConfigVal('mod.tools_em.hideRepositoryUpdate'));
 
+               /* file operations */
+               $fileAllowMove = intval($GLOBALS['BE_USER']->getTSConfigVal('mod.tools_em.fileAllowMove'));
+               $fileAllowDelete = intval($GLOBALS['BE_USER']->getTSConfigVal('mod.tools_em.fileAllowDelete'));
+               $fileAllowRename = intval($GLOBALS['BE_USER']->getTSConfigVal('mod.tools_em.fileAllowRename'));
+               $fileAllowUpload = intval($GLOBALS['BE_USER']->getTSConfigVal('mod.tools_em.fileAllowUpload'));
+               $fileAllowCreate = intval($GLOBALS['BE_USER']->getTSConfigVal('mod.tools_em.fileAllowCreate'));
+               $fileAllowDownload = intval($GLOBALS['BE_USER']->getTSConfigVal('mod.tools_em.fileAllowDownload'));
+
+
                        // add the settings
                $additionalSettings = array(
                        'siteUrl' => t3lib_div::getIndpEnv('TYPO3_SITE_URL'),
@@ -181,8 +192,16 @@ class tx_em_ExtensionManager {
                        'inlineToWindow' => $globalSettings['inlineToWindow'],
                        'allowRepositoryUpdate' => $allowRepositoryUpdate,
                        'displayMyExtensions' => $globalSettings['displayMyExtensions'],
-                       'fileSaveAllowed' => $GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit'] == 0,
                        'debug' => $GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] > 0,
+                       //TODO: some are disabled until feater-proofed
+                       'fileAllowSave' => $GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit'] == 0,
+                       'fileAllowMove' => 0, //$fileAllowMove,
+                       'fileAllowDelete' => 0, //$fileAllowDelete,
+                       'fileAllowRename' => 0, //$fileAllowRename,
+                       'fileAllowUpload' => 0, //$fileAllowUpload,
+                       'fileAllowCreate' => 0, //$fileAllowCreate,
+                       'fileAllowDownload' => $fileAllowDownload,
+
                );
                $settings = array_merge($settings, $additionalSettings);
 
@@ -195,6 +214,7 @@ class tx_em_ExtensionManager {
                $this->pageRenderer->addJsFile($this->resPath . 'js/overrides/ext_overrides.js');
                $this->pageRenderer->addJsFile($this->resPath . 'js/ux/custom_plugins.js');
                $this->pageRenderer->addJsFile($this->parentObject->doc->backPath . '../t3lib/js/extjs/ux/Ext.ux.FitToParent.js');
+               $this->pageRenderer->addJsFile($this->parentObject->doc->backPath . '../t3lib/js/extjs/notifications.js');
                $this->pageRenderer->addJsFile($this->resPath . 'js/ux/TreeState.js');
                $this->pageRenderer->addJsFile($this->resPath . 'js/ux/RowPanelExpander.js');
                $this->pageRenderer->addJsFile($this->resPath . 'js/ux/searchfield.js');
@@ -239,12 +259,13 @@ class tx_em_ExtensionManager {
                        //hook for the extension manager gui
                if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['em/classes/class.tx_em_extensionamager.php']['renderHook'])) {
                        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['em/classes/class.tx_em_extensionamager.php']['renderHook'] as $classRef) {
-                               $hookObj = t3lib_div::getUserObj($classRef);
-                               if (method_exists($hookObj, 'render')) {
-                                       $hookObj->render(
-                                               $this->pageRenderer, $settings, $labels, $content
-                                       );
+                               $hookObject = t3lib_div::getUserObj($classRef);
+                               if(!($hookObject instanceof tx_em_renderHook)) {
+                                       throw new UnexpectedValueException('$hookObject must implement interface tx_em_renderHook', 1298121373);
                                }
+                               $hookObject->render(
+                                       $this->pageRenderer, $settings, $content
+                               );
                        }
                }
 
@@ -278,4 +299,4 @@ if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLA
        include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/class.tx_em_extensionsmanager.php']);
 }
 
-?>
+?>
\ No newline at end of file
index 1921ec0..0224f6a 100644 (file)
@@ -145,9 +145,7 @@ class tx_em_Connection_ExtDirectServer {
                $list = $this->getExtensionList();
                $extList = $list['data'];
 
-               $temp = $this->getSettings();
-               $selectedLanguages = unserialize($temp['selectedLanguages']);
-
+               $selectedLanguages = t3lib_div::trimExplode(',', $this->globalSettings['selectedLanguages']);
 
                $keys = array();
                $i = 0;
@@ -375,19 +373,16 @@ class tx_em_Connection_ExtDirectServer {
         * @return array
         */
        public function getExtFileTree($parameter) {
-               $ext = array();
-               $extKey = $parameter->extkey;
                $type = $parameter->typeShort;
                $node = substr($parameter->node, 0, 6) !== 'xnode-' ? $parameter->node : $parameter->baseNode;
 
                $path = PATH_site . $node;
                $fileArray = array();
-//debug($node)
+
                $dirs = t3lib_div::get_dirs($path);
                $files = t3lib_div::getFilesInDir($path, '', FALSE, '', '');
 
-               $editTypes = explode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext']);
-               $imageTypes = array('gif', 'jpg', 'png');
+
 
                if (!is_array($dirs) && !is_array($files)) {
                        return array();
@@ -404,53 +399,25 @@ class tx_em_Connection_ExtDirectServer {
                        }
                }
 
-               $unknownType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_unknownType');
-               $imageType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_imageType');
-               $textType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_textType');
-               $extType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_extType');
-               foreach ($files as $key => $file) {
-                       $fileExt = '';
-                       $type = '';
-                       $cls = t3lib_iconWorks::mapFileExtensionToSpriteIconClass('');
-                       if (strrpos($file, '.') !== FALSE) {
-                               $fileExt = strtolower(substr($file, strrpos($file, '.') + 1));
-                       }
-
-                       if ($fileExt && in_array($fileExt, $imageTypes) || in_array($fileExt, $editTypes)) {
-                               $cls = t3lib_iconWorks::mapFileExtensionToSpriteIconClass($fileExt);
-                               $type = in_array($fileExt, $imageTypes) ? 'image' : 'text';
-                       }
-
-                       if (t3lib_div::strtolower($file) === 'changelog') {
-                               $cls = t3lib_iconWorks::mapFileExtensionToSpriteIconClass('txt');
-                               $type = 'text';
-                       }
 
-                       switch($type) {
-                               CASE 'image':
-                                       $label = $imageType;
-                               break;
-                               CASE 'text':
-                                       $label = $textType;
-                               break;
-                               default:
-                                       $label = $fileExt ? sprintf($extType, $fileExt) : $unknownType;
-                       }
+               foreach ($files as $key => $file) {
+                       $fileInfo = $this->getFileInfo($file);
 
                        $fileArray[] = array(
                                'id' => $node . '/' . $file,
-                               'text' => htmlspecialchars($file),
+                               'text' => $fileInfo[0],
                                'leaf' => true,
-                               'qtip' => $label,
-                               'iconCls' => $cls,
-                               'fileType' => $type,
-                               'ext' => $fileExt
+                               'qtip' => $fileInfo[1],
+                               'iconCls' => $fileInfo[4],
+                               'fileType' => $fileInfo[3],
+                               'ext' => $fileInfo[2]
                        );
                }
 
                return $fileArray;
        }
 
+
        /**
         * Read extension file and send content
         *
@@ -503,6 +470,128 @@ class tx_em_Connection_ExtDirectServer {
                );
        }
 
+       /**
+        * Create a new file
+        *
+        * @param  string $folder
+        * @param  string $file
+        * @param  boolean $isFolder
+        * @return array result
+        */
+       public function createNewFile($folder, $file, $isFolder) {
+               $result = tx_em_Tools::createNewFile($folder, $file, $isFolder);
+
+               $node = array();
+
+               if ($result[0] === TRUE) {
+                       if ($isFolder) {
+                               $node = array(
+                                       'id' => htmlspecialchars(substr($result[1], strlen(PATH_site))),
+                                       'text' => htmlspecialchars(basename($result[1])),
+                                       'leaf' => FALSE,
+                                       'qtip' => ''
+                               );
+                       } else {
+                               $fileInfo = $this->getFileInfo($result[1]);
+                               $node = array(
+                                       'id' => substr($fileInfo[0], strlen(PATH_site)),
+                                       'text' => basename($fileInfo[0]),
+                                       'leaf' => !$isFolder,
+                                       'qtip' => $fileInfo[1],
+                                       'iconCls' => $fileInfo[4],
+                                       'fileType' => $fileInfo[3],
+                                       'ext' => $fileInfo[2]
+                               );
+                       }
+               }
+               return array(
+                       'success' => $result[0],
+                       'created' => $result[1],
+                       'node' => $node,
+                       'error' => $result[2]
+               );
+       }
+
+       /**
+        * Rename a file/folder
+        *
+        * @param  string $file
+        * @param  string $newName
+        * @param  boolean $isFolder
+        * @return array result
+        */
+       public function renameFile($file, $newName, $isFolder) {
+               $src = basename($file);
+               $newFile = substr($file, 0, -1 * strlen($src)) . $newName;
+
+               $success = tx_em_Tools::renameFile($file, $newFile);
+
+               return array(
+                       'success' => $success,
+                       'oldFile' => $file,
+                       'newFile' => $newFile,
+                       'newFilename' => basename($newFile),
+               );
+       }
+
+
+       /**
+        * Moves a file to new destination
+        *
+        * @param  string $file
+        * @param  string $destination
+        * @param  boolean $isFolder
+        * @return array
+        */
+       public function moveFile($file, $destination, $isFolder) {
+               return array(
+                       'success' => TRUE,
+                       'file' => $file,
+                       'destination' => $destination,
+                       'isFolder' => $isFolder
+               );
+       }
+
+       /**
+        * Deletes a file/folder
+        *
+        * @param  string $file
+        * @param  boolean $isFolder
+        * @return array
+        */
+       public function deleteFile($file, $isFolder) {
+
+               $file = str_replace('//', '/', PATH_site . $file);
+               $command['delete'][] = array(
+                       'data' => $file
+               );
+               $result = $this->fileOperation($command);
+
+               return array(
+                       'success' => TRUE,
+                       'file' => $file,
+                       'isFolder' => $isFolder,
+                       'command' => $command,
+                       'result' => $result
+               );
+       }
+
+       /**
+        * Shows a diff of content changes of a file
+        *
+        * @param  string $file
+        * @param  string $content
+        * @return array
+        */
+       public function makeDiff($original, $content) {
+               $diff = t3lib_div::makeInstance('t3lib_diff');
+               $result = $diff->makeDiffDisplay($original, $content);
+               //debug(array($original, $content, $result));
+               return array(
+                       'success' => TRUE,
+                       'diff' => '<pre>' . $result . '</pre>'
+               );
+       }
 
        /**
         * Load upload form for extension upload to TER
@@ -667,24 +756,16 @@ class tx_em_Connection_ExtDirectServer {
                                        $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_update_em_conf') . '</td></tr>';
 
 
-                       $lines[] = '<tr class="bgColor4"><td colspan="2">' .
-                       $sure = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extUpdateEMCONF_sure');
                        $updateEMConf = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extUpdateEMCONF_file');
-
-                       $onClick = "if (confirm('$sure')) {window.location.href='" . t3lib_div::linkThisScript(array(
-                               'CMD[showExt]' => $extKey,
-                               'CMD[doUpdateEMCONF]' => 1
-                       )) . "';}";
-
                        $lines[] = '<tr class="bgColor4"><td colspan="2">' .
-                                       '<a class="t3-link emconfLink" href="#" onclick="' . htmlspecialchars($onClick) .
-                                       ' return false;"><strong>' . $updateEMConf . '</strong> ' .
+                                       $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extUpdateEMCONF_info_changes') . '<br />
+                                               ' . $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extUpdateEMCONF_info_reset') .
+                                       '<br /><br />' .
+                                       '<a class="t3-link emconfLink" href="#"><strong>' . $updateEMConf . '</strong> ' .
                                        sprintf($GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extDelete_from_location'),
                                                $api->typeLabels[$list[$extKey]['type']],
                                                substr(tx_em_Tools::getExtPath($extKey, $list[$extKey]['type']['type']), strlen(PATH_site))
                                        ) . '</a>'
-                                       .  '<br /><br />' . $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extUpdateEMCONF_info_changes') . '<br />
-                                               ' . $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extUpdateEMCONF_info_reset')
                                        . '</td></tr>';
 
 
@@ -1438,6 +1519,96 @@ class tx_em_Connection_ExtDirectServer {
                return $selectedRepository;
        }
 
+       /**
+        * Gets file info for ExtJs tree node
+        *
+        * @param  $file
+        * @return array
+        */
+       protected function getFileInfo($file) {
+               $unknownType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_unknownType');
+               $imageType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_imageType');
+               $textType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_textType');
+               $extType = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_file_extType');
+
+               $editTypes = explode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext']);
+               $imageTypes = array('gif', 'jpg', 'png');
+
+               $fileExt = '';
+               $type = '';
+               $cls = t3lib_iconWorks::mapFileExtensionToSpriteIconClass('');
+               if (strrpos($file, '.') !== FALSE) {
+                       $fileExt = strtolower(substr($file, strrpos($file, '.') + 1));
+               }
+
+               if ($fileExt && in_array($fileExt, $imageTypes) || in_array($fileExt, $editTypes)) {
+                       $cls = t3lib_iconWorks::mapFileExtensionToSpriteIconClass($fileExt);
+                       $type = in_array($fileExt, $imageTypes) ? 'image' : 'text';
+               }
+
+               if (t3lib_div::strtolower($file) === 'changelog') {
+                       $cls = t3lib_iconWorks::mapFileExtensionToSpriteIconClass('txt');
+                       $type = 'text';
+               }
+
+               switch($type) {
+                       CASE 'image':
+                               $label = $imageType;
+                       break;
+                       CASE 'text':
+                               $label = $textType;
+                       break;
+                       default:
+                               $label = $fileExt ? sprintf($extType, $fileExt) : $unknownType;
+               }
+
+               return array(
+                       htmlspecialchars($file),
+                       $label,
+                       htmlspecialchars($fileExt),
+                       $type,
+                       $cls
+               );
+
+       }
+
+
+       /**
+        * File operations like delete, copy, move
+        * @param  $file commandMap, @see
+        * @return
+        */
+       protected function fileOperation($file) {
+               $mount = array(0 => array(
+                       'name' => 'root',
+                       'path' => PATH_site,
+                       'type' => ''
+               ));
+               $files = array(0 => array(
+                       'webspace' => array('allow' => '*', 'deny' => ''),
+                       'ftpspace' => array('allow' => '*', 'deny' => '')
+               ));
+               $fileProcessor = t3lib_div::makeInstance('t3lib_extFileFunctions');
+               $fileProcessor->init($mount, $files);
+               $fileProcessor->init_actionPerms($GLOBALS['BE_USER']->getFileoperationPermissions());
+               $fileProcessor->dontCheckForUnique = 0;
+
+                       // Checking referer / executing:
+               $refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
+               $httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
+               if ($httpHost != $refInfo['host']
+                       && $this->vC != $GLOBALS['BE_USER']->veriCode()
+                       && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']
+                       && $GLOBALS['CLIENT']['BROWSER'] != 'flash') {
+                       $fileProcessor->writeLog(0, 2, 1, 'Referer host "%s" and server host "%s" did not match!', array($refInfo['host'], $httpHost));
+               } else {
+                       $fileProcessor->start($file);
+                       $fileData = $fileProcessor->processData();
+               }
+
+               return $fileData;
+       }
+
 }
 
 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/connection/class.tx_em_connectionextdirectserver.php'])) {
index eb58ce9..4b4103c 100644 (file)
@@ -197,6 +197,8 @@ class tx_em_Extensions_List {
                                $key = count($list);
                                $loaded = t3lib_extMgm::isLoaded($extKey);
 
+
+
                                $exist = $this->findIndex($extKey, $list);
                                if ($exist !== FALSE) {
                                        $key = $exist;
@@ -212,6 +214,8 @@ class tx_em_Extensions_List {
                                $list[$key]['doubleInstall'] = $list[$key]['doubleInstall'] ? $list[$key]['doubleInstall'] . '/' . $this->types[$type] : $this->types[$type];
                                $list[$key]['doubleInstallShort'] .= $type;
 
+                               $list[$key] = t3lib_div::array_merge_recursive_overrule($list[$key], $emConf);
+
                                if (@is_file($path . $extKey . '/class.ext_update.php')) {
                                        $list[$key]['updateModule'] = TRUE;
                                } else {
@@ -220,9 +224,11 @@ class tx_em_Extensions_List {
                                $list[$key]['type'] = $this->types[$type];
                                $list[$key]['typeShort'] = $type;
                                $list[$key]['installed'] = $loaded ? 1 : 0;
-                               // FIXME: raises PHP warning
-                               // "Core: Error handler (BE): PHP Warning: htmlspecialchars() expects parameter 1 to be string, array given in [...]/typo3/mod/tools/em/classes/class.tx_em_extensions_list.php line 185
-                               $list[$key] = t3lib_div::array_merge_recursive_overrule($list[$key], $emConf);
+
+
+                               $state = htmlspecialchars($emConf['state']);
+                               $list[$key]['state'] = $this->states[$state];
+                               $list[$key]['stateCls'] = 'state-' . $state;
                                $list[$key]['title'] = htmlspecialchars($list[$key]['title']);
                                $list[$key]['description'] = htmlspecialchars($list[$key]['description']);
                                $list[$key]['author'] = htmlspecialchars($list[$key]['author']);
@@ -249,7 +255,7 @@ class tx_em_Extensions_List {
 
                                $list[$key]['categoryShort'] = $list[$key]['category'];
                                $list[$key]['category'] = isset($this->categories[$list[$key]['category']]) ? $this->categories[$list[$key]['category']] : $list[$key]['category'];
-                               $list[$key]['required'] = t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['EXT']['requiredExt'], $extKey);
+                               $list[$key]['required'] = t3lib_div::inList(t3lib_extMgm::getRequiredExtensionList(), $extKey);
 
                                $constraints = $this->humanizeConstraints($list[$key]['constraints']);
                                $list[$key]['depends'] = $constraints['depends'];
@@ -932,7 +938,7 @@ EXTENSION KEYS:
         * @see removeExtFromList(), addExtToList()
         */
        function removeRequiredExtFromListArr($listArr) {
-               $requiredExtensions = t3lib_div::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXT']['requiredExt'], 1);
+               $requiredExtensions = t3lib_div::trimExplode(',', t3lib_extMgm::getRequiredExtensionList(), 1);
                foreach ($listArr as $k => $ext) {
                        if (in_array($ext, $requiredExtensions) || !strcmp($ext, '_CACHEFILE')) {
                                unset($listArr[$k]);
index e3b600f..030489a 100644 (file)
@@ -266,7 +266,7 @@ class SC_mod_tools_em_index extends t3lib_SCbase {
 
                // Setting internal static:
 
-               $this->requiredExt = t3lib_div::trimExplode(',', $TYPO3_CONF_VARS['EXT']['requiredExt'], 1);
+               $this->requiredExt = t3lib_div::trimExplode(',', t3lib_extMgm::getRequiredExtensionList(), TRUE);
 
                // Initialize Document Template object:
                $this->doc = t3lib_div::makeInstance('template');
@@ -366,7 +366,7 @@ class SC_mod_tools_em_index extends t3lib_SCbase {
                $this->MOD_MENU = $this->settings->MOD_MENU;
                $globalSettings = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['em']);
 
-               if (!isset($globalSettings['showOldModules'])) {
+               if (!is_array($globalSettings)) {
                                // no settings saved yet, set default values
                        $globalSettings['showOldModules'] = 1;
                        $globalSettings['inlineToWindow'] = 1;
@@ -2197,14 +2197,14 @@ class SC_mod_tools_em_index extends t3lib_SCbase {
                                'CMD[showExt]' => $extKey,
                                'CMD[doUpdateEMCONF]' => 1
                        )) . "';}";
+                       $content .= $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_changes') . '<br />'
+                               . $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_reset') . '<br /><br />';
                        $content .= '<a class="t3-link" href="#" onclick="' . htmlspecialchars($onClick) .
                                        ' return false;"><strong>' . $updateEMConf . '</strong> ' .
                                        sprintf($GLOBALS['LANG']->getLL('extDelete_from_location'),
                                                $this->typeLabels[$extInfo['type']],
                                                substr($absPath, strlen(PATH_site))
                                        ) . '</a>';
-                       $content .= '<br /><br />' . $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_changes') . '<br />
-                                               ' . $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_reset');
                        return $content;
                }
        }
@@ -2222,7 +2222,6 @@ class SC_mod_tools_em_index extends t3lib_SCbase {
                        $backUpData = $this->terConnection->makeUploadDataFromarray($uArr);
                        $filename = 'T3X_' . $extKey . '-' . str_replace('.', '_', $extInfo['EM_CONF']['version']) . '-z-' . date('YmdHi') . '.t3x';
                        if (intval($this->CMD['doBackup']) == 1) {
-                               t3lib_div::cleanOutputBuffers();
                                header('Content-Type: application/octet-stream');
                                header('Content-Disposition: attachment; filename=' . $filename);
                                echo $backUpData;
@@ -2568,6 +2567,16 @@ class SC_mod_tools_em_index extends t3lib_SCbase {
        }
 }
 
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']) {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']);
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/index.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/index.php']);
+}
+
+
 // Make instance:
 $SOBE = t3lib_div::makeInstance('SC_mod_tools_em_index');
 $SOBE->init();
@@ -2579,11 +2588,4 @@ $SOBE->checkExtObj();
 $SOBE->main();
 $SOBE->printContent();
 
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']) {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']);
-}
-
-if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/index.php'])) {
-       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/index.php']);
-}
 ?>
\ No newline at end of file
index 66616a8..e73fb00 100644 (file)
@@ -42,12 +42,13 @@ class tx_em_Settings implements t3lib_Singleton {
 
 
        /**
-        * Develop commands
+        * Settings array
         *
-        * @var string
+        * @var array
         */
        protected $settings;
 
+
        /**
         * Constructor
         *
@@ -97,6 +98,7 @@ class tx_em_Settings implements t3lib_Singleton {
         * @return void
         */
        protected function readSettings() {
+               $globalSettings = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['em']);
                $this->MOD_MENU = array(
                        'function' => array(
                                'loaded_list' => $GLOBALS['LANG']->getLL('menu_loaded_extensions'),
@@ -156,6 +158,7 @@ class tx_em_Settings implements t3lib_Singleton {
                        'mainTab' => '0',
                );
                $this->settings = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), 'tools_em');
+               $this->settings = array_merge($this->settings, $globalSettings);
        }
 
        /**
index 70c2524..629cc0f 100644 (file)
@@ -284,7 +284,7 @@ final class tx_em_Tools {
                        }
                        $emConf['constraints']['depends']['typo3'] = implode('-', $versionRange);
                }
-#debug($emConf);
+
                unset($emConf['private']);
                unset($emConf['download_password']);
                unset($emConf['TYPO3_version']);
@@ -618,18 +618,6 @@ final class tx_em_Tools {
                }
        }
 
-       /**
-        * Reads locallang file into array (for possible include in header)
-        *
-        * @param $file
-        */
-       public static function getArrayFromLocallang($file, $key = 'default') {
-               $content = t3lib_div::getURL($file);
-               $array = t3lib_div::xml2array($content);
-               return $array['data'][$key];
-
-       }
-
        /**
         * Include a locallang file and return the $LOCAL_LANG array serialized.
         *
@@ -1022,13 +1010,16 @@ final class tx_em_Tools {
        }
 
        /**
+        * Sends content of file for download
+        *
         * @static
         * @param  $path
         * @return void
         */
        public static function sendFile($path) {
-               $path = PATH_site . $path;
-               if (is_file($path) && is_readable($path)) {
+               $path = t3lib_div::resolveBackPath(PATH_site . $path);
+
+               if (is_file($path) && is_readable($path) && t3lib_div::isAllowedAbsPath($path)) {
                        header('Content-Type: application/octet-stream');
                        header('Content-Disposition: attachment; filename=' . basename($path));
                        readfile($path);
@@ -1036,6 +1027,89 @@ final class tx_em_Tools {
                }
        }
 
+       /**
+        * Rename a file / folder
+        * @static
+        * @param  $file
+        * @param  $newName
+        * @return bool
+        */
+       public static function renameFile($file, $newName) {
+               if($file[0] == '/') {
+                       $file = substr($file, 1);
+               }
+               if($newName[0] == '/') {
+                       $newName = substr($newName, 1);
+               }
+
+               $file = t3lib_div::resolveBackPath(PATH_site . $file);
+               $newName = t3lib_div::resolveBackPath(PATH_site . $newName);
+               if (is_writable($file) && t3lib_div::isAllowedAbsPath($file) && t3lib_div::isAllowedAbsPath($newName)) {
+                       return rename($file, $newName);
+               }
+
+               return false;
+       }
+
+
+       /**
+        * Creates a new file
+        *
+        * Returns an array with
+        * 0: boolean success
+        * 1: string absolute path of written file/folder
+        * 2: error code
+        *
+        * The error code returns
+        * 0: no error
+        * -1: not writable
+        * -2: not allowed path
+        * -3: already exists
+        * -4: not able to create
+        *
+        * @static
+        * @param  $folder
+        * @param  $file
+        * @param  $isFolder
+        * @return array
+        */
+       public static function createNewFile($folder, $file, $isFolder) {
+               $success = FALSE;
+               $error = 0;
+
+               if (substr($folder, -1) !== '/') {
+                       $folder .= '/';
+               }
+
+
+               $newFile = t3lib_div::resolveBackPath(PATH_site . $folder . $file);
+
+               if (!is_writable(dirname($newFile))) {
+                       $error = -1;
+               } elseif (!t3lib_div::isAllowedAbsPath($newFile)) {
+                       $error = -2;
+               } elseif (file_exists($newFile)) {
+                       $error = -3;
+               } else {
+                       if ($isFolder) {
+                               $success = t3lib_div::mkdir($newFile);
+                       } else {
+                               $success = t3lib_div::writeFile($newFile, '');
+                       }
+
+                       if (!$success) {
+                               $error = -4;
+                       }
+               }
+
+               return array(
+                       $success,
+                       $newFile,
+                       $error
+               );
+       }
+
+
        /**
         * Wrapping input string in a link tag with link to email address
         *
index cd60cfb..93dcb17 100644 (file)
@@ -4,6 +4,7 @@ $emClassesPath = $extensionPath . '/classes/';
 $emInterfacesPath = $extensionPath . '/interfaces/';
 return array(
        'tx_em_index_checkdatabaseupdateshook' => $emInterfacesPath . 'interface.tx_em_index_checkdatabaseupdateshook.php',
+       'tx_em_renderhook' => $emInterfacesPath . 'interface.tx_em_renderhook.php',
 
        'sc_mod_tools_em_index' => $emClassesPath . 'index.php',
        'tx_em_api' => $emClassesPath . 'class.tx_em_api.php',
index cdd05f2..960dd8a 100644 (file)
@@ -3,7 +3,7 @@
 ########################################################################
 # Extension Manager/Repository config file for ext "em".
 #
-# Auto generated 08-02-2011 19:22
+# Auto generated 23-02-2011 14:04
 #
 # Manual updates:
 # Only the data in the array - everything else is removed by next
@@ -34,7 +34,7 @@ $EM_CONF[$_EXTKEY] = array(
        'CGLcompliance' => '',
        'CGLcompliance_note' => '',
        'version' => '4.5.1',
-       '_md5_values_when_last_written' => 'a:103:{s:9:"ChangeLog";s:4:"b360";s:16:"ext_autoload.php";s:4:"397a";s:21:"ext_conf_template.txt";s:4:"582d";s:12:"ext_icon.gif";s:4:"2cc2";s:17:"ext_localconf.php";s:4:"fd30";s:14:"ext_tables.php";s:4:"3d63";s:14:"ext_tables.sql";s:4:"5a42";s:25:"ext_tables_static+adt.sql";s:4:"3c1b";s:27:"classes/class.tx_em_api.php";s:4:"c09b";s:40:"classes/class.tx_em_extensionmanager.php";s:4:"68e8";s:16:"classes/conf.php";s:4:"d842";s:17:"classes/index.php";s:4:"376e";s:61:"classes/connection/class.tx_em_connection_extdirectserver.php";s:4:"b40e";s:59:"classes/connection/class.tx_em_connection_extdirectsoap.php";s:4:"fda8";s:50:"classes/connection/class.tx_em_connection_soap.php";s:4:"decd";s:49:"classes/connection/class.tx_em_connection_ter.php";s:4:"813e";s:41:"classes/database/class.tx_em_database.php";s:4:"5852";s:53:"classes/exception/class.tx_em_connectionexception.php";s:4:"8b14";s:58:"classes/exception/class.tx_em_extensionimportexception.php";s:4:"62e2";s:55:"classes/exception/class.tx_em_extensionxmlexception.php";s:4:"fcfe";s:52:"classes/exception/class.tx_em_mirrorxmlexception.php";s:4:"ad05";s:46:"classes/exception/class.tx_em_xmlexception.php";s:4:"3679";s:53:"classes/extensions/class.tx_em_extensions_details.php";s:4:"7b5a";s:50:"classes/extensions/class.tx_em_extensions_list.php";s:4:"0b87";s:59:"classes/import/class.tx_em_import_extensionlistimporter.php";s:4:"25e8";s:56:"classes/import/class.tx_em_import_mirrorlistimporter.php";s:4:"6c5e";s:39:"classes/install/class.tx_em_install.php";s:4:"545e";s:64:"classes/parser/class.tx_em_parser_extensionxmlabstractparser.php";s:4:"3cc8";s:60:"classes/parser/class.tx_em_parser_extensionxmlpullparser.php";s:4:"8cb1";s:60:"classes/parser/class.tx_em_parser_extensionxmlpushparser.php";s:4:"728a";s:61:"classes/parser/class.tx_em_parser_mirrorxmlabstractparser.php";s:4:"8f3c";s:57:"classes/parser/class.tx_em_parser_mirrorxmlpullparser.php";s:4:"8092";s:57:"classes/parser/class.tx_em_parser_mirrorxmlpushparser.php";s:4:"7267";s:55:"classes/parser/class.tx_em_parser_xmlabstractparser.php";s:4:"6d00";s:54:"classes/parser/class.tx_em_parser_xmlparserfactory.php";s:4:"471c";s:55:"classes/reports/class.tx_em_reports_extensionstatus.php";s:4:"efb5";s:45:"classes/repository/class.tx_em_repository.php";s:4:"a953";s:53:"classes/repository/class.tx_em_repository_mirrors.php";s:4:"987c";s:53:"classes/repository/class.tx_em_repository_utility.php";s:4:"33ed";s:41:"classes/settings/class.tx_em_settings.php";s:4:"9c1d";s:55:"classes/tasks/class.tx_em_tasks_updateextensionlist.php";s:4:"b634";s:35:"classes/tools/class.tx_em_tools.php";s:4:"5f11";s:41:"classes/tools/class.tx_em_tools_unzip.php";s:4:"d183";s:46:"classes/tools/class.tx_em_tools_xmlhandler.php";s:4:"312d";s:49:"classes/translations/class.tx_em_translations.php";s:4:"efba";s:61:"interfaces/interface.tx_em_index_checkdatabaseupdateshook.php";s:4:"7178";s:22:"language/locallang.xml";s:4:"0107";s:18:"res/css/editor.css";s:4:"d4a2";s:17:"res/css/t3_em.css";s:4:"8f6e";s:24:"res/icons/arrow_redo.png";s:4:"343b";s:24:"res/icons/arrow_undo.png";s:4:"9a4f";s:20:"res/icons/cancel.png";s:4:"757a";s:22:"res/icons/download.png";s:4:"c5b2";s:19:"res/icons/drive.png";s:4:"9520";s:19:"res/icons/email.png";s:4:"af58";s:32:"res/icons/extension-required.png";s:4:"5619";s:25:"res/icons/filebrowser.png";s:4:"25b9";s:18:"res/icons/flag.png";s:4:"8798";s:19:"res/icons/image.png";s:4:"82ab";s:21:"res/icons/install.gif";s:4:"8d57";s:20:"res/icons/jslint.gif";s:4:"2e24";s:19:"res/icons/oodoc.gif";s:4:"744b";s:23:"res/icons/repupdate.png";s:4:"eaa5";s:20:"res/icons/server.png";s:4:"92ce";s:22:"res/icons/settings.png";s:4:"30a1";s:25:"res/icons/text_indent.png";s:4:"47f0";s:19:"res/icons/tools.png";s:4:"16d9";s:23:"res/icons/uninstall.gif";s:4:"a77f";s:16:"res/js/em_app.js";s:4:"2d0d";s:23:"res/js/em_components.js";s:4:"4b6a";s:18:"res/js/em_files.js";s:4:"7905";s:22:"res/js/em_languages.js";s:4:"d58d";s:20:"res/js/em_layouts.js";s:4:"05c1";s:22:"res/js/em_locallist.js";s:4:"3939";s:27:"res/js/em_repositorylist.js";s:4:"4f0f";s:21:"res/js/em_settings.js";s:4:"0264";s:16:"res/js/em_ter.js";s:4:"b7bf";s:18:"res/js/em_tools.js";s:4:"d187";s:22:"res/js/em_usertools.js";s:4:"3816";s:33:"res/js/overrides/ext_overrides.js";s:4:"eda6";s:24:"res/js/ux/GridFilters.js";s:4:"95db";s:29:"res/js/ux/RowPanelExpander.js";s:4:"d4dd";s:22:"res/js/ux/TreeState.js";s:4:"ba48";s:27:"res/js/ux/custom_plugins.js";s:4:"d761";s:28:"res/js/ux/fileuploadfield.js";s:4:"a7a0";s:19:"res/js/ux/jslint.js";s:4:"8c75";s:24:"res/js/ux/searchfield.js";s:4:"4e83";s:29:"res/js/ux/css/GridFilters.css";s:4:"78fa";s:27:"res/js/ux/css/RangeMenu.css";s:4:"c5f6";s:33:"res/js/ux/filter/BooleanFilter.js";s:4:"d67f";s:30:"res/js/ux/filter/DateFilter.js";s:4:"1d6d";s:26:"res/js/ux/filter/Filter.js";s:4:"5601";s:30:"res/js/ux/filter/ListFilter.js";s:4:"88bc";s:33:"res/js/ux/filter/NumericFilter.js";s:4:"a32d";s:32:"res/js/ux/filter/StringFilter.js";s:4:"ce23";s:27:"res/js/ux/images/equals.png";s:4:"87b7";s:25:"res/js/ux/images/find.png";s:4:"9f1c";s:33:"res/js/ux/images/greater_than.png";s:4:"746c";s:30:"res/js/ux/images/less_than.png";s:4:"2fb7";s:38:"res/js/ux/images/sort_filtered_asc.gif";s:4:"9e7a";s:39:"res/js/ux/images/sort_filtered_desc.gif";s:4:"6d59";s:26:"res/js/ux/menu/ListMenu.js";s:4:"d5ff";s:27:"res/js/ux/menu/RangeMenu.js";s:4:"6a5e";}',
+       '_md5_values_when_last_written' => 'a:104:{s:9:"ChangeLog";s:4:"bc4a";s:16:"ext_autoload.php";s:4:"e8cb";s:21:"ext_conf_template.txt";s:4:"582d";s:12:"ext_icon.gif";s:4:"2cc2";s:17:"ext_localconf.php";s:4:"fd30";s:14:"ext_tables.php";s:4:"3d63";s:14:"ext_tables.sql";s:4:"5a42";s:25:"ext_tables_static+adt.sql";s:4:"3c1b";s:27:"classes/class.tx_em_api.php";s:4:"c09b";s:40:"classes/class.tx_em_extensionmanager.php";s:4:"4cb8";s:16:"classes/conf.php";s:4:"d842";s:17:"classes/index.php";s:4:"872c";s:61:"classes/connection/class.tx_em_connection_extdirectserver.php";s:4:"5719";s:59:"classes/connection/class.tx_em_connection_extdirectsoap.php";s:4:"fda8";s:50:"classes/connection/class.tx_em_connection_soap.php";s:4:"decd";s:49:"classes/connection/class.tx_em_connection_ter.php";s:4:"813e";s:41:"classes/database/class.tx_em_database.php";s:4:"5852";s:53:"classes/exception/class.tx_em_connectionexception.php";s:4:"8b14";s:58:"classes/exception/class.tx_em_extensionimportexception.php";s:4:"62e2";s:55:"classes/exception/class.tx_em_extensionxmlexception.php";s:4:"fcfe";s:52:"classes/exception/class.tx_em_mirrorxmlexception.php";s:4:"ad05";s:46:"classes/exception/class.tx_em_xmlexception.php";s:4:"3679";s:53:"classes/extensions/class.tx_em_extensions_details.php";s:4:"7b5a";s:50:"classes/extensions/class.tx_em_extensions_list.php";s:4:"ee52";s:59:"classes/import/class.tx_em_import_extensionlistimporter.php";s:4:"25e8";s:56:"classes/import/class.tx_em_import_mirrorlistimporter.php";s:4:"6c5e";s:39:"classes/install/class.tx_em_install.php";s:4:"545e";s:64:"classes/parser/class.tx_em_parser_extensionxmlabstractparser.php";s:4:"3cc8";s:60:"classes/parser/class.tx_em_parser_extensionxmlpullparser.php";s:4:"8cb1";s:60:"classes/parser/class.tx_em_parser_extensionxmlpushparser.php";s:4:"728a";s:61:"classes/parser/class.tx_em_parser_mirrorxmlabstractparser.php";s:4:"8f3c";s:57:"classes/parser/class.tx_em_parser_mirrorxmlpullparser.php";s:4:"8092";s:57:"classes/parser/class.tx_em_parser_mirrorxmlpushparser.php";s:4:"7267";s:55:"classes/parser/class.tx_em_parser_xmlabstractparser.php";s:4:"6d00";s:54:"classes/parser/class.tx_em_parser_xmlparserfactory.php";s:4:"471c";s:55:"classes/reports/class.tx_em_reports_extensionstatus.php";s:4:"efb5";s:45:"classes/repository/class.tx_em_repository.php";s:4:"a953";s:53:"classes/repository/class.tx_em_repository_mirrors.php";s:4:"987c";s:53:"classes/repository/class.tx_em_repository_utility.php";s:4:"33ed";s:41:"classes/settings/class.tx_em_settings.php";s:4:"bac9";s:55:"classes/tasks/class.tx_em_tasks_updateextensionlist.php";s:4:"b634";s:35:"classes/tools/class.tx_em_tools.php";s:4:"c3c9";s:41:"classes/tools/class.tx_em_tools_unzip.php";s:4:"d183";s:46:"classes/tools/class.tx_em_tools_xmlhandler.php";s:4:"312d";s:49:"classes/translations/class.tx_em_translations.php";s:4:"efba";s:61:"interfaces/interface.tx_em_index_checkdatabaseupdateshook.php";s:4:"7178";s:41:"interfaces/interface.tx_em_renderhook.php";s:4:"ef3f";s:22:"language/locallang.xml";s:4:"618c";s:18:"res/css/editor.css";s:4:"c89d";s:17:"res/css/t3_em.css";s:4:"5faf";s:24:"res/icons/arrow_redo.png";s:4:"343b";s:24:"res/icons/arrow_undo.png";s:4:"9a4f";s:20:"res/icons/cancel.png";s:4:"757a";s:22:"res/icons/download.png";s:4:"c5b2";s:19:"res/icons/drive.png";s:4:"9520";s:19:"res/icons/email.png";s:4:"af58";s:32:"res/icons/extension-required.png";s:4:"5619";s:25:"res/icons/filebrowser.png";s:4:"25b9";s:18:"res/icons/flag.png";s:4:"8798";s:19:"res/icons/image.png";s:4:"82ab";s:21:"res/icons/install.gif";s:4:"8d57";s:20:"res/icons/jslint.gif";s:4:"2e24";s:19:"res/icons/oodoc.gif";s:4:"744b";s:23:"res/icons/repupdate.png";s:4:"eaa5";s:20:"res/icons/server.png";s:4:"92ce";s:22:"res/icons/settings.png";s:4:"30a1";s:25:"res/icons/text_indent.png";s:4:"47f0";s:19:"res/icons/tools.png";s:4:"16d9";s:23:"res/icons/uninstall.gif";s:4:"a77f";s:16:"res/js/em_app.js";s:4:"db4f";s:23:"res/js/em_components.js";s:4:"3767";s:18:"res/js/em_files.js";s:4:"3d39";s:22:"res/js/em_languages.js";s:4:"e8c6";s:20:"res/js/em_layouts.js";s:4:"05c1";s:22:"res/js/em_locallist.js";s:4:"828e";s:27:"res/js/em_repositorylist.js";s:4:"0b09";s:21:"res/js/em_settings.js";s:4:"9ce1";s:16:"res/js/em_ter.js";s:4:"b7bf";s:18:"res/js/em_tools.js";s:4:"d187";s:22:"res/js/em_usertools.js";s:4:"3816";s:33:"res/js/overrides/ext_overrides.js";s:4:"eda6";s:24:"res/js/ux/GridFilters.js";s:4:"95db";s:29:"res/js/ux/RowPanelExpander.js";s:4:"f239";s:22:"res/js/ux/TreeState.js";s:4:"ba48";s:27:"res/js/ux/custom_plugins.js";s:4:"d761";s:28:"res/js/ux/fileuploadfield.js";s:4:"a7a0";s:19:"res/js/ux/jslint.js";s:4:"8c75";s:24:"res/js/ux/searchfield.js";s:4:"4e83";s:29:"res/js/ux/css/GridFilters.css";s:4:"78fa";s:27:"res/js/ux/css/RangeMenu.css";s:4:"c5f6";s:33:"res/js/ux/filter/BooleanFilter.js";s:4:"d67f";s:30:"res/js/ux/filter/DateFilter.js";s:4:"1d6d";s:26:"res/js/ux/filter/Filter.js";s:4:"5601";s:30:"res/js/ux/filter/ListFilter.js";s:4:"88bc";s:33:"res/js/ux/filter/NumericFilter.js";s:4:"a32d";s:32:"res/js/ux/filter/StringFilter.js";s:4:"ce23";s:27:"res/js/ux/images/equals.png";s:4:"87b7";s:25:"res/js/ux/images/find.png";s:4:"9f1c";s:33:"res/js/ux/images/greater_than.png";s:4:"746c";s:30:"res/js/ux/images/less_than.png";s:4:"2fb7";s:38:"res/js/ux/images/sort_filtered_asc.gif";s:4:"9e7a";s:39:"res/js/ux/images/sort_filtered_desc.gif";s:4:"6d59";s:26:"res/js/ux/menu/ListMenu.js";s:4:"d5ff";s:27:"res/js/ux/menu/RangeMenu.js";s:4:"6a5e";}',
        'constraints' => array(
                'depends' => array(
                        'cms' => '',
index ccb3d22..0116077 100644 (file)
                        <label index="enter_repository_url">Enter repository URL:</label>
                        <label index="repository_url_hint">If you set a repository URL, this overrides the use of a mirror. Use this to select a specific (private) repository.</label>
                        <label index="repository_settings">Repository settings</label>
-                       <label index="repository_edit">Edit repository "[0]"</label>
+                       <label index="repository_edit">Edit repository "{0}"</label>
                        <label index="repository_create">Create new repository</label>
                        <label index="repository_delete">Delete repository</label>
                        <label index="repository_deleting">Deleting repository</label>
                        <label index="msg_unknownError">Unknow error occured.</label>
                        <label index="msg_startTyping">Start typing here and press &lt;return&gt;</label>
                        <label index="configurationSaved">Configuration was saved.</label>
+                       <label index="settingsSaved">Settings were saved.</label>
                        <label index="action_loading_extlist">Loading Extension List ...</label>
                        <label index="action_loadingRepositoryExtlist">Loading Repository Extension List ...</label>
                        <label index="action_loading">Loading ...</label>
                        <label index="extTemplate_inlineToWindow">Use windows instead of inline display: On small screens the inline display of rows might take too much space. This switch moves the inline info to windows.</label>
                        <label index="extTemplate_displayMyExtensions">Display "My Extensions" Tab: In this tab you can manage your own extensions.</label>
                        <label index="soap_error">Unexpected result from SOAP</label>
+                       <label index="fileEditFileChanged">File content changed</label>
+                       <label index="fileEditFileChangedSavePrompt">Do you want to save this file before loading another file?</label>
+                       <label index="fileEditNewFilePrompt">Please enter complete filename</label>
+                       <label index="fileEditRename">Rename</label>
+                       <label index="fileEditCreateFileFolder">Create new file or folder</label>
+                       <label index="fileEditCreateFolder">Make Folder</label>
+                       <label index="fileEditReloadFiletree">Reload file tree</label>
+                       <label index="fileEditOperation">File Operation</label>
+                       <label index="fileEditMoveConfirmation">Are you sure to move "{0}" into "{1}"?</label>
+                       <label index="fileEditCopyConfirmation">Are you sure to copy "{0}" into "{1}"?</label>
+                       <label index="fileEditCopyConfirmation">Are you sure to copy "{0}" into "{1}"?</label>
 
                </languageKey>
        </data>
index a1e200b..f6cf549 100644 (file)
@@ -10,3 +10,7 @@
        white-space: nowrap;
        overflow: auto;
 }
+/* overwrite codemirror css */
+span.syntax-error {
+       background-color: #FFDFE6 !important;
+}
\ No newline at end of file
index 8c817c0..1169077 100644 (file)
@@ -241,4 +241,5 @@ a.email {
 
 .fileChanged {
        color: red;
-}
\ No newline at end of file
+}
+
index b38cff9..d99ebac 100644 (file)
@@ -96,6 +96,9 @@ TYPO3.EM.App = {
                        stateId: 'mainTab',
                        stateEvents:['tabchange'],
                        autoScroll: true,
+                       tabPosition: 'top',
+                       enableTabScroll: true,
+                       autoWidth: true,
                        defaults: {
                                layout: 'fit'
                        },
index 0b8e437..2d58283 100644 (file)
@@ -39,6 +39,7 @@ Ext.ns('TYPO3.EM', 'TYPO3.EM.GridColumns', 'TYPO3.EM.ExtDirect', 'TYPO3.EMSOAP.E
 TYPO3.EM.Filters = new Ext.ux.grid.GridFilters({
        encode: true,
        local: true,
+       menuFilterText: TYPO3.lang.cmd_filter,
        filters: [
                {
                        type: 'string',
@@ -55,7 +56,15 @@ TYPO3.EM.Filters = new Ext.ux.grid.GridFilters({
                        }, {
                        type: 'list',
                        dataIndex: 'state',
-                       options: ['alpha', 'beta', 'stable', 'experimental', 'test', 'obsolete', 'excludeFromUpdates'],
+                       options: [
+                               TYPO3.lang.state_alpha,
+                               TYPO3.lang.state_beta,
+                               TYPO3.lang.state_stable,
+                               TYPO3.lang.state_experimental,
+                               TYPO3.lang.state_test,
+                               TYPO3.lang.state_obsolete,
+                               TYPO3.lang.state_exclude_from_updates
+                       ],
                        phpMode: true
                        }, {
                        type: 'boolean',
@@ -100,7 +109,16 @@ TYPO3.EM.RemoteFilters = new Ext.ux.grid.GridFilters({
                }, {
                type: 'list',
                dataIndex: 'statevalue',
-               options: [[0, 'alpha'], [1, 'beta'], [2, 'stable'], [3, 'experimental'], [4, 'test'], [5, 'obsolete'], [6, 'excludeFromUpdates'], [999, 'n/a']],
+               options: [
+                       [0, TYPO3.lang.state_alpha],
+                       [1, TYPO3.lang.state_beta],
+                       [2, TYPO3.lang.state_stable],
+                       [3, TYPO3.lang.state_experimental],
+                       [4, TYPO3.lang.state_test],
+                       [5, TYPO3.lang.state_obsolete],
+                       [6, TYPO3.lang.state_exclude_from_updates],
+                       [999, TYPO3.lang.translation_n_a]
+               ],
                phpMode: true
                }, {
                type: 'list',
@@ -386,7 +404,7 @@ TYPO3.EM.GridColumns.ExtensionState = {
        filterable: true,
        dataIndex:'state',
        renderer: function(value, metaData, record, rowIndex, colIndex, store){
-               metaData.css += 'state-' + value + ' ';
+               metaData.css += record.data.stateCls + ' ';
                return value;
        }
 };
@@ -401,7 +419,7 @@ TYPO3.EM.GridColumns.ExtensionStateValue = {
        hideable: true,
        dataIndex:'statevalue',
        renderer: function(value, metaData, record, rowIndex, colIndex, store){
-               metaData.css += 'state-' + record.data.state + ' ';
+               metaData.css += record.data.stateCls + ' ';
                return record.data.state;
        },
        filterable: true
index 7b47876..1dab552 100644 (file)
@@ -18,20 +18,31 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
        rootText: TYPO3.lang.ext_details_ext_files,
        baseParams: null,
        treeId: null,
+       fileContent: '',
+       parser: 'PHPHTMLMixedParser',
+
+       allowedOperations: {
+               moveFile: TYPO3.settings.EM.fileAllowMove,
+               deleteFile: TYPO3.settings.EM.fileAllowDelete,
+               renameFile: TYPO3.settings.EM.fileAllowRename,
+               uploadFile: TYPO3.settings.EM.fileAllowUpload,
+               createFile: TYPO3.settings.EM.fileAllowCreate,
+               downloadFile: TYPO3.settings.EM.fileAllowDownload
+       },
 
        initComponent:function() {
 
-               var hlEditor = new TYPO3.EM.CodeMirror({
-                       parser: 'mixed',
-                       itemId: 'hlEditor',
-                       stylesheet: TYPO3.settings.EM.editorCss,
-                       editFile: null
+               this.highlightEditor = new TYPO3.EM.CodeMirror({
+                       itemId: 'this.highlightEditor',
+                       fileContent: this.fileContent,
+                       parser: this.parser,
+                       stylesheet: TYPO3.settings.EM.editorCss
                });
 
 
 
 
-               var fileTree = new Ext.tree.TreePanel ({
+               this.fileTree = new Ext.tree.TreePanel ({
                        itemId: 'extfiletree',
                        cls: 'extfiletree',
                        margins: '0 0 0 0',
@@ -41,6 +52,10 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                        stateEvents: [],
                        plugins: new Ext.ux.state.TreePanel(),
 
+                       enableDD: this.allowedOperations.moveFile,
+                       ddAppendOnly: true,
+                       copyAction: false,
+
                        root: {
                                text: this.rootText,
                                itemId: 'fileroot',
@@ -58,48 +73,51 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                        },
                        listeners: {
                                click: function(node) {
-                                       if (node.attributes.fileType === 'text') {
-                                               this.layout.center.panel.reloadButton.show().disable();
-                                               TYPO3.EM.ExtDirect.readExtFile(node.attributes.id , function(response) {
-                                                       // load in textarea
-                                                       hlEditor.openText(response, node.attributes.ext);
-                                                       hlEditor.editFile = node.attributes.id;
-                                                       this.layout.center.panel.reloadButton.enable();
-                                                       this.layout.center.panel.fileLabel.setText('File: ' + hlEditor.editFile);
-                                                       this.layout.center.panel.fileLabel.removeClass('fileChanged');
-                                                       this.layout.center.panel.saveButton.disable();
-                                                       this.layout.center.panel.undoButton.enable();
-                                                       this.layout.center.panel.redoButton.enable();
-                                                       this.layout.center.panel.indentButton.enable();
-                                                       if (node.attributes.ext == 'js') {
-                                                               this.layout.center.panel.jslintButton.enable();
+                                       this.clickNode(node);
+                               },
+
+                       /* Drag and Drop of file nodes */
+                       nodedragover: function (dragevent) {
+                               // allow only drop on dirs and exclude parent
+                               return (!dragevent.target.leaf && (dragevent.target.id !== dragevent.dropNode.parentNode.id));
+                       },
+                       beforenodedrop : function(dropEvent) {
+                               var action = dropEvent.rawEvent.ctrlKey ? 'copy' : 'move';
+                               dropEvent.tree.dragZone.proxy.animRepair = false;
+                               dropEvent.cancel = true;
+                               var question = this.copyAction ? TYPO3.lang.fileEditCopyConfirmation : TYPO3.lang.fileEditMoveConfirmation;
+
+                               Ext.Msg.confirm(TYPO3.lang.fileEditOperation, String.format(question, dropEvent.dropNode.text, dropEvent.target.text), function(button) {
+                                       if (button == 'yes') {
+                                               TYPO3.EM.ExtDirect.moveFile(dropEvent.dropNode.id, dropEvent.target.id, !dropEvent.dropNode.leaf, function(response) {
+                                                       if (response.success) {
+                                                               dropEvent.tree.dragZone.proxy.animRepair = true;
+                                                               if (!dropEvent.target.leaf) {
+                                                                       dropEvent.target.expand();
+                                                               }
+                                                               switch (dropEvent.point) {
+                                                                       case "append":
+                                                                       case "ap-pend":
+                                                                               dropEvent.target.appendChild(dropEvent.dropNode);
+                                                                               break;
+                                                                       case "above":
+                                                                               dropEvent.target.parentNode.insertBefore(dropEvent.dropNode, dropEvent.target);
+                                                                               break;
+                                                                       case "below":
+                                                                               dropEvent.target.parentNode.insertBefore(dropEvent.dropNode, dropEvent.target.nextSibling);
+                                                                               break;
+                                                               }
+                                                               dropEvent.dropNode.ui.focus();
+                                                               dropEvent.dropNode.ui.highlight();
+
                                                        } else {
-                                                               this.layout.center.panel.jslintButton.disable();
-                                                       }
 
-                                               }, this);
-                                       }
-                                       if (node.attributes.fileType === 'image') {
-                                               var w = new Ext.Window({
-                                                       width: 200,
-                                                       height: 200,
-                                                       title: node.attributes.text,
-                                                       layout: 'fit',
-                                                       items: [{
-                                                               xtype: 'image',
-                                                               src: TYPO3.settings.EM.siteUrl + node.attributes.id,
-                                                               autoSize: true,
-                                                               resizable: false,
-                                                               renderTo: document.body
-                                                       }]
-                                               }).show();
-                                       }
-                                       if (node.isLeaf()) {
-                                               this.layout.west.panel.downloadFileButton.enable();
-                                       } else {
-                                               this.layout.west.panel.downloadFileButton.disable();
+                                                       }
+                                               });
                                        }
-                               },
+                               });
+                       },
+
                                scope: this
                        }
 
@@ -117,30 +135,86 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                                collapseMode: 'mini',
                                cls: 'filetree-panel',
                                hideCollapseTool: true,
-                               items: [fileTree],
+                               items: [this.fileTree],
                                tbar: [{
                                        iconCls: 'x-tbar-loading',
+                                       tooltip: TYPO3.lang.fileEditReloadFiletree,
                                        handler: function() {
-                                               fileTree.getRootNode().reload();
+                                               this.fileTree.getRootNode().reload();
                                        },
                                        scope: this
                                }, {
                                        iconCls: 'x-btn-upload',
                                        tooltip: TYPO3.lang.cmd_upload,
                                        ref: '../uploadFileButton',
-                                       hidden: true
-                               }, {
+                                       hidden: !this.allowedOperations.uploadFile
+                               }, '-', {
                                        iconCls: 't3-icon t3-icon-actions t3-icon-actions-system t3-icon-system-extension-download',
                                        tooltip: TYPO3.lang.cmd_download,
                                        ref: '../downloadFileButton',
                                        disabled: true,
+                                       hidden: !this.allowedOperations.downloadFile,
                                        handler: function() {
-                                               var node = fileTree.getSelectionModel().getSelectedNode();
+                                               var node = this.fileTree.getSelectionModel().getSelectedNode();
                                                if (node.isLeaf()) {
                                                        this.downloadFile(node.attributes.id);
                                                }
                                        },
                                        scope: this
+                               }, {
+                                       iconCls: 't3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-new',
+                                       tooltip: TYPO3.lang.fileEditCreateFileFolder,
+                                       ref: '../createFileButton',
+                                       disabled: true,
+                                       hidden: !this.allowedOperations.createFile,
+                                       scope: this,
+                                       handler: function() {
+                                               var folderNode = this.fileTree.getSelectionModel().getSelectedNode();
+                                               this.fileCreationDialog(folderNode, function() {
+                                                       //this.createNewFile(folderNode, text);
+                                               });
+                                       }
+                               }, {
+                                       iconCls: 't3-icon t3-icon-actions t3-icon-actions-edit t3-icon-edit-rename',
+                                       tooltip: TYPO3.lang.fileEditRename,
+                                       ref: '../renameButton',
+                                       scope: this,
+                                       hidden: !this.allowedOperations.renameFile,
+                                       handler: function() {
+                                               var node = this.fileTree.getSelectionModel().getSelectedNode();
+                                               var isFolder = !node.isLeaf();
+                                               Ext.Msg.prompt(TYPO3.lang.fileEditRename, '', function(btn, text) {
+                                                       if (btn == 'ok' && text != node.text) {
+                                                               TYPO3.EM.ExtDirect.renameFile(node.attributes.id, text, isFolder, function(response) {
+                                                                       if (response.success) {
+                                                                               node.setId(response.newFile);
+                                                                               node.setText(response.newFilename);
+                                                                               node.ui.focus();
+                                                                               node.ui.highlight();
+                                                                       }
+                                                               }, this);
+                                                       }
+                                               }, this, false, node.text);
+                                       }
+                               }, {
+                                       iconCls: 't3-icon t3-icon-actions t3-icon-actions-edit t3-icon-edit-delete',
+                                       tooltip: TYPO3.lang.ext_details_delete,
+                                       ref: '../deleteButton',
+                                       hidden: !this.allowedOperations.deleteFile,
+                                       scope: this,
+                                       handler: function() {
+                                               var node = this.fileTree.getSelectionModel().getSelectedNode();
+                                               var isFolder = !node.isLeaf();
+                                               Ext.Msg.confirm(TYPO3.lang.ext_details_delete, '', function(btn, text) {
+                                                       if (btn == 'yes') {
+                                                               TYPO3.EM.ExtDirect.deleteFile(node.attributes.id, isFolder, function(response) {
+                                                                       if (response.success) {
+                                                                               node.remove();
+                                                                       }
+                                                               }, this);
+                                                       }
+                                               }, this, false, node.text);
+                                       }
                                }]
                        }, {
 
@@ -151,7 +225,7 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                                cmargins: '0 0 0 0',
                                border: false,
                                cls: 'file-editor',
-                               items: [hlEditor],
+                               items: [this.highlightEditor],
                                tbar: [{
                                        iconCls: 'x-btn-filebrowser',
                                        tooltip: TYPO3.lang.cmd_openInNewWindow,
@@ -185,37 +259,31 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                                        scope: this,
                                        hidden: true,
                                        handler: function() {
-                                               if (hlEditor.editFile) {
+                                               if (this.highlightEditor.editFile) {
                                                        this.layout.center.panel.reloadButton.disable();
-                                                       TYPO3.EM.ExtDirect.readExtFile(hlEditor.editFile , function(response) {
-                                                               hlEditor.setValue(response);
+                                                       TYPO3.EM.ExtDirect.readExtFile(this.highlightEditor.editFile , function(response) {
+                                                               this.highlightEditor.setValue(response);
                                                                this.layout.center.panel.reloadButton.enable();
                                                        }, this);
                                                }
                                        }
                                }, {
                                        iconCls: 'x-btn-save',
-                                       tooltip: TYPO3.settings.EM.fileSaveAllowed ? TYPO3.lang.cmd_save : TYPO3.lang.ext_details_saving_disabled,
+                                       tooltip: TYPO3.settings.EM.fileAlloweSave ? TYPO3.lang.cmd_save : TYPO3.lang.ext_details_saving_disabled,
                                        ref: '../saveButton',
                                        disabled: true,
                                        scope: this,
                                        handler: function() {
-                                               this.layout.center.panel.reloadButton.disable();
-                                               var file = this.layout.west.items[0].getSelectionModel().getSelectedNode().attributes.id;
-                                               TYPO3.EM.ExtDirect.saveExtFile(
-                                                       file,
-                                                       hlEditor.getValue(),
-                                                       function(response) {
-                                                               if (response.success) {
-                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.cmd_save, String.format(TYPO3.lang.msg_fileSaved, response.file), 5);
-                                                                       this.layout.center.panel.saveButton.disable();
-                                                                       this.layout.center.panel.reloadButton.enable();
-                                                                       this.layout.center.panel.fileLabel.removeClass('fileChanged');
-                                                               } else {
-                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.cmd_save, response.error, 5);
-                                                               }
-                                               }, this);
+                                               this.saveFile(this.highlightEditor.editFile);
                                        }
+
+                               }, '-', {
+                                       iconCls: 't3-icon t3-icon-status t3-icon-status-version t3-icon-version-no-version',
+                                               tooltip: 'Show diff',
+                                               ref: '../diffButton',
+                                               disabled: true,
+                                               scope: this,
+                                               handler: this.showDiff
                                },
                                {
                                        iconCls: 'x-btn-undo',
@@ -224,7 +292,7 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                                        disabled: true,
                                        scope: this,
                                        handler: function() {
-                                               hlEditor.codeMirrorEditor.undo();
+                                               this.highlightEditor.codeMirrorEditor.undo();
                                        }
                                },
                                {
@@ -234,7 +302,7 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                                        disabled: true,
                                        scope: this,
                                        handler: function() {
-                                               hlEditor.codeMirrorEditor.redo();
+                                               this.highlightEditor.codeMirrorEditor.redo();
                                        }
                                },
                                {
@@ -244,7 +312,7 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                                        disabled: true,
                                        scope: this,
                                        handler: function() {
-                                               hlEditor.codeMirrorEditor.reindent();
+                                               this.highlightEditor.codeMirrorEditor.reindent();
                                        }
                                },
                                {
@@ -256,28 +324,21 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                                        handler: function() {
                                                try {
                                                        var bValidates = JSLINT(this.findByType('textarea')[0].getValue());
-
-                                                       var oStore = hlEditor.debugWindow.findByType('grid')[0].getStore();
+                                                       var oStore = this.highlightEditor.debugWindow.findByType('grid')[0].getStore();
                                                        if (!bValidates) {
                                                                var aErrorData = [];
-
                                                                for (var err in JSLINT.errors) {
                                                                        if (JSLINT.errors.hasOwnProperty(err) && (JSLINT.errors[err] !== null)) {
                                                                                aErrorData.push([JSLINT.errors[err].line, JSLINT.errors[err].character, JSLINT.errors[err].reason]);
                                                                        }
                                                                }
-
                                                                oStore.loadData(aErrorData, false);
-                                                               hlEditor.debugWindow.show();
-
-                                                       }
-                                                       else {
-
+                                                       } else {
                                                                oStore.loadData([
                                                                        [1, 1, TYPO3.lang.msg_congratsNoErrors]
                                                                ], false);
-                                                               hlEditor.debugWindow.show();
                                                        }
+                                                       this.highlightEditor.debugWindow.show();
                                                } catch(e) {
                                                }
                                        }
@@ -300,118 +361,247 @@ TYPO3.EM.ExtFilelist = Ext.extend(Ext.Panel, {
                TYPO3.EM.ExtFilelist.superclass.onRender.apply(this, arguments);
        },
 
-       downloadFile: function(path) {
 
-                       // create hidden target iframe
-                       var id = Ext.id();
-                       var frame = document.createElement('iframe');
-                       frame.id = id;
-                       frame.name = id;
-                       frame.className = 'x-hidden';
-                       if (Ext.isIE) {
-                               frame.src = Ext.SSL_SECURE_URL;
+       clickNode: function(node, doSelect) {
+               if (doSelect) {
+                       this.fileTree.getSelectionModel().select(node);
+               }
+               if (node.attributes.fileType === 'text') {
+                       var file = node.attributes.id;
+                       if (this.highlightEditor.contentChanged) {
+                                Ext.MessageBox.confirm(TYPO3.lang.fileEditFileChanged, TYPO3.lang.fileEditFileChangedSavePrompt, function(btn){
+                                       if (btn == 'yes'){
+                                               this.saveFile(this.highlightEditor.editFile, function() {
+                                                       this.loadFile(node);
+                                               });
+
+                                       }
+                               }, this);
+                       } else {
+                               this.loadFile(node);
                        }
 
-                       document.body.appendChild(frame);
+               }
+               if (node.attributes.fileType === 'image') {
+                       var w = new Ext.Window({
+                               width: 200,
+                               height: 200,
+                               title: node.attributes.text,
+                               layout: 'fit',
+                               items: [{
+                                       xtype: 'image',
+                                       src: TYPO3.settings.EM.siteUrl + node.attributes.id,
+                                       autoSize: true,
+                                       resizable: false,
+                                       renderTo: document.body
+                               }]
+                       }).show();
+               }
+               if (node.isLeaf()) {
+                       this.layout.west.panel.downloadFileButton.enable();
+                       this.layout.west.panel.createFileButton.disable();
+               } else {
+                       this.layout.west.panel.downloadFileButton.disable();
+                       this.layout.west.panel.createFileButton.enable();
+               }
+       },
 
-                       if (Ext.isIE) {
-                               document.frames[id].name = id;
+       loadFile: function(node) {
+               this.layout.center.panel.reloadButton.show().disable();
+               TYPO3.EM.ExtDirect.readExtFile(node.attributes.id , function(response) {
+                       // load in textarea
+                       var centerPanel = this.layout.center.panel;
+                       this.highlightEditor.openText(response, node.attributes.ext);
+                       this.highlightEditor.editFile = node.attributes.id;
+                       this.highlightEditor.contentChanged = false;
+                       centerPanel.reloadButton.enable();
+                       centerPanel.fileLabel.setText('File: ' + this.highlightEditor.editFile);
+                       centerPanel.fileLabel.removeClass('fileChanged');
+                       centerPanel.saveButton.disable();
+                       centerPanel.undoButton.enable();
+                       centerPanel.redoButton.enable();
+                       centerPanel.indentButton.enable();
+                       centerPanel.diffButton.disable();
+                       if (node.attributes.ext == 'js') {
+                               centerPanel.jslintButton.enable();
+                       } else {
+                               centerPanel.jslintButton.disable();
                        }
 
-                       var form = Ext.DomHelper.append(document.body, {
-                                               tag: 'form',
-                                               method: 'post',
-                                               action: 'mod.php?M=tools_em',
-                                               target: id
-                                       });
-
-                       document.body.appendChild(form);
-
-                       var hidden;
-
-                       // append path to form
-                       hidden = document.createElement('input');
-                       hidden.type = 'hidden';
-                       hidden.name = 'CMD[downloadExtFile]';
-                       hidden.value = path;
-                       form.appendChild(hidden);
-
-                       var callback = function() {
-                               Ext.EventManager.removeListener(frame, 'load', callback, this);
-                               setTimeout(function() {
-                                       document.body.removeChild(form);
-                               }, 100);
-                               setTimeout(function() {
-                                       document.body.removeChild(frame);
-                               }, 110);
-                       };
-
-                       Ext.EventManager.on(frame, 'load', callback, this);
-
-                       form.submit();
-               }
+               }, this);
+       },
 
+       saveFile: function(file, cb) {
+               var panel = this.layout.center.panel;
+               var content = this.highlightEditor.getValue();
+
+               panel.reloadButton.disable();
+               TYPO3.EM.ExtDirect.saveExtFile(
+                       file,
+                       content,
+                       function(response) {
+                               if (response.success) {
+                                       TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.cmd_save, String.format(TYPO3.lang.msg_fileSaved, response.file), 5);
+                                       this.highlightEditor.contentChanged = false;
+                                       this.layout.center.panel.fileLabel.removeClass('fileChanged');
+                               } else {
+                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.cmd_save, response.error, 5);
+                               }
+                               if (Ext.isFunction(cb)) {
+                                       cb.call(this);
+                               }
+               }, this);
 
+               panel.saveButton.disable();
+               panel.reloadButton.enable();
 
-});
+       },
 
-// register xtype
-Ext.reg('extfilelist', TYPO3.EM.ExtFilelist);
+       moveFile: function(file, destination) {
 
+       },
 
-TYPO3.EM.CodeMirrorConfig = {
-       cssPath: TYPO3.settings.EM.codemirrorCssPath,
-       jsPath: TYPO3.settings.EM.codemirrorJsPath,
-       parser: {
-               defo: { // js code
-                       parserfile: ["tokenizejavascript.js", "parsejavascript.js"],
-                       stylesheet: [TYPO3.settings.EM.codemirrorCssPath + "jscolors.css"]
-               },
-               css: {
-                       parserfile: ["parsecss.js"],
-                       stylesheet: [TYPO3.settings.EM.codemirrorCssPath + "csscolors.css"]
-               },
-               js: {
-                       parserfile: ["tokenizejavascript.js", "parsejavascript.js"],
-                       stylesheet: [TYPO3.settings.EM.codemirrorCssPath + "jscolors.css"]
-               },
-               php: {
-                       parserfile: ["../contrib/php/js/tokenizephp.js", "../contrib/php/js/parsephp.js"],
-                       stylesheet: [TYPO3.settings.EM.codemirrorContribPath + "php/css/phpcolors.css"]
-               },
-               html: {
-                       parserfile: ["parsexml.js", "parsecss.js", "tokenizejavascript.js", "parsejavascript.js", "../contrib/php/js/tokenizephp.js", "../contrib/php/js/parsephp.js", "../contrib/php/js/parsephphtmlmixed.js"],
-                       stylesheet: [
-                               TYPO3.settings.EM.codemirrorCssPath + "xmlcolors.css",
-                               TYPO3.settings.EM.codemirrorCssPath + "jscolors.css",
-                               TYPO3.settings.EM.codemirrorCssPath + "csscolors.css",
-                               TYPO3.settings.EM.codemirrorContribPath + "php/css/phpcolors.css"]
-
-               },
-               mixed: {
-                       parserfile: ["parsexml.js", "parsecss.js", "tokenizejavascript.js", "parsejavascript.js", "../contrib/php/js/tokenizephp.js", "../contrib/php/js/parsephp.js", "../contrib/php/js/parsephphtmlmixed.js"],
-                       stylesheet: [
-                               TYPO3.settings.EM.codemirrorCssPath + "xmlcolors.css",
-                               TYPO3.settings.EM.codemirrorCssPath + "jscolors.css",
-                               TYPO3.settings.EM.codemirrorCssPath + "csscolors.css",
-                               TYPO3.settings.EM.codemirrorContribPath + "php/css/phpcolors.css"
-                       ]
+       showDiff: function() {
+               var original =  this.highlightEditor.oldSourceCode;
+               var content = this.highlightEditor.codeMirrorEditor.getCode();
+               TYPO3.EM.ExtDirect.makeDiff(original, content, function(response) {
+                       TYPO3.Windows.showWindow({
+                               title: 'Diff view',
+                               resizable: true,
+                               html: '<div style="background:#fff;padding: 5px;overflow:auto;">' + response.diff + '</div>'
+                       });
+               });
+       },
+
+       downloadFile: function(path) {
+
+               // create hidden target iframe
+               var id = Ext.id();
+               var frame = document.createElement('iframe');
+               frame.id = id;
+               frame.name = id;
+               frame.className = 'x-hidden';
+               if (Ext.isIE) {
+                       frame.src = Ext.SSL_SECURE_URL;
+               }
+
+               document.body.appendChild(frame);
+
+               if (Ext.isIE) {
+                       document.frames[id].name = id;
                }
+
+               var form = Ext.DomHelper.append(document.body, {
+                                       tag: 'form',
+                                       method: 'post',
+                                       action: 'mod.php?M=tools_em',
+                                       target: id
+                               });
+
+               document.body.appendChild(form);
+
+               var hidden;
+
+               // append path to form
+               hidden = document.createElement('input');
+               hidden.type = 'hidden';
+               hidden.name = 'CMD[downloadExtFile]';
+               hidden.value = path;
+               form.appendChild(hidden);
+
+               var callback = function() {
+                       Ext.EventManager.removeListener(frame, 'load', callback, this);
+                       setTimeout(function() {
+                               document.body.removeChild(form);
+                       }, 100);
+                       setTimeout(function() {
+                               document.body.removeChild(frame);
+                       }, 110);
+               };
+
+               Ext.EventManager.on(frame, 'load', callback, this);
+
+               form.submit();
+       },
+
+       fileCreationDialog: function(folderNode) {
+               new Ext.Window({
+                       id: 'em-files-createfilefolderdialog',
+                       title: TYPO3.lang.fileEditCreateFileFolder,
+                       layout: 'form',
+                       callerClass: this,
+                       items: [
+                               {
+                                       fieldLabel:  TYPO3.lang.fileEditNewFilePrompt,
+                                       itemId: 'newfile',
+                                       xtype: 'textfield',
+                                       width: 250
+                               },
+                               {
+                                       fieldLabel: TYPO3.lang.fileEditCreateFolder,
+                                       xtype: 'checkbox',
+                                       itemId: 'isFolder'
+                               }
+                       ],
+                       buttons: [{
+                               text: TYPO3.lang.cmd_create,
+                               handler: function() {
+                                       var me = Ext.WindowMgr.get('em-files-createfilefolderdialog');
+                                       var newfile = me.getComponent('newfile').getValue();
+                                       var isFolder = me.getComponent('isFolder').getValue();
+                                       TYPO3.EM.ExtDirect.createNewFile(folderNode.attributes.id, newfile, isFolder, function(response) {
+                                               if (response.success) {
+                                                       var newNode = null, delay;
+                                                       if (!folderNode.isExpanded()) {
+                                                               folderNode.expand();
+                                                               delay = 750;
+                                                       } else {
+                                                               newNode = new Ext.tree.TreeNode(
+                                                                       response.node
+                                                               );
+                                                               folderNode.appendChild(newNode);
+                                                               delay = 250;
+                                                       }
+                                                       (function() {
+                                                               if (!newNode) {
+                                                                       newNode = folderNode.findChild('id', response.node.id);
+                                                               }
+                                                               newNode.ui.focus();
+                                                               newNode.ui.highlight();
+                                                               me.callerClass.clickNode(newNode, true);
+                                                       }).defer(delay);
+                                               }
+                                       }, this);
+                                       me.close();
+                               },
+                               scope: this
+                       }, {
+                               text: TYPO3.lang.cmd_cancel,
+                               handler: function() {
+                                       var me = TYPO3.Windows.getById('em-files-createfilefolderdialog');
+                                       me.close();
+                               }
+                       }]
+               }).show();
        }
-};
+
+
+
+});
+
+// register xtype
+Ext.reg('extfilelist', TYPO3.EM.ExtFilelist);
 
 
 TYPO3.EM.CodeMirror = Ext.extend(Ext.Panel, {
        layout: 'fit',
        sourceCode: '',
        stylesheet: null,
+       fileLoaded: false,
+       fileContent: '',
+
        initComponent: function() {
                        // add custom stylesheet to all parser
-               if (this.stylesheet) {
-                       Ext.iterate(TYPO3.EM.CodeMirrorConfig.parser, function(key, value) {
-                               value.stylesheet.push(this.stylesheet);
-                       }, this);
-               }
 
                this.contentChanged = false;
                var me = this;
@@ -425,10 +615,15 @@ TYPO3.EM.CodeMirror = Ext.extend(Ext.Panel, {
                                layout: 'fit',
                                region: 'center',
                                border: false,
+                               viewConfig: {
+                                       forceFit: true
+                               },
                                listeners: {
                                        rowclick: function(grid) {
                                                var oData = grid.getSelectionModel().getSelected().data;
                                                me.codeMirrorEditor.jumpToLine(oData.line);
+                                               var pos = me.codeMirrorEditor.cursorPosition(true);
+                                               me.codeMirrorEditor.selectLines(pos.line, 0, pos.line, oData.character - 1);
                                        }
                                },
                                store: new Ext.data.ArrayStore({
@@ -442,21 +637,22 @@ TYPO3.EM.CodeMirror = Ext.extend(Ext.Panel, {
                                        {
                                                id: 'line',
                                                header: TYPO3.lang.msg_line,
-                                               width: 60,
-                                               sortable: true,
+                                               width: 40,
+                                               fixed: true,
+                                               menuDisabled: true,
                                                dataIndex: 'line'
                                        },
                                        {
                                                id: 'character',
                                                header: TYPO3.lang.msg_character,
-                                               width: 60,
-                                               sortable: true,
+                                               width: 70,
+                                               fixed: true,
+                                               menuDisabled: true,
                                                dataIndex: 'character'
                                        },
                                        {
                                                header: TYPO3.lang.show_description,
-                                               width: 240,
-                                               sortable: true,
+                                               menuDisabled: true,
                                                dataIndex: 'reason'
                                        }
                                ],
@@ -464,6 +660,8 @@ TYPO3.EM.CodeMirror = Ext.extend(Ext.Panel, {
                        })]
                });
 
+               me.addEvents('init');
+
                Ext.apply(this, {
                        items: [
                                {
@@ -507,23 +705,44 @@ TYPO3.EM.CodeMirror = Ext.extend(Ext.Panel, {
        /** @private */
        triggerCodeEditor: function() {
                var me = this;
+               var stylesheets = [
+                       TYPO3.settings.EM.codemirrorCssPath + "xmlcolors.css",
+                       TYPO3.settings.EM.codemirrorCssPath + "jscolors.css",
+                       TYPO3.settings.EM.codemirrorCssPath + "csscolors.css",
+                       TYPO3.settings.EM.codemirrorContribPath + "php/css/phpcolors.css",
+                       TYPO3.settings.EM.codemirrorContribPath + "sql/css/sqlcolors.css"
+               ];
+               if (this.stylesheet) {
+                       stylesheets.push(this.stylesheet);
+               }
                var oCmp = this.findByType('textarea')[0];
+
                this.editorConfig = Ext.applyIf(this.codeMirror || {}, {
                        lineNumbers: true,
                        textWrapping: false,
-                       content: oCmp.getValue(),
+                       content: this.fileContent || '',
                        indentUnit: 4,
                        tabMode: 'shift',
                        readOnly: oCmp.readOnly,
-                       path: TYPO3.EM.CodeMirrorConfig.jsPath,
+                       path: TYPO3.settings.EM.codemirrorJsPath,
                        autoMatchParens: true,
+                       parser: this.parser,
+                       parserfile: [
+                               "parsexml.js",
+                               "parsecss.js",
+                               "tokenizejavascript.js",
+                               "parsejavascript.js",
+                               "../contrib/php/js/tokenizephp.js",
+                               "../contrib/php/js/parsephp.js",
+                               "../contrib/php/js/parsephphtmlmixed.js",
+                               "../contrib/sql/js/parsesql.js"
+                       ],
+                       stylesheet: stylesheets,
+
                        initCallback: function(editor) {
-                               try {
-                                       var iLineNmbr = ((Ext.state.Manager.get("edcmr_" + me.itemId + '_lnmbr') !== undefined) ? Ext.state.Manager.get("edcmr_" + me.itemId + '_lnmbr') : 1);
-                                       editor.jumpToLine(iLineNmbr);
-                               } catch(e) {
-                               }
+                               me.fireEvent('init', editor);
                        },
+
                        onChange: function() {
                                var sCode = me.codeMirrorEditor.getCode();
                                oCmp.setValue(sCode);
@@ -533,24 +752,24 @@ TYPO3.EM.CodeMirror = Ext.extend(Ext.Panel, {
                                } else {
                                        me.changeAction(true);
                                }
-
                        }
                });
 
                var sParserType = me.parser || 'defo';
-               this.editorConfig = Ext.applyIf(this.editorConfig, TYPO3.EM.CodeMirrorConfig.parser[sParserType]);
                this.codeMirrorEditor = new CodeMirror.fromTextArea(Ext.getDom(oCmp.id).id, this.editorConfig);
 
        },
 
        changeAction: function(changed) {
-               if (TYPO3.settings.EM.fileSaveAllowed) {
+               if (TYPO3.settings.EM.fileAlloweSave && this.fileLoaded) {
                        if (!changed) {
                                this.ownerCt.saveButton.disable();
+                               this.ownerCt.diffButton.disable();
                                this.ownerCt.fileLabel.removeClass('fileChanged');
                                this.contentChanged = false;
                        } else {
                                this.ownerCt.saveButton.enable();
+                               this.ownerCt.diffButton.enable();
                                this.ownerCt.fileLabel.addClass('fileChanged');
                                this.contentChanged = true;
                        }
@@ -572,8 +791,45 @@ TYPO3.EM.CodeMirror = Ext.extend(Ext.Panel, {
                this.codeMirrorEditor.insertIntoLine(handleForCursorLine, cursorPosition.character, text);
        },
 
-       openText: function(text, parser) {
+       openText: function(text, ext) {
+               var parserName = this.getParserFromExtension(ext);
+               this.codeMirrorEditor.setParser(parserName);
                this.codeMirrorEditor.setCode(text);
+               this.oldSourceCode = text;
+               this.fileLoaded = true;
+       },
+
+       getParserFromExtension: function(ext) {
+               var parser = '';
+               switch(ext.toLowerCase()) {
+                       case 'js':
+                       case 'json':
+                               parser = 'JSParser';
+                       break;
+                       case 'css':
+                               parser = 'CSSParser';
+                       break;
+                       case 'php':
+                       case 'php3':
+                       case 'php4':
+                       case 'php5':
+                       case 'php6':
+                       case 'phpsh':
+                       case 'inc':
+                       case 'html':
+                       case 'htm':
+                       case 'tmpl':
+                       case 'phtml':
+                               parser = 'PHPHTMLMixedParser';
+                       break;
+                       case 'sql':
+                               parser = 'SqlParser';
+                       break;
+                       case 'xml':
+                       default:
+                               parser = 'XMLParser';
+               }
+               return parser;
        }
 
 });
index c018374..90fb497 100644 (file)
@@ -304,7 +304,7 @@ TYPO3.EM.Languages = Ext.extend(Ext.FormPanel, {
 
                buttonPanel.hide();
                progressBar.show();
-           languagegrid.disable();
+               languagegrid.disable();
 
 
                if (button.id === 'lang-checkbutton') {
index cfe664b..1d14dfc 100644 (file)
@@ -47,254 +47,257 @@ TYPO3.EM.LocalList = Ext.extend(Ext.grid.GridPanel, {
                createExpandingRowPanelItems: function(record, rowIndex) {
                        var panelItems = [
                                new Ext.TabPanel({
-                                                       plain: true,
-                                                       activeTab: 0,
-                                                       defaults: {
-                                                               cls: 'gridrowpanel',
-                                                               height: 250
-                                                       },
-                                                       record: record,
-                                                       items:[
-                                                               {
-                                                                       title: TYPO3.lang.msg_info,
-                                                                       html: TYPO3.EM.Layouts.showExtInfo(record.data),
-                                                                       listeners: {
-                                                                               activate: function(panel) {
-                                                                                       var updateScriptLink = Ext.fly('update-check-' + record.data.extkey);
-                                                                                       if (updateScriptLink) {
-                                                                                               updateScriptLink.on('click', function() {
-                                                                                                       panel.getEl().mask('loading');
-                                                                                                       TYPO3.EM.ExtDirect.getExtensionUpdateScript(record.data.extkey, function(response) {
-                                                                                                               panel.getEl().unmask();
-                                                                                                               if (response.success) {
-                                                                                                                       var w = new Ext.Window({
-                                                                                                                                               width: 500,
-                                                                                                                                               height: 500,
-                                                                                                                                               layout: 'fit',
-                                                                                                                                               title: TYPO3.lang.ext_details_updateScript + ' (' + record.data.extkey + ')',
-                                                                                                                                               items: [
-                                                                                                                                                       {
-                                                                                                                                                               xtype: 'iframePanel',
-                                                                                                                                                               id: 'updateScript-' + record.data.extkey
-                                                                                                                                                       }
-                                                                                                                                               ]
-                                                                                                                                       }).show(true, function() {
-                                                                                                                               Ext.getCmp('updateScript-' + record.data.extkey).setUrl('mod.php?M=tools_em&nodoc=1&CMD[showExt]=' + record.data.extkey + '&SET[singleDetails]=updateModule');
-                                                                                                                       });
-                                                                                                               } else {
-                                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.lang.cmd_update, TYPO3.lang.repository_update_not_needed, 5);
-                                                                                                               }
+                                       plain: true,
+                                       activeTab: 0,
+                                       tabPosition: 'top',
+                                       enableTabScroll: true,
+                                       autoWidth: true,
+                                       plugins: [new Ext.ux.plugins.FitWidthToParent()],
+                                       defaults: {
+                                               cls: 'gridrowpanel',
+                                               height: 250
+                                       },
+                                       record: record,
+                                       items:[
+                                               {
+                                                       title: TYPO3.lang.msg_info,
+                                                       html: TYPO3.EM.Layouts.showExtInfo(record.data),
+                                                       listeners: {
+                                                               activate: function(panel) {
+                                                                       var updateScriptLink = Ext.fly('update-check-' + record.data.extkey);
+                                                                       if (updateScriptLink) {
+                                                                               updateScriptLink.on('click', function() {
+                                                                                       panel.getEl().mask('loading');
+                                                                                       TYPO3.EM.ExtDirect.getExtensionUpdateScript(record.data.extkey, function(response) {
+                                                                                               panel.getEl().unmask();
+                                                                                               if (response.success) {
+                                                                                                       var w = new Ext.Window({
+                                                                                                                               width: 500,
+                                                                                                                               height: 500,
+                                                                                                                               layout: 'fit',
+                                                                                                                               title: TYPO3.lang.ext_details_updateScript + ' (' + record.data.extkey + ')',
+                                                                                                                               items: [
+                                                                                                                                       {
+                                                                                                                                               xtype: 'iframePanel',
+                                                                                                                                               id: 'updateScript-' + record.data.extkey
+                                                                                                                                       }
+                                                                                                                               ]
+                                                                                                                       }).show(true, function() {
+                                                                                                               Ext.getCmp('updateScript-' + record.data.extkey).setUrl('mod.php?M=tools_em&nodoc=1&CMD[showExt]=' + record.data.extkey + '&SET[singleDetails]=updateModule');
                                                                                                        });
-                                                                                               }, this);
-                                                                                       }
-
-                                                                               }
-                                                                       }
-                                                               },
-                                                               {
-                                                                       title: TYPO3.lang.msg_dbupdate,
-                                                                       html: TYPO3.EM.App.loadingIndicor,
-                                                                       xtype: 'form',
-                                                                       disabled: record.data.installed === 0,
-                                                                       listeners: {
-                                                                               activate: function(panel) {
-                                                                                       panel.update(TYPO3.EM.App.loadingIndicor);
-                                                                                       TYPO3.EM.ExtDirect.getExtensionUpdate(record.data.extkey, function(response) {
-                                                                                               panel.update(response, true, this.readUpdateForm.createDelegate(this));
-                                                                                       }, this);
-                                                                               }
-                                                                       },
-                                                                       scope: this,
-                                                                       readUpdateForm: function() {
-                                                                               var button = Ext.get('update-submit-' + record.data.extkey);
-                                                                               Ext.apply(this.form, {
-                                                                                                       api: {
-                                                                                                               submit: TYPO3.EM.ExtDirect.saveExtensionConfiguration
-                                                                                                       },
-                                                                                                       paramsAsHash: false
-                                                                                               });
-                                                                               if (button) {
-                                                                                       button.on('click', function() {
-                                                                                               this.doUpdate(false);
-                                                                                       }, this);
-                                                                               }
-                                                                       },
-                                                                       doUpdate: function(noSave) {
-                                                                               this.form.submit({
-                                                                                                       waitMsg : noSave ? ' ' : TYPO3.lang.action_updateDatabase,
-                                                                                                       params: {
-                                                                                                               extkey: record.data.extkey,
-                                                                                                               exttype: record.data.typeShort,
-                                                                                                               noSave: noSave
-                                                                                                       },
-                                                                                                       success: function(form, action) {
-                                                                                                               this.ownerCt.activeTab.update(TYPO3.EM.App.loadingIndicor);
-                                                                                                               TYPO3.EM.ExtDirect.getExtensionUpdate(record.data.extkey, function(response) {
-                                                                                                                       this.ownerCt.activeTab.update(response, true, this.readUpdateForm.createDelegate(this));
-                                                                                                               }, this);
-                                                                                                       },
-                                                                                                       failure: function(form, action) {
-                                                                                                               if (action.failureType === Ext.form.Action.CONNECT_FAILURE) {
-                                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.msg_error,
-                                                                                                                                       TYPO3.lang.msg_error + ':' + action.response.status + ': ' +
-                                                                                                                                                       action.response.statusText, 5);
-                                                                                                               }
-                                                                                                               if (action.failureType === Ext.form.Action.SERVER_INVALID) {
-                                                                                                                       // server responded with success = false
-                                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.invalid, action.result.errormsg, 5);
-                                                                                                               }
-                                                                                                       },
-                                                                                                       scope: this
-                                                                                               });
+                                                                                               } else {
+                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.lang.cmd_update, TYPO3.lang.repository_update_not_needed, 5);
+                                                                                               }
+                                                                                       });
+                                                                               }, this);
                                                                        }
-                                                               },
-                                                               {
-                                                                       title: TYPO3.lang.msg_configuration,
-                                                                       xtype: 'form',
-                                                                       disabled: record.data.installed === 0,
-                                                                       html: TYPO3.EM.App.loadingIndicor,
-                                                                       listeners: {
-                                                                               activate: function(panel) {
-                                                                                       panel.update(TYPO3.EM.App.loadingIndicor);
-                                                                                       TYPO3.EM.ExtDirect.getExtensionConfiguration(record.data.extkey, function(response) {
-                                                                                               panel.update(response, true, this.readConfigForm.createDelegate(this));
-                                                                                       }, this);
-                                                                               }
-                                                                       },
-                                                                       scope: this,
-                                                                       readConfigForm: function() {
-                                                                               var button = Ext.get('configuration-submit-' + record.data.extkey);
-                                                                               if (!button) {
-                                                                                       var button = Ext.get('update-submit-' + record.data.extkey);
-                                                                               }
-                                                                               var select = Ext.select('.mod-menu-template-select');
-                                                                               Ext.apply(this.form, {
-                                                                                                       api: {
-                                                                                                               submit: TYPO3.EM.ExtDirect.saveExtensionConfiguration
-                                                                                                       },
-                                                                                                       paramsAsHash: false
-                                                                                               });
-                                                                               if (select) {
-                                                                                       var converted = new Ext.form.ComboBox({
-                                                                                                               transform: select.elements[0],
-                                                                                                               typeAhead: true,
-                                                                                                               listeners: {
-                                                                                                                       beforequery: function(o) {
-                                                                                                                               o.forceAll = true;
-                                                                                                                       },
-                                                                                                                       select: function() {
-                                                                                                                               this.doSubmit(true);
-                                                                                                                       },
-                                                                                                                       scope: this
-                                                                                                               }
-                                                                                                       });
-                                                                               }
-                                                                               if (button) {
-                                                                                       button.on('click', function() {
-                                                                                               this.doSubmit(false);
-                                                                                       }, this);
-                                                                               }
-                                                                       },
-                                                                       doSubmit: function(noSave) {
-                                                                               this.form.submit({
-                                                                                                       waitMsg : noSave ? ' ' : TYPO3.lang.action_saving_settings,
-                                                                                                       params: {
-                                                                                                               extkey: record.data.extkey,
-                                                                                                               exttype: record.data.typeShort,
-                                                                                                               noSave: noSave
-                                                                                                       },
-                                                                                                       success: function(form, action) {
-                                                                                                               if (action.result.html) {
-                                                                                                                       this.ownerCt.activeTab.update(action.result.html, true, this.readConfigForm.createDelegate(this));
-                                                                                                               } else {
-                                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.msg_configuration, TYPO3.lang.configurationSaved, 5);
-                                                                                                               }
+
+                                                               }
+                                                       }
+                                               },
+                                               {
+                                                       title: TYPO3.lang.msg_dbupdate,
+                                                       html: TYPO3.EM.App.loadingIndicor,
+                                                       xtype: 'form',
+                                                       disabled: record.data.installed === 0,
+                                                       listeners: {
+                                                               activate: function(panel) {
+                                                                       panel.update(TYPO3.EM.App.loadingIndicor);
+                                                                       TYPO3.EM.ExtDirect.getExtensionUpdate(record.data.extkey, function(response) {
+                                                                               panel.update(response, true, this.readUpdateForm.createDelegate(this));
+                                                                       }, this);
+                                                               }
+                                                       },
+                                                       scope: this,
+                                                       readUpdateForm: function() {
+                                                               var button = Ext.get('update-submit-' + record.data.extkey);
+                                                               Ext.apply(this.form, {
+                                                                                       api: {
+                                                                                               submit: TYPO3.EM.ExtDirect.saveExtensionConfiguration
+                                                                                       },
+                                                                                       paramsAsHash: false
+                                                                               });
+                                                               if (button) {
+                                                                       button.on('click', function() {
+                                                                               this.doUpdate(false);
+                                                                       }, this);
+                                                               }
+                                                       },
+                                                       doUpdate: function(noSave) {
+                                                               this.form.submit({
+                                                                                       waitMsg : noSave ? ' ' : TYPO3.lang.action_updateDatabase,
+                                                                                       params: {
+                                                                                               extkey: record.data.extkey,
+                                                                                               exttype: record.data.typeShort,
+                                                                                               noSave: noSave
+                                                                                       },
+                                                                                       success: function(form, action) {
+                                                                                               this.ownerCt.activeTab.update(TYPO3.EM.App.loadingIndicor);
+                                                                                               TYPO3.EM.ExtDirect.getExtensionUpdate(record.data.extkey, function(response) {
+                                                                                                       this.ownerCt.activeTab.update(response, true, this.readUpdateForm.createDelegate(this));
+                                                                                               }, this);
+                                                                                       },
+                                                                                       failure: function(form, action) {
+                                                                                               if (action.failureType === Ext.form.Action.CONNECT_FAILURE) {
+                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.msg_error,
+                                                                                                                       TYPO3.lang.msg_error + ':' + action.response.status + ': ' +
+                                                                                                                                       action.response.statusText, 5);
+                                                                                               }
+                                                                                               if (action.failureType === Ext.form.Action.SERVER_INVALID) {
+                                                                                                       // server responded with success = false
+                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.invalid, action.result.errormsg, 5);
+                                                                                               }
+                                                                                       },
+                                                                                       scope: this
+                                                                               });
+                                                       }
+                                               },
+                                               {
+                                                       title: TYPO3.lang.msg_configuration,
+                                                       xtype: 'form',
+                                                       disabled: record.data.installed === 0,
+                                                       html: TYPO3.EM.App.loadingIndicor,
+                                                       listeners: {
+                                                               activate: function(panel) {
+                                                                       panel.update(TYPO3.EM.App.loadingIndicor);
+                                                                       TYPO3.EM.ExtDirect.getExtensionConfiguration(record.data.extkey, function(response) {
+                                                                               panel.update(response, true, this.readConfigForm.createDelegate(this));
+                                                                       }, this);
+                                                               }
+                                                       },
+                                                       scope: this,
+                                                       readConfigForm: function() {
+                                                               var button = Ext.get('configuration-submit-' + record.data.extkey);
+                                                               if (!button) {
+                                                                       var button = Ext.get('update-submit-' + record.data.extkey);
+                                                               }
+                                                               var select = Ext.select('.mod-menu-template-select');
+                                                               Ext.apply(this.form, {
+                                                                                       api: {
+                                                                                               submit: TYPO3.EM.ExtDirect.saveExtensionConfiguration
+                                                                                       },
+                                                                                       paramsAsHash: false
+                                                                               });
+                                                               if (select) {
+                                                                       var converted = new Ext.form.ComboBox({
+                                                                                               transform: select.elements[0],
+                                                                                               typeAhead: true,
+                                                                                               listeners: {
+                                                                                                       beforequery: function(o) {
+                                                                                                               o.forceAll = true;
                                                                                                        },
-                                                                                                       failure: function(form, action) {
-                                                                                                               if (action.failureType === Ext.form.Action.CONNECT_FAILURE) {
-                                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.msg_error,
-                                                                                                                                       TYPO3.lang.msg_error + ':' + action.response.status + ': ' +
-                                                                                                                                                       action.response.statusText, 5);
-                                                                                                               }
-                                                                                                               if (action.failureType === Ext.form.Action.SERVER_INVALID) {
-                                                                                                                       // server responded with success = false
-                                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.invalid, action.result.errormsg, 5);
-                                                                                                               }
+                                                                                                       select: function() {
+                                                                                                               this.doSubmit(true);
                                                                                                        },
                                                                                                        scope: this
-                                                                                               });
-                                                                       }
-                                                               },
-                                                               {
-                                                                       title: TYPO3.lang.msg_files,
-                                                                       xtype: 'extfilelist',
-                                                                       recordData: record.data,
-                                                                       cls: 'gridrowfilespanel'
-                                                               },
-                                                               {
-                                                                       xtype: 'terupload',
-                                                                       title: TYPO3.lang.cmd_terupload,
-                                                                       recordData: record.data,
-                                                                       disabled: !TYPO3.settings.EM.hasCredentials
-                                                               },
-                                                               {
-                                                                       title: TYPO3.lang.msg_developerinformation,
-                                                                       html: '<div class="loading-indicator">' + TYPO3.lang.action_loading + '</div>',
-                                                                       listeners: {
-                                                                               activate: function(panel) {
-                                                                                       TYPO3.EM.ExtDirect.getExtensionDevelopInfo(record.data.extkey, function(response) {
-                                                                                               panel.update(response);
-                                                                                       });
-                                                                               }
-                                                                       }
-                                                               },
-                                                               {
-                                                                       title: TYPO3.lang.details_maintenance,
-                                                                       //disabled: record.data.installed === 0,
-                                                                       html: TYPO3.EM.App.loadingIndicor,
-                                                                       listeners: {
-                                                                               activate: function(panel) {
-                                                                                       TYPO3.EM.ExtDirect.getExtensionBackupDelete(record.data.extkey, function(response) {
-                                                                                               panel.update(response, true, this.readBackupDeleteLinks.createDelegate(this));
-                                                                                       }, this);
-                                                                               }
-                                                                       },
-                                                                       scope: this,
-                                                                       readBackupDeleteLinks: function() {
-                                                                               var emconflink = Ext.select('a.emconfLink');
-                                                                               if (emconflink.elements.length) {
-                                                                                       var link = emconflink.elements[0];
-                                                                                       link.removeAttribute('onclick');
-                                                                                       Ext.get(link).on('click', function() {
-                                                                                               this.waitBox = Ext.Msg.wait(TYPO3.lang.ext_details_update_em_conf, record.data.extkey);
-                                                                                               TYPO3.EM.ExtDirect.cleanEmConf(record.data.extkey, function(response) {
-                                                                                                       this.waitBox.hide();
-                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.ext_details_update_em_conf, response.result, 5);
-                                                                                               }, this);
+                                                                                               }
                                                                                        });
-                                                                               }
-                                                                               var deletelink = Ext.select('a.deleteLink');
-                                                                               if (deletelink.elements.length) {
-                                                                                       var link = deletelink.elements[0];
-                                                                                       link.removeAttribute('onclick');
-                                                                                       Ext.get(link).on('click', function() {
-                                                                                               this.waitBox = Ext.Msg.wait(TYPO3.lang.extDelete_from_server, record.data.extkey);
-                                                                                               TYPO3.EM.ExtDirect.deleteExtension(record.data.extkey, function(response) {
-                                                                                                       this.waitBox.hide();
-                                                                                                       if (response.success) {
-                                                                                                               TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.msg_extkexDeletedSuccess, response.result, 5);
-                                                                                                               Ext.StoreMgr.get('localstore').remove(record);
-                                                                                                       } else {
-                                                                                                               TYPO3.Flashmessage.display(TYPO3.Severity.error, response.error, response.result, 5);
-                                                                                                       }
-                                                                                               }, this);
-                                                                                       });
-                                                                               }
-
-                                                                       }
                                                                }
-                                                       ]
-                                               })
+                                                               if (button) {
+                                                                       button.on('click', function() {
+                                                                               this.doSubmit(false);
+                                                                       }, this);
+                                                               }
+                                                       },
+                                                       doSubmit: function(noSave) {
+                                                               this.form.submit({
+                                                                                       waitMsg : noSave ? ' ' : TYPO3.lang.action_saving_settings,
+                                                                                       params: {
+                                                                                               extkey: record.data.extkey,
+                                                                                               exttype: record.data.typeShort,
+                                                                                               noSave: noSave
+                                                                                       },
+                                                                                       success: function(form, action) {
+                                                                                               if (action.result.html) {
+                                                                                                       this.ownerCt.activeTab.update(action.result.html, true, this.readConfigForm.createDelegate(this));
+                                                                                               } else {
+                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.msg_configuration, TYPO3.lang.configurationSaved, 5);
+                                                                                               }
+                                                                                       },
+                                                                                       failure: function(form, action) {
+                                                                                               if (action.failureType === Ext.form.Action.CONNECT_FAILURE) {
+                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.msg_error,
+                                                                                                                       TYPO3.lang.msg_error + ':' + action.response.status + ': ' +
+                                                                                                                                       action.response.statusText, 5);
+                                                                                               }
+                                                                                               if (action.failureType === Ext.form.Action.SERVER_INVALID) {
+                                                                                                       // server responded with success = false
+                                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.lang.invalid, action.result.errormsg, 5);
+                                                                                               }
+                                                                                       },
+                                                                                       scope: this
+                                                                               });
+                                                       }
+                                               },
+                                               {
+                                                       title: TYPO3.lang.msg_files,
+                                                       xtype: 'extfilelist',
+                                                       recordData: record.data,
+                                                       cls: 'gridrowfilespanel'
+                                               },
+                                               {
+                                                       xtype: 'terupload',
+                                                       title: TYPO3.lang.cmd_terupload,
+                                                       recordData: record.data,
+                                                       disabled: !TYPO3.settings.EM.hasCredentials
+                                               },
+                                               {
+                                                       title: TYPO3.lang.msg_developerinformation,
+                                                       html: '<div class="loading-indicator">' + TYPO3.lang.action_loading + '</div>',
+                                                       listeners: {
+                                                               activate: function(panel) {
+                                                                       TYPO3.EM.ExtDirect.getExtensionDevelopInfo(record.data.extkey, function(response) {
+                                                                               panel.update(response);
+                                                                       });
+                                                               }
+                                                       }
+                                               },
+                                               {
+                                                       title: TYPO3.lang.details_maintenance,
+                                                       html: TYPO3.EM.App.loadingIndicor,
+                                                       listeners: {
+                                                               activate: function(panel) {
+                                                                       TYPO3.EM.ExtDirect.getExtensionBackupDelete(record.data.extkey, function(response) {
+                                                                               panel.update(response, true, this.readBackupDeleteLinks.createDelegate(this));
+                                                                       }, this);
+                                                               }
+                                                       },
+                                                       scope: this,
+                                                       readBackupDeleteLinks: function() {
+                                                               var emconflink = Ext.select('a.emconfLink');
+                                                               if (emconflink.elements.length) {
+                                                                       var link = emconflink.elements[0];
+                                                                       link.removeAttribute('onclick');
+                                                                       Ext.get(link).on('click', function() {
+                                                                               this.waitBox = Ext.Msg.wait(TYPO3.lang.ext_details_update_em_conf, record.data.extkey);
+                                                                               TYPO3.EM.ExtDirect.cleanEmConf(record.data.extkey, function(response) {
+                                                                                       this.waitBox.hide();
+                                                                                       TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.ext_details_update_em_conf, response.result, 5);
+                                                                               }, this);
+                                                                       });
+                                                               }
+                                                               var deletelink = Ext.select('a.deleteLink');
+                                                               if (deletelink.elements.length) {
+                                                                       var link = deletelink.elements[0];
+                                                                       link.removeAttribute('onclick');
+                                                                       Ext.get(link).on('click', function() {
+                                                                               this.waitBox = Ext.Msg.wait(TYPO3.lang.extDelete_from_server, record.data.extkey);
+                                                                               TYPO3.EM.ExtDirect.deleteExtension(record.data.extkey, function(response) {
+                                                                                       this.waitBox.hide();
+                                                                                       if (response.success) {
+                                                                                               TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.lang.msg_extkexDeletedSuccess, response.result, 5);
+                                                                                               Ext.StoreMgr.get('localstore').remove(record);
+                                                                                       } else {
+                                                                                               TYPO3.Flashmessage.display(TYPO3.Severity.error, response.error, response.result, 5);
+                                                                                       }
+                                                                               }, this);
+                                                                       });
+                                                               }
+
+                                                       }
+                                               }
+                                       ]
+                               })
                        ];
                        return panelItems;
                }
@@ -319,6 +322,7 @@ TYPO3.EM.LocalList = Ext.extend(Ext.grid.GridPanel, {
                                                        {name:'version'},
                                                        {name:'type'},
                                                        {name:'state'},
+                                                       {name:'stateCls'},
                                                        {name:'icon'},
                                                        {name:'description'},
                                                        {name:'shy'},
index 5e439e6..27ef1e4 100644 (file)
@@ -49,7 +49,8 @@ TYPO3.EM.RepositoryList = Ext.extend(Ext.grid.GridPanel, {
                                        plain: true,
                                        activeTab: 0,
                                        defaults: {
-                                               autoHeight: true
+                                               autoHeight: true,
+                                               autoWidth: true
                                        },
                                        record: record,
                                        items:[
@@ -85,6 +86,7 @@ TYPO3.EM.RepositoryList = Ext.extend(Ext.grid.GridPanel, {
                                {name:'downloadcounter', type: 'int'},
                                {name:'statevalue'},
                                {name:'state'},
+                               {name:'stateCls'},
                                {name:'icon'},
                                {name:'description'},
                                {name:'lastuploaddate', type: 'date', dateFormat: 'timestamp'},
index a2af58d..83880af 100644 (file)
@@ -309,9 +309,9 @@ TYPO3.EM.Settings = Ext.extend(Ext.FormPanel, {
 
        saveFormHandler: function() {
                this.getForm().submit({
-                       waitMsg : 'Saving Settings...',
+                       waitMsg : TYPO3.lang.action_saving_settings,
                        success: function(form, action) {
-                               TYPO3.Flashmessage.display(TYPO3.Severity.information,'Settings', 'Settings were saved ', 5);
+                               TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.lang.menu_settings, TYPO3.lang.settingsSaved, 5);
                                TYPO3.settings.EM.hasCredentials = (action.result.data.fe_u !== '' && action.result.data.fe_p !== '');
                                        // enable/disable user extension tab
                                if (TYPO3.settings.EM.hasCredentials) {
@@ -499,8 +499,8 @@ TYPO3.EM.EditRepository = Ext.extend(Ext.Window, {
                        waitMsg : type === 0 ? TYPO3.lang.repository_saving : TYPO3.lang.repository_creating,
                        success: function(form, action) {
                                TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.lang.repository, type == 0
-                                               ? String.format(TYPO3.lang.repository_created, action.result.params.title)
-                                               : String.format(TYPO3.lang.repository_created, action.result.params.title)
+                                               ? String.format(TYPO3.lang.repository_saved, action.result.params.title)
+                                               : String.format(TYPO3.lang.repository_saved, action.result.params.title)
                                                , 5);
                                Ext.StoreMgr.get('repositoriessettings').load();
                                this.close();
index ccd8434..6e821cb 100644 (file)
@@ -339,4 +339,32 @@ Ext.ux.grid.RowPanelExpander = Ext.extend(Ext.util.Observable, {
        }
 });
 
-Ext.preg('rowexpander', Ext.ux.grid.RowPanelExpander);
\ No newline at end of file
+Ext.preg('rowexpander', Ext.ux.grid.RowPanelExpander);
+
+Ext.ux.plugins.FitWidthToParent = Ext.extend(Object, {
+       constructor : function(parent) {
+               this.parent = parent;
+       },
+       init : function(c) {
+               c.on('render', function(c) {
+                       c.fitToElement = Ext.get(this.parent
+                                       || c.getPositionEl().dom.parentNode);
+                       if (!c.doLayout) {
+                               this.fitSizeToParent();
+                               Ext.EventManager.onWindowResize(this.fitSizeToParent, this);
+                       }
+               }, this, {
+                       single : true
+               });
+               if (c.doLayout) {
+                       c.monitorResize = true;
+                       c.doLayout = c.doLayout.createInterceptor(this.fitSizeToParent);
+               }
+       },
+
+       fitSizeToParent : function() {
+               var pos = this.getPosition(true), size = this.fitToElement.getViewSize();
+               this.setWidth(size.width - pos[0]);
+
+       }
+});
\ No newline at end of file
index bedacf8..ee8103d 100644 (file)
-/*!
- * Ext JS Library 3.1.1
- * Copyright(c) 2006-2010 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
+/*!\r
+ * Ext JS Library 3.1.1\r
+ * Copyright(c) 2006-2010 Ext JS, LLC\r
+ * licensing@extjs.com\r
+ * http://www.extjs.com/license\r
+ */\r
 Ext.namespace('Ext.ux.grid.filter');\r
 \r
-/**
+/**\r
  * @class Ext.ux.grid.filter.Filter\r
  * @extends Ext.util.Observable\r
  * Abstract base class for filter implementations.\r
  */\r
 Ext.ux.grid.filter.Filter = Ext.extend(Ext.util.Observable, {\r
-       /**
-        * @cfg {Boolean} active
-        * Indicates the initial status of the filter (defaults to false).
-        */
-       active : false,
-       /**
-        * True if this filter is active.  Use setActive() to alter after configuration.
-        * @type Boolean
-        * @property active
-        */
-       /**
-        * @cfg {String} dataIndex
-        * The {@link Ext.data.Store} dataIndex of the field this filter represents.
-        * The dataIndex does not actually have to exist in the store.
-        */
-       dataIndex : null,
-       /**
-        * The filter configuration menu that will be installed into the filter submenu of a column menu.
-        * @type Ext.menu.Menu
-        * @property
-        */
-       menu : null,
-       /**
-        * @cfg {Number} updateBuffer
-        * Number of milliseconds to wait after user interaction to fire an update. Only supported
-        * by filters: 'list', 'numeric', and 'string'. Defaults to 500.
-        */
-       updateBuffer : 500,
+       /**\r
+        * @cfg {Boolean} active\r
+        * Indicates the initial status of the filter (defaults to false).\r
+        */\r
+       active : false,\r
+       /**\r
+        * True if this filter is active.  Use setActive() to alter after configuration.\r
+        * @type Boolean\r
+        * @property active\r
+        */\r
+       /**\r
+        * @cfg {String} dataIndex\r
+        * The {@link Ext.data.Store} dataIndex of the field this filter represents.\r
+        * The dataIndex does not actually have to exist in the store.\r
+        */\r
+       dataIndex : null,\r
+       /**\r
+        * The filter configuration menu that will be installed into the filter submenu of a column menu.\r
+        * @type Ext.menu.Menu\r
+        * @property\r
+        */\r
+       menu : null,\r
+       /**\r
+        * @cfg {Number} updateBuffer\r
+        * Number of milliseconds to wait after user interaction to fire an update. Only supported\r
+        * by filters: 'list', 'numeric', and 'string'. Defaults to 500.\r
+        */\r
+       updateBuffer : 500,\r
+\r
+       constructor : function (config) {\r
+               Ext.apply(this, config);\r
+\r
+               this.addEvents(\r
+                               /**\r
+                                * @event activate\r
+                                * Fires when an inactive filter becomes active\r
+                                * @param {Ext.ux.grid.filter.Filter} this\r
+                                */\r
+                               'activate',\r
+                               /**\r
+                                * @event deactivate\r
+                                * Fires when an active filter becomes inactive\r
+                                * @param {Ext.ux.grid.filter.Filter} this\r
+                                */\r
+                               'deactivate',\r
+                               /**\r
+                                * @event serialize\r
+                                * Fires after the serialization process. Use this to attach additional parameters to serialization\r
+                                * data before it is encoded and sent to the server.\r
+                                * @param {Array/Object} data A map or collection of maps representing the current filter configuration.\r
+                                * @param {Ext.ux.grid.filter.Filter} filter The filter being serialized.\r
+                                */\r
+                               'serialize',\r
+                               /**\r
+                                * @event update\r
+                                * Fires when a filter configuration has changed\r
+                                * @param {Ext.ux.grid.filter.Filter} this The filter object.\r
+                                */\r
+                               'update'\r
+               );\r
+               Ext.ux.grid.filter.Filter.superclass.constructor.call(this);\r
+\r
+               this.menu = new Ext.menu.Menu();\r
+               this.init(config);\r
+               if (config && config.value) {\r
+                       this.setValue(config.value);\r
+                       this.setActive(config.active !== false, true);\r
+                       delete config.value;\r
+               }\r
+       },\r
+\r
+       /**\r
+        * Destroys this filter by purging any event listeners, and removing any menus.\r
+        */\r
+       destroy : function() {\r
+               if (this.menu) {\r
+                       this.menu.destroy();\r
+               }\r
+               this.purgeListeners();\r
+       },\r
+\r
+       /**\r
+        * Template method to be implemented by all subclasses that is to\r
+        * initialize the filter and install required menu items.\r
+        * Defaults to Ext.emptyFn.\r
+        */\r
+       init : Ext.emptyFn,\r
+\r
+       /**\r
+        * Template method to be implemented by all subclasses that is to\r
+        * get and return the value of the filter.\r
+        * Defaults to Ext.emptyFn.\r
+        * @return {Object} The 'serialized' form of this filter\r
+        * @methodOf Ext.ux.grid.filter.Filter\r
+        */\r
+       getValue : Ext.emptyFn,\r
 \r
-       constructor : function (config) {
-               Ext.apply(this, config);
+       /**\r
+        * Template method to be implemented by all subclasses that is to\r
+        * set the value of the filter and fire the 'update' event.\r
+        * Defaults to Ext.emptyFn.\r
+        * @param {Object} data The value to set the filter\r
+        * @methodOf Ext.ux.grid.filter.Filter\r
+        */\r
+       setValue : Ext.emptyFn,\r
 \r
-               this.addEvents(
-                               /**
-                                * @event activate
-                                * Fires when an inactive filter becomes active
-                                * @param {Ext.ux.grid.filter.Filter} this
-                                */
-                               'activate',
-                               /**
-                                * @event deactivate
-                                * Fires when an active filter becomes inactive
-                                * @param {Ext.ux.grid.filter.Filter} this
-                                */
-                               'deactivate',
-                               /**
-                                * @event serialize
-                                * Fires after the serialization process. Use this to attach additional parameters to serialization
-                                * data before it is encoded and sent to the server.
-                                * @param {Array/Object} data A map or collection of maps representing the current filter configuration.
-                                * @param {Ext.ux.grid.filter.Filter} filter The filter being serialized.
-                                */
-                               'serialize',
-                               /**
-                                * @event update
-                                * Fires when a filter configuration has changed
-                                * @param {Ext.ux.grid.filter.Filter} this The filter object.
-                                */
-                               'update'
-               );
-               Ext.ux.grid.filter.Filter.superclass.constructor.call(this);
+       /**\r
+        * Template method to be implemented by all subclasses that is to\r
+        * return <tt>true</tt> if the filter has enough configuration information to be activated.\r
+        * Defaults to <tt>return true</tt>.\r
+        * @return {Boolean}\r
+        */\r
+       isActivatable : function() {\r
+               return true;\r
+       },\r
 \r
-               this.menu = new Ext.menu.Menu();
-               this.init(config);
-               if (config && config.value) {
-                       this.setValue(config.value);
-                       this.setActive(config.active !== false, true);
-                       delete config.value;
-               }
-       },
+       /**\r
+        * Template method to be implemented by all subclasses that is to\r
+        * get and return serialized filter data for transmission to the server.\r
+        * Defaults to Ext.emptyFn.\r
+        */\r
+       getSerialArgs : Ext.emptyFn,\r
 \r
-       /**
-        * Destroys this filter by purging any event listeners, and removing any menus.
-        */
-       destroy : function() {
-               if (this.menu) {
-                       this.menu.destroy();
-               }
-               this.purgeListeners();
-       },
+       /**\r
+        * Template method to be implemented by all subclasses that is to\r
+        * validates the provided Ext.data.Record against the filters configuration.\r
+        * Defaults to <tt>return true</tt>.\r
+        * @param {Ext.data.Record} record The record to validate\r
+        * @return {Boolean} true if the record is valid within the bounds\r
+        * of the filter, false otherwise.\r
+        */\r
+       validateRecord : function() {\r
+               return true;\r
+       },\r
 \r
-       /**
-        * Template method to be implemented by all subclasses that is to
-        * initialize the filter and install required menu items.
-        * Defaults to Ext.emptyFn.
-        */
-       init : Ext.emptyFn,
+       /**\r
+        * Returns the serialized filter data for transmission to the server\r
+        * and fires the 'serialize' event.\r
+        * @return {Object/Array} An object or collection of objects containing\r
+        * key value pairs representing the current configuration of the filter.\r
+        * @methodOf Ext.ux.grid.filter.Filter\r
+        */\r
+       serialize : function() {\r
+               var args = this.getSerialArgs();\r
+               this.fireEvent('serialize', args, this);\r
+               return args;\r
+       },\r
 \r
-       /**
-        * Template method to be implemented by all subclasses that is to
-        * get and return the value of the filter.
-        * Defaults to Ext.emptyFn.
-        * @return {Object} The 'serialized' form of this filter
-        * @methodOf Ext.ux.grid.filter.Filter
-        */
-       getValue : Ext.emptyFn,
+       /** @private */\r
+       fireUpdate : function() {\r
+               if (this.active) {\r
+                       this.fireEvent('update', this);\r
+               }\r
+               this.setActive(this.isActivatable());\r
+       },\r
 \r
-       /**
-        * Template method to be implemented by all subclasses that is to
-        * set the value of the filter and fire the 'update' event.
-        * Defaults to Ext.emptyFn.
-        * @param {Object} data The value to set the filter
-        * @methodOf Ext.ux.grid.filter.Filter
-        */
-       setValue : Ext.emptyFn,
-
-       /**
-        * Template method to be implemented by all subclasses that is to
-        * return <tt>true</tt> if the filter has enough configuration information to be activated.
-        * Defaults to <tt>return true</tt>.
-        * @return {Boolean}
-        */
-       isActivatable : function() {
-               return true;
-       },
-
-       /**
-        * Template method to be implemented by all subclasses that is to
-        * get and return serialized filter data for transmission to the server.
-        * Defaults to Ext.emptyFn.
-        */
-       getSerialArgs : Ext.emptyFn,
-
-       /**
-        * Template method to be implemented by all subclasses that is to
-        * validates the provided Ext.data.Record against the filters configuration.
-        * Defaults to <tt>return true</tt>.
-        * @param {Ext.data.Record} record The record to validate
-        * @return {Boolean} true if the record is valid within the bounds
-        * of the filter, false otherwise.
-        */
-       validateRecord : function() {
-               return true;
-       },
-
-       /**
-        * Returns the serialized filter data for transmission to the server
-        * and fires the 'serialize' event.
-        * @return {Object/Array} An object or collection of objects containing
-        * key value pairs representing the current configuration of the filter.
-        * @methodOf Ext.ux.grid.filter.Filter
-        */
-       serialize : function() {
-               var args = this.getSerialArgs();
-               this.fireEvent('serialize', args, this);
-               return args;
-       },
-
-       /** @private */
-       fireUpdate : function() {
-               if (this.active) {
-                       this.fireEvent('update', this);
-               }
-               this.setActive(this.isActivatable());
-       },
-
-       /**
-        * Sets the status of the filter and fires the appropriate events.
-        * @param {Boolean} active              The new filter state.
-        * @param {Boolean} suppressEvent True to prevent events from being fired.
-        * @methodOf Ext.ux.grid.filter.Filter
-        */
-       setActive : function(active, suppressEvent) {
-               if (this.active != active) {
-                       this.active = active;
-                       if (suppressEvent !== true) {
-                               this.fireEvent(active ? 'activate' : 'deactivate', this);
-                       }
-               }
-       }
+       /**\r
+        * Sets the status of the filter and fires the appropriate events.\r
+        * @param {Boolean} active              The new filter state.\r
+        * @param {Boolean} suppressEvent True to prevent events from being fired.\r
+        * @methodOf Ext.ux.grid.filter.Filter\r
+        */\r
+       setActive : function(active, suppressEvent) {\r
+               if (this.active != active) {\r
+                       this.active = active;\r
+                       if (suppressEvent !== true) {\r
+                               this.fireEvent(active ? 'activate' : 'deactivate', this);\r
+                       }\r
+               }\r
+       }\r
 });
\ No newline at end of file
index e6b9699..0f61b32 100644 (file)
@@ -1,10 +1,10 @@
-/*!
- * Ext JS Library 3.1.1
- * Copyright(c) 2006-2010 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
-/**
+/*!\r
+ * Ext JS Library 3.1.1\r
+ * Copyright(c) 2006-2010 Ext JS, LLC\r
+ * licensing@extjs.com\r
+ * http://www.extjs.com/license\r
+ */\r
+/**\r
  * @class Ext.ux.grid.filter.ListFilter\r
  * @extends Ext.ux.grid.filter.Filter\r
  * <p>List filters are able to be preloaded/backed by an Ext.data.Store to load\r
  * {@link Ext.ux.menu.ListMenu} component.</p>\r
  * <p>Although not shown here, this class accepts all configuration options\r
  * for {@link Ext.ux.menu.ListMenu}.</p>\r
- *
+ *\r
  * <p><b><u>Example Usage:</u></b></p>\r
- * <pre><code>
- var filters = new Ext.ux.grid.GridFilters({
- ...
- filters: [{
- type: 'list',
- dataIndex: 'size',
- phpMode: true,
- // options will be used as data to implicitly creates an ArrayStore
- options: ['extra small', 'small', 'medium', 'large', 'extra large']
- }]
- });
+ * <pre><code>\r
+ var filters = new Ext.ux.grid.GridFilters({\r
+ ...\r
+ filters: [{\r
+ type: 'list',\r
+ dataIndex: 'size',\r
+ phpMode: true,\r
+ // options will be used as data to implicitly creates an ArrayStore\r
+ options: ['extra small', 'small', 'medium', 'large', 'extra large']\r
+ }]\r
+ });\r
  * </code></pre>\r
- *
+ *\r
  */\r
 Ext.ux.grid.filter.ListFilter = Ext.extend(Ext.ux.grid.filter.Filter, {\r
 \r
-       /**
-        * @cfg {Array} options
-        * <p><code>data</code> to be used to implicitly create a data store
-        * to back this list when the data source is <b>local</b>. If the
-        * data for the list is remote, use the <code>{@link #store}</code>
-        * config instead.</p>
-        * <br><p>Each item within the provided array may be in one of the
-        * following formats:</p>
-        * <div class="mdetail-params"><ul>
-        * <li><b>Array</b> :
-        * <pre><code>
-        options: [
-        [11, 'extra small'],
-        [18, 'small'],
-        [22, 'medium'],
-        [35, 'large'],
-        [44, 'extra large']
-        ]
-        * </code></pre>
-        * </li>
-        * <li><b>Object</b> :
-        * <pre><code>
-        labelField: 'name', // override default of 'text'
-        options: [
-        {id: 11, name:'extra small'},
-        {id: 18, name:'small'},
-        {id: 22, name:'medium'},
-        {id: 35, name:'large'},
-        {id: 44, name:'extra large'}
-        ]
-        * </code></pre>
-        * </li>
-        * <li><b>String</b> :
-        * <pre><code>
-        * options: ['extra small', 'small', 'medium', 'large', 'extra large']
-        * </code></pre>
-        * </li>
-        */
-       /**
-        * @cfg {Boolean} phpMode
-        * <p>Adjust the format of this filter. Defaults to false.</p>
-        * <br><p>When GridFilters <code>@cfg encode = false</code> (default):</p>
-        * <pre><code>
-        // phpMode == false (default):
-        filter[0][data][type] list
-        filter[0][data][value] value1
-        filter[0][data][value] value2
-        filter[0][field] prod
+       /**\r
+        * @cfg {Array} options\r
+        * <p><code>data</code> to be used to implicitly create a data store\r
+        * to back this list when the data source is <b>local</b>. If the\r
+        * data for the list is remote, use the <code>{@link #store}</code>\r
+        * config instead.</p>\r
+        * <br><p>Each item within the provided array may be in one of the\r
+        * following formats:</p>\r
+        * <div class="mdetail-params"><ul>\r
+        * <li><b>Array</b> :\r
+        * <pre><code>\r
+        options: [\r
+        [11, 'extra small'],\r
+        [18, 'small'],\r
+        [22, 'medium'],\r
+        [35, 'large'],\r
+        [44, 'extra large']\r
+        ]\r
+        * </code></pre>\r
+        * </li>\r
+        * <li><b>Object</b> :\r
+        * <pre><code>\r
+        labelField: 'name', // override default of 'text'\r
+        options: [\r
+        {id: 11, name:'extra small'},\r
+        {id: 18, name:'small'},\r
+        {id: 22, name:'medium'},\r
+        {id: 35, name:'large'},\r
+        {id: 44, name:'extra large'}\r
+        ]\r
+        * </code></pre>\r
+        * </li>\r
+        * <li><b>String</b> :\r
+        * <pre><code>\r
+        * options: ['extra small', 'small', 'medium', 'large', 'extra large']\r
+        * </code></pre>\r
+        * </li>\r
+        */\r
+       /**\r
+        * @cfg {Boolean} phpMode\r
+        * <p>Adjust the format of this filter. Defaults to false.</p>\r
+        * <br><p>When GridFilters <code>@cfg encode = false</code> (default):</p>\r
+        * <pre><code>\r
+        // phpMode == false (default):\r
+        filter[0][data][type] list\r
+        filter[0][data][value] value1\r
+        filter[0][data][value] value2\r
+        filter[0][field] prod\r
+\r
+        // phpMode == true:\r
+        filter[0][data][type] list\r
+        filter[0][data][value] value1, value2\r
+        filter[0][field] prod\r
+        * </code></pre>\r
+        * When GridFilters <code>@cfg encode = true</code>:\r
+        * <pre><code>\r
+        // phpMode == false (default):\r
+        filter : [{"type":"list","value":["small","medium"],"field":"size"}]\r
+\r
+        // phpMode == true:\r
+        filter : [{"type":"list","value":"small,medium","field":"size"}]\r
+        * </code></pre>\r
+        */\r
+       phpMode : false,\r
+       /**\r
+        * @cfg {Ext.data.Store} store\r
+        * The {@link Ext.data.Store} this list should use as its data source\r
+        * when the data source is <b>remote</b>. If the data for the list\r
+        * is local, use the <code>{@link #options}</code> config instead.\r
+        */\r
+\r
+       /**\r
+        * @private\r
+        * Template method that is to initialize the filter and install required menu items.\r
+        * @param {Object} config\r
+        */\r
+       init : function (config) {\r
+               this.dt = new Ext.util.DelayedTask(this.fireUpdate, this);\r
+\r
+               // if a menu already existed, do clean up first\r
+               if (this.menu) {\r
+                       this.menu.destroy();\r
+               }\r
+               this.menu = new Ext.ux.menu.ListMenu(config);\r
+               this.menu.on('checkchange', this.onCheckChange, this);\r
+       },\r
 \r
-        // phpMode == true:
-        filter[0][data][type] list
-        filter[0][data][value] value1, value2
-        filter[0][field] prod
-        * </code></pre>
-        * When GridFilters <code>@cfg encode = true</code>:
-        * <pre><code>
-        // phpMode == false (default):
-        filter : [{"type":"list","value":["small","medium"],"field":"size"}]
+       /**\r
+        * @private\r
+        * Template method that is to get and return the value of the filter.\r
+        * @return {String} The value of this filter\r
+        */\r
+       getValue : function () {\r
+               return this.menu.getSelected();\r
+       },\r
+       /**\r
+        * @private\r
+        * Template method that is to set the value of the filter.\r
+        * @param {Object} value The value to set the filter\r
+        */\r
+       setValue : function (value) {\r
+               this.menu.setSelected(value);\r
+               this.fireEvent('update', this);\r
+       },\r
 \r
-        // phpMode == true:
-        filter : [{"type":"list","value":"small,medium","field":"size"}]
-        * </code></pre>
-        */
-       phpMode : false,
-       /**
-        * @cfg {Ext.data.Store} store
-        * The {@link Ext.data.Store} this list should use as its data source
-        * when the data source is <b>remote</b>. If the data for the list
-        * is local, use the <code>{@link #options}</code> config instead.
-        */
+       /**\r
+        * @private\r
+        * Template method that is to return <tt>true</tt> if the filter\r
+        * has enough configuration information to be activated.\r
+        * @return {Boolean}\r
+        */\r
+       isActivatable : function () {\r
+               return this.getValue().length > 0;\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to initialize the filter and install required menu items.
-        * @param {Object} config
-        */
-       init : function (config) {
-               this.dt = new Ext.util.DelayedTask(this.fireUpdate, this);
+       /**\r
+        * @private\r
+        * Template method that is to get and return serialized filter data for\r
+        * transmission to the server.\r
+        * @return {Object/Array} An object or collection of objects containing\r
+        * key value pairs representing the current configuration of the filter.\r
+        */\r
+       getSerialArgs : function () {\r
+               var args = {type: 'list', value: this.phpMode ? this.getValue().join(',') : this.getValue()};\r
+               return args;\r
+       },\r
 \r
-               // if a menu already existed, do clean up first
-               if (this.menu) {
-                       this.menu.destroy();
-               }
-               this.menu = new Ext.ux.menu.ListMenu(config);
-               this.menu.on('checkchange', this.onCheckChange, this);
-       },
+       /** @private */\r
+       onCheckChange : function() {\r
+               this.dt.delay(this.updateBuffer);\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to get and return the value of the filter.
-        * @return {String} The value of this filter
-        */
-       getValue : function () {
-               return this.menu.getSelected();
-       },
-       /**
-        * @private
-        * Template method that is to set the value of the filter.
-        * @param {Object} value The value to set the filter
-        */
-       setValue : function (value) {
-               this.menu.setSelected(value);
-               this.fireEvent('update', this);
-       },
 \r
-       /**
-        * @private
-        * Template method that is to return <tt>true</tt> if the filter
-        * has enough configuration information to be activated.
-        * @return {Boolean}
-        */
-       isActivatable : function () {
-               return this.getValue().length > 0;
-       },
-
-       /**
-        * @private
-        * Template method that is to get and return serialized filter data for
-        * transmission to the server.
-        * @return {Object/Array} An object or collection of objects containing
-        * key value pairs representing the current configuration of the filter.
-        */
-       getSerialArgs : function () {
-               var args = {type: 'list', value: this.phpMode ? this.getValue().join(',') : this.getValue()};
-               return args;
-       },
-
-       /** @private */
-       onCheckChange : function() {
-               this.dt.delay(this.updateBuffer);
-       },
-
-
-       /**
-        * Template method that is to validate the provided Ext.data.Record
-        * against the filters configuration.
-        * @param {Ext.data.Record} record The record to validate
-        * @return {Boolean} true if the record is valid within the bounds
-        * of the filter, false otherwise.
-        */
-       validateRecord : function (record) {
-               return this.getValue().indexOf(record.get(this.dataIndex)) > -1;
-       }
+       /**\r
+        * Template method that is to validate the provided Ext.data.Record\r
+        * against the filters configuration.\r
+        * @param {Ext.data.Record} record The record to validate\r
+        * @return {Boolean} true if the record is valid within the bounds\r
+        * of the filter, false otherwise.\r
+        */\r
+       validateRecord : function (record) {\r
+               return this.getValue().indexOf(record.get(this.dataIndex)) > -1;\r
+       }\r
 });
\ No newline at end of file
index 29e9ddc..c6cc354 100644 (file)
-/*!
- * Ext JS Library 3.1.1
- * Copyright(c) 2006-2010 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
-/**
+/*!\r
+ * Ext JS Library 3.1.1\r
+ * Copyright(c) 2006-2010 Ext JS, LLC\r
+ * licensing@extjs.com\r
+ * http://www.extjs.com/license\r
+ */\r
+/**\r
  * @class Ext.ux.grid.filter.NumericFilter\r
  * @extends Ext.ux.grid.filter.Filter\r
  * Filters using an Ext.ux.menu.RangeMenu.\r
  * <p><b><u>Example Usage:</u></b></p>\r
- * <pre><code>
- var filters = new Ext.ux.grid.GridFilters({
- ...
- filters: [{
- type: 'numeric',
- dataIndex: 'price'
- }]
- });
- * </code></pre>
+ * <pre><code>\r
+ var filters = new Ext.ux.grid.GridFilters({\r
+ ...\r
+ filters: [{\r
+ type: 'numeric',\r
+ dataIndex: 'price'\r
+ }]\r
+ });\r
+ * </code></pre>\r
  */\r
 Ext.ux.grid.filter.NumericFilter = Ext.extend(Ext.ux.grid.filter.Filter, {\r
 \r
-       /**
-        * @cfg {Object} fieldCls
-        * The Class to use to construct each field item within this menu
-        * Defaults to:<pre>
-        * fieldCls : Ext.form.NumberField
-        * </pre>
-        */
-       fieldCls : Ext.form.NumberField,
-       /**
-        * @cfg {Object} fieldCfg
-        * The default configuration options for any field item unless superseded
-        * by the <code>{@link #fields}</code> configuration.
-        * Defaults to:<pre>
-        * fieldCfg : {}
-        * </pre>
-        * Example usage:
-        * <pre><code>
-        fieldCfg : {
-        width: 150,
-        },
-        * </code></pre>
-        */
-       /**
-        * @cfg {Object} fields
-        * The field items may be configured individually
-        * Defaults to <tt>undefined</tt>.
-        * Example usage:
-        * <pre><code>
-        fields : {
-        gt: { // override fieldCfg options
-        width: 200,
-        fieldCls: Ext.ux.form.CustomNumberField // to override default {@link #fieldCls}
-        }
-        },
-        * </code></pre>
-        */
-       /**
-        * @cfg {Object} iconCls
-        * The iconCls to be applied to each comparator field item.
-        * Defaults to:<pre>
-        iconCls : {
-        gt : 'ux-rangemenu-gt',
-        lt : 'ux-rangemenu-lt',
-        eq : 'ux-rangemenu-eq'
-        }
-        * </pre>
-        */
-       iconCls : {
-               gt : 'ux-rangemenu-gt',
-               lt : 'ux-rangemenu-lt',
-               eq : 'ux-rangemenu-eq'
-       },
+       /**\r
+        * @cfg {Object} fieldCls\r
+        * The Class to use to construct each field item within this menu\r
+        * Defaults to:<pre>\r
+        * fieldCls : Ext.form.NumberField\r
+        * </pre>\r
+        */\r
+       fieldCls : Ext.form.NumberField,\r
+       /**\r
+        * @cfg {Object} fieldCfg\r
+        * The default configuration options for any field item unless superseded\r
+        * by the <code>{@link #fields}</code> configuration.\r
+        * Defaults to:<pre>\r
+        * fieldCfg : {}\r
+        * </pre>\r
+        * Example usage:\r
+        * <pre><code>\r
+        fieldCfg : {\r
+        width: 150,\r
+        },\r
+        * </code></pre>\r
+        */\r
+       /**\r
+        * @cfg {Object} fields\r
+        * The field items may be configured individually\r
+        * Defaults to <tt>undefined</tt>.\r
+        * Example usage:\r
+        * <pre><code>\r
+        fields : {\r
+        gt: { // override fieldCfg options\r
+        width: 200,\r
+        fieldCls: Ext.ux.form.CustomNumberField // to override default {@link #fieldCls}\r
+        }\r
+        },\r
+        * </code></pre>\r
+        */\r
+       /**\r
+        * @cfg {Object} iconCls\r
+        * The iconCls to be applied to each comparator field item.\r
+        * Defaults to:<pre>\r
+        iconCls : {\r
+        gt : 'ux-rangemenu-gt',\r
+        lt : 'ux-rangemenu-lt',\r
+        eq : 'ux-rangemenu-eq'\r
+        }\r
+        * </pre>\r
+        */\r
+       iconCls : {\r
+               gt : 'ux-rangemenu-gt',\r
+               lt : 'ux-rangemenu-lt',\r
+               eq : 'ux-rangemenu-eq'\r
+       },\r
+\r
+       /**\r
+        * @cfg {Object} menuItemCfgs\r
+        * Default configuration options for each menu item\r
+        * Defaults to:<pre>\r
+        menuItemCfgs : {\r
+        emptyText: 'Enter Filter Text...',\r
+        selectOnFocus: true,\r
+        width: 125\r
+        }\r
+        * </pre>\r
+        */\r
+       menuItemCfgs : {\r
+               emptyText: 'Enter Filter Text...',\r
+               selectOnFocus: true,\r
+               width: 125\r
+       },\r
+\r
+       /**\r
+        * @cfg {Array} menuItems\r
+        * The items to be shown in this menu.  Items are added to the menu\r
+        * according to their position within this array. Defaults to:<pre>\r
+        * menuItems : ['lt','gt','-','eq']\r
+        * </pre>\r
+        */\r
+       menuItems : ['lt', 'gt', '-', 'eq'],\r
 \r
-       /**
-        * @cfg {Object} menuItemCfgs
-        * Default configuration options for each menu item
-        * Defaults to:<pre>
-        menuItemCfgs : {
-        emptyText: 'Enter Filter Text...',
-        selectOnFocus: true,
-        width: 125
-        }
-        * </pre>
-        */
-       menuItemCfgs : {
-               emptyText: 'Enter Filter Text...',
-               selectOnFocus: true,
-               width: 125
-       },
+       /**\r
+        * @private\r
+        * Template method that is to initialize the filter and install required menu items.\r
+        */\r
+       init : function (config) {\r
+               // if a menu already existed, do clean up first\r
+               if (this.menu) {\r
+                       this.menu.destroy();\r
+               }\r
+               this.menu = new Ext.ux.menu.RangeMenu(Ext.apply(config, {\r
+                                       // pass along filter configs to the menu\r
+                                       fieldCfg : this.fieldCfg || {},\r
+                                       fieldCls : this.fieldCls,\r
+                                       fields : this.fields || {},\r
+                                       iconCls: this.iconCls,\r
+                                       menuItemCfgs: this.menuItemCfgs,\r
+                                       menuItems: this.menuItems,\r
+                                       updateBuffer: this.updateBuffer\r
+                               }));\r
+               // relay the event fired by the menu\r
+               this.menu.on('update', this.fireUpdate, this);\r
+       },\r
 \r
-       /**
-        * @cfg {Array} menuItems
-        * The items to be shown in this menu.  Items are added to the menu
-        * according to their position within this array. Defaults to:<pre>
-        * menuItems : ['lt','gt','-','eq']
-        * </pre>
-        */
-       menuItems : ['lt', 'gt', '-', 'eq'],
+       /**\r
+        * @private\r
+        * Template method that is to get and return the value of the filter.\r
+        * @return {String} The value of this filter\r
+        */\r
+       getValue : function () {\r
+               return this.menu.getValue();\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to initialize the filter and install required menu items.
-        */
-       init : function (config) {
-               // if a menu already existed, do clean up first
-               if (this.menu) {
-                       this.menu.destroy();
-               }
-               this.menu = new Ext.ux.menu.RangeMenu(Ext.apply(config, {
-                                       // pass along filter configs to the menu
-                                       fieldCfg : this.fieldCfg || {},
-                                       fieldCls : this.fieldCls,
-                                       fields : this.fields || {},
-                                       iconCls: this.iconCls,
-                                       menuItemCfgs: this.menuItemCfgs,
-                                       menuItems: this.menuItems,
-                                       updateBuffer: this.updateBuffer
-                               }));
-               // relay the event fired by the menu
-               this.menu.on('update', this.fireUpdate, this);
-       },
+       /**\r
+        * @private\r
+        * Template method that is to set the value of the filter.\r
+        * @param {Object} value The value to set the filter\r
+        */\r
+       setValue : function (value) {\r
+               this.menu.setValue(value);\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to get and return the value of the filter.
-        * @return {String} The value of this filter
-        */
-       getValue : function () {
-               return this.menu.getValue();
-       },
+       /**\r
+        * @private\r
+        * Template method that is to return <tt>true</tt> if the filter\r
+        * has enough configuration information to be activated.\r
+        * @return {Boolean}\r
+        */\r
+       isActivatable : function () {\r
+               var values = this.getValue();\r
+               for (key in values) {\r
+                       if (values[key] !== undefined) {\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to set the value of the filter.
-        * @param {Object} value The value to set the filter
-        */
-       setValue : function (value) {
-               this.menu.setValue(value);
-       },
+       /**\r
+        * @private\r
+        * Template method that is to get and return serialized filter data for\r
+        * transmission to the server.\r
+        * @return {Object/Array} An object or collection of objects containing\r
+        * key value pairs representing the current configuration of the filter.\r
+        */\r
+       getSerialArgs : function () {\r
+               var key,\r
+                               args = [],\r
+                               values = this.menu.getValue();\r
+               for (key in values) {\r
+                       args.push({\r
+                                               type: 'numeric',\r
+                                               comparison: key,\r
+                                               value: values[key]\r
+                                       });\r
+               }\r
+               return args;\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to return <tt>true</tt> if the filter
-        * has enough configuration information to be activated.
-        * @return {Boolean}
-        */
-       isActivatable : function () {
-               var values = this.getValue();
-               for (key in values) {
-                       if (values[key] !== undefined) {
-                               return true;
-                       }
-               }
-               return false;
-       },
-
-       /**
-        * @private
-        * Template method that is to get and return serialized filter data for
-        * transmission to the server.
-        * @return {Object/Array} An object or collection of objects containing
-        * key value pairs representing the current configuration of the filter.
-        */
-       getSerialArgs : function () {
-               var key,
-                               args = [],
-                               values = this.menu.getValue();
-               for (key in values) {
-                       args.push({
-                                               type: 'numeric',
-                                               comparison: key,
-                                               value: values[key]
-                                       });
-               }
-               return args;
-       },
-
-       /**
-        * Template method that is to validate the provided Ext.data.Record
-        * against the filters configuration.
-        * @param {Ext.data.Record} record The record to validate
-        * @return {Boolean} true if the record is valid within the bounds
-        * of the filter, false otherwise.
-        */
-       validateRecord : function (record) {
-               var val = record.get(this.dataIndex),
-                               values = this.getValue();
-               if (values.eq !== undefined && val != values.eq) {
-                       return false;
-               }
-               if (values.lt !== undefined && val >= values.lt) {
-                       return false;
-               }
-               if (values.gt !== undefined && val <= values.gt) {
-                       return false;
-               }
-               return true;
-       }
+       /**\r
+        * Template method that is to validate the provided Ext.data.Record\r
+        * against the filters configuration.\r
+        * @param {Ext.data.Record} record The record to validate\r
+        * @return {Boolean} true if the record is valid within the bounds\r
+        * of the filter, false otherwise.\r
+        */\r
+       validateRecord : function (record) {\r
+               var val = record.get(this.dataIndex),\r
+                               values = this.getValue();\r
+               if (values.eq !== undefined && val != values.eq) {\r
+                       return false;\r
+               }\r
+               if (values.lt !== undefined && val >= values.lt) {\r
+                       return false;\r
+               }\r
+               if (values.gt !== undefined && val <= values.gt) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
 });
\ No newline at end of file
index 9199f07..250090f 100644 (file)
-/*!
- * Ext JS Library 3.1.1
- * Copyright(c) 2006-2010 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
-/**
+/*!\r
+ * Ext JS Library 3.1.1\r
+ * Copyright(c) 2006-2010 Ext JS, LLC\r
+ * licensing@extjs.com\r
+ * http://www.extjs.com/license\r
+ */\r
+/**\r
  * @class Ext.ux.grid.filter.StringFilter\r
  * @extends Ext.ux.grid.filter.Filter\r
  * Filter by a configurable Ext.form.TextField\r
  * <p><b><u>Example Usage:</u></b></p>\r
- * <pre><code>
- var filters = new Ext.ux.grid.GridFilters({
- ...
- filters: [{
- // required configs
- type: 'string',
- dataIndex: 'name',
-
- // optional configs
- value: 'foo',
- active: true, // default is false
- iconCls: 'ux-gridfilter-text-icon' // default
- // any Ext.form.TextField configs accepted
- }]
- });
+ * <pre><code>\r
+ var filters = new Ext.ux.grid.GridFilters({\r
+ ...\r
+ filters: [{\r
+ // required configs\r
+ type: 'string',\r
+ dataIndex: 'name',\r
+\r
+ // optional configs\r
+ value: 'foo',\r
+ active: true, // default is false\r
+ iconCls: 'ux-gridfilter-text-icon' // default\r
+ // any Ext.form.TextField configs accepted\r
+ }]\r
+ });\r
  * </code></pre>\r
  */\r
 Ext.ux.grid.filter.StringFilter = Ext.extend(Ext.ux.grid.filter.Filter, {\r
 \r
-       /**
-        * @cfg {String} iconCls
-        * The iconCls to be applied to the menu item.
-        * Defaults to <tt>'ux-gridfilter-text-icon'</tt>.
-        */
-       iconCls : 'ux-gridfilter-text-icon',
+       /**\r
+        * @cfg {String} iconCls\r
+        * The iconCls to be applied to the menu item.\r
+        * Defaults to <tt>'ux-gridfilter-text-icon'</tt>.\r
+        */\r
+       iconCls : 'ux-gridfilter-text-icon',\r
+\r
+       emptyText: 'Enter Filter Text...',\r
+       selectOnFocus: true,\r
+       width: 125,\r
+\r
+       /**\r
+        * @private\r
+        * Template method that is to initialize the filter and install required menu items.\r
+        */\r
+       init : function (config) {\r
+               Ext.applyIf(config, {\r
+                                       enableKeyEvents: true,\r
+                                       iconCls: this.iconCls,\r
+                                       listeners: {\r
+                                               scope: this,\r
+                                               keyup: this.onInputKeyUp\r
+                                       }\r
+                               });\r
+\r
+               this.inputItem = new Ext.form.TextField(config);\r
+               this.menu.add(this.inputItem);\r
+               this.updateTask = new Ext.util.DelayedTask(this.fireUpdate, this);\r
+       },\r
+\r
+       /**\r
+        * @private\r
+        * Template method that is to get and return the value of the filter.\r
+        * @return {String} The value of this filter\r
+        */\r
+       getValue : function () {\r
+               return this.inputItem.getValue();\r
+       },\r
 \r
-       emptyText: 'Enter Filter Text...',
-       selectOnFocus: true,
-       width: 125,
+       /**\r
+        * @private\r
+        * Template method that is to set the value of the filter.\r
+        * @param {Object} value The value to set the filter\r
+        */\r
+       setValue : function (value) {\r
+               this.inputItem.setValue(value);\r
+               this.fireEvent('update', this);\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to initialize the filter and install required menu items.
-        */
-       init : function (config) {
-               Ext.applyIf(config, {
-                                       enableKeyEvents: true,
-                                       iconCls: this.iconCls,
-                                       listeners: {
-                                               scope: this,
-                                               keyup: this.onInputKeyUp
-                                       }
-                               });
+       /**\r
+        * @private\r
+        * Template method that is to return <tt>true</tt> if the filter\r
+        * has enough configuration information to be activated.\r
+        * @return {Boolean}\r
+        */\r
+       isActivatable : function () {\r
+               return this.inputItem.getValue().length > 0;\r
+       },\r
 \r
-               this.inputItem = new Ext.form.TextField(config);
-               this.menu.add(this.inputItem);
-               this.updateTask = new Ext.util.DelayedTask(this.fireUpdate, this);
-       },
+       /**\r
+        * @private\r
+        * Template method that is to get and return serialized filter data for\r
+        * transmission to the server.\r
+        * @return {Object/Array} An object or collection of objects containing\r
+        * key value pairs representing the current configuration of the filter.\r
+        */\r
+       getSerialArgs : function () {\r
+               return {type: 'string', value: this.getValue()};\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to get and return the value of the filter.
-        * @return {String} The value of this filter
-        */
-       getValue : function () {
-               return this.inputItem.getValue();
-       },
+       /**\r
+        * Template method that is to validate the provided Ext.data.Record\r
+        * against the filters configuration.\r
+        * @param {Ext.data.Record} record The record to validate\r
+        * @return {Boolean} true if the record is valid within the bounds\r
+        * of the filter, false otherwise.\r
+        */\r
+       validateRecord : function (record) {\r
+               var val = record.get(this.dataIndex);\r
 \r
-       /**
-        * @private
-        * Template method that is to set the value of the filter.
-        * @param {Object} value The value to set the filter
-        */
-       setValue : function (value) {
-               this.inputItem.setValue(value);
-               this.fireEvent('update', this);
-       },
+               if (typeof val != 'string') {\r
+                       return (this.getValue().length === 0);\r
+               }\r
 \r
-       /**
-        * @private
-        * Template method that is to return <tt>true</tt> if the filter
-        * has enough configuration information to be activated.
-        * @return {Boolean}
-        */
-       isActivatable : function () {
-               return this.inputItem.getValue().length > 0;
-       },
+               return val.toLowerCase().indexOf(this.getValue().toLowerCase()) > -1;\r
+       },\r
 \r
-       /**
-        * @private
-        * Template method that is to get and return serialized filter data for
-        * transmission to the server.
-        * @return {Object/Array} An object or collection of objects containing
-        * key value pairs representing the current configuration of the filter.
-        */
-       getSerialArgs : function () {
-               return {type: 'string', value: this.getValue()};
-       },
-
-       /**
-        * Template method that is to validate the provided Ext.data.Record
-        * against the filters configuration.
-        * @param {Ext.data.Record} record The record to validate
-        * @return {Boolean} true if the record is valid within the bounds
-        * of the filter, false otherwise.
-        */
-       validateRecord : function (record) {
-               var val = record.get(this.dataIndex);
-
-               if (typeof val != 'string') {
-                       return (this.getValue().length === 0);
-               }
-
-               return val.toLowerCase().indexOf(this.getValue().toLowerCase()) > -1;
-       },
-
-       /**
-        * @private
-        * Handler method called when there is a keyup event on this.inputItem
-        */
-       onInputKeyUp : function (field, e) {
-               var k = e.getKey();
-               if (k == e.RETURN && field.isValid()) {
-                       e.stopEvent();
-                       this.menu.hide(true);
-                       return;
-               }
-               // restart the timer
-               this.updateTask.delay(this.updateBuffer);
-       }
+       /**\r
+        * @private\r
+        * Handler method called when there is a keyup event on this.inputItem\r
+        */\r
+       onInputKeyUp : function (field, e) {\r
+               var k = e.getKey();\r
+               if (k == e.RETURN && field.isValid()) {\r
+                       e.stopEvent();\r
+                       this.menu.hide(true);\r
+                       return;\r
+               }\r
+               // restart the timer\r
+               this.updateTask.delay(this.updateBuffer);\r
+       }\r
 });\r
index 88113e4..fd3893b 100644 (file)
@@ -1,12 +1,12 @@
-/*!
- * Ext JS Library 3.1.1
- * Copyright(c) 2006-2010 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
+/*!\r
+ * Ext JS Library 3.1.1\r
+ * Copyright(c) 2006-2010 Ext JS, LLC\r
+ * licensing@extjs.com\r
+ * http://www.extjs.com/license\r
+ */\r
 Ext.namespace('Ext.ux.menu');\r
 \r
-/**
+/**\r
  * @class Ext.ux.menu.ListMenu\r
  * @extends Ext.menu.Menu\r
  * This is a supporting class for {@link Ext.ux.grid.filter.ListFilter}.\r
@@ -14,164 +14,164 @@ Ext.namespace('Ext.ux.menu');
  * also accepts all configuration options from {@link Ext.ux.grid.filter.ListFilter}.\r
  */\r
 Ext.ux.menu.ListMenu = Ext.extend(Ext.menu.Menu, {\r
-       /**
-        * @cfg {String} labelField
-        * Defaults to 'text'.
-        */
-       labelField :  'text',
-       /**
-        * @cfg {String} paramPrefix
-        * Defaults to 'Loading...'.
-        */
-       loadingText : 'Loading...',
-       /**
-        * @cfg {Boolean} loadOnShow
-        * Defaults to true.
-        */
-       loadOnShow : true,
-       /**
-        * @cfg {Boolean} single
-        * Specify true to group all items in this list into a single-select
-        * radio button group. Defaults to false.
-        */
-       single : false,
-\r
-       constructor : function (cfg) {
-               this.selected = [];
-               this.addEvents(
-                               /**
-                                * @event checkchange
-                                * Fires when there is a change in checked items from this list
-                                * @param {Object} item Ext.menu.CheckItem
-                                * @param {Object} checked The checked value that was set
-                                */
-                               'checkchange'
-               );
-\r
-               Ext.ux.menu.ListMenu.superclass.constructor.call(this, cfg = cfg || {});
-\r
-               if (!cfg.store && cfg.options) {
-                       var options = [];
-                       for (var i = 0, len = cfg.options.length; i < len; i++) {
-                               var value = cfg.options[i];
-                               switch (Ext.type(value)) {
-                                       case 'array':  options.push(value); break;
-                                       case 'object': options.push([value.id, value[this.labelField]]); break;
-                                       case 'string': options.push([value, value]); break;
-                               }
-                       }
-\r
-                       this.store = new Ext.data.Store({
-                                               reader: new Ext.data.ArrayReader({id: 0}, ['id', this.labelField]),
-                                               data:   options,
-                                               listeners: {
-                                                       'load': this.onLoad,
-                                                       scope:  this
-                                               }
-                                       });
-                       this.loaded = true;
-               } else {
-                       this.add({text: this.loadingText, iconCls: 'loading-indicator'});
-                       this.store.on('load', this.onLoad, this);
-               }
-       },
-\r
-       destroy : function () {
-               if (this.store) {
-                       this.store.destroy();
-               }
-               Ext.ux.menu.ListMenu.superclass.destroy.call(this);
-       },
-
-       /**
-        * Lists will initially show a 'loading' item while the data is retrieved from the store.
-        * In some cases the loaded data will result in a list that goes off the screen to the
-        * right (as placement calculations were done with the loading item). This adapter will
-        * allow show to be called with no arguments to show with the previous arguments and
-        * thus recalculate the width and potentially hang the menu from the left.
-        */
-       show : function () {
-               var lastArgs = null;
-               return function() {
-                       if (arguments.length === 0) {
-                               Ext.ux.menu.ListMenu.superclass.show.apply(this, lastArgs);
-                       } else {
-                               lastArgs = arguments;
-                               if (this.loadOnShow && !this.loaded) {
-                                       this.store.load();
-                               }
-                               Ext.ux.menu.ListMenu.superclass.show.apply(this, arguments);
-                       }
-               };
-       }(),
-
-       /** @private */
-       onLoad : function (store, records) {
-               var visible = this.isVisible();
-               this.hide(false);
-
-               this.removeAll(true);
-
-               var gid = this.single ? Ext.id() : null;
-               for (var i = 0, len = records.length; i < len; i++) {
-                       var item = new Ext.menu.CheckItem({
-                                               text:   records[i].get(this.labelField),
-                                               group:   gid,
-                                               checked: this.selected.indexOf(records[i].id) > -1,
-                                               hideOnClick: false});
-
-                       item.itemId = records[i].id;
-                       item.on('checkchange', this.checkChange, this);
-
-                       this.add(item);
-               }
-
-               this.loaded = true;
-
-               if (visible) {
-                       this.show();
-               }
-               this.fireEvent('load', this, records);
-       },
-
-       /**
-        * Get the selected items.
-        * @return {Array} selected
-        */
-       getSelected : function () {
-               return this.selected;
-       },
-
-       /** @private */
-       setSelected : function (value) {
-               value = this.selected = [].concat(value);
-
-               if (this.loaded) {
-                       this.items.each(function(item) {
-                               item.setChecked(false, true);
-                               for (var i = 0, len = value.length; i < len; i++) {
-                                       if (item.itemId == value[i]) {
-                                               item.setChecked(true, true);
-                                       }
-                               }
-                       }, this);
-               }
-       },
-
-       /**
-        * Handler for the 'checkchange' event from an check item in this menu
-        * @param {Object} item Ext.menu.CheckItem
-        * @param {Object} checked The checked value that was set
-        */
-       checkChange : function (item, checked) {
-               var value = [];
-               this.items.each(function(item) {
-                       if (item.checked) {
-                               value.push(item.itemId);
-                       }
-               }, this);
-               this.selected = value;
-
-               this.fireEvent('checkchange', item, checked);
-       }
+       /**\r
+        * @cfg {String} labelField\r
+        * Defaults to 'text'.\r
+        */\r
+       labelField :  'text',\r
+       /**\r
+        * @cfg {String} paramPrefix\r
+        * Defaults to 'Loading...'.\r
+        */\r
+       loadingText : 'Loading...',\r
+       /**\r
+        * @cfg {Boolean} loadOnShow\r
+        * Defaults to true.\r
+        */\r
+       loadOnShow : true,\r
+       /**\r
+        * @cfg {Boolean} single\r
+        * Specify true to group all items in this list into a single-select\r
+        * radio button group. Defaults to false.\r
+        */\r
+       single : false,\r
+\r
+       constructor : function (cfg) {\r
+               this.selected = [];\r
+               this.addEvents(\r
+                               /**\r
+                                * @event checkchange\r
+                                * Fires when there is a change in checked items from this list\r
+                                * @param {Object} item Ext.menu.CheckItem\r
+                                * @param {Object} checked The checked value that was set\r
+                                */\r
+                               'checkchange'\r
+               );\r
+\r
+               Ext.ux.menu.ListMenu.superclass.constructor.call(this, cfg = cfg || {});\r
+\r
+               if (!cfg.store && cfg.options) {\r
+                       var options = [];\r
+                       for (var i = 0, len = cfg.options.length; i < len; i++) {\r
+                               var value = cfg.options[i];\r
+                               switch (Ext.type(value)) {\r
+                                       case 'array':  options.push(value); break;\r
+                                       case 'object': options.push([value.id, value[this.labelField]]); break;\r
+                                       case 'string': options.push([value, value]); break;\r
+                               }\r
+                       }\r
+\r
+                       this.store = new Ext.data.Store({\r
+                                               reader: new Ext.data.ArrayReader({id: 0}, ['id', this.labelField]),\r
+                                               data:   options,\r
+                                               listeners: {\r
+                                                       'load': this.onLoad,\r
+                                                       scope:  this\r
+                                               }\r
+                                       });\r
+                       this.loaded = true;\r
+               } else {\r
+                       this.add({text: this.loadingText, iconCls: 'loading-indicator'});\r
+                       this.store.on('load', this.onLoad, this);\r
+               }\r
+       },\r
+\r
+       destroy : function () {\r
+               if (this.store) {\r
+                       this.store.destroy();\r
+               }\r
+               Ext.ux.menu.ListMenu.superclass.destroy.call(this);\r
+       },\r
+\r
+       /**\r
+        * Lists will initially show a 'loading' item while the data is retrieved from the store.\r
+        * In some cases the loaded data will result in a list that goes off the screen to the\r
+        * right (as placement calculations were done with the loading item). This adapter will\r
+        * allow show to be called with no arguments to show with the previous arguments and\r
+        * thus recalculate the width and potentially hang the menu from the left.\r
+        */\r
+       show : function () {\r
+               var lastArgs = null;\r
+               return function() {\r
+                       if (arguments.length === 0) {\r
+                               Ext.ux.menu.ListMenu.superclass.show.apply(this, lastArgs);\r
+                       } else {\r
+                               lastArgs = arguments;\r
+                               if (this.loadOnShow && !this.loaded) {\r
+                                       this.store.load();\r
+                               }\r
+                               Ext.ux.menu.ListMenu.superclass.show.apply(this, arguments);\r
+                       }\r
+               };\r
+       }(),\r
+\r
+       /** @private */\r
+       onLoad : function (store, records) {\r
+               var visible = this.isVisible();\r
+               this.hide(false);\r
+\r
+               this.removeAll(true);\r
+\r
+               var gid = this.single ? Ext.id() : null;\r
+               for (var i = 0, len = records.length; i < len; i++) {\r
+                       var item = new Ext.menu.CheckItem({\r
+                                               text:   records[i].get(this.labelField),\r
+                                               group:   gid,\r
+                                               checked: this.selected.indexOf(records[i].id) > -1,\r
+                                               hideOnClick: false});\r
+\r
+                       item.itemId = records[i].id;\r
+                       item.on('checkchange', this.checkChange, this);\r
+\r
+                       this.add(item);\r
+               }\r
+\r
+               this.loaded = true;\r
+\r
+               if (visible) {\r
+                       this.show();\r
+               }\r
+               this.fireEvent('load', this, records);\r
+       },\r
+\r
+       /**\r
+        * Get the selected items.\r
+        * @return {Array} selected\r
+        */\r
+       getSelected : function () {\r
+               return this.selected;\r
+       },\r
+\r
+       /** @private */\r
+       setSelected : function (value) {\r
+               value = this.selected = [].concat(value);\r
+\r
+               if (this.loaded) {\r
+                       this.items.each(function(item) {\r
+                               item.setChecked(false, true);\r
+                               for (var i = 0, len = value.length; i < len; i++) {\r
+                                       if (item.itemId == value[i]) {\r
+                                               item.setChecked(true, true);\r
+                                       }\r
+                               }\r
+                       }, this);\r
+               }\r
+       },\r
+\r
+       /**\r
+        * Handler for the 'checkchange' event from an check item in this menu\r
+        * @param {Object} item Ext.menu.CheckItem\r
+        * @param {Object} checked The checked value that was set\r
+        */\r
+       checkChange : function (item, checked) {\r
+               var value = [];\r
+               this.items.each(function(item) {\r
+                       if (item.checked) {\r
+                               value.push(item.itemId);\r
+                       }\r
+               }, this);\r
+               this.selected = value;\r
+\r
+               this.fireEvent('checkchange', item, checked);\r
+       }\r
 });
\ No newline at end of file
index 5d49e8b..ab184a3 100644 (file)
-/*!
- * Ext JS Library 3.1.1
- * Copyright(c) 2006-2010 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
+/*!\r
+ * Ext JS Library 3.1.1\r
+ * Copyright(c) 2006-2010 Ext JS, LLC\r
+ * licensing@extjs.com\r
+ * http://www.extjs.com/license\r
+ */\r
 Ext.ns('Ext.ux.menu');\r
 \r
-/**
+/**\r
  * @class Ext.ux.menu.RangeMenu\r
  * @extends Ext.menu.Menu\r
  * Custom implementation of Ext.menu.Menu that has preconfigured\r
  * items for gt, lt, eq.\r
  * <p><b><u>Example Usage:</u></b></p>\r
- * <pre><code>
+ * <pre><code>\r
 \r
- * </code></pre>
+ * </code></pre>\r
  */\r
 Ext.ux.menu.RangeMenu = Ext.extend(Ext.menu.Menu, {\r
 \r
-       constructor : function (config) {
+       constructor : function (config) {\r
+\r
+               Ext.ux.menu.RangeMenu.superclass.constructor.call(this, config);\r
+\r
+               this.addEvents(\r
+                               /**\r
+                                * @event update\r
+                                * Fires when a filter configuration has changed\r
+                                * @param {Ext.ux.grid.filter.Filter} this The filter object.\r
+                                */\r
+                               'update'\r
+               );\r
+\r
+               this.updateTask = new Ext.util.DelayedTask(this.fireUpdate, this);\r
+\r
+               var i, len, item, cfg, Cls;\r
+\r
+               for (i = 0,len = this.menuItems.length; i < len; i++) {\r
+                       item = this.menuItems[i];\r
+                       if (item !== '-') {\r
+                               // defaults\r
+                               cfg = {\r
+                                       itemId: 'range-' + item,\r
+                                       enableKeyEvents: true,\r
+                                       iconCls: this.iconCls[item] || 'no-icon',\r
+                                       listeners: {\r
+                                               scope: this,\r
+                                               keyup: this.onInputKeyUp\r
+                                       }\r
+                               };\r
+                               Ext.apply(\r
+                                               cfg,\r
+                                               // custom configs\r
+                                               Ext.applyIf(this.fields[item] || {}, this.fieldCfg[item]),\r
+                                               // configurable defaults\r
+                                               this.menuItemCfgs\r
+                               );\r
+                               Cls = cfg.fieldCls || this.fieldCls;\r
+                               item = this.fields[item] = new Cls(cfg);\r
+                       }\r
+                       this.add(item);\r
+               }\r
+       },\r
+\r
+       /**\r
+        * @private\r
+        * called by this.updateTask\r
+        */\r
+       fireUpdate : function () {\r
+               this.fireEvent('update', this);\r
+       },\r
 \r
-               Ext.ux.menu.RangeMenu.superclass.constructor.call(this, config);
+       /**\r
+        * Get and return the value of the filter.\r
+        * @return {String} The value of this filter\r
+        */\r
+       getValue : function () {\r
+               var result = {}, key, field;\r
+               for (key in this.fields) {\r
+                       field = this.fields[key];\r
+                       if (field.isValid() && String(field.getValue()).length > 0) {\r
+                               result[key] = field.getValue();\r
+                       }\r
+               }\r
+               return result;\r
+       },\r
 \r
-               this.addEvents(
-                               /**
-                                * @event update
-                                * Fires when a filter configuration has changed
-                                * @param {Ext.ux.grid.filter.Filter} this The filter object.
-                                */
-                               'update'
-               );
+       /**\r