Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c170c44168
|
@ -56,7 +56,7 @@ class addressbook_wizard_import_contacts_csv extends importexport_wizard_basic_i
|
|||
unset($this->mapping_fields['jpegphoto']); // can't cvs import that
|
||||
|
||||
// Add in special handled fields
|
||||
$this->mapping_fields[lang('Special')] = addressbook_import_contacts_csv::$special_fields;
|
||||
$this->mapping_fields += addressbook_import_contacts_csv::$special_fields;
|
||||
|
||||
// Actions
|
||||
$this->actions = array(
|
||||
|
|
|
@ -2336,8 +2336,9 @@ class CalDAV extends HTTP_WebDAV_Server
|
|||
$this->store_request = $_SERVER['REQUEST_METHOD'] != 'POST' ||
|
||||
!self::isFileUpload() ||
|
||||
substr($_SERVER['CONTENT_TYPE'], 0, 5) == 'text/';
|
||||
ob_start();
|
||||
}
|
||||
// unconditionally start output-buffering to fix problems with huge multiget reports from TB110 AB
|
||||
ob_start();
|
||||
parent::ServeRequest($prefix);
|
||||
|
||||
if (self::$request_starttime) self::log_request();
|
||||
|
|
|
@ -78,13 +78,13 @@ class Contact extends Entry
|
|||
'__default__' => array(
|
||||
'options' => array(
|
||||
'bday' => array('type' => 'date', 'options' => 'Y-m-d'),
|
||||
'owner' => array('type' => 'select-account', 'options' => ''),
|
||||
'modifier' => array('type' => 'select-account', 'options' => ''),
|
||||
'creator' => array('type' => 'select-account', 'options' => ''),
|
||||
'modifed' => array('type' => 'date-time', 'options' => ''),
|
||||
'created' => array('type' => 'date-time', 'options' => ''),
|
||||
'cat_id' => array('type' => 'select-cat', 'options' => ''),
|
||||
'__default__' => array('type' => 'label', 'options' => ''),
|
||||
'owner' => array('type' => 'select-account'),
|
||||
'modifier' => array('type' => 'select-account'),
|
||||
'creator' => array('type' => 'select-account'),
|
||||
'modifed' => array('type' => 'date-time'),
|
||||
'created' => array('type' => 'date-time'),
|
||||
'cat_id' => array('type' => 'select-cat'),
|
||||
'__default__' => array('type' => 'label'),
|
||||
),
|
||||
'noLang' => true,
|
||||
),
|
||||
|
|
|
@ -69,7 +69,7 @@ abstract class Entry extends Transformer
|
|||
|
||||
$form_name = self::form_name($cname, $this->id);
|
||||
$prefixed_id = (substr($this->id, 0, 1) == self::ID_PREFIX ? $this->id : self::ID_PREFIX . $this->id);
|
||||
$data_id = $attrs['value'] ? self::form_name($cname, $attrs['value']) : self::form_name($cname, $prefixed_id);
|
||||
$data_id = !empty($attrs['value']) ? self::form_name($cname, $attrs['value']) : self::form_name($cname, $prefixed_id);
|
||||
|
||||
// No need to proceed
|
||||
if(!$data_id) return;
|
||||
|
@ -151,9 +151,9 @@ abstract class Entry extends Transformer
|
|||
$value =& $data;
|
||||
if(!is_array($value)) return $value;
|
||||
|
||||
foreach(array($attrs['field']) + explode(':',$attrs['alternate_fields']) as $field)
|
||||
foreach(array($attrs['field']) + explode(':', ($attrs['alternate_fields'] ?? '')) as $field)
|
||||
{
|
||||
if($value[$field])
|
||||
if(!empty($value[$field]))
|
||||
{
|
||||
return $value[$field];
|
||||
}
|
||||
|
@ -175,12 +175,12 @@ abstract class Entry extends Transformer
|
|||
*/
|
||||
protected function customfield($attrs, &$data)
|
||||
{
|
||||
list($app, $type) = explode('-',$attrs['type']);
|
||||
$data_id = $attrs['value'] ?: $attrs['id'];
|
||||
list($app, $type) = explode('-', $attrs['type']);
|
||||
$data_id = isset($attrs['value']) ? $attrs['value'] : $attrs['id'];
|
||||
$id = is_array($data) ? static::get_array($data, $data_id) : $data;
|
||||
if(!$app || !$type || !$GLOBALS['egw_info']['apps'][$app] || !$id ||
|
||||
if(!$app || !$type || !isset($GLOBALS['egw_info']['apps'][$app]) || !$id ||
|
||||
// Simple CF, already there
|
||||
$data[$attrs['field']]
|
||||
isset($data[$attrs['field']])
|
||||
)
|
||||
{
|
||||
return;
|
||||
|
@ -194,7 +194,7 @@ abstract class Entry extends Transformer
|
|||
$merge = new $classname();
|
||||
$replacement_field = '$$'.$attrs['field'].'$$';
|
||||
$replacements = $merge->get_app_replacements($app, $id, $replacement_field);
|
||||
$data[$attrs['field']] = $replacements[$replacement_field];
|
||||
$data[$attrs['field']] = $replacements[$replacement_field] ?? '';
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ abstract class Entry extends Transformer
|
|||
protected function regex($attrs, &$data)
|
||||
{
|
||||
$value =& $this->get_data_field($attrs, $data);
|
||||
if(!$attrs['regex'] || !$value)
|
||||
if(!isset($attrs['regex']) || !$value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -219,15 +219,18 @@ abstract class Transformer extends Etemplate\Widget
|
|||
elseif(is_array($action))
|
||||
{
|
||||
// case matches --> run all actions
|
||||
if (isset($action[$attrs[$attr]]) || !isset($action[$attrs[$attr]]) && isset($action['__default__']))
|
||||
if(isset($attrs[$attr]) && isset($action[$attrs[$attr]]) || (!isset($attrs[$attr]) || !isset($action[$attrs[$attr]])) && isset($action['__default__']))
|
||||
{
|
||||
$actions = isset($action[$attrs[$attr]]) ? $action[$attrs[$attr]] : $action['__default__'];
|
||||
$actions = isset($attrs[$attr]) && isset($action[$attrs[$attr]]) ? $action[$attrs[$attr]] : $action['__default__'];
|
||||
if(!is_array($actions))
|
||||
{
|
||||
$attrs[$attr] = $actions;
|
||||
$actions = array($attr => $actions);
|
||||
}
|
||||
if (self::DEBUG) error_log(__METHOD__."(attr='$attr', action=".array2string($action).") attrs['$attr']=='{$attrs[$attr]}' --> running actions");
|
||||
if(self::DEBUG)
|
||||
{
|
||||
error_log(__METHOD__ . "(attr='$attr', action=" . array2string($action) . ") attrs['$attr']=='{$attrs[$attr]}' --> running actions");
|
||||
}
|
||||
foreach($actions as $attr => $action)
|
||||
{
|
||||
$this->action($attr, $action, $attrs);
|
||||
|
|
|
@ -331,6 +331,7 @@ class IncludeMgr
|
|||
// we will do no further processing but just include the file
|
||||
// XXX: Is this case still used? If yes, it will not work with
|
||||
// adding the ctime to all js files...
|
||||
$args = '';
|
||||
if (is_array($file))
|
||||
{
|
||||
foreach($file as $name => $val)
|
||||
|
|
|
@ -60,10 +60,10 @@ class Http
|
|||
static function schema()
|
||||
{
|
||||
return !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ||
|
||||
$_SERVER['SERVER_PORT'] == 443 ||
|
||||
!empty($GLOBALS['egw_info']['server']['enforce_ssl']) ||
|
||||
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ?
|
||||
'https' : 'http';
|
||||
$_SERVER['SERVER_PORT'] == 443 ||
|
||||
!empty($GLOBALS['egw_info']['server']['enforce_ssl']) ||
|
||||
isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ?
|
||||
'https' : 'http';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1683,13 +1683,14 @@ abstract class Merge
|
|||
{
|
||||
if(str_starts_with($cf_sub, '#'))
|
||||
{
|
||||
$expand_sub_cfs[$cf[$index]] .= '$$' . $cf_sub . '$$ ';
|
||||
$expand_sub_cfs[$cf[$index]] = (isset($expand_sub_cfs[$cf[$index]]) ? $expand_sub_cfs[$cf[$index]] : '') .
|
||||
'$$' . $cf_sub . '$$ ';
|
||||
}
|
||||
}
|
||||
|
||||
foreach($cf as $index => $field)
|
||||
{
|
||||
if($cfs[$field])
|
||||
if(isset($cfs[$field]))
|
||||
{
|
||||
if(in_array($cfs[$field]['type'], array_keys($GLOBALS['egw_info']['apps'])))
|
||||
{
|
||||
|
@ -1719,18 +1720,18 @@ abstract class Merge
|
|||
}
|
||||
|
||||
// Get replacements for that application
|
||||
if(!$app_replacements[$field])
|
||||
if(!isset($app_replacements[$field]))
|
||||
{
|
||||
// If we send the real content it can result in infinite loop of lookups
|
||||
// so we send only the used fields
|
||||
$content = $expand_sub_cfs[$field] ?? $matches[0][$index];
|
||||
$app_replacements[$field] = $this->get_app_replacements($field_app, $values['#' . $field], $content);
|
||||
}
|
||||
$replacements[$placeholders[$index]] = $app_replacements[$field]['$$' . $sub[$index] . '$$'];
|
||||
$replacements[$placeholders[$index]] = $app_replacements[$field]['$$' . $sub[$index] . '$$'] ?? '';
|
||||
}
|
||||
else
|
||||
{
|
||||
if($cfs[$field]['type'] == 'date' || $cfs[$field]['type'] == 'date-time')
|
||||
if(isset($cfs[$field]) && ($cfs[$field]['type'] == 'date' || $cfs[$field]['type'] == 'date-time'))
|
||||
{
|
||||
$this->date_fields[] = '#' . $field;
|
||||
}
|
||||
|
|
|
@ -1450,6 +1450,19 @@ div.et2_vfsPath li img {
|
|||
visibility: visible;
|
||||
}
|
||||
|
||||
/* Category indents in select options */
|
||||
sl-menu-item.cat_level1::part(label) {
|
||||
padding-left: var(--sl-spacing-medium, 1em);
|
||||
}
|
||||
|
||||
sl-menu-item.cat_level2::part(label) {
|
||||
padding-left: calc(2 * var(--sl-spacing-medium, 1em));
|
||||
}
|
||||
|
||||
sl-menu-item.cat_level3::part(label) {
|
||||
padding-left: calc(3 * var(--sl-spacing-medium, 1em));
|
||||
}
|
||||
|
||||
.egw_tooltip {
|
||||
position: fixed;
|
||||
border: 1px solid #897f51;
|
||||
|
|
|
@ -134,7 +134,7 @@ class calendar_holidays
|
|||
{
|
||||
ksort($data);
|
||||
}
|
||||
error_log(__METHOD__."('$country', $year, $end_year) took ". number_format(microtime(true)-$starttime, 3).'s to fetch '.count(call_user_func_array('array_merge', $years)).' events');
|
||||
//error_log(__METHOD__."('$country', $year, $end_year) took ". number_format(microtime(true)-$starttime, 3).'s to fetch '.count(call_user_func_array('array_merge', $years)).' events');
|
||||
unset($starttime);
|
||||
|
||||
return $until_year ? $years : $years[$year];
|
||||
|
|
|
@ -51,7 +51,7 @@ export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
|
|||
|
||||
// Start fetch of users
|
||||
const type = this.egw().preference('account_selection', 'common');
|
||||
if(!type || type == "none" || type == "selectbox")
|
||||
if(!type || type == "none")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
|
|||
else
|
||||
{
|
||||
fetch.push(this.egw().accounts('accounts').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
|
||||
fetch.push(this.egw().accounts('groups').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
|
||||
}
|
||||
this.fetchComplete = Promise.all(fetch)
|
||||
.then(() => this._renderOptions());
|
||||
|
|
|
@ -4010,8 +4010,17 @@ export class CalendarApp extends EgwApp
|
|||
var all_loaded = this.sidebox_et2 !== null;
|
||||
|
||||
// Avoid home portlets using our templates, and get them right
|
||||
if(_et2.uniqueId.indexOf('portlet') === 0) return;
|
||||
if(_et2.uniqueId === 'calendar-add') return;
|
||||
if(_et2.uniqueId.indexOf('portlet') === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip templates not involved in main view
|
||||
if(['calendar.conflicts', 'calendar.add'].includes(_name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Flag to make sure we don't hide non-view templates
|
||||
var view_et2 = false;
|
||||
|
|
|
@ -540,7 +540,7 @@ export class et2_calendar_view extends et2_valueWidget
|
|||
{
|
||||
// Create event
|
||||
this._drag_create_event()
|
||||
}, 100);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -115,48 +115,39 @@
|
|||
</grid>
|
||||
</template>
|
||||
<template id="filemanager.file.eacl" template="" lang="" group="0" version="1.9.001">
|
||||
<grid width="100%" spacing="10">
|
||||
<columns>
|
||||
<column width="120"/>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row valign="top" height="200">
|
||||
<groupbox span="all">
|
||||
<caption label="Extended access control list"/>
|
||||
<grid width="100%" overflow="auto" id="eacl">
|
||||
<columns>
|
||||
<column width="80"/>
|
||||
<column width="80"/>
|
||||
<column width="20%"/>
|
||||
<column width="16"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<et2-description value="Owner"></et2-description>
|
||||
<et2-description value="Rights"></et2-description>
|
||||
<et2-description value="Inherited"></et2-description>
|
||||
<et2-description></et2-description>
|
||||
</row>
|
||||
<row class="row" disabled="!@1">
|
||||
<et2-select-account id="${row}[owner]" readonly="true"></et2-select-account>
|
||||
<et2-select id="${row}[rights]" readonly="true"></et2-select>
|
||||
<et2-description id="${row}[path]"></et2-description>
|
||||
<et2-button label="Delete" id="delete[$row_cont[ino]-$row_cont[owner]]" onclick="et2_dialog.confirm(widget,'Delete this extended ACL?','Delete')" image="delete"></et2-button>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
</row>
|
||||
<row valign="bottom" disabled="!@is_owner">
|
||||
<et2-select-account class="filemanager-file_filemanager-file-eaclowner eaclAccount" label="Owner" id="eacl_owner" emptyLabel="select one" accountType="both"></et2-select-account>
|
||||
<et2-select class="eaclRights" statustext="You can only grant additional rights, you can NOT take rights away!" label="Rights" id="eacl[rights]"></et2-select>
|
||||
<et2-button label="Add" id="button[eacl]" image="add"></et2-button>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<et2-vbox class="full-height">
|
||||
<groupbox style="flex-grow: 1">
|
||||
<caption label="Extended access control list"/>
|
||||
<grid width="100%" overflow="auto" id="eacl">
|
||||
<columns>
|
||||
<column width="80"/>
|
||||
<column width="80"/>
|
||||
<column width="20%"/>
|
||||
<column width="16"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<et2-description value="Owner"></et2-description>
|
||||
<et2-description value="Rights"></et2-description>
|
||||
<et2-description value="Inherited"></et2-description>
|
||||
<et2-description></et2-description>
|
||||
</row>
|
||||
<row class="row" disabled="!@1">
|
||||
<et2-select-account id="${row}[owner]" readonly="true"></et2-select-account>
|
||||
<et2-select id="${row}[rights]" readonly="true"></et2-select>
|
||||
<et2-description id="${row}[path]"></et2-description>
|
||||
<et2-button label="Delete" id="delete[$row_cont[ino]-$row_cont[owner]]" onclick="et2_dialog.confirm(widget,'Delete this extended ACL?','Delete')" image="delete"></et2-button>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
<et2-hbox valign="bottom" disabled="!@is_owner">
|
||||
<et2-select-account class="filemanager-file_filemanager-file-eaclowner eaclAccount" label="Owner" id="eacl_owner" emptyLabel="select one" accountType="both" placement="top"></et2-select-account>
|
||||
<et2-select class="eaclRights" statustext="You can only grant additional rights, you can NOT take rights away!" label="Rights" id="eacl[rights]"></et2-select>
|
||||
<et2-button label="Add" id="button[eacl]" image="add"></et2-button>
|
||||
</et2-hbox>
|
||||
</et2-vbox>
|
||||
</template>
|
||||
<template id="filemanager.file.preview" template="" lang="" group="0" version="1.5.001">
|
||||
<grid width="100%" spacing="10" overflow="auto">
|
||||
<columns>
|
||||
|
@ -259,48 +250,49 @@
|
|||
<et2-button align="right" statustext="Enter setup user and password to get root rights" label="Superuser" id="sudouser" onclick="jQuery('.superuser').css('display','inline'); document.getElementById(form::name('sudo[user]')).focus();" image="superuser" noSubmit="true"></et2-button>
|
||||
</et2-hbox>
|
||||
</row>
|
||||
<row>
|
||||
<groupbox class="superuser">
|
||||
<caption label="Enter setup user and password"/>
|
||||
<grid>
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<et2-description for="sudo[user]" value="User"></et2-description>
|
||||
<et2-textbox id="sudo[user]"></et2-textbox>
|
||||
</row>
|
||||
<row>
|
||||
<et2-description for="sudo[passwd]" value="Password"></et2-description>
|
||||
<et2-password id="sudo[passwd]" autocomplete="on"></et2-password>
|
||||
</row>
|
||||
<row>
|
||||
<et2-description></et2-description>
|
||||
<et2-hbox>
|
||||
<et2-button label="Submit" id="button[setup]"></et2-button>
|
||||
<et2-button label="Cancel" onclick="jQuery('.superuser').hide();" noSubmit="true"></et2-button>
|
||||
</et2-hbox>
|
||||
<row>
|
||||
<groupbox class="superuser">
|
||||
<caption label="Enter setup user and password"/>
|
||||
<grid>
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<et2-description for="sudo[user]" value="User"></et2-description>
|
||||
<et2-textbox id="sudo[user]"></et2-textbox>
|
||||
</row>
|
||||
<row>
|
||||
<et2-description for="sudo[passwd]" value="Password"></et2-description>
|
||||
<et2-password id="sudo[passwd]" autocomplete="on"></et2-password>
|
||||
</row>
|
||||
<row>
|
||||
<et2-description></et2-description>
|
||||
<et2-hbox>
|
||||
<et2-button label="Submit" id="button[setup]"></et2-button>
|
||||
<et2-button label="Cancel" onclick="jQuery('.superuser').hide();" noSubmit="true"></et2-button>
|
||||
</et2-hbox>
|
||||
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<styles>
|
||||
.eaclAccount select,.eaclRights select { width: 160px; }
|
||||
.superuser {
|
||||
position: absolute;
|
||||
top: 130px;
|
||||
left: 120px;
|
||||
width: 200px;
|
||||
background-color: white;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
}
|
||||
</styles>
|
||||
</template>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<styles>
|
||||
.full-height { height: 100% }
|
||||
.full-height > fieldset { flex-grow: 1; }
|
||||
.superuser {
|
||||
position: absolute;
|
||||
top: 130px;
|
||||
left: 120px;
|
||||
width: 200px;
|
||||
background-color: white;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
}
|
||||
</styles>
|
||||
</template>
|
||||
</overlay>
|
|
@ -351,7 +351,24 @@ class importexport_export_csv implements importexport_iface_export_record
|
|||
$names = array();
|
||||
foreach($record->$name as $_name)
|
||||
{
|
||||
$option = $selects[$name][$_name];
|
||||
$select_options = $selects[$name] ?? [];
|
||||
$option = '';
|
||||
foreach($select_options as $key => $select_option)
|
||||
{
|
||||
if(is_array($select_option) && isset($select_option['value']) && $select_option['value'] == $name && isset($select_option['label']))
|
||||
{
|
||||
$option = $select_option['label'];
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($key == $_name && !is_array($select_option))
|
||||
{
|
||||
$option = $select_option;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$names[] = lang(is_array($option) && $option['label'] ? $option['label'] : $option);
|
||||
}
|
||||
$record->$name = implode(', ', $names);
|
||||
|
|
|
@ -357,9 +357,9 @@ class mail_integration {
|
|||
foreach($mailcontent['attachments'] as $key => $attachment)
|
||||
{
|
||||
$data_attachments[$key] = array(
|
||||
'name' => $mailcontent['attachments'][$key]['name'],
|
||||
'type' => $mailcontent['attachments'][$key]['type'],
|
||||
'size' => $mailcontent['attachments'][$key]['size'],
|
||||
'name' => $attachment['filename'] ?? $mailcontent['attachments'][$key]['name'],
|
||||
'type' => $mailcontent['attachments'][$key]['type'],
|
||||
'size' => $mailcontent['attachments'][$key]['size'],
|
||||
'tmp_name' => $mailcontent['attachments'][$key]['tmp_name']
|
||||
);
|
||||
if ($uid && !$mailcontent['attachments'][$key]['add_raw'])
|
||||
|
|
|
@ -1207,13 +1207,13 @@ app.classes.mail = AppJS.extend(
|
|||
},
|
||||
{
|
||||
id: 'saveOneToVfs',
|
||||
label: 'Save in Filemanager',
|
||||
label: 'Save to Filemanager',
|
||||
icon: 'filemanager/navbar',
|
||||
value: 'saveOneToVfs'
|
||||
},
|
||||
{
|
||||
id: 'saveAllToVfs',
|
||||
label: 'Save all to Filemanager',
|
||||
label: 'Save all attachments to Filemanager',
|
||||
icon: 'mail/save_all',
|
||||
value: 'saveAllToVfs'
|
||||
},
|
||||
|
|
|
@ -502,7 +502,7 @@ rule with priority mail en rule with priority
|
|||
rules mail en rules
|
||||
s/mime encryption failed because no certificate has been found for sender address: %1 mail en S/MIME Encryption failed because no certificate has been found for sender address: %1
|
||||
save all mail en Save all
|
||||
save all attachments to filemanager mail en Save all attachments to filemanager
|
||||
save all attachments to filemanager mail en Save all to filemanager
|
||||
save as calendar mail en Save as Calendar
|
||||
save as default mail en save as default
|
||||
save as draft mail en Save as Draft
|
||||
|
@ -518,7 +518,7 @@ save message to disk mail en Save Message to disk
|
|||
save of message %1 failed. could not save message to folder %2 due to: %3 mail en Save of message %1 failed. Could not save message to folder %2 due to: %3
|
||||
save the drafted message as eml file into vfs mail en Save the drafted message as eml file into VFS
|
||||
save to disk mail en Save to disk
|
||||
save to filemanager mail en Save to filemanager
|
||||
save to filemanager mail en Save in filemanager
|
||||
save: mail en Save:
|
||||
saves subscription changes mail en Save subscription changes
|
||||
saves this acl mail en Save this ACL
|
||||
|
|
Loading…
Reference in New Issue