diff --git a/plugins/ktstandard/documentpreview/documentPreview.php b/plugins/ktstandard/documentpreview/documentPreview.php new file mode 100644 index 0000000..96911d1 --- /dev/null +++ b/plugins/ktstandard/documentpreview/documentPreview.php @@ -0,0 +1,299 @@ +_oDocument = false; + return; + } + $oDocument = Document::get($iId); + + if(PEAR::isError($oDocument)){ + $this->_oDocument = false; + return; + } + + $this->_oDocument = $oDocument; + $this->_IDocId = $iId; + $this->_iMimeId = $oDocument->getMimeTypeID(); + $this->imageMimeTypes = array(10, 27, 37, 38, 39, 71); + } + + /** + * Get the document title for the preview + * + * @return string The document title and mime icon + */ + function getTitle(){ + if($this->_oDocument === false){ + return ''._kt('Error').''; + } + GLOBAL $default; + $sIcon = ''; + + $sTitle = htmlentities($this->_oDocument->getName(), ENT_NOQUOTES, 'utf-8'); + $iLen = strlen($sTitle); + + if($iLen > 60){ + $sFull = $sTitle; + if($iLen >= 99){ + $sTitle = substr($sTitle, 0, 97).'...'; + } + $sTitle = '

'.$sTitle.'

'; + }else{ + $sTitle = '

'.$sTitle.'

'; + } + + // Get the icon + $sIcon = $this->getMimeIcon(); + + $sTitle = '
+
'.$sIcon.'
+
'.$sTitle.'
+
'; + return $sTitle; + } + + /** + * Display the mime type icon. + * + * @param unknown_type $iMimeId + * @return unknown + */ + function getMimeIcon() { + global $default; + $iMimeId = $this->_iMimeId; + + $sIconPath = $this->getIconPath(); + $sIconPath = $default->rootUrl.$sIconPath; + return "  "; + } + + /** + * If there isn't an icon for the given extension, find a generic icon for the type else return the default icon. + * + * @param string $ext + * @return string + */ + function checkForGeneric($ext) { + if(in_array($ext, array('py','php'))){ + return 'generic/source'; + } + if(in_array($ext, array('odt','sxw', 'ott', 'sxt'))){ + return 'generic/wordprocessing'; + } + if(in_array($ext, array('ods','ots', 'sxc', 'stc'))){ + return 'spreadsheet'; + } + if(in_array($ext, array('odp','otp', 'sxi', 'sti'))){ + return 'generic/pres'; + } + if(in_array($ext, array('mp3','m4a'))){ + return 'generic/sound'; + } + if(in_array($ext, array('m4v'))){ + return 'generic/video'; + } + return 'default'; + } + + /** + * Get the path to the correct icon for the mime type + * + * @return string + */ + function getIconPath() { + + $sIconPath = KTMime::getIconPath($this->_iMimeId); + + // Get mime type icon + $sIconPath = '/resources/mimetypes/big/'.$sIconPath.'.png'; + + if(!file_exists(KT_DIR.$sIconPath)){ + // See if there is an icon for the extension + $sMimeType = KTMime::getMimeTypeName($this->_iMimeId); + $aMimeInfo = KTMime::getFriendlyNameAndExtension($sMimeType); + if(!PEAR::isError($aMimeInfo) && !empty($aMimeInfo)){ + $sExt = $aMimeInfo[0]['filetypes']; + $sIconPath = '/resources/mimetypes/big/'.$sExt.'.png'; + + if(!file_exists(KT_DIR.$sIconPath)){ + $generic = $this->checkForGeneric($sExt); + // if all else fails, use the default icon + $sIconPath = '/resources/mimetypes/big/'.$generic.'.png'; + } + } + } + return $sIconPath; + } + + /** + * Render the info box content + * + * @return string + */ + function renderPreview(){ + if($this->_oDocument === false){ + return '

'._kt('A problem occured while loading the document preview.').'

'; + } + + $sInfo = $this->getMetadata(); + + return '
'.$sInfo.'
'; + } + + /** + * Create a table of the document metadata. + * Hard coded for the moment + * + * @return unknown + */ + function getMetadata(){ + /* Get document info */ + + // Filename + $sFilenameLb = _kt('Document Filename: '); + $sFilename = $this->_oDocument->getFileName(); + + // Mime type + $sMimeTypeLb = _kt('File is a: '); + $iMimeId = $this->_oDocument->getMimeTypeID(); + $sMimeType = KTMime::getMimeTypeName($iMimeId); + $sMimeType = KTMime::getFriendlyNameForString($sMimeType); + + // Version + $sVersionLb = _kt('Document Version: '); + $iVersion = $this->_oDocument->getVersion(); + + // Created by + $sCreatedByLb = _kt('Created by: '); + $iCreatorId = $this->_oDocument->getCreatorID(); + $sCreated = $this->_oDocument->getCreatedDateTime(); + $oCreator = User::get($iCreatorId); + $sCreatedBy = $oCreator->getName().' ('.$sCreated.')'; + + // Owned by + $sOwnedByLb = _kt('Owned by: '); + $iOwnedId = $this->_oDocument->getOwnerID(); + $oOwner = User::get($iOwnedId); + $sOwnedBy = $oOwner->getName(); + + // Last update by + $iModifiedId = $this->_oDocument->getModifiedUserId(); + $sLastUpdatedByLb = ''; $sLastUpdatedBy = ''; + if(!empty($iModifiedId)){ + $sLastUpdatedByLb = _kt('Last updated by: '); + $sModified = $this->_oDocument->getLastModifiedDate(); + $oModifier = User::get($iModifiedId); + $sLastUpdatedBy = $oModifier->getName().' ('.$sModified.')'; + } + + // Document type + $sDocTypeLb = _kt('Document Type: '); + $iDocTypeId = $this->_oDocument->getDocumentTypeID(); + $oDocType = DocumentType::get($iDocTypeId); + $sDocType = $oDocType->getName(); + + // Workflow + $iWFId = $this->_oDocument->getWorkflowId(); + $sWF = ''; $sWFLb = ''; + if(!empty($iWFId)){ + $sWFLb = _kt('Workflow: '); + $iWFStateId = $this->_oDocument->getWorkflowStateId(); + $oWF = KTWorkflow::get($iWFId); + $sWF = $oWF->getHumanName(); + $oWFState = KTWorkflowState::get($iWFStateId); + $sWF .= ' ('.$oWFState->getHumanName().')'; + } + + // Checked out by + $sCheckedLb = ''; $sCheckedOutBy = ''; + if($this->_oDocument->getIsCheckedOut()){ + $sCheckedLb = _kt('Checked out by: '); + $iCheckedID = $this->_oDocument->getCheckedOutUserID(); + $oCheckedUser = User::get($iCheckedID); + $sCheckedOutBy = $oCheckedUser->getName(); + } + + // Id + $sIdLb = _kt('Document ID: '); + $sId = $this->_IDocId; + + /* Create table */ + + $sInfo = " + + + + + "; + + if(!empty($sLastUpdatedBy)){ + $sInfo .= ""; + } + $sInfo .= ""; + if(!empty($sWF)){ + $sInfo .= ""; + } + if(!empty($sCheckedOutBy)){ + $sInfo .= ""; + } + + $sInfo .= " +
{$sFilenameLb}{$sFilename}
{$sMimeTypeLb}{$sMimeType}
{$sVersionLb}{$iVersion}
{$sCreatedByLb}{$sCreatedBy}
{$sOwnedByLb}{$sOwnedBy}
{$sLastUpdatedByLb}{$sLastUpdatedBy}
{$sDocTypeLb}{$sDocType}
{$sWFLb}{$sWF}
{$sCheckedLb}{$sCheckedOutBy}
{$sIdLb}{$sId}
"; + + return $sInfo; + } +} + +/** + * Get the document id and render the preview / info box + */ + +$iDocumentId = $_REQUEST['fDocumentId']; + +$oPreview = new DocumentPreview($iDocumentId); + +$sTitle = $oPreview->getTitle(); +$sContent = $oPreview->renderPreview(); + +echo $sTitle.'
'.$sContent; +exit; +?> \ No newline at end of file diff --git a/plugins/ktstandard/documentpreview/documentPreviewPlugin.php b/plugins/ktstandard/documentpreview/documentPreviewPlugin.php new file mode 100644 index 0000000..1cd858d --- /dev/null +++ b/plugins/ktstandard/documentpreview/documentPreviewPlugin.php @@ -0,0 +1,108 @@ +label = null; + + $oConfig = KTConfig::getSingleton(); + $this->sActivation = $oConfig->get('browse/previewActivation', 'onclick'); + + // Get file path + $this->sPluginPath = 'plugins/ktstandard/documentpreview'; + } + + function renderHeader($sReturnURL) { + // Get the yui libraries required + global $main; + + // Get the CSS to render the pop-up + $main->requireCSSResource($this->sPluginPath.'/resources/container.css'); + + // Get the javascript to render the document preview + $main->requireJSResource($this->sPluginPath.'/resources/preview.js'); + + return ' '; + } + + function renderData($aDataRow) { + // only _ever_ show this for documents. + if ($aDataRow["type"] === "folder") { + return ' '; + } + + $sUrl = KTUtil::kt_url().'/'.$this->sPluginPath.'/documentPreview.php'; + $sDir = KT_DIR; + $iDelay = 1000; // milliseconds + + $iDocumentId = $aDataRow['document']->getId(); + $sTitle = _kt('Preview Document'); + $sLoading = _kt('Loading...'); + + + $link = 'sActivation == 'mouse-over'){ + $sJs = "javascript: this.t = setTimeout('showInfo(\'$iDocumentId\', \'$sUrl\', \'$sDir\', \'$sLoading\')', $iDelay);"; + $link .= 'onmouseover = "'.$sJs.'" onmouseout = "clearTimeout(this.t);">'; + }else{ + $sJs = "javascript: showInfo('$iDocumentId', '$sUrl', '$sDir', '$sLoading');"; + $link .= 'onclick = "'.$sJs.'" title="'.$sTitle.'">'; + } + + return $link.$sTitle.''; + } + + function getName() { return _kt('Preview'); } +} + +class DocumentPreviewPlugin extends KTPlugin { + var $sNamespace = 'document.preview.plugin'; + + function DocumentPreviewPlugin($sFilename = null) { + $res = parent::KTPlugin($sFilename); + $this->sFriendlyName = _kt('Document Preview Plugin'); + return $res; + } + + function setup() { + $this->registerColumn(_kt('Preview File'), 'ktcore.columns.preview', 'PreviewColumn', 'documentPreviewPlugin.php'); + + require_once(KT_LIB_DIR . '/templating/templating.inc.php'); + $oTemplating =& KTTemplating::getSingleton(); + $oTemplating->addLocation('documentpreview', '/plugins/ktstandard/documentpreview/templates', 'document.preview.plugin'); + } +} + +$oPluginRegistry =& KTPluginRegistry::getSingleton(); +$oPluginRegistry->registerPlugin('DocumentPreviewPlugin', 'document.preview.plugin', __FILE__); +?> diff --git a/plugins/ktstandard/documentpreview/resources/container.css b/plugins/ktstandard/documentpreview/resources/container.css new file mode 100644 index 0000000..04dc39a --- /dev/null +++ b/plugins/ktstandard/documentpreview/resources/container.css @@ -0,0 +1,131 @@ + +/* The containing div's, in which the dialog window is created */ + +.panel { + visibility:hidden; + position:relative; + left:0px;top:0px; + font:1em Arial; + background-color:transparent; + overflow:hidden; + line-height: 1.6em; +} + +#info-preview { + padding: 10px; +} + +#info-dlg { + visibility: hidden; + position: absolute; + top: 0px; +} + +/* Styling for the dialog content */ + +.preview { + padding-right: 10px; + padding-bottom: 0px; + cursor: pointer; + height: 250px; + overflow: hidden; + clear: both; +} + +.previewhd { + padding-left: 10px; + padding-right: 10px; + overflow: hidden; + visibility: visible; +} + +.previewhd h4 { + padding-top: 0; + margin-top: 0; + line-height: 110%; +} + +.previewhd h2 { + padding-top: 0; + margin-top: 0; + font-family: "Lucida Grande", "Bitstream Vera Sans", Tahoma, sans-serif; + border-width: 0 0 0 0; + border-style: solid; + border-color: #eee; + font-size: large; + color: #333; +} + +.previewhd img { + height: 40px; + width: 40px; +} + +/* Override ExtJS CSS */ + +.x-window-tc { + background: url(../../../resources/graphics/portlet_bg.png) repeat-x 0 0; + overflow:hidden; + zoom:1; +} + +.x-window-tl { + background: url(../../../resources/graphics/portlet_corner_topleft.png) no-repeat 0 0; + padding-left:6px; + zoom:1; + z-index:1; + position:relative; +} + +.x-window-tr { + background: url(graphics/portlet_corner_topright.png) no-repeat right 0; + padding-right:6px; +} + +.x-window-bc { + background: #FFF; + zoom:1; +} +.x-window-bl { + border-left:1px solid #AFAFAF; + border-bottom:1px solid #AFAFAF; + background: #FFF; + padding-left:6px; + zoom:1; +} +.x-window-br { + border-right:1px solid #AFAFAF; + background: #FFF; + padding-right:6px; + zoom:1; +} + +.x-window-ml { + border-left:1px solid #AFAFAF; + background: #FFF; + padding-left:6px; + zoom:1; +} +.x-window-mr { + border-right:1px solid #AFAFAF; + background: #FFF; + padding-right:6px; + zoom:1; +} + +.x-window-mc { + border:1px solid #FFF; + border-top:1px solid #FFF; + padding:0; + margin:0; + font: normal 11px tahoma,arial,helvetica,sans-serif; + background:#FFF; +} + +.x-window-body { + border-left:1px solid #FFF; + border-top:1px solid #FFF; + border-bottom:1px solid #FFF; + border-right:1px solid #FFF; + background: transparent; +} diff --git a/plugins/ktstandard/documentpreview/resources/graphics/portlet_corner_topright.png b/plugins/ktstandard/documentpreview/resources/graphics/portlet_corner_topright.png new file mode 100644 index 0000000..57b9673 --- /dev/null +++ b/plugins/ktstandard/documentpreview/resources/graphics/portlet_corner_topright.png diff --git a/plugins/ktstandard/documentpreview/resources/preview.js b/plugins/ktstandard/documentpreview/resources/preview.js new file mode 100644 index 0000000..f65a54c --- /dev/null +++ b/plugins/ktstandard/documentpreview/resources/preview.js @@ -0,0 +1,73 @@ +/* + Create the preview / info box using an ExtJS Dialog window +*/ +var showInfo = function(iDocId, sUrl, sDir, loading){ + + // Create the info box container div + createPanel(); + + showIcon = Ext.get('box_'+iDocId); + dialog = new Ext.Window({ + el: 'info-dlg', + closeAction: 'destroy', + layout: 'fit', + shadow: false, + modal: true, + plain: false, + width: 500, + height: 300, + minWidth: 300, + minHeight: 250 + }); + dialog.show(showIcon.dom); + + var info = document.getElementById('info-preview'); + info.innerHTML = loading; + + Ext.Ajax.request({ + url: sUrl, + success: function(response) { + info.innerHTML = response.responseText; + }, + failure: function(response) { + alert('Error. Couldn\'t create info box.'); + }, + params: { + fDocumentId: iDocId, + kt_dir: sDir + } + }); +} + +/* + Create the container div's in which the info box will be created. + Add the div's required by the ExtJS dialog box. +*/ +var createPanel = function() { + + if(document.getElementById('info-panel')){ + destroyPanel(); + p = document.getElementById('info-panel'); + p.style.display = 'block'; + }else{ + p = document.getElementById('pageBody').appendChild(document.createElement('div')); + p.id = 'info-panel'; + } + + b = p.appendChild(document.createElement('div')); + b.id = 'info-dlg'; + b.innerHTML = '
Info Panel
'; +} + +/* + Set the container div to empty. + The display must be set to none for IE, otherwise the icons under the div aren't clickable. +*/ +var destroyPanel = function() { + if(dialog){ + dialog.destroy(); + } + p = document.getElementById('info-panel'); + p.innerHTML = ''; + p.style.display = 'none'; +} \ No newline at end of file