Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageManager.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageManager.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageManager.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageManager.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,664 @@
+<?php
+/**
+ * ImageManager, list images, directories, and thumbnails.
+ * @author $Author: ray $
+ * @version $Id: ImageManager.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+require_once('../ImageManager/Classes/Files.php');
+
+// uncomment to turn on debugging
+
+// _ddtOn();
+
+/**
+ * ImageManager Class.
+ * @author $Author: ray $
+ * @version $Id: ImageManager.php 709 2007-01-30 23:22:04Z ray $
+ */
+class ImageManager
+{
+ /**
+ * Configuration array.
+ */
+ var $config;
+
+ /**
+ * Array of directory information.
+ */
+ var $dirs;
+
+ /**
+ * Constructor. Create a new Image Manager instance.
+ * @param array $config configuration array, see config.inc.php
+ */
+ function ImageManager($config)
+ {
+ $this->config = $config;
+ }
+
+ /**
+ * Get the images base directory.
+ * @return string base dir, see config.inc.php
+ */
+ function getImagesDir()
+ {
+ Return $this->config['images_dir'];
+ }
+
+ /**
+ * Get the images base URL.
+ * @return string base url, see config.inc.php
+ */
+ function getImagesURL()
+ {
+ Return $this->config['images_url'];
+ }
+
+ function isValidBase()
+ {
+ return is_dir($this->getImagesDir());
+ }
+
+ /**
+ * Get the tmp file prefix.
+ * @return string tmp file prefix.
+ */
+ function getTmpPrefix()
+ {
+ Return $this->config['tmp_prefix'];
+ }
+
+ /**
+ * Get the sub directories in the base dir.
+ * Each array element contain
+ * the relative path (relative to the base dir) as key and the
+ * full path as value.
+ * @return array of sub directries
+ * <code>array('path name' => 'full directory path', ...)</code>
+ */
+ function getDirs()
+ {
+ if(is_null($this->dirs))
+ {
+ $dirs = $this->_dirs($this->getImagesDir(),'/');
+ ksort($dirs);
+ $this->dirs = $dirs;
+ }
+ return $this->dirs;
+ }
+
+ /**
+ * Recursively travese the directories to get a list
+ * of accessable directories.
+ * @param string $base the full path to the current directory
+ * @param string $path the relative path name
+ * @return array of accessiable sub-directories
+ * <code>array('path name' => 'full directory path', ...)</code>
+ */
+ function _dirs($base, $path)
+ {
+ $base = Files::fixPath($base);
+ $dirs = array();
+
+ if($this->isValidBase() == false)
+ return $dirs;
+
+ $d = @dir($base);
+
+ while (false !== ($entry = $d->read()))
+ {
+ //If it is a directory, and it doesn't start with
+ // a dot, and if is it not the thumbnail directory
+ if(is_dir($base.$entry)
+ && substr($entry,0,1) != '.'
+ && $this->isThumbDir($entry) == false)
+ {
+ $relative = Files::fixPath($path.$entry);
+ $fullpath = Files::fixPath($base.$entry);
+ $dirs[$relative] = $fullpath;
+ $dirs = array_merge($dirs, $this->_dirs($fullpath, $relative));
+ }
+ }
+ $d->close();
+
+ Return $dirs;
+ }
+
+ /**
+ * Get all the files and directories of a relative path.
+ * @param string $path relative path to be base path.
+ * @return array of file and path information.
+ * <code>array(0=>array('relative'=>'fullpath',...), 1=>array('filename'=>fileinfo array(),...)</code>
+ * fileinfo array: <code>array('url'=>'full url',
+ * 'relative'=>'relative to base',
+ * 'fullpath'=>'full file path',
+ * 'image'=>imageInfo array() false if not image,
+ * 'stat' => filestat)</code>
+ */
+ function getFiles($path)
+ {
+ $files = array();
+ $dirs = array();
+
+ if($this->isValidBase() == false)
+ return array($files,$dirs);
+
+ $path = Files::fixPath($path);
+ $base = Files::fixPath($this->getImagesDir());
+ $fullpath = Files::makePath($base,$path);
+
+
+ $d = @dir($fullpath);
+
+ while (false !== ($entry = $d->read()))
+ {
+ //not a dot file or directory
+ if(substr($entry,0,1) != '.')
+ {
+ if(is_dir($fullpath.$entry)
+ && $this->isThumbDir($entry) == false)
+ {
+ $relative = Files::fixPath($path.$entry);
+ $full = Files::fixPath($fullpath.$entry);
+ $count = $this->countFiles($full);
+ $dirs[$relative] = array('fullpath'=>$full,'entry'=>$entry,'count'=>$count);
+ }
+ else if(is_file($fullpath.$entry) && $this->isThumb($entry)==false && $this->isTmpFile($entry) == false)
+ {
+ $img = $this->getImageInfo($fullpath.$entry);
+
+ if(!(!is_array($img)&&$this->config['validate_images']))
+ {
+ $file['url'] = Files::makePath($this->config['base_url'],$path).$entry;
+ $file['relative'] = $path.$entry;
+ $file['fullpath'] = $fullpath.$entry;
+ $file['image'] = $img;
+ $file['stat'] = stat($fullpath.$entry);
+ $files[$entry] = $file;
+ }
+ }
+ }
+ }
+ $d->close();
+ ksort($dirs);
+ ksort($files);
+
+ Return array($dirs, $files);
+ }
+
+ /**
+ * Count the number of files and directories in a given folder
+ * minus the thumbnail folders and thumbnails.
+ */
+ function countFiles($path)
+ {
+ $total = 0;
+
+ if(is_dir($path))
+ {
+ $d = @dir($path);
+
+ while (false !== ($entry = $d->read()))
+ {
+ //echo $entry."<br>";
+ if(substr($entry,0,1) != '.'
+ && $this->isThumbDir($entry) == false
+ && $this->isTmpFile($entry) == false
+ && $this->isThumb($entry) == false)
+ {
+ $total++;
+ }
+ }
+ $d->close();
+ }
+ return $total;
+ }
+
+ /**
+ * Get image size information.
+ * @param string $file the image file
+ * @return array of getImageSize information,
+ * false if the file is not an image.
+ */
+ function getImageInfo($file)
+ {
+ Return @getImageSize($file);
+ }
+
+ /**
+ * Check if the file contains the thumbnail prefix.
+ * @param string $file filename to be checked
+ * @return true if the file contains the thumbnail prefix, false otherwise.
+ */
+ function isThumb($file)
+ {
+ $len = strlen($this->config['thumbnail_prefix']);
+ if(substr($file,0,$len)==$this->config['thumbnail_prefix'])
+ Return true;
+ else
+ Return false;
+ }
+
+ /**
+ * Check if the given directory is a thumbnail directory.
+ * @param string $entry directory name
+ * @return true if it is a thumbnail directory, false otherwise
+ */
+ function isThumbDir($entry)
+ {
+ if($this->config['thumbnail_dir'] == false
+ || strlen(trim($this->config['thumbnail_dir'])) == 0)
+ Return false;
+ else
+ Return ($entry == $this->config['thumbnail_dir']);
+ }
+
+ /**
+ * Check if the given file is a tmp file.
+ * @param string $file file name
+ * @return boolean true if it is a tmp file, false otherwise
+ */
+ function isTmpFile($file)
+ {
+ $len = strlen($this->config['tmp_prefix']);
+ if(substr($file,0,$len)==$this->config['tmp_prefix'])
+ Return true;
+ else
+ Return false;
+ }
+
+ /**
+ * For a given image file, get the respective thumbnail filename
+ * no file existence check is done.
+ * @param string $fullpathfile the full path to the image file
+ * @return string of the thumbnail file
+ */
+ function getThumbName($fullpathfile)
+ {
+ $path_parts = pathinfo($fullpathfile);
+
+ $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+
+ if( strlen(trim($this->config['thumbnail_dir'])) == 0 || $this->config['safe_mode'] == true)
+ {
+ Return Files::makeFile($path_parts['dirname'],$thumbnail);
+ }
+ else
+ {
+ $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+ if(!is_dir($path))
+ Files::createFolder($path);
+ Return Files::makeFile($path,$thumbnail);
+ }
+ }
+
+ /**
+ * Similar to getThumbName, but returns the URL, base on the
+ * given base_url in config.inc.php
+ * @param string $relative the relative image file name,
+ * relative to the base_dir path
+ * @return string the url of the thumbnail
+ */
+ function getThumbURL($relative)
+ {
+
+ _ddt( __FILE__, __LINE__, "getThumbURL(): relative is '$relative'" );
+
+ $path_parts = pathinfo($relative);
+ $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+ if($path_parts['dirname']=='\\') $path_parts['dirname']='/';
+
+ if($this->config['safe_mode'] == true
+ || strlen(trim($this->config['thumbnail_dir'])) == 0)
+ {
+ Return Files::makeFile($this->getImagesURL(),$thumbnail);
+ }
+ else
+ {
+ if(strlen(trim($this->config['thumbnail_dir'])) > 0)
+ {
+ $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+ $url_path = Files::makePath($this->getImagesURL(), $path);
+
+ _ddt( __FILE__, __LINE__, "getThumbURL(): url_path is '$url_path'" );
+
+ Return Files::makeFile($url_path,$thumbnail);
+ }
+ else //should this ever happen?
+ {
+ //error_log('ImageManager: Error in creating thumbnail url');
+ }
+
+ }
+ }
+
+
+ /**
+ * For a given image file, get the respective resized filename
+ * no file existence check is done.
+ * @param string $fullpathfile the full path to the image file
+ * @param integer $width the intended width
+ * @param integer $height the intended height
+ * @param boolean $mkDir whether to attempt to make the resized_dir if it doesn't exist
+ * @return string of the resized filename
+ */
+ function getResizedName($fullpathfile, $width, $height, $mkDir = TRUE)
+ {
+ $path_parts = pathinfo($fullpathfile);
+
+ $thumbnail = $this->config['resized_prefix']."_{$width}x{$height}_{$path_parts['basename']}";
+
+ if( strlen(trim($this->config['resized_dir'])) == 0 || $this->config['safe_mode'] == true )
+ {
+ Return Files::makeFile($path_parts['dirname'],$thumbnail);
+ }
+ else
+ {
+ $path = Files::makePath($path_parts['dirname'],$this->config['resized_dir']);
+ if($mkDir && !is_dir($path))
+ Files::createFolder($path);
+ Return Files::makeFile($path,$thumbnail);
+ }
+ }
+
+ /**
+ * Check if the given path is part of the subdirectories
+ * under the base_dir.
+ * @param string $path the relative path to be checked
+ * @return boolean true if the path exists, false otherwise
+ */
+ function validRelativePath($path)
+ {
+ $dirs = $this->getDirs();
+ if($path == '/')
+ Return true;
+ //check the path given in the url against the
+ //list of paths in the system.
+ for($i = 0; $i < count($dirs); $i++)
+ {
+ $key = key($dirs);
+ //we found the path
+ if($key == $path)
+ Return true;
+
+ next($dirs);
+ }
+ Return false;
+ }
+
+ /**
+ * Process uploaded files, assumes the file is in
+ * $_FILES['upload'] and $_POST['dir'] is set.
+ * The dir must be relative to the base_dir and exists.
+ * If 'validate_images' is set to true, only file with
+ * image dimensions will be accepted.
+ * @return null
+ */
+ function processUploads()
+ {
+ if($this->isValidBase() == false)
+ return;
+
+ $relative = null;
+
+ if(isset($_POST['dir']))
+ $relative = rawurldecode($_POST['dir']);
+ else
+ return;
+
+ //check for the file, and must have valid relative path
+ if(isset($_FILES['upload']) && $this->validRelativePath($relative))
+ {
+ $this->_processFiles($relative, $_FILES['upload']);
+ }
+ }
+
+ /**
+ * Process upload files. The file must be an
+ * uploaded file. If 'validate_images' is set to
+ * true, only images will be processed. Any duplicate
+ * file will be renamed. See Files::copyFile for details
+ * on renaming.
+ * @param string $relative the relative path where the file
+ * should be copied to.
+ * @param array $file the uploaded file from $_FILES
+ * @return boolean true if the file was processed successfully,
+ * false otherwise
+ */
+ function _processFiles($relative, $file)
+ {
+
+ if($file['error']!=0)
+ {
+ Return false;
+ }
+
+ if(!is_file($file['tmp_name']))
+ {
+ Return false;
+ }
+
+ if(!is_uploaded_file($file['tmp_name']))
+ {
+ Files::delFile($file['tmp_name']);
+ Return false;
+ }
+
+
+ if($this->config['validate_images'] == true)
+ {
+ $imgInfo = @getImageSize($file['tmp_name']);
+ if(!is_array($imgInfo))
+ {
+ Files::delFile($file['tmp_name']);
+ Return false;
+ }
+ }
+
+ //now copy the file
+ $path = Files::makePath($this->getImagesDir(),$relative);
+ $result = Files::copyFile($file['tmp_name'], $path, $file['name']);
+
+ //no copy error
+ if(!is_int($result))
+ {
+ Files::delFile($file['tmp_name']);
+ Return true;
+ }
+
+ //delete tmp files.
+ Files::delFile($file['tmp_name']);
+ Return false;
+ }
+
+ /**
+ * Get the URL of the relative file.
+ * basically appends the relative file to the
+ * base_url given in config.inc.php
+ * @param string $relative a file the relative to the base_dir
+ * @return string the URL of the relative file.
+ */
+ function getFileURL($relative)
+ {
+ Return Files::makeFile($this->getImagesURL(),$relative);
+ }
+
+ /**
+ * Get the fullpath to a relative file.
+ * @param string $relative the relative file.
+ * @return string the full path, .ie. the base_dir + relative.
+ */
+ function getFullPath($relative)
+ {
+ Return Files::makeFile($this->getImagesDir(),$relative);;
+ }
+
+ /**
+ * Get the default thumbnail.
+ * @return string default thumbnail, empty string if
+ * the thumbnail doesn't exist.
+ */
+ function getDefaultThumb()
+ {
+
+ // FIXME: hack
+
+ Return $this->config['default_thumbnail'];
+
+ if(is_file($this->config['default_thumbnail']))
+ {
+ Return $this->config['default_thumbnail'];
+ }
+ else
+ Return '';
+ }
+
+
+ /**
+ * Get the thumbnail url to be displayed.
+ * If the thumbnail exists, and it is up-to-date
+ * the thumbnail url will be returns. If the
+ * file is not an image, a default image will be returned.
+ * If it is an image file, and no thumbnail exists or
+ * the thumbnail is out-of-date (i.e. the thumbnail
+ * modified time is less than the original file)
+ * then a thumbs.php?img=filename.jpg is returned.
+ * The thumbs.php url will generate a new thumbnail
+ * on the fly. If the image is less than the dimensions
+ * of the thumbnails, the image will be display instead.
+ * @param string $relative the relative image file.
+ * @return string the url of the thumbnail, be it
+ * actually thumbnail or a script to generate the
+ * thumbnail on the fly.
+ */
+ function getThumbnail($relative)
+ {
+
+ global $IMConfig;
+
+ _ddt( __FILE__, __LINE__, "getThumbnail(): top with '$relative'" );
+
+ $fullpath = Files::makeFile($this->getImagesDir(),$relative);
+
+ //not a file???
+ if(!is_file($fullpath))
+ Return $this->getDefaultThumb();
+
+ $imgInfo = @getImageSize($fullpath);
+
+ //not an image
+ if(!is_array($imgInfo))
+ Return $this->getDefaultThumb();
+
+ //the original image is smaller than thumbnails,
+ //so just return the url to the original image.
+ if ($imgInfo[0] <= $this->config['thumbnail_width']
+ && $imgInfo[1] <= $this->config['thumbnail_height'])
+ Return $this->getFileURL($relative);
+
+ $thumbnail = $this->getThumbName($fullpath);
+
+ //check for thumbnails, if exists and
+ // it is up-to-date, return the thumbnail url
+ if(is_file($thumbnail))
+ {
+ if(filemtime($thumbnail) >= filemtime($fullpath))
+ {
+ _ddt( __FILE__, __LINE__, "getThumbnail(): returning url '" . $this->getThumbURL($relative) . "'" );
+
+ Return $this->getThumbURL($relative);
+ }
+ }
+
+ //well, no thumbnail was found, so ask the thumbs.php
+ //to generate the thumbnail on the fly.
+ Return $IMConfig['backend_url'] . '__function=thumbs&img='.rawurlencode($relative);
+ }
+
+ /**
+ * Delete and specified files.
+ * @return boolean true if delete, false otherwise
+ */
+ function deleteFiles()
+ {
+ if(isset($_GET['delf']))
+ $this->_delFile(rawurldecode($_GET['delf']));
+ }
+
+ /**
+ * Delete and specified directories.
+ * @return boolean true if delete, false otherwise
+ */
+ function deleteDirs()
+ {
+ if(isset($_GET['deld']))
+ return $this->_delDir(rawurldecode($_GET['deld']));
+ else
+ Return false;
+ }
+
+ /**
+ * Delete the relative file, and any thumbnails.
+ * @param string $relative the relative file.
+ * @return boolean true if deleted, false otherwise.
+ */
+ function _delFile($relative)
+ {
+ $fullpath = Files::makeFile($this->getImagesDir(),$relative);
+
+ //check that the file is an image
+ if($this->config['validate_images'] == true)
+ {
+ if(!is_array($this->getImageInfo($fullpath)))
+ return false; //hmmm not an Image!!???
+ }
+
+ $thumbnail = $this->getThumbName($fullpath);
+
+ if(Files::delFile($fullpath))
+ Return Files::delFile($thumbnail);
+ else
+ Return false;
+ }
+
+ /**
+ * Delete directories recursively.
+ * @param string $relative the relative path to be deleted.
+ * @return boolean true if deleted, false otherwise.
+ */
+ function _delDir($relative)
+ {
+ $fullpath = Files::makePath($this->getImagesDir(),$relative);
+ if($this->countFiles($fullpath) <= 0)
+ return Files::delFolder($fullpath,true); //delete recursively.
+ else
+ Return false;
+ }
+
+ /**
+ * Create new directories.
+ * If in safe_mode, nothing happens.
+ * @return boolean true if created, false otherwise.
+ */
+ function processNewDir()
+ {
+ if($this->config['safe_mode'] == true)
+ Return false;
+
+ if(isset($_GET['newDir']) && isset($_GET['dir']))
+ {
+ $newDir = rawurldecode($_GET['newDir']);
+ $dir = rawurldecode($_GET['dir']);
+ $path = Files::makePath($this->getImagesDir(),$dir);
+ $fullpath = Files::makePath($path, Files::escape($newDir));
+ if(is_dir($fullpath))
+ Return false;
+
+ Return Files::createFolder($fullpath);
+ }
+ }
+}
+
+?>
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/NetPBM.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/NetPBM.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/NetPBM.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/NetPBM.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,257 @@
+<?php
+/***********************************************************************
+** Title.........: NetPBM Driver
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <[email protected]>
+** Filename......: NetPBM.php
+** Last changed..: 30 Aug 2003
+** Notes.........: Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | [email protected] so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <[email protected]> |
+// +----------------------------------------------------------------------+
+//
+// $Id: NetPBM.php 709 2007-01-30 23:22:04Z ray $
+//
+// Image Transformation interface using command line NetPBM
+
+require_once "../ImageManager/Classes/Transform.php";
+
+Class Image_Transform_Driver_NetPBM extends Image_Transform
+{
+
+ /**
+ * associative array commands to be executed
+ * @var array
+ */
+ var $command = array();
+
+ /**
+ * Class Constructor
+ */
+ function Image_Transform_Driver_NetPBM()
+ {
+ $this->uid = md5($_SERVER['REMOTE_ADDR']);
+
+ return true;
+ } // End function Image_NetPBM
+
+ /**
+ * Load image
+ *
+ * @param string filename
+ *
+ * @return mixed none or a PEAR error object on error
+ * @see PEAR::isError()
+ */
+ function load($image)
+ {
+ //echo $image;
+ $this->image = $image;
+ $this->_get_image_details($image);
+ } // End load
+
+ /**
+ * Resizes the image
+ *
+ * @return none
+ * @see PEAR::isError()
+ */
+ function _resize($new_x, $new_y)
+ {
+ // there's no technical reason why resize can't be called multiple
+ // times...it's just silly to do so
+
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+ "pnmscale -width $new_x -height $new_y";
+
+ $this->_set_new_x($new_x);
+ $this->_set_new_y($new_y);
+ } // End resize
+
+ /**
+ * Crop the image
+ *
+ * @param int $crop_x left column of the image
+ * @param int $crop_y top row of the image
+ * @param int $crop_width new cropped image width
+ * @param int $crop_height new cropped image height
+ */
+ function crop($crop_x, $crop_y, $crop_width, $crop_height)
+ {
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+ "pnmcut -left $crop_x -top $crop_y -width $crop_width -height $crop_height";
+ }
+
+ /**
+ * Rotates the image
+ *
+ * @param int $angle The angle to rotate the image through
+ */
+ function rotate($angle)
+ {
+ $angle = -1*floatval($angle);
+
+ if($angle > 90)
+ {
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias 90";
+ $this->rotate(-1*($angle-90));
+ }
+ else if ($angle < -90)
+ {
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias -90";
+ $this->rotate(-1*($angle+90));
+ }
+ else
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias $angle";
+ } // End rotate
+
+ /**
+ * Flip the image horizontally or vertically
+ *
+ * @param boolean $horizontal true if horizontal flip, vertical otherwise
+ */
+ function flip($horizontal)
+ {
+ if($horizontal)
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -lr";
+ else
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -tb";
+ }
+
+ /**
+ * Adjust the image gamma
+ *
+ * @param float $outputgamma
+ *
+ * @return none
+ */
+ function gamma($outputgamma = 1.0) {
+ $this->command[13] = IMAGE_TRANSFORM_LIB_PATH . "pnmgamma $outputgamma";
+ }
+
+ /**
+ * adds text to an image
+ *
+ * @param array options Array contains options
+ * array(
+ * 'text' // The string to draw
+ * 'x' // Horizontal position
+ * 'y' // Vertical Position
+ * 'Color' // Font color
+ * 'font' // Font to be used
+ * 'size' // Size of the fonts in pixel
+ * 'resize_first' // Tell if the image has to be resized
+ * // before drawing the text
+ * )
+ *
+ * @return none
+ */
+ function addText($params)
+ {
+ $default_params = array('text' => 'This is Text',
+ 'x' => 10,
+ 'y' => 20,
+ 'color' => 'red',
+ 'font' => 'Arial.ttf',
+ 'size' => '12',
+ 'angle' => 0,
+ 'resize_first' => false);
+ // we ignore 'resize_first' since the more logical approach would be
+ // for the user to just call $this->_resize() _first_ ;)
+ extract(array_merge($default_params, $params));
+ $this->command[] = "ppmlabel -angle $angle -colour $color -size "
+ ."$size -x $x -y ".$y+$size." -text \"$text\"";
+ } // End addText
+
+ function _postProcess($type, $quality, $save_type)
+ {
+ $type = is_null($type) || $type==''? $this->type : $type;
+ $save_type = is_null($save_type) || $save_type==''? $this->type : $save_type;
+ //echo "TYPE:". $this->type;
+ array_unshift($this->command, IMAGE_TRANSFORM_LIB_PATH
+ . $type.'topnm '. $this->image);
+ $arg = '';
+ switch(strtolower($save_type)){
+ case 'gif':
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmquant 256";
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type";
+ break;
+ case 'jpg':
+ case 'jpeg':
+ $arg = "--quality=$quality";
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type $arg";
+ break;
+ default:
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmto$save_type $arg";
+ break;
+ } // switch
+ return implode('|', $this->command);
+ }
+
+ /**
+ * Save the image file
+ *
+ * @param string $filename the name of the file to write to
+ * @param string $type (jpeg,png...);
+ * @param int $quality 75
+ * @return none
+ */
+ function save($filename, $type=null, $quality = 85)
+ {
+ $cmd = $this->_postProcess('', $quality, $type) . ">$filename";
+
+ //if we have windows server
+ if(isset($_ENV['OS']) && eregi('window',$_ENV['OS']))
+ $cmd = ereg_replace('/','\\',$cmd);
+ //echo $cmd."##";
+ $output = system($cmd);
+ error_log('NETPBM: '.$cmd);
+ //error_log($output);
+ $this->command = array();
+ } // End save
+
+
+ /**
+ * Display image without saving and lose changes
+ *
+ * @param string $type (jpeg,png...);
+ * @param int $quality 75
+ * @return none
+ */
+ function display($type = null, $quality = 75)
+ {
+ header('Content-type: image/' . $type);
+ $cmd = $this->_postProcess($type, $quality);
+
+ passthru($cmd);
+ $this->command = array();
+ }
+
+ /**
+ * Destroy image handle
+ *
+ * @return none
+ */
+ function free()
+ {
+ // there is no image handle here
+ return true;
+ }
+
+
+} // End class NetPBM
+?>
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Thumbnail.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Thumbnail.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Thumbnail.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Thumbnail.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Create thumbnails.
+ * @author $Author: ray $
+ * @version $Id: Thumbnail.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+
+require_once('../ImageManager/Classes/Transform.php');
+
+/**
+ * Thumbnail creation
+ * @author $Author: ray $
+ * @version $Id: Thumbnail.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ * @subpackage Images
+ */
+class Thumbnail
+{
+ /**
+ * Graphics driver, GD, NetPBM or ImageMagick.
+ */
+ var $driver;
+
+ /**
+ * Thumbnail default width.
+ */
+ var $width = 96;
+
+ /**
+ * Thumbnail default height.
+ */
+ var $height = 96;
+
+ /**
+ * Thumbnail default JPEG quality.
+ */
+ var $quality = 85;
+
+ /**
+ * Thumbnail is proportional
+ */
+ var $proportional = true;
+
+ /**
+ * Default image type is JPEG.
+ */
+ var $type = 'jpeg';
+
+ /**
+ * Create a new Thumbnail instance.
+ * @param int $width thumbnail width
+ * @param int $height thumbnail height
+ */
+ function Thumbnail($width=96, $height=96)
+ {
+ $this->driver = Image_Transform::factory(IMAGE_CLASS);
+ $this->width = $width;
+ $this->height = $height;
+ }
+
+ /**
+ * Create a thumbnail.
+ * @param string $file the image for the thumbnail
+ * @param string $thumbnail if not null, the thumbnail will be saved
+ * as this parameter value.
+ * @return boolean true if thumbnail is created, false otherwise
+ */
+ function createThumbnail($file, $thumbnail=null)
+ {
+ if(!is_file($file))
+ Return false;
+
+ //error_log('Creating Thumbs: '.$file);
+
+ $this->driver->load($file);
+
+ if($this->proportional)
+ {
+ $width = $this->driver->img_x;
+ $height = $this->driver->img_y;
+
+ if ($width > $height)
+ $this->height = intval($this->width/$width*$height);
+ else if ($height > $width)
+ $this->width = intval($this->height/$height*$width);
+ }
+
+ $this->driver->resize($this->width, $this->height);
+
+ if(is_null($thumbnail))
+ $this->save($file);
+ else
+ $this->save($thumbnail);
+
+
+ $this->free();
+
+ if(is_file($thumbnail))
+ Return true;
+ else
+ Return false;
+ }
+
+ /**
+ * Save the thumbnail file.
+ * @param string $file file name to be saved as.
+ */
+ function save($file)
+ {
+ $this->driver->save($file);
+ }
+
+ /**
+ * Free up the graphic driver resources.
+ */
+ function free()
+ {
+ $this->driver->free();
+ }
+}
+
+
+?>
\ No newline at end of file
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Transform.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Transform.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Transform.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Transform.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,569 @@
+<?php
+/***********************************************************************
+** Title.........: Image Transformation Interface
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <[email protected]>
+** Filename......: Transform.php
+** Last changed..: 30 Aug 2003
+** Notes.........: Orginal is from PEAR
+
+ Added a few extra,
+ - create unique filename in a particular directory,
+ used for temp image files.
+ - added cropping to GD, NetPBM, ImageMagick
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | [email protected] so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <[email protected]> |
+// | Alan Knowles <[email protected]> |
+// | Vincent Oostindie <[email protected]> |
+// +----------------------------------------------------------------------+
+//
+// $Id: Transform.php 709 2007-01-30 23:22:04Z ray $
+//
+// Image Transformation interface
+//
+
+
+/**
+ * The main "Image_Resize" class is a container and base class which
+ * provides the static methods for creating Image objects as well as
+ * some utility functions (maths) common to all parts of Image Resize.
+ *
+ * The object model of DB is as follows (indentation means inheritance):
+ *
+ * Image_Resize The base for each Image implementation. Provides default
+ * | implementations (in OO lingo virtual methods) for
+ * | the actual Image implementations as well as a bunch of
+ * | maths methods.
+ * |
+ * +-Image_GD The Image implementation for the PHP GD extension . Inherits
+ * Image_Resize
+ * When calling DB::setup for GD images the object returned is an
+ * instance of this class.
+ *
+ * @package Image Resize
+ * @version 1.00
+ * @author Peter Bowyer <[email protected]>
+ * @since PHP 4.0
+ */
+Class Image_Transform
+{
+ /**
+ * Name of the image file
+ * @var string
+ */
+ var $image = '';
+ /**
+ * Type of the image file (eg. jpg, gif png ...)
+ * @var string
+ */
+ var $type = '';
+ /**
+ * Original image width in x direction
+ * @var int
+ */
+ var $img_x = '';
+ /**
+ * Original image width in y direction
+ * @var int
+ */
+ var $img_y = '';
+ /**
+ * New image width in x direction
+ * @var int
+ */
+ var $new_x = '';
+ /**
+ * New image width in y direction
+ * @var int
+ */
+ var $new_y = '';
+ /**
+ * Path the the library used
+ * e.g. /usr/local/ImageMagick/bin/ or
+ * /usr/local/netpbm/
+ */
+ var $lib_path = '';
+ /**
+ * Flag to warn if image has been resized more than once before displaying
+ * or saving.
+ */
+ var $resized = false;
+
+
+ var $uid = '';
+
+ var $lapse_time =900; //15 mins
+
+ /**
+ * Create a new Image_resize object
+ *
+ * @param string $driver name of driver class to initialize
+ *
+ * @return mixed a newly created Image_Transform object, or a PEAR
+ * error object on error
+ *
+ * @see PEAR::isError()
+ * @see Image_Transform::setOption()
+ */
+ function &factory($driver)
+ {
+ if ('' == $driver) {
+ die("No image library specified... aborting. You must call ::factory() with one parameter, the library to load.");
+
+ }
+ $this->uid = md5($_SERVER['REMOTE_ADDR']);
+
+ include_once "../ImageManager/Classes/$driver.php";
+
+ $classname = "Image_Transform_Driver_{$driver}";
+ $obj =& new $classname;
+ return $obj;
+ }
+
+
+ /**
+ * Resize the Image in the X and/or Y direction
+ * If either is 0 it will be scaled proportionally
+ *
+ * @access public
+ *
+ * @param mixed $new_x (0, number, percentage 10% or 0.1)
+ * @param mixed $new_y (0, number, percentage 10% or 0.1)
+ *
+ * @return mixed none or PEAR_error
+ */
+ function resize($new_x = 0, $new_y = 0)
+ {
+ // 0 means keep original size
+ $new_x = (0 == $new_x) ? $this->img_x : $this->_parse_size($new_x, $this->img_x);
+ $new_y = (0 == $new_y) ? $this->img_y : $this->_parse_size($new_y, $this->img_y);
+ // Now do the library specific resizing.
+ return $this->_resize($new_x, $new_y);
+ } // End resize
+
+
+ /**
+ * Scale the image to have the max x dimension specified.
+ *
+ * @param int $new_x Size to scale X-dimension to
+ * @return none
+ */
+ function scaleMaxX($new_x)
+ {
+ $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+ return $this->_resize($new_x, $new_y);
+ } // End resizeX
+
+ /**
+ * Scale the image to have the max y dimension specified.
+ *
+ * @access public
+ * @param int $new_y Size to scale Y-dimension to
+ * @return none
+ */
+ function scaleMaxY($new_y)
+ {
+ $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+ return $this->_resize($new_x, $new_y);
+ } // End resizeY
+
+ /**
+ * Scale Image to a maximum or percentage
+ *
+ * @access public
+ * @param mixed (number, percentage 10% or 0.1)
+ * @return mixed none or PEAR_error
+ */
+ function scale($size)
+ {
+ if ((strlen($size) > 1) && (substr($size,-1) == '%')) {
+ return $this->scaleByPercentage(substr($size, 0, -1));
+ } elseif ($size < 1) {
+ return $this->scaleByFactor($size);
+ } else {
+ return $this->scaleByLength($size);
+ }
+ } // End scale
+
+ /**
+ * Scales an image to a percentage of its original size. For example, if
+ * my image was 640x480 and I called scaleByPercentage(10) then the image
+ * would be resized to 64x48
+ *
+ * @access public
+ * @param int $size Percentage of original size to scale to
+ * @return none
+ */
+ function scaleByPercentage($size)
+ {
+ return $this->scaleByFactor($size / 100);
+ } // End scaleByPercentage
+
+ /**
+ * Scales an image to a factor of its original size. For example, if
+ * my image was 640x480 and I called scaleByFactor(0.5) then the image
+ * would be resized to 320x240.
+ *
+ * @access public
+ * @param float $size Factor of original size to scale to
+ * @return none
+ */
+ function scaleByFactor($size)
+ {
+ $new_x = round($size * $this->img_x, 0);
+ $new_y = round($size * $this->img_y, 0);
+ return $this->_resize($new_x, $new_y);
+ } // End scaleByFactor
+
+ /**
+ * Scales an image so that the longest side has this dimension.
+ *
+ * @access public
+ * @param int $size Max dimension in pixels
+ * @return none
+ */
+ function scaleByLength($size)
+ {
+ if ($this->img_x >= $this->img_y) {
+ $new_x = $size;
+ $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+ } else {
+ $new_y = $size;
+ $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+ }
+ return $this->_resize($new_x, $new_y);
+ } // End scaleByLength
+
+
+ /**
+ *
+ * @access public
+ * @return void
+ */
+ function _get_image_details($image)
+ {
+ //echo $image;
+ $data = @GetImageSize($image);
+ #1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 = TIFF(motorola byte order,
+ # 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC
+ if (is_array($data)){
+ switch($data[2]){
+ case 1:
+ $type = 'gif';
+ break;
+ case 2:
+ $type = 'jpeg';
+ break;
+ case 3:
+ $type = 'png';
+ break;
+ case 4:
+ $type = 'swf';
+ break;
+ case 5:
+ $type = 'psd';
+ case 6:
+ $type = 'bmp';
+ case 7:
+ case 8:
+ $type = 'tiff';
+ default:
+ echo("We do not recognize this image format");
+ }
+ $this->img_x = $data[0];
+ $this->img_y = $data[1];
+ $this->type = $type;
+
+ return true;
+ } else {
+ echo("Cannot fetch image or images details.");
+ return null;
+ }
+ /*
+ $output = array(
+ 'width' => $data[0],
+ 'height' => $data[1],
+ 'type' => $type
+ );
+ return $output;
+ */
+ }
+
+
+ /**
+ * Parse input and convert
+ * If either is 0 it will be scaled proportionally
+ *
+ * @access private
+ *
+ * @param mixed $new_size (0, number, percentage 10% or 0.1)
+ * @param int $old_size
+ *
+ * @return mixed none or PEAR_error
+ */
+ function _parse_size($new_size, $old_size)
+ {
+ if ('%' == $new_size) {
+ $new_size = str_replace('%','',$new_size);
+ $new_size = $new_size / 100;
+ }
+ if ($new_size > 1) {
+ return (int) $new_size;
+ } elseif ($new_size == 0) {
+ return (int) $old_size;
+ } else {
+ return (int) round($new_size * $old_size, 0);
+ }
+ }
+
+
+ function uniqueStr()
+ {
+ return substr(md5(microtime()),0,6);
+ }
+
+ //delete old tmp files, and allow only 1 file per remote host.
+ function cleanUp($id, $dir)
+ {
+ $d = dir($dir);
+ $id_length = strlen($id);
+
+ while (false !== ($entry = $d->read())) {
+ if (is_file($dir.'/'.$entry) && substr($entry,0,1) == '.' && !ereg($entry, $this->image))
+ {
+ //echo filemtime($this->directory.'/'.$entry)."<br>";
+ //echo time();
+
+ if (filemtime($dir.'/'.$entry) + $this->lapse_time < time())
+ unlink($dir.'/'.$entry);
+
+ if (substr($entry, 1, $id_length) == $id)
+ {
+ if (is_file($dir.'/'.$entry))
+ unlink($dir.'/'.$entry);
+ }
+ }
+ }
+ $d->close();
+ }
+
+
+ function createUnique($dir)
+ {
+ $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+
+ //make sure the the unique temp file does not exists
+ while (file_exists($dir.$unique_str))
+ {
+ $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+ }
+
+ $this->cleanUp($this->uid, $dir);
+
+ return $unique_str;
+ }
+
+
+ /**
+ * Set the image width
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_img_x($size)
+ {
+ $this->img_x = $size;
+ }
+
+ /**
+ * Set the image height
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_img_y($size)
+ {
+ $this->img_y = $size;
+ }
+
+ /**
+ * Set the image width
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_new_x($size)
+ {
+ $this->new_x = $size;
+ }
+
+ /**
+ * Set the image height
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_new_y($size)
+ {
+ $this->new_y = $size;
+ }
+
+ /**
+ * Get the type of the image being manipulated
+ *
+ * @return string $this->type the image type
+ */
+ function getImageType()
+ {
+ return $this->type;
+ }
+
+ /**
+ *
+ * @access public
+ * @return string web-safe image type
+ */
+ function getWebSafeFormat()
+ {
+ switch($this->type){
+ case 'gif':
+ case 'png':
+ return 'png';
+ break;
+ default:
+ return 'jpeg';
+ } // switch
+ }
+
+ /**
+ * Place holder for the real resize method
+ * used by extended methods to do the resizing
+ *
+ * @access private
+ * @return PEAR_error
+ */
+ function _resize() {
+ return null; //PEAR::raiseError("No Resize method exists", true);
+ }
+
+ /**
+ * Place holder for the real load method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @return PEAR_error
+ */
+ function load($filename) {
+ return null; //PEAR::raiseError("No Load method exists", true);
+ }
+
+ /**
+ * Place holder for the real display method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @param string filename
+ * @return PEAR_error
+ */
+ function display($type, $quality) {
+ return null; //PEAR::raiseError("No Display method exists", true);
+ }
+
+ /**
+ * Place holder for the real save method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @param string filename
+ * @return PEAR_error
+ */
+ function save($filename, $type, $quality) {
+ return null; //PEAR::raiseError("No Save method exists", true);
+ }
+
+ /**
+ * Place holder for the real free method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @return PEAR_error
+ */
+ function free() {
+ return null; //PEAR::raiseError("No Free method exists", true);
+ }
+
+ /**
+ * Reverse of rgb2colorname.
+ *
+ * @access public
+ * @return PEAR_error
+ *
+ * @see rgb2colorname
+ */
+ function colorhex2colorarray($colorhex) {
+ $r = hexdec(substr($colorhex, 1, 2));
+ $g = hexdec(substr($colorhex, 3, 2));
+ $b = hexdec(substr($colorhex, 4, 2));
+ return array($r,$g,$b);
+ }
+
+ /**
+ * Reverse of rgb2colorname.
+ *
+ * @access public
+ * @return PEAR_error
+ *
+ * @see rgb2colorname
+ */
+ function colorarray2colorhex($color) {
+ $color = '#'.dechex($color[0]).dechex($color[1]).dechex($color[2]);
+ return strlen($color)>6?false:$color;
+ }
+
+
+ /* Methods to add to the driver classes in the future */
+ function addText()
+ {
+ return null; //PEAR::raiseError("No addText method exists", true);
+ }
+
+ function addDropShadow()
+ {
+ return null; //PEAR::raiseError("No AddDropShadow method exists", true);
+ }
+
+ function addBorder()
+ {
+ return null; //PEAR::raiseError("No addBorder method exists", true);
+ }
+
+ function crop()
+ {
+ return null; //PEAR::raiseError("No crop method exists", true);
+ }
+
+ function flip()
+ {
+ return null;
+ }
+
+ function gamma()
+ {
+ return null; //PEAR::raiseError("No gamma method exists", true);
+ }
+}
+?>
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/README.txt
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/README.txt?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/README.txt (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/README.txt Fri Sep 21 03:36:30 2007
@@ -0,0 +1,150 @@
+Originally Developed by: http://www.zhuo.org/htmlarea/
+
+> This is a plug-in for HTMLArea 3.0
+>
+> The PHP ImageManager + Editor provides an interface to
+> browser for image files on your web server. The Editor
+> allows some basic image manipulations such as, cropping,
+> rotation, flip, and scaling.
+>
+> Further and up-to-date documentation can be found at
+> http://www.zhuo.org/htmlarea/docs/index.html
+>
+> Cheer,
+> Wei
+
+2005-03-20
+ by Yermo Lamers of DTLink, LLC (http://www.formvista.com/contact.html)
+
+Please post questions/comments/flames about this plugin in the Xinha forums
+at
+
+ http://xinha.gogo.co.nz/punbb/viewforum.php?id=1
+
+------------------------------------------------------------------------------
+If you have GD installed and configured in PHP this should work out of the
+box.
+
+For production use see config.inc.php for configuration values. You will
+want to adjust images_dir and images_url for your application.
+
+For demo purposes ImageManager is set up to view images in the
+
+ /xinha/plugins/ImageManager/demo_images
+
+directory. This is governed by the images_dir and images_url config options.
+
+The permissions on the demo_images directory may not be correct. The directory
+should be owned by the user your webserver runs as and should have 755
+permissions.
+
+--------------------------------------------------------------------------------
+
+By default this ImageManager is set up to browse some graphics
+in plugins/ImageManager/demo_images.
+
+For security reasons image uploading is turned off by default.
+You can enable it by editing config.inc.php.
+
+---------------------------------
+For Developers
+---------------------------------
+
+CHANGES FROM Wei's Original Code:
+
+Single Backend:
+---------------
+
+All requests from the javascript code back to the server now
+are routed through a single configurable backend script,
+backend.php.
+
+Request URLs are of the form:
+
+ <config backend URL>(?|&)__plugin=ImageManager&__function=<function>&arg=value&arg=value
+
+The default URL is plugins/xinha/backend.php.
+
+This approach makes it possible to completely replace the
+backend with a perl or ASP implementation without having to
+change any of the client side code.
+
+You can override the location and name of the backend.php
+script by setting the config.ImageManager.backend property from
+the calling page. Make sure the URL ends in an "&". The code,
+for now, assumes it can just tack on variables.
+
+For the moment the javascript files in the assets directory do
+not have access to the main editor object and as a result have
+not access to the config. For the moment we use a _backend_url
+variable output from PHP to communicate the location of the
+backend to these assets. It's a kludge. Ideally all these
+config values should be set from the calling page and be
+available through the editor.config.ImageManager object.
+
+Debug Messages
+---------------
+
+The php files include a simple debugging library, ddt.php. See
+config.inc.php for how to turn it on. It can display trace
+messages to the browser or dump them to a log file.
+
+I'll try to package up the client-side tracing-to-textarea
+_ddt() functions I've put together. Having a trace message
+infrastructure has always served me well.
+
+-------------
+Flakey Editor
+-------------
+
+The editor I use is flakey (but very very fast). It has
+problems with tab to space conversion so if the indenting looks
+weird that's why.
+
+----
+TODO
+----
+
+ImageManager really needs a complete rewrite.
+
+. ImageManager should appear in a pane instead of a popup
+ window using Sleeman's windowpane support.
+
+. html and php code are intermixed. It would be very nice to
+use some kind of templating for the dialogs; this templating
+should be done long hand so it can be re-used regardless of the
+backend implementation language.
+
+. the config should probably be some format that would be
+easily read by multiple implementations of the back end. It
+would be nice to have a single configuration system regardless
+of whether the backend is PHP, Perl or ASP.
+
+. javascript assets are not objects. Passing config options to
+the assets functions requires intermediate variables which is
+really ugly. Everything should be cleanly integrated into the
+object heirarchy akin to the way Linker is done.
+
+. if an image is selected from the document editor window it
+should be focused and highlighted in the image selection
+window.
+
+. fix fully-qualified url in image selection box under MSIE.
+
+. per-image permissions. We should include some kind of backend
+permissions management so users can only
+delete/edit/move/rename images that they have uploaded.
+
+. add a CANCEL button and a SAVE AS button to the editor.
+
+. add a list view akin to EFM. (and include image properties
+width/height/depth/etc.)
+
+. figure out a way for ImageManager to work "out of the box"
+regardless of install.
+
+. client-side tracing.
+
+. fancy stuff like adding a UI to define rollovers, animations,
+etc.
+
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/EditorContent.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/EditorContent.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/EditorContent.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/EditorContent.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,657 @@
+function MM_findObj(n,d){
+var p,i,x;
+if(!d){
+d=document;
+}
+if((p=n.indexOf("?"))>0&&parent.frames.length){
+d=parent.frames[n.substring(p+1)].document;
+n=n.substring(0,p);
+}
+if(!(x=d[n])&&d.all){
+x=d.all[n];
+}
+for(i=0;!x&&i<d.forms.length;i++){
+x=d.forms[i][n];
+}
+for(i=0;!x&&d.layers&&i<d.layers.length;i++){
+x=MM_findObj(n,d.layers[i].document);
+}
+if(!x&&d.getElementById){
+x=d.getElementById(n);
+}
+return x;
+}
+var pic_x,pic_y;
+function P7_Snap(){
+var x,y,ox,bx,oy,p,tx,a,b,k,d,da,e,el,args=P7_Snap.arguments;
+a=parseInt(a);
+for(k=0;k<(args.length-3);k+=4){
+if((g=MM_findObj(args[k]))!=null){
+el=eval(MM_findObj(args[k+1]));
+a=parseInt(args[k+2]);
+b=parseInt(args[k+3]);
+x=0;
+y=0;
+ox=0;
+oy=0;
+p="";
+tx=1;
+da="document.all['"+args[k]+"']";
+if(document.getElementById){
+d="document.getElementsByName('"+args[k]+"')[0]";
+if(!eval(d)){
+d="document.getElementById('"+args[k]+"')";
+if(!eval(d)){
+d=da;
+}
+}
+}else{
+if(document.all){
+d=da;
+}
+}
+if(document.all||document.getElementById){
+while(tx==1){
+p+=".offsetParent";
+if(eval(d+p)){
+x+=parseInt(eval(d+p+".offsetLeft"));
+y+=parseInt(eval(d+p+".offsetTop"));
+}else{
+tx=0;
+}
+}
+ox=parseInt(g.offsetLeft);
+oy=parseInt(g.offsetTop);
+var tw=x+ox+y+oy;
+if(tw==0||(navigator.appVersion.indexOf("MSIE 4")>-1&&navigator.appVersion.indexOf("Mac")>-1)){
+ox=0;
+oy=0;
+if(g.style.left){
+x=parseInt(g.style.left);
+y=parseInt(g.style.top);
+}else{
+var w1=parseInt(el.style.width);
+bx=(a<0)?-5-w1:-10;
+a=(Math.abs(a)<1000)?0:a;
+b=(Math.abs(b)<1000)?0:b;
+if(event==null){
+x=document.body.scrollLeft+bx;
+}else{
+x=document.body.scrollLeft+event.clientX+bx;
+}
+if(event==null){
+y=document.body.scrollTop;
+}else{
+y=document.body.scrollTop+event.clientY;
+}
+}
+}
+}else{
+if(document.layers){
+x=g.x;
+y=g.y;
+var q0=document.layers,dd="";
+for(var s=0;s<q0.length;s++){
+dd="document."+q0[s].name;
+if(eval(dd+".document."+args[k])){
+x+=eval(dd+".left");
+y+=eval(dd+".top");
+break;
+}
+}
+}
+}
+if(el){
+e=(document.layers)?el:el.style;
+var xx=parseInt(x+ox+a),yy=parseInt(y+oy+b);
+if(navigator.appName=="Netscape"&&parseInt(navigator.appVersion)>4){
+xx+="px";
+yy+="px";
+}
+if(navigator.appVersion.indexOf("MSIE 5")>-1&&navigator.appVersion.indexOf("Mac")>-1){
+xx+=parseInt(document.body.leftMargin);
+yy+=parseInt(document.body.topMargin);
+xx+="px";
+yy+="px";
+}
+e.left=xx;
+e.top=yy;
+}
+pic_x=parseInt(xx);
+pic_y=parseInt(yy);
+}
+}
+}
+var ie=document.all;
+var ns6=document.getElementById&&!document.all;
+var dragapproved=false;
+var z,x,y,status,ant,canvas,content,pic_width,pic_height,image,resizeHandle,oa_w,oa_h,oa_x,oa_y,mx2,my2;
+function init_resize(){
+if(mode=="scale"){
+P7_Snap("theImage","ant",0,0);
+if(canvas==null){
+canvas=MM_findObj("imgCanvas");
+}
+if(pic_width==null||pic_height==null){
+image=MM_findObj("theImage");
+pic_width=image.width;
+pic_height=image.height;
+}
+if(ant==null){
+ant=MM_findObj("ant");
+}
+ant.style.left=pic_x;
+ant.style.top=pic_y;
+ant.style.width=pic_width;
+ant.style.height=pic_height;
+ant.style.visibility="visible";
+drawBoundHandle();
+jg_doc.paint();
+}
+}
+initEditor=function(){
+init_crop();
+init_resize();
+var _a=MM_findObj("markerImg",window.top.document);
+if(_a.src.indexOf("img/t_white.gif")>0){
+toggleMarker();
+}
+};
+function init_crop(){
+P7_Snap("theImage","ant",0,0);
+}
+function setMode(_b){
+mode=_b;
+reset();
+}
+function reset(){
+if(ant==null){
+ant=MM_findObj("ant");
+}
+ant.style.visibility="hidden";
+ant.style.left=0;
+ant.style.top=0;
+ant.style.width=0;
+ant.style.height=0;
+mx2=null;
+my2=null;
+jg_doc.clear();
+if(mode!="measure"){
+showStatus();
+}
+if(mode=="scale"){
+init_resize();
+}
+P7_Snap("theImage","ant",0,0);
+}
+function toggleMarker(){
+if(ant==null){
+ant=MM_findObj("ant");
+}
+if(ant.className=="selection"){
+ant.className="selectionWhite";
+}else{
+ant.className="selection";
+}
+if(jg_doc.getColor()=="#000000"){
+jg_doc.setColor("#FFFFFF");
+}else{
+jg_doc.setColor("#000000");
+}
+drawBoundHandle;
+jg_doc.paint();
+}
+function move(e){
+if(dragapproved){
+var w=ns6?temp1+e.clientX-x:temp1+event.clientX-x;
+var h=ns6?temp2+e.clientY-y:temp2+event.clientY-y;
+if(ant!=null){
+if(w>=0){
+ant.style.left=x;
+ant.style.width=w;
+}else{
+ant.style.left=x+w;
+ant.style.width=-1*w;
+}
+if(h>=0){
+ant.style.top=y;
+ant.style.height=h;
+}else{
+ant.style.top=y+h;
+ant.style.height=-1*h;
+}
+}
+showStatus();
+return false;
+}
+}
+function moveContent(e){
+if(dragapproved){
+var dx=ns6?oa_x+e.clientX-x:oa_x+event.clientX-x;
+var dy=ns6?oa_y+e.clientY-y:oa_y+event.clientY-y;
+ant.style.left=dx;
+ant.style.top=dy;
+showStatus();
+return false;
+}
+}
+function moveHandle(e){
+if(dragapproved){
+var w=ns6?e.clientX-x:event.clientX-x;
+var h=ns6?e.clientY-y:event.clientY-y;
+var _15=MM_findObj("constProp",window.top.document);
+var _16=document.theImage.height;
+var _17=document.theImage.width;
+rapp=_17/_16;
+rapp_inv=_16/_17;
+switch(resizeHandle){
+case "s-resize":
+if(oa_h+h>=0){
+ant.style.height=oa_h+h;
+if(_15.checked){
+ant.style.width=rapp*(oa_h+h);
+ant.style.left=oa_x-rapp*h/2;
+}
+}
+break;
+case "e-resize":
+if(oa_w+w>=0){
+ant.style.width=oa_w+w;
+if(_15.checked){
+ant.style.height=rapp_inv*(oa_w+w);
+ant.style.top=oa_y-rapp_inv*w/2;
+}
+}
+break;
+case "n-resize":
+if(oa_h-h>=0){
+ant.style.top=oa_y+h;
+ant.style.height=oa_h-h;
+if(_15.checked){
+ant.style.width=rapp*(oa_h-h);
+ant.style.left=oa_x+rapp*h/2;
+}
+}
+break;
+case "w-resize":
+if(oa_w-w>=0){
+ant.style.left=oa_x+w;
+ant.style.width=oa_w-w;
+if(_15.checked){
+ant.style.height=rapp_inv*(oa_w-w);
+ant.style.top=oa_y+rapp_inv*w/2;
+}
+}
+break;
+case "nw-resize":
+if(oa_h-h>=0&&oa_w-w>=0){
+ant.style.left=oa_x+w;
+ant.style.width=oa_w-w;
+ant.style.top=oa_y+h;
+if(_15.checked){
+ant.style.height=rapp_inv*(oa_w-w);
+}else{
+ant.style.height=oa_h-h;
+}
+}
+break;
+case "ne-resize":
+if(oa_h-h>=0&&oa_w+w>=0){
+ant.style.top=oa_y+h;
+ant.style.width=oa_w+w;
+if(_15.checked){
+ant.style.height=rapp_inv*(oa_w+w);
+}else{
+ant.style.height=oa_h-h;
+}
+}
+break;
+case "se-resize":
+if(oa_h+h>=0&&oa_w+w>=0){
+ant.style.width=oa_w+w;
+if(_15.checked){
+ant.style.height=rapp_inv*(oa_w+w);
+}else{
+ant.style.height=oa_h+h;
+}
+}
+break;
+case "sw-resize":
+if(oa_h+h>=0&&oa_w-w>=0){
+ant.style.left=oa_x+w;
+ant.style.width=oa_w-w;
+if(_15.checked){
+ant.style.height=rapp_inv*(oa_w-w);
+}else{
+ant.style.height=oa_h+h;
+}
+}
+}
+showStatus();
+return false;
+}
+}
+function drags(e){
+if(!ie&&!ns6){
+return;
+}
+var _19=ns6?e.target:event.srcElement;
+var _1a=ns6?"HTML":"BODY";
+while(_19.tagName!=_1a&&!(_19.className=="crop"||_19.className=="handleBox"||_19.className=="selection"||_19.className=="selectionWhite")){
+_19=ns6?_19.parentNode:_19.parentElement;
+}
+if(_19.className=="handleBox"){
+if(content!=null){
+if(content.width!=null&&content.height!=null){
+content.width=0;
+content.height=0;
+}
+}
+resizeHandle=_19.id;
+x=ns6?e.clientX:event.clientX;
+y=ns6?e.clientY:event.clientY;
+oa_w=parseInt(ant.style.width);
+oa_h=parseInt(ant.style.height);
+oa_x=parseInt(ant.style.left);
+oa_y=parseInt(ant.style.top);
+dragapproved=true;
+document.onmousemove=moveHandle;
+return false;
+}else{
+if((_19.className=="selection"||_19.className=="selectionWhite")&&mode=="crop"){
+x=ns6?e.clientX:event.clientX;
+y=ns6?e.clientY:event.clientY;
+oa_x=parseInt(ant.style.left);
+oa_y=parseInt(ant.style.top);
+dragapproved=true;
+document.onmousemove=moveContent;
+return false;
+}else{
+if(_19.className=="crop"&&mode=="crop"){
+if(content!=null){
+if(content.width!=null&&content.height!=null){
+content.width=0;
+content.height=0;
+}
+}
+if(status==null){
+status=MM_findObj("status");
+}
+if(ant==null){
+ant=MM_findObj("ant");
+}
+if(canvas==null){
+canvas=MM_findObj("imgCanvas");
+}
+if(content==null){
+content=MM_findObj("cropContent");
+}
+if(pic_width==null||pic_height==null){
+image=MM_findObj("theImage");
+pic_width=image.width;
+pic_height=image.height;
+}
+ant.style.visibility="visible";
+obj=_19;
+dragapproved=true;
+z=_19;
+temp1=parseInt(z.style.left+0);
+temp2=parseInt(z.style.top+0);
+x=ns6?e.clientX:event.clientX;
+y=ns6?e.clientY:event.clientY;
+document.onmousemove=move;
+return false;
+}else{
+if(_19.className=="crop"&&mode=="measure"){
+if(ant==null){
+ant=MM_findObj("ant");
+}
+if(canvas==null){
+canvas=MM_findObj("imgCanvas");
+}
+x=ns6?e.clientX:event.clientX;
+y=ns6?e.clientY:event.clientY;
+dragapproved=true;
+document.onmousemove=measure;
+return false;
+}
+}
+}
+}
+}
+function measure(e){
+if(dragapproved){
+mx2=ns6?e.clientX:event.clientX;
+my2=ns6?e.clientY:event.clientY;
+jg_doc.clear();
+jg_doc.setStroke(Stroke.DOTTED);
+jg_doc.drawLine(x,y,mx2,my2);
+jg_doc.paint();
+showStatus();
+return false;
+}
+}
+function setMarker(nx,ny,nw,nh){
+if(isNaN(nx)){
+nx=0;
+}
+if(isNaN(ny)){
+ny=0;
+}
+if(isNaN(nw)){
+nw=0;
+}
+if(isNaN(nh)){
+nh=0;
+}
+if(ant==null){
+ant=MM_findObj("ant");
+}
+if(canvas==null){
+canvas=MM_findObj("imgCanvas");
+}
+if(content==null){
+content=MM_findObj("cropContent");
+}
+if(pic_width==null||pic_height==null){
+image=MM_findObj("theImage");
+pic_width=image.width;
+pic_height=image.height;
+}
+ant.style.visibility="visible";
+nx=pic_x+nx;
+ny=pic_y+ny;
+if(nw>=0){
+ant.style.left=nx;
+ant.style.width=nw;
+}else{
+ant.style.left=nx+nw;
+ant.style.width=-1*nw;
+}
+if(nh>=0){
+ant.style.top=ny;
+ant.style.height=nh;
+}else{
+ant.style.top=ny+nh;
+ant.style.height=-1*nh;
+}
+}
+function max(x,y){
+if(y>x){
+return x;
+}else{
+return y;
+}
+}
+function drawBoundHandle(){
+if(ant==null||ant.style==null){
+return false;
+}
+var ah=parseInt(ant.style.height);
+var aw=parseInt(ant.style.width);
+var ax=parseInt(ant.style.left);
+var ay=parseInt(ant.style.top);
+jg_doc.drawHandle(ax-15,ay-15,30,30,"nw-resize");
+jg_doc.drawHandle(ax-15,ay+ah-15,30,30,"sw-resize");
+jg_doc.drawHandle(ax+aw-15,ay-15,30,30,"ne-resize");
+jg_doc.drawHandle(ax+aw-15,ay+ah-15,30,30,"se-resize");
+jg_doc.drawHandle(ax+max(15,aw/10),ay-8,aw-2*max(15,aw/10),8,"n-resize");
+jg_doc.drawHandle(ax+max(15,aw/10),ay+ah,aw-2*max(15,aw/10),8,"s-resize");
+jg_doc.drawHandle(ax-8,ay+max(15,ah/10),8,ah-2*max(15,ah/10),"w-resize");
+jg_doc.drawHandle(ax+aw,ay+max(15,ah/10),8,ah-2*max(15,ah/10),"e-resize");
+jg_doc.drawHandleBox(ax-4,ay-4,8,8,"nw-resize");
+jg_doc.drawHandleBox(ax-4,ay+ah-4,8,8,"sw-resize");
+jg_doc.drawHandleBox(ax+aw-4,ay-4,8,8,"ne-resize");
+jg_doc.drawHandleBox(ax+aw-4,ay+ah-4,8,8,"se-resize");
+jg_doc.drawHandleBox(ax+aw/2-4,ay-4,8,8,"n-resize");
+jg_doc.drawHandleBox(ax+aw/2-4,ay+ah-4,8,8,"s-resize");
+jg_doc.drawHandleBox(ax-4,ay+ah/2-4,8,8,"w-resize");
+jg_doc.drawHandleBox(ax+aw-4,ay+ah/2-4,8,8,"e-resize");
+}
+function showStatus(){
+if(ant==null||ant.style==null){
+return false;
+}
+if(mode=="measure"){
+mx1=x-pic_x;
+my1=y-pic_y;
+mw=mx2-x;
+mh=my2-y;
+md=parseInt(Math.sqrt(mw*mw+mh*mh)*100)/100;
+ma=(Math.atan(-1*mh/mw)/Math.PI)*180;
+if(mw<0&&mh<0){
+ma=ma+180;
+}
+if(mw<0&&mh>0){
+ma=ma-180;
+}
+ma=parseInt(ma*100)/100;
+if(m_sx!=null&&!isNaN(mx1)){
+m_sx.value=mx1+"px";
+}
+if(m_sy!=null&&!isNaN(my1)){
+m_sy.value=my1+"px";
+}
+if(m_w!=null&&!isNaN(mw)){
+m_w.value=mw+"px";
+}
+if(m_h!=null&&!isNaN(mh)){
+m_h.value=mh+"px";
+}
+if(m_d!=null&&!isNaN(md)){
+m_d.value=md+"px";
+}
+if(m_a!=null&&!isNaN(ma)){
+m_a.value=ma+"";
+}
+if(r_ra!=null&&!isNaN(ma)){
+r_ra.value=ma;
+}
+return false;
+}
+var ah=parseInt(ant.style.height);
+var aw=parseInt(ant.style.width);
+var ax=parseInt(ant.style.left);
+var ay=parseInt(ant.style.top);
+var cx=ax-pic_x<0?0:ax-pic_x;
+var cy=ay-pic_y<0?0:ay-pic_y;
+cx=cx>pic_width?pic_width:cx;
+cy=cy>pic_height?pic_height:cy;
+var cw=ax-pic_x>0?aw:aw-(pic_x-ax);
+var ch=ay-pic_y>0?ah:ah-(pic_y-ay);
+ch=ay+ah<pic_y+pic_height?ch:ch-(ay+ah-pic_y-pic_height);
+cw=ax+aw<pic_x+pic_width?cw:cw-(ax+aw-pic_x-pic_width);
+ch=ch<0?0:ch;
+cw=cw<0?0:cw;
+if(ant.style.visibility=="hidden"){
+cx="";
+cy="";
+cw="";
+ch="";
+}
+if(mode=="crop"){
+if(t_cx!=null){
+t_cx.value=cx;
+}
+if(t_cy!=null){
+t_cy.value=cy;
+}
+if(t_cw!=null){
+t_cw.value=cw;
+}
+if(t_ch!=null){
+t_ch.value=ch;
+}
+}else{
+if(mode=="scale"){
+var sw=aw,sh=ah;
+if(s_sw.value.indexOf("%")>0&&s_sh.value.indexOf("%")>0){
+sw=cw/pic_width;
+sh=ch/pic_height;
+}
+if(s_sw!=null){
+s_sw.value=sw;
+}
+if(s_sh!=null){
+s_sh.value=sh;
+}
+}
+}
+}
+function dragStopped(){
+dragapproved=false;
+if(ant==null||ant.style==null){
+return false;
+}
+if(mode=="measure"){
+jg_doc.drawLine(x-4,y,x+4,y);
+jg_doc.drawLine(x,y-4,x,y+4);
+jg_doc.drawLine(mx2-4,my2,mx2+4,my2);
+jg_doc.drawLine(mx2,my2-4,mx2,my2+4);
+jg_doc.paint();
+showStatus();
+return false;
+}
+var ah=parseInt(ant.style.height);
+var aw=parseInt(ant.style.width);
+var ax=parseInt(ant.style.left);
+var ay=parseInt(ant.style.top);
+jg_doc.clear();
+if(content!=null){
+if(content.width!=null&&content.height!=null){
+content.width=aw-1;
+content.height=ah-1;
+}
+}
+if(mode=="crop"){
+jg_doc.fillRectPattern(pic_x,pic_y,pic_width,ay-pic_y,pattern);
+var h1=ah;
+var y1=ay;
+if(ah+ay>=pic_height+pic_y){
+h1=pic_height+pic_y-ay;
+}else{
+if(ay<=pic_y){
+h1=ay+ah-pic_y;
+y1=pic_y;
+}
+}
+jg_doc.fillRectPattern(pic_x,y1,ax-pic_x,h1,pattern);
+jg_doc.fillRectPattern(ax+aw,y1,pic_x+pic_width-ax-aw,h1,pattern);
+jg_doc.fillRectPattern(pic_x,ay+ah,pic_width,pic_height+pic_y-ay-ah,pattern);
+}else{
+if(mode=="scale"){
+document.theImage.height=ah;
+document.theImage.width=aw;
+document.theImage.style.height=ah+" px";
+document.theImage.style.width=aw+" px";
+P7_Snap("theImage","ant",0,0);
+}
+}
+drawBoundHandle();
+jg_doc.paint();
+showStatus();
+return false;
+}
+document.onmousedown=drags;
+document.onmouseup=dragStopped;
+
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/ImageEditor.css
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/ImageEditor.css?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/ImageEditor.css (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/ImageEditor.css Fri Sep 21 03:36:30 2007
@@ -0,0 +1,76 @@
+.icons {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-align: center;
+ text-decoration: none;
+ border: 1px solid #EEEEFF;
+ -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+
+body, td, p {
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+.iconsOver {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-align: center;
+ text-decoration: none;
+ background-color: #F9F9FF;
+ border: 1px solid #666699;
+ -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.topBar {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+}
+.iconsSel {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-align: center;
+ text-decoration: none;
+ border: 1px solid #666699;
+ -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.iconText {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-decoration: none;
+ text-align: center;
+}
+.measureStats{
+ width: 50px;
+}
+
+#slidercasing {
+ /*border:1px solid #CCCCCC;
+ background-color:#FFFFFF;*/
+ width:100px;
+ height:5px;
+ position:relative;
+ z-index:4;
+ padding:10px;
+}
+
+
+#slidertrack {
+ position:relative;
+ border:1px solid #CCCCCC;
+ background-color:#FFFFCC;
+ z-index:5;
+ height:5px;
+}
+
+
+#sliderbar {
+ position:absolute;
+ z-index:6;
+ border:1px solid #CCCCCC;
+ background-color:#DDDDDD;
+ width:15px;
+ padding:0px;
+ height:20px;
+ cursor: pointer;
+ top:2px;
+}
+
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/dialog.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/dialog.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/dialog.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/dialog.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,75 @@
+function Dialog(_1,_2,_3){
+if(typeof _3=="undefined"){
+_3=window;
+}
+Dialog._geckoOpenModal(_1,_2,_3);
+}
+Dialog._parentEvent=function(ev){
+setTimeout(function(){
+if(Dialog._modal&&!Dialog._modal.closed){
+Dialog._modal.focus();
+}
+},50);
+if(Dialog._modal&&!Dialog._modal.closed){
+Dialog._stopEvent(ev);
+}
+};
+Dialog._return=null;
+Dialog._modal=null;
+Dialog._arguments=null;
+Dialog._geckoOpenModal=function(_5,_6,_7){
+var _8="hadialog"+_5;
+var _9=/\W/g;
+_8=_8.replace(_9,"_");
+var _a=window.open(_5,_8,"toolbar=no,menubar=no,personalbar=no,width=10,height=10,"+"scrollbars=no,resizable=yes,modal=yes,dependable=yes");
+Dialog._modal=_a;
+Dialog._arguments=_7;
+function capwin(w){
+Dialog._addEvent(w,"click",Dialog._parentEvent);
+Dialog._addEvent(w,"mousedown",Dialog._parentEvent);
+Dialog._addEvent(w,"focus",Dialog._parentEvent);
+}
+function relwin(w){
+Dialog._removeEvent(w,"click",Dialog._parentEvent);
+Dialog._removeEvent(w,"mousedown",Dialog._parentEvent);
+Dialog._removeEvent(w,"focus",Dialog._parentEvent);
+}
+capwin(window);
+for(var i=0;i<window.frames.length;capwin(window.frames[i++])){
+}
+Dialog._return=function(_e){
+if(_e&&_6){
+_6(_e);
+}
+relwin(window);
+for(var i=0;i<window.frames.length;relwin(window.frames[i++])){
+}
+Dialog._modal=null;
+};
+};
+Dialog._addEvent=function(el,_11,_12){
+if(Dialog.is_ie){
+el.attachEvent("on"+_11,_12);
+}else{
+el.addEventListener(_11,_12,true);
+}
+};
+Dialog._removeEvent=function(el,_14,_15){
+if(Dialog.is_ie){
+el.detachEvent("on"+_14,_15);
+}else{
+el.removeEventListener(_14,_15,true);
+}
+};
+Dialog._stopEvent=function(ev){
+if(Dialog.is_ie){
+ev.cancelBubble=true;
+ev.returnValue=false;
+}else{
+ev.preventDefault();
+ev.stopPropagation();
+}
+};
+Dialog.agt=navigator.userAgent.toLowerCase();
+Dialog.is_ie=((Dialog.agt.indexOf("msie")!=-1)&&(Dialog.agt.indexOf("opera")==-1));
+
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.css
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.css?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.css (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.css Fri Sep 21 03:36:30 2007
@@ -0,0 +1,194 @@
+ body
+ {
+ margin: 0; padding: 0;
+ font: 11px Tahoma,Verdana,sans-serif;
+ }
+ select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+
+ #indicator
+ {
+ width: 25px;
+ height: 20px;
+ background-color: #eef;
+ padding: 15px 20px;
+ position: absolute;
+ left: 0; top: 0;
+ }
+ * html #indicator
+ {
+ padding: 14px 22px;
+ }
+ #tools
+ {
+ width: 600px;
+ height: 50px;
+ background-color: #eef;
+ padding: 0;
+ position: absolute;
+ left: 63px;
+ border-left: 1px solid white;
+ border-bottom: 1px solid white;
+ }
+ #toolbar
+ {
+ width: 53px;
+ height: 435px;
+ background-color: #eef;
+ float: left;
+ text-align: center;
+ padding: 5px;
+ position: absolute;
+ top: 50px;
+ border-top: 1px solid white;
+ border-right: 1px solid white;
+ }
+
+ #contents
+ {
+ width: 600px;
+ height: 445px;
+ position: absolute;
+ left: 64px; top: 51px;
+ }
+
+ #editor
+ {
+ width: 600px;
+ height: 445px;
+ }
+
+ #toolbar a
+ {
+ padding: 5px;
+ width: 40px;
+ display: block;
+ border: 1px solid #eef;
+ text-align: center;
+ text-decoration: none;
+ color: #669;
+ margin: 5px 0;
+ }
+ #toolbar a:hover
+ {
+ background-color: #F9F9FF;
+ border-color: #669;
+ }
+
+ #toolbar a.iconActive
+ {
+ border-color: #669;
+ }
+
+ #toolbar a span
+ {
+ display: block;
+ text-decoration: none;
+
+ }
+ #toolbar a img
+ {
+ border: 0 none;
+ }
+
+ #tools .textInput
+ {
+ width: 3em;
+ vertical-align: 0px;
+
+ }
+ * html #tools .textInput
+ {
+ vertical-align: middle;
+ }
+ #tools .measureStats
+ {
+ width: 4.5em;
+ border: 0 none;
+ background-color: #eef;
+ vertical-align: 0px;
+ }
+ * html #tools .measureStats
+ {
+ vertical-align: middle;
+ }
+ #tools label
+ {
+ margin: 0 2px 0 5px;
+ }
+ #tools input
+ {
+ vertical-align: middle;
+ }
+ #tools #tool_inputs
+ {
+ padding-top: 10px;
+ float: left;
+ }
+ #tools .div
+ {
+ vertical-align: middle;
+ margin: 0 5px;
+ }
+ #tools img
+ {
+ border: 0 none;
+ }
+ #tools a.buttons
+ {
+ margin-top: 10px;
+ border: 1px solid #eef;
+ display: block;
+ float: left;
+ }
+ #tools a.buttons:hover
+ {
+ background-color: #F9F9FF;
+ border-color: #669;
+ }
+ #slidercasing {
+ /*border:1px solid #CCCCCC;
+ background-color:#FFFFFF;*/
+ width:100px;
+ height:5px;
+ position:relative;
+ z-index:4;
+ padding:10px;
+ top: 6px;
+ margin: 0 -5px 0 -10px;
+
+
+}
+
+
+#slidertrack {
+ position:relative;
+ border:1px solid #CCCCCC;
+ background-color:#FFFFCC;
+ z-index:5;
+ height:5px;
+}
+
+
+#sliderbar {
+ position:absolute;
+ z-index:6;
+ border:1px solid #CCCCCC;
+ background-color:#DDDDDD;
+ width:15px;
+ padding:0px;
+ height:20px;
+ cursor: pointer;
+ top:2px;
+}
+
+* html #slidercasing
+{
+ top:0;
+}
+
+
+#bottom
+{
+ position: relative;
+ top: 490px;
+}
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editor.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,127 @@
+var current_action=null;
+var actions=["crop","scale","rotate","measure","save"];
+var orginal_width=null,orginal_height=null;
+function toggle(_1){
+if(current_action!=_1){
+for(var i in actions){
+if(actions[i]!=_1){
+var _3=document.getElementById("tools_"+actions[i]);
+_3.style.display="none";
+var _4=document.getElementById("icon_"+actions[i]);
+_4.className="";
+}
+}
+current_action=_1;
+var _3=document.getElementById("tools_"+_1);
+_3.style.display="block";
+var _4=document.getElementById("icon_"+_1);
+_4.className="iconActive";
+var _5=document.getElementById("indicator_image");
+_5.src="img/"+_1+".gif";
+editor.setMode(current_action);
+if(_1=="scale"){
+var _6=editor.window.document.getElementById("theImage");
+orginal_width=_6.width;
+orginal_height=_6.height;
+var w=document.getElementById("sw");
+w.value=orginal_width;
+var h=document.getElementById("sh");
+h.value=orginal_height;
+}
+}
+}
+function toggleMarker(){
+var _9=document.getElementById("markerImg");
+if(_9!=null&&_9.src!=null){
+if(_9.src.indexOf("t_black.gif")>=0){
+_9.src="img/t_white.gif";
+}else{
+_9.src="img/t_black.gif";
+}
+editor.toggleMarker();
+}
+}
+function toggleConstraints(){
+var _a=document.getElementById("scaleConstImg");
+var _b=document.getElementById("constProp");
+if(_a!=null&&_a.src!=null){
+if(_a.src.indexOf("unlocked2.gif")>=0){
+_a.src="img/islocked2.gif";
+_b.checked=true;
+checkConstrains("width");
+}else{
+_a.src="img/unlocked2.gif";
+_b.checked=false;
+}
+}
+}
+function checkConstrains(_c){
+var _d=document.getElementById("constProp");
+if(_d.checked){
+var w=document.getElementById("sw");
+var _f=w.value;
+var h=document.getElementById("sh");
+var _11=h.value;
+if(orginal_width>0&&orginal_height>0){
+if(_c=="width"&&_f>0){
+h.value=parseInt((_f/orginal_width)*orginal_height);
+}else{
+if(_c=="height"&&_11>0){
+w.value=parseInt((_11/orginal_height)*orginal_width);
+}
+}
+}
+}
+updateMarker("scale");
+}
+function updateMarker(_12){
+if(_12=="crop"){
+var _13=document.getElementById("cx");
+var _14=document.getElementById("cy");
+var _15=document.getElementById("cw");
+var _16=document.getElementById("ch");
+editor.setMarker(parseInt(_13.value),parseInt(_14.value),parseInt(_15.value),parseInt(_16.value));
+}else{
+if(_12=="scale"){
+var _17=document.getElementById("sw");
+var _18=document.getElementById("sh");
+editor.setMarker(0,0,parseInt(_17.value),parseInt(_18.value));
+}
+}
+}
+function rotatePreset(_19){
+var _1a=_19.options[_19.selectedIndex].value;
+if(_1a.length>0&&parseInt(_1a)!=0){
+var ra=document.getElementById("ra");
+ra.value=parseInt(_1a);
+}
+}
+function updateFormat(_1c){
+var _1d=_1c.options[_1c.selectedIndex].value;
+var _1e=_1d.split(",");
+if(_1e.length>1){
+updateSlider(parseInt(_1e[1]));
+}
+}
+function addEvent(obj,_20,fn){
+if(obj.addEventListener){
+obj.addEventListener(_20,fn,true);
+return true;
+}else{
+if(obj.attachEvent){
+var r=obj.attachEvent("on"+_20,fn);
+return r;
+}else{
+return false;
+}
+}
+}
+init=function(){
+var _23=document.getElementById("bottom");
+if(window.opener){
+__dlg_init(_23);
+__dlg_translate("ImageManager");
+}
+};
+addEvent(window,"load",init);
+
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.css
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.css?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.css (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.css Fri Sep 21 03:36:30 2007
@@ -0,0 +1,8 @@
+body { margin: 0; padding: 0; background-color: #eee; }
+table { width: 100%; }
+table td { text-align: center; }
+.crop{cursor:crosshair;}
+.selection { border: dotted 1px #000000; position:absolute; width: 0px; height: 1px; z-index:5; }
+.selectionWhite{ border: dotted 1px #FFFFFF; position:absolute; width: 0px; height: 1px; z-index:5; }
+.handleBox{ z-index:105; }
+.error { font-size:large; font-weight:bold; color:#c00; font-family: Helvetica, sans-serif; }
\ No newline at end of file
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/editorFrame.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,73 @@
+var topDoc=window.top.document;
+var t_cx=topDoc.getElementById("cx");
+var t_cy=topDoc.getElementById("cy");
+var t_cw=topDoc.getElementById("cw");
+var t_ch=topDoc.getElementById("ch");
+var m_sx=topDoc.getElementById("sx");
+var m_sy=topDoc.getElementById("sy");
+var m_w=topDoc.getElementById("mw");
+var m_h=topDoc.getElementById("mh");
+var m_a=topDoc.getElementById("ma");
+var m_d=topDoc.getElementById("md");
+var s_sw=topDoc.getElementById("sw");
+var s_sh=topDoc.getElementById("sh");
+var r_ra=topDoc.getElementById("ra");
+var pattern="img/2x2.gif";
+function doSubmit(_1){
+if(_1=="crop"){
+var _2=_backend_url+"__function=editorFrame&img="+currentImageFile+"&action=crop¶ms="+parseInt(t_cx.value)+","+parseInt(t_cy.value)+","+parseInt(t_cw.value)+","+parseInt(t_ch.value);
+location.href=_2;
+}else{
+if(_1=="scale"){
+var _2=_backend_url+"__function=editorFrame&img="+currentImageFile+"&action=scale¶ms="+parseInt(s_sw.value)+","+parseInt(s_sh.value);
+location.href=_2;
+}else{
+if(_1=="rotate"){
+var _3=topDoc.getElementById("flip");
+if(_3.value=="hoz"||_3.value=="ver"){
+location.href=_backend_url+"__function=editorFrame&img="+currentImageFile+"&action=flip¶ms="+_3.value;
+}else{
+if(isNaN(parseFloat(r_ra.value))==false){
+location.href=_backend_url+"__function=editorFrame&img="+currentImageFile+"&action=rotate¶ms="+parseFloat(r_ra.value);
+}
+}
+}else{
+if(_1=="save"){
+var _4=topDoc.getElementById("save_filename");
+var _5=topDoc.getElementById("save_format");
+var _6=topDoc.getElementById("quality");
+var _7=_5.value.split(",");
+if(_4.value.length<=0){
+alert(i18n("Please enter a filename to save."));
+}else{
+var _8=encodeURI(_4.value);
+var _9=parseInt(_6.value);
+var _2=_backend_url+"__function=editorFrame&img="+currentImageFile+"&action=save¶ms="+_7[0]+","+_9+"&file="+_8;
+location.href=_2;
+}
+}
+}
+}
+}
+}
+function addEvent(_a,_b,fn){
+if(_a.addEventListener){
+_a.addEventListener(_b,fn,true);
+return true;
+}else{
+if(_a.attachEvent){
+var r=_a.attachEvent("on"+_b,fn);
+return r;
+}else{
+return false;
+}
+}
+}
+var jg_doc;
+init=function(){
+jg_doc=new jsGraphics("imgCanvas");
+jg_doc.setColor("#000000");
+initEditor();
+};
+addEvent(window,"load",init);
+
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/hover.htc
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/hover.htc?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/hover.htc (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/hover.htc Fri Sep 21 03:36:30 2007
@@ -0,0 +1,34 @@
+<attach event="onmouseover" handler="hoverRollOver" />
+<attach event="onmouseout" handler="hoverRollOff" />
+<script type="text/javascript">
+//
+// Simple behaviour for IE5+ to emulate :hover CSS pseudo-class.
+// Experimental ver 0.1
+//
+// This is an experimental version! Handle with care!
+// Manual at: http://www.hszk.bme.hu/~hj130/css/list_menu/hover/
+//
+
+function hoverRollOver() {
+
+ element.origClassName = element.className; // backup origonal className
+
+ var tempClassStr = element.className;
+
+ tempClassStr += "Hover"; // convert name+'Hover' the last class name to emulate tag.class:hover
+
+ tempClassStr = tempClassStr.replace(/\s/g,"Hover "); //convert name+'Hover' the others to emulate tag.class:hover
+
+ tempClassStr += " hover"; // add simple 'hover' class name to emulate tag:hover
+
+ element.className = element.className + " " + tempClassStr;
+
+ //alert(element.className);
+ //window.status = element.className; // only for TEST
+}
+function hoverRollOff() {
+ element.className = element.origClassName;
+}
+
+</script>
+
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/imagelist.css
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/imagelist.css?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/imagelist.css (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/assets/imagelist.css Fri Sep 21 03:36:30 2007
@@ -0,0 +1,46 @@
+body { margin: 0; padding: 0; }
+.edit { font-size: small; font-family: small-caption, sans-serif; padding-top: 3px;}
+.edit a { border: none; padding: 3px; text-decoration:none; }
+.edit a:hover { background-color: ButtonHighlight; }
+.edit a img { border: none; vertical-align: bottom; }
+.noResult { font-size:large; font-weight:bold; color:#ccc; font-family: Helvetica, sans-serif; text-align: center; padding-top: 60px; }
+.error { color:#c00; font-weight:bold; font-size: medium; font-family: Helvetica, sans-serif; text-align: center; padding-top: 65px;}
+
+.dir_holder, .thumb_holder
+{
+ width:110px; height:132px;
+ float:left;
+ margin:6px;
+ background-color:ButtonFace;
+ border: 1px outset;
+}
+
+.thumb_holder.active
+{
+ background:Highlight;
+ color:HighlightText;
+ border:1px dashed Highlight;
+}
+
+.dir_holder a.dir, .thumb_holder a.thumb
+{
+ height:100px;
+ display:block;
+ text-align:center;
+ padding:5px;
+ text-decoration:none;
+}
+
+.thumb_holder a.thumb img
+{
+ border:1px solid black;
+}
+
+.dir_holder a.dir img
+{
+ border:none;
+}
+.listview { width:100% }
+.listview td, .listview th { text-align:left; font-size:small; }
+.listview td.actions { text-align:right; }
+.listview td.actions img { border:0px; }
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.