Add support for filemanager favorites in home

This commit is contained in:
Nathan Gray 2014-12-05 19:34:12 +00:00
parent 1869e94f84
commit d7956554de
4 changed files with 203 additions and 18 deletions

View 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']));
}
}
}

View File

@ -111,7 +111,7 @@ class filemanager_ui
*
* @return array
*/
private static function get_actions()
public static function get_actions()
{
$actions = array(
'open' => array(
@ -514,7 +514,7 @@ class filemanager_ui
* @param int &$files=null on return number of files deleted
* @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))
{

View File

@ -18,9 +18,9 @@ app.classes.filemanager = AppJS.extend(
{
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
*/
@ -35,6 +35,17 @@ app.classes.filemanager = AppJS.extend(
{
// call parent
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');
}
}
},
/**
@ -42,7 +53,7 @@ app.classes.filemanager = AppJS.extend(
*/
destroy: function()
{
delete this.et2;
delete this.et2;
// call parent
this._super.apply(this, arguments);
},
@ -54,12 +65,12 @@ app.classes.filemanager = AppJS.extend(
*
* @param et2 etemplate2 Newly ready object
*/
et2_ready: function(et2)
et2_ready: function(et2,name)
{
// call parent
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'))
{
@ -140,9 +151,13 @@ app.classes.filemanager = AppJS.extend(
*
* @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)
{
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)
{
var path = this.get_path();
var path = this.get_path(action.parent.data.nextmatch.getInstanceManager().uniqueId || false);
if(action)
{
var paths = this._elems2paths(selected);
@ -564,18 +580,20 @@ app.classes.filemanager = AppJS.extend(
*
* @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)
{
case '..':
_dir = this.dirname(this.path_widget.getValue());
_dir = this.dirname(this.get_path(etemplate_name));
break;
case '~':
_dir = this.et2.getWidgetById('nm').options.settings.home_dir;
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'
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
{
egw.open({path: path, type: data.data.mime}, 'file');
}
return false;
},
/**
@ -607,7 +626,7 @@ app.classes.filemanager = AppJS.extend(
*/
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', {
menuaction: 'filemanager.filemanager_ui.file',
@ -630,7 +649,7 @@ app.classes.filemanager = AppJS.extend(
// Target will be missing ID if directory is empty
// 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
if(_target)
@ -700,7 +719,7 @@ app.classes.filemanager = AppJS.extend(
this.readonly = [_path, _ro];
return;
}
var path = this.path_widget.getValue();
var path = this.get_path();
if (_path == path)
{

View 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>