mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-06-25 20:31:31 +02:00
Add support for filemanager favorites in home
This commit is contained in:
parent
1869e94f84
commit
d7956554de
112
filemanager/inc/class.filemanager_favorite_portlet.inc.php
Normal file
112
filemanager/inc/class.filemanager_favorite_portlet.inc.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Egroupware - Filemanager - A portlet for displaying a list of entries
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package filemanager
|
||||||
|
* @subpackage home
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Nathan Gray
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filemanager_list_portlet uses a nextmatch / favorite
|
||||||
|
* to display a list of entries.
|
||||||
|
*/
|
||||||
|
class filemanager_favorite_portlet extends home_favorite_portlet
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the portlet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct(Array &$context = array(), &$need_reload = false)
|
||||||
|
{
|
||||||
|
$context['appname'] = 'filemanager';
|
||||||
|
|
||||||
|
// Let parent handle the basic stuff
|
||||||
|
parent::__construct($context,$need_reload);
|
||||||
|
|
||||||
|
$ui = new filemanager_ui();
|
||||||
|
|
||||||
|
$this->context['template'] = 'filemanager.index.rows';
|
||||||
|
$this->nm_settings += array(
|
||||||
|
'get_rows' => 'filemanager.filemanager_ui.get_rows',
|
||||||
|
'csv_export' => true,
|
||||||
|
// Use a different template so it can be accessed from client side
|
||||||
|
'template' => 'filemanager.home.rows',
|
||||||
|
// Filemanager needs this header, it's an important component for actions, but we reduce it to the minimum
|
||||||
|
'header_left' => 'filemanager.home.header_left',
|
||||||
|
// Use a reduced column set for home, user can change if needed
|
||||||
|
'default_cols' => 'mime,name',
|
||||||
|
'no_cat' => true,
|
||||||
|
'no_filter2' => true,
|
||||||
|
'row_id' => 'path',
|
||||||
|
'row_modified' => 'mtime',
|
||||||
|
'parent_id' => 'dir',
|
||||||
|
'is_parent' => 'mime',
|
||||||
|
'is_parent_value'=> egw_vfs::DIR_MIME_TYPE,
|
||||||
|
'placeholder_actions' => array('mkdir','file_drop_mail','file_drop_move','file_drop_copy','file_drop_symlink')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exec($id = null, etemplate_new &$etemplate = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->context['sel_options']['filter'] = array(
|
||||||
|
'' => 'Current directory',
|
||||||
|
'2' => 'Directories sorted in',
|
||||||
|
'3' => 'Show hidden files',
|
||||||
|
'4' => 'All subdirectories',
|
||||||
|
'5' => 'Files from links',
|
||||||
|
'0' => 'Files from subdirectories',
|
||||||
|
);
|
||||||
|
$this->nm_settings['actions'] = filemanager_ui::get_actions();
|
||||||
|
|
||||||
|
$this->nm_settings['home_dir'] = filemanager_ui::get_home_dir();
|
||||||
|
parent::exec($id, $etemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override from filemanager to clear the app header
|
||||||
|
*
|
||||||
|
* @param type $query
|
||||||
|
* @param type $rows
|
||||||
|
* @param type $readonlys
|
||||||
|
* @return integer Total rows found
|
||||||
|
*/
|
||||||
|
public static function get_rows(&$query, &$rows, &$readonlys)
|
||||||
|
{
|
||||||
|
$ui = new filemanager_ui();
|
||||||
|
$total = $ui->get_rows($query, $rows, $readonlys);
|
||||||
|
unset($GLOBALS['egw_info']['flags']['app_header']);
|
||||||
|
return $total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here we need to handle any incoming data. Setup is done in the constructor,
|
||||||
|
* output is handled by parent.
|
||||||
|
*
|
||||||
|
* @param type $id
|
||||||
|
* @param etemplate_new $etemplate
|
||||||
|
*/
|
||||||
|
public static function process($content = array())
|
||||||
|
{
|
||||||
|
parent::process($content);
|
||||||
|
|
||||||
|
// This is just copy+pasted from filemanager_ui line 378, but we don't want
|
||||||
|
// the etemplate exec to fire again.
|
||||||
|
if ($content['nm']['action'])
|
||||||
|
{
|
||||||
|
$msg = filemanager_ui::action($content['nm']['action'],$content['nm']['selected'],$content['nm']['path']);
|
||||||
|
if($msg) egw_json_response::get()->apply('egw.message',array($msg));
|
||||||
|
foreach($content['nm']['selected'] as &$id)
|
||||||
|
{
|
||||||
|
$id = 'filemanager::'.$id;
|
||||||
|
}
|
||||||
|
// Directly request an update - this will get filemanager tab too
|
||||||
|
egw_json_response::get()->apply('egw.dataRefreshUIDs',array($content['nm']['selected']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -111,7 +111,7 @@ class filemanager_ui
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private static function get_actions()
|
public static function get_actions()
|
||||||
{
|
{
|
||||||
$actions = array(
|
$actions = array(
|
||||||
'open' => array(
|
'open' => array(
|
||||||
@ -514,7 +514,7 @@ class filemanager_ui
|
|||||||
* @param int &$files=null on return number of files deleted
|
* @param int &$files=null on return number of files deleted
|
||||||
* @return string success or failure message displayed to the user
|
* @return string success or failure message displayed to the user
|
||||||
*/
|
*/
|
||||||
static private function action($action,$selected,$dir=null,&$errs=null,&$files=null,&$dirs=null)
|
static public function action($action,$selected,$dir=null,&$errs=null,&$files=null,&$dirs=null)
|
||||||
{
|
{
|
||||||
if (!count($selected))
|
if (!count($selected))
|
||||||
{
|
{
|
||||||
|
@ -18,9 +18,9 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
{
|
{
|
||||||
appname: 'filemanager',
|
appname: 'filemanager',
|
||||||
/**
|
/**
|
||||||
* path widget
|
* path widget, by template
|
||||||
*/
|
*/
|
||||||
path_widget: null,
|
path_widget: {},
|
||||||
/**
|
/**
|
||||||
* Are files cut into clipboard - need to be deleted at source on paste
|
* Are files cut into clipboard - need to be deleted at source on paste
|
||||||
*/
|
*/
|
||||||
@ -35,6 +35,17 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
{
|
{
|
||||||
// call parent
|
// call parent
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
// Loading filemanager in its tab and home causes us problems with
|
||||||
|
// unwanted destruction, so we check for already existing path widgets
|
||||||
|
var lists = etemplate2.getByApplication('home');
|
||||||
|
for(var i = 0; i < lists.length; i++)
|
||||||
|
{
|
||||||
|
if(lists[i].app == 'filemanager' && lists[i].widgetContainer.getWidgetById('path'))
|
||||||
|
{
|
||||||
|
this.path_widget[lists[i].uniqueId] = lists[i].widgetContainer.getWidgetById('path');
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,12 +65,12 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
*
|
*
|
||||||
* @param et2 etemplate2 Newly ready object
|
* @param et2 etemplate2 Newly ready object
|
||||||
*/
|
*/
|
||||||
et2_ready: function(et2)
|
et2_ready: function(et2,name)
|
||||||
{
|
{
|
||||||
// call parent
|
// call parent
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
this.path_widget = this.et2.getWidgetById('path');
|
this.path_widget[et2.DOMContainer.id] = this.et2.getWidgetById('path') || null;
|
||||||
|
|
||||||
if(this.et2.getWidgetById('nm'))
|
if(this.et2.getWidgetById('nm'))
|
||||||
{
|
{
|
||||||
@ -140,9 +151,13 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
get_path: function()
|
get_path: function(etemplate_name)
|
||||||
{
|
{
|
||||||
return this.path_widget ? this.path_widget.get_value() : null;
|
if(!etemplate_name)
|
||||||
|
{
|
||||||
|
etemplate_name = 'filemanager-index';
|
||||||
|
}
|
||||||
|
return this.path_widget[etemplate_name] ? this.path_widget[etemplate_name].get_value() : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -433,7 +448,8 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
action: function(_action, _elems)
|
action: function(_action, _elems)
|
||||||
{
|
{
|
||||||
var paths = this._elems2paths(_elems);
|
var paths = this._elems2paths(_elems);
|
||||||
this._do_action(_action.id, paths);
|
var path = this.get_path(_action && _action.parent.data.nextmatch.getInstanceManager().uniqueId || false);
|
||||||
|
this._do_action(_action.id, paths,true, path);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -448,7 +464,7 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
|
|
||||||
if (dir)
|
if (dir)
|
||||||
{
|
{
|
||||||
var path = this.get_path();
|
var path = this.get_path(action.parent.data.nextmatch.getInstanceManager().uniqueId || false);
|
||||||
if(action)
|
if(action)
|
||||||
{
|
{
|
||||||
var paths = this._elems2paths(selected);
|
var paths = this._elems2paths(selected);
|
||||||
@ -564,18 +580,20 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
*
|
*
|
||||||
* @param _dir directory to change to incl. '..' for one up
|
* @param _dir directory to change to incl. '..' for one up
|
||||||
*/
|
*/
|
||||||
change_dir: function(_dir)
|
change_dir: function(_dir, widget)
|
||||||
{
|
{
|
||||||
|
var etemplate_name = widget && widget.getInstanceManager().uniqueId || 'filemanager-index';
|
||||||
switch (_dir)
|
switch (_dir)
|
||||||
{
|
{
|
||||||
case '..':
|
case '..':
|
||||||
_dir = this.dirname(this.path_widget.getValue());
|
_dir = this.dirname(this.get_path(etemplate_name));
|
||||||
break;
|
break;
|
||||||
case '~':
|
case '~':
|
||||||
_dir = this.et2.getWidgetById('nm').options.settings.home_dir;
|
_dir = this.et2.getWidgetById('nm').options.settings.home_dir;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.path_widget.set_value(_dir);
|
|
||||||
|
this.path_widget[etemplate_name].set_value(_dir);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -591,12 +609,13 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
// symlinks dont have mime 'http/unix-directory', but server marks all directories with class 'isDir'
|
// symlinks dont have mime 'http/unix-directory', but server marks all directories with class 'isDir'
|
||||||
if (data.data.mime == 'httpd/unix-directory' || data.data['class'] && data.data['class'].split(/ +/).indexOf('isDir') != -1)
|
if (data.data.mime == 'httpd/unix-directory' || data.data['class'] && data.data['class'].split(/ +/).indexOf('isDir') != -1)
|
||||||
{
|
{
|
||||||
this.change_dir(path);
|
this.change_dir(path,_action.parent.data.nextmatch || this.et2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
egw.open({path: path, type: data.data.mime}, 'file');
|
egw.open({path: path, type: data.data.mime}, 'file');
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -607,7 +626,7 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
*/
|
*/
|
||||||
editprefs: function(_action, _senders)
|
editprefs: function(_action, _senders)
|
||||||
{
|
{
|
||||||
var path = typeof _senders != 'undefined' ? this.id2path(_senders[0].id) : this.path_widget.getValue();
|
var path = typeof _senders != 'undefined' ? this.id2path(_senders[0].id) : this.get_path(_action && _action.parent.data.nextmatch.getInstanceManager().uniqueId || false);
|
||||||
|
|
||||||
egw().open_link(egw.link('/index.php', {
|
egw().open_link(egw.link('/index.php', {
|
||||||
menuaction: 'filemanager.filemanager_ui.file',
|
menuaction: 'filemanager.filemanager_ui.file',
|
||||||
@ -630,7 +649,7 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
|
|
||||||
// Target will be missing ID if directory is empty
|
// Target will be missing ID if directory is empty
|
||||||
// so start with the current directory
|
// so start with the current directory
|
||||||
var dst = this.get_path();
|
var dst = this.get_path(_action.parent.data.nextmatch.getInstanceManager().uniqueId || false);
|
||||||
|
|
||||||
// File(s) were dropped on a row, they want them inside
|
// File(s) were dropped on a row, they want them inside
|
||||||
if(_target)
|
if(_target)
|
||||||
@ -700,7 +719,7 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
this.readonly = [_path, _ro];
|
this.readonly = [_path, _ro];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var path = this.path_widget.getValue();
|
var path = this.get_path();
|
||||||
|
|
||||||
if (_path == path)
|
if (_path == path)
|
||||||
{
|
{
|
||||||
|
54
filemanager/templates/default/home.rows.xet
Normal file
54
filemanager/templates/default/home.rows.xet
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- $Id$ -->
|
||||||
|
<!-- This template is in a seperate file so etemplate can find it for home -->
|
||||||
|
<overlay>
|
||||||
|
<template id="filemanager.home.header_left" template="" lang="" group="0" version="1.9.002">
|
||||||
|
<hbox span="all" class="filemanager_navigation">
|
||||||
|
<image label="Up" src="goup" onclick="app.filemanager.change_dir('..',widget);" id="up"/>
|
||||||
|
<image label="Go to your home directory" src="gohome" onclick="app.filemanager.change_dir('~',widget);" id="home"/>
|
||||||
|
<vfs-name label="Path" id="path" onchange="if(widget.getValue() == '') { app.filemanager.change_dir('~',widget);} return true;" size="80" class="address"/>
|
||||||
|
</hbox>
|
||||||
|
</template>
|
||||||
|
<template id="filemanager.home.rows" template="" lang="" group="0" version="1.9.001">
|
||||||
|
<grid width="100%">
|
||||||
|
<columns>
|
||||||
|
<column width="50"/>
|
||||||
|
<column width="50%"/>
|
||||||
|
<column width="80"/>
|
||||||
|
<column width="120"/>
|
||||||
|
<column width="120"/>
|
||||||
|
<column width="80"/>
|
||||||
|
<column width="80"/>
|
||||||
|
<column width="80"/>
|
||||||
|
<column width="30%"/>
|
||||||
|
<column width="20%"/>
|
||||||
|
</columns>
|
||||||
|
<rows>
|
||||||
|
<row class="th">
|
||||||
|
<nextmatch-sortheader align="center" label="Type" id="mime"/>
|
||||||
|
<nextmatch-sortheader label="Name" id="name"/>
|
||||||
|
<nextmatch-sortheader label="Size" id="size"/>
|
||||||
|
<nextmatch-sortheader label="Modified" id="mtime"/>
|
||||||
|
<nextmatch-sortheader label="Created" id="ctime"/>
|
||||||
|
<nextmatch-sortheader label="Permissions" id="mode"/>
|
||||||
|
<nextmatch-sortheader label="Owner" id="uid"/>
|
||||||
|
<nextmatch-sortheader label="Group" id="gid"/>
|
||||||
|
<nextmatch-header label="Comment" id="comment"/>
|
||||||
|
<nextmatch-customfields id="customfields" readonly="true"/>
|
||||||
|
</row>
|
||||||
|
<row class="row $row_cont[class]">
|
||||||
|
<vfs-mime align="center" id="$row"/>
|
||||||
|
<vfs-name id="${row}[name]" no_lang="1" readonly="true"/>
|
||||||
|
<vfs-size align="right" id="${row}[size]"/>
|
||||||
|
<date-time id="${row}[mtime]" readonly="true"/>
|
||||||
|
<date-time id="${row}[ctime]" readonly="true"/>
|
||||||
|
<vfs-mode id="${row}[mode]"/>
|
||||||
|
<vfs-uid id="${row}[uid]" no_lang="1"/>
|
||||||
|
<vfs-gid id="${row}[gid]" no_lang="1"/>
|
||||||
|
<description id="${row}[comment]"/>
|
||||||
|
<customfields-list id="$row" class="customfields"/>
|
||||||
|
</row>
|
||||||
|
</rows>
|
||||||
|
</grid>
|
||||||
|
</template>
|
||||||
|
</overlay>
|
Loading…
x
Reference in New Issue
Block a user