merge filemanager
authorU-METAWAYS\mjatho <mjatho@lapmjatho.hh.metaways.de>
Tue, 6 Sep 2011 09:54:44 +0000 (11:54 +0200)
committerU-METAWAYS\mjatho <mjatho@lapmjatho.hh.metaways.de>
Tue, 6 Sep 2011 09:54:44 +0000 (11:54 +0200)
24 files changed:
1  2 
tests/tine20/Tinebase/ContainerTest.php
tine20/ExampleApplication/js/ExampleApplication.js
tine20/ExampleApplication/js/ExampleRecordGridPanel.js
tine20/ExampleApplication/js/Model.js
tine20/Felamimail/js/MessageEditDialog.js
tine20/Felamimail/js/TreePanel.js
tine20/Filemanager/Exception/NodeExists.php
tine20/Filemanager/translations/de.po
tine20/Filemanager/translations/en.po
tine20/Setup/Core.php
tine20/Tinebase/Frontend/Json.php
tine20/Tinebase/Frontend/Json/Container.php
tine20/Tinebase/Model/Filter/Abstract.php
tine20/Tinebase/Model/Filter/FilterGroup.php
tine20/Tinebase/Model/Tree/NodePathFilter.php
tine20/Tinebase/TempFile.php
tine20/Tinebase/Tinebase.jsb2
tine20/Tinebase/User/Abstract.php
tine20/Tinebase/User/Sql.php
tine20/Tinebase/css/Tinebase.css
tine20/Tinebase/js/ux/Percentage.js
tine20/Tinebase/js/widgets/container/TreePanel.js
tine20/Tinebase/js/widgets/grid/GridPanel.js
tine20/Tinebase/js/widgets/tree/ContextMenu.js

@@@ -502,4 -494,24 +502,25 @@@ class Tinebase_ContainerTest extends PH
          ));
          $this->assertTrue($otherUsers->getRecordClassName() === 'Tinebase_Model_Container');
      }
 -    
++
+     /**
+      * search container with owner filter
+      */
+     public function testSearchContainerByOwner()
+     {
+         $filter = new Tinebase_Model_ContainerFilter(array(
+             array('field' => 'owner', 'operator' => 'equals', 'value' => Tinebase_Core::getUser()->getId())
+         ));
+         $result = Tinebase_Container::getInstance()->search($filter);
+         
+         $this->assertTrue(count($result) > 0);
+         
+         foreach ($result as $container) {
+             $this->assertEquals(Tinebase_Model_Container::TYPE_PERSONAL, $container->type);
+             $this->assertTrue(Tinebase_Container::getInstance()->hasGrant(
+                 Tinebase_Core::getUser()->getId(), $container->getId(), Tinebase_Model_Grants::GRANT_ADMIN
+             ), 'no admin grant:' . print_r($container->toArray(), TRUE));
+         }
+     }
++
  }
@@@ -57,7 -57,7 +57,7 @@@ Tine.ExampleApplication.ExampleRecordGr
          
          this.gridConfig.cm = this.getColumnModel();
          this.filterToolbar = this.filterToolbar || this.getFilterToolbar();
-         
 -       
++
          this.plugins = this.plugins || [];
          this.plugins.push(this.filterToolbar);
          
Simple merge
Simple merge
@@@ -25,7 -46,234 +46,238 @@@ msgstr "Ordner anderer Benutzer
  msgid "Filemanager"
  msgstr "Dateimanager"
  
- #, python-format
 +#: Controller.php:95
 +msgid "%s's personal files"
 +msgstr "Persönliche Dateien von %s"
++
+ #: Filemanager/js/Filemanager.js:56
+ msgid "File allready exists"
+ msgstr "Es existiert bereits eine Datei mit diesem Namen"
+ #: Filemanager/js/Filemanager.js:57
+ msgid "Do you want to replace the file?"
+ msgstr "Möchten Sie die Datei ersetzen?"
+ #: Filemanager/js/Filemanager.js:73
+ msgid "Failure on create folder"
+ msgstr "Fehler beim anlegen des Ordners"
+ #: Filemanager/js/Filemanager.js:74
+ msgid "Item with this name allready exists!"
+ msgstr "Es existiert bereits ein Eintrag mit diesem Namen!"
+ #: Filemanager/js/GridContextMenu.js:36
+ #: Filemanager/js/GridPanel.js:467
+ msgid "Please enter the new name of the {0}:"
+ msgstr "Bitte den neuen Namen von {0} eingeben"
+ #: Filemanager/js/GridContextMenu.js:42
+ #: Filemanager/js/GridPanel.js:473
+ msgid "Not renamed {0}"
+ msgstr "Unbenannter {0}"
+ #: Filemanager/js/GridContextMenu.js:42
+ #: Filemanager/js/GridPanel.js:473
+ #: Filemanager/js/GridPanel.js:533
+ msgid "You have to supply a {0} name!"
+ msgstr "Sie müssen einen {0}-namen angeben!"
+ #: Filemanager/js/GridContextMenu.js:45
+ #: Filemanager/js/GridContextMenu.js:135
+ #: Filemanager/js/GridPanel.js:476
+ #: Filemanager/js/GridPanel.js:536
+ #: Filemanager/js/GridPanel.js:578
+ #: Filemanager/js/Model.js:271
+ msgid "Please wait"
+ msgstr "Bitte warten"
+ #: Filemanager/js/GridContextMenu.js:45
+ #: Filemanager/js/GridPanel.js:476
+ msgid "Updating {0} \"{1}\""
+ msgstr "Update {0} \"{1}\""
+ #: Filemanager/js/GridContextMenu.js:133
+ #: Filemanager/js/GridPanel.js:575
+ msgid "Confirm"
+ msgstr "Bestätigen"
+ #: Filemanager/js/GridContextMenu.js:133
+ #: Filemanager/js/GridPanel.js:575
+ msgid "Do you really want to delete \"{0}\"?"
+ msgstr "Möchten Sie \"{0}\" wirklich löschen? "
+ #: Filemanager/js/GridContextMenu.js:135
+ msgid "Deleting {0} \"{1}\""
+ msgstr "Lösche {0} \"{1}\""
+ #: Filemanager/js/GridPanel.js:123
+ msgid "Name"
+ msgstr "Name"
+ #: Filemanager/js/GridPanel.js:130
+ msgid "Size"
+ msgstr "Größe"
+ #: Filemanager/js/GridPanel.js:137
+ #: Filemanager/js/Model.js:359
+ msgid "Contenttype"
+ msgstr "Typ"
+ #: Filemanager/js/GridPanel.js:145
+ msgid "Folder"
+ msgstr "Ordner"
+ #: Filemanager/js/GridPanel.js:153
+ msgid "Revision"
+ msgstr "Version"
+ #: Filemanager/js/GridPanel.js:167
+ #: Filemanager/js/Model.js:360
+ msgid "Creation Time"
+ msgstr "Erstellt am"
+ #: Filemanager/js/GridPanel.js:175
+ msgid "Created By"
+ msgstr "Erstellt von"
+ #: Filemanager/js/GridPanel.js:182
+ msgid "Last Modified Time"
+ msgstr "Zuletzt geändert"
+ #: Filemanager/js/GridPanel.js:189
+ msgid "Last Modified By"
+ msgstr "Zuletzt geändert von"
+ #: Filemanager/js/GridPanel.js:223
+ msgid "Show closed"
+ msgstr "Zeige archivierte"
+ #: Filemanager/js/GridPanel.js:246
+ msgid "Upload"
+ msgstr "Hochladen"
+ #: Filemanager/js/GridPanel.js:272
+ msgid "Create Folder"
+ msgstr "Ordner anlegen"
+ #: Filemanager/js/GridPanel.js:283
+ msgid "Folder Up"
+ msgstr "Aufwärts"
+ #: Filemanager/js/GridPanel.js:294
+ msgid "Save locally"
+ msgstr "Lokal speichern"
+ #: Filemanager/js/GridPanel.js:305
+ #: Filemanager/js/GridPanel.js:306
+ #: Filemanager/js/GridPanel.js:308
+ msgid "Delete"
+ msgstr "Löschen"
+ #: Filemanager/js/GridPanel.js:318
+ #: Filemanager/js/GridPanel.js:319
+ #: Filemanager/js/GridPanel.js:321
+ msgid "Rename"
+ msgstr "Umbenennen"
+ #: Filemanager/js/GridPanel.js:329
+ msgid "Pause upload"
+ msgstr "Upload pausieren"
+ #: Filemanager/js/GridPanel.js:336
+ msgid "Resume upload"
+ msgstr "Upload fortsetzen"
+ #: Filemanager/js/GridPanel.js:459
+ #: Filemanager/js/GridPanel.js:526
+ #: Filemanager/js/Model.js:361
+ msgid "user file folder"
+ msgstr "Ordner"
+ #: Filemanager/js/GridPanel.js:528
+ msgid "New {0}"
+ msgstr "Neuer {0}"
+ #: Filemanager/js/GridPanel.js:528
+ msgid "Please enter the name of the new {0}:"
+ msgstr "Bitte geben Sie den Namen des neuen {0} an:"
+ #: Filemanager/js/GridPanel.js:533
+ msgid "No {0} added"
+ msgstr "Kein {0} hinzugefügt"
+ #: Filemanager/js/GridPanel.js:536
+ msgid "Creating {0}..."
+ msgstr "Erstelle {0}..."
+ #: Filemanager/js/GridPanel.js:578
+ msgid "Deleting {0} "
+ msgstr "Lösche {0}"
+ #: Filemanager/js/GridPanel.js:662
+ #: Filemanager/js/GridPanel.js:807
+ #: Filemanager/js/TreePanel.js:626
+ #: Filemanager/js/TreePanel.js:646
+ msgid "Upload Failed"
+ msgstr "Hochladen fehlgeschlagen"
+ #: Filemanager/js/GridPanel.js:663
+ #: Filemanager/js/TreePanel.js:627
+ msgid "Could not upload file. Filesize could be too big. Please notify your Administrator. Max upload size: "
+ msgstr "Die Datei konnte nicht hochgeladen werden. Möglicherweise ist die Datei zu groß. Bitte benachrichtigen Sie Ihren Administrator. Maximale erlaubte Dateigröße:"
+ #: Filemanager/js/GridPanel.js:808
+ #: Filemanager/js/TreePanel.js:647
+ msgid "Dropping on this folder not allowed!"
+ msgstr "Auf diesen Ordner darf nicht gedropt werden!"
+ #: Filemanager/js/Model.js:252
+ msgid "Copying data .. {0}"
+ msgstr "Kopiere Daten .. {0}"
+ #: Filemanager/js/Model.js:253
+ msgid "Moving data .. {0}"
+ msgstr "Verschiebe Daten .. {0}"
+ #: Filemanager/js/Model.js:255
+ msgid "user file folders"
+ msgstr "Ordner"
+ #: Filemanager/js/Model.js:357
+ msgid "Quick search"
+ msgstr "Schnellsuche"
+ #: Filemanager/js/Model.js:358
+ msgid "Type"
+ msgstr "Typ"
+ #: Filemanager/js/PathFilterModel.js:59
+ msgid "path"
+ msgstr "Pfad"
+ #~ msgid "Do you really want to delete the {0} \"{1}\"?"
+ #~ msgstr "Möchten Sie wirklich den {0} löschen? "
+ #~ msgid "example record"
+ #~ msgid_plural "example records"
+ #~ msgstr[0] "Beispieleintrag"
+ #~ msgstr[1] "Beispieleinträge"
+ #~ msgid "example record list"
+ #~ msgid_plural "example record lists"
+ #~ msgstr[0] "Beispieleintragliste"
+ #~ msgstr[1] "Beispieleintraglisten"
+ #~ msgid "Description"
+ #~ msgstr "Beschreibung"
+ #~ msgid "progress"
+ #~ msgstr "Fortschritt"
+ #~ msgid "user file"
+ #~ msgstr "Datei"
+ #~ msgid "user files"
+ #~ msgstr "Dateien"
@@@ -13,8 -14,16 +14,15 @@@ msgstr "
  "X-Poedit-Country: GB\n"
  "X-Poedit-SourceCharset: utf-8\n"
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
 -#, php-format
+ "X-Poedit-KeywordsList: _\n"
+ "X-Poedit-Basepath: ../../\n"
+ "X-Poedit-SearchPath-0: Filemanager\n"
+ #: Filemanager/Controller.php:95
+ msgid "%s's personal files"
+ msgstr "%s's personal files"
  
- #: Acl/Rights.php:97
+ #: Filemanager/Acl/Rights.php:97
  msgid "manage shared folders"
  msgstr "manage shared folders"
  
@@@ -26,7 -47,228 +46,232 @@@ msgstr "Other users folders
  msgid "Filemanager"
  msgstr "Filemanager"
  
- #, python-format
 +#: Controller.php:95
 +msgid "%s's personal files"
 +msgstr "%s's personal files"
++
+ #: Filemanager/js/Filemanager.js:56
+ msgid "File allready exists"
+ msgstr "File allready exists"
+ #: Filemanager/js/Filemanager.js:57
+ msgid "Do you want to replace the file?"
+ msgstr "Do you want to replace the file?"
+ #: Filemanager/js/Filemanager.js:73
+ msgid "Failure on create folder"
+ msgstr "Failure on create folder"
+ #: Filemanager/js/Filemanager.js:74
+ msgid "Item with this name allready exists!"
+ msgstr "Item with this name allready exists!"
+ #: Filemanager/js/GridContextMenu.js:36
+ #: Filemanager/js/GridPanel.js:467
+ msgid "Please enter the new name of the {0}:"
+ msgstr "Please enter the new name of the {0}:"
+ #: Filemanager/js/GridContextMenu.js:42
+ #: Filemanager/js/GridPanel.js:473
+ msgid "Not renamed {0}"
+ msgstr "Not renamed {0}"
+ #: Filemanager/js/GridContextMenu.js:42
+ #: Filemanager/js/GridPanel.js:473
+ #: Filemanager/js/GridPanel.js:533
+ msgid "You have to supply a {0} name!"
+ msgstr "You have to supply a {0} name!"
+ #: Filemanager/js/GridContextMenu.js:45
+ #: Filemanager/js/GridContextMenu.js:135
+ #: Filemanager/js/GridPanel.js:476
+ #: Filemanager/js/GridPanel.js:536
+ #: Filemanager/js/GridPanel.js:578
+ #: Filemanager/js/Model.js:271
+ msgid "Please wait"
+ msgstr "Please wait"
+ #: Filemanager/js/GridContextMenu.js:45
+ #: Filemanager/js/GridPanel.js:476
+ msgid "Updating {0} \"{1}\""
+ msgstr "Updating {0} \"{1}\""
+ #: Filemanager/js/GridContextMenu.js:133
+ #: Filemanager/js/GridPanel.js:575
+ msgid "Confirm"
+ msgstr "Confirm"
+ #: Filemanager/js/GridContextMenu.js:133
+ #: Filemanager/js/GridPanel.js:575
+ msgid "Do you really want to delete \"{0}\"?"
+ msgstr "Do you really want to delete \"{0}\"?"
+ #: Filemanager/js/GridContextMenu.js:135
+ msgid "Deleting {0} \"{1}\""
+ msgstr "Deleting {0} \"{1}\""
+ #: Filemanager/js/GridPanel.js:123
+ msgid "Name"
+ msgstr "Name"
+ #: Filemanager/js/GridPanel.js:130
+ msgid "Size"
+ msgstr "Size"
+ #: Filemanager/js/GridPanel.js:137
+ #: Filemanager/js/Model.js:359
+ msgid "Contenttype"
+ msgstr "Contenttype"
+ #: Filemanager/js/GridPanel.js:145
+ msgid "Folder"
+ msgstr "Folder"
+ #: Filemanager/js/GridPanel.js:153
+ msgid "Revision"
+ msgstr "Revision"
+ #: Filemanager/js/GridPanel.js:167
+ #: Filemanager/js/Model.js:360
+ msgid "Creation Time"
+ msgstr "Creation Time"
+ #: Filemanager/js/GridPanel.js:175
+ msgid "Created By"
+ msgstr "Created By"
+ #: Filemanager/js/GridPanel.js:182
+ msgid "Last Modified Time"
+ msgstr "Last Modified Time"
+ #: Filemanager/js/GridPanel.js:189
+ msgid "Last Modified By"
+ msgstr "Last Modified By"
+ #: Filemanager/js/GridPanel.js:223
+ msgid "Show closed"
+ msgstr "Show closed"
+ #: Filemanager/js/GridPanel.js:246
+ msgid "Upload"
+ msgstr "Upload"
+ #: Filemanager/js/GridPanel.js:272
+ msgid "Create Folder"
+ msgstr "Create Folder"
+ #: Filemanager/js/GridPanel.js:283
+ msgid "Folder Up"
+ msgstr "Folder Up"
+ #: Filemanager/js/GridPanel.js:294
+ msgid "Save locally"
+ msgstr "Save locally"
+ #: Filemanager/js/GridPanel.js:305
+ #: Filemanager/js/GridPanel.js:306
+ #: Filemanager/js/GridPanel.js:308
+ msgid "Delete"
+ msgstr "Delete"
+ #: Filemanager/js/GridPanel.js:318
+ #: Filemanager/js/GridPanel.js:319
+ #: Filemanager/js/GridPanel.js:321
+ msgid "Rename"
+ msgstr "Rename"
+ #: Filemanager/js/GridPanel.js:329
+ msgid "Pause upload"
+ msgstr "Pause upload"
+ #: Filemanager/js/GridPanel.js:336
+ msgid "Resume upload"
+ msgstr "Resume upload"
+ #: Filemanager/js/GridPanel.js:459
+ #: Filemanager/js/GridPanel.js:526
+ #: Filemanager/js/Model.js:361
+ msgid "user file folder"
+ msgstr "folder"
+ #: Filemanager/js/GridPanel.js:528
+ msgid "New {0}"
+ msgstr "New {0}"
+ #: Filemanager/js/GridPanel.js:528
+ msgid "Please enter the name of the new {0}:"
+ msgstr "Please enter the name of the new {0}:"
+ #: Filemanager/js/GridPanel.js:533
+ msgid "No {0} added"
+ msgstr "No {0} added"
+ #: Filemanager/js/GridPanel.js:536
+ msgid "Creating {0}..."
+ msgstr "Creating {0}..."
+ #: Filemanager/js/GridPanel.js:578
+ msgid "Deleting {0} "
+ msgstr "Deleting {0} "
+ #: Filemanager/js/GridPanel.js:662
+ #: Filemanager/js/GridPanel.js:807
+ #: Filemanager/js/TreePanel.js:626
+ #: Filemanager/js/TreePanel.js:646
+ msgid "Upload Failed"
+ msgstr "Upload Failed"
+ #: Filemanager/js/GridPanel.js:663
+ #: Filemanager/js/TreePanel.js:627
+ msgid "Could not upload file. Filesize could be too big. Please notify your Administrator. Max upload size: "
+ msgstr "Could not upload file. Filesize could be too big. Please notify your Administrator. Max upload size: "
+ #: Filemanager/js/GridPanel.js:808
+ #: Filemanager/js/TreePanel.js:647
+ msgid "Dropping on this folder not allowed!"
+ msgstr "Dropping on this folder not allowed!"
+ #: Filemanager/js/Model.js:252
+ msgid "Copying data .. {0}"
+ msgstr "Copying data .. {0}"
+ #: Filemanager/js/Model.js:253
+ msgid "Moving data .. {0}"
+ msgstr "Moving data .. {0}"
+ #: Filemanager/js/Model.js:255
+ msgid "user file folders"
+ msgstr "folders"
+ #: Filemanager/js/Model.js:357
+ msgid "Quick search"
+ msgstr "Quick search"
+ #: Filemanager/js/Model.js:358
+ msgid "Type"
+ msgstr "Type"
+ #: Filemanager/js/PathFilterModel.js:59
+ msgid "path"
+ msgstr "path"
+ #~ msgid "Do you really want to delete the {0} \"{1}\"?"
+ #~ msgstr "Do you really want to delete the {0} \"{1}\"?"
+ #~ msgid "example record"
+ #~ msgid_plural "example records"
+ #~ msgstr[0] "example record"
+ #~ msgstr[1] "example records"
+ #~ msgid "example record list"
+ #~ msgid_plural "example record lists"
+ #~ msgstr[0] "example record list"
+ #~ msgstr[1] "example record lists"
+ #~ msgid "Description"
+ #~ msgstr "Description"
+ #~ msgid "progress"
+ #~ msgstr "progress"
@@@ -185,22 -185,25 +185,24 @@@ class Setup_Core extends Tinebase_Cor
          
          // check database first
          if (self::configFileExists()) {
 -            $dbConfig = Tinebase_Core::getConfig()->database;            
 +            $dbConfig = Tinebase_Core::getConfig()->database;
 +            
              if ($dbConfig->adapter === self::PDO_MYSQL && (! defined(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY) || ! defined(PDO::MYSQL_ATTR_INIT_COMMAND))) {
                  Setup_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ 
 -                    . ' PDO constants not defined.');
 +                    . ' MySQL PDO constants not defined.');
++
                  return;
              }
              
              try {
                  parent::setupDatabaseConnection();
                  
 -                // check (mysql)db server version
 -                $ext = new Setup_ExtCheck(dirname(__FILE__) . '/essentials.xml');
 -                if ($dbConfig->adapter === self::PDO_MYSQL && ($mysqlRequired = $ext->getExtensionData('MySQL'))) {
 -                    //Check if installed MySQL version is compatible with required version
 -                    $hostnameWithPort = (isset($dbConfig->port)) ? $dbConfig->host . ':' . $dbConfig->port : $dbConfig->host;
 -                    $link = @mysql_connect($hostnameWithPort, $dbConfig->username, $dbConfig->password);
 -                    if ($link) {
 -                        $serverVersion = @mysql_get_server_info();
 -                        if (version_compare($mysqlRequired['VERSION'], $serverVersion, '<')) {
 +                $serverVersion = self::getDb()->getServerVersion();
 +                
 +                switch($dbConfig->adapter) {
 +                    case self::PDO_MYSQL:
 +                        if (version_compare(self::MYSQL_MINIMAL_VERSION, $serverVersion, '<')) {
++
                              self::set(Setup_Core::CHECKDB, TRUE);
                          } else {
                              Setup_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ 
Simple merge
index 0000000,0000000..9d21feb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,70 @@@
++<?php
++/**
++ * Tine 2.0
++ * 
++ * @package     Tinebase
++ * @subpackage  Filter
++ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
++ * @copyright   Copyright (c) 2011 Metaways Infosystems GmbH (http://www.metaways.de)
++ * @author      Philipp Schüle <p.schuele@metaways.de>
++ */
++
++/**
++ * Tinebase_Model_Tree_NodePathFilter
++ * 
++ * @package     Tinebase
++ * @subpackage  Filter
++ * 
++ */
++class Tinebase_Model_Tree_NodePathFilter extends Tinebase_Model_Filter_Text 
++{
++    /**
++     * @var array list of allowed operators
++     * 
++     * @todo add more operators?
++     */
++    protected $_operators = array(
++        0 => 'equals',       
++        //1 => 'in',         
++    );
++    
++    /**
++     * a path could belong to one container
++     * 
++     * @var Tinebase_Model_Container
++     */
++    protected $_container = NULL;
++    
++    /**
++     * set container
++     * 
++     * @param Tinebase_Model_Container $_container
++     */
++    public function setContainer(Tinebase_Model_Container $_container)
++    {
++        $this->_container = $_container;
++    }
++    
++    /**
++     * appends sql to given select statement
++     *
++     * @param  Zend_Db_Select                    $_select
++     * @param  Tinebase_Backend_Sql_Abstract     $_backend
++     */
++    public function appendFilterSql($_select, $_backend)
++    {
++        $path = $this->_value;
++        if ($this->_container) {
++            $path = preg_replace('/' . $this->_container->name . '/', $this->_container->getId(), $path);
++        }
++        
++        $node = Tinebase_FileSystem::getInstance()->stat($path);
++        
++        $field = 'parent_id';
++        $action = $this->_opSqlMap[$this->_operator];
++        $value = $node->getId();
++        
++        $where = Tinebase_Core::getDb()->quoteInto($field . $action['sqlop'], $value);
++        $_select->where($where);
++    }    
++}
Simple merge
Simple merge
Simple merge
Simple merge
index a137660,6abbcef..3ec4dbf
mode 100755,100644..100644
@@@ -715,18 -733,3 +733,18 @@@ span:hover.tinebase-addtocontacts-link 
  span:hover.tinebase-showheaders-link {\r
      color: #4444ff;\r
  }\r
- }*/
 +\r
 +.tine-keyfield-icon {\r
 +    width: 12px;\r
 +    height: 12px;\r
 +    vertical-align: text-bottom;\r
 +    padding-right: 4px;\r
 +}\r
 +\r
 +.x-grid .tine-keyfield-icon {\r
 +    vertical-align: text-top;\r
 +}\r
 +\r
 +/*.x-combo-list-item .tine-keyfield-icon {\r
 +    padding-right: 4px;\r
++}*/
Simple merge
@@@ -1211,7 -1224,8 +1218,8 @@@ Ext.extend(Tine.widgets.grid.GridPanel
       * 
       * @param {String|Tine.Tinebase.data.Record} record
       */
 -    onUpdateRecord: function(record) {
 -             
 +    onUpdateRecord: function(record, mode) {
++
          if (Ext.isString(record) && this.recordProxy) {
              record = this.recordProxy.recordReader({responseText: record});
          } else if (record && Ext.isFunction(record.copy)) {
@@@ -18,43 -18,276 +18,276 @@@ Ext.ns('Tine.widgets', 'Tine.widgets.tr
   * ctxNode class var is required in calling class
   */
  Tine.widgets.tree.ContextMenu = {
--      
++    
      /**
       * create new Ext.menu.Menu with actions
       * 
       * @param {} config has the node name, actions, etc.
       * @return {}
       */
--      getMenu: function(config) {
++    getMenu: function(config) {
          
-         /***************** define action handlers *****************/
-         var handler = {
-             /**
-              * create
-              */
-             addNode: function() {
-                 Ext.MessageBox.prompt(String.format(_('New {0}'), config.nodeName), String.format(_('Please enter the name of the new {0}:'), config.nodeName), function(_btn, _text) {
-                     if( this.ctxNode && _btn == 'ok') {
+         this.config = config;
+                 
+         /****************** create ITEMS array ****************/
+               
+         this.action_add = new Ext.Action({
+             text: String.format(_('Add')),
+             iconCls: 'action_add',
+             handler: this.addNode,
+             requiredGrant: 'addGrant',
+             scope: this.config
+         });
+         
+         this.action_rename = new Ext.Action({
+             text: String.format(_('Rename')),
+             iconCls: 'action_rename',
+             handler: this.renameNode,
+             scope: this.config,
+             requiredGrant: 'editGrant',
+             allowMultiple: false
+         });
+         
+         
+         var i18n = new Locale.Gettext();
+         i18n.textdomain('Tinebase');
+         this.action_delete = new Ext.Action({
+             text: String.format(_('Delete')),
+             iconCls: 'action_delete',
+             handler: this.deleteNode,
+             scope: this.config,
+             requiredGrant: 'deleteGrant',
+             allowMultiple: true
+         });
+         
+         this.action_grants = new Ext.Action({
+             text: _('Manage permissions'),
+             iconCls: 'action_managePermissions',
+             handler: this.managePermissions,
+             requiredGrant: 'editGrant',
+             scope: this.config
+         });
+         
+         this.action_changecolor = new Ext.Action({     
+             text: String.format(_('Set color')),
+             iconCls: 'action_changecolor',
+             requiredGrant: 'deleteGrant',
+             allowMultiple: true,
+             menu: new Ext.menu.ColorMenu({
+                 scope: this,
+                 listeners: {
+                     select: this.changeNodeColor,
+                     scope: this.config
+                 }
+             })                                        
+         });
+         
+         this.action_reload = new Ext.Action({
+             text: String.format(_('Reload')),
+             iconCls: 'x-tbar-loading',
+             handler: this.reloadNode,
+             scope: this.config
+         });
+         
+         this.action_resume = new Ext.Action({
+             text: String.format(_('Resume upload'), config.nodeName),
+             iconCls: 'action_resume',
+             handler: this.onResume,
+             scope: this.config,
+             actionUpdater: this.isResumeEnabled
+         });
+         
+         this.action_pause = new Ext.Action({
+             text: String.format(_('Pause upload'), config.nodeName),
+             iconCls: 'action_pause',
+             handler: this.onPause,
+             actionUpdater: this.isPauseEnabled,
+             scope: this.config
+         });
+         
+         this.action_download = new Ext.Action({
+             text: String.format(_('Download'), config.nodeName),
+             iconCls: 'action_filemanager_save_all',
+             handler: this.downloadFile,
+             actionUpdater: this.isDownloadEnabled,
+             requiredGrant: 'exportGrant',
+             scope: this.config
+         });
+         
+         var items = [];
+         for (var i=0; i < config.actions.length; i++) {
+             switch(config.actions[i]) {
+                 case 'add':
+                     items.push(this.action_add);
+                     break;
+                 case 'delete':                    
+                     items.push(this.action_delete);
+                     break;
+                 case 'rename':
+                     items.push(this.action_rename);
+                     break;
+                 case 'changecolor':
+                     items.push(this.action_changecolor);
+                     break;
+                 case 'grants':
+                     items.push(this.action_grants);
+                     break;
+                 case 'reload':
+                     items.push(this.action_reload);
+                     break;
+                 case 'resume':
+                     items.push(this.action_resume);
+                     break;
+                 case 'pause':
+                     items.push(this.action_pause);
+                     break;
+                 case 'download':
+                     items.push(this.action_download);
+                     break;
+                 default:
+                     // add custom actions
+                     items.push(new Ext.Action(config.actions[i]));
+             }
+         }
+              
+         /******************* return menu **********************/
+         
+         return new Ext.menu.Menu({
 -                  items: items
 -              });
 -      },
++            items: items
++        });
++    },
+     
 -      /**
 -       * create tree node
 -       */
 -      addNode: function() {
++    /**
++     * create tree node
++     */
++    addNode: function() {
+         Ext.MessageBox.prompt(String.format(_('New {0}'), this.nodeName), String.format(_('Please enter the name of the new {0}:'), this.nodeName), function(_btn, _text) {
+             if( this.scope.ctxNode && _btn == 'ok') {
+                 if (! _text) {
+                     Ext.Msg.alert(String.format(_('No {0} added'), this.nodeName), String.format(_('You have to supply a {0} name!'), this.nodeName));
+                     return;
+                 }
+                 Ext.MessageBox.wait(_('Please wait'), String.format(_('Creating {0}...' ), this.nodeName));
+                 var parentNode = this.scope.ctxNode;
+                 
+                 var params = {
+                     method: this.backend + '.add' + this.backendModel,
+                     name: _text
+                 };
+                 
+                 // TODO try to generalize this and move app specific stuff to app
+                 
+                 if (this.backendModel == 'Node') {
+                     params.application = this.scope.app.appName || this.scope.appName;                            
+                     var filename = parentNode.attributes.nodeRecord.data.path + '/' + _text;
+                     params.filename = filename;
+                     params.type = 'folder';
+                     params.method = this.backend + ".createNode";
+                 }
+                 else if (this.backendModel == 'Container') {
+                     params.application = this.scope.app.appName || this.scope.appName;
+                     params.containerType = Tine.Tinebase.container.path2type(parentNode.attributes.path);
+                 } 
+                 else if (this.backendModel == 'Folder') {
+                     var parentFolder = Tine.Tinebase.appMgr.get('Felamimail').getFolderStore().getById(parentNode.attributes.folder_id);
+                     params.parent = parentFolder.get('globalname');
+                     params.accountId = parentFolder.get('account_id');
+                 }
+                 
+                 Ext.Ajax.request({
+                     params: params,
+                     scope: this,
+                     success: function(result, request){
+                         var nodeData = Ext.util.JSON.decode(result.responseText);
+                         // TODO add + icon if it wasn't expandable before
+                         if(nodeData.type == 'folder') {
+                             var nodeData = Ext.util.JSON.decode(result.responseText);
+                             var app = Tine.Tinebase.appMgr.get(this.scope.app.appName);
+                             var newNode = app.getMainScreen().getWestPanel().getContainerTreePanel().createTreeNode(nodeData, parentNode);
+                             parentNode.appendChild(newNode);
+                         }
+                         else {
+                             var newNode = this.loader.createNode(nodeData);
+                             parentNode.appendChild(newNode);
+                         }
+                         
+                         parentNode.expand();
+                         this.scope.fireEvent('containeradd', nodeData);
+                         
+                         // TODO: im event auswerten
+                         if (this.backendModel == 'Node') {
+                             this.scope.app.getMainScreen().getCenterPanel().getStore().reload();
+                             if(nodeData.error) {
+                                 Tine.log.debug(nodeData);
+                             }
+                         }
+                         Ext.MessageBox.hide();
+                     },
+                     failure: function(result, request) {
+                         var nodeData = Ext.util.JSON.decode(result.responseText);
+                         
+                         var appContext = Tine[this.scope.app.appName];
+                         if(appContext && appContext.handleRequestException) {
+                             appContext.handleRequestException(nodeData.data);
+                         }
+                     }
+                 });
+                 
+             }
+         }, this);
+     },
+     
+     /**
+      * rename tree node
+      */
+     renameNode: function() {
+         if (this.scope.ctxNode) {
+                        
+             var node = this.scope.ctxNode;
+             Ext.MessageBox.show({
+                 title: 'Rename ' + this.nodeName,
+                 msg: String.format(_('Please enter the new name of the {0}:'), this.nodeName),
+                 buttons: Ext.MessageBox.OKCANCEL,
+                 value: node.text,
+                 fn: function(_btn, _text){
+                     if (_btn == 'ok') {
                          if (! _text) {
-                             Ext.Msg.alert(String.format(_('No {0} added'), config.nodeName), String.format(_('You have to supply a {0} name!'), config.nodeName));
+                             Ext.Msg.alert(String.format(_('Not renamed {0}'), this.nodeName), String.format(_('You have to supply a {0} name!'), this.nodeName));
                              return;
                          }
-                         Ext.MessageBox.wait(_('Please wait'), String.format(_('Creating {0}...' ), config.nodeName));
-                         var parentNode = this.ctxNode;
+                         Ext.MessageBox.wait(_('Please wait'), String.format(_('Updating {0} "{1}"'), this.nodeName, node.text));
                          
                          var params = {
-                             method: config.backend + '.add' + config.backendModel,
-                             name: _text
+                             method: this.backend + '.rename' + this.backendModel,
+                             newName: _text
                          };
                          
-                         // TODO try to generalize this and move app specific stuff to app
-                         if (config.backendModel == 'Container') {
-                             params.application = this.app.appName || this.appName;
-                             params.containerType = Tine.Tinebase.container.path2type(parentNode.attributes.path);
-                         } else if (config.backendModel == 'Folder') {
-                             var parentFolder = Tine.Tinebase.appMgr.get('Felamimail').getFolderStore().getById(parentNode.attributes.folder_id);
-                             params.parent = parentFolder.get('globalname');
-                             params.accountId = parentFolder.get('account_id');
+                         if (this.backendModel == 'Node') {
+                             params.application = this.scope.app.appName || this.scope.appName;                                
+                             var filename = node.attributes.path;
+                             params.sourceFilenames = [filename];
+                             
+                             var targetFilename = "/";
+                             var sourceSplitArray = filename.split("/");
+                             for (var i=1; i<sourceSplitArray.length-1; i++) {
+                                 targetFilename += sourceSplitArray[i] + '/'; 
+                             }
+                             
+                             params.destinationFilenames = [targetFilename + _text];
+                             params.method = this.backend + '.moveNodes';
+                         }
+                         
+                         // TODO try to generalize this
+                         if (this.backendModel == 'Container') {
+                             params.containerId = node.attributes.nodeRecord.data.id;
+                         } else if (this.backendModel == 'Folder') {
+                             var folder = Tine.Tinebase.appMgr.get('Felamimail').getFolderStore().getById(node.attributes.folder_id);
+                             params.oldGlobalName = folder.get('globalname');
+                             params.accountId = folder.get('account_id');
                          }
                          
                          Ext.Ajax.request({
                              scope: this,
                              success: function(_result, _request){
                                  var nodeData = Ext.util.JSON.decode(_result.responseText);
-                                 var newNode = this.loader.createNode(nodeData);
-                                 parentNode.appendChild(newNode);
-                                 // TODO add + icon if it wasn't expandable before
-                                 parentNode.expand();
-                                 this.fireEvent('containeradd', nodeData);
+                                 node.setText(_text);
+                                 this.scope.fireEvent('containerrename', nodeData);
                                  Ext.MessageBox.hide();
+                                 
+                                 // TODO: im event auswerten
+                                 if (this.backendModel == 'Node') {
+                                     this.scope.app.getMainScreen().getCenterPanel().getStore().reload();
+                                 }
+                             },
+                             failure: function(result, request) {
+                                 var nodeData = Ext.util.JSON.decode(result.responseText);
+                                 
+                                 var appContext = Tine[this.scope.app.appName];
+                                 if(appContext && appContext.handleRequestException) {
+                                     appContext.handleRequestException(nodeData.data);
+                                 }
                              }
                          });
-                         
                      }
-                 }, this);
-             },
-             
-             /**
-              * delete
-              */
-             deleteNode: function() {
-                 if (this.ctxNode) {
-                     var node = this.ctxNode;
-                     Ext.MessageBox.confirm(_('Confirm'), String.format(_('Do you really want to delete the {0} "{1}"?'), config.nodeName, node.text), function(_btn){
-                         if ( _btn == 'yes') {
-                             Ext.MessageBox.wait(_('Please wait'), String.format(_('Deleting {0} "{1}"' ), config.nodeName , node.text));
-                             
-                             var params = {
-                                 method: config.backend + '.delete' + config.backendModel
-                             }
-                             
-                             if (config.backendModel == 'Container') {
-                                 params.containerId = node.attributes.container.id
-                             } else if (config.backendModel == 'Folder') {
-                                 var folder = Tine.Tinebase.appMgr.get('Felamimail').getFolderStore().getById(node.attributes.folder_id);
-                                 params.folder = folder.get('globalname');
-                                 params.accountId = folder.get('account_id');
-                             } else {
-                                 // use default json api style
-                                 params.ids = [node.id];
-                                 params.method = params.method + 's';
-                             }
-                             
-                             Ext.Ajax.request({
-                                 params: params,
-                                 scope: this,
-                                 success: function(_result, _request){
-                                     if(node.isSelected()) {
-                                         this.getSelectionModel().select(node.parentNode);
-                                         this.fireEvent('click', node.parentNode, Ext.EventObject.setEvent());
-                                     }
-                                     node.remove();
-                                     if (config.backendModel == 'Container') {
-                                         this.fireEvent('containerdelete', node.attributes.container);
-                                     } else {
-                                         this.fireEvent('containerdelete', node.attributes);
-                                     }
-                                     Ext.MessageBox.hide();
-                                 },
-                                 failure: (config.backendModel == 'Folder') ? Tine.Felamimail.handleRequestException : Tine.Tinebase.ExceptionHandler.handleRequestException
-                             });
-                         }
-                     }, this);
-                 }
-             },
+                 },
+                 scope: this,
+                 prompt: true,
+                 icon: Ext.MessageBox.QUESTION
+             });
+         }
+     },
+     
+     /**
+      * delete tree node
+      */
+     deleteNode: function() {
+         
+         if (this.scope.ctxNode) {
+             var node = this.scope.ctxNode;
              
-             /**
-              * rename
-              */
-             renameNode: function() {
-                 if (this.ctxNode) {
-                     var node = this.ctxNode;
-                     Ext.MessageBox.show({
-                         title: 'Rename ' + config.nodeName,
-                         msg: String.format(_('Please enter the new name of the {0}:'), config.nodeName),
-                         buttons: Ext.MessageBox.OKCANCEL,
-                         value: node.text,
-                         fn: function(_btn, _text){
-                             if (_btn == 'ok') {
-                                 if (! _text) {
-                                     Ext.Msg.alert(String.format(_('Not renamed {0}'), config.nodeName), String.format(_('You have to supply a {0} name!'), config.nodeName));
-                                     return;
+             Ext.MessageBox.confirm(_('Confirm'), String.format(_('Do you really want to delete the {0} "{1}"?'), this.nodeName, node.text), function(_btn){
+                 if ( _btn == 'yes') {
+                     Ext.MessageBox.wait(_('Please wait'), String.format(_('Deleting {0} "{1}"' ), this.nodeName , node.text));
+                     
+                     var params = {
+                         method: this.backend + '.delete' + this.backendModel
+                     };
+                     
+                     if (this.backendModel == 'Node') {
+                                            
+                         var filenames = [node.attributes.path];                                              
+                         params.application = this.scope.app.appName || this.scope.appName;    
+                         params.filenames = filenames;
+                         params.method = this.backend + ".deleteNodes";
+                     
+                     } else if (this.backendModel == 'Container') {
+                         params.containerId = node.attributes.container.id;
+                     } else if (this.backendModel == 'Folder') {
+                         var folder = Tine.Tinebase.appMgr.get('Felamimail').getFolderStore().getById(node.attributes.folder_id);
+                         params.folder = folder.get('globalname');
+                         params.accountId = folder.get('account_id');
+                     } else {
+                         // use default json api style
+                         params.ids = [node.id];
+                         params.method = params.method + 's';
+                     }
+                     
+                     Ext.Ajax.request({
+                         params: params,
+                         scope: this,
+                         success: function(_result, _request){
+                               
+                             if(node) {
+                                 if(node.isSelected()) {
+                                     this.scope.getSelectionModel().select(node.parentNode);
+                                     this.scope.fireEvent('click', node.parentNode, Ext.EventObject.setEvent());
                                  }
-                                 Ext.MessageBox.wait(_('Please wait'), String.format(_('Updating {0} "{1}"'), config.nodeName, node.text));
-                                 
-                                 var params = {
-                                     method: config.backend + '.rename' + config.backendModel,
-                                     newName: _text
-                                 };
-                                 
-                                 // TODO try to generalize this
-                                 if (config.backendModel == 'Container') {
-                                     params.containerId = node.attributes.container.id;
-                                 } else if (config.backendModel == 'Folder') {
-                                     var folder = Tine.Tinebase.appMgr.get('Felamimail').getFolderStore().getById(node.attributes.folder_id);
-                                     params.oldGlobalName = folder.get('globalname');
-                                     params.accountId = folder.get('account_id');
-                                     
+                                 node.remove();
+                                 if (this.backendModel == 'Container') {
+                                     this.scope.fireEvent('containerdelete', node.attributes.container);
+                                 } else if (this.backendModel == 'Node') {
+                                     this.scope.fireEvent('containerdelete', node);
+                                 } else {
+                                     this.scope.fireEvent('containerdelete', node.attributes);
                                  }
-                                 
-                                 Ext.Ajax.request({
-                                     params: params,
-                                     scope: this,
-                                     success: function(_result, _request){
-                                         var nodeData = Ext.util.JSON.decode(_result.responseText);
-                                         node.setText(_text);
-                                         this.fireEvent('containerrename', nodeData);
-                                         Ext.MessageBox.hide();
-                                     },
-                                     failure: (config.backendModel == 'Folder') ? Tine.Felamimail.handleRequestException : Tine.Tinebase.ExceptionHandler.handleRequestException
-                                 });
                              }
+                            
+                             
+                             
+                             Ext.MessageBox.hide();
                          },
-                         scope: this,
-                         prompt: true,
-                         icon: Ext.MessageBox.QUESTION
-                     });
-                 }
-             },
-             
-             /**
-              * set color
-              */
-             changeNodeColor: function(cp, color) {
-                 if (this.ctxNode) {
-                     var node = this.ctxNode;
-                     node.getUI().addClass("x-tree-node-loading");
-                         Ext.Ajax.request({
-                             params: {
-                                 method: config.backend + '.set' + config.backendModel + 'Color',
-                                 containerId: node.attributes.container.id,
-                                 color: '#' + color
-                             },
-                             scope: this,
-                             success: function(_result, _request){
-                                 var nodeData = Ext.util.JSON.decode(_result.responseText);
-                                 node.getUI().colorNode.setStyle({color: nodeData.color});
-                                 node.attributes.container.color = nodeData.color;
-                                 this.fireEvent('containercolorset', nodeData);
-                                 node.getUI().removeClass("x-tree-node-loading");
+                         failure: function(result, request) {
+                             var nodeData = Ext.util.JSON.decode(result.responseText);
+                             
+                             var appContext = Tine[this.scope.app.appName];
+                             if(appContext && appContext.handleRequestException) {
+                                 appContext.handleRequestException(nodeData.data);
                              }
-                         });
-                 
-                 }
-             },
-             
-             /**
-              * manage permissions
-              * 
-              */
-             managePermissions: function() {
-                 if (this.ctxNode) {
-                     var node = this.ctxNode;
-                     var window = Tine.widgets.container.GrantsDialog.openWindow({
-                         title: String.format(_('Manage Permissions for {0} "{1}"'), config.nodeName, Ext.util.Format.htmlEncode(node.attributes.container.name)),
-                         containerName: config.nodeName,
-                         grantContainer: node.attributes.container
+                         }
                      });
                  }
-             },
-             
-             /**
-              * reload node
-              */
-             reloadNode: function() {
-                 if (this.ctxNode) {
-                     var tree = this;
-                     this.ctxNode.reload(function(node) {
-                         node.expand();
-                         node.select();
-                         // update grid
-                         tree.filterPlugin.onFilterChange();
-                     });                    
-                 }
-             }
+             }, this);
          }
 -      
+     },
++    
+     /**
+      * change tree node color
+      */
+     changeNodeColor: function(cp, color) {
+         if (this.scope.ctxNode) {
+             var node = this.scope.ctxNode;
+             node.getUI().addClass("x-tree-node-loading");
+                 Ext.Ajax.request({
+                     params: {
+                         method: this.backend + '.set' + this.backendModel + 'Color',
+                         containerId: node.attributes.nodeRecord.data.id,
+                         color: '#' + color
+                     },
+                     scope: this,
+                     success: function(_result, _request){
+                         var nodeData = Ext.util.JSON.decode(_result.responseText);
+                         node.getUI().colorNode.setStyle({color: nodeData.color});
+                         node.attributes.nodeRecord.data.color = nodeData.color;
+                         this.scope.fireEvent('containercolorset', nodeData);
+                         node.getUI().removeClass("x-tree-node-loading");
+                     },
+                     failure: function(result, request) {
+                         var nodeData = Ext.util.JSON.decode(result.responseText);
+                         
+                         var appContext = Tine[this.scope.app.appName];
+                         if(appContext && appContext.handleRequestException) {
+                             appContext.handleRequestException(nodeData.data);
+                         }
+                     }
+                 });
          
-         /****************** create ITEMS array ****************/
-         
-         var items = [];
-         for (var i=0; i < config.actions.length; i++) {
-             switch(config.actions[i]) {
-                 case 'add':
-                     items.push(new Ext.Action({
-                         text: String.format(_('Add {0}'), config.nodeName),
-                         iconCls: 'action_add',
-                         handler: handler.addNode,
-                         scope: config.scope
-                     }));
-                     break;
-                 case 'delete':
-                     var i18n = new Locale.Gettext();
-                     i18n.textdomain('Tinebase');
-                     items.push(new Ext.Action({
-                         text: String.format(i18n.n_('Delete {0}', 'Delete {0}', 1), config.nodeName),
-                         iconCls: 'action_delete',
-                         handler: handler.deleteNode,
-                         scope: config.scope
-                     }));
-                     break;
-                 case 'rename':
-                     items.push(new Ext.Action({
-                         text: String.format(_('Rename {0}'), config.nodeName),
-                         iconCls: 'action_rename',
-                         handler: handler.renameNode,
-                         scope: config.scope
-                     }));
-                     break;
-                 case 'changecolor':
-                     items.push(new Ext.Action({     
-                         text: String.format(_('Set color for {0}'), config.nodeName),
-                         iconCls: 'action_changecolor',
-                         menu: new Ext.menu.ColorMenu({
-                             scope: this,
-                             listeners: {
-                                 select: handler.changeNodeColor,
-                                 scope: config.scope
-                             }
-                         })                                        
-                     }));
-                     break;
-                 case 'grants':
-                     items.push(new Ext.Action({
-                         text: _('Manage permissions'),
-                         iconCls: 'action_managePermissions',
-                         handler: handler.managePermissions,
-                         scope: config.scope
-                     }));
-                     break;
-                 case 'reload':
-                     items.push(new Ext.Action({
-                         text: String.format(_('Reload {0}'), config.nodeName),
-                         iconCls: 'x-tbar-loading',
-                         handler: handler.reloadNode,
-                         scope: config.scope
-                     }));
-                     break;
-                 default:
-                     // add custom actions
-                     items.push(new Ext.Action(config.actions[i]));
+         }
+     },
+     
 -      /**
++    /**
+      * manage permissions
+      * 
+      */
+     managePermissions: function() {
+         console.log(this.scope.ctxNode);
+         if (this.scope.ctxNode) {
+             var node = this.scope.ctxNode;
+             
+             var grantContainer = node.attributes.nodeRecord.data;
+             if(grantContainer.name.id) {
+                 grantContainer = grantContainer.name;
              }
+             
+             var window = Tine.widgets.container.GrantsDialog.openWindow({
+                 title: String.format(_('Manage Permissions for {0} "{1}"'), this.nodeName, Ext.util.Format.htmlEncode(node.attributes.nodeRecord.data.name)),
+                 containerName: this.nodeName,
+                 grantContainer: grantContainer
+             });
          }
-         /******************* return menu **********************/
-         
-         return new Ext.menu.Menu({
-                   items: items
-               });
-       }
+     },
+     
+     /**
+      * reload node
+      */
+     reloadNode: function() {
+         if (this.scope.ctxNode) {
+             var tree = this.scope;
+             this.scope.ctxNode.reload(function(node) {
+                 node.expand();
+                 node.select();
+                 // update grid
+                 tree.filterPlugin.onFilterChange();
+             });                    
+         }
+     }
+     
  };