plugins/managesieve/Changelog
@@ -1,3 +1,5 @@ - Added optional separate interface for out-of-office management (#1488266) * version 7.2 [2014-02-14] ----------------------------------------------------------- - Nicely handle server-side modification of script names (#1489412) plugins/managesieve/config.inc.php.dist
@@ -68,4 +68,10 @@ // If not empty, user will need to select domain from a list $config['managesieve_domains'] = array(); // Enables separate management interface for vacation responses (out-of-office) // 0 - no separate section (default), // 1 - add Vacation section, // 2 - add Vacation section, but hide Filters section $config['managesieve_vacation'] = 0; ?> plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
@@ -24,21 +24,21 @@ class rcube_sieve_engine { private $rc; private $sieve; private $errors; private $form; private $tips = array(); private $script = array(); private $exts = array(); private $list; private $active = array(); private $headers = array( protected $rc; protected $sieve; protected $errors; protected $form; protected $tips = array(); protected $script = array(); protected $exts = array(); protected $list; protected $active = array(); protected $headers = array( 'subject' => 'Subject', 'from' => 'From', 'to' => 'To', ); private $addr_headers = array( protected $addr_headers = array( // Required "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to", // Additional (RFC 822 / RFC 2822) @@ -53,7 +53,7 @@ "x-beenthere", ); const VERSION = '7.2'; const VERSION = '8.0'; const PROGNAME = 'Roundcube (Managesieve)'; const PORT = 4190; @@ -70,7 +70,7 @@ /** * Loads configuration, initializes plugin (including sieve connection) */ function start() function start($mode = null) { // register UI objects $this->rc->output->add_handlers(array( @@ -137,13 +137,16 @@ $this->rc->session->remove('managesieve_current'); } if (!empty($_GET['_set']) || !empty($_POST['_set'])) { $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true); if ($mode != 'vacation') { if (!empty($_GET['_set']) || !empty($_POST['_set'])) { $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true); } else if (!empty($_SESSION['managesieve_current'])) { $script_name = $_SESSION['managesieve_current']; } } else if (!empty($_SESSION['managesieve_current'])) { $script_name = $_SESSION['managesieve_current']; } else { if ($script_name === null || $script_name === '') { // get (first) active script if (!empty($this->active[0])) { $script_name = $this->active[0]; @@ -911,9 +914,12 @@ break; case 'vacation': $reason = $this->strip_value($reasons[$idx]); $interval_type = $interval_types[$idx] == 'seconds' ? 'seconds' : 'days'; console('---------------'); console($_POST); console($reason); $this->form['actions'][$i]['reason'] = str_replace("\r\n", "\n", $reason); $this->form['actions'][$i]['subject'] = $subject[$idx]; $this->form['actions'][$i]['addresses'] = array_shift($addresses); @@ -980,7 +986,7 @@ } if (!$this->errors && !$error) { // zapis skryptu // save the script if (!isset($this->script[$fid])) { $fid = $this->sieve->script->add_rule($this->form); $new = true; @@ -1016,7 +1022,7 @@ $this->send(); } private function send() protected function send() { // Handle form action if (isset($_GET['_framed']) || isset($_POST['_framed'])) { @@ -1026,7 +1032,8 @@ else { $this->rc->output->send('managesieve.filteredit'); } } else { } else { $this->rc->output->set_pagetitle($this->plugin->gettext('filters')); $this->rc->output->send('managesieve.managesieve'); } @@ -1809,12 +1816,12 @@ return $out; } private function genid() protected function genid() { return preg_replace('/[^0-9]/', '', microtime(true)); } private function strip_value($str, $allow_html = false, $trim = true) protected function strip_value($str, $allow_html = false, $trim = true) { if (is_array($str)) { foreach ($str as $idx => $val) { @@ -1835,7 +1842,7 @@ return $trim ? trim($str) : $str; } private function error_class($id, $type, $target, $elem_prefix='') protected function error_class($id, $type, $target, $elem_prefix='') { // TODO: tooltips if (($type == 'test' && ($str = $this->errors['tests'][$id][$target])) || @@ -1848,7 +1855,7 @@ return ''; } private function add_tip($id, $str, $error=false) protected function add_tip($id, $str, $error=false) { if ($error) $str = html::span('sieve error', $str); @@ -1856,7 +1863,7 @@ $this->tips[] = array($id, $str); } private function print_tips() protected function print_tips() { if (empty($this->tips)) return; @@ -1865,7 +1872,7 @@ $this->rc->output->add_script($script, 'foot'); } private function list_input($id, $name, $value, $enabled, $class, $size=null) protected function list_input($id, $name, $value, $enabled, $class, $size=null) { $value = (array) $value; $value = array_map(array('rcube', 'Q'), $value); @@ -1881,7 +1888,7 @@ /** * Validate input for date part elements */ private function validate_date_part($type, $value) protected function validate_date_part($type, $value) { // we do simple validation of date/part format switch ($type) { @@ -1926,7 +1933,7 @@ * * @return string Mailbox name */ private function mod_mailbox($mailbox, $mode = 'out') protected function mod_mailbox($mailbox, $mode = 'out') { $delimiter = $_SESSION['imap_delimiter']; $replace_delimiter = $this->rc->config->get('managesieve_replace_delimiter'); @@ -2218,7 +2225,7 @@ /** * Initializes internal script data */ private function init_script() protected function init_script() { $this->script = $this->sieve->script->as_array(); plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
New file @@ -0,0 +1,303 @@ <?php /** * Managesieve Vacation Engine * * Engine part of Managesieve plugin implementing UI and backend access. * * Copyright (C) 2011-2014, Kolab Systems AG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ class rcube_sieve_vacation extends rcube_sieve_engine { function actions() { $error = $this->start('vacation'); // find current vacation rule if (!$error) { $this->vacation_rule(); $this->vacation_post(); } $this->plugin->add_label('vacation.saving'); $this->rc->output->add_handlers(array( 'vacationform' => array($this, 'vacation_form'), )); $this->rc->output->set_pagetitle($this->plugin->gettext('vacation')); $this->rc->output->send('managesieve.vacation'); } private function vacation_rule() { $this->vacation = array(); if (empty($this->active)) { return; } $list = array(); // find (first) vacation rule foreach ($this->script as $idx => $rule) { if (empty($this->vacation) && !empty($rule['actions']) && $rule['actions'][0]['type'] == 'vacation') { $this->vacation = array_merge($rule['actions'][0], array( 'idx' => $idx, 'disabled' => $rule['disabled'], 'name' => $rule['name'], 'tests' => $rule['tests'], )); } else { $list[$idx] = $rule['name']; } } $this->vacation['list'] = $list; } private function vacation_post() { if (empty($_POST)) { return; } $status = rcube_utils::get_input_value('vacation_status', rcube_utils::INPUT_POST); $subject = rcube_utils::get_input_value('vacation_subject', rcube_utils::INPUT_POST, true); $reason = rcube_utils::get_input_value('vacation_reason', rcube_utils::INPUT_POST, true); $addresses = rcube_utils::get_input_value('vacation_addresses', rcube_utils::INPUT_POST, true); $interval = rcube_utils::get_input_value('vacation_interval', rcube_utils::INPUT_POST); $interval_type = rcube_utils::get_input_value('vacation_interval_type', rcube_utils::INPUT_POST); $date_from = rcube_utils::get_input_value('vacation_datefrom', rcube_utils::INPUT_POST); $date_to = rcube_utils::get_input_value('vacation_dateto', rcube_utils::INPUT_POST); $after = rcube_utils::get_input_value('vacation_after', rcube_utils::INPUT_POST); $interval_type = $interval_type == 'seconds' ? 'seconds' : 'days'; $vacation_action['type'] = 'vacation'; $vacation_action['reason'] = $this->strip_value(str_replace("\r\n", "\n", $reason)); $vacation_action['subject'] = $subject; $vacation_action['addresses'] = $addresses; $vacation_action[$interval_type] = $interval; $vacation_tests = (array) $this->vacation['tests']; foreach ((array) $vacation_action['addresses'] as $aidx => $address) { $vacation_action['addresses'][$aidx] = $address = trim($address); if (empty($address)) { unset($vacation_action['addresses'][$aidx]); } else if (!rcube_utils::check_email($address)) { $error = 'noemailwarning'; break; } } if ($vacation_action['reason'] == '') { $error = 'managesieve.cannotbeempty'; } if ($vacation_action[$interval_type] && !preg_match('/^[0-9]+$/', $vacation_action[$interval_type])) { $error = 'managesieve.forbiddenchars'; } foreach (array('date_from', 'date_to') as $var) { $date = $$var; if ($date && ($dt = rcube_utils::anytodatetime($date))) { $type = 'value-' . ($var == 'date_from' ? 'ge' : 'le'); $test = array( 'test' => 'currentdate', 'part' => 'date', 'type' => $type, 'arg' => $dt->format('Y-m-d'), ); // find existing date rule foreach ((array) $vacation_tests as $idx => $t) { if ($t['test'] == 'currentdate' && $t['part'] == 'date' && $t['type'] == $type) { $vacation_tests[$idx] = $test; continue 2; } } $vacation_tests[] = $test; } } if (empty($vacation_tests)) { $vacation_tests = $this->rc->config->get('managesieve_vacation_test', array(array('test' => 'true'))); } // @TODO: handle situation when there's no active script if (!$error) { $rule = $this->vacation; $rule['type'] = 'if'; $rule['name'] = $rule['name'] ?: $this->plugin->gettext('vacation'); $rule['disabled'] = $status == 'off'; $rule['actions'][0] = $vacation_action; $rule['tests'] = $vacation_tests; $rule['join'] = count($vacation_tests) > 1; // reset original vacation rule if (isset($this->vacation['idx'])) { $this->script[$this->vacation['idx']] = null; } // re-order rules if needed if (isset($after) && $after !== '') { // add at target position if ($after >= count($this->script) - 1) { $this->script[] = $rule; } else { $script = array(); foreach ($this->script as $idx => $r) { if ($r) { $script[] = $r; } if ($idx == $after) { $script[] = $rule; } } $this->script = $script; } } else { array_unshift($this->script, $rule); } $this->sieve->script->content = array_values(array_filter($this->script)); if ($this->save_script()) { $this->rc->output->show_message('managesieve.vacationsaved', 'confirmation'); $this->rc->output->send(); } } $this->rc->output->show_message($error ? $error : 'managesieve.saveerror', 'error'); $this->rc->output->send(); } /** * Independent vacation form */ public function vacation_form($attrib) { // check supported extensions $date_extension = in_array('date', $this->exts); $seconds_extension = in_array('vacation-seconds', $this->exts); // build FORM tag $form_id = !empty($attrib['id']) ? $attrib['id'] : 'form'; $out = $this->rc->output->request_form(array( 'id' => $form_id, 'name' => $form_id, 'method' => 'post', 'task' => 'settings', 'action' => 'plugin.managesieve-vacation', 'noclose' => true ) + $attrib); // form elements $subject = new html_inputfield(array('name' => 'vacation_subject', 'size' => 50)); $reason = new html_textarea(array('name' => 'vacation_reason', 'cols' => 60, 'rows' => 8)); $interval = new html_inputfield(array('name' => 'vacation_interval', 'size' => 5)); $addresses = '<textarea name="vacation_addresses" data-type="list" data-size="30" style="display: none">' . rcube::Q(implode("\n", (array) $this->vacation['addresses']), 'strict', false) . '</textarea>'; $status = new html_select(array('name' => 'vacation_status')); $status->add($this->plugin->gettext('vacation.on'), 'on'); $status->add($this->plugin->gettext('vacation.off'), 'off'); if ($this->rc->config->get('managesieve_vacation') != 2 && count($this->vacation['list'])) { $after = new html_select(array('name' => 'vacation_after')); $after->add('', ''); foreach ($this->vacation['list'] as $idx => $rule) { $after->add($rule, $idx); } } $interval_txt = $interval->show(isset($this->vacation['seconds']) ? $this->vacation['seconds'] : $this->vacation['days']); if ($seconds_extension) { $interval_select = new html_select(array('name' => 'vacation_interval_type')); $interval_select->add($this->plugin->gettext('days'), 'days'); $interval_select->add($this->plugin->gettext('seconds'), 'seconds'); $interval_txt .= ' ' . $interval_select->show(isset($this->vacation['seconds']) ? 'seconds' : 'days'); } else { $interval_txt .= ' ' . $this->plugin->gettext('days'); } if ($date_extension) { $date_from = new html_inputfield(array('name' => 'vacation_datefrom', 'class' => 'datepicker', 'size' => 12)); $date_to = new html_inputfield(array('name' => 'vacation_dateto', 'class' => 'datepicker', 'size' => 12)); $date_format = $this->rc->config->get('date_format', 'Y-m-d'); foreach ((array) $this->vacation['tests'] as $test) { if ($test['test'] == 'currentdate' && $test['part'] == 'date') { $date = $this->rc->format_date($test['arg'], $date_format, false); $date_value[$test['type'] == 'value-ge' ? 'from' : 'to'] = $date; } } } // Message tab $table = new html_table(array('cols' => 2)); $table->add('title', html::label('vacation_subject', $this->plugin->gettext('vacation.subject'))); $table->add(null, $subject->show($this->vacation['subject'])); $table->add('title', html::label('vacation_reason', $this->plugin->gettext('vacation.body'))); $table->add(null, $reason->show($this->vacation['reason'])); if ($date_extension) { $table->add('title', html::label('vacation_datefrom', $this->plugin->gettext('vacation.dates'))); $table->add(null, $this->plugin->gettext('vacation.from'). ' ' . $date_from->show($date_value['from']) . ' ' . $this->plugin->gettext('vacation.to'). ' ' . $date_to->show($date_value['to']) ); } $table->add('title', html::label('vacation_status', $this->plugin->gettext('vacation.status'))); $table->add(null, $status->show($this->vacation['disabled'] ? 'off' : 'on')); $out .= html::tag('fieldset', $class, html::tag('legend', null, $this->plugin->gettext('vacation.reply')) . $table->show($attrib)); // Advanced tab $table = new html_table(array('cols' => 2)); $table->add('title', $this->plugin->gettext('vacation.addresses')); $table->add(null, $addresses); $table->add('title', $this->plugin->gettext('vacation.interval')); $table->add(null, $interval_txt); if ($after) { $table->add('title', $this->plugin->gettext('vacation.after')); $table->add(null, $after->show($this->vacation['idx'] - 1)); } $out .= html::tag('fieldset', $class, html::tag('legend', null, $this->plugin->gettext('vacation.advanced')) . $table->show($attrib)); $out .= '</form>'; $this->rc->output->add_gui_object('sieveform', $form_id); return $out; } } plugins/managesieve/localization/en_US.inc
@@ -59,10 +59,10 @@ $labels['vacationaddr'] = 'My additional e-mail address(es):'; $labels['vacationdays'] = 'How often send messages (in days):'; $labels['vacationinterval'] = 'How often send messages:'; $labels['days'] = 'days'; $labels['seconds'] = 'seconds'; $labels['vacationreason'] = 'Message body (vacation reason):'; $labels['vacationsubject'] = 'Message subject:'; $labels['days'] = 'days'; $labels['seconds'] = 'seconds'; $labels['rulestop'] = 'Stop evaluating rules'; $labels['enable'] = 'Enable/Disable'; $labels['filterset'] = 'Filters set'; @@ -159,6 +159,21 @@ $labels['asciinumeric'] = 'numeric (ascii-numeric)'; $labels['index'] = 'index:'; $labels['indexlast'] = 'backwards'; $labels['vacation'] = 'Vacation'; $labels['vacation.reply'] = 'Reply message'; $labels['vacation.advanced'] = 'Advanced settings'; $labels['vacation.subject'] = 'Subject'; $labels['vacation.body'] = 'Body'; $labels['vacation.dates'] = 'Vacation time'; $labels['vacation.from'] = 'From:'; $labels['vacation.to'] = 'To:'; $labels['vacation.status'] = 'Status'; $labels['vacation.on'] = 'On'; $labels['vacation.off'] = 'Off'; $labels['vacation.addresses'] = 'My additional addresses'; $labels['vacation.interval'] = 'Reply interval'; $labels['vacation.after'] = 'Put vacation rule after'; $labels['vacation.saving'] = 'Saving data...'; $messages = array(); $messages['filterunknownerror'] = 'Unknown server error.'; @@ -193,5 +208,7 @@ $messages['setexist'] = 'Set already exists.'; $messages['nodata'] = 'At least one position must be selected!'; $messages['invaliddateformat'] = 'Invalid date or date part format'; $messages['saveerror'] = 'Unable to save data. Server error occurred.'; $messages['vacationsaved'] = 'Vacation data saved successfully.'; ?> plugins/managesieve/managesieve.js
@@ -50,6 +50,18 @@ $('textarea[data-type="list"]', rcmail.gui_objects.sieveform).each(function() { smart_field_init(this); }); // enable date pickers on date fields if ($.datepicker && rcmail.env.date_format) { $.datepicker.setDefaults({ dateFormat: rcmail.env.date_format, changeMonth: true, showOtherMonths: true, selectOtherMonths: true, onSelect: function(dateText) { $(this).focus().val(dateText) } }); $('input.datepicker').datepicker(); } } else { rcmail.enable_command('plugin.managesieve-add', 'plugin.managesieve-setadd', !rcmail.env.sieveconnerror); @@ -443,6 +455,12 @@ // Form submition rcube_webmail.prototype.managesieve_save = function() { if (this.env.action == 'plugin.managesieve-vacation') { var data = $(this.gui_objects.sieveform).serialize(); this.http_post('plugin.managesieve-vacation', data, this.display_message(this.get_label('managesieve.vacation.saving'), 'loading')); return; } if (parent.rcmail && parent.rcmail.filters_list && this.gui_objects.sieveform.name != 'filtersetform') { var id = parent.rcmail.filters_list.get_single_selection(); if (id != null) plugins/managesieve/managesieve.php
@@ -42,6 +42,7 @@ // register actions $this->register_action('plugin.managesieve', array($this, 'managesieve_actions')); $this->register_action('plugin.managesieve-action', array($this, 'managesieve_actions')); $this->register_action('plugin.managesieve-vacation', array($this, 'managesieve_actions')); $this->register_action('plugin.managesieve-save', array($this, 'managesieve_save')); if ($this->rc->task == 'settings') { @@ -69,8 +70,25 @@ } // load localization $this->add_texts('localization/', array('filters','managefilters')); $this->include_script('managesieve.js'); $this->add_texts('localization/'); if (strpos($this->rc->action, 'plugin.managesieve') === 0) { $this->include_script('managesieve.js'); } // include styles $skin_path = $this->local_skin_path(); if ($this->rc->task == 'settings') { if (is_file($this->home . "/$skin_path/managesieve.css")) { $this->include_stylesheet("$skin_path/managesieve.css"); } } else { if (is_file($this->home . "/$skin_path/managesieve_mail.css")) { $this->include_stylesheet("$skin_path/managesieve_mail.css"); } } $this->ui_initialized = true; } @@ -80,8 +98,30 @@ */ function settings_actions($args) { // register as settings action $args['actions'][] = array('action' => 'plugin.managesieve', 'class' => 'filter', 'label' => 'filters', 'domain' => 'managesieve'); $this->load_config(); $vacation_mode = (int) $this->rc->config->get('managesieve_vacation'); // register Filters action if ($vacation_mode != 2) { $args['actions'][] = array( 'action' => 'plugin.managesieve', 'class' => 'filter', 'label' => 'filters', 'domain' => 'managesieve', ); } // register Vacation action if ($vacation_mode > 0) { $args['actions'][] = array( 'action' => 'plugin.managesieve-vacation', 'class' => 'vacation', 'label' => 'vacation', 'domain' => 'managesieve', ); } return $args; } @@ -100,12 +140,6 @@ // include js script and localization $this->init_ui(); // include styles $skin_path = $this->local_skin_path(); if (is_file($this->home . "/$skin_path/managesieve_mail.css")) { $this->include_stylesheet("$skin_path/managesieve_mail.css"); } // add 'Create filter' item to message menu $this->api->add_content(html::tag('li', null, @@ -163,9 +197,11 @@ $this->rc->output->send(); } // handle other action // handle other actions $engine_type = $this->rc->action == 'plugin.managesieve-vacation' ? 'vacation' : ''; $engine = $this->get_engine($engine_type); $this->init_ui(); $engine = $this->get_engine(); $engine->actions(); } @@ -189,7 +225,7 @@ /** * Initializes engine object */ private function get_engine() private function get_engine($type = null) { if (!$this->engine) { $this->load_config(); @@ -199,7 +235,8 @@ $include_path .= ini_get('include_path'); set_include_path($include_path); $this->engine = new rcube_sieve_engine($this); $class_name = 'rcube_sieve_' . ($type ? $type : 'engine'); $this->engine = new $class_name($this); } return $this->engine; plugins/managesieve/skins/classic/managesieve.css
@@ -115,7 +115,7 @@ padding: 20px 10px 10px 10px; } legend, label #filter-form legend, #filter-form label { color: #666666; } @@ -410,3 +410,20 @@ { padding: 10px 5px 5px 5px; } #vacationform .listarea { max-height: 83px; } #vacationform .listelement, #vacationform .listelement .reset { height: 20px; } #vacationform .listelement .reset { background-position: -1px 2px; } #vacationform .listelement input { vertical-align: top; } plugins/managesieve/skins/classic/templates/filteredit.html
@@ -3,7 +3,6 @@ <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> <link rel="stylesheet" type="text/css" href="/this/managesieve.css" /> </head> <body class="iframe<roundcube:exp expression="env:task != 'mail' ? '' : ' mail'" />"> plugins/managesieve/skins/classic/templates/managesieve.html
@@ -3,7 +3,6 @@ <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> <link rel="stylesheet" type="text/css" href="/this/managesieve.css" /> <script type="text/javascript" src="/functions.js"></script> <script type="text/javascript" src="/splitter.js"></script> plugins/managesieve/skins/classic/templates/setedit.html
@@ -3,7 +3,6 @@ <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> <link rel="stylesheet" type="text/css" href="/this/managesieve.css" /> </head> <body class="iframe"> plugins/managesieve/skins/classic/templates/vacation.html
New file @@ -0,0 +1,31 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> <script type="text/javascript" src="/functions.js"></script> </head> <body> <roundcube:include file="/includes/taskbar.html" /> <roundcube:include file="/includes/header.html" /> <roundcube:include file="/includes/settingstabs.html" /> <div id="mainscreen"> <div class="box" style="height: 100%; overflow: auto"> <div id="prefs-title" class="boxtitle"><roundcube:label name="managesieve.vacation" /></div> <roundcube:object name="vacationform" id="vacationform" style="margin: 10px 10px 0 10px" /> <div id="formfooter" style="padding: 0 10px"> <div class="footerleft"> <roundcube:button command="save" type="input" class="button mainaction" label="save" /> </div> </div> </div> </div> <script type="text/javascript"> rcube_init_mail_ui(); </script> </body> </html> plugins/managesieve/skins/larry/images/vacation_icons.png
plugins/managesieve/skins/larry/managesieve.css
@@ -89,7 +89,7 @@ padding: 20px 10px 10px 10px; } legend, label #filter-form legend, #filter-form label { color: #666666; } @@ -124,7 +124,7 @@ min-width: 600px; } td #filter-form td { vertical-align: top; } @@ -414,3 +414,39 @@ { padding: 10px 5px 5px 5px; } /* vacation form */ #settings-sections span.vacation a { background: url(images/vacation_icons.png) no-repeat 7px 1px; } #settings-sections span.vacation.selected a { background-position: 7px -23px; } #managesieve-vacation { position: absolute; top: 0; left: 212px; right: 0; bottom: 0; overflow: auto; } #vacationform .listarea { max-height: 83px; } #vacationform .listelement, #vacationform .listelement .reset { height: 27px; } #vacationform .listelement .reset { background-position: -1px 5px; } #vacationform .listelement input { vertical-align: top; } plugins/managesieve/skins/larry/templates/filteredit.html
@@ -3,7 +3,6 @@ <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> <link rel="stylesheet" type="text/css" href="/this/managesieve.css" /> </head> <body class="iframe<roundcube:exp expression="env:task != 'mail' ? ' floatingbuttons' : ' mail'" />"> plugins/managesieve/skins/larry/templates/managesieve.html
@@ -3,7 +3,6 @@ <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> <link rel="stylesheet" type="text/css" href="/this/managesieve.css" /> </head> <body class="noscroll"> plugins/managesieve/skins/larry/templates/setedit.html
@@ -3,7 +3,6 @@ <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> <link rel="stylesheet" type="text/css" href="/this/managesieve.css" /> </head> <body class="iframe floatingbuttons"> plugins/managesieve/skins/larry/templates/vacation.html
New file @@ -0,0 +1,30 @@ <roundcube:object name="doctype" value="html5" /> <html> <head> <title><roundcube:object name="pagetitle" /></title> <roundcube:include file="/includes/links.html" /> </head> <body class="noscroll"> <roundcube:include file="/includes/header.html" /> <div id="mainscreen" class="offset"> <roundcube:include file="/includes/settingstabs.html" /> <div id="managesieve-vacation" class="uibox contentbox"> <div> <h2 class="boxtitle"><roundcube:label name="managesieve.vacation" /></h2> <roundcube:object name="vacationform" id="vacationform" class="propform boxcontent tabbed" /> </div> <div class="footerleft formbuttons"> <roundcube:button command="plugin.managesieve-save" type="input" class="button mainaction" label="save" /> </div> </div> </div> <roundcube:include file="/includes/footer.html" /> </body> </html>