From 4b15b36d2837e9492f812798e694488332df50cc Mon Sep 17 00:00:00 2001
From: lolandese <lolandese@210402.no-reply.drupal.org>
Date: Fri, 24 Jul 2015 23:54:48 +0200
Subject:  lolandese: Generated with Drush iq

---
 block/flickr_block.admin.inc                 |   18 ++-
 cachewarmer/flickrcachewarmer.admin.inc      |    3 +-
 filter/flickr_filter.admin.inc               |    2 +
 flickr.admin.inc                             |  169 +++++++++++++++++---
 flickr.css                                   |   28 +++-
 flickr.info                                  |    2 +
 flickr.install                               |    8 +
 flickr.module                                |   41 +++--
 sets/flickr_sets.admin.inc                   |   12 +-
 style/css/flickrstyle.css                    |   12 ++
 style/css/flickrstyle_big.css                |   18 ++-
 style/css/flickrstyle_border.css             |    8 +-
 style/css/flickrstyle_bordernoshadow.css     |   10 +-
 style/css/flickrstyle_caption_border.css     |    7 +-
 style/css/flickrstyle_caption_shadow.css     |    8 +-
 style/css/flickrstyle_enlarge.css            |   10 +-
 style/css/flickrstyle_magnifier.css          |   16 +-
 style/css/flickrstyle_rounded.css            |    6 +-
 style/css/flickrstyle_shadow.css             |    6 +-
 style/css/flickrstyle_wrapcaption_border.css |    6 +-
 style/css/flickrstyle_wrapcaption_shadow.css |    8 +-
 style/css/flickrstyle_zoom.css               |   10 +-
 style/flickrstyle.admin.inc                  |  212 +++++++++++++++++++++++---
 style/flickrstyle.install                    |    2 +
 style/flickrstyle.module                     |    4 +
 tags/flickr_tags.admin.inc                   |   37 ++++-
 tags/flickr_tags.module                      |    4 +-
 27 files changed, 534 insertions(+), 133 deletions(-)
 create mode 100644 style/css/flickrstyle.css

diff --git a/block/flickr_block.admin.inc b/block/flickr_block.admin.inc
index 2ccc42b..8b36c71 100644
--- a/block/flickr_block.admin.inc
+++ b/block/flickr_block.admin.inc
@@ -21,6 +21,8 @@ function flickr_block_form_flickr_admin_settings_alter(&$form, &$form_state) {
     '#required' => TRUE,
     '#default_value' => variable_get('flickr_block_heading', 'h2'),
     '#description' => t("Use 'p' for no style, e.g. 'h2' for a heading or 'none' to not display an album title."),
+    '#field_prefix' => t('<'),
+    '#field_suffix' => t('>'),
     '#size' => 4,
     '#maxlength' => 4,
   );
@@ -32,6 +34,7 @@ function flickr_block_form_flickr_admin_settings_alter(&$form, &$form_state) {
     '#field_suffix' => t('hours.'),
     '#size' => 3,
     '#maxlength' => 3,
+    '#attributes' => array('class' => array('flickr-form-align')),
   );
   $cache_warming = l(t('cache warming'), 'https://drupal.org/node/1576686/', array(
     'attributes' => array(
@@ -48,6 +51,7 @@ function flickr_block_form_flickr_admin_settings_alter(&$form, &$form_state) {
     '#field_suffix' => t('hours.'),
     '#size' => 3,
     '#maxlength' => 3,
+    '#attributes' => array('class' => array('flickr-form-align')),
   );
   $form['block_settings']['flickr_block_photos_per_set'] = array(
     '#type' => 'textfield',
@@ -65,19 +69,19 @@ function flickr_block_form_flickr_admin_settings_alter(&$form, &$form_state) {
  * Validate user input.
  */
 function flickr_block_admin_settings_validate($form, &$form_state) {
-  $limit5 = trim($form_state['values']['flickr_block_refresh_random']);
-  $limit6 = trim($form_state['values']['flickr_block_refresh_others']);
-  $limit10 = trim($form_state['values']['flickr_block_photos_per_set']);
   // Validate refresh rate random blocks.
-  if (!is_numeric($limit5) || $limit5 < 2) {
+  $limit = trim($form_state['values']['flickr_block_refresh_random']);
+  if (!is_numeric($limit) || $limit < 2) {
     form_set_error('flickr_block_refresh_random', t('Set a number from 2 to 999.'));
   }
   // Validate refresh rate other blocks.
-  if (!is_numeric($limit6) || $limit6 < 2) {
+  $limit = trim($form_state['values']['flickr_block_refresh_others']);
+  if (!is_numeric($limit) || $limit < 2) {
     form_set_error('flickr_block_refresh_others', t('Set a number from 2 to 999.'));
   }
   // Validate photos per set.
-  if (!is_numeric($limit10) || $limit10 < 1) {
-    form_set_error('flickr_block_photos_per_set', t('Set a number from 1 to 99.'));
+  $limit = trim($form_state['values']['flickr_block_photos_per_set']);
+  if (!ctype_digit($limit) || $limit < 1) {
+    form_set_error('flickr_block_photos_per_set', t('Set an integer from 1 to 99.'));
   }
 }
diff --git a/cachewarmer/flickrcachewarmer.admin.inc b/cachewarmer/flickrcachewarmer.admin.inc
index 10784d5..c703b47 100644
--- a/cachewarmer/flickrcachewarmer.admin.inc
+++ b/cachewarmer/flickrcachewarmer.admin.inc
@@ -59,7 +59,7 @@ function flickrcachewarmer_form_flickr_admin_settings_alter(&$form, &$form_state
     '#type' => 'checkbox',
     '#title' => t("Rebuild the cache on form submit to enhance performance for all page visits after saving this form."),
     '#default_value' => variable_get('flickrcachewarmer_run', 0),
-    '#description' => t("Note that form submit will very slow. The cache will be rebuilt for the nodes of the selected content types for cache warming.") . '<br />' . t("If you get errors, try to !runcron.", array('!runcron' => $runcron)),
+    '#description' => t("Note that form submit will be very slow. The cache will be rebuilt for the nodes of the selected content types for cache warming.") . '<br />' . t("If you get errors, try to !runcron.", array('!runcron' => $runcron)),
     '#weight' => 98,
   );
 }
@@ -68,6 +68,7 @@ function flickrcachewarmer_form_flickr_admin_settings_alter(&$form, &$form_state
  * Validate user input.
  */
 function flickrcachewarmer_admin_settings_validate($form, &$form_state) {
+  // Put validation rules here.
 }
 
 /**
diff --git a/filter/flickr_filter.admin.inc b/filter/flickr_filter.admin.inc
index 511ab04..10430c9 100644
--- a/filter/flickr_filter.admin.inc
+++ b/filter/flickr_filter.admin.inc
@@ -40,6 +40,8 @@ function flickr_filter_form_flickr_admin_settings_alter(&$form, &$form_state) {
     '#required' => TRUE,
     '#default_value' => variable_get('flickr_filter_heading', 'p'),
     '#description' => t("Use 'p' for no style, e.g. 'h3' for a heading or 'none' to not display an album title."),
+    '#field_prefix' => t('<'),
+    '#field_suffix' => t('>'),
     '#size' => 4,
     '#maxlength' => 4,
   );
diff --git a/flickr.admin.inc b/flickr.admin.inc
index b8a82b3..e4411f9 100644
--- a/flickr.admin.inc
+++ b/flickr.admin.inc
@@ -48,7 +48,7 @@ function flickr_admin_settings() {
     '#type' => 'textfield',
     '#title' => t('Default Flickr User ID'),
     '#default_value' => $default,
-    '#description' => t('An, optional, default Flickr user (number@number, alias, username or email). This will be used when no user is specified.'),
+    '#description' => t('An optional default Flickr user (number@number, alias, username or email). This will be used when no user is specified.'),
   );
   // We need an api key before we can verify usernames.
   if (!$form['credentials']['flickr_api_key']['#default_value']) {
@@ -109,6 +109,7 @@ function flickr_admin_settings() {
     '#field_suffix' => t('px'),
     '#size' => 3,
     '#maxlength' => 3,
+    '#attributes' => array('class' => array('flickr-form-align')),
   );
   $form['info_settings']['flickr_metadata_suppress_on_small'] = array(
     '#type' => 'textfield',
@@ -119,6 +120,7 @@ function flickr_admin_settings() {
     '#field_suffix' => t('px'),
     '#size' => 3,
     '#maxlength' => 3,
+    '#attributes' => array('class' => array('flickr-form-align')),
   );
   $rubular = l(t('http://rubular.com/r/RhKjj9Thy1'), 'http://rubular.com/r/RhKjj9Thy1', array(
       'attributes' => array(
@@ -131,7 +133,7 @@ function flickr_admin_settings() {
     '#type' => 'textfield',
     '#title' => t("Replace photo titles matching this Regular Expression with 'View on Flickr'"),
     '#default_value' => variable_get('flickr_regex', '^[a-zA-Z]+[^\s][0-9]+$'),
-    '#description' => t("Avoids camera generated titles like e.g. 'IMG_4259'. Try your own RegEx first with !rubular. Leave empty to NOT replace any titles.", array('!rubular' => $rubular)),
+    '#description' => t("Avoids camera generated titles like 'IMG_4259'. Try your own RegEx first with !rubular. Leave empty to NOT replace any titles.", array('!rubular' => $rubular)),
     '#field_prefix' => t('/'),
     '#field_suffix' => t('/'),
     '#size' => 60,
@@ -213,8 +215,8 @@ function flickr_admin_settings() {
     '#title' => t('Counter thousands separator'),
     '#default_value' => variable_get('flickr_thousands_sep', ','),
     '#description' => t('Common values are NULL, a dot ("."), a comma (",") or a space (" ").'),
-    '#field_prefix' => t('E.g. 4 out of 23'),
-    '#field_suffix' => t('473'),
+    '#field_prefix' => t('For example <em>4 out of 23</em>'),
+    '#field_suffix' => t('<em>473</em>'),
     '#size' => 1,
     '#maxlength' => 1,
   );
@@ -278,7 +280,6 @@ function flickr_admin_settings() {
   // Disable the caption hover option if a date in the caption is set to 'none'.
   if (variable_get('flickr_date_format_image_caption', 'interval') == 'none') {
     $form['date_formats_settings']['flickr_date_format_image_caption_hover']['#disabled'] = TRUE;
-    $form['date_formats_settings']['flickr_date_format_image_caption_hover']['#title'] = '<span class="grayed-out">' . t('When hovering a date in the caption') . '</span>';
     $form['date_formats_settings']['flickr_date_format_image_caption_hover']['#description'] = t('Disabled until a date format for the image caption is selected.');
   }
   $form['date_formats_settings']['flickr_date_format_album_title'] = array(
@@ -368,6 +369,108 @@ function flickr_admin_settings() {
     '#default_value' => variable_get('flickr_css', 1),
     '#description' => t("Uncheck to take care of the styling yourself in custom CSS.<br />If you use Flickr Filter, you might find the !autofloat_module useful.", array('!autofloat_module' => $autofloat_module)),
   );
+  $form['css_settings']['css_variables'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('CSS variables'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+  );
+  $style_settings_module = l(t('Style (CSS) Settings module'), 'https://drupal.org/project/style_settings', array(
+      'attributes' => array(
+        'title' => t('Style (CSS) Settings | Drupal.org'),
+        'target' => '_blank',
+      ),
+  ));
+  if (module_exists('style_settings')) {
+    $form['css_settings']['css_variables']['#collapsed'] = TRUE;
+    $form['css_settings']['css_variables']['flickr_capsize'] = array(
+      '#type' => 'fieldset', 
+      '#title' => t('Caption font-size'),
+      '#description' => t('Relative to the font size for the normal text. A minimum font size setting of your browser might limit it. Test it on different browsers.'),
+      // Make containing fields align horizontally.
+      '#attributes' => array('class' => array('container-inline')), 
+    );
+    // Number field without a '#field_suffix'.
+    $form['css_settings']['css_variables']['flickr_capsize']['flickr_capsize_value'] = array(
+      '#type' => 'style_settings_number',
+      '#default_value' => variable_get('flickr_capsize_value', 85),
+    );
+    // A measurement unit select field.
+    $form['css_settings']['css_variables']['flickr_capsize']['flickr_capsize_unit'] = array(
+      '#type' => 'select',
+      '#options' => array(
+        'px' => t('px'),
+        'em' => t('em'),
+        '%' => t('%'),
+      ),
+      '#default_value' => variable_get('flickr_capsize_unit', '%'),
+      '#required' => TRUE,
+    );
+    $form['css_settings']['css_variables']['flickr_sswidth'] = array(
+      '#type' => 'fieldset', 
+      '#title' => t('Slideshow width'),
+      '#description' => t('Relative to width of the containing block element (%) or fixed (px). Never wider than the containing block (max-width: 100 %).'),
+      // Make containing fields align horizontally.
+      '#attributes' => array('class' => array('container-inline')), 
+    );
+    // Number field without a '#field_suffix'.
+    $form['css_settings']['css_variables']['flickr_sswidth']['flickr_sswidth_value'] = array(
+      '#type' => 'style_settings_number',
+      '#default_value' => variable_get('flickr_sswidth_value', '100'),
+    );
+    // A measurement unit select field.
+    $form['css_settings']['css_variables']['flickr_sswidth']['flickr_sswidth_unit'] = array(
+      '#type' => 'select',
+      '#options' => array(
+        'px' => t('px'),
+        '%' => t('%'),
+      ),
+      '#default_value' => variable_get('flickr_sswidth_unit', '%'),
+      '#required' => TRUE,
+    );
+    $form['css_settings']['css_variables']['flickr_ssratio'] = array(
+      '#type' => 'fieldset', 
+      '#title' => t('Slideshow width:height ratio'),
+      // Make containing fields align horizontally.
+      '#attributes' => array('class' => array('container-inline')), 
+    );
+    // Number field without a '#field_suffix'.
+    $form['css_settings']['css_variables']['flickr_ssratio']['flickr_sswratio'] = array(
+      '#type' => 'style_settings_number',
+      '#default_value' => variable_get('flickr_sswratio', 4),
+      '#field_suffix' => '&nbsp;&nbsp;:&nbsp;&nbsp;',
+      '#step' => 1,
+      '#min' => 1,
+    );
+    // Number field without a '#field_suffix'.
+    $form['css_settings']['css_variables']['flickr_ssratio']['flickr_sshratio'] = array(
+      '#type' => 'style_settings_number',
+      '#default_value' => variable_get('flickr_sshratio', 3),
+      '#step' => 1,
+      '#min' => 1,
+      '#attributes' => NULL,
+      '#input_help' => NULL,
+    );
+  }
+  elseif (!module_exists('flickrstyle')) {
+    $form['css_settings']['css_variables']['flickr_note'] = array(
+      '#markup' => t("Enable the !style_settings_module (<strong>dev version!</strong>) to get even more styling options. They consist of:<ul>
+          <li>the photo caption font size</li>
+          <li>the slideshow width, fluid (%) or fixed (px)</li>
+          <li>the slideshow width/height ratio</li>
+        </ul>", array('!style_settings_module' => $style_settings_module)),
+    );
+  }
+  else {
+    $form['css_settings']['css_variables']['flickr_note'] = array(
+      '#markup' => t("Enable the !style_settings_module (<strong>dev version!</strong>) to get even more styling options. They consist of:<ul>
+          <li>the photo caption font size</li>
+          <li>the slideshow width, fluid (%) or fixed (px)</li>
+          <li>the slideshow width/height ratio</li>
+          <li>customized rounded corners, shadow, border and scale properties</li>
+        </ul>", array('!style_settings_module' => $style_settings_module)),
+    );
+  }
   $flickr_style = l(t('Flickr Style'), 'admin/modules', array(
       'attributes' => array(
         'title' => t('Extra configuration options.'),
@@ -404,7 +507,7 @@ function flickr_admin_settings() {
     '#title' => t('Update interval'),
     '#options' => $ageoptions,
     '#default_value' => variable_get('flickr_cache_duration', 3600),
-    '#description' => t('The refresh interval indicating how often you want to check cached Flickr API calls are up to date.'),
+    '#description' => t("The refresh interval indicating how often you want to check cached Flickr API calls are up to date. This only kicks in when a repeating request with the same query is made, e.g. when re-saving a Flickr block without changing the parameters within the above specified interval. A Flickr API request is usually avoided by a page or block cache, therefore it is pretty safe to set it to '<em>1 hour</em>'."),
   );
   $cache_warming = l(t('cache warming'), 'https://drupal.org/node/1576686', array(
     'attributes' => array(
@@ -483,11 +586,6 @@ function flickr_admin_settings() {
   );
   // Disable the Devel output until it is available.
   if (!module_exists('devel')) {
-    $form['advanced_settings']['flickr_debug']['#options'] = array(
-      t('None'),
-      t('Flickr response only (as a link to an XML page in a debug message)'),
-      '<span class="grayed-out">' . t('Plus Devel (Flickr response plus additional output') . '</span> <span class="grayed-out-help">' . t('Disabled until you enable the !devel_module.', array('!devel_module' => $devel_module)) . '</span> ',
-    );
     $form['advanced_settings']['flickr_debug'][2]['#disabled'] = TRUE;
     $form['advanced_settings']['flickr_debug']['#description'] = t('Display the Flickr XML response.');
   }
@@ -544,6 +642,9 @@ function flickr_admin_settings() {
     '#description' => t("Note that form submit will be slower. Your content will be rebuilt at the first visit. Your choice will be 'remembered' for your next visit to this configuration page."),
     '#weight' => 97,
   );
+  if (variable_get('flickr_css', 1) && module_exists('style_settings')) {
+    $form['flickr_cc']['#title'] = t("Flush the cache on form submit to see your changes instantly. CSS is flushed in any case.");
+  }
 
   // Call submit_function() on form submission.
   $form['#submit'][] = 'flickr_admin_settings_submit';
@@ -555,19 +656,16 @@ function flickr_admin_settings() {
  * Validate user input.
  */
 function flickr_admin_settings_validate($form, &$form_state) {
+  // Validate the credentials.
   $key = trim($form_state['values']['flickr_api_key']);
-  $sec = trim($form_state['values']['flickr_api_secret']);
-  $uid = trim($form_state['values']['flickr_default_userid']);
-  $limit1 = trim($form_state['values']['flickr_photos_per_page']);
-  $limit2 = trim($form_state['values']['flickr_title_suppress_on_small']);
-  $limit3 = trim($form_state['values']['flickr_metadata_suppress_on_small']);
-  $limit7 = trim($form_state['values']['flickr_per_page']);
   if ($key && (preg_match('/^[A-Fa-f\d]{32}$/', $key) != 1)) {
     form_set_error('flickr_api_key', t('This does not appear to be a Flickr API key.'));
   }
+  $sec = trim($form_state['values']['flickr_api_secret']);
   if ($sec && (preg_match('/^[A-Fa-f\d]{16}$/', $sec) != 1)) {
     form_set_error('flickr_api_secret', t('This does not appear to be a Flickr API secret.'));
   }
+  $uid = trim($form_state['values']['flickr_default_userid']);
   if ($uid) {
     $user = flickr_user_find_by_identifier($uid);
     if (!$user) {
@@ -575,20 +673,24 @@ function flickr_admin_settings_validate($form, &$form_state) {
     }
   }
   // Validate the number of photos.
-  if (!is_numeric($limit1) || $limit1 < 1) {
-    form_set_error('flickr_photos_per_page', t('Set a number from 1 to 999.'));
+  $limit = trim($form_state['values']['flickr_photos_per_page']);
+  if (!ctype_digit($limit) || $limit < 1) {
+    form_set_error('flickr_photos_per_page', t('Set an integer from 1 to 999.'));
   }
   // Validate the minimum width to suppress title caption.
-  if (!is_numeric($limit2) || $limit2 < 0) {
+  $limit = trim($form_state['values']['flickr_title_suppress_on_small']);
+  if (!is_numeric($limit) || $limit < 0) {
     form_set_error('flickr_title_suppress_on_small', t('Set a width from 0 to 999 px.'));
   }
   // Validate the minimum width to suppress metadata caption.
-  if (!is_numeric($limit3) || $limit3 < 0) {
+  $limit = trim($form_state['values']['flickr_metadata_suppress_on_small']);
+  if (!is_numeric($limit) || $limit < 0) {
     form_set_error('flickr_metadata_suppress_on_small', t('Set a width from 0 to 999 px.'));
   }
-  // Validate the number to return on a random or views sorted API requests.
-  if (!is_numeric($limit7) || $limit7 < 20 || $limit7 > 500) {
-    form_set_error('flickr_per_page', t('Set a number from 20 to 500.'));
+  // Validate the number to return on 'random' or 'views' sorted API requests.
+  $limit = trim($form_state['values']['flickr_per_page']);
+  if (!ctype_digit($limit) || $limit < 20 || $limit > 500) {
+    form_set_error('flickr_per_page', t('Set an integer from 20 to 500.'));
   }
 }
 
@@ -596,10 +698,29 @@ function flickr_admin_settings_validate($form, &$form_state) {
  * Submit form data.
  */
 function flickr_admin_settings_submit($form, &$form_state) {
+  if (variable_get('flickr_css', 1) && module_exists('style_settings')) {
+    // Concatenate the caption font-size value and unit.
+    variable_set('flickr_capsize', $form_state['values']['flickr_capsize_value'] . $form_state['values']['flickr_capsize_unit']);
+    // Concatenate the caption font-size value and unit.
+    variable_set('flickr_sswidth', $form_state['values']['flickr_sswidth_value'] . $form_state['values']['flickr_sswidth_unit']);
+    $ssratio = $form_state['values']['flickr_sswidth_value'] * $form_state['values']['flickr_sshratio'] / $form_state['values']['flickr_sswratio'];
+    $ssratio = $ssratio > 100 ? $ssratio . 'px' : $ssratio . '%';
+    variable_set('flickr_slideshow_ratio', $ssratio);
+    // IMAGE URL: Reset to default if empty.
+    if (module_exists('flickrstyle')) {
+      if (trim($form_state['values']['flickrstyle_magnifier_image']) == '') {
+        $form_state['values']['flickrstyle_magnifier_image'] = '/' . drupal_get_path('module', 'flickrstyle') . '/img/magnifier.png';
+        drupal_set_message(t('The image URL has been reset to the default.'), 'warning', FALSE);
+      }
+    }
+  }
   if ($form_state['values']['flickr_cc']) {
     drupal_flush_all_caches();
     drupal_set_message(t('All caches are flushed.'), 'status', FALSE);
   }
+  elseif (variable_get('flickr_css', 1) && module_exists('style_settings')) {
+    _drupal_flush_css_js();
+  }
   // Clean up the data.
   $form_state['values']['flickr_api_key'] = trim($form_state['values']['flickr_api_key']);
   $form_state['values']['flickr_api_secret'] = trim($form_state['values']['flickr_api_secret']);
diff --git a/flickr.css b/flickr.css
index 809bec6..3362467 100644
--- a/flickr.css
+++ b/flickr.css
@@ -1,3 +1,9 @@
+/**
+ * The CSS values that are wrapped in /*variable comments are intended for use
+ * by https://www.drupal.org/project/style_settings. Enable that module to
+ * have those CSS variables exposed in the settings UI.
+ */
+
 .flickr-photo-img {
   vertical-align: text-bottom;
 }
@@ -32,23 +38,25 @@ span.flickr-credit {
   display: block;
   overflow: hidden;
   padding: 0 0 4px 4px;
-  font-size: 80%;
+  font-size: /*variable:flickr_capsize*/80%/*variable*/;
   line-height: 100%;
 }
 
 .flickr-slideshow {
   position: relative;
   overflow: hidden;
-  width: 100%;
+  width: /*variable:flickr_sswidth*/100%/*variable*/;
   height: 0;
-  /*Change percentage below to change ratio. Currently 16:9 (as most screens).*/
-  padding-bottom: 56.25%;
+  /*The percentage is the height/width ratio. Defaults to 3:4.*/
+  padding-bottom: /*variable:flickr_slideshow_ratio*/75%/*variable*/;
 }
 
 .flickr-slideshow object {
   position: absolute;
   top: 0;
   left: 0;
+  max-width: 100%;
+  max-height: 100%;
 }
 
 .flickr-block-photosets .flickr-block-photoset {
@@ -97,10 +105,20 @@ span.flickr-empty {
   float: none !important;
 }
 
-span.grayed-out {
+span.grayed-out,
+.form-disabled label,
+input[disabled=disabled] label {
   color: darkgray;
 }
 
 span.grayed-out-help {
   color: #666;
 }
+
+.flickr-form-align {
+  text-align: right;
+}
+
+.form-item.form-type-textfield.form-item-flickr-sswratio {
+  float: left;
+}
diff --git a/flickr.info b/flickr.info
index 1eff94c..54dd5af 100644
--- a/flickr.info
+++ b/flickr.info
@@ -3,3 +3,5 @@ description = Flickr and Drupal integration.
 core = 7.x
 package = Flickr
 configure = admin/config/media/flickr
+
+soft_dependencies[] = style_settings
diff --git a/flickr.install b/flickr.install
index 3261994..49898d2 100644
--- a/flickr.install
+++ b/flickr.install
@@ -51,6 +51,14 @@ function flickr_uninstall() {
   variable_del('flickr_date_format_image_caption');
   variable_del('flickr_date_format_image_caption_hover');
   variable_del('flickr_date_format_album_title');
+  variable_del('flickr_capsize');
+  variable_del('flickr_sswidth_value');
+  variable_del('flickr_sswidth_unit');
+  variable_del('flickr_sswidth');
+  variable_del('flickr_sswratio');
+  variable_del('flickr_sshratio');
+  variable_del('flickr_ssratio');
+  variable_del('flickr_caption_fontsize');
 }
 
 /**
diff --git a/flickr.module b/flickr.module
index 47909a0..c080dcc 100644
--- a/flickr.module
+++ b/flickr.module
@@ -715,7 +715,7 @@ function theme_flickr_photo($variables) {
     $notitle = '<span class="flickr-no-title">' . t('Flickr') . '</span> ';
     $metadatacaption = $width < $min_metadata ? $license : $metadatacaption;
   }
-  $class_notitle = $width < $min_title ? ' flickr-no-title' : '';
+  $class_notitle = $width < $min_title && $width < $min_metadata ? ' flickr-no-title' : '';
   $credit = $width < $min_title ? $notitle : '<span class="flickr-title">' . $title . '</span><br />';
   // Determine what info goes with the enlarged version of the image.
   $overlay = variable_get('flickr_info_overlay', array(
@@ -729,8 +729,11 @@ function theme_flickr_photo($variables) {
   $description = (gettype($overlay['description']) == 'integer' || $overlaytitle == $description . ' - ') ? '' : $description . ' - ';
   $licenselong = (gettype($overlay['license']) == 'integer') ? '' : $licenselong;
   $overlayhtml = $overlaytitle . $metadata . $description . $licenselong;
-  // Optionally use the GPL licensed magnifier image supplied with the module.
-  $magnifier = (variable_get('flickrstyle_emphasize', 2) == 4) ? '<span class="hover-icon"><img src="/' . drupal_get_path('module', 'flickr') . '/style/img/magnifier.png' . '" style="width:50px;height:50px;"></span>' : '';
+  // Optionally use the GPL licensed magnifier image supplied with the module or user specified.
+  $uri = variable_get('flickrstyle_magnifier_image', '');
+  $magnifierurl = empty($uri) ? '/' . drupal_get_path('module', 'flickr') . '/style/img/magnifier.png' : $uri;
+  $iconsize = variable_get('flickrstyle_magnifier_size', '50px');
+  $magnifier = (variable_get('flickrstyle_emphasize', 2) == 4) ? '<span class="hover-icon"><img src="' . $magnifierurl . '" style="width:' . $iconsize . ';height:' . $iconsize . ';"></span>' : '';
   // Final step when NO overlay browser is used that generates the image that
   // links to the Flickr page to comply with the TOS of Flickr.
   if (variable_get('flickr_class') == NULL && variable_get('flickr_rel') == NULL && $width < $min_title && $width < $min_metadata) {
@@ -915,16 +918,22 @@ function theme_flickr_flickrcomslideshow($variables) {
   if (isset($attribs[0]['width'])) {
     if (strpos($attribs[0]['width'], '%') !== FALSE) {
       $width = $attribs[0]['width'];
-      $height = isset($attribs[0]['height']) ? $attribs[0]['height'] : $width;
+      $div = '<div style="width: ' . (int)$width . '%;">';
+      $width = '100%';
+      $height = '100%';
     }
     else {
       $width = $attribs[0]['width'];
-      $height = isset($attribs[0]['height']) ? $attribs[0]['height'] : round($width * 9 / 16);
+      $height = isset($attribs[0]['height']) ? $attribs[0]['height'] : round($width * variable_get('flickr_sshratio', 3) / variable_get('flickr_sswratio', 4)) . 'px';
+      $div = '<div style="width: ' . (int)$width . 'px; height: ' . (int)$height . 'px;">';
     }
+    $divend = '</div>';
   }
   else {
     $width = '100%';
     $height = '100%';
+    $div = '';
+    $divend = '';
   }
   unset($attribs[0]['width']);
   unset($attribs[0]['height']);
@@ -938,21 +947,21 @@ function theme_flickr_flickrcomslideshow($variables) {
     case 'photoset':
       $info = flickr_photosets_getinfo($id);
       $user_id = $info['owner'];
-      return '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="application/x-shockwave-flash" data="https://www.flickr.com/apps/slideshow/show.swf?v=71649">
+      return $div . '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="application/x-shockwave-flash" data="https://www.flickr.com/apps/slideshow/show.swf?v=71649">
     <param name="movie" value="https://www.flickr.com/apps/slideshow/show.swf?v=71649" />
     <param name="allowFullScreen" value="true" />
     <param name="wmode" value="opaque" />
-    <param name="flashvars" value="offsite=true&amp;lang=en-us&amp;page_show_url=/photos/' . $user_id . '/sets/' . $id . '/show/&amp;page_show_back_url=/photos/' . $user_id . '/sets/' . $id . '/&amp;set_id=' . $id . '" /></object></div>';
+    <param name="flashvars" value="offsite=true&amp;lang=en-us&amp;page_show_url=/photos/' . $user_id . '/sets/' . $id . '/show/&amp;page_show_back_url=/photos/' . $user_id . '/sets/' . $id . '/&amp;set_id=' . $id . '" /></object></div>' . $divend;
 
     case 'user':
-      return '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="application/x-shockwave-flash" data="https://www.flickr.com/apps/slideshow/show.swf?v=71649">
+      return $div . '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="application/x-shockwave-flash" data="https://www.flickr.com/apps/slideshow/show.swf?v=71649">
       <param name="movie" value="https://www.flickr.com/apps/slideshow/show.swf?v=71649" />
       <param name="allowFullScreen" value="true" />
       <param name="wmode" value="opaque" />
-      <param name="flashvars" value="offsite=tru&amp;lang=en-us&amp;page_show_url=%2Fphotos%2F' . $id . '%2Fshow&amp;user_id=' . $id . '" /></object></div>';
+      <param name="flashvars" value="offsite=tru&amp;lang=en-us&amp;page_show_url=%2Fphotos%2F' . $id . '%2Fshow&amp;user_id=' . $id . '" /></object></div>' . $divend;
 
     case 'group':
-      return '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="application/x-shockwave-flash" data="https://www.flickr.com/apps/slideshow/show.swf?v=140556"><param name="movie" value="https://www.flickr.com/apps/slideshow/show.swf?v=140556"></param><param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fgroups%2F' . $id . '%2Fpool%2Fshow%2F&page_show_back_url=%2Fgroups%2F' . $id . '%2Fpool%2F&group_id=' . $id . '&jump_to=&start_index="></param><param name="allowFullScreen" value="true"><param name="wmode" value="opaque" /></param></object></div>';
+      return $div . '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="application/x-shockwave-flash" data="https://www.flickr.com/apps/slideshow/show.swf?v=140556"><param name="movie" value="https://www.flickr.com/apps/slideshow/show.swf?v=140556"></param><param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fgroups%2F' . $id . '%2Fpool%2Fshow%2F&page_show_back_url=%2Fgroups%2F' . $id . '%2Fpool%2F&group_id=' . $id . '&jump_to=&start_index="></param><param name="allowFullScreen" value="true"><param name="wmode" value="opaque" /></param></object></div>' . $divend;
   }
   drupal_set_message(t('No valid set, user or group ID is provided for the slideshow.'), 'error');
 }
@@ -974,16 +983,22 @@ function theme_flickr_flickrcomslideshow_simple($variables) {
   if (isset($attribs[0]['width'])) {
     if (strpos($attribs[0]['width'], '%') !== FALSE) {
       $width = $attribs[0]['width'];
-      $height = isset($attribs[0]['height']) ? $attribs[0]['height'] : $width;
+      $div = '<div style="width: ' . (int)$width . '%;">';
+      $width = '100%';
+      $height = '100%';
     }
     else {
       $width = $attribs[0]['width'];
-      $height = isset($attribs[0]['height']) ? $attribs[0]['height'] : round($width * 9 / 16);
+      $height = isset($attribs[0]['height']) ? $attribs[0]['height'] : round($width * variable_get('flickr_sshratio', 3) / variable_get('flickr_sswratio', 4)) . 'px';
+      $div = '<div style="width: ' . (int)$width . 'px; height: ' . (int)$height . 'px;">';
     }
+    $divend = '</div>';
   }
   else {
     $width = '100%';
     $height = '100%';
+    $div = '';
+    $divend = '';
   }
   unset($attribs[0]['width']);
   unset($attribs[0]['height']);
@@ -1008,7 +1023,7 @@ function theme_flickr_flickrcomslideshow_simple($variables) {
       $src = 'https://www.flickr.com/slideShow/index.gne?group_id=' . $id . '&user_id=&set_id=&text=';
       break;
   }
-  return '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="text/html" data="' . $src . '"></object></div>';
+  return $div . '<div class="flickr-slideshow ' . $class . '"><object width="' . $width . '" height="' . $height . '" style="' . $attribs . '" type="text/html" data="' . $src . '"></object></div>' . $divend;
 }
 
 /**
diff --git a/sets/flickr_sets.admin.inc b/sets/flickr_sets.admin.inc
index f482bea..2dc1bfe 100644
--- a/sets/flickr_sets.admin.inc
+++ b/sets/flickr_sets.admin.inc
@@ -58,14 +58,14 @@ function flickr_sets_form_flickr_admin_settings_alter(&$form, &$form_state) {
  * Validate user input.
  */
 function flickr_sets_admin_settings_validate($form, &$form_state) {
-  $limit8 = trim($form_state['values']['flickr_sets_per_page']);
-  $limit9 = trim($form_state['values']['flickr_sets_photos_per_set']);
   // Validate sets per page.
-  if (!is_numeric($limit8) || $limit8 < 1) {
-    form_set_error('flickr_sets_per_page', t('Set a number from 1 to 99.'));
+  $limit = trim($form_state['values']['flickr_sets_per_page']);
+  if (!ctype_digit($limit) || $limit < 1) {
+    form_set_error('flickr_sets_per_page', t('Set an integer from 1 to 99.'));
   }
   // Validate photos per set.
-  if (!is_numeric($limit9) || $limit9 < 1) {
-    form_set_error('flickr_sets_photos_per_set', t('Set a number from 1 to 99.'));
+  $limit = trim($form_state['values']['flickr_sets_photos_per_set']);
+  if (!ctype_digit($limit) || $limit < 1) {
+    form_set_error('flickr_sets_photos_per_set', t('Set an integer from 1 to 99.'));
   }
 }
diff --git a/style/css/flickrstyle.css b/style/css/flickrstyle.css
new file mode 100644
index 0000000..a0f35c5
--- /dev/null
+++ b/style/css/flickrstyle.css
@@ -0,0 +1,12 @@
+/**
+ * The CSS values that are wrapped in /*variable comments are intended for use
+ * by https://www.drupal.org/project/style_settings. Enable that module to
+ * have those CSS variables exposed in the settings UI.
+ */
+
+div.style-settings-image-preview img {
+  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=/*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/);
+  filter: alpha(opacity=/*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/);
+  -moz-opacity: /*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/;
+  opacity: /*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/;
+}
diff --git a/style/css/flickrstyle_big.css b/style/css/flickrstyle_big.css
index 84d57f6..a4d26fd 100644
--- a/style/css/flickrstyle_big.css
+++ b/style/css/flickrstyle_big.css
@@ -3,13 +3,15 @@ img.flickr-photoset-img:hover {
   position: relative;
   z-index: 99;
   top: 1.7em;
-  -webkit-transform: scale(1.8);
-     -moz-transform: scale(1.8);
-      -ms-transform: scale(1.8);
-       -o-transform: scale(1.8);
-          transform: scale(1.8);
-  border: solid 2px transparent;
-  background: white;
+  -webkit-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+     -moz-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+      -ms-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+       -o-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+          transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+  border-width: /*variable:flickrstyle_spacing*/2px/*variable*/;
+  border-style: solid;
+  border-color: transparent;
+  background-color: /*variable:flickrstyle_bgcolor*/White/*variable*/;
 }
 
 .flickr-photo-img,
@@ -21,7 +23,7 @@ img.flickr-photoset-img {
        -o-transition: all 0.2s ease;
           transition: all 0.2s ease;
   border: solid 2px transparent;
-  background: transparent;
+  background-color: transparent;
 
   -o-object-fit: cover;
      object-fit: cover;
diff --git a/style/css/flickrstyle_border.css b/style/css/flickrstyle_border.css
index 49d93ed..f1a48b3 100644
--- a/style/css/flickrstyle_border.css
+++ b/style/css/flickrstyle_border.css
@@ -1,10 +1,12 @@
 .flickr-photo-img,
 img.flickr-photoset-img {
-  border: solid 2px white;
-  background: white !important;
+  border-style: solid;
+  border-width: /*variable:flickrstyle_spacing*/2px/*variable*/;
+  border-color: /*variable:flickrstyle_bgcolor*/White/*variable*/;
+  background: /*variable:flickrstyle_bgcolor*/White/*variable*/ !important;
 }
 
-/*Make the caption as wide as the image */
+/* Make the caption as wide as the image.*/
 span.flickr-credit,
 .flickr-citation {
   padding: 0 2px 4px 4px;
diff --git a/style/css/flickrstyle_bordernoshadow.css b/style/css/flickrstyle_bordernoshadow.css
index f3036bb..3982520 100644
--- a/style/css/flickrstyle_bordernoshadow.css
+++ b/style/css/flickrstyle_bordernoshadow.css
@@ -1,12 +1,14 @@
 .flickr-photo-img,
 img.flickr-photoset-img {
-  padding: 2px;
-  border: solid 2px lightgray !important;
-  background: white !important;
+  padding: /*variable:flickrstyle_spacing*/2px/*variable*/;
+  border-style: solid;
+  border-width: /*variable:flickrstyle_border_thickness*/2px/*variable*/ !important;
+  border-color: /*variable:flickrstyle_border_color*/LightGrey/*variable*/ !important;
+  background-color: /*variable:flickrstyle_bgcolor*/White/*variable*/ !important;
 }
 
 /*Make the caption as wide as the image */
 span.flickr-credit,
 .flickr-citation {
-  padding: 0 4px;
+  padding: 0 /*variable:flickrstyle_border_thickness_doubled*/4px/*variable*/;
 }
diff --git a/style/css/flickrstyle_caption_border.css b/style/css/flickrstyle_caption_border.css
index 658b227..df7cc76 100644
--- a/style/css/flickrstyle_caption_border.css
+++ b/style/css/flickrstyle_caption_border.css
@@ -1,6 +1,7 @@
 span.flickr-credit {
-  /*Use the dedicated field at admin/config/media/flickr for a horizontal inside spacing value (padding/border).*/
   padding: 3px 7px;
-  border: solid 2px lightgray;
-  background: white;
+  border-width: /*variable:flickrstyle_border_thickness*/2px/*variable*/;
+  border-style: solid;
+  border-color: /*variable:flickrstyle_border_color*/LightGrey/*variable*/;
+  background-color: /*variable:flickrstyle_bgcolor*/White/*variable*/;
 }
diff --git a/style/css/flickrstyle_caption_shadow.css b/style/css/flickrstyle_caption_shadow.css
index 73fc09d..3097cbd 100644
--- a/style/css/flickrstyle_caption_shadow.css
+++ b/style/css/flickrstyle_caption_shadow.css
@@ -1,10 +1,10 @@
 span.flickr-credit {
   /*Use the dedicated field at admin/config/media/flickr for a horizontal inside spacing value (padding/border).*/
   padding: 3px 7px;
-  background: white;
-  -webkit-box-shadow: 2px 2px 7px 3px #a5a5a5;
-     -moz-box-shadow: 2px 2px 7px 3px #a5a5a5;
-          box-shadow: 2px 2px 7px 3px #a5a5a5;
+  background: /*variable:flickrstyle_bgcolor*/White/*variable*/;
+  -webkit-box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
+     -moz-box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
+          box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
 }
 
 .flickr-wrap {
diff --git a/style/css/flickrstyle_enlarge.css b/style/css/flickrstyle_enlarge.css
index 44b4fb5..2f51a41 100644
--- a/style/css/flickrstyle_enlarge.css
+++ b/style/css/flickrstyle_enlarge.css
@@ -1,10 +1,10 @@
 img.flickr-photoset-img:hover,
 .flickr-wrap:hover {
-  -webkit-transform: scale(1.05);
-     -moz-transform: scale(1.05);
-      -ms-transform: scale(1.05);
-       -o-transform: scale(1.05);
-          transform: scale(1.05);
+  -webkit-transform: scale(/*variable:flickrstyle_scale*/1.05/*variable*/);
+     -moz-transform: scale(/*variable:flickrstyle_scale*/1.05/*variable*/);
+      -ms-transform: scale(/*variable:flickrstyle_scale*/1.05/*variable*/);
+       -o-transform: scale(/*variable:flickrstyle_scale*/1.05/*variable*/);
+          transform: scale(/*variable:flickrstyle_scale*/1.05/*variable*/);
 }
 
 img.flickr-photoset-img,
diff --git a/style/css/flickrstyle_magnifier.css b/style/css/flickrstyle_magnifier.css
index 03fa78f..95dc4ee 100644
--- a/style/css/flickrstyle_magnifier.css
+++ b/style/css/flickrstyle_magnifier.css
@@ -8,10 +8,10 @@
   bottom: 50%;
   left: 50%;
   display: block;
-  width: 50px;
-  height: 50px;
-  margin-bottom: -25px;
-  margin-left: -25px;
+  width: /*variable:flickrstyle_magnifier_size*/50px/*variable*/;
+  height: /*variable:flickrstyle_magnifier_size*/50px/*variable*/;
+  margin-bottom: /*variable:flickrstyle_magnifier_halfsize*/-25px/*variable*/;
+  margin-left: /*variable:flickrstyle_magnifier_halfsize*/-25px/*variable*/;
   -webkit-transition-duration: 150ms;
      -moz-transition-duration: 150ms;
       -ms-transition-duration: 150ms;
@@ -40,8 +40,8 @@
       -ms-transform: scale(1,1);
        -o-transform: scale(1,1);
           transform: scale(1,1);
-  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0.85);
-  filter: alpha(opacity=0.85);
-  -moz-opacity: 0.85;
-  opacity: 0.85;
+  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=/*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/);
+  filter: alpha(opacity=/*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/);
+  -moz-opacity: /*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/;
+  opacity: /*variable:flickrstyle_magnifier_opacity*/0.85/*variable*/;
 }
diff --git a/style/css/flickrstyle_rounded.css b/style/css/flickrstyle_rounded.css
index 0c95bb0..643e948 100644
--- a/style/css/flickrstyle_rounded.css
+++ b/style/css/flickrstyle_rounded.css
@@ -2,7 +2,7 @@
 img.flickr-photoset-img,
 .flickr-wrap,
 span.flickr-credit {
-  -webkit-border-radius: 1em;
-     -moz-border-radius: 1em;
-          border-radius: 1em;
+  -webkit-border-radius: /*variable:flickrstyle_radius*/1em/*variable*/;
+     -moz-border-radius: /*variable:flickrstyle_radius*/1em/*variable*/;
+          border-radius: /*variable:flickrstyle_radius*/1em/*variable*/;
 }
diff --git a/style/css/flickrstyle_shadow.css b/style/css/flickrstyle_shadow.css
index 5439422..8ff4264 100644
--- a/style/css/flickrstyle_shadow.css
+++ b/style/css/flickrstyle_shadow.css
@@ -1,9 +1,9 @@
 .flickr-photo-img,
 img.flickr-photoset-img {
   margin: 0 3px 0 0; /*Shadows need some additional space*/
-  -webkit-box-shadow: 2px 2px 7px 3px #a5a5a5;
-     -moz-box-shadow: 2px 2px 7px 3px #a5a5a5;
-          box-shadow: 2px 2px 7px 3px #a5a5a5;
+  -webkit-box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
+     -moz-box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
+          box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
 }
 
 /*Additional space between the image and caption box*/
diff --git a/style/css/flickrstyle_wrapcaption_border.css b/style/css/flickrstyle_wrapcaption_border.css
index 6a412de..a87fb31 100644
--- a/style/css/flickrstyle_wrapcaption_border.css
+++ b/style/css/flickrstyle_wrapcaption_border.css
@@ -1,7 +1,9 @@
 .flickr-wrap {
   margin: 0;
-  border: solid 2px lightgray;
-  background: white;
+  border-width: /*variable:flickrstyle_border_thickness*/2px/*variable*/;
+  border-style: solid;
+  border-color: /*variable:flickrstyle_border_color*/LightGrey/*variable*/;
+  background-color: /*variable:flickrstyle_bgcolor*/White/*variable*/;
 }
 
 .flickr-photo-img {
diff --git a/style/css/flickrstyle_wrapcaption_shadow.css b/style/css/flickrstyle_wrapcaption_shadow.css
index b9dda2f..dcff8c2 100644
--- a/style/css/flickrstyle_wrapcaption_shadow.css
+++ b/style/css/flickrstyle_wrapcaption_shadow.css
@@ -1,9 +1,9 @@
 span.flickr-wrap {
   margin: 0 8px 5px 0 !important;
-  background: white;
-  -webkit-box-shadow: 2px 2px 7px 3px #a5a5a5;
-     -moz-box-shadow: 2px 2px 7px 3px #a5a5a5;
-          box-shadow: 2px 2px 7px 3px #a5a5a5;
+  background-color: /*variable:flickrstyle_bgcolor*/White/*variable*/;
+  -webkit-box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
+     -moz-box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
+          box-shadow: 2px 2px 7px 3px /*variable:flickrstyle_shadow_color*/#a5a5a5/*variable*/;
 }
 
 .flickr-photo-img {
diff --git a/style/css/flickrstyle_zoom.css b/style/css/flickrstyle_zoom.css
index 0544887..db991ae 100644
--- a/style/css/flickrstyle_zoom.css
+++ b/style/css/flickrstyle_zoom.css
@@ -5,11 +5,11 @@ img.flickr-photoset-img:hover {
   top: 1.4em;
   margin: 0;
   padding: 0;
-  -webkit-transform: scale(1.85);
-     -moz-transform: scale(1.85);
-      -ms-transform: scale(1.85);
-       -o-transform: scale(1.85);
-          transform: scale(1.85);
+  -webkit-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+     -moz-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+      -ms-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+       -o-transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
+          transform: scale(/*variable:flickrstyle_scale*/1.85/*variable*/);
   border: none;
   -webkit-box-shadow: none;
      -moz-box-shadow: none;
diff --git a/style/flickrstyle.admin.inc b/style/flickrstyle.admin.inc
index 750bf60..997cc0b 100644
--- a/style/flickrstyle.admin.inc
+++ b/style/flickrstyle.admin.inc
@@ -8,7 +8,7 @@
  * Implements hook_form_FORM_ID_alter().
  */
 function flickrstyle_form_flickr_admin_settings_alter(&$form, &$form_state) {
-  $form['#validate'][] = 'flickrstyle_admin_settings_validate';
+  $form['#submit'][] = 'flickrstyle_admin_settings_submit';
   // Do not display CSS styling options if the module's CSS is disabled.
   if (variable_get('flickr_css', 1)) {
     $options = array(
@@ -19,6 +19,7 @@ function flickrstyle_form_flickr_admin_settings_alter(&$form, &$form_state) {
     $form['css_settings']['flickrstyle_styles'] = array(
       '#type' => 'checkboxes',
       '#title' => t('Image styles'),
+      '#description' => t('Shadow only = Image with shadow. No space between.<br />Border only = Some space between image and a solid border.<br />Shadow + Border = Some space between image and shadow. No real border.'),
       '#default_value' => variable_get('flickrstyle_styles', array(
         'rounded' => 'rounded',
         'shadow' => 'shadow',
@@ -32,6 +33,165 @@ function flickrstyle_form_flickr_admin_settings_alter(&$form, &$form_state) {
       'shadow' => 'shadow',
       'border' => 'border',
     ));
+    if (module_exists('style_settings')) {
+      $form['css_settings']['css_variables']['flickrstyle_radius'] = array(
+        '#type' => 'fieldset', 
+        '#title' => t('Rounded corner radius'),
+        // Make containing fields align horizontally.
+        '#attributes' => array('class' => array('container-inline')),
+        '#description' => t('Note: A value of 50% or higher results in round/ellipse images.'),
+      );
+      // Number field without a '#field_suffix'.
+      $form['css_settings']['css_variables']['flickrstyle_radius']['flickrstyle_radius_value'] = array(
+        '#type' => 'style_settings_number',
+        '#default_value' => variable_get('flickrstyle_radius_value', '1'),
+      );
+      // A measurement unit select field.
+      $form['css_settings']['css_variables']['flickrstyle_radius']['flickrstyle_radius_unit'] = array(
+        '#type' => 'select',
+        '#options' => array(
+          'px' => t('px'),
+          'em' => t('em'),
+          '%' => t('%'),
+        ),
+        '#default_value' => variable_get('flickrstyle_radius_unit', 'em'),
+        '#required' => TRUE,
+      );
+      // We need rounded corners before we can use a radius on it.
+      if (gettype($styles['rounded']) == 'integer') {
+        $form['css_settings']['css_variables']['flickrstyle_radius']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_radius']['#description'] = '<span class="grayed-out">' . t('A value of 50% or higher results in round/ellipse images.') . '</span> | ' . t("Disabled until the 'Rounded corners' image style is selected below and saved.");
+      }
+      $form['css_settings']['css_variables']['flickrstyle_bgcolor'] = array(
+        '#type' => 'style_settings_colorpicker',
+        '#title' => t('Background color'),
+        '#description' => t('Applies on the bordered caption area and the space between image and border.'),
+        '#default_value' => variable_get('flickrstyle_bgcolor', 'White'),
+        '#weight' => 10,
+      );
+      // We need a 'Border' or styled caption to have a background to color.
+      if (gettype($styles['border']) == 'integer' && !variable_get('flickrstyle_caption', 1)) {
+        $form['css_settings']['css_variables']['flickrstyle_bgcolor']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_bgcolor']['#description'] = t("Disabled until the 'Border' or a caption style is selected below and saved.");;
+      }
+      $form['css_settings']['css_variables']['flickrstyle_shadow_color'] = array(
+        '#type' => 'style_settings_colorpicker',
+        '#title' => t('Shadow color'),
+        '#default_value' => variable_get('flickrstyle_shadow_color', '#a5a5a5'),
+        '#weight' => 11,
+      );
+      // We need a shadow before we can use a color for it.
+      if (gettype($styles['shadow']) == 'integer') {
+        $form['css_settings']['css_variables']['flickrstyle_shadow_color']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_shadow_color']['#description'] = t("Disabled until the 'Shadow' image style is selected below and saved.");
+      }
+      $form['css_settings']['css_variables']['flickrstyle_border_color'] = array(
+        '#type' => 'style_settings_colorpicker',
+        '#title' => t('Border color'),
+        '#default_value' => variable_get('flickrstyle_border_color', 'LightGrey'),
+        '#weight' => 12,
+      );
+      $form['css_settings']['css_variables']['flickrstyle_border_thickness'] = array(
+        '#type' => 'style_settings_number',
+        '#title' => t('Border width'),
+        '#default_value' => floatval(variable_get('flickrstyle_border_thickness', '2px')),
+        '#field_suffix' => t('px'),
+        '#weight' => 13,
+      );
+      $form['css_settings']['css_variables']['flickrstyle_spacing'] = array(
+        '#type' => 'style_settings_number',
+        '#title' => t('Space between image and border'),
+        '#default_value' => floatval(variable_get('flickrstyle_spacing', 'px')),
+        '#field_suffix' => t('px'),
+        '#weight' => 14,
+      );
+      // We need a 'Border' to space.
+      if (gettype($styles['border']) == 'integer') {
+        $form['css_settings']['css_variables']['flickrstyle_spacing']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_spacing']['#description'] = t("Disabled until the 'Border' image style is selected below and saved.");;
+      }
+      $form['css_settings']['css_variables']['flickrstyle_scale'] = array(
+        '#type' => 'style_settings_slider',
+        '#title' => t('Scale factor'),
+        '#description' => t('Applies to the enlarge and zoom styles on image hover.'),
+        '#default_value' => variable_get('flickrstyle_scale', 1.85),
+        '#min' => 1.01,
+        '#max' => 2.15,
+        '#weight' => 15,
+      );
+      // We need an 'Enlarge' or 'Zoom' style to scale.
+      if (variable_get('flickrstyle_emphasize', 2) < 1 || variable_get('flickrstyle_emphasize', 2) > 3) {
+        $form['css_settings']['css_variables']['flickrstyle_scale']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_scale']['#description'] = t("Disabled until the 'Enlarge' or 'Zoom' style on hover is selected below and saved.");;
+      }
+      $form['css_settings']['css_variables']['flickrstyle_magnifier'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Magnifier icon'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#weight' => 16,
+      );
+      $magnifierurl = l(t('http://cdn-img.easyicon.net/png/5053/505399.png'), 'http://cdn-img.easyicon.net/png/5053/505399.png', array(
+          'attributes' => array(
+            'title' => t('505399.png (128×128)'),
+            'target' => '_blank',
+          ),
+      ));
+      $form['css_settings']['css_variables']['flickrstyle_magnifier']['flickrstyle_magnifier_imgfield'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('IMAGE SOURCE'),
+        // Make containing fields align horizontally.
+        '#attributes' => array('class' => array('container-inline')),
+        '#description' => t("Absolute URL, e.g. !magnifierurl or relative (local) image URL. A relative URL must be given from the base URL (<em>/sites/..</em>).<br />Leave all empty to reset to the default icon.", array('!magnifierurl' => $magnifierurl)),
+      );
+      // IMAGE UPLOAD.
+      $form['css_settings']['css_variables']['flickrstyle_magnifier']['flickrstyle_magnifier_imgfield']['flickrstyle_magnifier_imgupload'] = array(
+        '#type' => 'managed_file',
+        '#description' => t('Alternatively upload an image. Visible after form submit.'),
+        '#default_value' => variable_get('flickrstyle_magnifier_imgupload', ''),
+        '#size' => 40,
+        '#upload_location' => 'public://flickr/style/',
+        '#theme' => 'image_widget',
+      ); 
+      if (!variable_get('flickrstyle_magnifier_imgupload', '')) {
+        variable_set('flickrstyle_magnifier_imgupload_url', '');
+      }
+      // IMAGE URL example.
+      $uploaded_url = variable_get('flickrstyle_magnifier_imgupload_url', '');
+      $default = empty($uploaded_url) ? variable_get('flickrstyle_magnifier_image', '/' . drupal_get_path('module', 'flickrstyle') . '/img/magnifier.png') : $uploaded_url;
+      $form['css_settings']['css_variables']['flickrstyle_magnifier']['flickrstyle_magnifier_imgfield']['flickrstyle_magnifier_image'] = array(
+        '#type' => 'style_settings_imgurl',
+        '#default_value' => $default,
+        // In the submit handler below we reset an empty field to the default URL.
+        // This way the user isn't required to know the URL of the default image.
+      );
+      $form['css_settings']['css_variables']['flickrstyle_magnifier']['flickrstyle_magnifier_opacity'] = array(
+        '#type' => 'style_settings_slider',
+        '#title' => t('Opacity'),
+        '#description' => t('0 = transparent. 1 = opaque.'),
+        '#default_value' => variable_get('flickrstyle_magnifier_opacity', 0.85),
+      );
+      $form['css_settings']['css_variables']['flickrstyle_magnifier']['flickrstyle_magnifier_size'] = array(
+        '#type' => 'style_settings_number',
+        '#title' => t('Size'),
+        '#default_value' => floatval(variable_get('flickrstyle_magnifier_size', '50px')),
+        '#field_suffix' => t('px'),
+      );
+      // We need a magnifier icon before styling it.
+      if (variable_get('flickrstyle_emphasize', 2) != 4) {
+        $form['css_settings']['css_variables']['flickrstyle_magnifier']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_magnifier']['#description'] = t("Disabled until the 'Magnifier icon' style on hover is selected below and saved.");;
+      }
+      // We need a border before we can use a color or thickness for it.
+      // Same with a shadow when we don't have a real border.
+      if (gettype($styles['shadow']) == 'string' || gettype($styles['border']) == 'integer') {
+        $form['css_settings']['css_variables']['flickrstyle_border_color']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_border_color']['#description'] = t("Disabled until the 'Border' image style is selected below and saved. 'Shadow' must be unselected as it suppresses a real border.");
+        $form['css_settings']['css_variables']['flickrstyle_border_thickness']['#disabled'] = TRUE;
+        $form['css_settings']['css_variables']['flickrstyle_border_thickness']['#description'] = t("Disabled until the 'Border' image style is selected below and saved. 'Shadow' must be unselected as it suppresses a real border.");
+      }
+    }
+
     // We need a shadow and/or border before we can use a style on the caption
     // and a reset to 'No' of it if so.
     if (gettype($styles['shadow']) == 'integer' && gettype($styles['border']) == 'integer') {
@@ -53,11 +213,6 @@ function flickrstyle_form_flickr_admin_settings_alter(&$form, &$form_state) {
     // We need a shadow and/or border before we can use a style on the caption.
     if (gettype($styles['shadow']) == 'integer' && gettype($styles['border']) == 'integer') {
       $form['css_settings']['flickrstyle_caption']['#disabled'] = TRUE;
-      $form['css_settings']['flickrstyle_caption']['#options'] = array(
-        '<span class="grayed-out">' . t('No') . '</span>',
-        '<span class="grayed-out">' . t('Yes, separate from the image') . '</span>',
-        '<span class="grayed-out">' . t('Yes, wrapped around the image and caption') . '</span>',
-      );
       $form['css_settings']['flickrstyle_caption']['#description'] = t('Disabled until a shadow and/or border image style is selected. Select above and save the form to make a caption style available.');
     }
     $form['css_settings']['flickrstyle_nostyle'] = array(
@@ -78,25 +233,18 @@ function flickrstyle_form_flickr_admin_settings_alter(&$form, &$form_state) {
       '#title' => t('Emphasize the image on hover?'),
       '#options' => array(
         t('No'),
-        t('Enlarge slightly (includes the caption)'),
-        t('Enlarge (image only) (*)'),
+        t('Enlarge image + caption (intended for a small scale factor)'),
+        t('Enlarge image (*)'),
         t('Zoom (*)'),
         t('Magnifier icon'),
       ),
       // Defaults to 'Enlarge slightly'.
       '#default_value' => variable_get('flickrstyle_emphasize', 2),
-      '#description' => t("(*): The 'Zoom' and 'Enlarge' styles use bigger images to maintain the resolution. This has a slight performance impact and the size 'big square' (q) is not square but 150px on the longest side to avoid distortion on older browsers."),
+      '#description' => t("(*): The 'Zoom' and 'Enlarge image' styles use bigger images to maintain the resolution. This has a slight performance impact and the size 'big square' (q) is not square but 150px on the longest side to avoid distortion on older browsers."),
       '#weight' => 12,
     );
     // Disable the 'Enlarge' style until a border is set or shadow unselected.
     if (gettype($styles['shadow']) != 'integer' && gettype($styles['border']) == 'integer') {
-      $form['css_settings']['flickrstyle_emphasize']['#options'] = array(
-        t('No'),
-        t('Enlarge slightly (includes the caption)'),
-        '<span class="grayed-out">' . t('Enlarge (image only) (*)') . '</span> <span class="grayed-out-help">' . t("Disabled until you set a 'border' or unselect 'shadow' in the 'Image styles' above. It will be available after saving the form.") . '</span> ',
-        t('Zoom (*)'),
-        t('Magnifier icon'),
-      );
       $form['css_settings']['flickrstyle_emphasize'][2]['#disabled'] = TRUE;
     }
   }
@@ -108,8 +256,34 @@ function flickrstyle_form_flickr_admin_settings_alter(&$form, &$form_state) {
 }
 
 /**
- * Validate user input.
+ * Submit form data.
  */
-function flickrstyle_admin_settings_validate($form, &$form_state) {
-  // Put validation rules here.
+function flickrstyle_admin_settings_submit($form, &$form_state) {
+  if (variable_get('flickr_css', 1) && module_exists('style_settings')) {
+    // Rounded corners: concatenate the value and unit.
+    variable_set('flickrstyle_radius', $form_state['values']['flickrstyle_radius_value'] . $form_state['values']['flickrstyle_radius_unit']);
+
+    //IMAGE UPLOAD.
+    if (!empty($form_state['values']['flickrstyle_magnifier_imgupload'])) {
+      $image = file_load($form_state['values']['flickrstyle_magnifier_imgupload']);
+      $url = '/' . variable_get('file_public_path', conf_path() . '/files') . '/' . file_uri_target($image->uri);
+      variable_set('flickrstyle_magnifier_imgupload_url', $url);
+      // If we have an uploaded file, use the URL of it.
+      $form_state['values']['flickrstyle_magnifier_image'] = $url;
+      $image->status = FILE_STATUS_PERMANENT;
+      file_save($image);
+      // Add a reference to prevent warnings.
+      file_usage_add($image, 'flickrstyle', 'flickrstyle_upload', $image->fid);
+    }
+
+    // IMAGE URL: Reset to default if empty. Does not work after a
+    // hook_form_FORM_ID_alter(). In that case move it to the submit handler
+    // after hook_settings() in the 'parent' form.
+    if (trim($form_state['values']['flickrstyle_magnifier_image']) == '') {
+      $form_state['values']['flickrstyle_magnifier_image'] = '/' . drupal_get_path('module', 'flickrstyle') . '/img/magnifier.png';
+      drupal_set_message(t('The image URL has been reset to the default.'), 'warning', FALSE);
+    }
+  }
+  variable_set('flickrstyle_magnifier_halfsize', '-' . (floatval($form_state['values']['flickrstyle_magnifier_size']) / 2) . 'px');
+  variable_set('flickrstyle_border_thickness_doubled', (floatval($form_state['values']['flickrstyle_border_thickness']) * 2) . 'px');
 }
diff --git a/style/flickrstyle.install b/style/flickrstyle.install
index 4a3b2ae..efe104c 100644
--- a/style/flickrstyle.install
+++ b/style/flickrstyle.install
@@ -12,4 +12,6 @@ function flickrstyle_uninstall() {
   variable_del('flickrstyle_caption');
   variable_del('flickrstyle_emphasize');
   variable_del('flickrstyle_nostyle');
+  variable_del('flickrstyle_rounded');
+  variable_del('flickrstyle_radius');
 }
diff --git a/style/flickrstyle.module b/style/flickrstyle.module
index ef7198a..5e04564 100644
--- a/style/flickrstyle.module
+++ b/style/flickrstyle.module
@@ -24,6 +24,10 @@ function flickrstyle_help($path, $arg) {
 function flickrstyle_page_build(&$page) {
   // Determine the settings which CSS files to use.
   if (variable_get('flickr_css', 1)) {
+    drupal_add_css(drupal_get_path('module', 'flickrstyle') . '/css/flickrstyle.css', array(
+      'group' => CSS_DEFAULT,
+      'every_page' => TRUE,
+    ));
     $styles = variable_get('flickrstyle_styles', array(
       'rounded' => 'rounded',
       'shadow' => 'shadow',
diff --git a/tags/flickr_tags.admin.inc b/tags/flickr_tags.admin.inc
index 6963d63..fce0a1f 100644
--- a/tags/flickr_tags.admin.inc
+++ b/tags/flickr_tags.admin.inc
@@ -16,7 +16,7 @@ function flickr_tags_form_flickr_admin_settings_alter(&$form, &$form_state) {
     '#collapsed' => TRUE,
     '#weight' => 22,
   );
- $form['tags_settings']['flickr_tags_in_cloud'] = array(
+  $form['tags_settings']['flickr_tags_in_cloud'] = array(
     '#type' => 'textfield',
     '#title' => t('Maximum number of tags in a tag cloud'),
     '#required' => TRUE,
@@ -25,15 +25,44 @@ function flickr_tags_form_flickr_admin_settings_alter(&$form, &$form_state) {
     '#size' => 3,
     '#maxlength' => 3,
   );
+  $form['tags_settings']['flickr_tags_minfont'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Minimum font size'),
+    '#required' => TRUE,
+    '#default_value' => variable_get('flickr_tags_minfont', 0.7),
+    '#size' => 3,
+    '#maxlength' => 3,
+    '#field_suffix' => t('em'),
+    '#attributes' => array('class' => array('flickr-form-align')),
+  );
+  $form['tags_settings']['flickr_tags_maxfont'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum font size'),
+    '#required' => TRUE,
+    '#default_value' => variable_get('flickr_tags_maxfont', 3.5),
+    '#size' => 3,
+    '#maxlength' => 3,
+    '#field_suffix' => t('em'),
+    '#attributes' => array('class' => array('flickr-form-align')),
+  );
 }
 
 /**
  * Validate user input.
  */
 function flickr_tags_admin_settings_validate($form, &$form_state) {
-  $limit = trim($form_state['values']['flickr_tags_in_cloud']);
   // Validate tags in cloud.
-  if (!is_numeric($limit) || $limit < 1) {
-    form_set_error('flickr_tags_in_cloud', t('Set a number from 1 to 999.'));
+  $limit = trim($form_state['values']['flickr_tags_in_cloud']);
+  if (!ctype_digit($limit) || $limit < 1) {
+    form_set_error('flickr_tags_in_cloud', t('Set an integer from 1 to 999.'));
+  }
+  // Validate the tags font size.
+  $limit = trim($form_state['values']['flickr_tags_minfont']);
+  if (!is_numeric($limit) || $limit < 0) {
+    form_set_error('flickr_tags_minfont', t('Set a number from 0 to 999.'));
+  }
+  $limit = trim($form_state['values']['flickr_tags_maxfont']);
+  if (!is_numeric($limit) || $limit < 0) {
+    form_set_error('flickr_tags_maxfont', t('Set a number from 0 to 999.'));
   }
 }
diff --git a/tags/flickr_tags.module b/tags/flickr_tags.module
index c2cdd52..a10650e 100644
--- a/tags/flickr_tags.module
+++ b/tags/flickr_tags.module
@@ -229,8 +229,8 @@ function theme_flickr_tags_cloud($variables) {
   $min_occur = min($tags);
 
   // Font size specified in em.
-  $max_font = 3.5;
-  $min_font = 0.7;
+  $max_font = variable_get('flickr_tags_maxfont', 3.5);
+  $min_font = variable_get('flickr_tags_minfont', 0.7);
 
   $output = "<ul id='flickr_tagcloud'>\n";
   foreach ($tags as $tagname => $occurences) {
-- 
1.7.9.5

