Add possibility to print contact information (of a single contact)
10 files modified
3 files added
| | |
| | | CHANGELOG Roundcube Webmail |
| | | =========================== |
| | | |
| | | - Add possibility to print contact information (of a single contact) |
| | | - Fix refreshing of drafts list when sending a message which was saved in meantime (#1490238) |
| | | |
| | | RELEASE 1.1.0 |
| | |
| | | this.enable_command('download', 'print', true); |
| | | // show printing dialog |
| | | else if (this.env.action == 'print' && this.env.uid) { |
| | | if (bw.safari) |
| | | setTimeout('window.print()', 10); |
| | | else |
| | | window.print(); |
| | | this.print_dialog(); |
| | | } |
| | | |
| | | // get unread count for each mailbox |
| | |
| | | this.enable_command('save', true); |
| | | if (this.env.action == 'add' || this.env.action == 'edit' || this.env.action == 'search') |
| | | this.init_contact_form(); |
| | | } |
| | | else if (this.env.action == 'print') { |
| | | this.print_dialog(); |
| | | } |
| | | |
| | | break; |
| | |
| | | break; |
| | | |
| | | case 'print': |
| | | if (this.env.action == 'get') { |
| | | if (this.task == 'addressbook') { |
| | | if (uid = this.contact_list.get_single_selection()) { |
| | | url = '&_action=print&_cid=' + uid; |
| | | if (this.env.source) |
| | | url += '&_source=' + urlencode(this.env.source); |
| | | this.open_window(this.env.comm_path + url, true, true); |
| | | } |
| | | } |
| | | else if (this.env.action == 'get') { |
| | | this.gui_objects.messagepartframe.contentWindow.print(); |
| | | } |
| | | else if (uid = this.get_single_uid()) { |
| | |
| | | clearTimeout(this.preview_timer); |
| | | |
| | | var n, id, sid, contact, writable = false, |
| | | selected = list.selection.length, |
| | | source = this.env.source ? this.env.address_sources[this.env.source] : null; |
| | | |
| | | // we don't have dblclick handler here, so use 200 instead of this.dblclick_time |
| | |
| | | else if (this.env.contentframe) |
| | | this.show_contentframe(false); |
| | | |
| | | if (list.selection.length) { |
| | | if (selected) { |
| | | list.draggable = false; |
| | | |
| | | // no source = search result, we'll need to detect if any of |
| | |
| | | |
| | | // if a group is currently selected, and there is at least one contact selected |
| | | // thend we can enable the group-remove-selected command |
| | | this.enable_command('group-remove-selected', this.env.group && list.selection.length > 0 && writable); |
| | | this.enable_command('compose', this.env.group || list.selection.length > 0); |
| | | this.enable_command('export-selected', 'copy', list.selection.length > 0); |
| | | this.enable_command('group-remove-selected', this.env.group && selected && writable); |
| | | this.enable_command('compose', this.env.group || selected); |
| | | this.enable_command('print', selected == 1); |
| | | this.enable_command('export-selected', 'copy', selected > 0); |
| | | this.enable_command('edit', id && writable); |
| | | this.enable_command('delete', 'move', list.selection.length > 0 && writable); |
| | | this.enable_command('delete', 'move', selected && writable); |
| | | |
| | | return false; |
| | | }; |
| | |
| | | this.contact_list.data = {}; |
| | | this.contact_list.clear(true); |
| | | this.show_contentframe(false); |
| | | this.enable_command('delete', 'move', 'copy', false); |
| | | this.enable_command('compose', this.env.group ? true : false); |
| | | this.enable_command('delete', 'move', 'copy', 'print', false); |
| | | this.enable_command('compose', this.env.group); |
| | | }; |
| | | |
| | | this.set_group_prop = function(prop) |
| | |
| | | this.contact_list.clear_selection(); |
| | | |
| | | this.enable_command('compose', rec && rec.email); |
| | | this.enable_command('export-selected', rec && rec._type != 'group'); |
| | | this.enable_command('export-selected', 'print', rec && rec._type != 'group'); |
| | | } |
| | | else if (framed) |
| | | return false; |
| | |
| | | this.enable_command('compose', (uid && this.contact_list.rows[uid])); |
| | | this.enable_command('delete', 'edit', writable); |
| | | this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0)); |
| | | this.enable_command('export-selected', false); |
| | | this.enable_command('export-selected', 'print', false); |
| | | } |
| | | |
| | | case 'move': |
| | |
| | | return false; |
| | | } |
| | | }; |
| | | |
| | | this.print_dialog = function() |
| | | { |
| | | if (bw.safari) |
| | | setTimeout('window.print()', 10); |
| | | else |
| | | window.print(); |
| | | }; |
| | | } // end object rcube_webmail |
| | | |
| | | |
| | |
| | | $labels['advsearch'] = 'Advanced Search'; |
| | | $labels['advanced'] = 'Advanced'; |
| | | $labels['other'] = 'Other'; |
| | | $labels['printcontact'] = 'Print contact'; |
| | | |
| | | $labels['typehome'] = 'Home'; |
| | | $labels['typework'] = 'Work'; |
| | |
| | | |
| | | $form = $plugin['form']; |
| | | $record = $plugin['record']; |
| | | $edit_mode = $RCMAIL->action != 'show'; |
| | | $edit_mode = $RCMAIL->action != 'show' && $RCMAIL->action != 'print'; |
| | | $del_button = $attrib['deleteicon'] ? html::img(array('src' => $RCMAIL->output->get_skin_file($attrib['deleteicon']), 'alt' => $RCMAIL->gettext('delete'))) : $RCMAIL->gettext('delete'); |
| | | unset($attrib['deleteicon']); |
| | | $out = ''; |
| | | |
| | | unset($attrib['deleteicon']); |
| | | |
| | | // get default coltypes |
| | | $coltypes = $GLOBALS['CONTACT_COLTYPES']; |
| | |
| | | |
| | | foreach ($form as $section => $fieldset) { |
| | | // skip empty sections |
| | | if (empty($fieldset['content'])) |
| | | if (empty($fieldset['content'])) { |
| | | continue; |
| | | } |
| | | |
| | | $select_add = new html_select(array('class' => 'addfieldmenu', 'rel' => $section)); |
| | | $select_add->add($RCMAIL->gettext('addfield'), ''); |
| | |
| | | $content = ''; |
| | | |
| | | // unset display name if it is composed from name parts |
| | | if ($record['name'] == rcube_addressbook::compose_display_name(array('name' => '') + (array)$record)) |
| | | if ($record['name'] == rcube_addressbook::compose_display_name(array('name' => '') + (array)$record)) { |
| | | unset($record['name']); |
| | | } |
| | | |
| | | // group fields |
| | | $field_blocks = array( |
| | |
| | | 'department' => array('department'), |
| | | 'jobtitle' => array('jobtitle'), |
| | | ); |
| | | |
| | | foreach ($field_blocks as $blockname => $colnames) { |
| | | $fields = ''; |
| | | foreach ($colnames as $col) { |
| | |
| | | if (!$coltypes[$col]) |
| | | continue; |
| | | |
| | | // skip cols not listed in the form definition |
| | | if (is_array($fieldset['content']) && !in_array($col, array_keys($fieldset['content']))) { |
| | | continue; |
| | | } |
| | | |
| | | // only string values are expected here |
| | | if (is_array($record[$col])) |
| | | $record[$col] = join(' ', $record[$col]); |
| | | |
| | | if ($RCMAIL->action == 'show') { |
| | | if (!$edit_mode) { |
| | | if (!empty($record[$col])) |
| | | $fields .= html::span('namefield ' . $col, rcube::Q($record[$col])) . " "; |
| | | } |
| | |
| | | $fullkey = $col.':'.$subtype; |
| | | |
| | | // skip cols unknown to the backend |
| | | if (!$coltypes[$field]) |
| | | if (!$coltypes[$field] && empty($colprop['value'])) { |
| | | continue; |
| | | } |
| | | |
| | | // merge colprop with global coltype configuration |
| | | if ($coltypes[$field]) { |
| | | $colprop += $coltypes[$field]; |
| | | } |
| | | |
| | | $label = isset($colprop['label']) ? $colprop['label'] : $RCMAIL->gettext($col); |
| | | |
| | | // prepare subtype selector in edit mode |
| | |
| | | $select_subtype = new html_select(array('name' => '_subtype_'.$col.'[]', 'class' => 'contactselectsubtype', 'title' => $colprop['label'] . ' ' . $RCMAIL->gettext('type'))); |
| | | $select_subtype->add($subtype_names, $colprop['subtypes']); |
| | | } |
| | | else |
| | | else { |
| | | $select_subtype = null; |
| | | } |
| | | |
| | | if (!empty($colprop['value'])) { |
| | | $values = (array)$colprop['value']; |
| | |
| | | |
| | | // display row with label |
| | | if ($label) { |
| | | if ($RCMAIL->action == 'print') { |
| | | $_label = rcube::Q($colprop['label'] . ($label != $colprop['label'] ? ' (' . $label . ')' : '')); |
| | | } |
| | | else { |
| | | $_label = $select_subtype ? $select_subtype->show($subtype) : html::label($colprop['id'], rcube::Q($label)); |
| | | } |
| | | |
| | | $rows .= html::div('row', |
| | | html::div('contactfieldlabel label', $select_subtype ? $select_subtype->show($subtype) : html::label($colprop['id'], rcube::Q($label))) . |
| | | html::div('contactfieldlabel label', $_label) . |
| | | html::div('contactfieldcontent '.$colprop['type'], $val)); |
| | | } |
| | | else // row without label |
| | | // row without label |
| | | else { |
| | | $rows .= html::div('row', html::div('contactfield', $val)); |
| | | } |
| | | } |
| | | |
| | | // add option to the add-field menu |
| | |
| | | |
| | | // wrap rows in fieldgroup container |
| | | if ($rows) { |
| | | $content .= html::tag('fieldset', array('class' => 'contactfieldgroup ' . ($colprop['subtypes'] ? 'contactfieldgroupmulti ' : '') . 'contactcontroller' . $col, 'style' => ($rows ? null : 'display:none')), |
| | | ($colprop['subtypes'] ? html::tag('legend', null, rcube::Q($colprop['label'])) : ' ') . |
| | | $rows); |
| | | $c_class = 'contactfieldgroup ' . ($colprop['subtypes'] ? 'contactfieldgroupmulti ' : '') . 'contactcontroller' . $col; |
| | | $with_label = $colprop['subtypes'] && $RCMAIL->action != 'print'; |
| | | $content .= html::tag( |
| | | 'fieldset', |
| | | array('class' => $c_class, 'style' => ($rows ? null : 'display:none')), |
| | | ($with_label ? html::tag('legend', null, rcube::Q($colprop['label'])) : ' ') . $rows |
| | | ); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | +-----------------------------------------------------------------------+ |
| | | | program/steps/addressbook/print.inc | |
| | | | | |
| | | | This file is part of the Roundcube Webmail client | |
| | | | Copyright (C) 2005-2015, The Roundcube Dev Team | |
| | | | Copyright (C) 2011-2015, Kolab Systems AG | |
| | | | | |
| | | | Licensed under the GNU General Public License version 3 or | |
| | | | any later version with exceptions for skins & plugins. | |
| | | | See the README file for a full license statement. | |
| | | | | |
| | | | PURPOSE: | |
| | | | Print contact details | |
| | | | | |
| | | +-----------------------------------------------------------------------+ |
| | | | Author: Thomas Bruederli <roundcube@gmail.com> | |
| | | | Author: Aleksander Machniak <machniak@kolabsys.com> | |
| | | +-----------------------------------------------------------------------+ |
| | | */ |
| | | |
| | | // Get contact ID and source ID from request |
| | | $cids = rcmail_get_cids(); |
| | | $source = key($cids); |
| | | $cid = $cids ? array_shift($cids[$source]) : null; |
| | | |
| | | // Initialize addressbook source |
| | | $CONTACTS = rcmail_contact_source($source, true); |
| | | $SOURCE_ID = $source; |
| | | |
| | | // read contact record |
| | | if ($cid && $CONTACTS) { |
| | | $record = $CONTACTS->get_record($cid, true); |
| | | } |
| | | |
| | | $OUTPUT->add_handlers(array( |
| | | 'contacthead' => 'rcmail_contact_head', |
| | | 'contactdetails' => 'rcmail_contact_details', |
| | | 'contactphoto' => 'rcmail_contact_photo', |
| | | )); |
| | | |
| | | $OUTPUT->send('contactprint'); |
| | | |
| | | |
| | | |
| | | function rcmail_contact_head($attrib) |
| | | { |
| | | global $CONTACTS, $RCMAIL; |
| | | |
| | | // check if we have a valid result |
| | | if (!(($result = $CONTACTS->get_result()) && ($record = $result->first()))) { |
| | | $RCMAIL->output->show_message('contactnotfound', 'error'); |
| | | return false; |
| | | } |
| | | |
| | | $form = array( |
| | | 'head' => array( // section 'head' is magic! |
| | | 'name' => $RCMAIL->gettext('contactnameandorg'), |
| | | 'content' => array( |
| | | 'prefix' => array(), |
| | | 'name' => array(), |
| | | 'firstname' => array(), |
| | | 'middlename' => array(), |
| | | 'surname' => array(), |
| | | 'suffix' => array(), |
| | | ), |
| | | ), |
| | | ); |
| | | |
| | | unset($attrib['name']); |
| | | return rcmail_contact_form($form, $record, $attrib); |
| | | } |
| | | |
| | | |
| | | function rcmail_contact_details($attrib) |
| | | { |
| | | global $CONTACTS, $RCMAIL, $CONTACT_COLTYPES; |
| | | |
| | | // check if we have a valid result |
| | | if (!(($result = $CONTACTS->get_result()) && ($record = $result->first()))) { |
| | | return false; |
| | | } |
| | | |
| | | $i_size = !empty($attrib['size']) ? $attrib['size'] : 40; |
| | | |
| | | $form = array( |
| | | 'contact' => array( |
| | | 'name' => $RCMAIL->gettext('properties'), |
| | | 'content' => array( |
| | | 'organization' => array(), |
| | | 'department' => array(), |
| | | 'jobtitle' => array(), |
| | | 'email' => array(), |
| | | 'phone' => array(), |
| | | 'address' => array(), |
| | | 'website' => array(), |
| | | 'im' => array(), |
| | | 'groups' => array('value' => 'sdfsdfs', 'label' => $RCMAIL->gettext('groups')), |
| | | ), |
| | | ), |
| | | 'personal' => array( |
| | | 'name' => $RCMAIL->gettext('personalinfo'), |
| | | 'content' => array( |
| | | 'nickname' => array(), |
| | | 'gender' => array(), |
| | | 'maidenname' => array(), |
| | | 'birthday' => array(), |
| | | 'anniversary' => array(), |
| | | 'manager' => array(), |
| | | 'assistant' => array(), |
| | | 'spouse' => array(), |
| | | ), |
| | | ), |
| | | ); |
| | | |
| | | if (isset($CONTACT_COLTYPES['notes'])) { |
| | | $form['notes'] = array( |
| | | 'name' => $RCMAIL->gettext('notes'), |
| | | 'content' => array( |
| | | 'notes' => array('type' => 'textarea', 'label' => false), |
| | | ), |
| | | ); |
| | | } |
| | | |
| | | if ($CONTACTS->groups) { |
| | | $groups = $CONTACTS->get_record_groups($record['ID']); |
| | | if (!empty($groups)) { |
| | | $form['contact']['content']['groups'] = array( |
| | | 'value' => rcube::Q(implode(', ', $groups)), |
| | | 'label' => $RCMAIL->gettext('groups') |
| | | ); |
| | | } |
| | | } |
| | | |
| | | return rcmail_contact_form($form, $record); |
| | | } |
| | |
| | | 'middlename' => array('type' => 'text'), |
| | | 'surname' => array('type' => 'text'), |
| | | 'suffix' => array('type' => 'text'), |
| | | 'name' => array('type' => 'text'), |
| | | 'nickname' => array('type' => 'text'), |
| | | 'organization' => array('type' => 'text'), |
| | | 'department' => array('type' => 'text'), |
| | | 'jobtitle' => array('type' => 'text'), |
| | | ), |
| | | ), |
| | | ); |
| | |
| | | background-position: -32px -32px; |
| | | } |
| | | |
| | | #abooktoolbar a.print { |
| | | background: url(images/mail_toolbar.png) 0 0 no-repeat transparent; |
| | | background-position: -256px 0; |
| | | } |
| | | |
| | | #abooktoolbar a.printSel { |
| | | background: url(images/mail_toolbar.png) 0 0 no-repeat transparent; |
| | | background-position: -256px -32px; |
| | | } |
| | | |
| | | #abooktoolbar a.delete { |
| | | background-position: -64px 0; |
| | | } |
| | |
| | | { |
| | | display: none; |
| | | } |
| | | |
| | | /* contact print */ |
| | | #contact-details fieldset { |
| | | color: #666; |
| | | border: 1px solid #999; |
| | | margin-top: 5px; |
| | | } |
| | | |
| | | #contact-details fieldset.contactfieldgroup { |
| | | border: 0; |
| | | padding: 0; |
| | | margin: 0; |
| | | } |
| | | |
| | | #contact-details div.row { |
| | | padding: 2px 0; |
| | | } |
| | | |
| | | #contact-details .contactfieldlabel { |
| | | display: inline-block; |
| | | vertical-align: top; |
| | | width: 150px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | #contact-details .contactfieldcontent { |
| | | display: inline-block; |
| | | vertical-align: top; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | #contact-details #contactphoto { |
| | | float: left; |
| | | margin: 5px 15px 5px 3px; |
| | | width: 112px; |
| | | border: 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | #contact-details #contactpic { |
| | | width: 112px; |
| | | background: white; |
| | | } |
| | | |
| | | #contact-details #contactpic img { |
| | | max-width: 112px; |
| | | visibility: inherit; |
| | | } |
| | | |
| | | #contact-details #contacthead { |
| | | border: 0; |
| | | margin: 0 16em 0 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | #contact-details #contacthead > legend { |
| | | display: none; |
| | | } |
| | | |
| | | #contact-details #contacthead .names span.namefield { |
| | | font-size: 140%; |
| | | font-weight: bold; |
| | | } |
| | |
| | | <div id="abooktoolbar"> |
| | | <roundcube:button command="add" type="link" class="buttonPas addcontact" classAct="button addcontact" classSel="button addcontactSel" title="newcontact" content=" " /> |
| | | <roundcube:button command="compose" type="link" class="buttonPas compose" classAct="button compose" classSel="button composeSel" title="composeto" content=" " /> |
| | | <roundcube:button command="print" type="link" class="buttonPas print" classAct="button print" classSel="button printSel" label="print" title="printcontact" content=" " /> |
| | | <roundcube:button command="delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="deletecontact" content=" " /> |
| | | <span class="separator"> </span> |
| | | <roundcube:button command="import" type="link" class="buttonPas import" classAct="button import" classSel="button importSel" title="importcontacts" content=" " /> |
New file |
| | |
| | | <!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> |
| | | <link rel="shortcut icon" href="/images/favicon.ico"/> |
| | | <link rel="stylesheet" type="text/css" href="/print.css" /> |
| | | </head> |
| | | <body> |
| | | |
| | | <roundcube:object name="logo" src="/images/roundcube_logo.png" id="logo" border="0" /> |
| | | |
| | | <div id="contact-details"> |
| | | <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" placeholderGroup="/images/contactgroup.png" /></div> |
| | | <roundcube:object name="contacthead" id="contacthead" /> |
| | | <div style="clear:both"></div> |
| | | <roundcube:object name="contactdetails" /> |
| | | </div> |
| | | |
| | | </body> |
| | | </html> |
| | |
| | | display: none; |
| | | } |
| | | |
| | | /* contact print */ |
| | | #contact-details fieldset { |
| | | color: #666; |
| | | border: 1px solid #999; |
| | | margin-top: 5px; |
| | | } |
| | | |
| | | #contact-details fieldset.contactfieldgroup { |
| | | border: 0; |
| | | padding: 0; |
| | | margin: 0; |
| | | } |
| | | |
| | | #contact-details div.row { |
| | | padding: 2px 0; |
| | | } |
| | | |
| | | #contact-details .contactfieldlabel { |
| | | display: inline-block; |
| | | vertical-align: top; |
| | | width: 150px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | #contact-details .contactfieldcontent { |
| | | display: inline-block; |
| | | vertical-align: top; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | #contact-details #contactphoto { |
| | | float: left; |
| | | margin: 5px 15px 5px 3px; |
| | | width: 112px; |
| | | border: 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | #contact-details #contactpic { |
| | | width: 112px; |
| | | background: white; |
| | | } |
| | | |
| | | #contact-details #contactpic img { |
| | | max-width: 112px; |
| | | visibility: inherit; |
| | | } |
| | | |
| | | #contact-details #contacthead { |
| | | border: 0; |
| | | margin: 0 16em 0 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | #contact-details #contacthead > legend { |
| | | display: none; |
| | | } |
| | | |
| | | #contact-details #contacthead .names span.namefield { |
| | | font-size: 140%; |
| | | font-weight: bold; |
| | | } |
| | |
| | | |
| | | <span class="spacer"></span> |
| | | <roundcube:button command="compose" type="link" class="button compose disabled" classAct="button compose" classSel="button compose pressed" label="compose" title="writenewmessage" /> |
| | | <roundcube:button command="print" type="link" class="button print disabled" classAct="button print" classSel="button print pressed" label="print" title="printcontact" /> |
| | | <roundcube:button command="advanced-search" type="link" class="button search disabled" classAct="button search" classSel="button search pressed" label="advanced" title="advsearch" /> |
| | | <roundcube:container name="toolbar" id="addressbooktoolbar" /> |
| | | |
New file |
| | |
| | | <roundcube:object name="doctype" value="html5" /> |
| | | <html> |
| | | <head> |
| | | <title><roundcube:object name="pagetitle" /></title> |
| | | <link rel="shortcut icon" href="/images/favicon.ico"/> |
| | | <link rel="stylesheet" type="text/css" href="/print.css" /> |
| | | </head> |
| | | <body> |
| | | |
| | | <div id="header"><roundcube:object name="logo" src="/images/roundcube_logo.png" id="toplogo" border="0" alt="Logo" /></div> |
| | | |
| | | <div id="contact-details" class="boxcontent"> |
| | | <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" placeholderGroup="/images/contactgroup.png" /></div> |
| | | <roundcube:object name="contacthead" id="contacthead" /> |
| | | <br style="clear:both" /> |
| | | <roundcube:object name="contactdetails" /> |
| | | </div> |
| | | |
| | | </body> |
| | | </html> |