From 83df70452906599e27bf7d18c67119c03a81dc0a Mon Sep 17 00:00:00 2001 From: Pierre-Luc Paour Date: Fri, 1 Jun 2007 15:54:17 +0000 Subject: [PATCH] 2007-06-01 Pierre-Luc Paour (1.5.1-b32) * Fixed detection of ImageMagick and jpegtran when running from a stripped Jar. * Removed enabling beta support for OpenGL when starting GR, it was causing some video drivers to crash. * Fixed URL to Codex when IM or jpegtran is missing. * Added signature for some of the Jars so they can be started by WebStart and still have full permissions. * Added ability to pre-set Gallery to a specific URL by passing the command-line parameters -url and -username . * Added support for golden section (in addition to rule of thirds) for cropping. * Fixed slideshow issue when transitions are disabled (the wrong image would be shown). --- ChangeLog | 16 +++++ build.xml | 4 ++ com/gallery/GalleryRemote/GalleryRemote.java | 63 +++++++++++++++++- com/gallery/GalleryRemote/MainFrame.java | 2 +- com/gallery/GalleryRemote/PreviewFrame.java | 61 +++++++++-------- com/gallery/GalleryRemote/SlideshowFrame.java | 8 ++- com/gallery/GalleryRemote/model/Gallery.java | 10 +-- .../GalleryRemote/prefs/PreferenceNames.java | 4 +- .../resources/GRResources.properties | 10 +-- .../GalleryRemote/util/ImageUtils.java | 48 ++++++++----- defaults.properties | 34 +++++----- lib/metadata-extractor-2.1.jar | Bin 65152 -> 69726 bytes 12 files changed, 181 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index 26ff8ff..1c0df88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2007-06-01 Pierre-Luc Paour (1.5.1-b32) + + * Fixed detection of ImageMagick and jpegtran when running + from a stripped Jar. + * Removed enabling beta support for OpenGL when starting GR, + it was causing some video drivers to crash. + * Fixed URL to Codex when IM or jpegtran is missing. + * Added signature for some of the Jars so they can be started + by WebStart and still have full permissions. + * Added ability to pre-set Gallery to a specific URL by passing + the command-line parameters -url and -username . + * Added support for golden section (in addition to rule of thirds) + for cropping. + * Fixed slideshow issue when transitions are disabled (the wrong + image would be shown). + 2007-02-14 Pierre-Luc Paour (1.5.1-b31) * Fixed missing string for slideshow preferences. diff --git a/build.xml b/build.xml index 225ba51..0970c11 100644 --- a/build.xml +++ b/build.xml @@ -73,6 +73,8 @@ + + @@ -178,10 +180,12 @@ + + = 1.6) { System.setProperty("sun.java2d.opengl", "true"); } } catch (RuntimeException e) { Log.log(Log.LEVEL_ERROR, "Couldn't get property java.specification.version: " + System.getProperty("java.specification.version")); - } + }*/ } public void createProperties() { diff --git a/com/gallery/GalleryRemote/MainFrame.java b/com/gallery/GalleryRemote/MainFrame.java index c583619..60ad7f0 100644 --- a/com/gallery/GalleryRemote/MainFrame.java +++ b/com/gallery/GalleryRemote/MainFrame.java @@ -1334,7 +1334,7 @@ public void actionPerformed(ActionEvent e) { // so ask the user if it's OK to log out. if (JOptionPane.showConfirmDialog( (JFrame) this, - GRI18n.getString(MODULE, "logoutQuestion"), + GRI18n.getString(MODULE, "logoutQuestion", new Object[] {getCurrentGallery()}), "Warning", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) { return; diff --git a/com/gallery/GalleryRemote/PreviewFrame.java b/com/gallery/GalleryRemote/PreviewFrame.java index e5f6e74..e9ad90a 100755 --- a/com/gallery/GalleryRemote/PreviewFrame.java +++ b/com/gallery/GalleryRemote/PreviewFrame.java @@ -196,17 +196,8 @@ public void paint(Graphics g) { g.setColor(Color.black); g.drawRect(cacheRect.x, cacheRect.y, cacheRect.width, cacheRect.height); - if (GalleryRemote._().properties.getBooleanProperty(PREVIEW_DRAW_THIRDS, false)) { - g.setColor(background); - g.drawLine(cacheRect.x + cacheRect.width / 3, cacheRect.y, - cacheRect.x + cacheRect.width / 3, cacheRect.y + cacheRect.height); - g.drawLine(cacheRect.x + cacheRect.width *2 / 3, cacheRect.y, - cacheRect.x + cacheRect.width * 2 / 3, cacheRect.y + cacheRect.height); - g.drawLine(cacheRect.x, cacheRect.y + cacheRect.height / 3, - cacheRect.x + cacheRect.width, cacheRect.y + cacheRect.height / 3); - g.drawLine(cacheRect.x, cacheRect.y + cacheRect.height * 2 / 3, - cacheRect.x + cacheRect.width, cacheRect.y + cacheRect.height * 2 / 3); - } + g.setColor(background); + drawThirds(g, cacheRect); g.setClip(null); } catch (NoninvertibleTransformException e) { @@ -254,16 +245,7 @@ public void updateRect() { g.setXORMode(Color.cyan); g.drawRect(oldRect.x, oldRect.y, oldRect.width, oldRect.height); - if (GalleryRemote._().properties.getBooleanProperty(PREVIEW_DRAW_THIRDS, false)) { - g.drawLine(oldRect.x + oldRect.width / 3, oldRect.y, - oldRect.x + oldRect.width / 3, oldRect.y + oldRect.height); - g.drawLine(oldRect.x + oldRect.width *2 / 3, oldRect.y, - oldRect.x + oldRect.width * 2 / 3, oldRect.y + oldRect.height); - g.drawLine(oldRect.x, oldRect.y + oldRect.height / 3, - oldRect.x + oldRect.width, oldRect.y + oldRect.height / 3); - g.drawLine(oldRect.x, oldRect.y + oldRect.height * 2 / 3, - oldRect.x + oldRect.width, oldRect.y + oldRect.height * 2 / 3); - } + drawThirds(g, oldRect); } if (inDrag) { @@ -271,16 +253,33 @@ public void updateRect() { oldRect = getRect(start, end); g.drawRect(oldRect.x, oldRect.y, oldRect.width, oldRect.height); - if (GalleryRemote._().properties.getBooleanProperty(PREVIEW_DRAW_THIRDS, false)) { - g.drawLine(oldRect.x + oldRect.width / 3, oldRect.y, - oldRect.x + oldRect.width / 3, oldRect.y + oldRect.height); - g.drawLine(oldRect.x + oldRect.width *2 / 3, oldRect.y, - oldRect.x + oldRect.width * 2 / 3, oldRect.y + oldRect.height); - g.drawLine(oldRect.x, oldRect.y + oldRect.height / 3, - oldRect.x + oldRect.width, oldRect.y + oldRect.height / 3); - g.drawLine(oldRect.x, oldRect.y + oldRect.height * 2 / 3, - oldRect.x + oldRect.width, oldRect.y + oldRect.height * 2 / 3); - } + drawThirds(g, oldRect); + } + } + + private void drawThirds(Graphics g, Rectangle r) { + if (GalleryRemote._().properties.getBooleanProperty(PREVIEW_DRAW_THIRDS, false) + || "thirds".equals(GalleryRemote._().properties.getProperty(PREVIEW_DRAW_THIRDS))) { + g.drawLine(r.x + r.width / 3, r.y, + r.x + r.width / 3, r.y + r.height); + g.drawLine(r.x + r.width * 2 / 3, r.y, + r.x + r.width * 2 / 3, r.y + r.height); + g.drawLine(r.x, r.y + r.height / 3, + r.x + r.width, r.y + r.height / 3); + g.drawLine(r.x, r.y + r.height * 2 / 3, + r.x + r.width, r.y + r.height * 2 / 3); + } else if ("golden".equals(GalleryRemote._().properties.getProperty(PREVIEW_DRAW_THIRDS))) { + double p = 1.6180339887499; + double gw = r.width * p / (2 * p + 1); + double gh = r.height * p / (2 * p + 1); + g.drawLine((int) (oldRect.x + gw), oldRect.y, + (int) (oldRect.x + gw), oldRect.y + oldRect.height); + g.drawLine((int) (oldRect.x + oldRect.width - gw), oldRect.y, + (int) (oldRect.x + oldRect.width - gw), oldRect.y + oldRect.height); + g.drawLine(oldRect.x, (int) (oldRect.y + gh), + oldRect.x + oldRect.width, (int) (oldRect.y + gh)); + g.drawLine(oldRect.x, (int) (oldRect.y + oldRect.height - gh), + oldRect.x + oldRect.width, (int) (oldRect.y + oldRect.height -gh)); } } diff --git a/com/gallery/GalleryRemote/SlideshowFrame.java b/com/gallery/GalleryRemote/SlideshowFrame.java index c55087a..167c831 100644 --- a/com/gallery/GalleryRemote/SlideshowFrame.java +++ b/com/gallery/GalleryRemote/SlideshowFrame.java @@ -612,13 +612,15 @@ public void initTransitionDuration() { Log.log(Log.LEVEL_TRACE, MODULE, "Is graphics accelerated: " + accelerated); enableTransitions = accelerated - || GalleryRemote._().properties.getBooleanProperty(UNACCELERATED_TRANSITION, false); + || GalleryRemote._().properties.getBooleanProperty(ALLOW_UNACCELERATED_TRANSITION, false); transitionDuration = enableTransitions? GalleryRemote._().properties.getIntProperty(SLIDESHOW_TRANSITION_DURATION, 3000):0; if (transitionDuration == 0) { enableTransitions = false; } + + Log.log(Log.LEVEL_TRACE, MODULE, "Transitions enabled: " + enableTransitions); } class SlideshowPane extends JPanel implements ActionListener { @@ -725,11 +727,15 @@ public void paintPicture(Graphics2D g) { if (! timer.isRunning()) { timer.start(); } + } else { + imageAlpha = 1; } } Composite composite = g.getComposite(); + Log.log(Log.LEVEL_TRACE, MODULE, "Painting alpha=" + imageAlpha); + if (imageAlpha != 1 && previousImage != null) { g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1 - imageAlpha)); g.drawImage(previousImage, previousRect.x, previousRect.y, getContentPane()); diff --git a/com/gallery/GalleryRemote/model/Gallery.java b/com/gallery/GalleryRemote/model/Gallery.java index fcb4563..d4bb313 100644 --- a/com/gallery/GalleryRemote/model/Gallery.java +++ b/com/gallery/GalleryRemote/model/Gallery.java @@ -308,7 +308,7 @@ public void setStUrlString(String urlString) { stUrlString = reformatUrlString(urlString, true); if (!blockWrites && stUrlString != null) { - GalleryRemote._().properties.setProperty(URL + prefsIndex, stUrlString); + GalleryRemote._().properties.setProperty(GURL + prefsIndex, stUrlString); } } @@ -634,7 +634,7 @@ public static Gallery readFromProperties(GalleryProperties p, int prefsIndex, St } public static Gallery readFromProperties(GalleryProperties p, int prefsIndex, StatusUpdate su, boolean mustHaveUsername) { - String url = p.getProperty(URL + prefsIndex); + String url = p.getProperty(GURL + prefsIndex); String username = p.getProperty(USERNAME + prefsIndex, true); if (mustHaveUsername && username == null) { @@ -688,9 +688,9 @@ public static Gallery readFromProperties(GalleryProperties p, int prefsIndex, St } public void writeToProperties(PropertiesFile p) { - Log.log(Log.LEVEL_TRACE, MODULE, "Wrote to properties: " + toString()); + Log.log(Log.LEVEL_TRACE, MODULE, "Writing to properties: " + toString()); - p.setProperty(URL + prefsIndex, stUrlString); + p.setProperty(GURL + prefsIndex, stUrlString); p.setProperty(USERNAME + prefsIndex, username); if (getPassword() != null && p.getBooleanProperty(SAVE_PASSWORDS)) { p.setBase64Property(PASSWORD + prefsIndex, password); @@ -729,7 +729,7 @@ public void writeToProperties(PropertiesFile p) { public static void removeFromProperties(PropertiesFile p, int n) { Log.log(Log.LEVEL_TRACE, MODULE, "Removed from properties: " + n); - p.setProperty(URL + n, null); + p.setProperty(GURL + n, null); p.setProperty(USERNAME + n, null); p.setProperty(PASSWORD + n, null); p.setProperty(TYPE + n, null); diff --git a/com/gallery/GalleryRemote/prefs/PreferenceNames.java b/com/gallery/GalleryRemote/prefs/PreferenceNames.java index 148b8aa..d99d5c9 100644 --- a/com/gallery/GalleryRemote/prefs/PreferenceNames.java +++ b/com/gallery/GalleryRemote/prefs/PreferenceNames.java @@ -36,7 +36,7 @@ public interface PreferenceNames { public static final String USERNAME = "username."; public static final String PASSWORD = "password."; public static final String TYPE = "type."; - public static final String URL = "url."; + public static final String GURL = "url."; public static final String STANDALONE = "Standalone"; public static final String POSTNUKE = "PostNuke"; public static final String PHPNUKE = "PHPNuke"; @@ -92,7 +92,7 @@ public interface PreferenceNames { public static final String FONT_OVERRIDE_STYLE = "fontOverrideStyle"; public static final String FONT_OVERRIDE_SIZE = "fontOverrideSize"; public static final String PREVIEW_TRANSITION_DURATION = "previewTransitionDuration"; - public static final String UNACCELERATED_TRANSITION = "unacceleratedTransition"; + public static final String ALLOW_UNACCELERATED_TRANSITION = "allowUnacceleratedTransition"; public static final String PREVIEW_DRAW_THIRDS = "previewDrawThirds"; // Applet diff --git a/com/gallery/GalleryRemote/resources/GRResources.properties b/com/gallery/GalleryRemote/resources/GRResources.properties index de6ab60..5e49779 100644 --- a/com/gallery/GalleryRemote/resources/GRResources.properties +++ b/com/gallery/GalleryRemote/resources/GRResources.properties @@ -156,8 +156,8 @@ SlidePa.extra=Extra SlidePa.extraHelp=Location of the extra fields information SlidePa.url=URL SlidePa.urlHelp=Location of the URL -SlidePa.url=Album -SlidePa.urlHelp=Location of the name of the album +SlidePa.album=Album +SlidePa.albumHelp=Location of the name of the album SlidePa.lowRez=Force download of lower-resolution pictures SlidePa.lowRezHelp=Check this option to make downloading images faster, so the slideshow goes faster SlidePa.random=Random order @@ -490,19 +490,19 @@ ImageUtils.warningTextIM=An optional part of Gallery Remote, ImageMagic or is malfunctioning. Gallery Remote will not be able to resize images before
\ uploading them, and loading thumbnails and previews will be much slower.
\ You can find out how to fix this by going to this page: -ImageUtils.warningUrlIM=http://codex.gallery2.org/index.php/Gallery_Remote_Bundled +ImageUtils.warningUrlIM=http://codex.gallery2.org/index.php/Gallery_Remote:Bundled ImageUtils.warningUrlTextIM=Gallery Remote Bundled ImageUtils.warningTextJpegtran=An optional part of Gallery Remote, jpegtran, could not be found
\ or is malfunctioning. Gallery Remote will not be able to rotate images before
\ uploading them.
\ You can find out how to fix this by going to this page: -ImageUtils.warningUrlJpegtran=http://codex.gallery2.org/index.php/Gallery_Remote_Bundled +ImageUtils.warningUrlJpegtran=http://codex.gallery2.org/index.php/Gallery_Remote:Bundled ImageUtils.warningUrlTextJpegtran=Gallery Remote Bundled ImageUtils.warningTextJpegtranCrop=An optional part of Gallery Remote, jpegtran, could not be found
\ or is malfunctioning for the purpose of cropping pictures. Gallery Remote will not be able to losslessly crop images before
\ uploading them.
\ You can find out how to fix this by going to this page: -ImageUtils.warningUrlJpegtranCrop=http://codex.gallery2.org/index.php/Gallery_Remote_Bundled +ImageUtils.warningUrlJpegtranCrop=http://codex.gallery2.org/index.php/Gallery_Remote:Bundled ImageUtils.warningUrlTextJpegtranCrop=Gallery Remote Bundled ImageUtils.warningTextJava=Using Java as a fallback to resize pictures will cause them to lose their EXIF data.
\ Do you want to resize with Gallery Remote anyway, or let the server perform the resize (longer upload time). diff --git a/com/gallery/GalleryRemote/util/ImageUtils.java b/com/gallery/GalleryRemote/util/ImageUtils.java index 438a86f..fc829a2 100644 --- a/com/gallery/GalleryRemote/util/ImageUtils.java +++ b/com/gallery/GalleryRemote/util/ImageUtils.java @@ -859,19 +859,25 @@ public static Dimension getPictureDimension(Picture p) { // Making sure ImageMagick works try { - PropertiesFile pt; + PropertiesFile pt = null; + if (new File("imagemagick/im.properties").exists()) { pt = new PropertiesFile("imagemagick/im"); - } else { + } else if (new File("im.properties").exists()) { pt = new PropertiesFile("im"); } - // force exception handling if file is missing - pt.read(); + GalleryProperties p = null; + + if (pt != null) { + pt.read(); - // allow overriding from main property file - GalleryProperties p = new GalleryProperties(pt); - GalleryRemote._().defaults.copyProperties(p); + // allow overriding from main property file + p = new GalleryProperties(pt); + GalleryRemote._().defaults.copyProperties(p); + } else { + p = GalleryRemote._().defaults; + } p = GalleryRemote._().properties; @@ -973,20 +979,26 @@ public static Dimension getPictureDimension(Picture p) { // Making sure jpegtran works try { - PropertiesFile pt; + PropertiesFile pt = null; + if (new File("jpegtran/jpegtran.properties").exists()) { pt = new PropertiesFile("jpegtran/jpegtran"); - } else { + } else if (new File("jpegtran.properties").exists()) { pt = new PropertiesFile("jpegtran"); } - // force exception handling if file is missing - pt.read(); + GalleryProperties p = null; - // allow overriding from main property file - GalleryProperties p = new GalleryProperties(pt); - GalleryRemote._().defaults.copyProperties(p); + if (pt != null) { + pt.read(); + // allow overriding from main property file + p = new GalleryProperties(pt); + GalleryRemote._().defaults.copyProperties(p); + } else { + p = GalleryRemote._().defaults; + } + p = GalleryRemote._().properties; useJpegtran = p.getBooleanProperty("jp.enabled"); @@ -996,14 +1008,18 @@ public static Dimension getPictureDimension(Picture p) { jpegtranPath = p.getProperty("jp.path"); Log.log(Log.LEVEL_INFO, MODULE, "jpegtranPath: " + jpegtranPath); + if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1 + && !jpegtranPath.endsWith(".exe")) { + jpegtranPath += ".exe"; + } + jpegtranIgnoreErrorCode = p.getBooleanProperty("jp.ignoreErrorCode", jpegtranIgnoreErrorCode); Log.log(Log.LEVEL_INFO, MODULE, "jpegtranIgnoreErrorCode: " + jpegtranIgnoreErrorCode); if (jpegtranPath.indexOf('/') == -1 && jpegtranPath.indexOf('\\') == -1) { Log.log(Log.LEVEL_CRITICAL, MODULE, "jpegtran path is not fully qualified, " + "presence won't be tested until later"); - } - if (!new File(jpegtranPath).exists()) { + } else if (!new File(jpegtranPath).exists()) { Log.log(Log.LEVEL_CRITICAL, MODULE, "Can't find jpegtran at the above path"); stopUsingJpegtran(); } diff --git a/defaults.properties b/defaults.properties index fa3f096..3186af5 100644 --- a/defaults.properties +++ b/defaults.properties @@ -86,8 +86,9 @@ showPreview=true # use less if you have little memory) previewCacheSize=10 -# Draw 1/3 guidelines during crop -previewDrawThirds=true +# Draw rule of thirds guidelines during crop +# (true or thirds for rule of thirds, golden for golden section) +previewDrawThirds=golden # display the image path in the list showPath=true @@ -202,6 +203,9 @@ slideshowFontThickness= # How long the transition between two images should be, in milliseconds (0 to disable transition) slideshowTransitionDuration=1000 +# Whether to allow transitions even if they aren't accelerated by Java2D +allowUnacceleratedTransition=false + # # --- Applet --- # @@ -231,13 +235,13 @@ fontOverrideSize= # # should jpegtran support be enabled? -jp.enabled= +jp.enabled=true # should lossless cropping be enabled? -jp.crop.enabled= +jp.crop.enabled=true # path to the executable -jp.path= +jp.path=jpegtran # ignore error code sent back by the executable # there's a bug in the Linux Java VM that returns a failed code @@ -249,34 +253,34 @@ jp.ignoreErrorCode= # # should ImageMagick support be enabled? -im.enabled= +im.enabled=true # path to the convert executable installed with ImageMagick -im.convertPath= +im.convertPath=convert # Filters (Point, Box, Triangle, Hermite, Hanning, Hamming, Blackman, Gaussian # Quadratic, Cubic, Catrom, Mitchell, Lanczos, Bessel, Sinc) # filter used for resize of thumbnails -im.thumbnailResizeFilter= +im.thumbnailResizeFilter=Lanczos # filter used for resize of preview -im.previewResizeFilter= +im.previewResizeFilter=Lanczos # filter used for resize of upload -im.uploadResizeFilter= +im.uploadResizeFilter=Lanczos # Formats # jpg Better for large images # gif Better for small images (8-bit) # filter used for resize of thumbnails -im.thumbnailResizeFormat= +im.thumbnailResizeFormat=gif # filter used for resize of preview -im.previewResizeFormat= +im.previewResizeFormat=jpeg # jpeg quality -im.jpegQuality= +im.jpegQuality=85 # ignore error code sent back by the executable # there's a bug in the Linux Java VM that returns a failed code @@ -318,6 +322,6 @@ updateUrlBeta=http://gallery.sourceforge.net/gallery_remote_version_check_beta.p # # --- Do not edit below this line --- # -version=1.5.1-b31 -releaseDate=2007/02/14 +version=1.5.1-b32 +releaseDate=2007/06/01 aboutText=Gallery Remote\n \n \nA part of the Gallery Open-Source Project\nhttp://gallery.sourceforge.net\n \n \nMaintained by:\n \nPierre-Luc Paour\n \n \nInitial version by Chris Smith\n \n \nContributors:\n \nTim Miller\nDolan Halbrook\nMarkus Cozowicz\nScott Gartner\nAmedeo Paglione\nChris Schwerdt\nSeth Ladd\n \n \nArtwork by Ross A. Reyman\n \n \nBundled software:\n \nImageMagick\nJava look and feel Graphics Repository icons\njpegtran, Guido Vollbeding's version\nMetadataExtractor\nSaverBeans diff --git a/lib/metadata-extractor-2.1.jar b/lib/metadata-extractor-2.1.jar index 8681d5652eb30441806ee7af0cc8417bc8baeafd..5f420d03fd80064e0d256ee1a17b148504bea9d1 100644 GIT binary patch delta 5376 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