mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-23 07:09:20 +01:00
Fixed bugs in the grid view js code (changes in the test_grid_view.html are for debugging purposes only), added class.egw_vfs_utils.inc.php which will contain high-level vfs functionality which was previously hidden inside etemplate and the filemanager, such as generating the thumbnail url for a file.
This commit is contained in:
parent
01fe133e60
commit
943f369cce
74
phpgwapi/inc/class.egw_vfs_utils.inc.php
Normal file
74
phpgwapi/inc/class.egw_vfs_utils.inc.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* eGroupWare API: VFS - static methods to use the new eGW virtual file system
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package api
|
||||
* @subpackage vfs
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @author Andreas Stöckel <as@stylite.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
class egw_vfs_utils
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the URL to the thumbnail of the given file. The thumbnail may simply
|
||||
* be the mime-type icon, or - if activated - the preview with the given thsize.
|
||||
*
|
||||
* @param string $file name of the file
|
||||
* @param int $thsize the size of the preview - false if the default should be used.
|
||||
* @param string $mime if you already know the mime type of the file, you can supply
|
||||
* it here. Otherwise supply "false".
|
||||
*/
|
||||
public static function thumbnail_url($file, $thsize = false, $mime = false)
|
||||
{
|
||||
// Retrive the mime-type of the file
|
||||
if (!$mime)
|
||||
{
|
||||
$mime = egw_vfs::mime_content_type($file);
|
||||
}
|
||||
|
||||
$image = "";
|
||||
|
||||
// Seperate the mime type into the primary and the secondary part
|
||||
list($mime_main, $mime_sub) = explode('/', $mime);
|
||||
|
||||
if ($mime_main == 'egw')
|
||||
{
|
||||
$image = $mime_sub.'/navbar'; // egw-applications for link-widget
|
||||
}
|
||||
else if ($file && $mime_main == 'image' && in_array($mime_sub, array('png','jpeg','jpg','gif','bmp')) &&
|
||||
(string)$GLOBALS['egw_info']['server']['link_list_thumbnail'] != '0' &&
|
||||
(string)$GLOBALS['egw_info']['user']['preferences']['common']['link_list_thumbnail'] != '0' &&
|
||||
(!is_array($value) && ($stat = egw_vfs::stat($file)) ? $stat['size'] : $value['size']) < 4000000)
|
||||
{
|
||||
if (substr($file, 0, 6) == '/apps/')
|
||||
{
|
||||
$file = parse_url(egw_vfs::resolve_url_symlinks($path), PHP_URL_PATH);
|
||||
}
|
||||
|
||||
//Assemble the thumbnail parameters
|
||||
$thparams = array();
|
||||
$thparams['path'] = $file;
|
||||
if ($thsize)
|
||||
{
|
||||
$thparams['thsize'] = $thsize;
|
||||
}
|
||||
$image = $GLOBALS['egw']->link('/etemplate/thumbnail.php', $thparams);
|
||||
}
|
||||
else
|
||||
{
|
||||
list($app, $name) = explode("/", egw_vfs::mime_icon($mime), 2);
|
||||
$image = $GLOBALS['egw']->common->image($app, $name);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -499,19 +499,16 @@ egwGridDataElement.prototype.callGridViewObjectUpdate = function(_immediate)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute index of this element
|
||||
*/
|
||||
egwGridDataElement.prototype.getTotalIndex = function()
|
||||
egwGridDataElement.prototype.getDeepestOpened = function()
|
||||
{
|
||||
var idx = this.index;
|
||||
|
||||
if (this.parent && this.parent.opened)
|
||||
if (this.opened && this.children.length > 0)
|
||||
{
|
||||
idx += this.parent.getTotalIndex();
|
||||
return this.children[this.children.length - 1].getDeepestOpened();
|
||||
}
|
||||
else
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -519,7 +516,7 @@ egwGridDataElement.prototype.getTotalIndex = function()
|
||||
*/
|
||||
egwGridDataElement.prototype.isOdd = function()
|
||||
{
|
||||
return (this.getTotalIndex() % 2) == 0;
|
||||
return (this.index % 2) == 0; // Improve - old exact version needed way too much performance
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,8 +9,6 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
//TODO: Spacer itemHeight should automatically be set to the average item height in the
|
||||
// grid to solve the "stutters" when scrolling up.
|
||||
//TODO (minor): Do auto cleanup - remove elements from the view again after they
|
||||
// haven't been viewed for a certain time.
|
||||
|
||||
@ -336,11 +334,10 @@ egwGridViewContainer.prototype.setVisible = function(_visible, _force)
|
||||
{
|
||||
$(this.parentNode).toggleClass("hidden", !_visible);
|
||||
|
||||
// While the element has been invisible, the viewarea might have changed,
|
||||
// so check it now
|
||||
if (this.visible)
|
||||
if (_visible)
|
||||
{
|
||||
this.checkViewArea();
|
||||
this.assumedHeight = 0;
|
||||
this.height = false;
|
||||
}
|
||||
|
||||
// As the element is now (in)visible, its height has changed. Inform the
|
||||
@ -400,6 +397,11 @@ egwGridViewContainer.prototype.setViewArea = function(_area, _force)
|
||||
|
||||
this.viewArea = relArea;
|
||||
|
||||
if (this.containerClass == "grid" && this.grid != null)
|
||||
{
|
||||
// console.log(this, _area, this.viewArea);
|
||||
}
|
||||
|
||||
this.checkViewArea(_force);
|
||||
}
|
||||
|
||||
@ -549,9 +551,12 @@ function egwGridViewGrid(_grid, _heightChangeProc, _scrollable, _outer)
|
||||
container.beginUpdate = egwGridViewGrid_beginUpdate;
|
||||
container.endUpdate = egwGridViewGrid_endUpdate;
|
||||
container.triggerUpdateAssumedHeights = egwGridViewGrid_triggerUpdateAssumedHeights;
|
||||
container.addIconHeightToAvg = egwGridViewGrid_addIconHeightToAvg;
|
||||
container.children = [];
|
||||
container.outer = _outer;
|
||||
container.containerClass = "grid";
|
||||
container.avgIconHeight = 16;
|
||||
container.avgIconCnt = 1;
|
||||
|
||||
// Overwrite the abstract container interface functions
|
||||
container.invalidateHeightCache = egwGridViewGrid_invalidateHeightCache;
|
||||
@ -582,13 +587,14 @@ function egwGridViewGrid_triggerUpdateAssumedHeights()
|
||||
var self = this;
|
||||
var id = this.triggerID;
|
||||
window.setTimeout(function() {
|
||||
if (id = self.triggerID)
|
||||
{
|
||||
self.triggerID = 0;
|
||||
self.updateAssumedHeights(20);
|
||||
}
|
||||
},
|
||||
EGW_GRID_UPDATE_HEIGHTS_TIMEOUT);
|
||||
if (id == self.triggerID)
|
||||
{
|
||||
self.triggerID = 0;
|
||||
self.updateAssumedHeights(20);
|
||||
}
|
||||
},
|
||||
EGW_GRID_UPDATE_HEIGHTS_TIMEOUT
|
||||
);
|
||||
}
|
||||
|
||||
function egwGridViewGrid_endUpdate(_recPrev)
|
||||
@ -617,10 +623,10 @@ function egwGridViewGrid_endUpdate(_recPrev)
|
||||
{
|
||||
this.triggerUpdateAssumedHeights();
|
||||
}
|
||||
|
||||
this.didUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.didUpdate = false;
|
||||
}
|
||||
|
||||
function egwGridViewGrid_getOuter()
|
||||
@ -756,6 +762,12 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
||||
|
||||
// Offset the position of all following elements by the delta.
|
||||
var delta = newHeight - oldHeight;
|
||||
|
||||
if (this.grid != null)
|
||||
{
|
||||
// console.log(child, delta, newHeight, oldHeight);
|
||||
}
|
||||
|
||||
if (Math.abs(delta) > 0.001)
|
||||
{
|
||||
for (var j = this.updateIndex + 1; j < this.children.length; j++)
|
||||
@ -779,8 +791,6 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
||||
this.endUpdate(true);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
// If the maximum-update-count has been exhausted, retrigger this function
|
||||
@ -790,6 +800,7 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
||||
{
|
||||
// Otherwise, all elements have been checked - we'll now call "setViewArea"
|
||||
// which may check whether new objects are now in the currently visible range
|
||||
var self = this;
|
||||
window.setTimeout(function() {
|
||||
self.setViewArea(self.viewArea);
|
||||
}, EGW_GRID_UPDATE_HEIGHTS_TIMEOUT);
|
||||
@ -919,8 +930,8 @@ function egwGridViewGrid_invalidateHeightCache(_children)
|
||||
_children = true;
|
||||
}
|
||||
|
||||
this.height = false;
|
||||
this.assumedHeight = false;
|
||||
// Call the inherited function
|
||||
egwGridViewContainer.prototype.invalidateHeightCache.call(this);
|
||||
|
||||
if (_children)
|
||||
{
|
||||
@ -951,6 +962,11 @@ function egwGridViewGrid_heightChangeHandler(_elem)
|
||||
{
|
||||
this.didUpdate = true;
|
||||
|
||||
if (this.grid != null)
|
||||
{
|
||||
// console.log("HCH for", _elem);
|
||||
}
|
||||
|
||||
// The old height of the element is now only an assumed height - the next
|
||||
// time the "updateAssumedHeights" functions is triggered, this will be
|
||||
// updated.
|
||||
@ -959,7 +975,7 @@ function egwGridViewGrid_heightChangeHandler(_elem)
|
||||
_elem.invalidateHeightCache(false);
|
||||
_elem.assumedHeight = oldHeight;
|
||||
|
||||
if (_elem.containerClass == "grid" && !this.inUpdate)
|
||||
if ((_elem.containerClass == "grid" || _elem.containerClass == "spacer") && !this.inUpdate)
|
||||
{
|
||||
this.triggerUpdateAssumedHeights();
|
||||
}
|
||||
@ -1065,6 +1081,14 @@ function egwGridViewGrid_doSetviewArea(_area, _recPrev)
|
||||
}
|
||||
}
|
||||
|
||||
function egwGridViewGrid_addIconHeightToAvg(_value)
|
||||
{
|
||||
this.avgIconCnt++;
|
||||
|
||||
var frac = 1.0 / this.avgIconCnt;
|
||||
this.avgIconHeight = this.avgIconHeight * (1 - frac) + _value * frac;
|
||||
}
|
||||
|
||||
/** -- egwGridViewRow Class -- **/
|
||||
|
||||
function egwGridViewRow(_grid, _heightChangeProc, _item)
|
||||
@ -1259,9 +1283,19 @@ function egwGridViewRow_doUpdateData(_immediate)
|
||||
{
|
||||
// Build the icon element
|
||||
var icon = $(document.createElement("img"));
|
||||
|
||||
// Default the image height to the average height - this attribute
|
||||
// is removed from the row as soon as the icon is loaded
|
||||
icon.attr("height", Math.round(this.grid.avgIconHeight));
|
||||
icon.attr("src", data[col.id].iconUrl);
|
||||
icon.load(this, function(e) {
|
||||
e.data.callHeightChangeProc();
|
||||
|
||||
icon.load({"item": this, "col": td}, function(e) {
|
||||
var icon = $(this);
|
||||
icon.removeAttr("height");
|
||||
window.setTimeout(function() {
|
||||
e.data.item.grid.addIconHeightToAvg(icon.height());
|
||||
}, 100);
|
||||
e.data.item.callHeightChangeProc();
|
||||
});
|
||||
icon.addClass("icon");
|
||||
td.append(icon);
|
||||
@ -1322,6 +1356,8 @@ function egwGridViewRow_setOpen(_open)
|
||||
{
|
||||
if (_open != this.opened)
|
||||
{
|
||||
var inserted = false;
|
||||
|
||||
if (_open)
|
||||
{
|
||||
if (!this.childGrid)
|
||||
@ -1332,8 +1368,10 @@ function egwGridViewRow_setOpen(_open)
|
||||
arrow.addClass("loading");
|
||||
|
||||
// Create the "child grid"
|
||||
this.childGrid = this.grid.insertContainer(this.index, egwGridViewGrid,
|
||||
var childGrid = null;
|
||||
this.childGrid = childGrid = this.grid.insertContainer(this.index, egwGridViewGrid,
|
||||
false);
|
||||
inserted = true;
|
||||
this.childGrid.setVisible(false);
|
||||
var spacer = this.childGrid.insertContainer(-1, egwGridViewSpacer,
|
||||
this.grid.getOuter().avgRowHeight);
|
||||
@ -1342,11 +1380,12 @@ function egwGridViewRow_setOpen(_open)
|
||||
arrow.removeClass("closed");
|
||||
arrow.addClass("opened");
|
||||
spacer.setItemList(_children);
|
||||
childGrid.setVisible(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.childGrid)
|
||||
if (this.childGrid && !inserted)
|
||||
{
|
||||
this.childGrid.setVisible(_open);
|
||||
}
|
||||
@ -1354,6 +1393,7 @@ function egwGridViewRow_setOpen(_open)
|
||||
this.opened = _open;
|
||||
this.item.opend = _open;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1373,6 +1413,7 @@ function egwGridViewSpacer(_grid, _heightChangeProc, _itemHeight)
|
||||
container.domNode = null;
|
||||
container.items = [];
|
||||
container.setItemList = egwGridViewSpacer_setItemList;
|
||||
container.containerClass = "spacer";
|
||||
|
||||
// Overwrite the inherited functions
|
||||
container.doInsertIntoDOM = egwGridViewSpacer_doInsertIntoDOM;
|
||||
@ -1437,13 +1478,17 @@ function egwGridViewSpacer_doSetViewArea()
|
||||
// created elements.
|
||||
if (it_top.length > 0)
|
||||
{
|
||||
var spacer = this.grid.insertContainer(idx - 1, egwGridViewSpacer, avgHeight);
|
||||
spacer.setItemList(it_top)
|
||||
// this.itemHeight has to be passed to the new top spacer - otherwise the
|
||||
// scroll position might change and we'll go into a nasty setViewArea
|
||||
// loop.
|
||||
var spacer = this.grid.insertContainer(idx - 1, egwGridViewSpacer, this.itemHeight);
|
||||
spacer.setItemList(it_top);
|
||||
}
|
||||
|
||||
// If there are items left at the bottom of the spacer, set theese as items of this spacer
|
||||
if (it_bot.length > 0)
|
||||
{
|
||||
// The height of this (the bottom) spacer can be set to the average height
|
||||
this.itemHeight = avgHeight;
|
||||
this.setItemList(it_bot);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
{
|
||||
"id": "name",
|
||||
"caption": "Name",
|
||||
"width": "20%",
|
||||
"width": "75%",
|
||||
"type": EGW_COL_TYPE_NAME_ICON_FIXED
|
||||
},
|
||||
{
|
||||
@ -39,36 +39,43 @@
|
||||
},
|
||||
{
|
||||
"id": "rights",
|
||||
"caption": "UNIX Filerights"
|
||||
"caption": "UNIX Filerights",
|
||||
"visibility": EGW_COL_VISIBILITY_INVISIBLE
|
||||
},
|
||||
{
|
||||
"id": "mime",
|
||||
"caption": "File-Type/MIME"
|
||||
"caption": "File-Type/MIME",
|
||||
"visibility": EGW_COL_VISIBILITY_INVISIBLE
|
||||
},
|
||||
{
|
||||
"id": "atime",
|
||||
"caption": "atime",
|
||||
"width": "15%"
|
||||
"width": "15%",
|
||||
"visibility": EGW_COL_VISIBILITY_INVISIBLE
|
||||
},
|
||||
{
|
||||
"id": "ctime",
|
||||
"caption": "ctime",
|
||||
"width": "15%"
|
||||
"width": "15%",
|
||||
"visibility": EGW_COL_VISIBILITY_INVISIBLE
|
||||
},
|
||||
{
|
||||
"id": "mtime",
|
||||
"caption": "mtime",
|
||||
"width": "15%"
|
||||
"width": "15%",
|
||||
"visibility": EGW_COL_VISIBILITY_INVISIBLE
|
||||
},
|
||||
{
|
||||
"id": "owner",
|
||||
"caption": "owner",
|
||||
"width": "10%"
|
||||
"width": "10%",
|
||||
"visibility": EGW_COL_VISIBILITY_INVISIBLE
|
||||
},
|
||||
{
|
||||
"id": "group",
|
||||
"caption": "group",
|
||||
"width": "10%"
|
||||
"width": "10%",
|
||||
"visibility": EGW_COL_VISIBILITY_INVISIBLE
|
||||
}
|
||||
];
|
||||
|
||||
@ -136,23 +143,46 @@
|
||||
"entryType": EGW_DATA_TYPE_RANGE,
|
||||
"prefix": "root_elem_",
|
||||
"canHaveChildren": true,
|
||||
"count": 10000
|
||||
"count": 1000
|
||||
}
|
||||
]
|
||||
);
|
||||
grid.resize(1500, 500);
|
||||
});
|
||||
|
||||
function check_positions()
|
||||
function check_positions(_grid, _delta)
|
||||
{
|
||||
var g = grid.gridOuter.grid;
|
||||
var delta = - g.scrollarea.offset().top;
|
||||
var outer = grid.gridOuter.grid;
|
||||
|
||||
if (typeof _grid == "undefined")
|
||||
{
|
||||
_grid = outer;
|
||||
}
|
||||
|
||||
if (typeof _delta == "undefined")
|
||||
{
|
||||
_delta = 0;
|
||||
}
|
||||
|
||||
|
||||
var g = _grid;
|
||||
var delta = outer.scrollarea.scrollTop() - outer.scrollarea.offset().top;
|
||||
for (var i = 0; i < g.children.length; i++)
|
||||
{
|
||||
var rtop = g.children[i].parentNode.offset().top + g.scrollarea.scrollTop() - g.scrollarea.offset().top;
|
||||
var itop = g.children[i].position;
|
||||
var rtop = g.children[i].parentNode.offset().top + delta;
|
||||
var itop = g.children[i].position + _delta;
|
||||
|
||||
console.log(Math.round(itop - rtop));
|
||||
var rheight = g.children[i].parentNode.outerHeight();
|
||||
var iheight = g.children[i].getHeight();
|
||||
|
||||
console.log(Math.round(itop - rtop), Math.round(iheight - rheight), g.children[i].visible);
|
||||
|
||||
if (g.children[i].containerClass == "grid" && g.children[i].visible)
|
||||
{
|
||||
console.log("-->");
|
||||
check_positions(g.children[i], itop);
|
||||
console.log("<--");
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
4978
phpgwapi/js/jquery/jquery.js
vendored
4978
phpgwapi/js/jquery/jquery.js
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user