From 67575e1cd1a57867201fb77f20091cd2b33e3980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20St=C3=B6ckel?= Date: Mon, 21 Mar 2011 16:12:28 +0000 Subject: [PATCH] Added move and copy multiple files functions to egw_vfs, implemented functions needed to reload subtrees of the egw_grid, fixed problems with data fetching in egw_grid_data.js --- phpgwapi/inc/class.egw_vfs.inc.php | 89 ++++++++++++++++++- phpgwapi/js/egw_action/egw_action.js | 19 ++-- phpgwapi/js/egw_action/egw_action_common.js | 96 +++++++++++++++++++++ phpgwapi/js/egw_action/egw_grid_data.js | 63 +++++++++++--- phpgwapi/js/egw_action/egw_grid_view.js | 38 +++++++- 5 files changed, 286 insertions(+), 19 deletions(-) diff --git a/phpgwapi/inc/class.egw_vfs.inc.php b/phpgwapi/inc/class.egw_vfs.inc.php index 5475fbb38c..638b5300d5 100644 --- a/phpgwapi/inc/class.egw_vfs.inc.php +++ b/phpgwapi/inc/class.egw_vfs.inc.php @@ -1556,7 +1556,7 @@ class egw_vfs extends vfs_stream_wrapper * * @return string */ - static function get_home_dir() + static public function get_home_dir() { $start = '/home/'.$GLOBALS['egw_info']['user']['account_lid']; @@ -1568,6 +1568,93 @@ class egw_vfs extends vfs_stream_wrapper } return $start; } + + /** + * Copies the files given in $src to $dst. + * + * @param array $src contains the source file + * @param string $dst is the destination directory + */ + static public function copy_files(array $src, $dst, &$errs, array &$copied) + { + if (self::is_dir($dst)) + { + foreach ($src as $file) + { + // Check whether the file has already been copied - prevents from + // recursion + if (!in_array($file, $copied)) + { + // Calculate the target filename + $target = egw_vfs::concat($dst, egw_vfs::basename($file)); + + if (self::is_dir($file)) + { + if ($file !== $target) + { + // Create the target directory + egw_vfs::mkdir($target,null,STREAM_MKDIR_RECURSIVE); + + $files = egw_vfs::find($file, array( + "hidden" => true + )); + + $copied[] = $file; + $copied[] = $target; // < newly created folder must not be copied again! + if (egw_vfs::copy_files(egw_vfs::find($file), $target, + $errs, $copied)) + { + continue; + } + } + + $errs++; + } + else + { + // Copy a single file - check whether the file should be + // copied onto itself. + // TODO: Check whether target file already exists and give + // return those files so that a dialog might be displayed + // on the client side which lets the user decide. + if ($target !== $file && egw_vfs::copy($file, $target)) + { + $copied[] = $file; + } + else + { + $errs++; + } + } + } + } + } + + return $errs == 0; + } + + /** + * Moves the files given in src to dst + */ + static public function move_files(array $src, $dst, &$errs, array &$moved) + { + if (egw_vfs::is_dir($dst)) + { + foreach($src as $file) + { + $target = egw_vfs::concat($dst, egw_vfs::basename($file)); + + if ($file != $target && egw_vfs::rename($file, $target)) + { + $moved[] = $file; + } + else + { + ++$errs; + } + } + } + } } egw_vfs::init_static(); diff --git a/phpgwapi/js/egw_action/egw_action.js b/phpgwapi/js/egw_action/egw_action.js index 668c1f3d7a..66b9ff65b1 100644 --- a/phpgwapi/js/egw_action/egw_action.js +++ b/phpgwapi/js/egw_action/egw_action.js @@ -55,6 +55,7 @@ function egwAction(_id, _handler, _caption, _iconUrl, _onExecute, _allowOnMultip this.caption = _caption; this.iconUrl = _iconUrl; this.allowOnMultiple = _allowOnMultiple; + this.enabled = true; this.type = "default"; //All derived classes have to override this! this.execJSFnct = null; @@ -137,6 +138,11 @@ egwAction.prototype.set_iconUrl = function(_value) this.iconUrl = _value; } +egwAction.prototype.set_enabled = function(_value) +{ + this.enabled = _value; +} + egwAction.prototype.set_allowOnMultiple = function(_value) { this.allowOnMultiple = _value; @@ -195,7 +201,7 @@ egwActionManager.prototype.updateActions = function(_actions) { //Check whether the action already exists, and if no, add it to the //actions list - var action = this.getAction(elem.id); + var action = this.getActionById(elem.id); if (!action) { if (typeof elem.type == "undefined") @@ -219,7 +225,10 @@ egwActionManager.prototype.updateActions = function(_actions) } } -egwActionManager.prototype.getAction = function(_id) +/** + * Returns the action inside the action manager which has the given id. + */ +egwActionManager.prototype.getActionById = function(_id) { for (var i = 0; i < this.actions.length; i++) { @@ -328,7 +337,7 @@ egwActionLink.prototype.set_visible = function(_value) egwActionLink.prototype.set_actionId = function(_value) { this.actionId = _value; - this.actionObj = this.manager.getAction(_value); + this.actionObj = this.manager.getActionById(_value); if (!this.actionObj) throw "Given action object does not exist!" @@ -1170,8 +1179,8 @@ egwActionObject.prototype.getSelectedLinks = function(_actionType) // Accumulate the action link properties var llink = actionLinks[olink.actionId]; - llink.enabled = llink.enabled && olink.enabled && - olink.visible; + llink.enabled = olink.actionObj.enabled && llink.enabled && + olink.enabled && olink.visible; llink.visible = llink.visible || olink.visible; llink.cnt++; } diff --git a/phpgwapi/js/egw_action/egw_action_common.js b/phpgwapi/js/egw_action/egw_action_common.js index 1770cf0c9a..37bdbc2de3 100644 --- a/phpgwapi/js/egw_action/egw_action_common.js +++ b/phpgwapi/js/egw_action/egw_action_common.js @@ -128,4 +128,100 @@ function egwCallAbstract(_obj, _fn, _args) return false; } +/** +sprintf() for JavaScript 0.6 + +Copyright (c) Alexandru Marasteanu +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of sprintf() for JavaScript nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Changelog: +2007.04.03 - 0.1: + - initial release +2007.09.11 - 0.2: + - feature: added argument swapping +2007.09.17 - 0.3: + - bug fix: no longer throws exception on empty paramenters (Hans Pufal) +2007.10.21 - 0.4: + - unit test and patch (David Baird) +2010.05.09 - 0.5: + - bug fix: 0 is now preceeded with a + sign + - bug fix: the sign was not at the right position on padded results (Kamal Abdali) + - switched from GPL to BSD license +2010.05.22 - 0.6: + - reverted to 0.4 and fixed the bug regarding the sign of the number 0 + Note: + Thanks to Raphael Pigulla (http://www.n3rd.org/) + who warned me about a bug in 0.5, I discovered that the last update was + a regress. I appologize for that. +**/ + +function str_repeat(i, m) { + for (var o = []; m > 0; o[--m] = i); + return o.join(''); +} + +function sprintf() { + var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = ''; + while (f) { + if (m = /^[^\x25]+/.exec(f)) { + o.push(m[0]); + } + else if (m = /^\x25{2}/.exec(f)) { + o.push('%'); + } + else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) { + if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) { + throw('Too few arguments.'); + } + if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) { + throw('Expecting number but found ' + typeof(a)); + } + switch (m[7]) { + case 'b': a = a.toString(2); break; + case 'c': a = String.fromCharCode(a); break; + case 'd': a = parseInt(a); break; + case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break; + case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break; + case 'o': a = a.toString(8); break; + case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break; + case 'u': a = Math.abs(a); break; + case 'x': a = a.toString(16); break; + case 'X': a = a.toString(16).toUpperCase(); break; + } + a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a); + c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' '; + x = m[5] - String(a).length - s.length; + p = m[5] ? str_repeat(c, x) : ''; + o.push(s + (m[4] ? a + p : p + a)); + } + else { + throw('Huh ?!'); + } + f = f.substring(m[0].length); + } + return o.join(''); +} diff --git a/phpgwapi/js/egw_action/egw_grid_data.js b/phpgwapi/js/egw_action/egw_grid_data.js index bb0a5b542c..bc0720c49a 100644 --- a/phpgwapi/js/egw_action/egw_grid_data.js +++ b/phpgwapi/js/egw_action/egw_grid_data.js @@ -637,7 +637,47 @@ egwGridDataElement.prototype.callEndUpdate = function() egwGridDataElement.prototype.empty = function() { this.children = []; - this.readQueue.empty(); +// this.readQueue.empty(); +} + +/** + * Returns all parents in a list + */ +egwGridDataElement.prototype.getParentList = function(_lst) +{ + if (typeof _lst == "undefined") + { + _lst = []; + } + + _lst.push(this); + + if (this.parent) + { + this.parent.getParentList(_lst); + } + + return _lst; +} + + +function egwGridData_getOutermostParent(_elements) +{ + var minElem = null; + var minCnt = 0; + + for (var i = 0; i < _elements.length; i++) + { + var parents = _elements[i].getParentList(); + + if (i == 0 || parents.length < minCnt) + { + minCnt = parents.length; + minElem = _elements[i]; + } + } + + return minElem ? (minElem.parent ? minElem.parent : minElem) : null; } /** - egwGridDataReadQueue -- **/ @@ -692,12 +732,15 @@ egwGridDataQueue.prototype._queue = function(_obj) else { // Specify that the element data is queued - for (var i = 0; i < this.queueColumns.length; i++) + if (_obj.type != EGW_DATA_QUEUE_CHILDREN) { - if (typeof _obj.elem.data[this.queueColumns[i]] == "undefined") + for (var i = 0; i < this.queueColumns.length; i++) { - _obj.elem.data[this.queueColumns[i]] = { - "queued": true + if (typeof _obj.elem.data[this.queueColumns[i]] == "undefined") + { + _obj.elem.data[this.queueColumns[i]] = { + "queued": true + } } } } @@ -757,15 +800,13 @@ egwGridDataQueue.prototype.queueCall = function(_elem, _columns, _callback, _con if (_columns === EGW_DATA_QUEUE_CHILDREN) { - if (!this._queue({ + this._queue({ "elem": _elem, "type": EGW_DATA_QUEUE_CHILDREN, "callback": _callback, "context": _context - })) - { - this.flushQueue(); - } + }); + console.log("Added ", _elem.id, " to queue: ", this.queue); } else { @@ -902,6 +943,8 @@ egwGridDataQueue.prototype.empty = function() */ egwGridDataQueue.prototype.flushQueue = function(_doPrefetch) { + console.log("Flush queue"); + var ids = []; if (_doPrefetch) diff --git a/phpgwapi/js/egw_action/egw_grid_view.js b/phpgwapi/js/egw_action/egw_grid_view.js index 2c32335fb8..890aa4f35e 100644 --- a/phpgwapi/js/egw_action/egw_grid_view.js +++ b/phpgwapi/js/egw_action/egw_grid_view.js @@ -1290,6 +1290,7 @@ function egwGridViewRow(_grid, _heightChangeProc, _item) container.getAOI = egwGridViewRow_getAOI; container._columnClick = egwGridViewRow__columnClick; container.setOpen = egwGridViewRow_setOpen; + container.reloadChildren = egwGridViewRow_reloadChildren; container.tdObjects = []; container.containerClass = "row"; container.childGrid = null; @@ -1426,9 +1427,10 @@ function egwGridViewRow_doUpdateData(_immediate) vis_idx++; var cont = this.tdObjects[i].cont; - cont.empty(); if (typeof data[col.id] != "undefined") { + cont.empty(); + if (col.type == EGW_COL_TYPE_NAME_ICON_FIXED) { // Insert the indentation spacer @@ -1521,6 +1523,7 @@ function egwGridViewRow_doUpdateData(_immediate) } else { + cont.empty(); cont.toggleClass("queued", true); } } @@ -1546,9 +1549,14 @@ function egwGridViewRow_doSetViewArea() } } -function egwGridViewRow_setOpen(_open) +function egwGridViewRow_setOpen(_open, _force) { - if (_open != this.opened) + if (typeof _force == "undefined") + { + _force = false; + } + + if (_open != this.opened || _force) { var inserted = false; @@ -1581,13 +1589,37 @@ function egwGridViewRow_setOpen(_open) if (this.childGrid && !inserted) { + if (!_open) + { + // Deselect all childrens + for (var i = 0; i < this.item.children.length; i++) + { + this.item.children[i].actionObject.setAllSelected(false); + } + } + this.childGrid.setVisible(_open); } this.opened = _open; this.item.opend = _open; } +} +function egwGridViewRow_reloadChildren() +{ + // Remove the child grid container + if (this.childGrid) + { + this.grid.removeContainer(this.childGrid); + this.childGrid = null; + + // Remove all the data from the data object + this.item.empty(); + + // Recreate the child grid + this.setOpen(this.opened, true); + } }