From: Michael M Slusarz Date: Tue, 11 Nov 2008 03:42:57 +0000 (-0700) Subject: Message display tweaking. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=150f95bf869362429ec12a10ff572a337407a92d;p=horde.git Message display tweaking. IMP 5 now can successfully display simple messages containing text/plain and text/html data. Playing around with the formatting a bit, but my desire is to *always* show the Mime part summary for every part we can display inline and *never* show inline parts in the attachment list. This is important because there is no other way to strip/download/display in a new window the parts that are shown inline. This goes back to the way we used to display things long ago (IMP 3), but that is probably the better way to do this. However, this has much work that can be done to it - for now, just need to be able to display the parts so I can continue implementing other things. --- diff --git a/imp/lib/Contents.php b/imp/lib/Contents.php index d67299984..452953fec 100644 --- a/imp/lib/Contents.php +++ b/imp/lib/Contents.php @@ -25,6 +25,7 @@ class IMP_Contents const SUMMARY_IMAGE_SAVE = 256; const SUMMARY_STRIP_LINK = 512; const SUMMARY_DOWNLOAD_ALL = 1024; + const SUMMARY_TEXTBODY = 2048; /** * The IMAP index of the message. @@ -321,11 +322,11 @@ class IMP_Contents */ public function findBody($subtype = null) { - foreach ($this->_message->contentTypeMap() as $key => $val) { - if ((strpos($val, 'text/') === 0) && - (intval($key) == 1) && - (is_null($subtype) || (substr($val, 5) == $subtype))) { - return $key; + foreach ($this->_message->contentTypeMap() as $mime_id => $mime_type) { + if ((strpos($mime_type, 'text/') === 0) && + (intval($mime_id) == 1) && + (is_null($subtype) || (substr($mime_type, 5) == $subtype))) { + return $mime_id; } } @@ -410,6 +411,9 @@ class IMP_Contents * * IMP_Contents::SUMMARY_DOWNLOAD_ALL * Output: info = 'download_all' + * + * IMP_Contents::SUMMARY_TEXTBODY + * Output: info = 'textbody' * * * @return array An array with two keys: 'info' and 'parts'. See above @@ -421,24 +425,15 @@ class IMP_Contents $info = array( 'download_all' => array(), 'has' => array(), - 'render' => array() + 'render' => array(), + 'textbody' => null ); $parts = array(); // Cache some settings before we enter the loop. $download_zip = (($mask & self::SUMMARY_DOWNLOAD_ZIP) && Util::extensionExists('zlib')); - if ($download_zip) { - $zip_img = Horde::img('compressed.png', _("Download in .zip Format"), null, $GLOBALS['registry']->getImageDir('horde') . '/mime'); - } - - if (($mask && self::SUMMARY_IMAGE_SAVE) && - $GLOBALS['registry']->hasMethod('images/selectGalleries') && - ($image_app = $GLOBALS['registry']->hasMethod('images/saveImage'))) { - $image_img = '' . _('; - } else { - $image_img = null; - } - + $img_save = (($mask && self::SUMMARY_IMAGE_SAVE) && + $GLOBALS['registry']->hasMethod('images/selectGalleries')); if ($mask && self::SUMMARY_STRIP_LINK) { $message_token = IMP::getRequestToken('imp.impcontents'); } @@ -454,10 +449,18 @@ class IMP_Contents 'render_info' => false, 'render_inline' => false, 'size' => null, - 'strip' => null + 'strip' => null, + 'textbody' => null ); $part = &$parts[$mime_id]; + if (($mask & self::SUMMARY_TEXTBODY) && + is_null($info['textbody']) && + (strpos($mime_type, 'text/') === 0) && + (intval($mime_id) == 1)) { + $info['textbody'] = $mime_id; + } + $mime_part = $this->getMIMEPart($mime_id, array('nocontents' => true, 'nodecode' => true)); /* If this is an attachment that has no specific MIME type info, @@ -510,7 +513,7 @@ class IMP_Contents } /* Get part's icon. */ - $part['icon'] = ($mask & self::SUMMARY_ICON) ? Horde::img(Horde_Mime_Viewer::getIcon($mime_type), '', array('title' => $mime_type)) : null; + $part['icon'] = ($mask & self::SUMMARY_ICON) ? Horde::img(Horde_Mime_Viewer::getIcon($mime_type), '', array('title' => $mime_type), '') : null; /* Get part's description. */ $description = $mime_part->getDescription(true); @@ -527,7 +530,7 @@ class IMP_Contents /* Download column. */ if (($mask & self::SUMMARY_DOWNLOAD) && (is_null($part['bytes']) || $part['bytes'])) { - $part['download'] = $this->linkView($mime_part, 'download_attach', '', array('class' => 'download', 'dload' => true, 'jstext' => sprintf(_("Download %s"), $description))); + $part['download'] = $this->linkView($mime_part, 'download_attach', '', array('class' => 'downloadAtc', 'dload' => true, 'jstext' => sprintf(_("Download %s"), $description))); $info['has']['download'] = true; } @@ -536,20 +539,19 @@ class IMP_Contents if ($download_zip && ($part['bytes'] > 204800) && !in_array($mime_type, array('application/zip', 'application/x-zip-compressed'))) { - $part['download_zip'] = $this->linkView($mime_part, 'download_attach', $zip_img, array('dload' => true, 'jstext' => sprintf(_("Download %s in .zip Format"), $mime_part->getDescription(true)), 'params' => array('zip' => 1))); + $part['download_zip'] = $this->linkView($mime_part, 'download_attach', null, array('class' => 'downloadZipAtc', 'dload' => true, 'jstext' => sprintf(_("Download %s in .zip Format"), $mime_part->getDescription(true)), 'params' => array('zip' => 1))); $info['has']['download_zip'] = true; } /* Display the image save link if the required registry calls are * present. */ - if (!is_null($image_img) && - ($mime_part->getPrimaryType() == 'image')) { + if ($img_save && ($mime_part->getPrimaryType() == 'image')) { if (empty($info['has']['img_save'])) { Horde::addScriptFile('prototype.js', 'horde', true); Horde::addScriptFile('popup.js', 'imp', true); $info['has']['img_save'] = true; } - $part['img_save'] = Horde::link('#', _("Save Image in Gallery"), null, null, IMP::popupIMPString('saveimage.php', array('index' => ($this->_index . IMP::IDX_SEP . $this->_mailbox), 'id' => $mime_id), 450, 200) . "return false;") . $image_img . ''; + $part['img_save'] = Horde::link('#', _("Save Image in Gallery"), 'saveImgAtc', null, IMP::popupIMPString('saveimage.php', array('index' => ($this->_index . IMP::IDX_SEP . $this->_mailbox), 'id' => $mime_id), 450, 200) . "return false;") . ''; } /* Strip the Attachment? */ @@ -557,12 +559,12 @@ class IMP_Contents // TODO: No stripping of RFC 822 parts. $url = Util::removeParameter(Horde::selfUrl(true), array('actionID', 'imapid', 'index')); $url = Util::addParameter($url, array('actionID' => 'strip_attachment', 'imapid' => $mime_id, 'index' => $this->_index, 'message_token' => $message_token)); - $part['strip'] = Horde::link($url, _("Strip Attachment"), null, null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete this attachment?")) . "');") . Horde::img('delete.png', _("Strip Attachment"), null, $GLOBALS['registry']->getImageDir('horde')) . ''; + $part['strip'] = Horde::link($url, _("Strip Attachment"), 'stripAtc', null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete this attachment?")) . "');") . ''; $info['has']['strip'] = true; } if ($mask && self::SUMMARY_DOWNLOAD_ALL) { - if ($download = $this->isDownloadable($mime_part)) { + if ($download = $this->isAttachment($mime_part)) { $info['download_all'][] = $mime_id; } } @@ -668,27 +670,31 @@ class IMP_Contents } /** - * Determines if a MIME part is downloadable. + * Determines if a MIME part is an attachment. + * For IMP's purposes, an attachment is any MIME part that can be + * downloaded by itself (i.e. all the data needed to view the part is + * contained within the download data). * * @param Horde_Mime_Part $mime_part The MIME part object. * - * @return boolean True if downloadable. + * @return boolean True if an attachment. */ - public function isDownloadable($mime_part) + public function isAttachment($mime_part) { $type = $mime_part->getType(); - $ptype = $mime_part->getPrimaryType(); - if ($ptype == 'message') { + switch ($mime_part->getPrimaryType()) { + case 'message': return ($type == 'message/rfc822'); - } - return ((($mime_part->getDisposition() == 'attachment') || - $mime_part->getContentTypeParameter('name')) && - ($ptype != 'multipart') && - ($type != 'application/applefile') && + case 'multipart': + return false; + + default: + return (($type != 'application/applefile') && ($type != 'application/x-pkcs7-signature') && ($type != 'application/pkcs7-signature')); + } } /** diff --git a/imp/message.php b/imp/message.php index c63c00d00..d6474684c 100644 --- a/imp/message.php +++ b/imp/message.php @@ -251,7 +251,8 @@ if (is_a($imp_contents, 'PEAR_Error')) { $contents_mask = IMP_Contents::SUMMARY_RENDER | IMP_Contents::SUMMARY_BYTES | IMP_Contents::SUMMARY_SIZE | - IMP_Contents::SUMMARY_ICON; + IMP_Contents::SUMMARY_ICON | + IMP_Contents::SUMMARY_TEXTBODY; if ($printer_friendly) { $contents_mask |= IMP_Contents::SUMMARY_DESCRIP_NOLINK; } else { @@ -631,11 +632,6 @@ if (!$printer_friendly) { echo $a_template->fetch(IMP_TEMPLATES . '/message/navbar_actions.html'); } -$atc_display = $prefs->getValue('attachment_display'); -$show_parts = (($atc_display == 'list') || ($atc_display == 'both')); -$downloadall_link = empty($summary['info']['download_all']) - ? false - : $imp_contents->urlView($imp_contents->getMIMEMessage(), 'download_all', array('params' => array('download_ids' => serialize($summary['info']['download_all'])))); $hdrs = array(); $i = 1; @@ -655,35 +651,52 @@ foreach ($all_list_headers as $head => $val) { $hdrs[] = array('name' => $list_headers_lookup[$head], 'val' => $val, 'i' => (++$i % 2)); } +/* Show attachment information in headers? */ +$download_all = $show_atc = false; +reset($summary['parts']); if (!empty($summary['parts']) && - ($show_parts || ($downloadall_link && !$printer_friendly))) { + ((count($summary['parts']) > 1) || + (key($summary['parts']) != $summary['info']['textbody']))) { + $atc_display = $prefs->getValue('attachment_display'); + $show_atc = (($atc_display == 'list') || ($atc_display == 'both')); + $download_all = (empty($summary['info']['download_all']) || !$printer_friendly) + ? false + : $imp_contents->urlView($imp_contents->getMIMEMessage(), 'download_all', array('params' => array('download_ids' => serialize($summary['info']['download_all'])))); +} + +$part_info = array('icon', 'description', 'type', 'size'); +foreach (array('download', 'download_zip', 'img_save', 'strip') as $val) { + if (isset($summary['info']['has'][$val])) { + $part_info[] = $val; + } +} + +if ($show_atc || $download_all) { $val = ''; - if ($show_parts) { - $part_info = array('icon', 'id', 'description', 'type', 'size'); - foreach (array('download', 'download_zip', 'img_save', 'strip') as $val) { - if (isset($summary['info']['has'][$val])) { - $part_info[] = $val; - } - } - $tmp = array(''); + + if ($show_atc) { + $tmp = array(); foreach ($summary['parts'] as $key => $val) { - $tmp[] = ''; - foreach ($part_info as $val2) { - $tmp[] = ''; + if ($key != $summary['info']['textbody']) { + $tmp[] = ''; + foreach ($part_info as $val2) { + $tmp[] = ''; + } + $tmp[] = ''; } - $tmp[] = ''; } - $tmp[] = '
' . $val[$val2] . '
' . $val[$val2] . '
'; - $val = implode('', $tmp); + $val = '' . implode('', $tmp) . '
'; } - if ($downloadall_link && !$printer_friendly) { - $val .= Horde::link($downloadall_link, _("Download All Attachments (in .zip file)")) . _("Download All Attachments (in .zip file)") . ' ' . Horde::img('compressed.png', _("Download All Attachments (in .zip file)"), '', $registry->getImageDir('horde') . '/mime') . ''; + + if ($download_all) { + $val .= Horde::link($download_all, _("Download All Attachments (in .zip file)")) . _("Download All Attachments (in .zip file)") . ' ' . Horde::img('compressed.png', _("Download All Attachments (in .zip file)"), '', $registry->getImageDir('horde') . '/mime') . ''; if ($prefs->getValue('strip_attachments')) { $url = Util::addParameter(Util::removeParameter(Horde::selfUrl(true), array('actionID')), array('actionID' => 'strip_all', 'message_token' => $message_token)); $val .= '
' . Horde::link($url, _("Strip All Attachments"), null, null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete all attachments?")) . "');") . _("Strip All Attachments") . ' ' . Horde::img('delete.png', _("Strip Attachments"), null, $registry->getImageDir('horde')) . ''; } } - $hdrs[] = array('name' => _("Part(s)"), 'val' => $val, 'i' => (++$i % 2)); + + $hdrs[] = array('name' => _("Attachment(s)"), 'val' => $val, 'i' => (++$i % 2)); } if ($printer_friendly && !empty($conf['print']['add_printedby'])) { @@ -691,8 +704,31 @@ if ($printer_friendly && !empty($conf['print']['add_printedby'])) { } $m_template->set('headers', $hdrs); -// TODO -//$m_template->set('msgtext', reset($inline_parts)); + +/* Build body text. */ +$msgtext = ''; +foreach ($summary['info']['render'] as $mime_id => $type) { + $render_part = $imp_contents->renderMIMEPart($mime_id, $type); + $ptr = $summary['parts'][$mime_id]; + $tmp_part = $tmp_status = array(); + + foreach ($part_info as $val) { + $tmp[] = $ptr[$val]; + } + + foreach ($render_part['status'] as $val) { + // TODO: status msgs. + $tmp_status[] = $render_part['status']['text']; + } + + $msgtext .= '' . + implode(' ', $tmp) . + '' . + implode(' ', $tmp_status) . + $render_part['data']; +} +$m_template->set('msgtext', $msgtext); + echo $m_template->fetch(IMP_TEMPLATES . '/message/message.html'); if (!$printer_friendly) { diff --git a/imp/templates/message/message.html b/imp/templates/message/message.html index fac4278f5..b2b641fad 100644 --- a/imp/templates/message/message.html +++ b/imp/templates/message/message.html @@ -10,7 +10,5 @@
- - -
+
diff --git a/imp/themes/graphics/delete.png b/imp/themes/graphics/delete.png new file mode 100644 index 000000000..f3076bc9f Binary files /dev/null and b/imp/themes/graphics/delete.png differ diff --git a/imp/themes/graphics/download.png b/imp/themes/graphics/download.png new file mode 100644 index 000000000..de62aaeb0 Binary files /dev/null and b/imp/themes/graphics/download.png differ diff --git a/imp/themes/graphics/gallery.png b/imp/themes/graphics/gallery.png new file mode 100644 index 000000000..f05b02958 Binary files /dev/null and b/imp/themes/graphics/gallery.png differ diff --git a/imp/themes/screen.css b/imp/themes/screen.css index 89e21b7c9..6ccc0ff0f 100644 --- a/imp/themes/screen.css +++ b/imp/themes/screen.css @@ -129,6 +129,9 @@ ul.msgactions, ul.msgactions ul { background: #fff; padding: 8px; } +.messageBody div.fixed { + padding-top: 8px; +} /* Search page styling. */ form#search div { @@ -382,3 +385,53 @@ ul.nav-audio { .largeaddrlist:hover { text-decoration: underline; } + +/* MIME styles. */ +.mimeStatusMessage, .mimeStatusWarning, .mimeHeaders, .mimePartInfo { + padding: 1px; + margin-bottom: 2px; + font-size: 90%; +} +.mimeStatusMessage { + color: #000; + background: #ffc; + border: 1px solid #fff760; + width: 100%; +} +.mimeStatusWarning { + border: 1px solid #800; + background: #e81222; + color: #fff; + width: 100%; +} +.mimeHeaders { + border: 1px solid #ccc; + background: #f9f9f9; + width: 100%; + font-family: "Lucida Console",Courier,"Courier New"; +} +.mimePartInfo { + border: 1px solid #ccc; + background: #f9f9f9; + padding-top: 4px; + padding-bottom: 3px; +} +.mimePartInfo img { + vertical-align: bottom; +} +.downloadAtc { + padding: 2px 20px 2px 0; + background: transparent url("graphics/download.png") center right no-repeat; +} +.downloadZipAtc { + padding: 2px 20px 2px 0; + background: transparent url("graphics/mime/compressed.png") center right no-repeat; +} +.saveImgAtc { + padding: 2px 20px 2px 0; + background: transparent url("graphics/gallery.png") center right no-repeat; +} +.stripAtc { + padding: 2px 20px 2px 0; + background: transparent url("graphics/delete.png") center right no-repeat; +}