summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Staudacher <andy.st@gmail.com>2009-08-29 14:17:48 -0700
committerAndy Staudacher <andy.st@gmail.com>2009-08-29 14:17:48 -0700
commita5dfc81a8f7bef0305b62254252de6df23684199 (patch)
tree4851cb68abede6920208871449dedd2e939c1a16
parentd5660d2d3ea6e8172272f1eb27e8071a1a42d87b (diff)
parenta9fcec755a835e284465bafcc9aba9ec9c2f0f62 (diff)
Merge commit 'upstream/master'
Conflicts: modules/akismet/views/admin_akismet.html.php modules/comment/helpers/comment_rss.php modules/gallery/helpers/gallery_rss.php modules/gallery/libraries/I18n.php modules/gallery/views/permissions_browse.html.php modules/gallery/views/simple_uploader.html.php modules/info/views/info_block.html.php modules/organize/controllers/organize.php modules/organize/views/organize.html.php modules/organize/views/organize_album.html.php themes/default/views/album.html.php themes/default/views/movie.html.php themes/default/views/photo.html.php
-rw-r--r--.htaccess5
-rw-r--r--index.php3
-rwxr-xr-xinstaller/install.sql44
-rw-r--r--installer/installer.php7
-rw-r--r--installer/views/invalid_db_version.html.php5
-rw-r--r--installer/web.php6
-rw-r--r--lib/gallery.ajax.js15
-rw-r--r--lib/gallery.common.js146
-rw-r--r--lib/gallery.dialog.js257
-rw-r--r--lib/gallery.panel.js116
-rw-r--r--lib/gallery.show_full_size.js116
-rw-r--r--lib/jquery-ui.js533
-rw-r--r--modules/akismet/views/admin_akismet.html.php6
-rw-r--r--modules/comment/helpers/comment.php2
-rw-r--r--modules/comment/helpers/comment_installer.php15
-rw-r--r--modules/comment/helpers/comment_rss.php51
-rw-r--r--modules/comment/helpers/comment_theme.php2
-rw-r--r--modules/comment/js/comment.js10
-rw-r--r--modules/comment/models/comment.php10
-rw-r--r--modules/comment/tests/Comment_Model_Test.php40
-rw-r--r--modules/comment/views/admin_comments.html.php2
-rw-r--r--modules/comment/views/comments.html.php10
-rw-r--r--modules/digibug/helpers/digibug_event.php26
-rw-r--r--modules/digibug/helpers/digibug_installer.php2
-rw-r--r--modules/exif/helpers/exif_installer.php2
-rw-r--r--modules/g2_import/helpers/g2_import_installer.php2
-rw-r--r--modules/gallery/controllers/admin_graphics.php39
-rw-r--r--modules/gallery/controllers/admin_languages.php52
-rw-r--r--modules/gallery/controllers/combined.php9
-rw-r--r--modules/gallery/controllers/file_proxy.php2
-rw-r--r--modules/gallery/controllers/l10n_client.php13
-rw-r--r--modules/gallery/controllers/packager.php4
-rw-r--r--modules/gallery/controllers/quick.php14
-rw-r--r--modules/gallery/controllers/simple_uploader.php2
-rw-r--r--modules/gallery/css/l10n_client.css12
-rw-r--r--modules/gallery/css/quick.css52
-rw-r--r--modules/gallery/helpers/album.php23
-rw-r--r--modules/gallery/helpers/gallery.php179
-rw-r--r--modules/gallery/helpers/gallery_installer.php32
-rw-r--r--modules/gallery/helpers/gallery_quick.php152
-rw-r--r--modules/gallery/helpers/gallery_rss.php5
-rw-r--r--modules/gallery/helpers/gallery_theme.php32
-rw-r--r--modules/gallery/helpers/graphics.php92
-rw-r--r--modules/gallery/helpers/item.php53
-rw-r--r--modules/gallery/helpers/module.php8
-rw-r--r--modules/gallery/helpers/photo.php8
-rw-r--r--modules/gallery/helpers/task.php1
-rw-r--r--modules/gallery/js/l10n_client.js7
-rw-r--r--modules/gallery/js/quick.js78
-rw-r--r--modules/gallery/libraries/I18n.php9
-rw-r--r--modules/gallery/libraries/Menu.php38
-rw-r--r--modules/gallery/libraries/ORM_MPTT.php65
-rw-r--r--modules/gallery/libraries/Sendmail.php4
-rw-r--r--modules/gallery/libraries/Theme_View.php9
-rw-r--r--modules/gallery/models/item.php71
-rw-r--r--modules/gallery/tests/Item_Helper_Test.php49
-rw-r--r--modules/gallery/tests/Item_Model_Test.php14
-rw-r--r--modules/gallery/tests/ORM_MPTT_Test.php8
-rw-r--r--modules/gallery/views/admin_graphics.html.php14
-rw-r--r--modules/gallery/views/admin_graphics_gd.html.php23
-rw-r--r--modules/gallery/views/admin_graphics_graphicsmagick.html.php18
-rw-r--r--modules/gallery/views/admin_graphics_imagemagick.html.php20
-rw-r--r--modules/gallery/views/admin_graphics_none.html.php7
-rw-r--r--modules/gallery/views/admin_languages.html.php103
-rw-r--r--modules/gallery/views/admin_maintenance.html.php16
-rw-r--r--modules/gallery/views/admin_modules.html.php2
-rw-r--r--modules/gallery/views/after_install.html.php2
-rw-r--r--modules/gallery/views/after_install_loader.html.php2
-rw-r--r--modules/gallery/views/l10n_client.html.php5
-rw-r--r--modules/gallery/views/permissions_browse.html.php42
-rw-r--r--modules/gallery/views/quick_pane.html.php26
-rw-r--r--modules/gallery/views/simple_uploader.html.php2
-rw-r--r--modules/info/views/info_block.html.php4
-rw-r--r--modules/notification/helpers/notification.php2
-rw-r--r--modules/notification/helpers/notification_event.php72
-rw-r--r--modules/notification/helpers/notification_installer.php4
-rw-r--r--modules/organize/controllers/organize.php560
-rw-r--r--modules/organize/css/organize.css268
-rw-r--r--modules/organize/helpers/organize.php94
-rw-r--r--modules/organize/helpers/organize_event.php4
-rw-r--r--modules/organize/helpers/organize_task.php131
-rw-r--r--modules/organize/helpers/organize_theme.php13
-rw-r--r--modules/organize/js/organize.js789
-rw-r--r--modules/organize/js/organize_init.js29
-rw-r--r--modules/organize/views/organize.html.php53
-rw-r--r--modules/organize/views/organize_album.html.php17
-rw-r--r--modules/organize/views/organize_button_pane.html.php50
-rw-r--r--modules/organize/views/organize_dialog.html.php47
-rw-r--r--modules/organize/views/organize_edit.html.php14
-rw-r--r--modules/organize/views/organize_thumb_grid.html.php26
-rw-r--r--modules/organize/views/organize_tree.html.php44
-rw-r--r--modules/search/helpers/search_event.php5
-rw-r--r--modules/search/helpers/search_installer.php2
-rw-r--r--modules/server_add/controllers/server_add.php33
-rw-r--r--modules/server_add/helpers/server_add_event.php29
-rw-r--r--modules/server_add/helpers/server_add_installer.php4
-rw-r--r--modules/server_add/js/server_add.js8
-rw-r--r--modules/server_add/views/server_add_tree_dialog.html.php9
-rw-r--r--modules/slideshow/helpers/slideshow_event.php18
-rw-r--r--modules/tag/helpers/tag_installer.php4
-rw-r--r--modules/tag/js/tag.js2
-rw-r--r--modules/tag/models/tag.php48
-rw-r--r--modules/user/controllers/password.php2
-rw-r--r--modules/user/helpers/user.php7
-rw-r--r--modules/user/helpers/user_installer.php6
-rw-r--r--modules/user/helpers/user_theme.php12
-rw-r--r--modules/user/models/user.php1
-rw-r--r--modules/user/views/admin_users.html.php2
-rw-r--r--modules/watermark/helpers/watermark_installer.php2
-rw-r--r--themes/admin_default/css/admin_screen.css37
-rw-r--r--themes/admin_default/css/screen.css82
-rw-r--r--themes/admin_default/js/ui.init.js18
-rw-r--r--themes/admin_default/views/admin.html.php1
-rw-r--r--themes/default/css/fix-ie.css4
-rw-r--r--themes/default/css/screen.css155
-rw-r--r--themes/default/js/ui.init.js147
-rw-r--r--themes/default/views/album.html.php2
-rw-r--r--themes/default/views/movie.html.php33
-rw-r--r--themes/default/views/page.html.php1
-rw-r--r--themes/default/views/photo.html.php6
120 files changed, 2673 insertions, 3079 deletions
diff --git a/.htaccess b/.htaccess
index 08b9c5bb..c3f94237 100644
--- a/.htaccess
+++ b/.htaccess
@@ -44,6 +44,11 @@
#
# Then just use your Gallery 3 without the index.php in the url.
#
+# NOTE: future upgrades of Gallery 3 will overwrite this file! If you
+# want these changes to be persistent, you should talk to your system
+# administrator about putting this block into your Apache config
+# files.
+#
# <IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteBase /
diff --git a/index.php b/index.php
index 7def7d16..d0e12cfc 100644
--- a/index.php
+++ b/index.php
@@ -21,7 +21,8 @@
define("IN_PRODUCTION", true);
// Gallery requires PHP 5.2+
-version_compare(PHP_VERSION, "5.2.3", "<") and exit("Gallery requires PHP 5.2.3 or newer.");
+version_compare(PHP_VERSION, "5.2.3", "<") and
+ exit("Gallery requires PHP 5.2.3 or newer (you're using " . PHP_VERSION . ")");
// Gallery requires short_tags to be on
!ini_get("short_open_tag") and exit("Gallery requires short_open_tag to be on.");
diff --git a/installer/install.sql b/installer/install.sql
index 48b504ba..21464379 100755
--- a/installer/install.sql
+++ b/installer/install.sql
@@ -11,7 +11,7 @@ CREATE TABLE {access_caches} (
`edit_2` binary(1) NOT NULL default '0',
`add_2` binary(1) NOT NULL default '0',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {access_caches} VALUES (1,1,'1','0','0','1','0','0');
DROP TABLE IF EXISTS {access_intents};
@@ -29,7 +29,7 @@ CREATE TABLE {access_intents} (
`edit_2` binary(1) default NULL,
`add_2` binary(1) default NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {access_intents} VALUES (1,1,'1','1','0','0','1','1','0','0');
DROP TABLE IF EXISTS {caches};
@@ -43,7 +43,7 @@ CREATE TABLE {caches} (
`cache` longblob,
PRIMARY KEY (`id`),
KEY `tags` (`tags`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {comments};
SET @saved_cs_client = @@character_set_client;
@@ -72,7 +72,7 @@ CREATE TABLE {comments} (
`text` text,
`updated` int(9) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {graphics_rules};
SET @saved_cs_client = @@character_set_client;
@@ -86,7 +86,7 @@ CREATE TABLE {graphics_rules} (
`priority` int(9) NOT NULL,
`target` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {graphics_rules} VALUES (1,1,'a:3:{s:5:\"width\";i:200;s:6:\"height\";i:200;s:6:\"master\";i:2;}','gallery','resize',100,'thumb');
INSERT INTO {graphics_rules} VALUES (2,1,'a:3:{s:5:\"width\";i:640;s:6:\"height\";i:480;s:6:\"master\";i:2;}','gallery','resize',100,'resize');
@@ -99,7 +99,7 @@ CREATE TABLE {groups} (
`special` tinyint(1) default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {groups} VALUES (1,'Everybody',1);
INSERT INTO {groups} VALUES (2,'Registered Users',1);
@@ -111,7 +111,7 @@ CREATE TABLE {groups_users} (
`user_id` int(9) NOT NULL,
PRIMARY KEY (`group_id`,`user_id`),
UNIQUE KEY `user_id` (`user_id`,`group_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {groups_users} VALUES (1,1);
INSERT INTO {groups_users} VALUES (1,2);
@@ -129,7 +129,7 @@ CREATE TABLE {incoming_translations} (
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`,`locale`),
KEY `locale_key` (`locale`,`key`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {items};
SET @saved_cs_client = @@character_set_client;
@@ -171,7 +171,7 @@ CREATE TABLE {items} (
KEY `type` (`type`),
KEY `random` (`rand_key`),
KEY `weight` (`weight`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {items} VALUES (1,NULL,NULL,UNIX_TIMESTAMP(),'',NULL,1,1,NULL,NULL,NULL,0,NULL,'',1,NULL,NULL,2,'weight','ASC',1,NULL,NULL,'Gallery','album',UNIX_TIMESTAMP(),0,1,NULL,'1','1');
DROP TABLE IF EXISTS {items_tags};
@@ -184,7 +184,7 @@ CREATE TABLE {items_tags} (
PRIMARY KEY (`id`),
KEY `tag_id` (`tag_id`,`id`),
KEY `item_id` (`item_id`,`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {logs};
SET @saved_cs_client = @@character_set_client;
@@ -200,7 +200,7 @@ CREATE TABLE {logs} (
`url` varchar(255) default NULL,
`user_id` int(9) default '0',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {messages};
SET @saved_cs_client = @@character_set_client;
@@ -212,7 +212,7 @@ CREATE TABLE {messages} (
`value` varchar(255) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {modules};
SET @saved_cs_client = @@character_set_client;
@@ -224,7 +224,7 @@ CREATE TABLE {modules} (
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {modules} VALUES (1,1,'gallery',10);
INSERT INTO {modules} VALUES (2,1,'user',1);
@@ -248,7 +248,7 @@ CREATE TABLE {outgoing_translations} (
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`,`locale`),
KEY `locale_key` (`locale`,`key`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {permissions};
SET @saved_cs_client = @@character_set_client;
@@ -259,7 +259,7 @@ CREATE TABLE {permissions} (
`name` varchar(64) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {permissions} VALUES (1,'View','view');
INSERT INTO {permissions} VALUES (2,'View Full Size','view_full');
@@ -276,7 +276,7 @@ CREATE TABLE {search_records} (
PRIMARY KEY (`id`),
KEY `item_id` (`item_id`),
FULLTEXT KEY `data` (`data`)
-) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {search_records} VALUES (1,1,0,' Gallery');
DROP TABLE IF EXISTS {sessions};
@@ -287,7 +287,7 @@ CREATE TABLE {sessions} (
`data` text NOT NULL,
`last_activity` int(10) unsigned NOT NULL,
PRIMARY KEY (`session_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {tags};
SET @saved_cs_client = @@character_set_client;
@@ -298,7 +298,7 @@ CREATE TABLE {tags} (
`count` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {tasks};
SET @saved_cs_client = @@character_set_client;
@@ -316,7 +316,7 @@ CREATE TABLE {tasks} (
`updated` int(9) default NULL,
PRIMARY KEY (`id`),
KEY `owner_id` (`owner_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {themes};
SET @saved_cs_client = @@character_set_client;
@@ -327,7 +327,7 @@ CREATE TABLE {themes} (
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {themes} VALUES (1,'default',1);
INSERT INTO {themes} VALUES (2,'admin_default',1);
@@ -350,7 +350,7 @@ CREATE TABLE {users} (
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `hash` (`hash`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {users} VALUES (1,'guest','Guest User','',0,0,NULL,0,1,NULL,NULL,NULL);
INSERT INTO {users} VALUES (2,'admin','Gallery Administrator','',0,0,NULL,1,0,NULL,NULL,NULL);
@@ -364,7 +364,7 @@ CREATE TABLE {vars} (
`value` text,
PRIMARY KEY (`id`),
UNIQUE KEY `module_name` (`module_name`,`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
INSERT INTO {vars} VALUES (1,'gallery','active_site_theme','default');
INSERT INTO {vars} VALUES (2,'gallery','active_admin_theme','admin_default');
diff --git a/installer/installer.php b/installer/installer.php
index b0af561e..456cffaa 100644
--- a/installer/installer.php
+++ b/installer/installer.php
@@ -104,6 +104,13 @@ class installer {
mysql_select_db($config["dbname"]);
}
+ static function verify_version($config) {
+ $result = mysql_query("SHOW VARIABLES WHERE variable_name = \"version\"");
+ $row = mysql_fetch_object($result);
+ $version = substr($row->Value, 0, strpos($row->Value, "-"));
+ return version_compare($version, "5.0.0", ">=");
+ }
+
static function db_empty($config) {
$query = "SHOW TABLES IN {$config['dbname']} LIKE '{$config['prefix']}items'";
return mysql_num_rows(mysql_query($query)) == 0;
diff --git a/installer/views/invalid_db_version.html.php b/installer/views/invalid_db_version.html.php
new file mode 100644
index 00000000..8776ac35
--- /dev/null
+++ b/installer/views/invalid_db_version.html.php
@@ -0,0 +1,5 @@
+<?php defined("SYSPATH") or die("No direct script access.") ?>
+<h1> Uh oh! </h1>
+<p class="error">
+ The MySql database that you are referencing is less than the minimum version of 5.0.0.
+</p>
diff --git a/installer/web.php b/installer/web.php
index 78784539..aceb5368 100644
--- a/installer/web.php
+++ b/installer/web.php
@@ -41,6 +41,8 @@ if (installer::already_installed()) {
if (!installer::connect($config)) {
$content = render("invalid_db_info.html.php");
+ } else if (!installer::verify_version($config)) {
+ $content = render("invalid_db_version.html.php");
} else if (!installer::select_db($config)) {
$content = render("missing_db.html.php");
} else if (!installer::db_empty($config)) {
@@ -104,6 +106,10 @@ function check_environment() {
$errors[] = "PHP is missing the <a href=\"http://php.net/iconv\">iconv extension</a>";
}
+ if (!(extension_loaded("simplexml"))) {
+ $errors[] = "PHP is missing the <a href=\"http://php.net/simplexml\">SimpleXML extension</a>";
+ }
+
if (extension_loaded("mbstring") && (ini_get("mbstring.func_overload") & MB_OVERLOAD_STRING)) {
$errors[] = "The <a href=\"http://php.net/mbstring\">mbstring extension</a> is overloading PHP's native string functions. Please disable it.";
}
diff --git a/lib/gallery.ajax.js b/lib/gallery.ajax.js
new file mode 100644
index 00000000..0cdd8f27
--- /dev/null
+++ b/lib/gallery.ajax.js
@@ -0,0 +1,15 @@
+(function($) {
+ $.widget("ui.gallery_ajax", {
+ _init: function() {
+ this.element.click(function(event) {
+ eval("var ajax_handler = " + $(event.currentTarget).attr("ajax_handler"));
+ $.get($(event.currentTarget).attr("href"), function(data) {
+ eval("var data = " + data);
+ ajax_handler(data);
+ });
+ event.preventDefault();
+ return false;
+ });
+ }
+ });
+})(jQuery);
diff --git a/lib/gallery.common.js b/lib/gallery.common.js
index 1eaa6db2..c6a619c1 100644
--- a/lib/gallery.common.js
+++ b/lib/gallery.common.js
@@ -1,36 +1,28 @@
-/**
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-(function () {
- $.fn.showMessage = function(message) {
+(function ($) {
+ $.fn.gallery_show_message = function(message) {
return this.each(function(i){
$(this).effect("highlight", {"color": "white"}, 3000);
$(this).animate({opacity: 1.0}, 6000);
});
};
-})(jQuery);
-// Vertically align a block element's content
-(function () {
- $.fn.vAlign = function(container) {
+ // Vertically align a block element's content
+ $.fn.gallery_valign = function(container) {
return this.each(function(i){
if (container == null) {
container = 'div';
}
- $(this).html("<" + container + ">" + $(this).html() + "</" + container + ">");
- var el = $(this).children(container + ":first");
+ $(this).html("<" + container + " class=\"gValign\">" + $(this).html() + "</" + container + ">");
+ var el = $(this).children(container + ".gValign");
var elh = $(el).height();
var ph = $(this).height();
var nh = (ph - elh) / 2;
$(el).css('margin-top', nh);
});
};
-})(jQuery);
-// Get the viewport size
-(function () {
- $.getViewportSize = function() {
+ // Get the viewport size
+ $.gallery_get_viewport_size = function() {
return {
width : function() {
return $(window).width();
@@ -40,4 +32,126 @@
}
};
};
+
+ /**
+ * Toggle the processing indicator, both large and small
+ * @param elementID Target ID, including #, to apply .gLoadingSize
+ */
+ $.fn.gallery_show_loading = function() {
+ return this.each(function(i){
+ var size;
+ switch ($(this).attr("id")) {
+ case "#gDialog":
+ case "#gPanel":
+ size = "Large";
+ break;
+ default:
+ size = "Small";
+ break;
+ }
+ $(this).toggleClass("gLoading" + size);
+ });
+ };
+
+ /**
+ * Reduce the width of an image if it's wider than its parent container
+ * @param elementID The image container's ID
+ */
+ $.fn.gallery_fit_photo = function() {
+ return this.each(function(i) {
+ var container_width = $(this).width();
+ var photo = $(this).gallery_get_photo();
+ var photo_width = photo.width();
+ if (container_width < photo_width) {
+ var proportion = container_width / photo_width;
+ photo.width(container_width);
+ photo.height(proportion * photo.height());
+ }
+ });
+ };
+
+ /**
+ * Get a thumbnail or resize photo within a container
+ * @param elementID The image container's ID
+ * @return object
+ */
+ $.fn.gallery_get_photo = function() {
+ var photo = $(this).find("img").filter(function() {
+ return this.id.match(/gPhotoId-\d+/);
+ });
+ return photo;
+ };
+
+ /**
+ * Get the sum of an element's height, margin-top, and margin-bottom
+ * @param elementID the element's ID
+ * @return int
+ */
+ $.fn.gallery_height = function() {
+ var ht = $(this).height();
+ var mt = parseInt($(this).css("margin-top"));
+ var mb = parseInt($(this).css("margin-bottom"));
+ return ht + parseInt(mt) + parseInt(mb);
+ };
+
+ // Add hover state to buttons
+ $.fn.gallery_hover_init = function() {
+ $(".ui-state-default").hover(
+ function(){
+ $(this).addClass("ui-state-hover");
+ },
+ function(){
+ $(this).removeClass("ui-state-hover");
+ }
+ );
+ };
+
+ // Ajax handler for replacing an image, used in Ajax thumbnail rotation
+ $.gallery_replace_image = function(data, thumb) {
+ $(thumb).attr({src: data.src, width: data.width, height: data.height});
+ };
+
+ $.fn.gallery_context_menu = function() {
+ var in_progress = 0;
+ $(".gContextMenu *").removeAttr('title');
+ $(".gContextMenu ul").hide();
+ $(".gContextMenu").hover(
+ function() {
+ if (in_progress == 0) {
+ $(this).find("ul").slideDown("fast", function() { in_progress = 1; });
+ $(this).find(".gDialogLink").gallery_dialog();
+ $(this).find(".gAjaxLink").gallery_ajax();
+ }
+ },
+ function() {
+ $(this).find("ul").slideUp("slow", function() { in_progress = 0; });
+ }
+ );
+ };
+
+ $.gallery_auto_fit_window = function(imageWidth, imageHeight) {
+ var size = $.gallery_get_viewport_size();
+ var width = size.width() - 6,
+ height = size.height() - 6;
+
+ var ratio = width / imageWidth;
+ imageWidth *= ratio;
+ imageHeight *= ratio;
+
+ /* after scaling the width, check that the height fits */
+ if (imageHeight > height) {
+ ratio = height / imageHeight;
+ imageWidth *= ratio;
+ imageHeight *= ratio;
+ }
+
+ // handle the case where the calculation is almost zero (2.14e-14)
+ return {
+ top: Number((height - imageHeight) / 2),
+ left: Number((width - imageWidth) / 2),
+ width: Number(imageWidth),
+ height: Number(imageHeight)
+ };
+ };
+
})(jQuery);
diff --git a/lib/gallery.dialog.js b/lib/gallery.dialog.js
index 74c2f20e..67f3f02d 100644
--- a/lib/gallery.dialog.js
+++ b/lib/gallery.dialog.js
@@ -1,140 +1,141 @@
-/**
- * Fire openDialog() and prevent links from opening
- * @see openDialog()
- */
-function handleDialogEvent(event) {
- var target = event.currentTarget;
- if (!target) {
- target = event.srcElement;
- }
- openDialog(target);
- event.preventDefault();
-}
+(function($) {
+ $.widget("ui.gallery_dialog", {
+ _init: function() {
+ var self = this;
+ if (!self.options.immediate) {
+ this.element.click(function(event) {
+ event.preventDefault();
+ self._show($(event.currentTarget).attr("href"));
+ return false;
+ });
+ } else {
+ self._show(this.element.attr("href"));
+ }
+ },
-function ajaxify_dialog() {
- $("#gDialog form").ajaxForm({
- dataType: "json",
- success: function(data) {
- if (data.form) {
- $("#gDialog form").replaceWith(data.form);
- ajaxify_dialog();
- on_form_loaded();
- if (typeof data.reset == 'function') {
- eval(data.reset + '()');
- }
- }
- if (data.result == "success") {
- if (data.location) {
- window.location = data.location;
- } else {
- window.location.reload();
- }
- }
- }
- });
-};
+ _show: function(sHref) {
+ var self = this;
+ var eDialog = '<div id="gDialog"></div>';
+
+ $("body").append(eDialog);
-/**
- * Display modal dialogs, populate dialog with trigger link's href
- * @requires ui.core
- * @requires ui.draggable
- * @requires ui.resizable
- * @requires ui.dialog
- * @see handleDialogEvent()
- * @see showLoading()
- */
-function openDialog(element) {
- var sHref = $(element).attr("href");
- var sTitle = $(element).attr("title");
- var eDialog = '<div id="gDialog"></div>';
- var dialogWidth;
+ if (!self.options.close) {
+ self.options.close = self.close_dialog;
+ }
+ $("#gDialog").dialog(self.options);
- $("body").append(eDialog);
+ $("#gDialog").gallery_show_loading();
- $("#gDialog").dialog({
- autoOpen: false,
- autoResize: true,
- modal: true,
- resizable: false,
- close: closeDialog
- });
+ $.get(sHref, function(data) {
+ $("#gDialog").html(data).gallery_show_loading();
- showLoading("#gDialog");
+ if ($("#gDialog form").length) {
+ self.form_loaded(null, $("#gDialog form"));
+ }
+ self._layout();
- $.get(sHref, function(data) {
- showLoading("#gDialog");
- $("#gDialog").html(data);
- var dialogHeight = $("#gDialog").height();
- var cssWidth = new String($("#gDialog form").css("width"));
- var childWidth = cssWidth.replace(/[^0-9]/g,"");
- if ($("#gDialog iframe").length) {
- dialogWidth = $(window).width() - 100;
- // Set the iframe width and height
- $("#gDialog iframe").width("100%");
- $("#gDialog iframe").height($(window).height() - 100);
- } else if (childWidth == "" || childWidth > 300) {
- dialogWidth = 500;
- }
- $("#gDialog").dialog('option', 'width', dialogWidth);
+ $("#gDialog").dialog("open");
+ // Remove titlebar for progress dialogs or set title
+ if ($("#gDialog #gProgress").length) {
+ $(".ui-dialog-titlebar").remove();
+ } else if ($("#gDialog h1").length) {
+ $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html());
+ } else if ($("#gDialog fieldset legend").length) {
+ $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html());
+ }
- on_form_loaded();
+ if ($("#gDialog form").length) {
+ self._ajaxify_dialog();
+ }
+ });
+ $("#gDialog").dialog("option", "self", self);
+ },
- $("#gDialog").dialog("open");
- // Remove titlebar for progress dialogs or set title
- if ($("#gDialog #gProgress").length) {
- $(".ui-dialog-titlebar").remove();
- } else if ($("#gDialog h1").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html());
- } else if ($("#gDialog fieldset legend").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html());
- }
+ _layout: function() {
+ var dialogWidth;
+ var dialogHeight = $("#gDialog").height();
+ var cssWidth = new String($("#gDialog form").css("width"));
+ var childWidth = cssWidth.replace(/[^0-9]/g,"");
+ var size = $.gallery_get_viewport_size();
+ if ($("#gDialog iframe").length) {
+ dialogWidth = size.width() - 100;
+ // Set the iframe width and height
+ $("#gDialog iframe").width("100%").height(size.height() - 100);
+ } else if ($("#gDialog .gDialogPanel").length) {
+ dialogWidth = size.width() - 100;
+ $("#gDialog").dialog("option", "height", size.height() - 100);
+ } else if (childWidth == "" || childWidth > 300) {
+ dialogWidth = 500;
+ }
+ $("#gDialog").dialog('option', 'width', dialogWidth);
+ },
+
+ form_loaded: function(event, ui) {
+ // Should be defined (and localized) in the theme
+ MSG_CANCEL = MSG_CANCEL || 'Cancel';
+ var eCancel = '<a href="#" class="gCancel">' + MSG_CANCEL + '</a>';
+ if ($("#gDialog .submit").length) {
+ $("#gDialog .submit").addClass("ui-state-default ui-corner-all");
+ $("#gDialog .submit").parent().append(eCancel);
+ $("#gDialog .gCancel").click(function(event) {
+ $("#gDialog").dialog("close");
+ event.preventDefault();
+ });
+ }
+ $("#gDialog .ui-state-default").hover(
+ function() {
+ $(this).addClass("ui-state-hover");
+ },
+ function() {
+ $(this).removeClass("ui-state-hover");
+ }
+ );
+ },
- ajaxify_dialog();
- });
- return false;
-}
+ close_dialog: function(event, ui) {
+ var self = $("#gDialog").dialog("option", "self");
+ if ($("#gDialog form").length) {
+ self._trigger("form_closing", null, $("#gDialog form"));
+ }
+ self._trigger("dialog_closing", null, $("#gDialog"));
+ $("#gDialog").dialog("destroy").remove();
+ },
-function on_form_loaded() {
- // Should be defined (and localized) in the theme
- MSG_CANCEL = MSG_CANCEL || 'Cancel';
- var eCancel = '<a href="javascript: closeDialog()" class="gCancel">' + MSG_CANCEL + '</a>';
- if ($("#gDialog .submit").length) {
- $("#gDialog .submit").addClass("ui-state-default ui-corner-all");
- $("#gDialog .submit").parent().append(eCancel);
- }
- $("#gDialog").dialog("option", "form", $("#gDialog form"));
- $("#gDialog .ui-state-default").hover(
- function() {
- $(this).addClass("ui-state-hover");
- },
- function() {
- $(this).removeClass("ui-state-hover");
- }
- );
-}
+ _ajaxify_dialog: function() {
+ var self = this;
+ $("#gDialog form").ajaxForm({
+ dataType: "json",
+ success: function(data) {
+ if (data.form) {
+ $("#gDialog form").replaceWith(data.form);
+ self._ajaxify_dialog();
+ self.form_loaded(null, $("#gDialog form"));
+ if (typeof data.reset == 'function') {
+ eval(data.reset + '()');
+ }
+ }
+ if (data.result == "success") {
+ if (data.location) {
+ window.location = data.location;
+ } else {
+ window.location.reload();
+ }
+ }
+ }
+ });
+ },
-function closeDialog() {
- var form = $("#gDialog").dialog("option", "form");
- if (form != null) {
- $("#gDialog").dialog("option", "form").trigger("form_closing");
- }
- $("#gDialog").dialog("destroy").remove();
-}
+ form_closing: function(event, ui) {},
+ dialog_closing: function(event, ui) {}
+ });
-/**
- * Toggle the processing indicator, both large and small
- * @param elementID Target ID, including #, to apply .gLoadingSize
- */
-function showLoading(elementID) {
- var size;
- switch (elementID) {
- case "#gDialog":
- case "#gPanel":
- size = "Large";
- break;
- default:
- size = "Small";
- break;
- }
- $(elementID).toggleClass("gLoading" + size);
-}
+ $.extend($.ui.gallery_dialog, {
+ defaults: {
+ autoOpen: false,
+ autoResize: true,
+ modal: true,
+ resizable: false,
+ position: "center"
+ }
+ });
+})(jQuery);
diff --git a/lib/gallery.panel.js b/lib/gallery.panel.js
index 022e4878..e0bf4259 100644
--- a/lib/gallery.panel.js
+++ b/lib/gallery.panel.js
@@ -1,62 +1,58 @@
-/**
- * Fire togglePanel() and prevent links from opening
- * @see togglePanel()
- */
-function handlePanelEvent(event) {
- togglePanel(event.currentTarget);
- event.preventDefault();
-}
+(function($) {
+ $.widget("ui.gallery_panel", {
+ _init: function() {
+ var self = this;
+ this.element.click(function(event) {
+ event.preventDefault();
+ var element = event.currentTarget;
+ var parent = $(element).parent().parent();
+ var sHref = $(element).attr("href");
+ var parentClass = $(parent).attr("class");
+ var ePanel = "<tr id=\"gPanel\"><td colspan=\"6\"></td></tr>";
-function togglePanel(element, on_success) {
- var parent = $(element).parent().parent();
- var sHref = $(element).attr("href");
- var parentClass = $(parent).attr("class");
- var ePanel = "<tr id=\"gPanel\"><td colspan=\"6\"></td></tr>";
+ if ($("#gPanel").length) {
+ $("#gPanel").slideUp("slow").remove();
+ if ($(element).attr("orig_text")) {
+ $(element).children(".gButtonText").text($(element).attr("orig_text"));
+ }
+ } else {
+ $(parent).after(ePanel);
+ $("#gPanel td").html(sHref);
+ $.get(sHref, function(data) {
+ $("#gPanel td").html(data);
+ self._ajaxify_panel();
+ if ($(element).attr("open_text")) {
+ $(element).attr("orig_text", $(element).children(".gButtonText").text());
+ $(element).children(".gButtonText").text($(element).attr("open_text"));
+ }
+ $("#gPanel").addClass(parentClass).show().slideDown("slow");
+ });
+ }
+ return false;
+ });
+ },
- if ($("#gPanel").length) {
- $("#gPanel").slideUp("slow");
- $("#gPanel *").remove();
- $("#gPanel").remove();
- if ($(element).attr("orig_text")) {
- $(element).children(".gButtonText").text($(element).attr("orig_text"));
- }
- //togglePanel(element, on_success);
- } else {
- $(parent).after(ePanel);
- //showLoading("#here");
- $("#gPanel td").html(sHref);
- $("#gPanel").addClass(parentClass).show().slideDown("slow");
- $.get(sHref, function(data) {
- $("#gPanel td").html(data);
- ajaxify_panel = function() {
- $("#gPanel td form").ajaxForm({
- dataType: "json",
- success: function(data) {
- if (data.form) {
- $("#gPanel td form").replaceWith(data.form);
- ajaxify_panel();
- }
- if (data.result == "success") {
- if (on_success) {
- on_success();
- } else if (data.location) {
- window.location = data.location;
- } else {
- window.location.reload();
- }
- }
- }
- });
- if ($("#gPanel td").hasClass("gLoadingLarge")) {
- showLoading("#gPanel td");
- }
- };
- ajaxify_panel();
- if ($(element).attr("open_text")) {
- $(element).attr("orig_text", $(element).children(".gButtonText").text());
- $(element).children(".gButtonText").text($(element).attr("open_text"));
- }
- });
- }
- return false;
-}
+ _ajaxify_panel: function () {
+ var self = this;
+ $("#gPanel td form").ajaxForm({
+ dataType: "json",
+ success: function(data) {
+ if (data.form) {
+ $("#gPanel td form").replaceWith(data.form);
+ self._ajaxify_panel();
+ }
+ if (data.result == "success") {
+ self._trigger("success", null, {});
+ if (data.location) {
+ window.location = data.location;
+ } else {
+ window.location.reload();
+ }
+ }
+ }
+ });
+ },
+
+ success: function(event, ui) {}
+ });
+ })(jQuery);
diff --git a/lib/gallery.show_full_size.js b/lib/gallery.show_full_size.js
index 8b271db9..7e826c32 100644
--- a/lib/gallery.show_full_size.js
+++ b/lib/gallery.show_full_size.js
@@ -1,76 +1,48 @@
-/**
- * @todo Move inline CSS out to external style sheet (theme style sheet)
- */
-var show_full_size = function(image_url, image_width, image_height) {
- /*
- * Calculate the size of the image panel based on the size of the image and the size of the
- * window. Scale the image so the entire panel fits in the view port.
- */
- function _auto_fit(imageWidth, imageHeight) {
- // ui-dialog gives a padding of 2 pixels
- var windowWidth = $(window).width() - 10;
- var windowHeight = $(window).height() - 10;
+(function($) {
+ /**
+ * @todo Move inline CSS out to external style sheet (theme style sheet)
+ */
+ $.gallery_show_full_size = function(image_url, image_width, image_height) {
+ var width = $(document).width();
+ var height = $(document).height();
+ var size = $.gallery_get_viewport_size();
- /* If the width is greater then scale the image width first */
- if (imageWidth > windowWidth) {
- var ratio = windowWidth / imageWidth;
- imageWidth *= ratio;
- imageHeight *= ratio;
- }
- /* after scaling the width, check that the height fits */
- if (imageHeight > windowHeight) {
- var ratio = windowHeight / imageHeight;
- imageWidth *= ratio;
- imageHeight *= ratio;
- }
+ $("body").append('<div id="gFullsizeOverlay" class="ui-dialog-overlay" ' +
+ 'style="border: none; margin: 0; padding: 0; background-color: #000; ' +
+ 'position: absolute; top: 0px; left: 0px; ' +
+ 'width: ' + width + 'px; height: ' + height + 'px;' +
+ ' opacity: 0.7; filter: alpha(opacity=70);' +
+ '-moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; ' +
+ '-moz-background-inline-policy: -moz-initial; z-index: 1001;"> </div>');
- // handle the case where the calculation is almost zero (2.14e-14)
- return {
- top: Number((windowHeight - imageHeight) / 2),
- left: Number((windowWidth - imageWidth) / 2),
- width: Number(imageWidth),
- height: Number(imageHeight)
- };
- }
+ var image_size = $.gallery_auto_fit_window(image_width, image_height);
- var width = $(document).width();
- var height = $(document).height();
+ $("body").append('<div id="gFullsize" class="ui-dialog ui-widget" ' +
+ 'style="overflow: hidden; display: block; ' +
+ 'position: absolute; z-index: 1002; outline-color: -moz-use-text-color; ' +
+ 'outline-style: none; outline-width: 0px; ' +
+ 'height: ' + image_size.height + 'px; ' +
+ 'width: ' + image_size.width + 'px; ' +
+ 'top: ' + image_size.top + 'px; left: ' + image_size.left + 'px;">' +
+ '<img id="gFullSizeImage" src="' + image_url + '"' +
+ 'height="' + image_size.height + '" width="' + image_size.width + '"/></div>');
- $("body").append('<div id="gFullsizeOverlay" class="ui-dialog-overlay" ' +
- 'style="border: none; margin: 0; padding: 0; background-color: #000; ' +
- 'position: absolute; top: 0px; left: 0px; ' +
- 'width: ' + width + 'px; height: ' + height + 'px; opacity: 0.7; filter: alpha(opacity=70);' +
- '-moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; ' +
- '-moz-background-inline-policy: -moz-initial; z-index: 1001;"> </div>');
-
- var image_size = _auto_fit(image_width, image_height);
-
- $("body").append('<div id="gFullsize" class="ui-dialog ui-widget" ' +
- 'style="overflow: hidden; display: block; ' +
- 'position: absolute; z-index: 1002; outline-color: -moz-use-text-color; ' +
- 'outline-style: none; outline-width: 0px; ' +
- 'height: ' + image_size.height + 'px; ' +
- 'width: ' + image_size.width + 'px; ' +
- 'top: ' + image_size.top + 'px; left: ' + image_size.left + 'px;">' +
- '<img id="gFullSizeImage" src="' + image_url + '"' +
- 'height="' + image_size.height + '" width="' + image_size.width + '"/></div>');
-
- $("#gFullsize").append('<span id="gFullsizeClose" class="fg-button ui-icon ui-state-default ' +
- 'ui-icon-closethick ui-corner-all" style="z-index: 1003; position: absolute; ' +
- 'right: 1em; top: 1em;"></span>');
- $("#gFullsizeClose").click(function() {
- $("#gFullsizeOverlay*").remove();
- $("#gFullsize").remove();
- });
- $(window).resize(function() {
- $("#gFullsizeOverlay").width($(document).width());
- $("#gFullsizeOverlay").height($(document).height());
- image_size = _auto_fit(image_width, image_height);
- $("#gFullsize").height(image_size.height);
- $("#gFullsize").width(image_size.width);
- $("#gFullsize").css("top", image_size.top);
- $("#gFullsize").css("left", image_size.left);
- $("#gFullSizeImage").height(image_size.height);
- $("#gFullSizeImage").width(image_size.width);
- });
-};
+ $().click(function() {
+ $("#gFullsizeOverlay*").remove();
+ $("#gFullsize").remove();
+ });
+ $().bind("keypress", function() {
+ $("#gFullsizeOverlay*").remove();
+ $("#gFullsize").remove();
+ });
+ $(window).resize(function() {
+ $("#gFullsizeOverlay").width($(document).width()).height($(document).height());
+ image_size = $.gallery_auto_fit_window(image_width, image_height);
+ $("#gFullsize").height(image_size.height)
+ .width(image_size.width)
+ .css("top", image_size.top)
+ .css("left", image_size.left);
+ $("#gFullSizeImage").height(image_size.height).width(image_size.width);
+ });
+ };
+})(jQuery);
diff --git a/lib/jquery-ui.js b/lib/jquery-ui.js
index 0c6a0ebe..4939d009 100644
--- a/lib/jquery-ui.js
+++ b/lib/jquery-ui.js
@@ -45,18 +45,6 @@ jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.bro
* ui.core.js
*/
(function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f<k.length;f++){var h=c.trim(k[f]),d="ui-resizable-"+h;var g=c('<div class="ui-resizable-handle '+d+'"></div>');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidth<k.width),l=a(k.height)&&h.maxHeight&&(h.maxHeight<k.height),g=a(k.width)&&h.minWidth&&(h.minWidth>k.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e<this._proportionallyResizeElements.length;e++){var g=this._proportionallyResizeElements[e];if(!this.borderDif){var d=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],h=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=c.map(d,function(k,m){var l=parseInt(k,10)||0,n=parseInt(h[m],10)||0;return l+n})}if(c.browser.msie&&!(!(c(f).is(":hidden")||c(f).parents(":hidden").length))){continue}g.css({height:(f.height()-this.borderDif[0]-this.borderDif[2])||0,width:(f.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var e=this.element,h=this.options;this.elementOffset=e.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));c.extend(c.ui.resizable,{version:"1.7.2",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,t){var s=(q[t]||0)+(j[t]||0);if(s&&s>=0){o[t]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=s._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)){s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/s.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*s.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);;/*
- * jQuery UI Selectable 1.7.2
- *
- * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * http://docs.jquery.com/UI/Selectables
- *
- * Depends:
- * ui.core.js
- */
-(function(a){a.widget("ui.selectable",a.extend({},a.ui.mouse,{_init:function(){var b=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]);c.each(function(){var d=a(this);var e=d.offset();a.data(this,"selectable-item",{element:this,$element:d,left:e.left,top:e.top,right:e.left+d.outerWidth(),bottom:e.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(d){var b=this;this.opos=[d.pageX,d.pageY];if(this.options.disabled){return}var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",d);a(c.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:d.clientX,top:d.clientY,width:0,height:0});if(c.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var e=a.data(this,"selectable-item");e.startselected=true;if(!d.metaKey){e.$element.removeClass("ui-selected");e.selected=false;e.$element.addClass("ui-unselecting");e.unselecting=true;b._trigger("unselecting",d,{unselecting:e.element})}});a(d.target).parents().andSelf().each(function(){var e=a.data(this,"selectable-item");if(e){e.$element.removeClass("ui-unselecting").addClass("ui-selecting");e.unselecting=false;e.selecting=true;e.selected=true;b._trigger("selecting",d,{selecting:e.element});return false}})},_mouseDrag:function(i){var c=this;this.dragged=true;if(this.options.disabled){return}var e=this.options;var d=this.opos[0],h=this.opos[1],b=i.pageX,g=i.pageY;if(d>b){var f=b;b=d;d=f}if(h>g){var f=g;g=h;h=f}this.helper.css({left:d,top:h,width:b-d,height:g-h});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!j||j.element==c.element[0]){return}var k=false;if(e.tolerance=="touch"){k=(!(j.left>b||j.right<d||j.top>g||j.bottom<h))}else{if(e.tolerance=="fit"){k=(j.left>d&&j.right<b&&j.top>h&&j.bottom<g)}}if(k){if(j.selected){j.$element.removeClass("ui-selected");j.selected=false}if(j.unselecting){j.$element.removeClass("ui-unselecting");j.unselecting=false}if(!j.selecting){j.$element.addClass("ui-selecting");j.selecting=true;c._trigger("selecting",i,{selecting:j.element})}}else{if(j.selecting){if(i.metaKey&&j.startselected){j.$element.removeClass("ui-selecting");j.selecting=false;j.$element.addClass("ui-selected");j.selected=true}else{j.$element.removeClass("ui-selecting");j.selecting=false;if(j.startselected){j.$element.addClass("ui-unselecting");j.unselecting=true}c._trigger("unselecting",i,{unselecting:j.element})}}if(j.selected){if(!i.metaKey&&!j.startselected){j.$element.removeClass("ui-selected");j.selected=false;j.$element.addClass("ui-unselecting");j.unselecting=true;c._trigger("unselecting",i,{unselecting:j.element})}}}});return false},_mouseStop:function(d){var b=this;this.dragged=false;var c=this.options;a(".ui-unselecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-unselecting");e.unselecting=false;e.startselected=false;b._trigger("unselected",d,{unselected:e.element})});a(".ui-selecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-selecting").addClass("ui-selected");e.selecting=false;e.selected=true;e.startselected=true;b._trigger("selected",d,{selected:e.element})});this._trigger("stop",d);this.helper.remove();return false}}));a.extend(a.ui.selectable,{version:"1.7.2",defaults:{appendTo:"body",autoRefresh:true,cancel:":input,option",delay:0,distance:0,filter:"*",tolerance:"touch"}})})(jQuery);;/*
* jQuery UI Sortable 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
@@ -107,18 +95,6 @@ jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.bro
* ui.core.js
*/
(function(a){a.widget("ui.tabs",{_init:function(){if(this.options.deselectable!==undefined){this.options.collapsible=this.options.deselectable}this._tabify(true)},_setData:function(b,c){if(b=="selected"){if(this.options.collapsible&&c==this.options.selected){return}this.select(c)}else{this.options[b]=c;if(b=="deselectable"){this.options.collapsible=c}this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+a.data(b)},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+a.data(this.list[0]));return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(c,b){return{tab:c,panel:b,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(n){this.list=this.element.children("ul:first");this.lis=a("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);var p=this,d=this.options;var c=/^#.+/;this.anchors.each(function(r,o){var q=a(o).attr("href");var s=q.split("#")[0],u;if(s&&(s===location.toString().split("#")[0]||(u=a("base")[0])&&s===u.href)){q=o.hash;o.href=q}if(c.test(q)){p.panels=p.panels.add(p._sanitizeSelector(q))}else{if(q!="#"){a.data(o,"href.tabs",q);a.data(o,"load.tabs",q.replace(/#.*$/,""));var w=p._tabId(o);o.href="#"+w;var v=a("#"+w);if(!v.length){v=a(d.panelTemplate).attr("id",w).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(p.panels[r-1]||p.list);v.data("destroy.tabs",true)}p.panels=p.panels.add(v)}else{d.disabled.push(r)}}});if(n){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(d.selected===undefined){if(location.hash){this.anchors.each(function(q,o){if(o.hash==location.hash){d.selected=q;return false}})}if(typeof d.selected!="number"&&d.cookie){d.selected=parseInt(p._cookie(),10)}if(typeof d.selected!="number"&&this.lis.filter(".ui-tabs-selected").length){d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}d.selected=d.selected||0}else{if(d.selected===null){d.selected=-1}}d.selected=((d.selected>=0&&this.anchors[d.selected])||d.selected<0)?d.selected:0;d.disabled=a.unique(d.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(q,o){return p.lis.index(q)}))).sort();if(a.inArray(d.selected,d.disabled)!=-1){d.disabled.splice(a.inArray(d.selected,d.disabled),1)}this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");if(d.selected>=0&&this.anchors.length){this.panels.eq(d.selected).removeClass("ui-tabs-hide");this.lis.eq(d.selected).addClass("ui-tabs-selected ui-state-active");p.element.queue("tabs",function(){p._trigger("show",null,p._ui(p.anchors[d.selected],p.panels[d.selected]))});this.load(d.selected)}a(window).bind("unload",function(){p.lis.add(p.anchors).unbind(".tabs");p.lis=p.anchors=p.panels=null})}else{d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}this.element[d.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");if(d.cookie){this._cookie(d.selected,d.cookie)}for(var g=0,m;(m=this.lis[g]);g++){a(m)[a.inArray(g,d.disabled)!=-1&&!a(m).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled")}if(d.cache===false){this.anchors.removeData("cache.tabs")}this.lis.add(this.anchors).unbind(".tabs");if(d.event!="mouseover"){var f=function(o,i){if(i.is(":not(.ui-state-disabled)")){i.addClass("ui-state-"+o)}};var j=function(o,i){i.removeClass("ui-state-"+o)};this.lis.bind("mouseover.tabs",function(){f("hover",a(this))});this.lis.bind("mouseout.tabs",function(){j("hover",a(this))});this.anchors.bind("focus.tabs",function(){f("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var b,h;if(d.fx){if(a.isArray(d.fx)){b=d.fx[0];h=d.fx[1]}else{b=h=d.fx}}function e(i,o){i.css({display:""});if(a.browser.msie&&o.opacity){i[0].style.removeAttribute("filter")}}var k=h?function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.hide().removeClass("ui-tabs-hide").animate(h,h.duration||"normal",function(){e(o,h);p._trigger("show",null,p._ui(i,o[0]))})}:function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");p._trigger("show",null,p._ui(i,o[0]))};var l=b?function(o,i){i.animate(b,b.duration||"normal",function(){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");e(i,b);p.element.dequeue("tabs")})}:function(o,i,q){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");p.element.dequeue("tabs")};this.anchors.bind(d.event+".tabs",function(){var o=this,r=a(this).closest("li"),i=p.panels.filter(":not(.ui-tabs-hide)"),q=a(p._sanitizeSelector(this.hash));if((r.hasClass("ui-tabs-selected")&&!d.collapsible)||r.hasClass("ui-state-disabled")||r.hasClass("ui-state-processing")||p._trigger("select",null,p._ui(this,q[0]))===false){this.blur();return false}d.selected=p.anchors.index(this);p.abort();if(d.collapsible){if(r.hasClass("ui-tabs-selected")){d.selected=-1;if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){l(o,i)}).dequeue("tabs");this.blur();return false}else{if(!i.length){if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this));this.blur();return false}}}if(d.cookie){p._cookie(d.selected,d.cookie)}if(q.length){if(i.length){p.element.queue("tabs",function(){l(o,i)})}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this))}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(a.browser.msie){this.blur()}});this.anchors.bind("click.tabs",function(){return false})},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var c=a.data(this,"href.tabs");if(c){this.href=c}var d=a(this).unbind(".tabs");a.each(["href","load","cache"],function(e,f){d.removeData(f+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){if(a.data(this,"destroy.tabs")){a(this).remove()}else{a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}});if(b.cookie){this._cookie(null,b.cookie)}},add:function(e,d,c){if(c===undefined){c=this.anchors.length}var b=this,g=this.options,i=a(g.tabTemplate.replace(/#\{href\}/g,e).replace(/#\{label\}/g,d)),h=!e.indexOf("#")?e.replace("#",""):this._tabId(a("a",i)[0]);i.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var f=a("#"+h);if(!f.length){f=a(g.panelTemplate).attr("id",h).data("destroy.tabs",true)}f.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(c>=this.lis.length){i.appendTo(this.list);f.appendTo(this.list[0].parentNode)}else{i.insertBefore(this.lis[c]);f.insertBefore(this.panels[c])}g.disabled=a.map(g.disabled,function(k,j){return k>=c?++k:k});this._tabify();if(this.anchors.length==1){i.addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[c],this.panels[c]))},remove:function(b){var d=this.options,e=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();if(e.hasClass("ui-tabs-selected")&&this.anchors.length>1){this.select(b+(b+1<this.anchors.length?1:-1))}d.disabled=a.map(a.grep(d.disabled,function(g,f){return g!=b}),function(g,f){return g>=b?--g:g});this._tabify();this._trigger("remove",null,this._ui(e.find("a")[0],c[0]))},enable:function(b){var c=this.options;if(a.inArray(b,c.disabled)==-1){return}this.lis.eq(b).removeClass("ui-state-disabled");c.disabled=a.grep(c.disabled,function(e,d){return e!=b});this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]))},disable:function(c){var b=this,d=this.options;if(c!=d.selected){this.lis.eq(c).addClass("ui-state-disabled");d.disabled.push(c);d.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}},select:function(b){if(typeof b=="string"){b=this.anchors.index(this.anchors.filter("[href$="+b+"]"))}else{if(b===null){b=-1}}if(b==-1&&this.options.collapsible){b=this.options.selected}this.anchors.eq(b).trigger(this.options.event+".tabs")},load:function(e){var c=this,g=this.options,b=this.anchors.eq(e)[0],d=a.data(b,"load.tabs");this.abort();if(!d||this.element.queue("tabs").length!==0&&a.data(b,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(e).addClass("ui-state-processing");if(g.spinner){var f=a("span",b);f.data("label.tabs",f.html()).html(g.spinner)}this.xhr=a.ajax(a.extend({},g.ajaxOptions,{url:d,success:function(i,h){a(c._sanitizeSelector(b.hash)).html(i);c._cleanup();if(g.cache){a.data(b,"cache.tabs",true)}c._trigger("load",null,c._ui(c.anchors[e],c.panels[e]));try{g.ajaxOptions.success(i,h)}catch(j){}c.element.dequeue("tabs")}}))},abort:function(){this.element.queue([]);this.panels.stop(false,true);if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup()},url:function(c,b){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",b)},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.7.2",getter:"length",defaults:{ajaxOptions:null,cache:false,cookie:null,collapsible:false,disabled:[],event:"click",fx:null,idPrefix:"ui-tabs-",panelTemplate:"<div></div>",spinner:"<em>Loading&#8230;</em>",tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>'}});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(d,f){var b=this,g=this.options;var c=b._rotate||(b._rotate=function(h){clearTimeout(b.rotation);b.rotation=setTimeout(function(){var i=g.selected;b.select(++i<b.anchors.length?i:0)},d);if(h){h.stopPropagation()}});var e=b._unrotate||(b._unrotate=!f?function(h){if(h.clientX){b.rotate(null)}}:function(h){t=g.selected;c()});if(d){this.element.bind("tabsshow",c);this.anchors.bind(g.event+".tabs",e);c()}else{clearTimeout(b.rotation);this.element.unbind("tabsshow",c);this.anchors.unbind(g.event+".tabs",e);delete this._rotate;delete this._unrotate}}})})(jQuery);;/*
- * jQuery UI Datepicker 1.7.2
- *
- * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * http://docs.jquery.com/UI/Datepicker
- *
- * Depends:
- * ui.core.js
- */
-(function($){$.extend($.ui,{datepicker:{version:"1.7.2"}});var PROP_NAME="datepicker";function Datepicker(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass="ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dateFormat:"mm/dd/yy",firstDay:0,isRTL:false};this._defaults={showOn:"focus",showAnim:"show",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,showMonthAfterYear:false,yearRange:"-10:+10",showOtherMonths:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"normal",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false};$.extend(this._defaults,this.regional[""]);this.dpDiv=$('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(target,inst){var input=$(target);inst.append=$([]);inst.trigger=$([]);if(input.hasClass(this.markerClassName)){return}var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){inst.append=$('<span class="'+this._appendClass+'">'+appendText+"</span>");input[isRTL?"before":"after"](inst.append)}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");inst.trigger=$(this._get(inst,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$('<button type="button"></button>').addClass(this._triggerClass).html(buttonImage==""?buttonText:$("<img/>").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](inst.trigger);inst.trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return}divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst);this._updateAlternate(inst)},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$('<input type="text" id="'+id+'" size="1" style="position: absolute; top: -100px;"/>');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){inst.append.remove();inst.trigger.remove();$target.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;inst.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().removeClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;inst.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().addClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i<this._disabledInputs.length;i++){if(this._disabledInputs[i]==target){return true}}return false},_getInst:function(target){try{return $.data(target,PROP_NAME)}catch(err){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(target,name,value){var inst=this._getInst(target);if(arguments.length==2&&typeof name=="string"){return(name=="defaults"?$.extend({},$.datepicker._defaults):(inst?(name=="all"?$.extend({},inst.settings):this._get(inst,name)):null))}var settings=name||{};if(typeof name=="string"){settings={};settings[name]=value}if(inst){if(this._curInst==inst){this._hideDatepicker(null)}var date=this._getDateDatepicker(target);extendRemove(inst.settings,settings);this._setDateDatepicker(target,date);this._updateDatepicker(inst)}},_changeDatepicker:function(target,name,value){this._optionDatepicker(target,name,value)},_refreshDatepicker:function(target){var inst=this._getInst(target);if(inst){this._updateDatepicker(inst)}},_setDateDatepicker:function(target,date,endDate){var inst=this._getInst(target);if(inst){this._setDate(inst,date,endDate);this._updateDatepicker(inst);this._updateAlternate(inst)}},_getDateDatepicker:function(target){var inst=this._getInst(target);if(inst&&!inst.inline){this._setDateFromField(inst)}return(inst?this._getDate(inst):null)},_doKeyDown:function(event){var inst=$.datepicker._getInst(event.target);var handled=true;var isRTL=inst.dpDiv.is(".ui-datepicker-rtl");inst._keyEvent=true;if($.datepicker._datepickerShowing){switch(event.keyCode){case 9:$.datepicker._hideDatepicker(null,"");break;case 13:var sel=$("td."+$.datepicker._dayOverClass+", td."+$.datepicker._currentClass,inst.dpDiv);if(sel[0]){$.datepicker._selectDay(event.target,inst.selectedMonth,inst.selectedYear,sel[0])}else{$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"))}return false;break;case 27:$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"));break;case 33:$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M");break;case 34:$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M");break;case 35:if(event.ctrlKey||event.metaKey){$.datepicker._clearDate(event.target)}handled=event.ctrlKey||event.metaKey;break;case 36:if(event.ctrlKey||event.metaKey){$.datepicker._gotoToday(event.target)}handled=event.ctrlKey||event.metaKey;break;case 37:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?+1:-1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M")}break;case 38:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,-7,"D")}handled=event.ctrlKey||event.metaKey;break;case 39:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?-1:+1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M")}break;case 40:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,+7,"D")}handled=event.ctrlKey||event.metaKey;break;default:handled=false}}else{if(event.keyCode==36&&event.ctrlKey){$.datepicker._showDatepicker(this)}else{handled=false}}if(handled){event.preventDefault();event.stopPropagation()}},_doKeyPress:function(event){var inst=$.datepicker._getInst(event.target);if($.datepicker._get(inst,"constrainInput")){var chars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat"));var chr=String.fromCharCode(event.charCode==undefined?event.keyCode:event.charCode);return event.ctrlKey||(chr<" "||!chars||chars.indexOf(chr)>-1)}},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return}var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};var self=this;inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){$(this).removeClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).removeClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).removeClass("ui-datepicker-next-hover")}}).bind("mouseover",function(){if(!self._isDisabledDatepicker(inst.inline?inst.dpDiv.parent()[0]:inst.input[0])){$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");$(this).addClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).addClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).addClass("ui-datepicker-next-hover")}}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();var numMonths=this._getNumberOfMonths(inst);var cols=numMonths[1];var width=17;if(cols>1){inst.dpDiv.addClass("ui-datepicker-multi-"+cols).css("width",(width*cols)+"em")}else{inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("")}inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"&&inst==$.datepicker._curInst){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var dpWidth=inst.dpDiv.outerWidth();var dpHeight=inst.dpDiv.outerHeight();var inputWidth=inst.input?inst.input.outerWidth():0;var inputHeight=inst.input?inst.input.outerHeight():0;var viewWidth=(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)+$(document).scrollLeft();var viewHeight=(window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)+$(document).scrollTop();offset.left-=(this._get(inst,"isRTL")?(dpWidth-inputWidth):0);offset.left-=(isFixed&&offset.left==inst.input.offset().left)?$(document).scrollLeft():0;offset.top-=(isFixed&&offset.top==(inst.input.offset().top+inputHeight))?$(document).scrollTop():0;offset.left-=(offset.left+dpWidth>viewWidth&&viewWidth>dpWidth)?Math.abs(offset.left+dpWidth-viewWidth):0;offset.top-=(offset.top+dpHeight>viewHeight&&viewHeight>dpHeight)?Math.abs(offset.top+dpHeight+inputHeight*2-viewHeight):0;return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return}if(inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(event){if(!$.datepicker._curInst){return}var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);if(this._isDisabledDatepicker(target[0])){return}this._adjustInstDate(inst,offset+(period=="M"?this._get(inst,"showCurrentAtPos"):0),period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_selectDay:function(id,month,year,td){var target=$(id);if($(td).hasClass(this._unselectableClass)||this._isDisabledDatepicker(target[0])){return}var inst=this._getInst(target[0]);inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay));this._updateDatepicker(inst)}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof(inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat")||this._get(inst,"dateFormat");var date=this._getDate(inst);dateStr=this.formatDate(altFormat,date,this._getFormatConfig(inst));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDate<firstMon){checkDate.setDate(checkDate.getDate()-3);return $.datepicker.iso8601Week(checkDate)}else{if(checkDate>new Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)<firstDay-3){return 1}}}return Math.floor(((checkDate-firstMon)/86400000)/7)+1},parseDate:function(format,value,settings){if(format==null||value==null){throw"Invalid arguments"}value=(typeof value=="object"?value.toString():value+"");if(value==""){return null}var shortYearCutoff=(settings?settings.shortYearCutoff:null)||this._defaults.shortYearCutoff;var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var year=-1;var month=-1;var day=-1;var doy=-1;var literal=false;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var getNumber=function(match){lookAhead(match);var origSize=(match=="@"?14:(match=="y"?4:(match=="o"?3:2)));var size=origSize;var num=0;while(size>0&&iValue<value.length&&value.charAt(iValue)>="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j<names.length;j++){size=Math.max(size,names[j].length)}var name="";var iInit=iValue;while(size>0&&iValue<value.length){name+=value.charAt(iValue++);for(var i=0;i<names.length;i++){if(name==names[i]){return i+1}}size--}throw"Unknown name at position "+iInit};var checkLiteral=function(){if(value.charAt(iValue)!=format.charAt(iFormat)){throw"Unexpected literal at position "+iValue}iValue++};var iValue=0;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{checkLiteral()}}else{switch(format.charAt(iFormat)){case"d":day=getNumber("d");break;case"D":getName("D",dayNamesShort,dayNames);break;case"o":doy=getNumber("o");break;case"m":month=getNumber("m");break;case"M":month=getName("M",monthNamesShort,monthNames);break;case"y":year=getNumber("y");break;case"@":var date=new Date(getNumber("@"));year=date.getFullYear();month=date.getMonth()+1;day=date.getDate();break;case"'":if(lookAhead("'")){checkLiteral()}else{literal=true}break;default:checkLiteral()}}}if(year==-1){year=new Date().getFullYear()}else{if(year<100){year+=new Date().getFullYear()-new Date().getFullYear()%100+(year<=shortYearCutoff?0:-100)}}if(doy>-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=this._daylightSavingAdjust(new Date(year,month-1,day));if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var formatNumber=function(match,value,len){var num=""+value;if(lookAhead(match)){while(num.length<len){num="0"+num}}return num};var formatName=function(match,value,shortNames,longNames){return(lookAhead(match)?longNames[value]:shortNames[value])};var output="";var literal=false;if(date){for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{output+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":output+=formatNumber("d",date.getDate(),2);break;case"D":output+=formatName("D",date.getDay(),dayNamesShort,dayNames);break;case"o":var doy=date.getDate();for(var m=date.getMonth()-1;m>=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{chars+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":case"m":case"y":case"@":chars+="0123456789";break;case"D":case"M":return null;case"'":if(lookAhead("'")){chars+="'"}else{literal=true}break;default:chars+=format.charAt(iFormat)}}}return chars},_get:function(inst,name){return inst.settings[name]!==undefined?inst.settings[name]:this._defaults[name]},_setDateFromField:function(inst){var dateFormat=this._get(inst,"dateFormat");var dates=inst.input?inst.input.val():null;inst.endDay=inst.endMonth=inst.endYear=null;var date=defaultDate=this._getDefaultDate(inst);var settings=this._getFormatConfig(inst);try{date=this.parseDate(dateFormat,dates,settings)||defaultDate}catch(event){this.log(event);date=defaultDate}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates?date.getDate():0);inst.currentMonth=(dates?date.getMonth():0);inst.currentYear=(dates?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setDate(date.getDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));date=(date&&date.toString()=="Invalid Date"?defaultDate:date);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return this._daylightSavingAdjust(date)},_daylightSavingAdjust:function(date){if(!date){return null}date.setHours(date.getHours()>12?date.getHours()+2:0);return date},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return startDate},_generateHTML:function(inst){var today=new Date();today=this._daylightSavingAdjust(new Date(today.getFullYear(),today.getMonth(),today.getDate()));var isRTL=this._get(inst,"isRTL");var showButtonPanel=this._get(inst,"showButtonPanel");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=this._daylightSavingAdjust((!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=this._daylightSavingAdjust(new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate()));maxDraw=(minDate&&maxDraw<minDate?minDate:maxDraw);while(this._daylightSavingAdjust(new Date(drawYear,drawMonth,1))>maxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}inst.drawMonth=drawMonth;inst.drawYear=drawYear;var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,this._daylightSavingAdjust(new Date(drawYear,drawMonth-stepMonths,1)),this._getFormatConfig(inst)));var prev=(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', -"+stepMonths+", 'M');\" title=\""+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>"));var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,this._daylightSavingAdjust(new Date(drawYear,drawMonth+stepMonths,1)),this._getFormatConfig(inst)));var next=(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', +"+stepMonths+", 'M');\" title=\""+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>"));var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var controls=(!inst.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">'+this._get(inst,"closeText")+"</button>":"");var buttonPanel=(showButtonPanel)?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(isRTL?controls:"")+(this._isInRange(inst,gotoDate)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#'+inst.id+"');\">"+currentText+"</button>":"")+(isRTL?"":controls)+"</div>":"";var firstDay=parseInt(this._get(inst,"firstDay"),10);firstDay=(isNaN(firstDay)?0:firstDay);var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var monthNamesShort=this._get(inst,"monthNamesShort");var beforeShowDay=this._get(inst,"beforeShowDay");var showOtherMonths=this._get(inst,"showOtherMonths");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var endDate=inst.endDay?this._daylightSavingAdjust(new Date(inst.endYear,inst.endMonth,inst.endDay)):currentDate;var defaultDate=this._getDefaultDate(inst);var html="";for(var row=0;row<numMonths[0];row++){var group="";for(var col=0;col<numMonths[1];col++){var selectedDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,inst.selectedDay));var cornerClass=" ui-corner-all";var calender="";if(isMultiMonth){calender+='<div class="ui-datepicker-group ui-datepicker-group-';switch(col){case 0:calender+="first";cornerClass=" ui-corner-"+(isRTL?"right":"left");break;case numMonths[1]-1:calender+="last";cornerClass=" ui-corner-"+(isRTL?"left":"right");break;default:calender+="middle";cornerClass="";break}calender+='">'}calender+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+cornerClass+'">'+(/all|left/.test(cornerClass)&&row==0?(isRTL?next:prev):"")+(/all|right/.test(cornerClass)&&row==0?(isRTL?prev:next):"")+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,monthNames,monthNamesShort)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var thead="";for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;thead+="<th"+((dow+firstDay+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+dayNames[day]+'">'+dayNamesMin[day]+"</span></th>"}calender+=thead+"</tr></thead><tbody>";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));var printDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,1-leadDays));for(var dRow=0;dRow<numRows;dRow++){calender+="<tr>";var tbody="";for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDate<minDate)||(maxDate&&printDate>maxDate);tbody+='<td class="'+((dow+firstDay+6)%7>=5?" ui-datepicker-week-end":"")+(otherMonth?" ui-datepicker-other-month":"")+((printDate.getTime()==selectedDate.getTime()&&drawMonth==inst.selectedMonth&&inst._keyEvent)||(defaultDate.getTime()==printDate.getTime()&&defaultDate.getTime()==selectedDate.getTime())?" "+this._dayOverClass:"")+(unselectable?" "+this._unselectableClass+" ui-state-disabled":"")+(otherMonth&&!showOtherMonths?"":" "+daySettings[1]+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?"":" onclick=\"DP_jQuery.datepicker._selectDay('#"+inst.id+"',"+drawMonth+","+drawYear+', this);return false;"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():"&#xa0;"):(unselectable?'<span class="ui-state-default">'+printDate.getDate()+"</span>":'<a class="ui-state-default'+(printDate.getTime()==today.getTime()?" ui-state-highlight":"")+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" ui-state-active":"")+'" href="#">'+printDate.getDate()+"</a>"))+"</td>";printDate.setDate(printDate.getDate()+1);printDate=this._daylightSavingAdjust(printDate)}calender+=tbody+"</tr>"}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}calender+="</tbody></table>"+(isMultiMonth?"</div>"+((numMonths[0]>0&&col==numMonths[1]-1)?'<div class="ui-datepicker-row-break"></div>':""):"");group+=calender}html+=group}html+=buttonPanel+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,monthNames,monthNamesShort){minDate=(inst.rangeStart&&minDate&&selectedDate<minDate?selectedDate:minDate);var changeMonth=this._get(inst,"changeMonth");var changeYear=this._get(inst,"changeYear");var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='<div class="ui-datepicker-title">';var monthHtml="";if(secondary||!changeMonth){monthHtml+='<span class="ui-datepicker-month">'+monthNames[drawMonth]+"</span> "}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='<select class="ui-datepicker-month" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'M');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='<option value="'+month+'"'+(month==drawMonth?' selected="selected"':"")+">"+monthNamesShort[month]+"</option>"}}monthHtml+="</select>"}if(!showMonthAfterYear){html+=monthHtml+((secondary||changeMonth||changeYear)&&(!(changeMonth&&changeYear))?"&#xa0;":"")}if(secondary||!changeYear){html+='<span class="ui-datepicker-year">'+drawYear+"</span>"}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=drawYear+parseInt(years[0],10);endYear=drawYear+parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='<select class="ui-datepicker-year" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'Y');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(;year<=endYear;year++){html+='<option value="'+year+'"'+(year==drawYear?' selected="selected"':"")+">"+year+"</option>"}html+="</select>"}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?"&#xa0;":"")+monthHtml}html+="</div>";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart<newMinDate?inst.rangeStart:newMinDate);var minDate=newMinDate||this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date>=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.7.2";window.DP_jQuery=$})(jQuery);;/*
* jQuery UI Progressbar 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
@@ -163,4 +139,511 @@ jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(v
* Depends:
* effects.core.js
*/
-(function(a){a.effects.transfer=function(b){return this.queue(function(){var f=a(this),h=a(b.options.to),e=h.offset(),g={top:e.top,left:e.left,height:h.innerHeight(),width:h.innerWidth()},d=f.offset(),c=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);; \ No newline at end of file
+(function(a){a.effects.transfer=function(b){return this.queue(function(){var f=a(this),h=a(b.options.to),e=h.offset(),g={top:e.top,left:e.left,height:h.innerHeight(),width:h.innerWidth()},d=f.offset(),c=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);;/*
+ * jQuery UI Selectable @VERSION
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function($) {
+
+ $.widget('ui.selectable', $.extend({}, $.ui.mouse, {
+
+ _init: function() {
+
+ var self = this;
+ this.items = $(this.options.filter, this.element);
+ this.element.addClass("ui-selectable");
+
+ //Set the currentFocus to the first item
+ this.currentFocus = this.items.eq(0);
+
+ //Refresh item positions
+ this.refresh();
+
+ //Disable text selection
+ this.element.disableSelection();
+
+ //Prepare caret selection
+ if(this.options.lasso) this._mouseInit();
+
+ this.element
+ .bind('mousedown.selectable', function(event) {
+
+ var item = self._targetIsItem(event.target);
+ if (!item) return;
+
+ // If item is part of current selection and current
+ // selection is multiple, return and allow mouseup
+ // to fire (Windows gets this right too, OSX doesn't)
+ if(self._selection.length > 1 && $(item).hasClass(self.options.selectedClass)) {
+ return (self._listenForMouseUp = 1);
+ }
+
+ if(self._trigger('beforeselect', event) === false)
+ return true;
+
+ self._select(event, item);
+ self.element[0].focus();
+ event.preventDefault();
+
+ })
+ .bind('mouseup.selectable', function(event) {
+ if(self._listenForMouseUp) {
+
+ self._listenForMouseUp = 0;
+ var item = self._targetIsItem(event.target);
+ if (!item) return;
+
+ if(self._trigger('beforeselect', event) === false)
+ return true;
+
+ self._select(event, item);
+ self.element[0].focus();
+ event.preventDefault();
+ }
+ })
+ .bind('focus.selectable', function() {
+ self.currentFocus.addClass('ui-focused');
+ })
+ .bind('blur.selectable', function() {
+ self.currentFocus.removeClass('ui-focused');
+ })
+ .bind('keydown.selectable', function(event) {
+
+ if(!self.options.keyboard)
+ return;
+
+ if(self._trigger('beforeselect', event) === false)
+ return true;
+
+ if(event.keyCode == $.ui.keyCode.DOWN) {
+ self.options.smart ? self.selectClosest('down', event) : self.selectNext(event);
+ event.preventDefault();
+ }
+
+ if(event.keyCode == $.ui.keyCode.RIGHT) {
+ self.options.smart ? self.selectClosest('right', event) : self.selectNext(event);
+ event.preventDefault();
+ }
+
+ if(event.keyCode == $.ui.keyCode.UP) {
+ self.options.smart ? self.selectClosest('up', event) : self.selectPrevious(event);
+ event.preventDefault();
+ }
+
+ if(event.keyCode == $.ui.keyCode.LEFT) {
+ self.options.smart ? self.selectClosest('left', event) : self.selectPrevious(event);
+ event.preventDefault();
+ }
+
+ if ((event.ctrlKey || event.metaKey) && event.keyCode == $.ui.keyCode.SPACE) {
+ self._toggleSelection(self.currentFocus, event);
+ }
+
+ });
+
+ this.helper = $(document.createElement('div'))
+ .addClass("ui-selectable-lasso");
+
+ },
+
+ selectClosest: function(direction, event) {
+
+ var current = [/(down|right)/.test(direction) ? 10000 : -10000, null],
+ overlap = 10000,
+ selfOffset = this.currentFocus.data('selectable-item');
+
+ $(this.options.filter, this.element).not(this.currentFocus).filter(':visible').each(function() {
+
+ var $this = $(this),
+ offset = $this.data('selectable-item'),
+ distance = {
+ x: Math.abs(selfOffset.left - offset.left) + Math.abs((offset.left+this.offsetWidth) - (selfOffset.left+this.offsetWidth)),
+ y: Math.abs(selfOffset.top - offset.top) + Math.abs((offset.top+this.offsetHeight) - (selfOffset.top+this.offsetHeight))
+ };
+
+ switch(direction) {
+
+ case 'up':
+ if((selfOffset.top > offset.top && offset.top >= current[0]) && (offset.top != current[0] || distance.x < overlap)) {
+ current = [offset.top, $this];
+ overlap = distance.x;
+ }
+ break;
+
+ case 'down':
+ if((selfOffset.top < offset.top && offset.top <= current[0]) && (offset.top != current[0] || distance.x < overlap)) {
+ current = [offset.top, $this];
+ overlap = distance.x;
+ }
+ break;
+
+ case 'left':
+ if((selfOffset.left > offset.left && offset.left >= current[0]) && (offset.left != current[0] || distance.y < overlap)) {
+ current = [offset.left, $this];
+ overlap = distance.y;
+ }
+ break;
+
+ case 'right':
+ if((selfOffset.left < offset.left && offset.left <= current[0]) && (offset.left != current[0] || distance.y < overlap)) {
+ current = [offset.left, $this];
+ overlap = distance.y;
+ }
+ break;
+
+ }
+
+ });
+
+ return current[1] ? this._select(event, current[1]) : false;
+
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass("ui-selectable ui-selectable-disabled")
+ .removeData("selectable")
+ .unbind(".selectable");
+ this._mouseDestroy();
+ },
+
+ _mouseCapture: function(event) {
+ //If the item we start dragging on is a selectable, we bail (if keyboard is used)
+ this.clickedOnItem = this._targetIsItem(event.target);
+ return !this.options.keyboard || !this.clickedOnItem;
+ },
+
+ _mouseStart: function(event) {
+
+ var self = this, o = this.options;
+ this.opos = [event.pageX, event.pageY];
+
+ if (o.disabled)
+ return;
+
+ //Cache positions
+ this.refresh();
+
+ //Trigger start event
+ this._trigger("start", event, this._uiHash());
+
+ // append and position helper (lasso)
+ $('body').append(this.helper);
+ this.helper.css({
+ zIndex: 100,
+ position: "absolute",
+ left: event.clientX,
+ top: event.clientY,
+ width: 0,
+ height: 0
+ });
+
+ //Tell the intersection that some start selected
+ this.items.filter('.'+this.options.selectedClass).each(function() {
+ if(event.metaKey) {
+ if(this != self.clickedOnItem) $.data(this, "selectable-item").startSelected = true;
+ } else self._removeFromSelection($(this), event);
+ });
+
+ },
+
+ _mouseDrag: function(event) {
+
+ var self = this, o = this.options;
+
+ if (o.disabled)
+ return;
+
+ //Do the lasso magic
+ var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
+ if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
+ if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
+ this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
+
+ //Loop through all items and check overlaps
+ this.items.each(function() {
+
+ var item = $.data(this, "selectable-item");
+
+ //prevent helper from being selected if appendTo: selectable
+ if (!item || item.element == self.element[0])
+ return;
+
+ var hit = false;
+ if (o.lasso && o.lasso.tolerance == 'touch') {
+ hit = ( !(item.left > x2 || item.right < x1 || item.top > y2 || item.bottom < y1) );
+ } else if (o.lasso && o.lasso.tolerance == 'fit') {
+ hit = (item.left > x1 && item.right < x2 && item.top > y1 && item.bottom < y2);
+ }
+
+ hit ?
+ item.startSelected ? self._removeFromSelection($(this), event) : self._addToSelection($(this), event)
+ : !item.startSelected ? self._removeFromSelection($(this), event) : self._addToSelection($(this), event);
+
+ });
+
+ return false;
+
+ },
+
+ _mouseStop: function(event) {
+ this._trigger("stop", event, this._uiHash());
+ this.helper.remove();
+ return false;
+ },
+
+ _targetIsItem: function(item) {
+ var found = $(item).parents().andSelf().filter(':data(selectable-item)');
+ return found.length && found;
+ },
+
+ _selection: [],
+
+ _clearSelection: function(triggerEvent) {
+
+ var triggerItems = [];
+
+ for (var i = this._selection.length - 1; i >= 0; i--){
+ if(triggerEvent && this._selection[i].data('selectable-item').selected) triggerItems.push(this._selection[i]);
+ this._selection[i].removeClass(this.options.selectedClass);
+ this._selection[i].data('selectable-item').selected = false;
+ };
+
+ this._selection = [];
+ if(triggerEvent) this._trigger('unselect', triggerEvent, this._uiHash($($.map(triggerItems, function(i) { return i[0]; })), 'removed'));
+
+ },
+
+ _toggleSelection: function(item, event) {
+ item.data('selectable-item').selected ? this._removeFromSelection(item, event) : this._addToSelection(item);
+ },
+
+ _addToSelection: function(item, triggerEvent) {
+
+ if (item.data('selectable-item').selected)
+ return null;
+
+ this._selection.push(item);
+ this.latestSelection = item;
+ item.addClass(this.options.selectedClass);
+ item.data('selectable-item').selected = true;
+
+ if(triggerEvent) {
+ this._trigger('select', triggerEvent, $.extend({ lasso: true }, this._uiHash(item)));
+ }
+
+ return item;
+
+ },
+
+ _removeFromSelection: function(item, triggerEvent) {
+
+ for (var i=0; i < this._selection.length; i++) {
+ if (this._selection[i][0] == item[0]) {
+ this._selection[i].removeClass(this.options.selectedClass);
+ this._selection[i].data('selectable-item').selected = false;
+ this._selection.splice(i,1);
+ if(triggerEvent) this._trigger('unselect', triggerEvent, this._uiHash($(item), 'removed'));
+ break;
+ }
+ };
+
+ },
+
+ _updateSelectionMouse: function(event) {
+
+ var newlySelected = [];
+
+ if (event.shiftKey && this.options.multiple) {
+
+ //Clear the previous selection to make room for a shift selection
+ this._clearSelection(event);
+
+ var index = this.items.index(this.latestWithoutModifier[0]) > this.items.index(this.currentFocus[0]) ? -1 : 1;
+ var i = this.latestWithoutModifier.data('selectable-item').selected ? this.items.eq(this.items.index(this.latestWithoutModifier[0])+index) : this.latestWithoutModifier;
+ while(i.length && i[0] != this.currentFocus[0]) {
+ i[0] == this.previousFocus[0] ? this._addToSelection(i) : newlySelected.push(this._addToSelection(i));
+ i = this.items.eq(this.items.index(i[0])+index);
+ }
+
+ //Readd the item with the current focus
+ newlySelected.push(this._addToSelection(this.currentFocus));
+
+ } else {
+
+ if (event.metaKey) {
+ this._toggleSelection(this.currentFocus, event);
+ } else {
+ this._clearSelection(event);
+ newlySelected.push(this._addToSelection(this.currentFocus));
+ this.latestWithoutModifier = this.currentFocus;
+ }
+
+ }
+
+ return $($.map(newlySelected, function(i) { return i[0]; }));
+
+ },
+
+ _updateSelection: function(event, index) {
+
+ var newlySelected = [];
+
+ if (event.shiftKey && this.options.multiple) {
+
+ if (this.currentFocus.data('selectable-item').selected) {
+ this._removeFromSelection(this.previousFocus, event);
+ } else {
+
+ var index2 = this.items.index(this.latestSelection[0]) > this.items.index(this.currentFocus[0]) ? 1 : -1;
+ if (!this.previousFocus.data('selectable-item').selected) {
+ var i = index == index2 ? this.items.eq(this.items.index(this.previousFocus[0])+index2) : this.previousFocus;
+ while(i.length && !i.data('selectable-item').selected) {
+ newlySelected.push(this._addToSelection(i));
+ i = this.items.eq(this.items.index(i[0])+index2);
+ }
+ }
+
+ newlySelected.push(this._addToSelection(this.currentFocus));
+
+ }
+
+ } else {
+
+ //If the CTRL or Apple/Win key is pressed, only set focus
+ if (event.metaKey)
+ return;
+
+ this._clearSelection(event);
+ newlySelected.push(this._addToSelection(this.currentFocus));
+ this.latestWithoutModifier = this.currentFocus;
+
+ }
+
+ return $($.map(newlySelected, function(i) { return i[0]; }));
+
+ },
+
+ _select: function(event, item) {
+
+ //Set the current selection to the previous/next item
+ this.previousFocus = this.currentFocus;
+ this.currentFocus = $(item);
+
+ this.previousFocus.removeClass('ui-focused');
+ this.currentFocus.addClass('ui-focused');
+
+ //Set and update the selection
+ var newlySelected = this._updateSelectionMouse(event);
+
+ //Trigger select event
+ if(newlySelected && newlySelected.length) this._trigger('select', event, this._uiHash(newlySelected, 'added'));
+
+ },
+
+ _selectAdjacent: function(event, index) {
+
+ var item = this.items.eq(this.items.index(this.currentFocus[0]) + index);
+
+ //Bail if there's no previous/next item
+ if (!item.length) return;
+
+ //Set the current selection to the previous/next item
+ this.previousFocus = this.currentFocus;
+ this.currentFocus = item;
+
+ this.previousFocus.removeClass('ui-focused');
+ this.currentFocus.addClass('ui-focused');
+
+ //Set and update the selection
+ var newlySelected = this._updateSelection(event, index);
+
+ //Trigger select event
+ if(newlySelected && newlySelected.length) this._trigger('select', event, this._uiHash(newlySelected, 'added'));
+
+ },
+
+ selectPrevious: function(event) {
+ this._selectAdjacent(event, -1);
+ },
+
+ selectNext: function(event) {
+ this._selectAdjacent(event, 1);
+ },
+
+ refresh: function() {
+
+ var o = this.options;
+ this.items = $(o.filter, this.element);
+ this.items.each(function() {
+ var $this = $(this);
+ var pos = $this.offset();
+ $.data(this, "selectable-item", {
+ left: pos.left,
+ top: pos.top,
+ right: pos.left + $this.width(),
+ bottom: pos.top + $this.height(),
+ startSelected: false,
+ selected: $this.hasClass(o.selectedClass)
+ });
+ });
+
+ },
+
+ select: function(item) {
+ //TODO
+ },
+
+ deselect: function(item) {
+ if(!item) this._clearSelection(true);
+ //TODO: Deselect single elements
+ },
+
+ _uiHash: function(items, specialKey) {
+ var uiHash = {
+ previousFocus: this.previousFocus,
+ currentFocus: this.currentFocus,
+ selection: $($.map(this._selection, function(i) { return i[0]; }))
+ };
+ if(specialKey) uiHash[specialKey] = items;
+ return uiHash;
+ }
+
+ }));
+
+ $.extend($.ui.selectable, {
+ defaults: {
+
+ //TODO: Figure out how to move these defaults out
+ cancel: ":input,option",
+ delay: 0,
+ distance: 1,
+ appendTo: 'body',
+
+ multiple: true,
+ smart: true,
+ filter: '> *',
+
+ keyboard: true,
+ lasso: {
+ cancel: ":input,option",
+ delay: 0,
+ distance: 1,
+ tolerance: 'touch',
+ appendTo: 'body'
+ },
+
+ //Should we really delete that?
+ selectedClass: 'ui-state-selected'
+ }
+ });
+
+})(jQuery);
diff --git a/modules/akismet/views/admin_akismet.html.php b/modules/akismet/views/admin_akismet.html.php
index cc5e3cfc..009d8810 100644
--- a/modules/akismet/views/admin_akismet.html.php
+++ b/modules/akismet/views/admin_akismet.html.php
@@ -3,12 +3,12 @@
<h1> <?= t("Akismet Spam Filtering") ?> </h1>
<p>
<?= t("Akismet is a free, automated spam filtering service. In order to use it, you need to sign up for a <a href=\"%api_key_url\">Wordpress.com API Key</a>, which is also free. Your comments will be automatically relayed to <a href=\"%akismet_url\">Akismet.com</a> where they'll be scanned for spam. Spam messages will be flagged accordingly and hidden from your vistors until you approve or delete them.",
- array("api_key_url" => "http://wordpress.com/api-keys",
- "akismet_url" => "http://akismet.com")) ?>
+ array("api_key_url" => "http://wordpress.com/api-keys",
+ "akismet_url" => "http://akismet.com")) ?>
</p>
<? if ($valid_key): ?>
- <div class="gSuccess">
+ <div class="gModuleStatus gSuccess">
<?= t("Your API Key is valid. Your comments will be filtered!") ?>
</div>
<? endif ?>
diff --git a/modules/comment/helpers/comment.php b/modules/comment/helpers/comment.php
index 3d743325..f74a8644 100644
--- a/modules/comment/helpers/comment.php
+++ b/modules/comment/helpers/comment.php
@@ -35,7 +35,7 @@ class comment_Core {
* @return Comment_Model
*/
static function create($item, $author, $text, $guest_name=null,
- $guest_email=ull, $guest_url=null) {
+ $guest_email=null, $guest_url=null) {
$comment = ORM::factory("comment");
$comment->author_id = $author->id;
$comment->guest_email = $guest_email;
diff --git a/modules/comment/helpers/comment_installer.php b/modules/comment/helpers/comment_installer.php
index f54913c3..80594c16 100644
--- a/modules/comment/helpers/comment_installer.php
+++ b/modules/comment/helpers/comment_installer.php
@@ -44,7 +44,7 @@ class comment_installer {
`text` text,
`updated` int(9) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
block_manager::add("dashboard_center", "comment", "recent_comments");
module::set_var("comment", "spam_caught", 0);
@@ -52,8 +52,8 @@ class comment_installer {
}
static function upgrade($version) {
+ $db = Database::instance();
if ($version == 1) {
- $db = Database::instance();
$db->query("ALTER TABLE {comments} CHANGE `state` `state` varchar(15) default 'unpublished'");
module::set_version("comment", 2);
}
@@ -61,9 +61,16 @@ class comment_installer {
static function uninstall() {
$db = Database::instance();
- $sql = "SELECT `item_id` FROM {comments}";
- module::event("item_related_update_batch", $sql);
+ // Notify listeners that we're deleting some data. This is probably going to be very
+ // inefficient for large uninstalls, and we could make it better by doing things like passing
+ // a SQL fragment through so that the listeners could use subselects. But by using a single,
+ // simple event API we lighten the load on module developers.
+ foreach (ORM::factory("item")
+ ->join("comments", "items.id", "comments.item_id")
+ ->find_all() as $item) {
+ module::event("item_related_update", $item);
+ }
$db->query("DROP TABLE IF EXISTS {comments};");
}
}
diff --git a/modules/comment/helpers/comment_rss.php b/modules/comment/helpers/comment_rss.php
index d0f15010..4151dcd0 100644
--- a/modules/comment/helpers/comment_rss.php
+++ b/modules/comment/helpers/comment_rss.php
@@ -34,41 +34,36 @@ class comment_rss_Core {
}
$comments = ORM::factory("comment")
- ->where("state", "published")
- ->orderby("created", "DESC");
- $all_comments = ORM::factory("comment")
+ ->viewable()
->where("state", "published")
->orderby("created", "DESC");
if ($feed_id == "item") {
$comments->where("item_id", $id);
- $all_comments->where("item_id", $id);
}
- if (!empty($comments)) {
- $feed->view = "comment.mrss";
- $comments = $comments->find_all($limit, $offset);
- $feed->children = array();
- foreach ($comments as $comment) {
- $item = $comment->item();
- $feed->children[] = new ArrayObject(
- array("pub_date" => date("D, d M Y H:i:s T", $comment->created),
- "text" => nl2br(SafeString::purify($comment->text)),
- "thumb_url" => $item->thumb_url(),
- "thumb_height" => $item->thumb_height,
- "thumb_width" => $item->thumb_width,
- "item_uri" => url::abs_site("{$item->type}s/$item->id"),
- "title" => SafeString::purify($item->title),
- "author" => SafeString::of($comment->author_name())),
- ArrayObject::ARRAY_AS_PROPS);
- }
+ $comments = $comments->find_all($limit, $offset);
+ $feed->view = "comment.mrss";
+ $feed->children = array();
+ foreach ($comments as $comment) {
+ $item = $comment->item();
+ $feed->children[] = new ArrayObject(
+ array("pub_date" => date("D, d M Y H:i:s T", $comment->created),
+ "text" => nl2br(SafeString::purify($comment->text)),
+ "thumb_url" => $item->thumb_url(),
+ "thumb_height" => $item->thumb_height,
+ "thumb_width" => $item->thumb_width,
+ "item_uri" => url::abs_site("{$item->type}s/$item->id"),
+ "title" => SafeString::purify($item->title),
+ "author" => SafeString::of($comment->author_name())),
+ ArrayObject::ARRAY_AS_PROPS);
+ }
- $feed->max_pages = ceil($all_comments->find_all()->count() / $limit);
- $feed->title = htmlspecialchars(t("Recent Comments"));
- $feed->uri = url::abs_site("albums/" . (empty($id) ? "1" : $id));
- $feed->description = t("Recent Comments");
+ $feed->max_pages = ceil($comments->count_all() / $limit);
+ $feed->title = htmlspecialchars(t("Recent Comments"));
+ $feed->uri = url::abs_site("albums/" . (empty($id) ? "1" : $id));
+ $feed->description = t("Recent Comments");
- return $feed;
- }
+ return $feed;
}
-} \ No newline at end of file
+}
diff --git a/modules/comment/helpers/comment_theme.php b/modules/comment/helpers/comment_theme.php
index b807e2cf..38a00b5c 100644
--- a/modules/comment/helpers/comment_theme.php
+++ b/modules/comment/helpers/comment_theme.php
@@ -26,7 +26,6 @@ class comment_theme_Core {
static function photo_bottom($theme) {
$block = new Block;
$block->css_id = "gComments";
- $block->anchor = t("comments");
$block->title = t("Comments");
$view = new View("comments.html");
@@ -37,7 +36,6 @@ class comment_theme_Core {
->find_all();
$block->content = $view;
- $block->content .= comment::get_add_form($theme->item())->render("form.html");
return $block;
}
} \ No newline at end of file
diff --git a/modules/comment/js/comment.js b/modules/comment/js/comment.js
index 00fc6027..9fd63c1a 100644
--- a/modules/comment/js/comment.js
+++ b/modules/comment/js/comment.js
@@ -1,5 +1,13 @@
$("document").ready(function() {
- ajaxify_comment_form();
+ $("#gAddCommentButton").click(function(event) {
+ event.preventDefault();
+ $.get($(this).attr("href"),
+ {},
+ function(data) {
+ $("#gCommentDetail").append(data);
+ ajaxify_comment_form();
+ });
+ });
});
function ajaxify_comment_form() {
diff --git a/modules/comment/models/comment.php b/modules/comment/models/comment.php
index 83d0888a..de9b0cd6 100644
--- a/modules/comment/models/comment.php
+++ b/modules/comment/models/comment.php
@@ -80,4 +80,14 @@ class Comment_Model extends ORM {
return $this;
}
+
+ /**
+ * Add a set of restrictions to any following queries to restrict access only to items
+ * viewable by the active user.
+ * @chainable
+ */
+ public function viewable() {
+ $this->join("items", "items.id", "comments.item_id");
+ return item::viewable($this);
+ }
}
diff --git a/modules/comment/tests/Comment_Model_Test.php b/modules/comment/tests/Comment_Model_Test.php
new file mode 100644
index 00000000..f4c68b15
--- /dev/null
+++ b/modules/comment/tests/Comment_Model_Test.php
@@ -0,0 +1,40 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Comment_Model_Test extends Unit_Test_Case {
+
+ public function cant_view_comments_for_unviewable_items_test() {
+ $root = ORM::factory("item", 1);
+ $album = album::create($root, rand(), rand(), rand());
+ $comment = comment::create($album, user::guest(), "text", "name", "email", "url");
+ user::set_active(user::guest());
+
+ // We can see the comment when permissions are granted on the album
+ access::allow(group::everybody(), "view", $album);
+ $this->assert_equal(
+ 1,
+ ORM::factory("comment")->viewable()->where("comments.id", $comment->id)->count_all());
+
+ // We can't see the comment when permissions are denied on the album
+ access::deny(group::everybody(), "view", $album);
+ $this->assert_equal(
+ 0,
+ ORM::factory("comment")->viewable()->where("comments.id", $comment->id)->count_all());
+ }
+}
diff --git a/modules/comment/views/admin_comments.html.php b/modules/comment/views/admin_comments.html.php
index b27e3166..8b0b4c29 100644
--- a/modules/comment/views/admin_comments.html.php
+++ b/modules/comment/views/admin_comments.html.php
@@ -103,7 +103,7 @@
</th>
</tr>
<? foreach ($comments as $i => $comment): ?>
- <tr id="gComment-<?= $comment->id ?>" class="<?= ($i % 2 == 0) ? "gEvenRow" : "gOddRow" ?>">
+ <tr id="gComment-<?= $comment->id ?>" class="<?= ($i % 2 == 0) ? "gOddRow" : "gEvenRow" ?>">
<td>
<a href="#">
<img src="<?= $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>"
diff --git a/modules/comment/views/comments.html.php b/modules/comment/views/comments.html.php
index 7941b7da..9eac0502 100644
--- a/modules/comment/views/comments.html.php
+++ b/modules/comment/views/comments.html.php
@@ -1,11 +1,17 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
+ <a href="<?= url::site("form/add/comments/{$item->id})") ?>" id="gAddCommentButton"
+ class="gButtonLink ui-corner-all ui-icon-left ui-state-default right">
+ <span class="ui-icon ui-icon-comment"></span>
+ <?= t("Add a comment") ?>
+</a>
+<div id="gCommentDetail">
<? if (!$comments->count()): ?>
<p id="gNoCommentsYet">
<?= t("No comments yet. Be the first to <a %attrs>comment</a>!",
array("attrs" => "href=\"#add_comment_form\" class=\"showCommentForm\"")) ?>
</p>
<? endif ?>
-<ul id="gComments">
+<ul>
<? foreach ($comments as $comment): ?>
<li id="gComment-<?= $comment->id ?>">
<p class="gAuthor">
@@ -26,4 +32,4 @@
</li>
<? endforeach ?>
</ul>
-<a name="add_comment_form"></a>
+</div>
diff --git a/modules/digibug/helpers/digibug_event.php b/modules/digibug/helpers/digibug_event.php
index c4f9e560..d2830b80 100644
--- a/modules/digibug/helpers/digibug_event.php
+++ b/modules/digibug/helpers/digibug_event.php
@@ -28,23 +28,23 @@ class digibug_event_Core {
static function photo_menu($menu, $theme) {
$item = $theme->item();
- $menu->append(
- Menu::factory("link")
- ->id("digibug")
- ->label(t("Print with Digibug"))
- ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
- ->css_id("gDigibugLink"));
+ $menu->append(Menu::factory("link")
+ ->id("digibug")
+ ->label(t("Print with Digibug"))
+ ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
+ ->css_id("gDigibugLink")
+ ->css_class("ui-icon-print"));
}
- static function thumb_menu($menu, $theme, $item) {
+ static function context_menu($menu, $theme, $item) {
if ($item->type == "photo") {
$menu->get("options_menu")
- ->append(
- Menu::factory("link")
- ->id("digibug")
- ->label(t("Print with Digibug"))
- ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
- ->css_id("gDigibugLink"));
+ ->append(Menu::factory("link")
+ ->id("digibug")
+ ->label(t("Print with Digibug"))
+ ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
+ ->css_id("gDigibugLink")
+ ->css_class("ui-icon-print"));
}
}
}
diff --git a/modules/digibug/helpers/digibug_installer.php b/modules/digibug/helpers/digibug_installer.php
index 1cd78b44..7e8145d2 100644
--- a/modules/digibug/helpers/digibug_installer.php
+++ b/modules/digibug/helpers/digibug_installer.php
@@ -26,7 +26,7 @@ class digibug_installer {
`request_date` TIMESTAMP NOT NULL DEFAULT current_timestamp,
`item_id` int(9) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_var("digibug", "company_id", "3153");
module::set_var("digibug", "event_id", "8491");
diff --git a/modules/exif/helpers/exif_installer.php b/modules/exif/helpers/exif_installer.php
index 0233f2bb..66226061 100644
--- a/modules/exif/helpers/exif_installer.php
+++ b/modules/exif/helpers/exif_installer.php
@@ -28,7 +28,7 @@ class exif_installer {
`dirty` BOOLEAN default 1,
PRIMARY KEY (`id`),
KEY(`item_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("exif", 1);
}
diff --git a/modules/g2_import/helpers/g2_import_installer.php b/modules/g2_import/helpers/g2_import_installer.php
index 0f87da6c..feacb518 100644
--- a/modules/g2_import/helpers/g2_import_installer.php
+++ b/modules/g2_import/helpers/g2_import_installer.php
@@ -26,7 +26,7 @@ class g2_import_installer {
`g3_id` int(9) NOT NULL,
PRIMARY KEY (`id`),
KEY (`g2_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("g2_import", 1);
mkdir(VARPATH . "modules/g2_import");
diff --git a/modules/gallery/controllers/admin_graphics.php b/modules/gallery/controllers/admin_graphics.php
index 72f8d8e1..c59dd38e 100644
--- a/modules/gallery/controllers/admin_graphics.php
+++ b/modules/gallery/controllers/admin_graphics.php
@@ -21,41 +21,24 @@ class Admin_Graphics_Controller extends Admin_Controller {
public function index() {
$view = new Admin_View("admin.html");
$view->content = new View("admin_graphics.html");
- $view->content->available = "";
-
- $tk = new ArrayObject(graphics::detect_toolkits(), ArrayObject::ARRAY_AS_PROPS);
- $active = module::get_var("gallery", "graphics_toolkit", "none");
- foreach (array("gd", "imagemagick", "graphicsmagick", "none") as $id) {
- if ($id == $active) {
- $view->content->active = new View("admin_graphics_$id.html");
- $view->content->active->tk = $tk;
- $view->content->active->is_active = true;
- } else if ($id != "none") {
- $v = new View("admin_graphics_$id.html");
- $v->tk = $tk;
- $v->is_active = false;
- $view->content->available .= $v;
- }
- }
-
+ $view->content->tk = graphics::detect_toolkits();
+ $view->content->active = module::get_var("gallery", "graphics_toolkit", "none");
print $view;
}
- public function choose($toolkit) {
+ public function choose($toolkit_id) {
access::verify_csrf();
- if ($toolkit != module::get_var("gallery", "graphics_toolkit")) {
- module::set_var("gallery", "graphics_toolkit", $toolkit);
-
- $toolkit_info = graphics::detect_toolkits();
- if ($toolkit == "graphicsmagick" || $toolkit == "imagemagick") {
- module::set_var("gallery", "graphics_toolkit_path", $toolkit_info[$toolkit]);
- }
+ if ($toolkit_id != module::get_var("gallery", "graphics_toolkit")) {
+ $tk = graphics::detect_toolkits();
+ module::set_var("gallery", "graphics_toolkit", $toolkit_id);
+ module::set_var("gallery", "graphics_toolkit_path", $tk->$toolkit_id->dir);
site_status::clear("missing_graphics_toolkit");
- message::success(t("Updated Graphics Toolkit"));
- log::success("graphics", t("Changed graphics toolkit to: %toolkit",
- array("toolkit" => $toolkit)));
+
+ $msg = t("Changed graphics toolkit to: %toolkit", array("toolkit" => $tk->$toolkit_id->name));
+ message::success($msg);
+ log::success("graphics", $msg);
}
url::redirect("admin/graphics");
diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php
index ae90ad07..6dc242c6 100644
--- a/modules/gallery/controllers/admin_languages.php
+++ b/modules/gallery/controllers/admin_languages.php
@@ -21,7 +21,10 @@ class Admin_Languages_Controller extends Admin_Controller {
public function index($share_translations_form=null) {
$v = new Admin_View("admin.html");
$v->content = new View("admin_languages.html");
- $v->content->settings_form = $this->_languages_form();
+ $v->content->available_locales = locales::available();
+ $v->content->installed_locales = locales::installed();
+ $v->content->default_locale = module::get_var("gallery", "default_locale");
+
if (empty($share_translations_form)) {
$share_translations_form = $this->_share_translations_form();
}
@@ -32,14 +35,21 @@ class Admin_Languages_Controller extends Admin_Controller {
public function save() {
access::verify_csrf();
-
- $form = $this->_languages_form();
- if ($form->validate()) {
- module::set_var("gallery", "default_locale", $form->choose_language->locale->value);
- locales::update_installed($form->choose_language->installed_locales->value);
- message::success(t("Settings saved"));
- }
- url::redirect("admin/languages");
+
+ locales::update_installed($this->input->post("installed_locales"));
+
+ $installed_locales = array_keys(locales::installed());
+ $new_default_locale = $this->input->post("default_locale");
+ if (!in_array($new_default_locale, $installed_locales)) {
+ if (!empty($installed_locales)) {
+ $new_default_locale = $installed_locales[0];
+ } else {
+ $new_default_locale = "en_US";
+ }
+ }
+ module::set_var("gallery", "default_locale", $new_default_locale);
+
+ print json_encode(array("result" => "success"));
}
public function share() {
@@ -88,30 +98,6 @@ class Admin_Languages_Controller extends Admin_Controller {
}
}
- private function _languages_form() {
- $all_locales = locales::available();
- $installed_locales = locales::installed();
- $form = new Forge("admin/languages/save", "", "post", array("id" => "gLanguageSettingsForm"));
- $group = $form->group("choose_language")
- ->label(t("Language settings"));
- $group->dropdown("locale")
- ->options($installed_locales)
- ->selected(module::get_var("gallery", "default_locale"))
- ->label(t("Default language"))
- ->rules('required');
-
- $installation_options = array();
- foreach ($all_locales as $code => $display_name) {
- $installation_options[$code] = array($display_name, isset($installed_locales->$code));
- }
- $group->checklist("installed_locales")
- ->label(t("Installed Languages"))
- ->options($installation_options)
- ->rules("required");
- $group->submit("save")->value(t("Save settings"));
- return $form;
- }
-
private function _outgoing_translations_count() {
return ORM::factory("outgoing_translation")->count_all();
}
diff --git a/modules/gallery/controllers/combined.php b/modules/gallery/controllers/combined.php
index 9a790fdf..c1f42bfe 100644
--- a/modules/gallery/controllers/combined.php
+++ b/modules/gallery/controllers/combined.php
@@ -42,22 +42,23 @@ class Combined_Controller extends Controller {
private function _emit($type, $key) {
$input = Input::instance();
+ // We don't need to save the session for this request
+ Session::abort_save();
+
// Our data is immutable, so if they already have a copy then it needs no updating.
if ($input->server("HTTP_IF_MODIFIED_SINCE")) {
header('HTTP/1.0 304 Not Modified');
header("Expires: Tue, 19 Jan 2038 00:00:00 GMT");
header("Cache-Control: max-age=2678400");
header('Pragma: public');
- return;
+ Kohana::close_buffers(false);
+ return "";
}
if (empty($key)) {
Kohana::show_404();
}
- // We don't need to save the session for this request
- Session::abort_save();
-
$cache = Cache::instance();
$use_gzip = function_exists("gzencode") &&
stripos($input->server("HTTP_ACCEPT_ENCODING"), "gzip") !== false &&
diff --git a/modules/gallery/controllers/file_proxy.php b/modules/gallery/controllers/file_proxy.php
index a85f0a85..8cb90c50 100644
--- a/modules/gallery/controllers/file_proxy.php
+++ b/modules/gallery/controllers/file_proxy.php
@@ -119,7 +119,7 @@ class File_Proxy_Controller extends Controller {
if (in_array($item->mime_type, array("video/x-flv", "video/mp4"))) {
header("Content-type: image/jpeg");
} else {
- print("Content-Type: $item->mime_type");
+ header("Content-Type: $item->mime_type");
}
Kohana::close_buffers(false);
diff --git a/modules/gallery/controllers/l10n_client.php b/modules/gallery/controllers/l10n_client.php
index 831c79c1..0775791e 100644
--- a/modules/gallery/controllers/l10n_client.php
+++ b/modules/gallery/controllers/l10n_client.php
@@ -90,10 +90,15 @@ class L10n_Client_Controller extends Controller {
}
$session = Session::instance();
- $session->set("l10n_mode",
- !$session->get("l10n_mode", false));
-
- url::redirect("albums/1");
+ $l10n_mode = $session->get("l10n_mode", false);
+ $session->set("l10n_mode", !$l10n_mode);
+
+ $redirect_url = "admin/languages";
+ if (!$l10n_mode) {
+ $redirect_url .= "#l10n-client";
+ }
+
+ url::redirect($redirect_url);
}
private static function _l10n_client_search_form() {
diff --git a/modules/gallery/controllers/packager.php b/modules/gallery/controllers/packager.php
index 7b4d68f6..fbb1d07d 100644
--- a/modules/gallery/controllers/packager.php
+++ b/modules/gallery/controllers/packager.php
@@ -123,6 +123,10 @@ class Packager_Controller extends Controller {
// Normalize dates
$line = preg_replace("/,$root_created_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
$line = preg_replace("/,$root_updated_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
+
+ // Remove ENGINE= specifications
+ $line = preg_replace("/ENGINE=\S+ /", "", $line);
+
$buf .= $line;
}
$fd = fopen($sql_file, "wb");
diff --git a/modules/gallery/controllers/quick.php b/modules/gallery/controllers/quick.php
index 98a5bf9f..8fddb563 100644
--- a/modules/gallery/controllers/quick.php
+++ b/modules/gallery/controllers/quick.php
@@ -18,20 +18,6 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Quick_Controller extends Controller {
- public function pane($id) {
- $item = model_cache::get("item", $id);
- if (!access::can("view", $item) || !access::can("edit", $item)) {
- return "";
- }
-
- $view = new View("quick_pane.html");
- $page_type = Input::instance()->get("page_type");
- $view->button_list = gallery_quick::get_quick_buttons($item, $page_type);
- $view->item = $item;
- $view->page_type = $page_type;
- print $view;
- }
-
public function rotate($id, $dir) {
access::verify_csrf();
$item = model_cache::get("item", $id);
diff --git a/modules/gallery/controllers/simple_uploader.php b/modules/gallery/controllers/simple_uploader.php
index e7c0bd6f..156d18ac 100644
--- a/modules/gallery/controllers/simple_uploader.php
+++ b/modules/gallery/controllers/simple_uploader.php
@@ -71,7 +71,7 @@ class Simple_Uploader_Controller extends Controller {
unlink($temp_filename);
}
header("HTTP/1.1 500 Internal Server Error");
- print "ERROR:" . $e->getMessage();
+ print "ERROR: " . $e->getMessage();
return;
}
unlink($temp_filename);
diff --git a/modules/gallery/css/l10n_client.css b/modules/gallery/css/l10n_client.css
index 51cbc753..9c1b12d0 100644
--- a/modules/gallery/css/l10n_client.css
+++ b/modules/gallery/css/l10n_client.css
@@ -42,9 +42,17 @@
cursor:pointer;
display:block;
position:absolute; right:0em;
- padding: 0em .75em; height:2em; line-height:2em;
+ height:2em; line-height:2em;
text-transform:uppercase;
- text-align:center; background:#000;}
+ text-align:center; background:#000;
+}
+#l10n-client-toggler a {
+ font-size: 1em;
+ padding: .5em;
+}
+#l10n-client-toggler #gMinimizeL10n {
+ border-right: 1px solid #ffffff;
+}
/* Panel labels */
#l10n-client h2 {
diff --git a/modules/gallery/css/quick.css b/modules/gallery/css/quick.css
deleted file mode 100644
index f153d475..00000000
--- a/modules/gallery/css/quick.css
+++ /dev/null
@@ -1,52 +0,0 @@
-.gQuickPane {
- position: absolute;
- top: 0;
- left: 0;
- text-align: center;
- width: 100%;
- height: auto;
-}
-
-.gItem:hover {
- background-color: #cfdeff;
-}
-
-.gQuick {
- border: none !important;
- margin: 0 !important;
- padding: 0 !important;
-}
-
-.gQuickPane {
- background: #000;
- border-bottom: 1px solid #ccc;
- opacity: 0.9;
- position: absolute;
- top: 0;
- left: 0;
-}
-
-.gQuickPane a {
- cursor: pointer;
- float: left;
- margin: 4px;
-}
-
-.gQuickPaneOptions {
- background: #000;
- float: left;
- width: 100%;
-}
-
-.gQuickPaneOptions li a {
- display: block;
- float: none;
- width: auto;
- margin: 0;
- padding: .5em .5em .5em .8em;
- text-align: left;
-}
-
-.gQuickPaneOptions li a:hover {
- background-color: #4d4d4d;
-}
diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php
index 8a7c9951..d46f21ac 100644
--- a/modules/gallery/helpers/album.php
+++ b/modules/gallery/helpers/album.php
@@ -56,7 +56,7 @@ class album_Core {
$album->thumb_dirty = 1;
$album->resize_dirty = 1;
$album->rand_key = ((float)mt_rand()) / (float)mt_getrandmax();
- $album->sort_column = "weight";
+ $album->sort_column = "created";
$album->sort_order = "ASC";
while (ORM::factory("item")
@@ -116,13 +116,7 @@ class album_Core {
$sort_order->dropdown("column", array("id" => "gAlbumSortColumn"))
->label(t("Sort by"))
- ->options(array("weight" => t("Order Added"),
- "captured" => t("Capture Date"),
- "created" => t("Creation Date"),
- "title" => t("Title"),
- "updated" => t("Updated Date"),
- "view_count" => t("Number of views"),
- "rand_key" => t("Random")))
+ ->options(album::get_sort_order_options())
->selected($parent->sort_column);
$sort_order->dropdown("direction", array("id" => "gAlbumSortDirection"))
->label(t("Order"))
@@ -137,4 +131,17 @@ class album_Core {
$form->add_rules_from(ORM::factory("item"));
return $form;
}
+
+ /**
+ * Return a structured set of all the possible sort orders.
+ */
+ static function get_sort_order_options() {
+ return array("weight" => t("Manual"),
+ "captured" => t("Date captured"),
+ "created" => t("Date uploaded"),
+ "title" => t("Title"),
+ "updated" => t("Date modified"),
+ "view_count" => t("Number of views"),
+ "rand_key" => t("Random"));
+ }
}
diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php
index 476e9cbe..122227fc 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -82,9 +82,9 @@ class gallery_Core {
static function site_menu($menu, $theme) {
if ($theme->page_type != "login") {
$menu->append(Menu::factory("link")
- ->id("home")
- ->label(t("Home"))
- ->url(url::site("albums/1")));
+ ->id("home")
+ ->label(t("Home"))
+ ->url(url::site("albums/1")));
$item = $theme->item();
@@ -92,48 +92,47 @@ class gallery_Core {
$can_add = $item && access::can("add", $item);
if ($can_add) {
- $menu->append(Menu::factory("dialog")
- ->id("add_photos_item")
- ->label(t("Add photos"))
- ->url(url::site("simple_uploader/app/$item->id")));
+ $menu->append($add_menu = Menu::factory("submenu")
+ ->id("add_menu")
+ ->label(t("Add")));
+ $add_menu->append(Menu::factory("dialog")
+ ->id("add_photos_item")
+ ->label(t("Add photos"))
+ ->url(url::site("simple_uploader/app/$item->id")));
+ if ($item->is_album()) {
+ $add_menu->append(Menu::factory("dialog")
+ ->id("add_album_item")
+ ->label(t("Add an album"))
+ ->url(url::site("form/add/albums/$item->id?type=album")));
+ }
}
$menu->append($options_menu = Menu::factory("submenu")
- ->id("options_menu")
- ->label(t("Options")));
+ ->id("options_menu")
+ ->label(t("Photo options")));
if ($item && ($can_edit || $can_add)) {
if ($can_edit) {
- $options_menu
- ->append(Menu::factory("dialog")
- ->id("edit_item")
- ->label($item->is_album() ? t("Edit album") : t("Edit photo"))
- ->url(url::site("form/edit/{$item->type}s/$item->id")));
+ $options_menu->append(Menu::factory("dialog")
+ ->id("edit_item")
+ ->label($item->is_album() ? t("Edit album") : t("Edit photo"))
+ ->url(url::site("form/edit/{$item->type}s/$item->id")));
}
- // @todo Move album options menu to the album quick edit pane
if ($item->is_album()) {
- if ($can_add) {
- $options_menu
- ->append(Menu::factory("dialog")
- ->id("add_album")
- ->label(t("Add an album"))
- ->url(url::site("form/add/albums/$item->id?type=album")));
- }
-
+ $options_menu->label(t("Album options"));
if ($can_edit) {
- $options_menu
- ->append(Menu::factory("dialog")
- ->id("edit_permissions")
- ->label(t("Edit permissions"))
- ->url(url::site("permissions/browse/$item->id")));
+ $options_menu->append(Menu::factory("dialog")
+ ->id("edit_permissions")
+ ->label(t("Edit permissions"))
+ ->url(url::site("permissions/browse/$item->id")));
}
}
}
if (user::active()->admin) {
$menu->append($admin_menu = Menu::factory("submenu")
- ->id("admin_menu")
- ->label(t("Admin")));
+ ->id("admin_menu")
+ ->label(t("Admin")));
gallery::admin_menu($admin_menu, $theme);
module::event("admin_menu", $admin_menu, $theme);
}
@@ -160,12 +159,6 @@ class gallery_Core {
->label(t("Languages"))
->url(url::site("admin/languages")))
->append(Menu::factory("link")
- ->id("l10n_mode")
- ->label(Session::instance()->get("l10n_mode", false)
- ? t("Stop translating") : t("Start translating"))
- ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" .
- access::csrf_token())))
- ->append(Menu::factory("link")
->id("advanced")
->label(t("Advanced"))
->url(url::site("admin/advanced_settings"))))
@@ -196,4 +189,118 @@ class gallery_Core {
->url(url::site("admin/maintenance")));
return $menu;
}
+
+ static function context_menu($menu, $theme, $item, $thumb_css_selector) {
+ $menu->append($options_menu = Menu::factory("submenu")
+ ->id("options_menu")
+ ->label(t("Options"))
+ ->css_class("ui-icon-carat-1-n"));
+
+ if (access::can("edit", $item)) {
+ $page_type = $theme->page_type();
+ switch ($item->type) {
+ case "movie":
+ $edit_title = t("Edit this movie");
+ $delete_title = t("Delete this movie");
+ break;
+
+ case "album":
+ $edit_title = t("Edit this album");
+ $delete_title = t("Delete this album");
+ break;
+
+ default:
+ $edit_title = t("Edit this photo");
+ $delete_title = t("Delete this photo");
+ break;
+ }
+ $cover_title = t("Choose as the album cover");
+ $move_title = t("Move to another album");
+
+ $csrf = access::csrf_token();
+
+ $options_menu->append(Menu::factory("dialog")
+ ->id("edit")
+ ->label($edit_title)
+ ->css_class("ui-icon-pencil")
+ ->url(url::site("quick/form_edit/$item->id?page_type=$page_type")));
+
+
+ if ($item->is_photo() && graphics::can("rotate")) {
+ $options_menu
+ ->append(
+ Menu::factory("ajax_link")
+ ->id("rotate_ccw")
+ ->label(t("Rotate 90&deg; counter clockwise"))
+ ->css_class("ui-icon-rotate-ccw")
+ ->ajax_handler("function(data) { " .
+ "\$.gallery_replace_image(data, \$('$thumb_css_selector')) }")
+ ->url(url::site("quick/rotate/$item->id/ccw?csrf=$csrf&page_type=$page_type")))
+ ->append(
+ Menu::factory("ajax_link")
+ ->id("rotate_cw")
+ ->label(t("Rotate 90&deg; clockwise"))
+ ->css_class("ui-icon-rotate-cw")
+ ->ajax_handler("function(data) { " .
+ "\$.gallery_replace_image(data, \$('$thumb_css_selector')) }")
+ ->url(url::site("quick/rotate/$item->id/cw?csrf=$csrf&page_type=$page_type")));
+ }
+
+ // Don't move photos from the photo page; we don't yet have a good way of redirecting after
+ // move
+ if ($page_type == "album") {
+ $options_menu
+ ->append(Menu::factory("dialog")
+ ->id("move")
+ ->label($move_title)
+ ->css_class("ui-icon-folder-open")
+ ->url(url::site("move/browse/$item->id")));
+ }
+
+ $parent = $item->parent();
+ if (access::can("edit", $parent)) {
+ // We can't make this item the highlight if it's an album with no album cover, or if it's
+ // already the album cover.
+ if (($item->type == "album" && empty($item->album_cover_item_id)) ||
+ ($item->type == "album" && $parent->album_cover_item_id == $item->album_cover_item_id) ||
+ $parent->album_cover_item_id == $item->id) {
+ $disabledState = " ui-state-disabled";
+ } else {
+ $disabledState = " ";
+ }
+ $options_menu
+ ->append(Menu::factory("ajax_link")
+ ->id("make_album_cover")
+ ->label($cover_title)
+ ->css_class("ui-icon-star")
+ ->ajax_handler("function(data) { window.location.reload() }")
+ ->url(url::site("quick/make_album_cover/$item->id?csrf=$csrf")))
+ ->append(Menu::factory("dialog")
+ ->id("delete")
+ ->label($delete_title)
+ ->css_class("ui-icon-trash")
+ ->css_id("gQuickDelete")
+ ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&page_type=$page_type")));
+ }
+
+ if ($item->is_album()) {
+ $options_menu
+ ->append(Menu::factory("dialog")
+ ->id("add_item")
+ ->label(t("Add a photo"))
+ ->css_class("add_item")
+ ->url(url::site("simple_uploader/app/$item->id")))
+ ->append(Menu::factory("dialog")
+ ->id("add_album")
+ ->label(t("Add an album"))
+ ->css_class("add_album")
+ ->url(url::site("form/add/albums/$item->id?type=album")))
+ ->append(Menu::factory("dialog")
+ ->id("edit_permissions")
+ ->label(t("Edit permissions"))
+ ->css_class("permissions")
+ ->url(url::site("permissions/browse/$item->id")));
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index d12dad70..a212ef85 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -24,13 +24,13 @@ class gallery_installer {
`id` int(9) NOT NULL auto_increment,
`item_id` int(9),
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {access_intents} (
`id` int(9) NOT NULL auto_increment,
`item_id` int(9),
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {caches} (
`id` int(9) NOT NULL auto_increment,
@@ -40,7 +40,7 @@ class gallery_installer {
`cache` longblob,
PRIMARY KEY (`id`),
KEY (`tags`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {graphics_rules} (
`id` int(9) NOT NULL auto_increment,
@@ -51,7 +51,7 @@ class gallery_installer {
`priority` int(9) NOT NULL,
`target` varchar(32) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {incoming_translations} (
`id` int(9) NOT NULL auto_increment,
@@ -63,7 +63,7 @@ class gallery_installer {
PRIMARY KEY (`id`),
UNIQUE KEY(`key`, `locale`),
KEY `locale_key` (`locale`, `key`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {items} (
`id` int(9) NOT NULL auto_increment,
@@ -100,7 +100,7 @@ class gallery_installer {
KEY `type` (`type`),
KEY `random` (`rand_key`),
KEY `weight` (`weight` DESC))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {logs} (
`id` int(9) NOT NULL auto_increment,
@@ -113,7 +113,7 @@ class gallery_installer {
`url` varchar(255) default NULL,
`user_id` int(9) default 0,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {messages} (
`id` int(9) NOT NULL auto_increment,
@@ -122,7 +122,7 @@ class gallery_installer {
`value` varchar(255) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`key`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {modules} (
`id` int(9) NOT NULL auto_increment,
@@ -131,7 +131,7 @@ class gallery_installer {
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {outgoing_translations} (
`id` int(9) NOT NULL auto_increment,
@@ -143,7 +143,7 @@ class gallery_installer {
PRIMARY KEY (`id`),
UNIQUE KEY(`key`, `locale`),
KEY `locale_key` (`locale`, `key`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {permissions} (
`id` int(9) NOT NULL auto_increment,
@@ -151,14 +151,14 @@ class gallery_installer {
`name` varchar(64) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {sessions} (
`session_id` varchar(127) NOT NULL,
`data` text NOT NULL,
`last_activity` int(10) UNSIGNED NOT NULL,
PRIMARY KEY (`session_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {tasks} (
`id` int(9) NOT NULL auto_increment,
@@ -173,7 +173,7 @@ class gallery_installer {
`updated` int(9) default NULL,
PRIMARY KEY (`id`),
KEY (`owner_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {themes} (
`id` int(9) NOT NULL auto_increment,
@@ -181,7 +181,7 @@ class gallery_installer {
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {vars} (
`id` int(9) NOT NULL auto_increment,
@@ -190,7 +190,7 @@ class gallery_installer {
`value` text,
PRIMARY KEY (`id`),
UNIQUE KEY(`module_name`, `name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
foreach (array("albums", "logs", "modules", "resizes", "thumbs", "tmp", "uploads") as $dir) {
@mkdir(VARPATH . $dir);
@@ -284,7 +284,7 @@ class gallery_installer {
`cache` text,
PRIMARY KEY (`id`),
KEY (`tags`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("gallery", $version = 4);
}
diff --git a/modules/gallery/helpers/gallery_quick.php b/modules/gallery/helpers/gallery_quick.php
deleted file mode 100644
index 8a92890b..00000000
--- a/modules/gallery/helpers/gallery_quick.php
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 Bharat Mediratta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
- */
-class gallery_quick_Core {
- static function get_quick_buttons($item, $page_type) {
- $buttons = self::buttons($item, $page_type);
- foreach (module::active() as $module) {
- if ($module->name == "gallery") {
- continue;
- }
- $class_name = "{$module->name}_quick";
- if (method_exists($class_name, "buttons")) {
- $module_buttons = call_user_func(array($class_name, "buttons"), $item, $page_type);
- foreach (array("left", "center", "right", "additional") as $position) {
- if (!empty($module_buttons[$position])) {
- $buttons[$position] = array_merge($buttons[$position], $module_buttons[$position]);
- }
- }
- }
- }
-
- $sorted_buttons->main = array();
- foreach (array("left", "center", "right") as $position) {
- $sorted_buttons->main = array_merge($sorted_buttons->main, $buttons[$position]);
- }
-
- $sorted_buttons->additional = $buttons["additional"];
- $max_display = empty($sorted_buttons->additional) ? 6 : 5;
- if (count($sorted_buttons->main) >= $max_display) {
- $to_move = array_slice($sorted_buttons->main, 5);
- $sorted_buttons->additional = array_merge($to_move, $sorted_buttons->additional);
- for ($i = count($sorted_buttons->main); $i >= 5; $i--) {
- unset($sorted_buttons->main[$i]);
- }
- }
-
- return $sorted_buttons;
- }
-
- static function buttons($item, $page_type) {
- $elements = array("left" => array(), "center" => array(), "right" => array(),
- "additional" => array());
- switch ($item->type) {
- case "movie":
- $edit_title = t("Edit this movie");
- $move_title = t("Move this movie to another album");
- $cover_title = t("Choose this movie as the album cover");
- $delete_title = t("Delete this movie");
- break;
- case "album":
- $edit_title = t("Edit this album");
- $move_title = t("Move this album to another album");
- $cover_title = t("Choose this album as the album cover");
- $delete_title = t("Delete this album");
- break;
- default:
- $edit_title = t("Edit this photo");
- $move_title = t("Move this photo to another album");
- $cover_title = t("Choose this photo as the album cover");
- $delete_title = t("Delete this photo");
- break;
- }
-
- $csrf = access::csrf_token();
- $elements["left"][] = (object)array(
- "title" => $edit_title,
- "class" => "gDialogLink gButtonLink",
- "icon" => "ui-icon-pencil",
- "href" => url::site("quick/form_edit/$item->id?page_type=$page_type"));
-
- if ($item->is_photo() && graphics::can("rotate")) {
- $elements["left"][] =
- (object)array(
- "title" => t("Rotate 90 degrees counter clockwise"),
- "class" => "gButtonLink",
- "icon" => "ui-icon-rotate-ccw",
- "href" => url::site("quick/rotate/$item->id/ccw?csrf=$csrf&page_type=$page_type"));
- $elements["left"][] =
- (object)array(
- "title" => t("Rotate 90 degrees clockwise"),
- "class" => "gButtonLink",
- "icon" => "ui-icon-rotate-cw",
- "href" => url::site("quick/rotate/$item->id/cw?csrf=$csrf&page_type=$page_type"));
- }
-
- // Don't move photos from the photo page; we don't yet have a good way of redirecting after move
- if ($page_type == "album") {
- $elements["left"][] = (object)array(
- "title" => $move_title,
- "class" => "gDialogLink gButtonLink",
- "icon" => "ui-icon-folder-open",
- "href" => url::site("move/browse/$item->id"));
- }
-
- $parent = $item->parent();
- if (access::can("edit", $parent)) {
- // We can't make this item the highlight if it's an album with no album cover, or if it's
- // already the album cover.
- if (($item->type == "album" && empty($item->album_cover_item_id)) ||
- ($item->type == "album" && $parent->album_cover_item_id == $item->album_cover_item_id) ||
- $parent->album_cover_item_id == $item->id) {
- $disabledState = " ui-state-disabled";
- } else {
- $disabledState = " ";
- }
- $elements["right"][] = (object)array(
- "title" => $cover_title,
- "class" => "gButtonLink$disabledState",
- "icon" => "ui-icon-star",
- "href" => url::site("quick/make_album_cover/$item->id?csrf=$csrf&page_type=$page_type"));
-
- $elements["right"][] = (object)array(
- "title" => $delete_title,
- "class" => "gDialogLink gButtonLink",
- "icon" => "ui-icon-trash",
- "id" => "gQuickDelete",
- "href" => url::site("quick/form_delete/$item->id?csrf=$csrf&page_type=$page_type"));
- }
-
- if ($item->is_album()) {
- $elements["additional"][] = (object)array(
- "title" => t("Add a photo"),
- "class" => "add_item gDialogLink",
- "href" => url::site("simple_uploader/app/$item->id"));
- $elements["additional"][] = (object)array(
- "title" => t("Add an album"),
- "class" => "add_album gDialogLink",
- "href" => url::site("form/add/albums/$item->id?type=album"));
- $elements["additional"][] = (object)array(
- "title" => t("Edit permissions"),
- "class" => "permissions gDialogLink",
- "href" => url::site("permissions/browse/$item->id"));
- }
- return $elements;
- }
-}
diff --git a/modules/gallery/helpers/gallery_rss.php b/modules/gallery/helpers/gallery_rss.php
index be555296..affb3101 100644
--- a/modules/gallery/helpers/gallery_rss.php
+++ b/modules/gallery/helpers/gallery_rss.php
@@ -50,8 +50,9 @@ class gallery_rss_Core {
$feed->children = $item
->viewable()
- ->descendants($limit, $offset, "photo");
- $feed->max_pages = ceil($item->viewable()->descendants_count("photo") / $limit);
+ ->descendants($limit, $offset, array("type" => "photo"));
+ $feed->max_pages = ceil(
+ $item->viewable()->descendants_count(array("type" => "photo")) / $limit);
$feed->title = SafeString::purify($item->title);
$feed->link = url::abs_site("albums/{$item->id}");
$feed->description = nl2br(SafeString::purify($item->description));
diff --git a/modules/gallery/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php
index d3751b80..69c5a091 100644
--- a/modules/gallery/helpers/gallery_theme.php
+++ b/modules/gallery/helpers/gallery_theme.php
@@ -24,11 +24,6 @@ class gallery_theme_Core {
if ($session->get("debug")) {
$theme->css("debug.css");
}
- if (($theme->page_type == "album" || $theme->page_type == "photo")
- && access::can("edit", $theme->item())) {
- $theme->css("quick.css");
- $theme->script("quick.js");
- }
if (module::is_active("rss")) {
if ($item = $theme->item()) {
@@ -51,33 +46,8 @@ class gallery_theme_Core {
return $buf;
}
- static function resize_top($theme, $item) {
- if (access::can("edit", $item)) {
- $edit_link = url::site("quick/pane/$item->id?page_type=photo");
- return "<div class=\"gQuick\" href=\"$edit_link\">";
- }
- }
-
- static function resize_bottom($theme, $item) {
- if (access::can("edit", $item)) {
- return "</div>";
- }
- }
-
- static function thumb_top($theme, $child) {
- if (access::can("edit", $child)) {
- $edit_link = url::site("quick/pane/$child->id?page_type=album");
- return "<div class=\"gQuick\" href=\"$edit_link\">";
- }
- }
-
- static function thumb_bottom($theme, $child) {
- if (access::can("edit", $child)) {
- return "</div>";
- }
- }
-
static function admin_head($theme) {
+ $theme->script("gallery.panel.js");
$session = Session::instance();
if ($session->get("debug")) {
$theme->css("debug.css");
diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php
index d506a982..7dc46eeb 100644
--- a/modules/gallery/helpers/graphics.php
+++ b/modules/gallery/helpers/graphics.php
@@ -339,15 +339,90 @@ class graphics_Core {
* GraphicsMagick we return the path to the directory containing the appropriate binaries.
*/
static function detect_toolkits() {
+ $toolkits = new stdClass();
+
+ // GD is special, it doesn't use exec()
$gd = function_exists("gd_info") ? gd_info() : array();
- $exec = function_exists("exec");
+ $toolkits->gd->name = "GD";
if (!isset($gd["GD Version"])) {
- $gd["GD Version"] = false;
+ $toolkits->gd->installed = false;
+ $toolkits->gd->error = t("GD is not installed");
+ } else {
+ $toolkits->gd->installed = true;
+ $toolkits->gd->version = $gd["GD Version"];
+ $toolkits->gd->rotate = function_exists("imagerotate");
+ $toolkits->gd->binary = "";
+ $toolkits->gd->dir = "";
+
+ if (!$toolkits->gd->rotate) {
+ $toolkits->gd->error =
+ t("You have GD version %version, but it lacks image rotation.",
+ array("version" => $gd["GD Version"]));
+ }
+ }
+
+ if (!function_exists("exec")) {
+ $toolkits->imagemagick->installed = false;
+ $toolkits->imagemagick->error = t("ImageMagick requires the <b>exec</b> function");
+
+ $toolkits->graphicsmagick->installed = false;
+ $toolkits->graphicsmagick->error = t("GraphicsMagick requires the <b>exec</b> function");
+ } else {
+ putenv("PATH=" . getenv("PATH") . ":/usr/local/bin:/opt/local/bin:/opt/bin");
+
+ // @todo: consider refactoring the two segments below into a loop since they are so
+ // similar.
+
+ // ImageMagick
+ $path = exec("which convert");
+ $toolkits->imagemagick->name = "ImageMagick";
+ if ($path) {
+ if (@is_file($path)) {
+ preg_match('/Version: \S+ (\S+)/', `convert -v`, $matches);
+ $version = $matches[1];
+
+ $toolkits->imagemagick->installed = true;
+ $toolkits->imagemagick->version = $version;
+ $toolkits->imagemagick->binary = $path;
+ $toolkits->imagemagick->dir = dirname($path);
+ $toolkits->imagemagick->rotate = true;
+ } else {
+ $toolkits->imagemagick->installed = false;
+ $toolkits->imagemagick->error =
+ t("ImageMagick is installed, but PHP's open_basedir restriction " .
+ "prevents Gallery from using it.");
+ }
+ } else {
+ $toolkits->imagemagick->installed = false;
+ $toolkits->imagemagick->error = t("We could not locate ImageMagick on your system.");
+ }
+
+ // GraphicsMagick
+ $path = exec("which gm");
+ $toolkits->graphicsmagick->name = "GraphicsMagick";
+ if ($path) {
+ if (@is_file($path)) {
+ preg_match('/\S+ (\S+)/', `gm version`, $matches);
+ $version = $matches[1];
+
+ $toolkits->graphicsmagick->installed = true;
+ $toolkits->graphicsmagick->version = $version;
+ $toolkits->graphicsmagick->binary = $path;
+ $toolkits->graphicsmagick->dir = dirname($path);
+ $toolkits->graphicsmagick->rotate = true;
+ } else {
+ $toolkits->graphicsmagick->installed = false;
+ $toolkits->graphicsmagick->error =
+ t("GraphicsMagick is installed, but PHP's open_basedir restriction " .
+ "prevents Gallery from using it.");
+ }
+ } else {
+ $toolkits->graphicsmagick->installed = false;
+ $toolkits->graphicsmagick->error = t("We could not locate GraphicsMagick on your system.");
+ }
}
- putenv("PATH=" . getenv("PATH") . ":/usr/local/bin:/opt/local/bin:/opt/bin");
- return array("gd" => $gd,
- "imagemagick" => $exec ? dirname(exec("which convert")) : false,
- "graphicsmagick" => $exec ? dirname(exec("which gm")) : false);
+
+ return $toolkits;
}
/**
@@ -357,12 +432,13 @@ class graphics_Core {
// Detect a graphics toolkit
$toolkits = graphics::detect_toolkits();
foreach (array("imagemagick", "graphicsmagick", "gd") as $tk) {
- if ($toolkits[$tk]) {
+ if ($toolkits->$tk->installed) {
module::set_var("gallery", "graphics_toolkit", $tk);
- module::set_var("gallery", "graphics_toolkit_path", $tk == "gd" ? "" : $toolkits[$tk]);
+ module::set_var("gallery", "graphics_toolkit_path", $toolkits->$tk->dir);
break;
}
}
+
if (!module::get_var("gallery", "graphics_toolkit")) {
site_status::warning(
t("Graphics toolkit missing! Please <a href=\"%url\">choose a toolkit</a>",
diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php
index 80c25862..8839861f 100644
--- a/modules/gallery/helpers/item.php
+++ b/modules/gallery/helpers/item.php
@@ -129,7 +129,7 @@ class item_Core {
if (Input::instance()->get("page_type") == "album") {
$page_type = "album";
} else {
- $page_type = "item";
+ $page_type = "photo";
}
$form = new Forge("quick/delete/$item->id?page_type=$page_type", "", "post", array("id" => "gConfirmDelete"));
$form->hidden("_method")->value("put");
@@ -137,4 +137,55 @@ class item_Core {
$group->submit("")->value(t("Delete"));
return $form;
}
+
+ /**
+ * Get the next weight value
+ */
+ static function get_max_weight() {
+ // Guard against an empty result when we create the first item. It's unfortunate that we
+ // have to check this every time.
+ // @todo: figure out a better way to bootstrap the weight.
+ $result = Database::instance()
+ ->select("weight")->from("items")
+ ->orderby("weight", "desc")->limit(1)
+ ->get()->current();
+ return ($result ? $result->weight : 0) + 1;
+ }
+
+ /**
+ * Add a set of restrictions to any following queries to restrict access only to items
+ * viewable by the active user.
+ * @chainable
+ */
+ static function viewable($model) {
+ $view_restrictions = array();
+ if (!user::active()->admin) {
+ foreach (user::group_ids() as $id) {
+ // Separate the first restriction from the rest to make it easier for us to formulate
+ // our where clause below
+ if (empty($view_restrictions)) {
+ $view_restrictions[0] = "items.view_$id";
+ } else {
+ $view_restrictions[1]["items.view_$id"] = access::ALLOW;
+ }
+ }
+ }
+ switch (count($view_restrictions)) {
+ case 0:
+ break;
+
+ case 1:
+ $model->where($view_restrictions[0], access::ALLOW);
+ break;
+
+ default:
+ $model->open_paren();
+ $model->where($view_restrictions[0], access::ALLOW);
+ $model->orwhere($view_restrictions[1]);
+ $model->close_paren();
+ break;
+ }
+
+ return $model;
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php
index 0d483206..03d538a9 100644
--- a/modules/gallery/helpers/module.php
+++ b/modules/gallery/helpers/module.php
@@ -274,11 +274,9 @@ class module_Core {
array_shift($args);
$function = str_replace(".", "_", $name);
- foreach (self::$modules as $module) {
- if (!$module->active) {
- continue;
- }
-
+ // @todo: consider calling gallery_event first, since for things menus we need it to do some
+ // setup
+ foreach (self::$active as $module) {
$class = "{$module->name}_event";
if (method_exists($class, $function)) {
call_user_func_array(array($class, $function), $args);
diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php
index 5cf37de1..96a66d29 100644
--- a/modules/gallery/helpers/photo.php
+++ b/modules/gallery/helpers/photo.php
@@ -109,8 +109,12 @@ class photo_Core {
// there's only one save() happening here.
module::event("item_created", $photo);
- // Build our thumbnail/resizes
- graphics::generate($photo);
+ // Build our thumbnail/resizes. If we fail to build thumbnail/resize we assume that the image
+ // is bad in some way and discard it.
+ if (!graphics::generate($photo)) {
+ $photo->delete();
+ throw new Exception("@todo BAD_IMAGE_FILE");
+ }
// If the parent has no cover item, make this it.
if (access::can("edit", $parent) && $parent->album_cover_item_id == null) {
diff --git a/modules/gallery/helpers/task.php b/modules/gallery/helpers/task.php
index 352fe522..9fa04305 100644
--- a/modules/gallery/helpers/task.php
+++ b/modules/gallery/helpers/task.php
@@ -84,6 +84,7 @@ class task_Core {
}
$task->save();
} catch (Exception $e) {
+ Kohana::log("error", $e->__toString());
$task->log($e->__toString());
$task->state = "error";
$task->done = true;
diff --git a/modules/gallery/js/l10n_client.js b/modules/gallery/js/l10n_client.js
index f5be5058..80fe166b 100644
--- a/modules/gallery/js/l10n_client.js
+++ b/modules/gallery/js/l10n_client.js
@@ -58,7 +58,8 @@ jQuery.extend(Gallery, {
case 1:
$('#l10n-client-string-select, #l10n-client-string-editor, #l10n-client .labels .label').show();
$('#l10n-client').height('22em').removeClass('hidden');
- $('#l10n-client-toggler').text(MSG_CLOSE_X);
+ //$('#l10n-client').slideUp();
+ $('#gMinimizeL10n').text("_");
/*
* This CSS clashes with Gallery's CSS, probably due to
* YUI's grid / floats.
@@ -72,7 +73,7 @@ jQuery.extend(Gallery, {
$('#l10n-client-string-select, #l10n-client-string-editor, #l10n-client .labels .label').hide();
$('#l10n-client').height('2em').addClass('hidden');
// TODO: Localize this message
- $('#l10n-client-toggler').text(MSG_TRANSLATE_TEXT);
+ $('#gMinimizeL10n').text(MSG_TRANSLATE_TEXT);
/*
if(!$.browser.msie) {
$('body').css('border-bottom', '0px');
@@ -197,7 +198,7 @@ Gallery.behaviors.l10nClient = function(context) {
});
// When l10n_client window is clicked, toggle based on current state.
- $('#l10n-client-toggler').click(function() {
+ $('#gMinimizeL10n').click(function() {
if($('#l10n-client').is('.hidden')) {
Gallery.l10nClient.toggle(1);
} else {
diff --git a/modules/gallery/js/quick.js b/modules/gallery/js/quick.js
deleted file mode 100644
index fda6470f..00000000
--- a/modules/gallery/js/quick.js
+++ /dev/null
@@ -1,78 +0,0 @@
-$(document).ready(function() {
- if ($("#gAlbumGrid").length) {
- // @todo Add quick edit pane for album (meta, move, permissions, delete)
- $(".gItem").hover(show_quick, function() {});
- }
- if ($("#gPhoto").length) {
- $("#gPhoto").hover(show_quick, function() {});
- }
-});
-
-var show_quick = function() {
- var cont = $(this);
- var quick = $(this).find(".gQuick");
- var img = cont.find(".gThumbnail,.gResize");
- cont.find(".gQuickPane").remove();
- cont.append("<div class=\"gQuickPane\"></div>");
- cont.find(".gQuickPane").hide();
- cont.hover(function() {}, function() { cont.find(".gQuickPane").remove(); });
- $.get(
- quick.attr("href"),
- {},
- function(data, textStatus) {
- cont.find(".gQuickPane").html(data).slideDown("fast");
- $(".ui-state-default").hover(
- function() {
- $(this).addClass("ui-state-hover");
- },
- function() {
- $(this).removeClass("ui-state-hover");
- }
- );
- cont.find(".gQuickPane a:not(.options)").click(function(e) {
- e.preventDefault();
- quick_do(cont, $(this), img);
- });
- cont.find(".gQuickPane a.options").click(function(e) {
- e.preventDefault();
- cont.find(".gQuickPaneOptions").slideToggle("fast");
- });
- }
- );
-};
-
-var quick_do = function(cont, pane, img) {
- if (pane.hasClass("ui-state-disabled")) {
- return false;
- }
- if (pane.hasClass("gDialogLink")) {
- openDialog(pane);
- } else {
- img.css("opacity", "0.1");
- cont.addClass("gLoadingLarge");
- $.ajax({
- type: "GET",
- url: pane.attr("href"),
- dataType: "json",
- success: function(data) {
- img.css("opacity", "1");
- cont.removeClass("gLoadingLarge");
- if (data.src) {
- img.attr("width", data.width);
- img.attr("height", data.height);
- img.attr("src", data.src);
- if (data.height > data.width) {
- img.css("margin-top", -32);
- } else {
- img.css("margin-top", 0);
- }
- } else if (data.location) {
- window.location = data.location;
- } else if (data.reload) {
- window.location.reload();
- }
- }
- });
- }
- return false;
-};
diff --git a/modules/gallery/libraries/I18n.php b/modules/gallery/libraries/I18n.php
index a53d5ae9..c3336052 100644
--- a/modules/gallery/libraries/I18n.php
+++ b/modules/gallery/libraries/I18n.php
@@ -77,7 +77,12 @@ class I18n_Core {
// TODO: See G2 for better fallack code.
$locale_prefs = array($locale);
$locale_prefs[] = 'en_US';
- setlocale(LC_ALL, $locale_prefs);
+ $new_locale = setlocale(LC_ALL, $locale_prefs);
+ if (is_string($new_locale) && strpos($new_locale, 'tr') === 0) {
+ // Make PHP 5 work with Turkish (the localization results are mixed though).
+ // Hack for http://bugs.php.net/18556
+ setlocale(LC_CTYPE, 'C');
+ }
}
return $this->_config['default_locale'];
}
@@ -184,7 +189,7 @@ class I18n_Core {
static function is_plural_message($message) {
return is_array($message);
}
-
+
private function interpolate($locale, $string, $key_values) {
// TODO: Handle locale specific number formatting.
diff --git a/modules/gallery/libraries/Menu.php b/modules/gallery/libraries/Menu.php
index a39b59a5..07b2b2b8 100644
--- a/modules/gallery/libraries/Menu.php
+++ b/modules/gallery/libraries/Menu.php
@@ -91,12 +91,43 @@ class Menu_Element_Link extends Menu_Element {
} else {
$css_class = "";
}
- return "<li><a$css_id class=\"gMenuElement$css_class\" href=\"$this->url\" " .
+ return "<li><a$css_id class=\"gMenuLink $css_class\" href=\"$this->url\" " .
"title=\"$this->label\">$this->label</a></li>";
}
}
/**
+ * Menu element that provides an AJAX link.
+ */
+class Menu_Element_Ajax_Link extends Menu_Element {
+ public $ajax_handler;
+
+ /**
+ * Set the AJAX handler
+ * @chainable
+ */
+ public function ajax_handler($ajax_handler) {
+ $this->ajax_handler = $ajax_handler;
+ return $this;
+ }
+
+ public function __toString() {
+ if (isset($this->css_id) && !empty($this->css_id)) {
+ $css_id = " id=\"$this->css_id\"";
+ } else {
+ $css_id = "";
+ }
+ if (isset($this->css_class) && !empty($this->css_class)) {
+ $css_class = " $this->css_class";
+ } else {
+ $css_class = "";
+ }
+ return "<li><a$css_id class=\"gAjaxLink $css_class\" href=\"$this->url\" " .
+ "title=\"$this->label\" ajax_handler=\"$this->ajax_handler\">$this->label</a></li>";
+ }
+}
+
+/**
* Menu element that provides a pop-up dialog
*/
class Menu_Element_Dialog extends Menu_Element {
@@ -111,7 +142,7 @@ class Menu_Element_Dialog extends Menu_Element {
} else {
$css_class = "";
}
- return "<li><a$css_id class=\"gMenuLink$css_class\" href=\"$this->url\" " .
+ return "<li><a$css_id class=\"gDialogLink $css_class\" href=\"$this->url\" " .
"title=\"$this->label\">$this->label</a></li>";
}
}
@@ -132,6 +163,9 @@ class Menu_Core extends Menu_Element {
case "link":
return new Menu_Element_Link($type);
+ case "ajax_link":
+ return new Menu_Element_Ajax_Link($type);
+
case "dialog":
return new Menu_Element_Dialog($type);
diff --git a/modules/gallery/libraries/ORM_MPTT.php b/modules/gallery/libraries/ORM_MPTT.php
index 1917d738..a7defba9 100644
--- a/modules/gallery/libraries/ORM_MPTT.php
+++ b/modules/gallery/libraries/ORM_MPTT.php
@@ -146,69 +146,62 @@ class ORM_MPTT_Core extends ORM {
* @chainable
* @param integer SQL limit
* @param integer SQL offset
+ * @param array additional where clauses
* @param array orderby
* @return array ORM
*/
- function children($limit=null, $offset=0, $orderby=null) {
- $this->where("parent_id", $this->id);
- if (empty($orderby)) {
- $this->orderby("id", "ASC");
- } else {
- $this->orderby($orderby);
- }
- return $this->find_all($limit, $offset);
+ function children($limit=null, $offset=0, $where=array(), $orderby=array("id" => "ASC")) {
+ return $this
+ ->where("parent_id", $this->id)
+ ->where($where)
+ ->orderby($orderby)
+ ->find_all($limit, $offset);
}
/**
* Return all of the children of this node, ordered by id.
*
* @chainable
- * @param integer SQL limit
- * @param integer SQL offset
+ * @param array additional where clauses
* @return array ORM
*/
- function children_count() {
- return $this->where("parent_id", $this->id)->count_all();
+ function children_count($where=array()) {
+ return $this
+ ->where($where)
+ ->where("parent_id", $this->id)
+ ->count_all();
}
/**
- * Return all of the children of the specified type, ordered by id.
+ * Return all of the decendents of the specified type, ordered by id.
*
* @param integer SQL limit
* @param integer SQL offset
- * @param string type to return
+ * @param array additional where clauses
* @param array orderby
* @return object ORM_Iterator
*/
- function descendants($limit=null, $offset=0, $type=null, $orderby=null) {
- $this->where("left_ptr >", $this->left_ptr)
- ->where("right_ptr <=", $this->right_ptr);
- if ($type) {
- $this->where("type", $type);
- }
-
- if (empty($orderby)) {
- $this->orderby("id", "ASC");
- } else {
- $this->orderby($orderby);
- }
-
- return $this->find_all($limit, $offset);
+ function descendants($limit=null, $offset=0, $where=array(), $orderby=array("id" => "ASC")) {
+ return $this
+ ->where("left_ptr >", $this->left_ptr)
+ ->where("right_ptr <=", $this->right_ptr)
+ ->where($where)
+ ->orderby($orderby)
+ ->find_all($limit, $offset);
}
/**
* Return the count of all the children of the specified type.
*
- * @param string type to count
+ * @param array additional where clauses
* @return integer child count
*/
- function descendants_count($type=null) {
- $this->where("left_ptr >", $this->left_ptr)
- ->where("right_ptr <=", $this->right_ptr);
- if ($type) {
- $this->where("type", $type);
- }
- return $this->count_all();
+ function descendants_count($where=array()) {
+ return $this
+ ->where("left_ptr >", $this->left_ptr)
+ ->where("right_ptr <=", $this->right_ptr)
+ ->where($where)
+ ->count_all();
}
/**
diff --git a/modules/gallery/libraries/Sendmail.php b/modules/gallery/libraries/Sendmail.php
index 90998457..7bc21a67 100644
--- a/modules/gallery/libraries/Sendmail.php
+++ b/modules/gallery/libraries/Sendmail.php
@@ -52,6 +52,7 @@ class Sendmail_Core {
break;
case "header":
if (count($value) != 2) {
+ Kohana::log("error", wordwrap("Invalid header parameters\n" . Kohana::debug($value)));
throw new Exception("@todo INVALID_HEADER_PARAMETERS");
}
$this->headers[$value[0]] = $value[1];
@@ -70,6 +71,7 @@ class Sendmail_Core {
public function send() {
if (empty($this->to)) {
+ Kohana::log("error", wordwrap("Sending mail failed:\nNo to address specified"));
throw new Exception("@todo TO_IS_REQUIRED_FOR_MAIL");
}
$to = implode(", ", $this->to);
@@ -84,8 +86,6 @@ class Sendmail_Core {
$headers = implode($this->header_separator, $headers);
$message = wordwrap($this->message, $this->line_length, "\n");
if (!$this->mail($to, $this->subject, $message, $headers)) {
- Kohana::log("error", wordwrap("Sending mail failed:\nTo: $to\n $this->subject\n" .
- "Headers: $headers\n $this->message"));
throw new Exception("@todo SEND_MAIL_FAILED");
}
return $this;
diff --git a/modules/gallery/libraries/Theme_View.php b/modules/gallery/libraries/Theme_View.php
index 360e5e46..541bce88 100644
--- a/modules/gallery/libraries/Theme_View.php
+++ b/modules/gallery/libraries/Theme_View.php
@@ -111,14 +111,15 @@ class Theme_View_Core extends Gallery_View {
return $menu->compact();
}
- public function thumb_menu($item) {
+ public function context_menu($item, $thumbnail_css_selector) {
$menu = Menu::factory("root")
->append(Menu::factory("submenu")
- ->id("options_menu")
+ ->id("context_menu")
->label(t("Options")))
- ->css_class("gThumbMenu");
+ ->css_class("gContextMenu");
- module::event("thumb_menu", $menu, $this, $item);
+ gallery::context_menu($menu, $this, $item, $thumbnail_css_selector);
+ module::event("context_menu", $menu, $this, $item, $thumbnail_css_selector);
return $menu->compact();
}
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index f3e6b8f3..68e89db6 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -19,7 +19,6 @@
*/
class Item_Model extends ORM_MPTT {
protected $children = 'items';
- private $view_restrictions = null;
protected $sorting = array();
var $rules = array(
@@ -34,38 +33,7 @@ class Item_Model extends ORM_MPTT {
* @chainable
*/
public function viewable() {
- if (is_null($this->view_restrictions)) {
- if (user::active()->admin) {
- $this->view_restrictions = array();
- } else {
- foreach (user::group_ids() as $id) {
- // Separate the first restriction from the rest to make it easier for us to formulate
- // our where clause below
- if (empty($this->view_restrictions)) {
- $this->view_restrictions[0] = "view_$id";
- } else {
- $this->view_restrictions[1]["view_$id"] = access::ALLOW;
- }
- }
- }
- }
- switch (count($this->view_restrictions)) {
- case 0:
- break;
-
- case 1:
- $this->where($this->view_restrictions[0], access::ALLOW);
- break;
-
- default:
- $this->open_paren();
- $this->where($this->view_restrictions[0], access::ALLOW);
- $this->orwhere($this->view_restrictions[1]);
- $this->close_paren();
- break;
- }
-
- return $this;
+ return item::viewable($this);
}
/**
@@ -351,14 +319,7 @@ class Item_Model extends ORM_MPTT {
$this->updated = time();
if (!$this->loaded) {
$this->created = $this->updated;
- // Guard against an empty result when we create the first item. It's unfortunate that we
- // have to check this every time.
- // @todo: figure out a better way to bootstrap the weight.
- $result = Database::instance()
- ->select("weight")->from("items")
- ->orderby("weight", "desc")->limit(1)
- ->get()->current();
- $this->weight = ($result ? $result->weight : 0) + 1;
+ $this->weight = item::get_max_weight();
} else {
$send_event = 1;
}
@@ -521,26 +482,38 @@ class Item_Model extends ORM_MPTT {
}
/**
- * Return all of the children of this node, ordered by the defined sort order.
+ * Return all of the children of this album. Unless you specify a specific sort order, the
+ * results will be ordered by this album's sort order.
*
* @chainable
* @param integer SQL limit
* @param integer SQL offset
+ * @param array additional where clauses
+ * @param array orderby
* @return array ORM
*/
- function children($limit=null, $offset=0) {
- return parent::children($limit, $offset, array($this->sort_column => $this->sort_order));
+ function children($limit=null, $offset=0, $where=array(), $orderby=null) {
+ if (empty($orderby)) {
+ $orderby = array($this->sort_column => $this->sort_order);
+ }
+ return parent::children($limit, $offset, $where, $orderby);
}
/**
- * Return all of the children of the specified type, ordered by the defined sort order.
+ * Return the children of this album, and all of it's sub-albums. Unless you specify a specific
+ * sort order, the results will be ordered by this album's sort order. Note that this
+ * album's sort order is imposed on all sub-albums, regardless of their sort order.
+ *
+ * @chainable
* @param integer SQL limit
* @param integer SQL offset
- * @param string type to return
+ * @param array additional where clauses
* @return object ORM_Iterator
*/
- function descendants($limit=null, $offset=0, $type=null) {
- return parent::descendants($limit, $offset, $type,
- array($this->sort_column => $this->sort_order));
+ function descendants($limit=null, $offset=0, $where=array(), $orderby=null) {
+ if (empty($orderby)) {
+ $orderby = array($this->sort_column => $this->sort_order);
+ }
+ return parent::descendants($limit, $offset, $where, $orderby);
}
}
diff --git a/modules/gallery/tests/Item_Helper_Test.php b/modules/gallery/tests/Item_Helper_Test.php
new file mode 100644
index 00000000..3f80733f
--- /dev/null
+++ b/modules/gallery/tests/Item_Helper_Test.php
@@ -0,0 +1,49 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Item_Helper_Test extends Unit_Test_Case {
+
+ public function viewable_test() {
+ $root = ORM::factory("item", 1);
+ $album = album::create($root, rand(), rand(), rand());
+ $item = self::_create_random_item($album);
+ user::set_active(user::guest());
+
+ // We can see the item when permissions are granted
+ access::allow(group::everybody(), "view", $album);
+ $this->assert_equal(
+ 1,
+ ORM::factory("item")->viewable()->where("id", $item->id)->count_all());
+
+ // We can't see the item when permissions are denied
+ access::deny(group::everybody(), "view", $album);
+ $this->assert_equal(
+ 0,
+ ORM::factory("item")->viewable()->where("id", $item->id)->count_all());
+ }
+
+
+ private static function _create_random_item($album) {
+ // Set all required fields (values are irrelevant)
+ $item = ORM::factory("item");
+ $item->name = rand();
+ $item->type = "photo";
+ return $item->add_to_parent($album);
+ }
+}
diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php
index 0940d076..585e247c 100644
--- a/modules/gallery/tests/Item_Model_Test.php
+++ b/modules/gallery/tests/Item_Model_Test.php
@@ -19,12 +19,12 @@
*/
class Item_Model_Test extends Unit_Test_Case {
public function saving_sets_created_and_updated_dates_test() {
- $item = self::create_random_item();
+ $item = self::_create_random_item();
$this->assert_true(!empty($item->created));
$this->assert_true(!empty($item->updated));
}
- private function create_random_item() {
+ private static function _create_random_item() {
$item = ORM::factory("item");
/* Set all required fields (values are irrelevant) */
$item->name = rand();
@@ -33,7 +33,7 @@ class Item_Model_Test extends Unit_Test_Case {
}
public function updating_doesnt_change_created_date_test() {
- $item = self::create_random_item();
+ $item = self::_create_random_item();
// Force the creation date to something well known
$db = Database::instance();
@@ -47,7 +47,7 @@ class Item_Model_Test extends Unit_Test_Case {
}
public function updating_view_count_only_doesnt_change_updated_date_test() {
- $item = self::create_random_item();
+ $item = self::_create_random_item();
$item->reload();
$this->assert_same(0, $item->view_count);
@@ -64,7 +64,7 @@ class Item_Model_Test extends Unit_Test_Case {
public function move_photo_test() {
// Create a test photo
- $item = self::create_random_item();
+ $item = self::_create_random_item();
file_put_contents($item->thumb_path(), "thumb");
file_put_contents($item->resize_path(), "resize");
@@ -128,7 +128,7 @@ class Item_Model_Test extends Unit_Test_Case {
public function item_rename_wont_accept_slash_test() {
// Create a test photo
- $item = self::create_random_item();
+ $item = self::_create_random_item();
$new_name = rand() . "/";
@@ -142,7 +142,7 @@ class Item_Model_Test extends Unit_Test_Case {
}
public function save_original_values_test() {
- $item = $this->create_random_item();
+ $item = self::_create_random_item();
$item->title = "ORIGINAL_VALUE";
$item->save();
$item->title = "NEW_VALUE";
diff --git a/modules/gallery/tests/ORM_MPTT_Test.php b/modules/gallery/tests/ORM_MPTT_Test.php
index 943810c3..f77f1f34 100644
--- a/modules/gallery/tests/ORM_MPTT_Test.php
+++ b/modules/gallery/tests/ORM_MPTT_Test.php
@@ -177,8 +177,8 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$parent->reload();
$this->assert_equal(3, $parent->descendants()->count());
- $this->assert_equal(2, $parent->descendants(null, 0, "photo")->count());
- $this->assert_equal(1, $parent->descendants(null, 0, "album")->count());
+ $this->assert_equal(2, $parent->descendants(null, 0, array("type" => "photo"))->count());
+ $this->assert_equal(1, $parent->descendants(null, 0, array("type" => "album"))->count());
}
public function descendant_limit_test() {
@@ -215,7 +215,7 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$parent->reload();
$this->assert_equal(3, $parent->descendants_count());
- $this->assert_equal(2, $parent->descendants_count("photo"));
- $this->assert_equal(1, $parent->descendants_count("album"));
+ $this->assert_equal(2, $parent->descendants_count(array("type" => "photo")));
+ $this->assert_equal(1, $parent->descendants_count(array("type" => "album")));
}
}
diff --git a/modules/gallery/views/admin_graphics.html.php b/modules/gallery/views/admin_graphics.html.php
index 08374471..c4a2f5c6 100644
--- a/modules/gallery/views/admin_graphics.html.php
+++ b/modules/gallery/views/admin_graphics.html.php
@@ -9,8 +9,8 @@
};
$("#gAdminGraphics div.gAvailable .gBlock").click(select_toolkit);
});
-
</script>
+
<div id="gAdminGraphics">
<h1> <?= t("Graphics Settings") ?> </h1>
<p>
@@ -18,11 +18,19 @@
</p>
<h2> <?= t("Active Toolkit") ?> </h2>
- <?= $active ?>
+ <? if ($active == "none"): ?>
+ <?= new View("admin_graphics_none.html") ?>
+ <? else: ?>
+ <?= new View("admin_graphics_$active.html", array("tk" => $tk->$active, "is_active" => true)) ?>
+ <? endif ?>
<div class="gAvailable">
<h2> <?= t("Available Toolkits") ?> </h2>
- <?= $available ?>
+ <? foreach (array_keys((array)$tk) as $id): ?>
+ <? if ($id != $active): ?>
+ <?= new View("admin_graphics_$id.html", array("tk" => $tk->$id, "is_active" => false)) ?>
+ <? endif ?>
+ <? endforeach ?>
</div>
</div>
diff --git a/modules/gallery/views/admin_graphics_gd.html.php b/modules/gallery/views/admin_graphics_gd.html.php
index b77da8e3..010a31b4 100644
--- a/modules/gallery/views/admin_graphics_gd.html.php
+++ b/modules/gallery/views/admin_graphics_gd.html.php
@@ -1,29 +1,30 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="gd" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->gd["GD Version"] ? " gInstalledToolkit" : " gUnavailable" ?>">
+<div id="gd" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->installed ? " gInstalledToolkit" : " gUnavailable" ?>">
<img class="logo" width="170" height="110" src="<?= url::file("modules/gallery/images/gd.png"); ?>" alt="<? t("Visit the GD lib project site") ?>" />
<h3> <?= t("GD") ?> </h3>
<p>
<?= t("The GD graphics library is an extension to PHP commonly installed most webservers. Please refer to the <a href=\"%url\">GD website</a> for more information.",
array("url" => "http://www.boutell.com/gd")) ?>
</p>
- <? if ($tk->gd["GD Version"] && function_exists('imagerotate')): ?>
- <p class="gSuccess">
- <?= t("You have GD version %version.", array("version" => $tk->gd["GD Version"])) ?>
- </p>
+ <? if ($tk->installed && $tk->rotate): ?>
+ <div class="gModuleStatus gInfo">
+ <?= t("You have GD version %version.", array("version" => $tk->version)) ?>
+ </div>
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate GD") ?></a>
</p>
- <? elseif ($tk->gd["GD Version"]): ?>
- <p class="gWarning">
- <?= t("You have GD version %version, but it lacks image rotation.",
- array("version" => $tk->gd["GD Version"])) ?>
+ <? elseif ($tk->installed): ?>
+ <? if ($tk->error): ?>
+ <p class="gModuleStatus gWarning">
+ <?= $tk->error ?>
</p>
+ <? endif ?>
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate GD") ?></a>
</p>
<? else: ?>
- <p class="gInfo">
+ <div class="gModuleStatus gInfo">
<?= t("You do not have GD installed.") ?>
- </p>
+ </div>
<? endif ?>
</div>
diff --git a/modules/gallery/views/admin_graphics_graphicsmagick.html.php b/modules/gallery/views/admin_graphics_graphicsmagick.html.php
index e2cd0777..97624850 100644
--- a/modules/gallery/views/admin_graphics_graphicsmagick.html.php
+++ b/modules/gallery/views/admin_graphics_graphicsmagick.html.php
@@ -1,21 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="graphicsmagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->graphicsmagick ? " gInstalledToolkit" : " gUnavailable" ?>">
- <h3> <?= t("GraphicsMagick") ?> </h3>
+<div id="graphicsmagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->installed ? " gInstalledToolkit" : " gUnavailable" ?>">
<img class="logo" width="107" height="76" src="<?= url::file("modules/gallery/images/graphicsmagick.png"); ?>" alt="<? t("Visit the GraphicsMagick project site") ?>" />
+ <h3> <?= t("GraphicsMagick") ?> </h3>
<p>
<?= t("GraphicsMagick is a standalone graphics program available on most Linux systems. Please refer to the <a href=\"%url\">GraphicsMagick website</a> for more information.",
array("url" => "http://www.graphicsmagick.org")) ?>
</p>
- <? if ($tk->graphicsmagick): ?>
- <p class="gSuccess">
- <?= t("GraphicsMagick is available in %path", array("path" => $tk->graphicsmagick)) ?>
- </p>
+ <? if ($tk->installed): ?>
+ <div class="gModuleStatus gInfo">
+ <?= t("GraphicsMagick version %version is available in %dir", array("version" => $tk->version, "dir" => $tk->dir)) ?>
+ </div>
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate Graphics Magic") ?></a>
</p>
<? else: ?>
- <p class="gInfo">
- <?= t("GraphicsMagick is not available on your system.") ?>
- </p>
+ <div class="gModuleStatus gWarning">
+ <?= $tk->error ?>
+ </div>
<? endif ?>
</div>
diff --git a/modules/gallery/views/admin_graphics_imagemagick.html.php b/modules/gallery/views/admin_graphics_imagemagick.html.php
index 081ddc15..cdff7c2c 100644
--- a/modules/gallery/views/admin_graphics_imagemagick.html.php
+++ b/modules/gallery/views/admin_graphics_imagemagick.html.php
@@ -1,21 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="imagemagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->imagemagick ? " gInstalledToolkit" : " gUnavailable" ?>">
- <h3> <?= t("ImageMagick") ?> </h3>
+<div id="imagemagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->installed ? " gInstalledToolkit" : " gUnavailable" ?>">
<img class="logo" width="114" height="118" src="<?= url::file("modules/gallery/images/imagemagick.jpg"); ?>" alt="<? t("Visit the ImageMagick project site") ?>" />
+ <h3> <?= t("ImageMagick") ?> </h3>
<p>
<?= t("ImageMagick is a standalone graphics program available on most Linux systems. Please refer to the <a href=\"%url\">ImageMagick website</a> for more information.",
array("url" => "http://www.imagemagick.org")) ?>
</p>
- <? if ($tk->imagemagick): ?>
- <p class="gSuccess">
- <?= t("ImageMagick is available in %path", array("path" => $tk->imagemagick)) ?>
- </p>
+ <? if ($tk->installed): ?>
+ <div class="gModuleStatus gInfo">
+ <?= t("ImageMagick version %version is available in %dir", array("version" => $tk->version, "dir" => $tk->dir)) ?>
+ </div>
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate ImageMagick") ?></a>
</p>
- <? else: ?>
- <p class="gInfo">
- <?= t("ImageMagick is not available on your system.") ?>
- </p>
+ <? elseif ($tk->error): ?>
+ <div class="gModuleStatus gWarning">
+ <?= $tk->error ?>
+ </div>
<? endif ?>
</div>
diff --git a/modules/gallery/views/admin_graphics_none.html.php b/modules/gallery/views/admin_graphics_none.html.php
index 5306a70d..e6923a5a 100644
--- a/modules/gallery/views/admin_graphics_none.html.php
+++ b/modules/gallery/views/admin_graphics_none.html.php
@@ -1,7 +1,8 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="none" class="gBlock">
- <h3 class="gWarning"> <?= t("No Active Toolkit") ?> </h3>
+
+<div id="none" class="gModuleStatus gWarning gBlock">
+ <h3> <?= t("No Active Toolkit") ?> </h3>
<p>
- <?= t("We were unable to detect a graphics program. You must install one of the toolkits below in order to many Gallery features.") ?>
+ <?= t("We were unable to detect a graphics program. You must install one of the toolkits below in order to use many Gallery features.") ?>
</p>
</div>
diff --git a/modules/gallery/views/admin_languages.html.php b/modules/gallery/views/admin_languages.html.php
index f41694b4..4025437a 100644
--- a/modules/gallery/views/admin_languages.html.php
+++ b/modules/gallery/views/admin_languages.html.php
@@ -1,15 +1,100 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="gLanguages">
- <h2> <?= t("Languages") ?> </h2>
+ <h1> <?= t("Languages") ?> </h1>
+ <p>
+ <?= t("Install new languages, update installed ones and set the default language for your Gallery.") ?>
+ </p>
- <?= $settings_form ?>
-
- <h2> <?= t("Download translations") ?> </h2>
- <a href="<?= url::site("admin/maintenance/start/gallery_task::update_l10n?csrf=$csrf") ?>"
- class="gDialogLink">
- <?= t("Get updates") ?>
- </a>
+ <form id="gLanguagesForm" method="post" action="<?= url::site("admin/languages/save") ?>">
+ <?= access::csrf_form_field() ?>
+ <table>
+ <tr>
+ <th> <?= t("Installed") ?> </th>
+ <th> <?= t("Language") ?> </th>
+ <th> <?= t("Default language") ?> </th>
+ </tr>
+ <? $i = 0 ?>
+ <? foreach ($available_locales as $code => $display_name): ?>
+
+ <? if ($i == (count($available_locales)/2)): ?>
+ <table>
+ <tr>
+ <th> <?= t("Installed") ?> </th>
+ <th> <?= t("Language") ?> </th>
+ <th> <?= t("Default language") ?> </th>
+ </tr>
+ <? endif ?>
+
+ <tr class="<?= (isset($installed_locales[$code])) ? "installed" : "" ?><?= ($default_locale == $code) ? " default" : "" ?>">
+ <td> <?= form::checkbox("installed_locales[]", $code, isset($installed_locales[$code])) ?> </td>
+ <td> <?= $display_name ?> </td>
+ <td>
+ <?= form::radio("default_locale", $code, ($default_locale == $code), ((isset($installed_locales[$code]))?'':'disabled="disabled"') ) ?>
+ </td>
+ </tr>
+ <? $i++ ?>
+
+ <? endforeach ?>
+ </table>
+ <input type="submit" value="<?= t("Update languages") ?>" />
+ </form>
+
+ <script type="text/javascript">
+ var old_default_locale = "<?= $default_locale ?>";
+
+ $("input[name='installed_locales[]']").change(function (event) {
+ if (this.checked) {
+ $("input[type='radio'][value='" + this.value + "']").enable();
+ } else {
+ if ($("input[type='radio'][value='" + this.value + "']").selected()) { // if you deselect your default language, switch to some other installed language
+ $("input[type='radio'][value='" + old_default_locale + "']").attr("checked", "checked");
+ }
+ $("input[type='radio'][value='" + this.value + "']").attr("disabled", "disabled");
+ }
+ });
+
+ $("#gLanguagesForm").ajaxForm({
+ dataType: "json",
+ success: function(data) {
+ if (data.result == "success") {
+ el = $('<a href="<?= url::site("admin/maintenance/start/gallery_task::update_l10n?csrf=$csrf") ?>"></a>'); // this is a little hack to trigger the update_l10n task in a dialog
+ el.gallery_dialog();
+ el.trigger('click');
+ }
+ }
+ });
+ </script>
+</div>
- <h2> <?= t("Your Own Translations") ?> </h2>
+<div id="gTranslations">
+ <h1> <?= t("Translations") ?> </h1>
+ <p>
+ <?= t("Create your own translations and share them with the rest of the Gallery community.") ?>
+ </p>
+
+ <h3><?= t("Translating Gallery") ?></h3>
+
+ <div class="gBlock">
+ <a href="http://codex.gallery2.org/Gallery3:Localization" target="_blank"
+ class="gDocLink ui-state-default ui-corner-all ui-icon ui-icon-help"
+ title="<?= t("Localization documentation") ?>">
+ <?= t("Localization documentation") ?>
+ </a>
+
+ <p><strong><?= t("Step 1") ?>:</strong> <?= t("Make sure the target language is installed and updated (check above).") ?></p>
+
+ <p><strong><?= t("Step 2") ?>:</strong> <?= t("Make sure the target language is the active one (currently '").locales::display_name()."')." ?></p>
+
+ <p><strong><?= t("Step 3") ?>:</strong> <?= t("Start the translation mode and the translation interface will appear at the bottom of each Gallery page.") ?></p>
+
+ <a href="<?= url::site("l10n_client/toggle_l10n_mode?csrf=".access::csrf_token()) ?>"
+ class="gButtonLink ui-state-default ui-corner-all ui-icon-left">
+ <span class="ui-icon ui-icon-power"></span>
+ <?= t((Session::instance()->get("l10n_mode", false)) ? "Stop translation mode" : "Start translation mode") ?>
+ </a>
+ </div>
+
+ <h3>Sharing your translations</h3>
+
<?= $share_translations_form ?>
</div>
diff --git a/modules/gallery/views/admin_maintenance.html.php b/modules/gallery/views/admin_maintenance.html.php
index a4db38ce..a0a6a19e 100644
--- a/modules/gallery/views/admin_maintenance.html.php
+++ b/modules/gallery/views/admin_maintenance.html.php
@@ -7,7 +7,7 @@
<div id="gAvailableTasks">
<h2> <?= t("Available Tasks") ?> </h2>
- <table>
+ <table class="gMessages">
<tr>
<th>
<?= t("Name") ?>
@@ -19,8 +19,9 @@
<?= t("Action") ?>
</th>
</tr>
+ <? $i = 0; ?>
<? foreach ($task_definitions as $task): ?>
- <tr class="<?= log::severity_class($task->severity) ?>">
+ <tr class="<?= log::severity_class($task->severity) ?> <?= ($i % 2 == 0) ? "gOddRow" : "gEvenRow" ?>">
<td>
<?= $task->name ?>
</td>
@@ -34,17 +35,18 @@
</a>
</td>
</tr>
+ <? $i++ ?>
<? endforeach ?>
</table>
</div>
<? if ($running_tasks->count()): ?>
<div id="gRunningTasks">
- <h2> <?= t("Running Tasks") ?> </h2>
<a href="<?= url::site("admin/maintenance/cancel_running_tasks?csrf=$csrf") ?>"
class="gButtonLink ui-icon-left ui-state-default ui-corner-all right">
<?= t("cancel all") ?></a>
+ <h2> <?= t("Running Tasks") ?> </h2>
<table>
<tr>
<th>
@@ -66,8 +68,9 @@
<?= t("Action") ?>
</th>
</tr>
+ <? $i = 0; ?>
<? foreach ($running_tasks as $task): ?>
- <tr class="<?= $task->state == "stalled" ? "gWarning" : "" ?>">
+ <tr class="<?= $task->state == "stalled" ? "gWarning" : "" ?> <?= ($i % 2 == 0) ? "gOddRow" : "gEvenRow" ?>">
<td>
<?= gallery::date_time($task->updated) ?>
</td>
@@ -105,6 +108,7 @@
</a>
</td>
</tr>
+ <? $i++ ?>
<? endforeach ?>
</table>
</div>
@@ -138,8 +142,9 @@
<?= t("Action") ?>
</th>
</tr>
+ <? $i = 0; ?>
<? foreach ($finished_tasks as $task): ?>
- <tr class="<?= $task->state == "success" ? "gSuccess" : "gError" ?>">
+ <tr class="<?= $task->state == "success" ? "gSuccess" : "gError" ?> <?= ($i % 2 == 0) ? "gOddRow" : "gEvenRow" ?>">
<td>
<?= gallery::date_time($task->updated) ?>
</td>
@@ -183,6 +188,7 @@
</td>
</tr>
<? endforeach ?>
+ <? $i++ ?>
</table>
</div>
<? endif ?>
diff --git a/modules/gallery/views/admin_modules.html.php b/modules/gallery/views/admin_modules.html.php
index 3fddd6cd..168e20d0 100644
--- a/modules/gallery/views/admin_modules.html.php
+++ b/modules/gallery/views/admin_modules.html.php
@@ -16,7 +16,7 @@
</tr>
<? $i = 0 ?>
<? foreach ($available as $module_name => $module_info): ?>
- <tr class="<?= ($i % 2 == 0) ? "gEvenRow" : "gOddRow" ?>">
+ <tr class="<?= ($i % 2 == 0) ? "gOddRow" : "gEvenRow" ?>">
<? $data = array("name" => $module_name); ?>
<? if ($module_info->locked) $data["disabled"] = 1; ?>
<td> <?= form::checkbox($data, '1', module::is_active($module_name)) ?> </td>
diff --git a/modules/gallery/views/after_install.html.php b/modules/gallery/views/after_install.html.php
index 2cf8ec8f..b77a1707 100644
--- a/modules/gallery/views/after_install.html.php
+++ b/modules/gallery/views/after_install.html.php
@@ -16,7 +16,7 @@
title="<?= t("Edit Your Profile") ?>"
id="gAfterInstallChangePasswordLink" class="gButtonLink ui-state-default ui-corners-all"><?= t("Change Password Now") ?></a>
<script>
- $("#gAfterInstallChangePasswordLink").bind("click", handleDialogEvent);
+ $("#gAfterInstallChangePasswordLink").gallery_dialog();
</script>
</p>
diff --git a/modules/gallery/views/after_install_loader.html.php b/modules/gallery/views/after_install_loader.html.php
index baf91eed..54484963 100644
--- a/modules/gallery/views/after_install_loader.html.php
+++ b/modules/gallery/views/after_install_loader.html.php
@@ -3,5 +3,5 @@
title="<?= t("Welcome to Gallery 3") ?>"
href="<?= url::site("after_install") ?>"/>
<script type="text/javascript">
- $(document).ready(function(){openDialog($("#gAfterInstall"));});
+ $(document).ready(function(){$("#gAfterInstall").gallery_dialog({immediate: true});});
</script>
diff --git a/modules/gallery/views/l10n_client.html.php b/modules/gallery/views/l10n_client.html.php
index 523552c3..520fd79e 100644
--- a/modules/gallery/views/l10n_client.html.php
+++ b/modules/gallery/views/l10n_client.html.php
@@ -1,7 +1,10 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="l10n-client" class="hidden">
<div class="labels">
- <span id="l10n-client-toggler">X</span>
+ <span id="l10n-client-toggler">
+ <a id="gMinimizeL10n">_</a>
+ <a id="gCloseL10n" href="<?= url::site("l10n_client/toggle_l10n_mode?csrf=".access::csrf_token()) ?>">X</a>
+ </span>
<div class="label strings"><h2><?= t("Page Text") ?>
<? if (!Input::instance()->get('show_all_l10n_messages')): ?>
<a style="background-color:#fff" href="<?= url::site("admin/languages?show_all_l10n_messages=1") ?>"><?= t("(Show All)") ?></a>
diff --git a/modules/gallery/views/permissions_browse.html.php b/modules/gallery/views/permissions_browse.html.php
index 9ea0da25..90970112 100644
--- a/modules/gallery/views/permissions_browse.html.php
+++ b/modules/gallery/views/permissions_browse.html.php
@@ -5,8 +5,9 @@
$.ajax({
url: form_url.replace("__ITEM__", id),
success: function(data) {
- $("div.form").slideUp();
- $("div#edit-" + id).html(data).slideDown();
+ $("#gEditPermissionForm").html(data);
+ $(".active").removeClass("active");
+ $("#item-" + id).addClass("active");
}
});
}
@@ -18,7 +19,7 @@
url: action_url.replace("__CMD__", cmd).replace("__GROUP__", group_id).
replace("__PERM__", perm_id).replace("__ITEM__", item_id),
success: function(data) {
- $("div#edit-" + item_id).load(form_url.replace("__ITEM__", item_id));
+ $("#gEditPermissionForm").load(form_url.replace("__ITEM__", item_id));
}
});
}
@@ -31,26 +32,25 @@
</li>
</ul>
<? endif ?>
- <ul>
+
+ <p><?= t("Edit permissions for album:") ?></p>
+
+ <ul class="gBreadcrumbs">
<? foreach ($parents as $parent): ?>
- <li>
+ <li id="item-<?= $parent->id ?>">
<a href="javascript:show(<?= $parent->id ?>)">
- <?= SafeString::of($parent->title) ?>
+ <?= SafeString::purify($parent->title) ?>
+ </a>
+ </li>
+ <? endforeach ?>
+ <li class="active" id="item-<?= $item->id ?>">
+ <a href="javascript:show(<?= $item->id ?>)">
+ <?= SafeString::purify($item->title) ?>
</a>
- <div class="form" id="edit-<?= $parent->id ?>"></div>
- <ul>
- <? endforeach ?>
- <li>
- <a href="javascript:show(<?= $item->id ?>)">
- <?= SafeString::purify($item->title) ?>
- </a>
- <div class="form" id="edit-<?= $item->id ?>">
- <?= $form ?>
- </div>
- </li>
- <? foreach ($parents as $parent): ?>
- </ul>
</li>
</ul>
- <? endforeach ?>
-</div>
+
+ <div id="gEditPermissionForm">
+ <?= $form ?>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules/gallery/views/quick_pane.html.php b/modules/gallery/views/quick_pane.html.php
deleted file mode 100644
index e5469696..00000000
--- a/modules/gallery/views/quick_pane.html.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<? foreach ($button_list->main as $button): ?>
-<a class="<?= $button->class ?> ui-corner-all ui-state-default" href="<?= $button->href ?>"
- title="<?= $button->title ?>">
- <span class="ui-icon <?= $button->icon ?>">
- <?= $button->title ?>
- </span>
-</a>
-<? endforeach ?>
-
-<? if (!empty($button_list->additional)): ?>
-<a class="gButtonLink ui-corner-all ui-state-default options" href="#" title="<?= t("additional options") ?>">
- <span class="ui-icon ui-icon-triangle-1-s">
- <?= t("Additional options") ?>
- </span>
-</a>
-
-<ul class="gQuickPaneOptions" style="display: none">
- <? foreach ($button_list->additional as $button): ?>
- <li><a class="<?= $button->class ?>" href="<?= $button->href ?>"
- title="<?= $button->title ?>">
- <?= $button->title ?>
- </a></li>
- <? endforeach ?>
-</ul>
-<? endif ?>
diff --git a/modules/gallery/views/simple_uploader.html.php b/modules/gallery/views/simple_uploader.html.php
index fc426e8f..1f185780 100644
--- a/modules/gallery/views/simple_uploader.html.php
+++ b/modules/gallery/views/simple_uploader.html.php
@@ -217,7 +217,7 @@
var fp = new File_Progress(file);
switch (error_code) {
case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
- fp.set_status("error", "<?= t("Upload error: ")->for_js() ?>" + message);
+ fp.set_status("error", "<?= t("Upload error: bad image file")->for_js() ?>");
break;
case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
fp.set_status("error", "<?= t("Upload failed")->for_js() ?>");
diff --git a/modules/info/views/info_block.html.php b/modules/info/views/info_block.html.php
index 365a1021..bfaaee99 100644
--- a/modules/info/views/info_block.html.php
+++ b/modules/info/views/info_block.html.php
@@ -10,9 +10,9 @@
<?= nl2br(SafeString::purify($item->description)) ?>
</li>
<? endif ?>
- <? if ($item->id != 1): ?>
+ <? if (!$item->is_album()): ?>
<li>
- <strong class="caption"><?= t("Folder name:") ?></strong>
+ <strong class="caption"><?= t("File name:") ?></strong>
<?= SafeString::of($item->name) ?>
</li>
<? endif ?>
diff --git a/modules/notification/helpers/notification.php b/modules/notification/helpers/notification.php
index 92c40d4f..d95b3060 100644
--- a/modules/notification/helpers/notification.php
+++ b/modules/notification/helpers/notification.php
@@ -153,7 +153,7 @@ class notification {
->where("email", $email)
->find_all();
if ($result->count() == 1) {
- $pending = $result->get();
+ $pending = $result->current();
Sendmail::factory()
->to($email)
->subject($pending->subject)
diff --git a/modules/notification/helpers/notification_event.php b/modules/notification/helpers/notification_event.php
index d1b76e93..c50b04c4 100644
--- a/modules/notification/helpers/notification_event.php
+++ b/modules/notification/helpers/notification_event.php
@@ -18,42 +18,80 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class notification_event_Core {
+ // The assumption is that the exception was logged at a lower level, but we
+ // don't want to screw up the processing that was generating the notification
+ // so we don't pass the exception up the call stack
static function item_updated($original, $new) {
- notification::send_item_updated($new);
+ try {
+ notification::send_item_updated($new);
+ } catch (Exception $e) {
+ Kohana::log("error", "@todo notification_event::item_updated() failed");
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
+ }
}
static function item_created($item) {
- notification::send_item_add($item);
+ try {
+ notification::send_item_add($item);
+ } catch (Exception $e) {
+ Kohana::log("error", "@todo notification_event::item_created() failed");
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
+ }
}
static function item_deleted($item) {
- notification::send_item_deleted($item);
+ try {
+ notification::send_item_deleted($item);
- if (notification::is_watching($item)) {
- notification::remove_watch($item);
+ if (notification::is_watching($item)) {
+ notification::remove_watch($item);
+ }
+ } catch (Exception $e) {
+ Kohana::log("error", "@todo notification_event::item_deleted() failed");
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
}
}
static function comment_created($comment) {
- if ($comment->state == "published") {
- notification::send_comment_published($comment);
+ try {
+ if ($comment->state == "published") {
+ notification::send_comment_published($comment);
+ }
+ } catch (Exception $e) {
+ Kohana::log("error", "@todo notification_event::comment_created() failed");
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
}
}
static function comment_updated($original, $new) {
- if ($new->state == "published" && $original->state != "published") {
- notification::send_comment_published($new);
+ try {
+ if ($new->state == "published" && $original->state != "published") {
+ notification::send_comment_published($new);
+ }
+ } catch (Exception $e) {
+ Kohana::log("error", "@todo notification_event::comment_updated() failed");
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
}
}
static function user_before_delete($user) {
- ORM::factory("subscription")
- ->where("user_id", $user->id)
- ->delete_all();
+ try {
+ ORM::factory("subscription")
+ ->where("user_id", $user->id)
+ ->delete_all();
+ } catch (Exception $e) {
+ Kohana::log("error", "@todo notification_event::user_before_delete() failed");
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
+ }
}
static function batch_complete() {
- notification::send_pending_notifications();
+ try {
+ notification::send_pending_notifications();
+ } catch (Exception $e) {
+ Kohana::log("error", "@todo notification_event::batch_complete() failed");
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
+ }
}
static function site_menu($menu, $theme) {
@@ -67,10 +105,10 @@ class notification_event_Core {
$menu->get("options_menu")
->append(Menu::factory("link")
- ->id("watch")
- ->label($label)
- ->css_id("gNotifyLink")
- ->url(url::site("notification/watch/$item->id?csrf=" . access::csrf_token())));
+ ->id("watch")
+ ->label($label)
+ ->css_id("gNotifyLink")
+ ->url(url::site("notification/watch/$item->id?csrf=" . access::csrf_token())));
}
}
}
diff --git a/modules/notification/helpers/notification_installer.php b/modules/notification/helpers/notification_installer.php
index 3d450258..aa2e09f7 100644
--- a/modules/notification/helpers/notification_installer.php
+++ b/modules/notification/helpers/notification_installer.php
@@ -27,14 +27,14 @@ class notification_installer {
PRIMARY KEY (`id`),
UNIQUE KEY (`item_id`, `user_id`),
UNIQUE KEY (`user_id`, `item_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {pending_notifications} (
`id` int(9) NOT NULL auto_increment,
`email` varchar(128) NOT NULL,
`subject` varchar(255) NOT NULL,
`text` text,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("notification", 1);
}
diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php
index d60aa838..2b966657 100644
--- a/modules/organize/controllers/organize.php
+++ b/modules/organize/controllers/organize.php
@@ -18,523 +18,131 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Organize_Controller extends Controller {
- private static $_MICRO_THUMB_SIZE = 90;
- private static $_MICRO_THUMB_PADDING = 5;
-
- function index($item_id=1) {
- $item = ORM::factory("item", $item_id);
- $root = ($item->id == 1) ? $item : ORM::factory("item", 1);
- access::required("view", $item);
- access::required("edit", $item);
-
- $v = new View("organize.html");
- $v->root = $root;
- $v->item = $item;
- $v->album_tree = $this->tree($item, $root);
- $v->button_pane = new View("organize_button_pane.html");
+ function dialog($album_id) {
+ $album = ORM::factory("item", $album_id);
+ access::required("view", $album);
+ access::required("edit", $album);
+
+ $v = new View("organize_dialog.html");
+ $v->album = $album;
+ $v->album_tree = self::_tree($album);
+ $v->micro_thumb_grid = self::_get_micro_thumb_grid($album, 0);
print $v;
}
- function content($item_id) {
- $item = ORM::factory("item", $item_id);
- access::required("view", $item);
- access::required("edit", $item);
-
- $width = $this->input->get("width");
- $height = $this->input->get("height");
- $offset = $this->input->get("offset", 0);
- $thumbsize = self::$_MICRO_THUMB_SIZE + 2 * self::$_MICRO_THUMB_PADDING;
- $page_size = ceil($width / $thumbsize) * ceil($height / $thumbsize);
-
- $v = new View("organize_thumb_grid.html");
- $v->children = $item->children($page_size, $offset);
- $v->thumbsize = self::$_MICRO_THUMB_SIZE;
- $v->padding = self::$_MICRO_THUMB_PADDING;
- $v->offset = $offset;
-
- print json_encode(array("count" => $v->children->count(),
- "data" => $v->__toString()));
- }
-
- function header($item_id) {
- $item = ORM::factory("item", $item_id);
- access::required("view", $item);
- access::required("edit", $item);
-
- print json_encode(
- array("title" => SafeString::purify($item->title),
- "description" => empty($item->description) ? "" : SafeString::purify($item->description)));
- }
-
- function tree($item, $parent) {
- access::required("view", $item);
- access::required("edit", $item);
-
- $albums = ORM::factory("item")
- ->where(array("parent_id" => $parent->id, "type" => "album"))
- ->orderby(array("title" => "ASC"))
- ->find_all();
-
- $v = new View("organize_album.html");
- $v->album = $parent;
- $v->selected = $parent->id == $item->id;
-
- if ($albums->count()) {
- $v->album_icon = $parent->id == 1 || $v->selected ? "ui-icon-minus" : "ui-icon-plus";
- } else {
- $v->album_icon = "";
- }
-
- $v->children = "";
- foreach ($albums as $album) {
- $v->children .= $this->tree($item, $album);
- }
- return $v->__toString();
- }
-
- function startTask($operation, $id) {
- access::verify_csrf();
- $items = $this->input->post("item");
-
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- $definition = $this->_getOperationDefinition($item, $operation);
+ function album($album_id, $offset) {
+ $album = ORM::factory("item", $album_id);
+ access::required("view", $album);
+ access::required("edit", $album);
- $task_def = Task_Definition::factory()
- ->callback("organize_task::run")
- ->description($definition["description"])
- ->name($definition["name"]);
- $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id,
- "type" => $definition["type"],
- "batch" => ceil(count($items) * .1)));
- // @todo If there is only one item then call task_run($task->id); Maybe even change js so
- // we can call finish as well.
- batch::start();
print json_encode(
- array("result" => "started",
- "runningMsg" => $definition["runningMsg"],
- "pauseMsg" => "<div class=\"gWarning\">{$definition['pauseMsg']}</div>",
- "resumeMsg" => "<div class=\"gWarning\">{$definition['resumeMsg']}</div>",
- "task" => array("id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "type" => $task->get("type"),
- "status" => $task->status,
- "state" => $task->state,
- "done" => $task->done)));
+ array("grid" => self::_get_micro_thumb_grid($album, $offset)->__toString(),
+ "sort_column" => $album->sort_column,
+ "sort_order" => $album->sort_order));
}
- function runTask($task_id) {
+ function move_to($album_id) {
access::verify_csrf();
- $task = task::run($task_id);
- if (!$task->loaded || $task->owner_id != user::active()->id) {
- access::forbidden();
+ $album = ORM::factory("item", $album_id);
+ foreach ($this->input->post("source_ids") as $source_id) {
+ item::move(ORM::factory("item", $source_id), $album);
}
- print json_encode(array("result" => $task->done ? $task->state : "in_progress",
- "task" => array("id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "type" => $task->get("type"),
- "post_process" => $task->get("post_process"),
- "status" => $task->status,
- "state" => $task->state,
- "done" => $task->done)));
+ print json_encode(
+ array("tree" => self::_tree($album)->__toString(),
+ "grid" => self::_get_micro_thumb_grid($album, 0)->__toString()));
}
- function finishTask($task_id) {
+ function rearrange($target_id, $before_or_after) {
access::verify_csrf();
- $task = ORM::factory("task", $task_id);
- if (!$task->loaded || $task->owner_id != user::active()->id) {
- access::forbidden();
- }
-
- if ($task->done) {
- $item = ORM::factory("item", (int)$task->get("target"));
- $type = $task->get("type");
- switch ($type) {
- case "albumCover":
- $task->status = t("Album cover set for '%album'", array("album" => $item->title));
- break;
- case "delete":
- $task->status = t("Selection deleted");
- break;
- case "move":
- $task->status = t("Move to '%album' completed", array("album" => $item->title));
- break;
- case "rearrange":
- try {
- $item->sort_column = "weight";
- $item->save();
- $task->status = t("Rearrange for '%album' completed", array("album" => $item->title));
- } catch (Exception $e) {
- $task->state = "error";
- $task->status = $e->getMessage();
- }
- break;
- case "rotateCcw":
- case "rotateCw":
- $task->status = t("Rotation completed");
- break;
- }
- $task->save();
- }
-
- batch::stop();
- print json_encode(array("result" => "success",
- "task" => array(
- "id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "status" => $task->status,
- "state" => $task->state,
- "done" => $task->done)));
- }
-
- function cancelTask($task_id) {
- access::verify_csrf();
+ $target = ORM::factory("item", $target_id);
+ $album = $target->parent();
+ access::required("view", $album);
+ access::required("edit", $album);
- $task = ORM::factory("task", $task_id);
- if (!$task->loaded || $task->owner_id != user::active()->id) {
- access::forbidden();
- }
+ $source_ids = $this->input->post("source_ids", array());
- if (!$task->done) {
- $task->done = 1;
- $task->state = "cancelled";
- $type = $task->get("type");
- switch ($type) {
- case "move":
- $task->status = t("Move to album was cancelled prior to completion");
- break;
- case "rearrange":
- $task->status = t("Rearrange album was cancelled prior to completion");
- case "rotateCcw":
- case "rotateCw":
- $task->status = t("Rotation was cancelled prior to completion");
- break;
+ if ($album->sort_column != "weight") {
+ $i = 0;
+ foreach ($album->children() as $child) {
+ // Do this directly in the database to avoid sending notifications
+ Database::Instance()->update("items", array("weight" => ++$i), array("id" => $child->id));
}
- $task->save();
+ $album->sort_column = "weight";
+ $album->sort_order = "ASC";
+ $album->save();
+ $target->reload();
}
- batch::stop();
- print json_encode(array("result" => "success",
- "task" => array(
- "id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "status" => $task->status,
- "state" => $task->state,
- "done" => $task->done)));
- }
-
- function editForm() {
- $event_parms = new stdClass();
- $event_parms->panes = array();
- $event_parms->itemids = $this->input->get("item");
-
- // The following code should be done more dynamically i.e. use the event mechanism
- if (count($event_parms->itemids) == 1) {
- $item = ORM::factory("item")
- ->in("id", $event_parms->itemids[0])
- ->find();
-
- access::required("view", $item);
- access::required("edit", $item);
-
- $event_parms->panes[] = array(
- "label" => $item->is_album() ? t("Edit Album") : t("Edit Photo"),
- "content" => organize::get_general_edit_form($item));
-
- if ($item->is_album()) {
- $event_parms->panes[] = array("label" => t("Sort Order"),
- "content" => organize::get_sort_edit_form($item));
- }
- }
-
- $event_parms->panes[] = array("label" => t("Manage Tags"),
- "content" => organize::get_tag_form($event_parms->itemids));
-
- $v = new View("organize_edit.html");
- $v->panes = $event_parms->panes;
- print $v->render();
- }
-
- // Handlers for the album/photo edit. Probably should be in modules/gallery
- public function general() {
- access::verify_csrf();
-
- $itemids = $this->input->post("item");
- $item = ORM::factory("item")
- ->in("id", $itemids[0])
- ->find();
- access::required("view", $item);
- access::required("edit", $item);
-
- $form = organize::get_general_edit_form($item);
- if ($form->validate()) {
- $orig = clone $item;
- $item->title = $form->title->value;
- $item->description = $form->description->value;
- $item->rename($form->dirname->value);
- $item->save();
-
- if ($item->is_album()) {
- log::success("content", "Updated album", "<a href=\"albums/$item->id\">view</a>");
- $message = t("Saved album %album_title", array("album_title" => SafeString::purify($item->title)));
- } else {
- log::success("content", "Updated photo", "<a href=\"photos/$item->id\">view</a>");
- $message = t("Saved photo %photo_title", array("photo_title" => SafeString::purify($item->title)));
- }
- print json_encode(array("form" => $form->__toString(), "message" => $message));
- } else {
- print json_encode(array("form" => $form->__toString()));
+ // Find the insertion point
+ $target_weight = $target->weight;
+ if ($before_or_after == "after") {
+ $target_weight++;
}
- }
-
- public function reset_general() {
- $itemids = Input::instance()->get("item");
- $item = ORM::factory("item")
- ->in("id", $itemids[0])
- ->find();
- access::required("view", $item);
- access::required("edit", $item);
-
- print organize::get_general_edit_form($item);
- }
-
- public function sort() {
- access::verify_csrf();
- $itemids = $this->input->post("item");
- $item = ORM::factory("item")
- ->in("id", $itemids[0])
- ->find();
- access::required("view", $item);
- access::required("edit", $item);
+ // Make a hole
+ $count = count($source_ids);
+ Database::Instance()->query(
+ "UPDATE {items} " .
+ "SET `weight` = `weight` + $count " .
+ "WHERE `weight` >= $target_weight AND `parent_id` = {$album->id}");
- $form = organize::get_sort_edit_form($item);
- if ($form->validate()) {
- $orig = clone $item;
- $item->sort_column = $form->column->value;
- $item->sort_order = $form->direction->value;
- $item->save();
-
- log::success("content", "Updated album", "<a href=\"albums/$item->id\">view</a>");
- $message = t("Saved album %album_title", array("album_title" => SafeString::purify($item->title)));
- print json_encode(array("form" => $form->__toString(), "message" => $message));
- } else {
- print json_encode(array("form" => $form->__toString()));
+ // Insert source items into the hole
+ foreach ($source_ids as $source_id) {
+ Database::Instance()->update(
+ "items", array("weight" => $target_weight++), array("id" => $source_id));
}
- }
- public function reset_sort() {
- $itemids = Input::instance()->get("item");
- $item = ORM::factory("item")
- ->in("id", $itemids[0])
- ->find();
- access::required("view", $item);
- access::required("edit", $item);
+ module::event("album_rearrange", $album);
- print organize::get_sort_edit_form($item);
+ print json_encode(
+ array("grid" => self::_get_micro_thumb_grid($album, 0)->__toString(),
+ "sort_column" => $album->sort_column,
+ "sort_order" => $album->sort_order));
}
- public function edit_tags() {
+ function sort_order($album_id, $col, $dir) {
access::verify_csrf();
- $itemids = explode("|", $this->input->post("item"));
- $form = organize::get_tag_form($itemids);
- $old_tags = $form->tags->value;
- if ($form->validate()) {
-
- $old_tags = preg_split("/[;,\s]+/", $old_tags);
- sort($old_tags);
- $new_tags = preg_split("/[;,\s]+/", $form->tags->value);
- sort($new_tags);
+ $album = ORM::factory("item", $album_id);
+ access::required("view", $album);
+ access::required("edit", $album);
- $HIGH_VALUE_STRING = "\256";
- for ($old_index = $new_index = 0;;) {
- $old_tag = $old_index >= count($old_tags) ? $HIGH_VALUE_STRING : $old_tags[$old_index];
- $new_tag = $new_index >= count($new_tags) ? $HIGH_VALUE_STRING : $new_tags[$new_index];
- if ($old_tag == $HIGH_VALUE_STRING && $new_tag == $HIGH_VALUE_STRING) {
- break;
- }
- $matches = array();
- $old_star = false;
- if (preg_match("/(.*)(\*)$/", $old_tag, $matches)) {
- $old_star = true;
- $old_tag = $matches[1];
- }
- $new_star = false;
- if (preg_match("/(.*)(\*)$/", $new_tag, $matches)) {
- $new_star = true;
- $new_tag = $matches[1];
- }
- if ($old_tag > $new_tag) {
- // Its missing in the old list so add it
- $this->_add_tag($new_tag, $itemids);
- $new_index++;
- } else if ($old_tag < $new_tag) {
- // Its missing in the new list so its been removed
- $this->_delete_tag($old_tag, $itemids);
- $old_index++;
- } else {
- if ($old_star && !$new_star) {
- // User wants tag to apply to all items, originally only on some of selected
- $this->_update_tag($old_tag, $itemids);
- } // Not changed ignore
- $old_index++;
- $new_index++;
- }
- }
+ $options = album::get_sort_order_options();
+ if (!isset($options[$col])) {
+ return;
}
- print json_encode(array("form" => $form->__toString(), "message" => t("Tags updated")));
- }
- public function reset_edit_tags() {
- $itemids = $this->input->get("item");
+ $album->sort_column = $col;
+ $album->sort_order = $dir;
+ $album->save();
- print organize::get_tag_form($itemids);
+ print json_encode(
+ array("grid" => self::_get_micro_thumb_grid($album, 0)->__toString(),
+ "sort_column" => $album->sort_column,
+ "sort_order" => $album->sort_order));
}
- private function _add_tag($new_tag, $itemids) {
- // Super lame security stopgap. This code is going to get rewritten anyway.
- foreach ($itemids as $item_id) {
- $item = ORM::factory("item", $item_id);
- access::required("view", $item);
- access::required("edit", $item);
- }
-
- $tag = ORM::factory("tag")
- ->where("name", $new_tag)
- ->find();
- if ($tag->loaded) {
- $tag->count += count($itemids);
- } else {
- $tag->name = $new_tag;
- $tag->count = count($itemids);
- }
- $tag->save();
-
- $db = Database::instance();
- foreach ($itemids as $item_id) {
- $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};");
- }
+ private static function _get_micro_thumb_grid($album, $offset) {
+ $v = new View("organize_thumb_grid.html");
+ $v->album = $album;
+ $v->offset = $offset;
+ return $v;
}
- private function _delete_tag($new_tag, $itemids) {
- // Super lame security stopgap. This code is going to get rewritten anyway.
- foreach ($itemids as $item_id) {
- $item = ORM::factory("item", $item_id);
- access::required("view", $item);
- access::required("edit", $item);
- }
+ private static function _tree($album) {
+ $v = new View("organize_tree.html");
+ $v->parents = $album->parents();
+ $v->album = $album;
- $tag = ORM::factory("tag")
- ->where("name", $new_tag)
- ->find();
- $tag->count -= count($itemids);
- if ($tag->count > 0) {
- $tag->save();
+ if ($album->id == 1) {
+ $v->peers = array($album);
} else {
- $tag->delete();
+ $v->peers = $album->parent()->children(null, 0, array("type" => "album"));
}
- $ids = implode(", ", $itemids);
- Database::instance()->query(
- "DELETE FROM {items_tags} WHERE tag_id = {$tag->id} AND item_id IN ($ids);");
- }
-
- private function _update_tag($new_tag, $itemids) {
- // Super lame security stopgap. This code is going to get rewritten anyway.
- foreach ($itemids as $item_id) {
- $item = ORM::factory("item", $item_id);
- access::required("view", $item);
- access::required("edit", $item);
- }
-
- $tag = ORM::factory("tag")
- ->where("name", $new_tag)
- ->find();
-
- $db = Database::instance();
- $ids = implode(", ", $itemids);
- $result = $db->query(
- "SELECT item_id FROM {items_tags}
- WHERE tag_id = {$tag->id}
- AND item_id IN ($ids)");
-
- $add_items = array_fill_keys($itemids, 1);
- foreach($result as $row) {
- unset($add_items[$row->item_id]);
- }
- $add_items = array_keys($add_items);
- $tag->count += count($add_items);
- $tag->save();
- foreach ($add_items as $item_id) {
- $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};");
- }
- }
-
- private function _getOperationDefinition($item, $operation) {
- switch ($operation) {
- case "move":
- return array("description" =>
- t("Move albums and photos to '%name'", array("name" => $item->title)),
- "name" => t("Move to '%name'", array("name" => $item->title)),
- "type" => "move",
- "runningMsg" => t("Move in progress"),
- "pauseMsg" => t("The move operation was paused"),
- "resumeMsg" => t("The move operation was resumed"));
- break;
-
- case "rearrange":
- return array("description" => t("Rearrange the order of albums and photos"),
- "name" => t("Rearrange: %name", array("name" => $item->title)),
- "type" => "rearrange",
- "runningMsg" => t("Rearrange in progress"),
- "pauseMsg" => t("The rearrange operation was paused"),
- "resumeMsg" => t("The rearrange operation was resumed"));
- break;
-
- case "rotateCcw":
- return array("description" => t("Rotate the selected photos counter clockwise"),
- "name" => t("Rotate images in %name", array("name" => $item->title)),
- "type" => "rotateCcw",
- "runningMsg" => t("Rotate Counter Clockwise in progress"),
- "pauseMsg" => t("The rotate operation was paused"),
- "resumeMsg" => t("The rotate operation was resumed"));
- break;
-
- case "rotateCw":
- return array("description" => t("Rotate the selected photos clockwise"),
- "name" => t("Rotate images in %name", array("name" => $item->title)),
- "type" => "rotateCw",
- "runningMsg" => t("Rotate Clockwise in progress"),
- "pauseMsg" => t("The rotate operation was paused"),
- "resumeMsg" => t("The rotate operation was resumed"));
- break;
-
- case "delete":
- return array("description" => t("Delete selected photos / albums"),
- "name" => t("Delete images in %name", array("name" => $item->title)),
- "type" => "delete",
- "runningMsg" => t("Delete images in progress"),
- "pauseMsg" => t("The delete operation was paused"),
- "resumeMsg" => t("The delete operation was resumed"));
- break;
-
- case "albumCover":
- return array("description" => t("Reset Album Cover"),
- "name" => t("Reset Album cover for %name", array("name" => $item->title)),
- "type" => "albumCover",
- "runningMsg" => t("Reset Album Cover in progress"),
- "pauseMsg" => t("Reset album cover was paused"),
- "resumeMsg" => t("Reset album cover was resumed"));
- break;
-
- default:
- throw new Exception("Operation '$operation' is not implmented");
- }
+ return $v;
}
}
diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css
index e58cd5a5..85168810 100644
--- a/modules/organize/css/organize.css
+++ b/modules/organize/css/organize.css
@@ -1,81 +1,79 @@
-/* @todo move to theme css */
+
/*******************************************************************
* Dialog wide stylings
*/
-#gMessage {
- margin-bottom: .4em;
+#gOrganizeDialog {
+ text-align: left;
}
-#gMessage .gInfo {
- background-color: transparent;
- background-image: none;
- padding-left: .4em;
+#gOrganize {
+ overflow: hidden;
}
-#gOrganizeProgressDialog {
- text-align: left;
+#gOrganize #bd {
+ height: 100%;
+}
+
+#gOrganize .yui-u {
+ width: 75%;
+}
+
+#gOrganize .yui-gf .first {
+ width: 25%;
}
-#gDialog .yui-gf div.first {
- width: 20%;
+#gOrganize .yui-gf #gMessage {
+ margin-bottom: .4em;
+ width: 75%;
+ white-space: nowrap;
}
-#gDialog .yui-gf .yui-u {
- width: 80%;
+#gOrganizeDetail {
+ height: 100%;
+}
+
+#gMessage .gInfo {
+ font-weight: bold;
+ padding-left: 2em;
}
/*******************************************************************
* Album Tree styling
*/
#gOrganizeTreeContainer {
- overflow-y: auto;
+ height: 100%;
+ overflow: auto;
margin: 0 !important;
padding: 0 !important;
}
-#gOrganizeAlbumDescription {
- height: 2em;
- overflow-y: auto;
+#gOrganizeTreeContainer ul ul li {
+ padding-left: 1.2em;
+}
+
+.gAlbumText:hover {
+ border: 1px dashed #999;
+ padding: 1px;
}
-.gBranchSelected {
+#gOrganizeAlbumTree .selected {
background-color: #cfdeff !important;
border-bottom: 1px solid #999 !important;
display: block;
padding: .3em 0;
}
-.gBranchDroppable {
- border: 1px dotted;
+.gOrganizeAlbum span {
+ cursor: pointer;
}
-.gBranchText {
+.gAlbumText {
cursor: pointer;
width: auto;
}
-
-.gBranchCollapsed {
- display: none;
-}
-
-.gBranchEmpty {
- visibility: hidden;
-}
-
-#gOrganizeTreeContainer ul ul li {
- padding-left: 1.2em;
-}
-
/*******************************************************************
* Album Panel Styles
*/
-
-#gMicroThumbUnselectAll,
-#gMicroThumbSelectAll {
- font-size: 1em;
- font-weight: bold;
-}
-
#gMicroThumbPanel {
margin: 0 !important;
padding: 0 !important;
@@ -83,200 +81,66 @@
border: 1px solid #999 !important;
border-top: none !important;
border-left: none !important;
- margin-left: -1em !important;
overflow-x: hidden;
overflow-y: auto;
}
#gMicroThumbGrid {
- padding: .5em;
+ padding: 1em;
}
-.gMicroThumbContainer {
- display: block;
+.gMicroThumbGridCell {
float: left;
- font-size: .7em;
- height: 9em;
- margin-bottom: 1em;
- margin-left: 1em;
- opacity: .4;
- padding: 0 .5em;
+ font-size: 0.8em;
+ padding: .5em !important;
+ opacity: .5;
+ border-left: 1px hidden #13A;
+ border-right: 1px hidden #13A;
}
.gMicroThumb {
- height: 9em;
- width: 9em;
- background-color: #fff;
display: block;
- float: left;
+ height: 9em;
text-align: center;
+ width: 9em;
}
-#gMicroThumbPanel #gMicroThumbGrid .gAlbum {
- background-color: #e8e8e8;
-}
-
-#gMicroThumbPanel #gMicroThumbGrid :hover {
+.gMicroThumbGridCell.ui-state-selected {
opacity: 1;
}
-.gMicroThumbContainer.ui-selected {
- opacity: 1;
+.ui-selectable-lasso {
+ z-index: 2000 !important;
+ border: 1px dashed #13A;
}
-#gDragHelper .gMicroThumbGrid {
- background-color: transparent;
- padding: 0;
- overflow: visible;
+.gThumbnail {
+ padding: .5em;
}
-#gDragHelper .gMicroThumbContainer {
- display: block;
- margin: 0;
- padding: 0;
+#gMicroThumbPanel #gMicroThumbGrid .gAlbum {
+ background-color: #e8e8e8;
}
-#gDragHelper .gMicroThumb {
- background-color: transparent;
- height: auto;
- width: auto;
+#gMicroThumbPanel #gMicroThumbGrid :hover {
+ opacity: 1;
}
-
/****************************************************************
- * Organize Edit Drawer styling
+ * Organize Controls styling
*/
-#gOrganizeEditDrawer {
+#gOrganizeControls {
+ padding-left: 8px;
background-color: #13A;
- width: 90%;
-}
-
-#gOrganizeEditDrawerPanel {
- background-color: #fff;
- border: 1px solid #13A;
- display: none;
- height: 195px;
-}
-
-#gOrganizeEditDrawerHandle {
- height: 30px;
-}
-
-#gOrganizeEditHandleLeft {
- background-color: #FFF;
- float: left;
- height: 30px;
- width: 15px;
-}
-
-#gOrganizeEditHandleButtonsMiddle,
-#gOrganizeEditHandleButtonsLeft {
- float: left;
- height: 20px;
- padding: 2px 10px;
-}
-
-#gOrganizeEditHandleButtonsMiddle {
- margin-left: 20px;
-}
-
-#gOrganizeEditHandleButtonsMiddle a,
-#gOrganizeEditHandleButtonsLeft a {
- float: left;
- margin: 0 2.5px;
-}
-
-#gOrganizeEditHandleButtonsRight {
- float: right;
- height: 20px;
- padding: 2px 10px;
-}
-
-#gOrganizeEditHandleButtonsRight a {
- float: left;
- margin: 0 2.5px;
-}
-
-#gOrganizeEditHandleRight {
- background-color: #FFF;
- background-position: -15px 0;
- float: right;
- height: 30px;
- width: 15px;
+ color: #ccc;
+ width: 100% !important;
}
-#gOrganizeFormButtons {
- bottom: 0.5em;
-}
-
-#gOrganizeFormButtons .submit {
+#gOrganizeControls select {
display: inline;
- float: none;
- left: 0.5em;
- position: relative;
}
-/* yui-u gives 80% width, but then we wrap so do it ourselves */
-#gOrganizeEditForm {
+#gOrganizeClose {
float: right;
- width: 79%;
- // height: 100px;
-}
-
-#gOrganizeFormThumbs {
- overflow: hidden;
-}
-
-#gOrganizeFormThumbs div {
- margin: 0;
- text-align: center;
- background: transparent none repeat scroll 0 0;
-}
-
-#gOrganizeFormThumbs .gMicroThumbContainer {
- display: block;
- float: left;
- opacity: 1;
- position: absolute;
-}
-
-/****************************************************************
- * Organize Edit From tabs styling
- */
-#gOrganizeEditForm.ui-tabs .ui-tabs-hide {
- display: block !important;
- left: -10000px;
- position: absolute;
-}
-
-#gOrganizeEditForm.ui-widget {
- font-size: .75em;
-}
-
-.gOrganizeEditPane {
- height: 135px;
- overflow-y: auto;
-}
-
-.textbox,
-.textarea {
- border: 1px solid #e8e8e8;
- border-top-color: #ccc;
- border-left-color: #ccc;
- color: #333;
- width: 100%;
-}
-
-.textarea {
- height: 6em;
-}
-
-.textbox {
- height: 1.3em;
- width: 50%
-}
-
-.gTagGroup {
- float:left;
- margin: .5em;
+ margin-right: 12px;
}
diff --git a/modules/organize/helpers/organize.php b/modules/organize/helpers/organize.php
deleted file mode 100644
index 25284771..00000000
--- a/modules/organize/helpers/organize.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 Bharat Mediratta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
- */
-class organize_Core {
- static function get_general_edit_form($item) {
- $generalPane = new Forge("organize/__FUNCTION__", "", "post",
- array("id" => "gEditGeneral", "ref" => "general"));
- // In this case we know there is only 1 item, but in general we should loop
- // and create multiple hidden items.
- $generalPane->hidden("item[]")->value($item->id);
- $generalPane->input("title")->label(t("Title"))->value($item->title);
- $generalPane->textarea("description")->label(t("Description"))->value($item->description);
- $generalPane->input("dirname")->label(t("Path Name"))->value($item->name)
- ->callback("item::validate_no_slashes")
- ->error_messages("no_slashes", t("The directory name can't contain a \"/\""))
- ->callback("item::validate_no_trailing_period")
- ->error_messages("no_trailing_period", t("The directory name can't end in \".\""))
- ->callback("item::validate_no_name_conflict")
- ->error_messages("conflict", t("The path name is not unique"));
-
- return $generalPane;
- }
-
- static function get_sort_edit_form($item) {
- $sortPane = new Forge("organize/__FUNCTION__", "", "post",
- array("id" => "gEditSort", "ref" => "sort"));
- $sortPane->hidden("item[]")->value($item->id);
- $sortPane->dropdown("column", array("id" => "gAlbumSortColumn"))
- ->label(t("Sort by"))
- ->options(array("weight" => t("Order Added"),
- "captured" => t("Capture Date"),
- "created" => t("Creation Date"),
- "title" => t("Title"),
- "updated" => t("Updated Date"),
- "view_count" => t("Number of views"),
- "rand_key" => t("Random")))
- ->selected($item->sort_column);
- $sortPane->dropdown("direction", array("id" => "gAlbumSortDirection"))
- ->label(t("Order"))
- ->options(array("ASC" => t("Ascending"),
- "DESC" => t("Descending")))
- ->selected($item->sort_order);
-
- return $sortPane;
- }
-
- static function get_tag_form($itemids) {
- $tagPane = new Forge("organize/__FUNCTION__", "", "post",
- array("id" => "gEditTags", "ref" => "edit_tags"));
- $tagPane->hidden("item")->value(implode("|", $itemids));
- $item_count = count($itemids);
- $ids = implode(", ", $itemids);
-
- // Lame stopgap security check. This code is going to get rewritten anyway.
- foreach ($itemids as $id) {
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
- }
-
- $tags = Database::instance()->query(
- "SELECT t.name, COUNT(it.item_id) as count
- FROM {items_tags} it, {tags} t
- WHERE it.tag_id = t.id
- AND it.item_id in($ids)
- GROUP BY it.tag_id
- ORDER BY t.name ASC");
- $taglist = array();
- foreach ($tags as $tag) {
- $taglist[] = $tag->name . ($item_count > $tag->count ? "*" : "");
- }
- $taglist = implode("; ", $taglist);
- $tagPane->textarea("tags")->label(t("Tags"))->value($taglist);
-
- return $tagPane;
- }
-
-} \ No newline at end of file
diff --git a/modules/organize/helpers/organize_event.php b/modules/organize/helpers/organize_event.php
index 99a28673..7d6b3e24 100644
--- a/modules/organize/helpers/organize_event.php
+++ b/modules/organize/helpers/organize_event.php
@@ -23,11 +23,11 @@ class organize_event_Core {
if ($item && access::can("edit", $item) && $item->is_album()) {
$menu->get("options_menu")
- ->append(Menu::factory("link")
+ ->append(Menu::factory("dialog")
->id("organize")
->label(t("Organize Album"))
->css_id("gOrganizeLink")
- ->url(url::site("organize/index/{$item->id}")));
+ ->url(url::site("organize/dialog/{$item->id}")));
}
}
}
diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php
deleted file mode 100644
index dc474818..00000000
--- a/modules/organize/helpers/organize_task.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 Bharat Mediratta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
- */
-class organize_task_Core {
- static function available_tasks() {
- // Return empty array so nothing appears in the maintenance screen
- return array();
- }
-
- static function run($task) {
- $context = unserialize($task->context);
- $taskType = $context["type"];
-
- try {
- $target = ORM::factory("item", $context["target"]);
- $total = count($context["items"]);
- $stop = min($total - $context["position"], $context["batch"]);
- $context["post_process"] = array();
- for ($offset = 0; $offset < $stop; $offset++) {
- $current_id = $context["position"] + $offset;
- $id = $context["items"][$current_id];
- switch ($taskType) {
- case "move":
- $source = ORM::factory("item", $id);
- access::required("view", $source);
- access::required("view", $target);
- access::required("edit", $source);
- access::required("edit", $target);
-
- item::move($source, $target);
- break;
-
- case "rearrange":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- Database::instance()
- ->query("Update {items} set weight = {$context["position"]} where id=$id;");
- break;
-
- case "rotateCcw":
- case "rotateCw":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- if ($item->is_photo()) {
- $context["post_process"]["reload"][] =
- self::_do_rotation($item, $taskType == "rotateCcw" ? -90 : 90);
- }
- break;
-
- case "albumCover":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("view", $item->parent());
- access::required("edit", $item->parent());
-
- item::make_album_cover($item);
- break;
-
- case "delete":
- $item = ORM::factory("item", $id);
- access::required("view", $item);
- access::required("edit", $item);
-
- $item->delete();
- $context["post_process"]["remove"][] = array("id" => $id);
- break;
-
- default:
- throw new Exception("Task '$taskType' is not implemented");
- }
- }
- $context["position"] += $stop;
- $task->state = "success";
- } catch(Exception $e) {
- $task->status = $e->getMessage();
- $task->state = "error";
- $task->save();
- throw $e;
- }
- $task->context = serialize($context);
- $total = count($context["items"]);
- $task->percent_complete = $context["position"] / (float)$total * 100;
- $task->done = $context["position"] == $total || $task->state == "error";
- }
-
- private static function _do_rotation($item, $degrees) {
- // This code is copied from Quick_Controller::rotate
- graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees));
-
- list($item->width, $item->height) = getimagesize($item->file_path());
- $item->resize_dirty= 1;
- $item->thumb_dirty= 1;
- $item->save();
-
- graphics::generate($item);
-
- $parent = $item->parent();
- if ($parent->album_cover_item_id == $item->id) {
- copy($item->thumb_path(), $parent->thumb_path());
- $parent->thumb_width = $item->thumb_width;
- $parent->thumb_height = $item->thumb_height;
- $parent->save();
- }
- list ($height, $width) = $item->scale_dimensions(90);
- $margin_top = (90 - $height) / 20;
-
- return array("src" => $item->thumb_url() . "?rnd=" . rand(),
- "id" => $item->id,
- "marginTop" => "{$margin_top}em", "width" => $width, "height" => $height);
- }
-} \ No newline at end of file
diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php
index e4feba2b..61b6fe7d 100644
--- a/modules/organize/helpers/organize_theme.php
+++ b/modules/organize/helpers/organize_theme.php
@@ -19,9 +19,14 @@
*/
class organize_theme {
static function head($theme) {
- // @tdo remove the addition css and organize.js (just here to test)
- $theme->script("organize_init.js");
- $theme->script("organize.js");
- $theme->css("organize.css");
+ $item = $theme->item();
+ if ($item && access::can("edit", $item) && $item->is_album()) {
+ // @todo: Defer loading js/css until we're loading the organize dialog as <script> and
+ // <link> elements so that we're not forcing them to be downloaded on every page view (which
+ // is expensive in terms of browser latency). When we do that, we'll have to figure out an
+ // approach that lets us continue to use the Kohana cascading filesystem.
+ $theme->script("organize.js");
+ $theme->css("organize.css");
+ }
}
}
diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js
index f10cbcc9..04e14a2f 100644
--- a/modules/organize/js/organize.js
+++ b/modules/organize/js/organize.js
@@ -1,621 +1,210 @@
-/*
- * @todo Trap resize of dialog and resize the child areas (tree, grid and edit form)
- */
-var url;
-var paused = false;
-var task = null;
-var transitItems = [];
-var heightMicroThumbPanel;
-
-// **************************************************************************
-// JQuery UI Widgets
-// Draggable
-var draggable = {
- handle: ".gMicroThumbContainer.ui-selected",
- revert: true,
- zindex: 2000,
- distance: 10,
- helper: function(event, ui) {
- if (!$(event.currentTarget).hasClass("ui-selected")) {
- $(event.currentTarget).addClass("ui-selected");
- setDrawerButtonState();
- }
- $("#gMicroThumbPanel").append("<div id=\"gDragHelper\"><ul></ul></div>");
- var beginTop = event.pageY;
- var beginLeft = event.pageX;
- var zindex = $(".gMicroThumbContainer").draggable("option", "zindex");
- $("#gDragHelper").css('top', event.pageY - 22.5);
- $("#gDragHelper").css('left', event.pageX + 22.5);
- var placeHolder = $(this).clone();
- $(placeHolder).attr("id", "gPlaceHolder");
- $(placeHolder).css("visibility", "hidden");
- $(placeHolder).removeClass("ui-selected");
- $(placeHolder).removeClass("ui-draggable");
- $(this).after(placeHolder);
+(function($) {
+ $.organize = {
+ micro_thumb_draggable: {
+ handle: ".ui-state-selected",
+ distance: 10,
+ cursorAt: { left: -10, top: -10},
+ appendTo: "#gMicroThumbPanel",
+ helper: function(event, ui) {
+ var selected = $(".ui-draggable.ui-state-selected img");
+ if (selected.length) {
+ var set = $('<div class="gDragHelper"></div>')
+ .css({
+ zIndex: 2000,
+ width: 80,
+ height: Math.ceil(selected.length / 5) * 16
+ });
+ var offset = $(this).offset();
+ var click = {left: event.pageX - offset.left, top: event.pageY - offset.top};
+
+ selected.each(function(i) {
+ var row = parseInt(i / 5);
+ var j = i - (row * 5);
+ var o = $(this).offset();
+ var copy = $(this).clone()
+ .css({
+ width: $(this).width(), height: $(this).height(), display: "block",
+ margin: 0, position: 'absolute', outline: '5px solid #fff',
+ left: o.left - event.pageX, top: o.top - event.pageY
+ })
+ .appendTo(set)
+ .animate({ width: 10, height: 10, outlineWidth: 1, margin: 1,
+ left: (20 * j), top: (row * 20) }, 500);
+ });
+ return set;
+ }
+ return null;
+ },
- $("li.ui-selected").each(function(i) {
- var clone = $(this).clone();
- $(clone).attr("id", "drag_clone_" + $(this).attr("ref"));
- $("#gDragHelper ul").append(clone);
- $(clone).css("position", "absolute");
- $(clone).css("top", beginTop);
- $(clone).css("left", beginLeft);
- $(clone).css("z-index", zindex--);
- $(this).hide();
+ start: function(event, ui) {
+ $("#gMicroThumbPanel .ui-state-selected").hide();
+ },
- var children = $(clone).find(".gMicroThumb .gThumbnail");
- var width = new String(children.css("width")).replace(/[^0-9]/g,"") * .5;
- var height = new String(children.css("height")).replace(/[^0-9]/g,"") * .5;
- var marginTop = new String(children.css("margin-top")).replace(/[^\.0-9]/g,"") * .5;
- children.attr("width", width);
- children.attr("height", height);
- children.css("margin-top", marginTop);
- if (i < 9) {
- beginTop -= 5;
- beginLeft += 5;
+ drag: function(event, ui) {
+ var top = $("#gMicroThumbPanel").offset().top;
+ var height = $("#gMicroThumbPanel").height();
+ if (ui.offset.top > height + top - 20) {
+ $("#gMicroThumbPanel").get(0).scrollTop += 100;
+ } else if (ui.offset.top < top + 20) {
+ $("#gMicroThumbPanel").get(0).scrollTop = Math.max(0, $("#gMicroThumbPanel").get(0).scrollTop - 100);
+ }
}
- });
- return $("#gDragHelper");
- },
- stop: function(event, ui) {
- $("#gDragHelper li").each(function(i) {
- $("#thumb_" + $(this).attr("ref")).show();
- });
- $(".gMicroThumbContainer.ui-selected").css("z-index", null);
- $("#gDragHelper").remove();
- $("#gPlaceHolder").remove();
- }
-};
-
-// Thumbnail Grid Droppable
-var thumbDroppable = {
- tolerance: "pointer",
- over: function(event, ui) {
- $("#gPlaceHolder").show();
- },
- out: function(event, ui) {
- $("#gPlaceHolder").hide();
- },
- drop: function(event, ui) {
- $("#gDragHelper").hide();
- $("#gPlaceHolder").hide();
- var newOrder = "";
- $("#gMicroThumbGrid .gMicroThumbContainer").each(function(i) {
- if ($(this).attr("id") == "gPlaceHolder") {
- $("#gDragHelper li").each(function(i) {
- newOrder += "&item[]=" + $(this).attr("ref");
+ },
+
+ content_droppable: {
+ accept: "*",
+ tolerance: "pointer",
+ greedy: true,
+ drop: function(event, ui) {
+ var before_or_after = $(".currentDropTarget").css("borderLeftStyle") == "solid" ? "before" : "after";
+ $.organize.do_drop({
+ url: rearrange_url
+ .replace("__TARGET_ID__", $(".currentDropTarget").attr("ref"))
+ .replace("__ALBUM_ID__", $(".currentDropTarget").attr("ref"))
+ .replace("__BEFORE__", before_or_after),
+ source: $(ui.helper).children("img")
});
- } else if ($(this).css("display") != "none") {
- newOrder += "&item[]=" + $(this).attr("ref");
- } else {
- // If its not displayed then its one of the ones being moved so ignore.
}
- });
- $("#gDragHelper li").each(function(i) {
- $("#gPlaceHolder").before($("#thumb_" + $(this).attr("ref")).show());
- });
- $.ajax({
- data: newOrder,
- dataType: "json",
- success: operationCallback,
- type: "POST",
- url: get_organize_url("organize/startTask/rearrange", {item_id: item_id})
- });
- }
-};
-
-// Album Tree Droppable
-var treeDroppable = {
- tolerance: "pointer",
- greedy: true,
- hoverClass: "gBranchDroppable",
- drop: function(event, ui) {
- $("#gDragHelper").hide();
- var targetItemId = $(this).attr("ref");
- if ($(this).hasClass("gBranchSelected")) {
- $("#gMessage").empty().append(INVALID_DROP_TARGET);
- ui.draggable.trigger("stop", event);
- return false;
- }
- var postData = serializeItemIds("#gDragHelper li");
- var okToMove = true;
- $("#gDragHelper li").each(function(i) {
- okToMove &= targetItemId != $(this).attr("ref");
- });
- if (!okToMove) {
- $("#gMessage").empty().append(INVALID_DROP_TARGET);
- ui.draggable.trigger("stop", event);
- return false;
- }
- $("#gDragHelper li").each(function(i) {
- $("#thumb_" + $(this).attr("ref")).remove();
- });
- $.ajax({
- data: postData,
- dataType: "json",
- success: operationCallback,
- type: "POST",
- url: get_organize_url("organize/startTask/move", {item_id: targetItemId})
- });
- return true;
- }
-};
-
-// Selectable
-var selectable = {
- filter: ".gMicroThumbContainer",
- selected: function(event, ui) {
- setDrawerButtonState();
- },
- unselected: function(event, ui) {
- setDrawerButtonState();
- },
- stop: function(event, ui) {
- getEditForm();
- }
-};
-
-// **************************************************************************
-// Event Handlers
-// MicroThumbContainer mouseup
-var onMicroThumbContainerMouseup = function(event) {
- // For simplicity always remove the ui-selected class. If it was unselected
- // it will get added back
- $(this).toggleClass("ui-selected");
-
- setDrawerButtonState();
- if ($("#gMicroThumbGrid li.ui-selected").length > 0) {
- getEditForm();
- }
-};
-
-// MicroThumbContainer mousemove
-var onMicroThumbContainerMousemove = function(event) {
- if ($("#gDragHelper").length > 0 && $(this).attr("id") != "gPlaceHolder") {
- if (event.pageX < $(this).offset().left + $(this).width() / 2) {
- $(this).before($("#gPlaceHolder"));
- } else {
- $(this).after($("#gPlaceHolder"));
- }
- var container = $("#gMicroThumbPanel").get(0);
- var scrollHeight = container.scrollHeight;
- var scrollTop = container.scrollTop;
- var height = $(container).height();
- if (event.pageY > height + scrollTop) {
- container.scrollTop = this.offsetTop;
- } else if (event.pageY < scrollTop) {
- container.scrollTop -= height;
- }
- }
-};
-
-// Handle click events on the buttons on the drawer handle
-function drawerHandleButtonsClick(event) {
- event.preventDefault();
- if (!$(this).attr("disabled")) {
- var operation = $(this).attr("ref");
- switch (operation) {
- case "edit":
- case "close":
- $("#gOrganizeEditDrawerPanel").animate(
- {"height": "toggle", "display": "block"},
- {duration: "fast",
- complete: function() {
- setSelectedThumbs();
- if (operation == "close") {
- $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "inline-block");
- $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "none");
- $("#gOrganizeEditHandleButtonsMiddle a").css("display", "none");
- } else {
- $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "none");
- $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "inline-block");
- $("#gOrganizeEditHandleButtonsMiddle a").css("display", "inline-block");
- }
- },
- step: function() {
- $("#gMicroThumbPanel").height(heightMicroThumbPanel - $(this).height());
- }
- });
- break;
- case "select-all":
- $("#gMicroThumbGrid li").addClass("ui-selected");
- $("#gMicroThumbSelectAll").hide();
- $("#gMicroThumbUnselectAll").show();
- setDrawerButtonState();
- getEditForm();
- break;
- case "unselect-all":
- $("#gMicroThumbGrid li").removeClass("ui-selected");
- $("#gMicroThumbSelectAll").show();
- $("#gMicroThumbUnselectAll").hide();
- setDrawerButtonState();
- break;
- case "done":
- $("#gDialog").dialog("close");
- break;
- case "submit":
- var currentTab = $("#gOrganizeEditForm").tabs("option", "selected");
- var form = $("#pane-"+currentTab+" form");
- var url = $(form).attr("action")
- .replace("__FUNCTION__", $(form).attr("ref"));
- $.ajax({
- data: $(form).serialize(),
- dataType: "json",
- success: function (data, textStatus) {
- $("#pane-"+currentTab).children("form").replaceWith(data.form);
- if (data.message) {
- $("#gMessage").empty().append("<div class='gSuccess'>" + data.message + "</div>");
- }
- },
- type: "POST",
- url: url
- });
- break;
- case "reset":
- currentTab = $("#gOrganizeEditForm").tabs("option", "selected");
- form = $("#pane-"+currentTab+" form");
- $.ajax({
- data: serializeItemIds("#gMicroThumbPanel li.ui-selected"),
- dataType: "html",
- success: function (data, textStatus) {
- $("#pane-"+currentTab + " form").replaceWith(data);
- },
- type: "GET",
- url: $(form).attr("action").replace("__FUNCTION__", "reset_" + $(form).attr("ref"))
- });
- break;
- case "delete":
- if (!confirm(CONFIRM_DELETE)) {
- break;
- }
- default:
- $.ajax({
- data: serializeItemIds("#gMicroThumbPanel li.ui-selected"),
- dataType: "json",
- success: operationCallback,
- type: "POST",
- url: get_organize_url("organize/startTask/" + operation, {item_id: item_id})
- });
- break;
- }
- }
-};
-
-// **************************************************************************
-// AJAX Callbacks
-// MicroThumbContainer click
-var getMicroThumbsCallback = function(json, textStatus) {
- if (json.count > 0) {
- $("#gMicroThumbGrid").append(json.data);
- retrieveMicroThumbs();
- $(".gMicroThumbContainer").mouseup(onMicroThumbContainerMouseup);
- $(".gMicroThumbContainer").mousemove(onMicroThumbContainerMousemove);
- $(".gMicroThumbContainer").draggable(draggable);
- }
-};
-
-var operationCallback = function (data, textStatus) {
- var done = false;
- if (!paused) {
- createProgressDialog(data.runningMsg);
- task = data.task;
- task.pauseMsg = data.pauseMsg;
- task.resumeMsg = data.resumeMsg;
- done = data.task.done;
- }
- $(".gMicroThumbContainer").draggable("disable");
- paused = false;
- while (!done && !paused) {
- $.ajax({async: false,
- success: function(data, textStatus) {
- $(".gProgressBar").progressbar("value", data.task.percent_complete);
- done = data.task.done;
- if (data.task.post_process.reload) {
- $.each(data.task.post_process.reload, function() {
- var selector = "#gMicroThumb-" + this.id + " img";
- $(selector).attr("height", this.height);
- $(selector).attr("width", this.width);
- $(selector).attr("src", this.src);
- $(selector).css("margin-top", this.marginTop);
- });
- }
- if (data.task.post_process.remove) {
- $.each(data.task.post_process.remove, function() {
- $("#thumb_" + this.id).remove();
+ },
+
+ branch_droppable: {
+ accept: "*",
+ tolerance: "pointer",
+ greedy: true,
+ drop: function(event, ui) {
+ if ($(event.target).hasClass("gViewOnly")) {
+ $(".ui-state-selected").show();
+ $(".gMicroThumbGridCell").css("borderStyle", "none");
+ } else {
+ $.organize.do_drop({
+ url: move_url.replace("__ALBUM_ID__", $(event.target).attr("ref")),
+ source: $(ui.helper).children("img")
});
}
- },
- error: function(XMLHttpRequest, textStatus, errorThrown) {
- paused = true;
- displayAjaxError(XMLHttpRequest.responseText);
- },
- dataType: "json",
- type: "POST",
- url: get_organize_url("organize/runTask", {task_id: task.id})
- });
- }
- if (!paused) {
- $("#gOrganizeProgressDialog").dialog("destroy").remove();
- $.ajax({async: false,
- success: function(data, textStatus) {
- setDrawerButtonState();
- task = null;
- $("#gMessage").empty().append("<div class='gSuccess'>" + data.task.status + "</div>");
- },
- dataType: "json",
- type: "POST",
- url: get_organize_url("organize/finishTask", {task_id: task.id})
- });
- }
- $(".gMicroThumbContainer").draggable("enable");
-};
-
-// **************************************************************************
-
-/**
- * Dynamically initialize the organize dialog when it is displayed
- */
-function organize_dialog_init() {
- var size = getViewportSize();
- heightMicroThumbPanel = size.height() - 100;
- var width = size.width() - 100;
-
- // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475
- $(".sf-menu li.sfHover ul").css("z-index", 70);
-
- $("#gDialog").dialog("option", "width", width);
- $("#gDialog").dialog("option", "height", heightMicroThumbPanel);
-
- $("#gDialog").dialog("open");
- if ($("#gDialog h1").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html());
- } else if ($("#gDialog fieldset legend").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html());
- }
-
- $("#gDialog").bind("organize_close", function(target) {
- document.location.reload();
- });
-
- heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-top"));
- heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-bottom"));
- heightMicroThumbPanel -= $("#gMicroThumbPanel").position().top;
- heightMicroThumbPanel -= $("#gDialog #ft").height();
- heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").height();
- heightMicroThumbPanel = Math.round(heightMicroThumbPanel);
-
- $("#gMicroThumbPanel").height(heightMicroThumbPanel);
- $("#gOrganizeTreeContainer").height(heightMicroThumbPanel);
-
- $(".gOrganizeBranch .ui-icon").click(organizeToggleChildren);
- $(".gBranchText").droppable(treeDroppable);
- $(".gBranchText").click(organizeOpenFolder);
- retrieveMicroThumbs(item_id);
- //showLoading("#gDialog");
-
- $("#gMicroThumbPanel").droppable(thumbDroppable);
- $("#gMicroThumbPanel").selectable(selectable);
- $("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick);
-}
-
-function retrieveMicroThumbs() {
- var offset = $("#gMicroThumbGrid li").length;
- if (url == null) {
- var grid_width = $("#gMicroThumbPanel").width();
- url = $("#gMicroThumbPanel").attr("ref");
- url = url.replace("__WIDTH__", grid_width);
- url = url.replace("__HEIGHT__", heightMicroThumbPanel);
- }
- var url_data = url.replace("__OFFSET__", offset);
- url_data = url_data.replace("__ITEM_ID__", item_id);
- $.getJSON(url_data, getMicroThumbsCallback);
-}
-
-function organizeToggleChildren(event) {
- var id = $(this).attr("ref");
- var span_children = $("#gOrganizeChildren-" + id);
- if ($(this).hasClass("ui-icon-plus")) {
- $(this).removeClass("ui-icon-plus");
- $(this).addClass("ui-icon-minus");
- $("#gOrganizeChildren-" + id).removeClass("gBranchCollapsed");
- } else {
- $(this).removeClass("ui-icon-minus");
- $(this).addClass("ui-icon-plus");
- $("#gOrganizeChildren-" + id).addClass("gBranchCollapsed");
- }
- event.preventDefault();
-}
-
-function organizeOpenFolder(event) {
- var selected = $(".gBranchSelected");
- if ($(selected).attr("id") != $(this).attr("id")) {
- $(selected).removeClass("gBranchSelected");
- $(this).addClass("gBranchSelected");
- item_id = $(this).attr("ref");
- $("#gMicroThumbGrid").empty();
- retrieveMicroThumbs();
- }
- event.preventDefault();
-}
-
-function get_organize_url(uri, parms) {
- var url = rearrangeUrl;
- url = url.replace("__URI__", uri);
- url = url.replace("__ITEM_ID__", !parms.item_id ? "" : parms.item_id);
- url += (parms.item_id && parms.task_id) ? "/" : "";
- url = url.replace("__TASK_ID__", !parms.task_id ? "" : parms.task_id);
- return url;
-}
-
-/**
- * Set the enabled/disabled state of the buttons. The album cover is only enabled if
- * there is only 1 image selected
- */
-function setDrawerButtonState() {
- $("#gOrganizeFormThumbStack").empty();
- $("#gOrganizeEditForm").empty();
- var selectedCount = $("#gMicroThumbGrid li.ui-selected").length;
- if (selectedCount) {
- $("#gOrganizeEditHandleButtonsLeft a").removeAttr("disabled");
- $("#gOrganizeEditHandleButtonsLeft a").removeClass("ui-state-disabled");
-
- if (selectedCount > 1) {
- $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").attr("disabled", true);
- $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").addClass("ui-state-disabled");
- }
- setSelectedThumbs();
- } else {
- if ($("#gOrganizeEditDrawerPanel::visible").length) {
- $("#gOrganizeEditHandleButtonsLeft a[ref='close']").trigger("click");
- }
- $("#gOrganizeEditHandleButtonsLeft a").attr("disabled", true);
- $("#gOrganizeEditHandleButtonsLeft a").addClass("ui-state-disabled");
- }
-}
+ }
+ },
-function setSelectedThumbs() {
- if (!$("#gOrganizeEditDrawerPanel::visible").length) {
- return;
- }
- var position = $("#gOrganizeFormThumbStack").position();
- var beginLeft = position.left;
- var beginTop = 50;
- var zindex = 2000;
- $("li.ui-selected").each(function(i) {
- var clone = $(this).clone();
- $(clone).attr("id", "edit_clone_" + $(this).attr("ref"));
- $("#gOrganizeFormThumbStack").append(clone);
- $(clone).removeClass("ui-draggable");
- $(clone).removeClass("ui-selected");
- $(clone).css("margin-top", beginTop);
- $(clone).css("left", beginLeft);
- $(clone).css("z-index", zindex--);
+ do_drop: function(options) {
+ $("#gMicroThumbPanel").selectable("destroy");
+ var source_ids = [];
+ $(options.source).each(function(i) {
+ source_ids.push($(this).attr("ref"));
+ });
- if (i < 9) {
- beginTop -= 5;
- beginLeft += 5;
- }
- });
-}
+ if (source_ids.length) {
+ $.post(options.url,
+ { "source_ids[]": source_ids },
+ function(data) { $.organize._refresh(data); },
+ "json");
+ }
+ },
-function getEditForm() {
- if ($("#gMicroThumbGrid li.ui-selected").length > 0) {
- var postData = serializeItemIds("li.ui-selected");
- var url_data = get_organize_url("organize/editForm", {}) + postData;
- $.get(url_data, function(data, textStatus) {
- $("#gOrganizeEditForm").tabs("destroy");
- $("#gOrganizeEditForm").html(data);
- if ($("#gOrganizeEditForm ul li").length) {
- $("#gOrganizeEditForm").tabs();
- $("#gOrganizeEditHandleButtonsMiddle a").removeAttr("disabled");
- $("#gOrganizeEditHandleButtonsMiddle a").removeClass("ui-state-disabled");
- } else {
- $("#gOrganizeEditHandleButtonsMiddle a").attr("disabled", true);
- $("#gOrganizeEditHandleButtonsMiddle a").addClass("ui-state-disabled");
+ _refresh: function(data) {
+ if (data.tree) {
+ $("#gOrganizeAlbumTree").html(data.tree);
}
- });
- } else {
- $("#gOrganizeEditForm").tabs("destroy");
- $("#gOrganizeEditForm").empty();
- }
-}
+ if (data.grid) {
+ $("#gMicroThumbGrid").html(data.grid);
+ $("#gOrganizeSortColumn").attr("value", data.sort_column);
+ $("#gOrganizeSortOrder").attr("value", data.sort_order);
+ }
+ $.organize.set_handlers();
+ },
+
+ mouse_move_handler: function(event) {
+ if ($(".gDragHelper").length) {
+ $(".gMicroThumbGridCell").css("borderStyle", "hidden");
+ $(".currentDropTarget").removeClass("currentDropTarget");
+ var borderStyle = event.pageX < $(this).offset().left + $(this).width() / 2 ?
+ "borderLeftStyle" : "borderRightStyle";
+ $(this).css(borderStyle, "solid");
+ $(this).addClass("currentDropTarget");
+ }
+ },
+
+ /**
+ * Dynamically initialize the organize dialog when it is displayed
+ */
+ init: function(data) {
+ var self = this;
+ // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 (target 1.8?)
+ $(".sf-menu li.sfHover ul").css("z-index", 68);
+ $("#gDialog").dialog("option", "zIndex", 70);
+ $("#gDialog").bind("dialogopen", function(event, ui) {
+ $("#gOrganize").height($("#gDialog").innerHeight() - 20);
+ $("#gMicroThumbPanel").height($("#gDialog").innerHeight() - 90);
+ $("#gOrganizeAlbumTree").height($("#gDialog").innerHeight() - 59);
+ });
-function serializeItemIds(selector) {
- var postData = "";
- $(selector).each(function(i) {
- postData += "&item[]=" + $(this).attr("ref");
- });
+ $("#gDialog").bind("dialogclose", function(event, ui) {
+ window.location.reload();
+ });
- return postData;
-}
+ $("#gDialog #gOrganizeClose").click(function(event) {
+ $("#gDialog").dialog("close");
+ });
-function submitCurrentForm(event) {
- console.log("submitCurrentForm");
- return false;
-}
+ $("#gOrganizeSortColumn,#gOrganizeSortOrder").change(function(event) {
+ $.organize.resort($("#gOrganizeSortColumn").attr("value"), $("#gOrganizeSortOrder").attr("value"));
+ });
-function resetCurrentForm(event) {
- console.log("resetCurrentForm");
- return false;
-}
+ $.organize.set_handlers();
+ },
-function createProgressDialog(title) {
- $("body").append("<div id='gOrganizeProgressDialog'>" +
- "<div class='gProgressBar'></div>" +
- "<button id='gOrganizeTaskPause' class='ui-state-default ui-corner-all'>" + PAUSE_BUTTON + "</button>" +
- "<button id='gOrganizeTaskResume' class='ui-state-default ui-corner-all' style='display: none'>" + RESUME_BUTTON + "</button>" +
- "<button id='gOrganizeTaskCancel' class='ui-state-default ui-corner-all' style='display: none'>" + CANCEL_BUTTON + "</button>" +
- "</div>");
- $("#gOrganizeProgressDialog").dialog({
- autoOpen: true,
- autoResize: false,
- modal: true,
- resizable: false,
- title: title
- });
+ set_handlers: function() {
+ $("#gMicroThumbPanel").selectable({filter: ".gMicroThumbGridCell"});
+ $("#gMicroThumbPanel").droppable($.organize.content_droppable);
- $(".gProgressBar").progressbar();
- $("#gOrganizeTaskPause").click(function(event) {
- paused = true;
- $("#gOrganizeTaskPause").hide();
- $("#gOrganizeTaskResume").show();
- $("#gOrganizeTaskCancel").show();
- $("#gMessage").empty().append(task.pauseMsg);
- });
- $("#gOrganizeTaskResume").click(function(event) {
- $("#gOrganizeTaskPause").show();
- $("#gOrganizeTaskResume").hide();
- $("#gOrganizeTaskCancel").hide();
- $("#gMessage").empty().append(task.resumeMsg);
- operationCallback();
- //startRearrangeCallback();
- });
- $("#gOrganizeTaskCancel").click(function(event) {
- $("#gOrganizeTaskPause").show();
- $("#gOrganizeTaskResume").hide();
- $("#gOrganizeTaskCancel").hide();
+ $(".gMicroThumbGridCell").draggable($.organize.micro_thumb_draggable);
+ $(".gMicroThumbGridCell").mousemove($.organize.mouse_move_handler);
+ $(".gOrganizeAlbum").droppable($.organize.branch_droppable);
+ $(".gAlbumText").click($.organize.show_album);
+ },
- $.ajax({async: false,
- success: function(data, textStatus) {
- task = null;
- paused = false;
- transitItems = [];
- $("#gMessage").empty().append("<div class='gWarning'>" + data.task.status + "</div>");
- $("#gOrganizeProgressDialog").dialog("destroy").remove();
- },
- dataType: "json",
- type: "POST",
- url: get_organize_url("organize/cancelTask", {task_id: task.id})
- });
- });
-}
-// **************************************************************************
-// Functions that should probably be in a gallery namespace
-function getViewportSize() {
- return {
- width : function() {
- return window.innerWidth
- || document.documentElement && document.documentElement.clientWidth
- || document.body.clientWidth;
- },
- height : function() {
- return window.innerHeight
- || document.documentElement && document.documentElement.clientHeight
- || document.body.clientHeight;
+ /**
+ * When the text of a selection is clicked, then show that albums contents
+ */
+ show_album: function(event) {
+ event.preventDefault();
+ if ($(event.currentTarget).hasClass("selected")) {
+ return;
}
+ var parent = $(event.currentTarget).parents(".gOrganizeBranch");
+ if ($(parent).hasClass("gViewOnly")) {
+ return;
+ }
+ $("#gMicroThumbPanel").selectable("destroy");
+ var id = $(event.currentTarget).attr("ref");
+ $("#gOrganizeAlbumTree .selected").removeClass("selected");
+ $(".gAlbumText[ref=" + id + "]").addClass("selected");
+ var url = $("#gMicroThumbPanel").attr("ref").replace("__ITEM_ID__", id).replace("__OFFSET__", 0);
+ $.get(url, {},
+ function(data) {
+ $("#gMicroThumbGrid").html(data.grid);
+ $("#gOrganizeSortColumn").attr("value", data.sort_column);
+ $("#gOrganizeSortOrder").attr("value", data.sort_order);
+ $.organize.set_handlers();
+ },
+ "json");
+ },
+
+ /**
+ * Change the sort order.
+ */
+ resort: function(column, dir) {
+ var url = sort_order_url
+ .replace("__ALBUM_ID__", $("#gOrganizeAlbumTree .selected").attr("ref"))
+ .replace("__COL__", column)
+ .replace("__DIR__", dir);
+ $.get(url, {},
+ function(data) {
+ $("#gMicroThumbGrid").html(data.grid);
+ $("#gOrganizeSortColumn").attr("value", data.sort_column);
+ $("#gOrganizeSortOrder").attr("value", data.sort_order);
+ $.organize.set_handlers();
+ },
+ "json");
+ }
};
-}
-
-function displayAjaxError(error) {
- $("body").append("<div id=\"gAjaxError\" title=\"" + FATAL_ERROR + "\">" + error + "</div>");
-
- $("#gAjaxError").dialog({
- autoOpen: true,
- autoResize: false,
- modal: true,
- resizable: true,
- width: 610,
- height: $("#gDialog").height()
- });
-}
+})(jQuery);
diff --git a/modules/organize/js/organize_init.js b/modules/organize/js/organize_init.js
deleted file mode 100644
index ed036fdb..00000000
--- a/modules/organize/js/organize_init.js
+++ /dev/null
@@ -1,29 +0,0 @@
-$("document").ready(function() {
- $("#gOrganizeLink").click(function(event) {
- event.preventDefault();
- var href = event.target.href;
-
- $("body").append('<div id="gDialog"></div>');
-
- $("#gDialog").dialog({
- autoOpen: false,
- autoResize: false,
- modal: true,
- resizable: false,
- close: function () {
- $("#gDialog").trigger("organize_close");
- $("#gDialog").dialog("destroy").remove();
- },
- zIndex: 75
- });
-
- //showLoading("#gDialog");
-
- $.get(href, function(data) {
- $("#gDialog").html(data);
- });
- return false;
- });
-});
-
-
diff --git a/modules/organize/views/organize.html.php b/modules/organize/views/organize.html.php
deleted file mode 100644
index d2f0aa8c..00000000
--- a/modules/organize/views/organize.html.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<!-- ?= html::script("modules/organize/js/organize.js") ? -->
-<script>
- var FATAL_ERROR = "<?= t("Fatal Error")->for_js() ?>";
- var PAUSE_BUTTON = "<?= t("Pause")->for_js() ?>";
- var RESUME_BUTTON = "<?= t("Resume"->for_js()) ?>";
- var CANCEL_BUTTON = "<?= t("Cancel")->for_js() ?>";
- var INVALID_DROP_TARGET = "<div class=\"gError\"><?= t("Drop cancelled as it would result in a recursive move")->for_js() ?></div>";
-var CONFIRM_DELETE = "<?= t("Do you really want to delete the selected albums and/or photos")->for_js() ?>"
- var item_id = <?= $item->id ?>;
-
- var csrf = <?= json_encode($csrf) ?>;
- var rearrangeUrl = "<?= url::site("__URI__/__ITEM_ID____TASK_ID__?csrf=$csrf")->for_js() ?>";
- $("#doc3").ready(function() {
- organize_dialog_init();
- });
-</script>
-<fieldset style="display: none">
- <legend><?= t("Organize %name", array("name" => SafeString::purify($item->title))) ?></legend>
-</fieldset>
-<div id="doc3" class="yui-t7">
- <div id="bd">
- <div class="yui-gf">
- <div class="yui-u first">
- <h3><?= t("Albums") ?></h3>
- </div>
- <div id="gMessage" class="yui-u">
- <div class="gInfo"><?= t("Select one or more items to edit; drag and drop items to re-order or move between albums") ?></div>
- </div>
- </div>
- <div class="yui-gf">
- <div id="gOrganizeTreeContainer" class="yui-u first">
- <?= $album_tree ?>
- </div>
- <div id="gMicroThumbPanel" class="yui-u"
- ref="<?= url::site("organize/content/__ITEM_ID__?width=__WIDTH__&amp;height=__HEIGHT__&amp;offset=__OFFSET__") ?>">
- <ul id="gMicroThumbGrid"></ul>
- </div>
- <div id="gOrganizeEditDrawer" class="yui-u">
- <div id="gOrganizeEditDrawerPanel" class="yui-gf">
- <div id="gOrganizeFormThumbs" class="yui-u first">
- <ul id="gOrganizeFormThumbStack" />
- </div>
- <div id="gOrganizeEditForm">
- </div>
- </div>
- <div id="gOrganizeEditDrawerHandle">
- <?= $button_pane ?>
- </div>
- </div>
- </div>
- </div>
-</div>
diff --git a/modules/organize/views/organize_album.html.php b/modules/organize/views/organize_album.html.php
deleted file mode 100644
index 4933ed32..00000000
--- a/modules/organize/views/organize_album.html.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<ul>
- <li class="gOrganizeBranch ui-icon-left" ref="<?= $album->id ?>">
- <span id="gOrganizeIcon-<?= $album->id ?>" ref="<?= $album->id ?>"
- class="ui-icon <?= $album_icon ?> <?= $album_icon ? "" : "gBranchEmpty" ?>">
- </span>
-
- <div id="gOrganizeBranch-<?= $album->id ?>" ref="<?= $album->id ?>"
- class="<?= $selected ? "gBranchSelected" : "" ?> gBranchText">
- <?= SafeString::of($album->title) ?>
- </div>
- <div id="gOrganizeChildren-<?= $album->id ?>"
- class="<?= $album_icon == "ui-icon-plus" ? "gBranchCollapsed" : "" ?>">
- <?= $children ?>
- <div>
- </li>
-</ul>
diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php
deleted file mode 100644
index c5839a44..00000000
--- a/modules/organize/views/organize_button_pane.html.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="gOrganizeEditHandleButtonsLeft">
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="edit"
- disabled="1" title="<?= t("Open Drawer") ?>">
- <span class="ui-icon ui-icon-arrowthickstop-1-n"><?= t("Open Drawer") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="close"
- disabled="1" title="<?= t("Close Drawer") ?>" style="display: none">
- <span class="ui-icon ui-icon-arrowthickstop-1-s"><?= t("Close Drawer") ?></span>
- </a>
-
- <? if (graphics::can("rotate")): ?>
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="rotateCcw"
- disabled="1" title="<?= t("Rotate 90 degrees counter clockwise") ?>">
- <span class="ui-icon ui-icon-rotate-ccw"><?= t("Rotate 90 degrees counter clockwise") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="rotateCw"
- disabled="1" title="<?= t("Rotate 90 degrees clockwise") ?>">
- <span class="ui-icon ui-icon-rotate-cw"> <?= t("Rotate 90 degrees clockwise") ?></span>
- </a>
- <? endif ?>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="albumCover"
- disabled="1" title="<?= t("Choose this photo as the album cover") ?>">
- <span class="ui-icon ui-icon-star"><?= t("Choose this photo as the album cover") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default ui-state-disabled" href="#" ref="delete"
- disabled="1" title="<?= t("Delete selection") ?>">
- <span class="ui-icon ui-icon-trash"><?= t("Delete selection") ?></span>
- </a>
-</div>
-<div id="gOrganizeEditHandleButtonsMiddle">
- <a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="submit"
- title="<?= t("Apply Changes") ?>" style="display: none" >
- <span class="ui-icon ui-icon-check"><?= t("Apply Changes") ?></span>
- </a>
-
- <a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="reset"
- title="<?= t("Reset Form") ?>" style="display: none" >
- <span class="ui-icon ui-icon-closethick"><?= t("Reset Form") ?></span>
- </a>
-</div>
-<div id="gOrganizeEditHandleButtonsRight">
- <a id="gMicroThumbSelectAll" href="#" ref="select-all" class="gButtonLink ui-corner-all ui-state-default"><?= t("Select all") ?></a>
- <a id="gMicroThumbUnselectAll" href="#" ref="unselect-all" style="display: none" class="gButtonLink ui-corner-all ui-state-default"><?= t("Deselect all") ?></a>
- <a id="gMicroThumbDone" href="#" ref="done" class="gButtonLink ui-corner-all ui-state-default"><?= t("Close") ?></a>
-</div>
diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php
new file mode 100644
index 00000000..b03c066c
--- /dev/null
+++ b/modules/organize/views/organize_dialog.html.php
@@ -0,0 +1,47 @@
+<?php defined("SYSPATH") or die("No direct script access.") ?>
+<script type="text/javascript">
+ var move_url = "<?= url::site("organize/move_to/__ALBUM_ID__?csrf=$csrf") ?>";
+ var rearrange_url = "<?= url::site("organize/rearrange/__TARGET_ID__/__BEFORE__?csrf=$csrf") ?>";
+ var sort_order_url = "<?= url::site("organize/sort_order/__ALBUM_ID__/__COL__/__DIR__?csrf=$csrf") ?>";
+</script>
+<div id="gOrganize" class="gDialogPanel">
+ <h1 style="display:none"><?= t("Organize %name", array("name" => p::purify($album->title))) ?></h1>
+ <div id="bd">
+ <div class="yui-gf">
+ <div class="yui-u first">
+ <h3><?= t("Albums") ?></h3>
+ </div>
+ <div id="gMessage" class="yui-u">
+ <div class="gInfo"><?= t("Drag and drop photos to re-order or move between albums") ?></div>
+ </div>
+ </div>
+ <div id="gOrganizeContentPane" class="yui-gf">
+ <div id="gOrganizeTreeContainer" class="yui-u first">
+ <ul id="gOrganizeAlbumTree">
+ <?= $album_tree ?>
+ </ul>
+ </div>
+ <div id="gOrganizeDetail" class="yui-u">
+ <div id="gMicroThumbPanel"
+ ref="<?= url::site("organize/album/__ITEM_ID__/__OFFSET__") ?>">
+ <ul id="gMicroThumbGrid">
+ <?= $micro_thumb_grid ?>
+ </ul>
+ </div>
+ <div id="gOrganizeControls">
+ <a id="gOrganizeClose" href="#" ref="done"
+ class="gButtonLink ui-corner-all ui-state-default"><?= t("Close") ?></a>
+ <form>
+ <?= t("Sort order") ?>
+ <?= form::dropdown(array("id" => "gOrganizeSortColumn"), album::get_sort_order_options(), $album->sort_column) ?>
+ <?= form::dropdown(array("id" => "gOrganizeSortOrder"), array("ASC" => "Ascending", "DESC" => "Descending"), $album->sort_order) ?>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script type="text/javascript">
+ $("#gOrganize").ready($.organize.init);
+</script>
diff --git a/modules/organize/views/organize_edit.html.php b/modules/organize/views/organize_edit.html.php
deleted file mode 100644
index 1adf290f..00000000
--- a/modules/organize/views/organize_edit.html.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<ul>
-<? foreach ($panes as $idx => $pane): ?>
- <li><a href="#pane-<?= $idx ?>"><?= $pane["label"] ?></a></li>
-<? endforeach?>
-</ul>
-
-<? if (count($panes) > 0): ?>
- <? foreach ($panes as $idx => $pane): ?>
- <div id="pane-<?= $idx ?>" class="gOrganizeEditPane ui-tabs-hide"><?= $pane["content"] ?></div>
- <? endforeach?>
-<? else: ?>
-<div class="gWarning"><?= t("No Edit pages apply to the selected items") ?></div>
-<? endif ?> \ No newline at end of file
diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php
index c80696ad..31dc9af5 100644
--- a/modules/organize/views/organize_thumb_grid.html.php
+++ b/modules/organize/views/organize_thumb_grid.html.php
@@ -1,12 +1,22 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<? foreach ($children as $i => $child): ?>
-<? $item_class = "gPhoto"; ?>
-<? if ($child->is_album()): ?>
- <? $item_class = "gAlbum"; ?>
-<? endif ?>
-<li id="thumb_<?= $child->id ?>" class="gMicroThumbContainer" ref="<?= $child->id ?>">
- <div id="gMicroThumb-<?= $child->id ?>" class="gMicroThumb <?= $item_class ?>">
- <?= $child->thumb_img(array("class" => "gThumbnail"), $thumbsize, true) ?>
+<? foreach ($album->children(25, $offset) as $child): ?>
+<li class="gMicroThumbGridCell" ref="<?= $child->id ?>">
+ <div id="gMicroThumb_<?= $child->id ?>"
+ class="gMicroThumb <?= $child->is_album() ? "gAlbum" : "gPhoto" ?>">
+ <?= $child->thumb_img(array("class" => "gThumbnail", "ref" => $child->id), 90, true) ?>
</div>
</li>
<? endforeach ?>
+
+<? if ($album->children_count() > $offset): ?>
+<script>
+ setTimeout(function() {
+ $.get("<?= url::site("organize/content/$album->id/" . ($offset + 25)) ?>",
+ function(data) {
+ $("#gMicroThumbGrid").append(data);
+ $.organize.set_handlers();
+ }
+ );
+ }, 50);
+</script>
+<? endif ?>
diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php
index d2cdd957..36f900ac 100644
--- a/modules/organize/views/organize_tree.html.php
+++ b/modules/organize/views/organize_tree.html.php
@@ -1,4 +1,44 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<? foreach ($children as $i => $child): ?>
-<? endforeach ?>
+<? foreach ($parents as $parent): ?>
+<li class="gOrganizeAlbum ui-icon-left <?= access::can("edit", $parent) ? "" : "gViewOnly" ?>"
+ ref="<?= $parent->id ?>">
+ <span class="ui-icon ui-icon-minus">
+ </span>
+ <span class="gAlbumText" ref="<?= $parent->id ?>">
+ <?= p::clean($parent->title) ?>
+ </span>
+ <ul class="ui-icon-plus">
+ <? endforeach ?>
+
+ <? foreach ($peers as $peer): ?>
+ <li class="gOrganizeAlbum ui-icon-left <?= access::can("edit", $peer) ? "" : "gViewOnly" ?>"
+ ref="<?= $peer->id ?>">
+ <span class="ui-icon <?= $peer->id == $album->id ? "ui-icon-minus" : "ui-icon-plus" ?>">
+ </span>
+ <span class="gAlbumText <?= $peer->id == $album->id ? "selected" : "" ?>"
+ ref="<?= $peer->id ?>">
+ <?= p::clean($peer->title) ?>
+ </span>
+ <? if ($peer->id == $album->id): ?>
+ <ul class="ui-icon-plus">
+ <? foreach ($album->children(null, 0, array("type" => "album")) as $child): ?>
+ <li class="gOrganizeAlbum ui-icon-left <?= access::can("edit", $child) ? "" : "gViewOnly" ?>"
+ ref="<?= $child->id ?>">
+ <span class="ui-icon ui-icon-plus">
+ </span>
+ <span class="gAlbumText"
+ ref="<?= $child->id ?>">
+ <?= p::clean($child->title) ?>
+ </span>
+ </li>
+ <? endforeach ?>
+ </ul>
+ <? endif ?>
+ </li>
+ <? endforeach ?>
+
+ <? foreach ($parents as $parent): ?>
+ </ul>
+</li>
+<? endforeach ?>
diff --git a/modules/search/helpers/search_event.php b/modules/search/helpers/search_event.php
index b65763af..836bbe15 100644
--- a/modules/search/helpers/search_event.php
+++ b/modules/search/helpers/search_event.php
@@ -35,9 +35,4 @@ class search_event_Core {
static function item_related_update($item) {
search::update($item);
}
-
- static function item_related_update_batch($sql) {
- $db = Database::instance();
- $db->query("UPDATE {search_records} SET `dirty` = 1 WHERE item_id IN ($sql)");
- }
}
diff --git a/modules/search/helpers/search_installer.php b/modules/search/helpers/search_installer.php
index cd253be4..10d8211f 100644
--- a/modules/search/helpers/search_installer.php
+++ b/modules/search/helpers/search_installer.php
@@ -28,7 +28,7 @@ class search_installer {
PRIMARY KEY (`id`),
KEY(`item_id`),
FULLTEXT INDEX (`data`))
- ENGINE=MyISAM DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("search", 1);
}
diff --git a/modules/server_add/controllers/server_add.php b/modules/server_add/controllers/server_add.php
index f68392ce..26b3bd08 100644
--- a/modules/server_add/controllers/server_add.php
+++ b/modules/server_add/controllers/server_add.php
@@ -150,7 +150,8 @@ class Server_Add_Controller extends Admin_Controller {
$queue[] = array($child, $entry->id);
} else {
$ext = strtolower(pathinfo($child, PATHINFO_EXTENSION));
- if (in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4"))) {
+ if (in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4")) &&
+ filesize($child) > 0) {
$child_entry = ORM::factory("server_add_file");
$child_entry->task_id = $task->id;
$child_entry->file = $child;
@@ -219,19 +220,25 @@ class Server_Add_Controller extends Admin_Controller {
$album = album::create($parent, $name, $title, null, $owner_id);
$entry->item_id = $album->id;
} else {
- $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION));
- if (in_array($extension, array("gif", "png", "jpg", "jpeg"))) {
- $photo = photo::create($parent, $entry->file, $name, $title, null, $owner_id);
- $entry->item_id = $photo->id;
- } else if (in_array($extension, array("flv", "mp4"))) {
- $movie = movie::create($parent, $entry->file, $name, $title, null, $owner_id);
- $entry->item_id = $movie->id;
- } else {
- // This should never happen, because we don't add stuff to the list that we can't
- // process. But just in, case.. set this to a non-null value so that we skip this
- // entry.
+ try {
+ $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION));
+ if (in_array($extension, array("gif", "png", "jpg", "jpeg"))) {
+ $photo = photo::create($parent, $entry->file, $name, $title, null, $owner_id);
+ $entry->item_id = $photo->id;
+ } else if (in_array($extension, array("flv", "mp4"))) {
+ $movie = movie::create($parent, $entry->file, $name, $title, null, $owner_id);
+ $entry->item_id = $movie->id;
+ } else {
+ // This should never happen, because we don't add stuff to the list that we can't
+ // process. But just in, case.. set this to a non-null value so that we skip this
+ // entry.
+ $entry->item_id = 0;
+ $task->log("Skipping unknown file type: $entry->file");
+ }
+ } catch (Exception $e) {
+ // This can happen if a photo file is invalid, like a BMP masquerading as a .jpg
$entry->item_id = 0;
- $task->log("Skipping unknown file type: $entry->file");
+ $task->log("Skipping invalid file: $entry->file");
}
}
diff --git a/modules/server_add/helpers/server_add_event.php b/modules/server_add/helpers/server_add_event.php
index b53e72d1..6b21ec2e 100644
--- a/modules/server_add/helpers/server_add_event.php
+++ b/modules/server_add/helpers/server_add_event.php
@@ -35,30 +35,11 @@ class server_add_event_Core {
// turn that into a dropdown if there are two different ways to add things. Do that in a
// portable way for now. If we find ourselves duplicating this pattern, we should make an
// API method for this.
- $server_add = Menu::factory("dialog")
- ->id("server_add")
- ->label(t("Add from server"))
- ->url(url::site("server_add/browse/$item->id"));
- $add_photos_item = $menu->get("add_photos_item");
- $add_photos_menu = $menu->get("add_photos_menu");
-
- if ($add_photos_item && !$add_photos_menu) {
- // Assuming that $add_menu is unset, create add_menu and add our item
- $menu->add_after(
- "add_photos_item",
- Menu::factory("submenu")
- ->id("add_photos_menu")
- ->label($add_photos_item->label)
- ->append(Menu::factory("dialog")
- ->id("add_photos_submenu_item")
- ->label(t("Simple Uploader"))
- ->url($add_photos_item->url))
- ->append($server_add));
- $menu->remove("add_photos_item");
- } else if ($add_photos_menu) {
- // Append to the existing sub-menu
- $add_photos_menu->append($server_add);
- }
+ $add_menu = $menu->get("add_menu");
+ $add_menu->append(Menu::factory("dialog")
+ ->id("server_add")
+ ->label(t("Server add"))
+ ->url(url::site("server_add/browse/$item->id")));
}
}
}
diff --git a/modules/server_add/helpers/server_add_installer.php b/modules/server_add/helpers/server_add_installer.php
index cd278eb7..c3c1572d 100644
--- a/modules/server_add/helpers/server_add_installer.php
+++ b/modules/server_add/helpers/server_add_installer.php
@@ -27,7 +27,7 @@ class server_add_installer {
`parent_id` int(9),
`task_id` int(9) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("server_add", 3);
server_add::check_config();
}
@@ -40,7 +40,7 @@ class server_add_installer {
`task_id` int(9) NOT NULL,
`file` varchar(255) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("server_add", $version = 2);
}
diff --git a/modules/server_add/js/server_add.js b/modules/server_add/js/server_add.js
index 989555cc..fbd61dcc 100644
--- a/modules/server_add/js/server_add.js
+++ b/modules/server_add/js/server_add.js
@@ -4,11 +4,9 @@
function select_file(li) {
$(li).toggleClass("selected");
if ($("#gServerAdd span.selected").length) {
- $("#gServerAddAddButton").enable(true);
- $("#gServerAddAddButton").removeClass("ui-state-disabled");
+ $("#gServerAddAddButton").enable(true).removeClass("ui-state-disabled");
} else {
- $("#gServerAddAddButton").enable(false);
- $("#gServerAddAddButton").addClass("ui-state-disabled");
+ $("#gServerAddAddButton").enable(false).addClass("ui-state-disabled");
}
}
@@ -54,7 +52,7 @@ function run_add(url) {
$("#gStatus").html(data.status);
$("#gServerAdd .gProgressBar").progressbar("value", data.percent_complete);
if (data.done) {
- $("#gProgress").slideUp();
+ $("#gServerAddProgress").slideUp();
} else {
setTimeout(function() { run_add(url); }, 0);
}
diff --git a/modules/server_add/views/server_add_tree_dialog.html.php b/modules/server_add/views/server_add_tree_dialog.html.php
index 533cad04..912e69b6 100644
--- a/modules/server_add/views/server_add_tree_dialog.html.php
+++ b/modules/server_add/views/server_add_tree_dialog.html.php
@@ -23,7 +23,7 @@
<?= $tree ?>
</ul>
- <div id="gProgress" style="display: none">
+ <div id="gServerAddProgress" style="display: none">
<div class="gProgressBar"></div>
<div id="gStatus"></div>
</div>
@@ -34,7 +34,7 @@
<?= t("Add") ?>
</button>
- <button class="ui-state-default ui-corner-all" onclick="closeDialog(); window.location.reload();">
+ <button id="gServerCloseButton" class="ui-state-default ui-corner-all">
<?= t("Close") ?>
</button>
</span>
@@ -46,7 +46,10 @@
$("#gServerAdd .gProgressBar").
progressbar().
progressbar("value", 0);
- $("#gProgress").slideDown("fast", function() { start_add() });
+ $("#gServerAddProgress").slideDown("fast", function() { start_add() });
+ });
+ $("#gServerCloseButton").click(function(event) {
+ $("#gDialog").dialog("close");
});
});
</script>
diff --git a/modules/slideshow/helpers/slideshow_event.php b/modules/slideshow/helpers/slideshow_event.php
index cf79f71a..1b881de4 100644
--- a/modules/slideshow/helpers/slideshow_event.php
+++ b/modules/slideshow/helpers/slideshow_event.php
@@ -31,13 +31,17 @@ class slideshow_event_Core {
}
static function album_menu($menu, $theme) {
- $menu
- ->append(Menu::factory("link")
- ->id("slideshow")
- ->label(t("View slideshow"))
- ->url("javascript:PicLensLite.start(" .
- "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})")
- ->css_id("gSlideshowLink"));
+ $descendants_count = ORM::factory("item", $theme->item->id)
+ ->descendants_count(array("type" => "photo"));
+ if ($descendants_count > 1) {
+ $menu
+ ->append(Menu::factory("link")
+ ->id("slideshow")
+ ->label(t("View slideshow"))
+ ->url("javascript:PicLensLite.start(" .
+ "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})")
+ ->css_id("gSlideshowLink"));
+ }
}
static function photo_menu($menu, $theme) {
diff --git a/modules/tag/helpers/tag_installer.php b/modules/tag/helpers/tag_installer.php
index 3c16e3f3..bcb830e4 100644
--- a/modules/tag/helpers/tag_installer.php
+++ b/modules/tag/helpers/tag_installer.php
@@ -26,7 +26,7 @@ class tag_installer {
`count` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {items_tags} (
`id` int(9) NOT NULL auto_increment,
@@ -35,7 +35,7 @@ class tag_installer {
PRIMARY KEY (`id`),
KEY(`tag_id`, `id`),
KEY(`item_id`, `id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("tag", 1);
}
diff --git a/modules/tag/js/tag.js b/modules/tag/js/tag.js
index 765c2a35..61ac73f4 100644
--- a/modules/tag/js/tag.js
+++ b/modules/tag/js/tag.js
@@ -23,7 +23,7 @@ function closeEditInPlaceForms() {
$("#gRenameTagForm").parent().html($("#gRenameTagForm").parent().data("revert"));
li.height("");
$(".gEditable", li).bind("click", editInPlace);
- $(".gDialogLink", li).bind("click", handleDialogEvent);
+ $(".gDialogLink", li).gallery_dialog();
}
}
diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php
index e910a8ee..d9488e1c 100644
--- a/modules/tag/models/tag.php
+++ b/modules/tag/models/tag.php
@@ -54,4 +54,52 @@ class Tag_Model extends ORM {
}
return $model->count_all();
}
+
+ /**
+ * Overload ORM::save() to trigger an item_related_update event for all items that are related
+ * to this tag. Since items can be added or removed as part of the save, we need to trigger an
+ * event for the union of all related items before and after the save.
+ */
+ public function save() {
+ $db = Database::instance();
+ $related_item_ids = array();
+ foreach ($db->getwhere("items_tags", array("tag_id" => $this->id)) as $row) {
+ $related_item_ids[$row->item_id] = 1;
+ }
+
+ $result = parent::save();
+
+ foreach ($db->getwhere("items_tags", array("tag_id" => $this->id)) as $row) {
+ $related_item_ids[$row->item_id] = 1;
+ }
+
+ if ($related_item_ids) {
+ foreach (ORM::factory("item")->in("id", array_keys($related_item_ids))->find_all() as $item) {
+ module::event("item_related_update", $item);
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Overload ORM::delete() to trigger an item_related_update event for all items that are
+ * related to this tag.
+ */
+ public function delete() {
+ $related_item_ids = array();
+ $db = Database::Instance();
+ foreach ($db->getwhere("items_tags", array("tag_id" => $this->id)) as $row) {
+ $related_item_ids[$row->item_id] = 1;
+ }
+
+ $result = parent::delete();
+
+ if ($related_item_ids) {
+ foreach (ORM::factory("item")->in("id", array_keys($related_item_ids))->find_all() as $item) {
+ module::event("item_related_update", $item);
+ }
+ }
+ return $result;
+ }
} \ No newline at end of file
diff --git a/modules/user/controllers/password.php b/modules/user/controllers/password.php
index 066efbba..a6522369 100644
--- a/modules/user/controllers/password.php
+++ b/modules/user/controllers/password.php
@@ -29,8 +29,6 @@ class Password_Controller extends Controller {
}
public function do_reset() {
- access::verify_csrf();
-
if (request::method() == "post") {
$this->_change_password();
} else {
diff --git a/modules/user/helpers/user.php b/modules/user/helpers/user.php
index 69a6ecb3..40acc2ec 100644
--- a/modules/user/helpers/user.php
+++ b/modules/user/helpers/user.php
@@ -159,7 +159,12 @@ class user_Core {
*/
static function active() {
// @todo (maybe) cache this object so we're not always doing session lookups.
- $user = Session::instance()->get("user", self::guest());
+ $user = Session::instance()->get("user", null);
+ if (!isset($user)) {
+ // Don't do this as a fallback in the Session::get() call because it can trigger unnecessary
+ // work.
+ $user = user::guest();
+ }
return $user;
}
diff --git a/modules/user/helpers/user_installer.php b/modules/user/helpers/user_installer.php
index 1959d038..8ef4f13d 100644
--- a/modules/user/helpers/user_installer.php
+++ b/modules/user/helpers/user_installer.php
@@ -36,7 +36,7 @@ class user_installer {
PRIMARY KEY (`id`),
UNIQUE KEY(`hash`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {groups} (
`id` int(9) NOT NULL auto_increment,
@@ -44,14 +44,14 @@ class user_installer {
`special` BOOLEAN default 0,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {groups_users} (
`group_id` int(9) NOT NULL,
`user_id` int(9) NOT NULL,
PRIMARY KEY (`group_id`, `user_id`),
UNIQUE KEY(`user_id`, `group_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$everybody = group::create("Everybody");
$everybody->special = true;
diff --git a/modules/user/helpers/user_theme.php b/modules/user/helpers/user_theme.php
index c5351f8e..8de2d248 100644
--- a/modules/user/helpers/user_theme.php
+++ b/modules/user/helpers/user_theme.php
@@ -19,14 +19,10 @@
*/
class user_theme_Core {
static function header_top($theme) {
- $view = new View("login.html");
- $view->user = user::active();
- return $view->render();
- }
-
- static function admin_head($theme) {
- if (strpos(Router::$current_uri, "admin/users") !== false) {
- $theme->script("gallery.panel.js");
+ if ($theme->page_type != "login") {
+ $view = new View("login.html");
+ $view->user = user::active();
+ return $view->render();
}
}
}
diff --git a/modules/user/models/user.php b/modules/user/models/user.php
index 4b43adff..55562f34 100644
--- a/modules/user/models/user.php
+++ b/modules/user/models/user.php
@@ -25,6 +25,7 @@ class User_Model extends ORM {
"full_name" => "length[0,255]",
"email" => "valid_email|length[1,255]",
"password" => "length[1,40]",
+ "url" => "valid_url",
"locale" => "length[2,10]");
public function __set($column, $value) {
diff --git a/modules/user/views/admin_users.html.php b/modules/user/views/admin_users.html.php
index 54c4847d..36c4f4fd 100644
--- a/modules/user/views/admin_users.html.php
+++ b/modules/user/views/admin_users.html.php
@@ -28,7 +28,7 @@
{},
function(data) {
$("#group-" + group_id).html(data);
- $("#group-" + group_id + " .gDialogLink").bind("click", handleDialogEvent);
+ $("#group-" + group_id + " .gDialogLink").gallery_dialog();
});
}
diff --git a/modules/watermark/helpers/watermark_installer.php b/modules/watermark/helpers/watermark_installer.php
index 705b89d4..b3e91044 100644
--- a/modules/watermark/helpers/watermark_installer.php
+++ b/modules/watermark/helpers/watermark_installer.php
@@ -30,7 +30,7 @@ class watermark_installer {
`mime_type` varchar(64) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
@mkdir(VARPATH . "modules/watermark");
module::set_version("watermark", 1);
diff --git a/themes/admin_default/css/admin_screen.css b/themes/admin_default/css/admin_screen.css
index d408acf0..fd1ed02e 100644
--- a/themes/admin_default/css/admin_screen.css
+++ b/themes/admin_default/css/admin_screen.css
@@ -35,13 +35,12 @@
.gSelected img,
.gAvailable .gBlock img {
float: left;
- margin-right: 1em;
+ margin: 0 1em 1em 0;
}
.rtl .gSelected img,
.rtl .gAvailable .gBlock img {
float: right;
- margin-left: 1em;
}
.gSelected {
@@ -202,7 +201,7 @@
#gAdminGraphics .gAvailable .gBlock {
clear: none;
float: left;
- height: 16em;
+ height: 17em;
margin-right: 1em;
width: 30%;
}
@@ -263,8 +262,8 @@ li.gGroup {
}
li.gGroup h4 {
- background-color: #EEEEEE;
- border-bottom: 1px dashed #CCCCCC;
+ background-color: #eee;
+ border-bottom: 1px dashed ccc;
padding: .5em 0 .5em .5em;
}
li.gGroup .gButtonLink {
@@ -451,8 +450,30 @@ li.gDefaultGroup h4, li.gDefaultGroup .gUser {
cursor: pointer;
}
-#gLanguageSettingsForm .checklist li {
- width: 150px;
- overflow: hidden;
+#gLanguagesForm table {
+ width: 400px;
+ float: left;
+ margin: 0 3em 1em 0;
+}
+#gLanguagesForm .installed {
+ background-color: #EEEEEE;
+}
+#gLanguagesForm .default {
+ background-color: #C5DBEC;
+ font-weight: bold;
+}
+#gLanguagesForm input {
+ clear: both;
}
+#gTranslations {
+ padding: 2em 0 0 0;
+ clear: both;
+}
+#gTranslations .gButtonLink {
+ padding: .5em;
+}
+
+.gDocLink {
+ float: right;
+}
diff --git a/themes/admin_default/css/screen.css b/themes/admin_default/css/screen.css
index 88631e81..c275eb10 100644
--- a/themes/admin_default/css/screen.css
+++ b/themes/admin_default/css/screen.css
@@ -108,7 +108,7 @@ table {
}
#gContent table {
- margin: 1em 0;
+ margin: 1em 0 3em 0;
}
caption,
@@ -124,6 +124,10 @@ td {
vertical-align: top;
}
+#gAdminMaintenance td {
+ vertical-align: middle;
+}
+
/* Forms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
fieldset {
@@ -276,12 +280,12 @@ li.gError select {
/* Status messages ~~~~~~~~~~~~~~~~~~~~~~~ */
#gMessage {
- width: 99%;
+ width: 100%;
}
-#gAdminAkismet .gSuccess,
#gSiteStatus li,
-#gMessage li {
+#gMessage li,
+.gModuleStatus {
border: 1px solid #ccc;
margin-bottom: .4em;
}
@@ -292,71 +296,62 @@ li.gError select {
border-bottom: 1px solid #ccc;
}
-#gSiteStatus .gError,
-#gMessage .gError,
-form p.gError,
-#gSiteStatus .gInfo,
-#gMessage .gInfo,
-#gSiteStatus .gSuccess,
-#gMessage .gSuccess,
-#gSiteStatus .gWarning,
-#gMessage .gWarning {
+.gModuleStatus {
+ clear: both;
+ margin-bottom: 1em;
+}
+
+.gError,
+.gInfo,
+.gSuccess,
+.gWarning {
background-position: .4em 50%;
background-repeat: no-repeat;
padding: .4em .5em .4em 30px;
}
.gError {
- background-color: #fcc;
-}
-
-form .gError {
- color: #f00;
-}
-
-#gSiteStatus .gError,
-#gMessage .gError,
-form p.gError {
+ background-color: #f6cbca;
+ color: red;
background-image: url('../images/ico-error.png');
}
.gInfo {
background-color: #e8e8e8;
-}
-
-#gSiteStatus .gInfo,
-#gMessage .gInfo {
background-image: url('../images/ico-info.png');
}
.gSuccess {
- background-color: #96EF95;
-}
-
-#gSiteStatus .gSuccess,
-#gMessage .gSuccess {
+ background-color: #d9efc2;
background-image: url('../images/ico-success.png');
}
.gWarning {
- background-color: #ff9;
+ background-color: #fcf9ce;
+ background-image: url('../images/ico-warning.png');
}
-#gSiteStatus .gWarning,
-#gMessage .gWarning {
- background-image: url('../images/ico-warning.png');
+table .gError {
+ background-color: #f6cbca !important;
+}
+
+table .gWarning {
+ background-color: #fcf9ce !important;
}
+.gPager .gInfo,
form .gError,
-.gPager .gInfo {
- background-color: #fff;
+table .gInfo,
+table .gSuccess {
+ background-color: transparent !important;
}
-#gAdminMaintenance .gError,
-#gAdminMaintenance .gInfo,
-#gAdminMaintenance .gWarning,
-#gAdminMaintenance .gSuccess {
- background-image: none;
+.gPager .gInfo,
+table .gError,
+table .gInfo,
+table .gSuccess,
+table .gWarning {
+ background-image: none !important;
}
/* Inline layout (forms, lists) ~~~~~~~~~~ */
@@ -823,7 +818,6 @@ form .gError,
.ui-widget-overlay {
background: #000;
opacity: .7;
- filter: Alpha(Opacity=70);
}
#gDialog {
diff --git a/themes/admin_default/js/ui.init.js b/themes/admin_default/js/ui.init.js
index 3f062a27..daa6dd70 100644
--- a/themes/admin_default/js/ui.init.js
+++ b/themes/admin_default/js/ui.init.js
@@ -1,5 +1,4 @@
$(document).ready(function(){
-
// Initialize Superfish menus
$("#gSiteAdminMenu ul.gMenu").addClass("sf-menu");
$("ul.gMenu").addClass("sf-menu");
@@ -15,23 +14,20 @@ $(document).ready(function(){
$("#gSiteAdminMenu").css("display", "block");
// Initialize status message effects
- $("#gMessage li").showMessage();
+ $("#gMessage li").gallery_show_message();
// Initialize modal dialogs
- var dialogLinks = $(".gDialogLink");
- for (var i=0; i < dialogLinks.length; i++) {
- $(dialogLinks[i]).bind("click", handleDialogEvent);
- }
+ $(".gDialogLink").gallery_dialog();
+
+ // Initialize ajax links
+ $(".gDialogLink").gallery_ajax();
// Initialize panels
- var panelLinks = $(".gPanelLink");
- for (i=0; i<panelLinks.length; i++) {
- $(panelLinks[i]).bind("click", handlePanelEvent);
- }
+ $(".gPanelLink").gallery_panel();
if ($("#gPhotoStream").length) {
// Vertically align thumbs in photostream
- $(".gItem").vAlign();
+ $(".gItem").gallery_valign();
}
// Apply jQuery UI button css to submit inputs
diff --git a/themes/admin_default/views/admin.html.php b/themes/admin_default/views/admin.html.php
index 61821428..2ed8c38e 100644
--- a/themes/admin_default/views/admin.html.php
+++ b/themes/admin_default/views/admin.html.php
@@ -25,6 +25,7 @@
<script type="text/javascript">
var MSG_CANCEL = "<?= t('Cancel')->for_js() ?>";
</script>
+ <?= $theme->script("gallery.ajax.js") ?>
<?= $theme->script("gallery.dialog.js") ?>
<?= $theme->script("superfish/js/superfish.js") ?>
<?= $theme->script("jquery.dropshadow.js") ?>
diff --git a/themes/default/css/fix-ie.css b/themes/default/css/fix-ie.css
index c7c1ebad..eee88c15 100644
--- a/themes/default/css/fix-ie.css
+++ b/themes/default/css/fix-ie.css
@@ -35,7 +35,3 @@ input.submit {
.gPager .ui-icon-right {
width: 60px;
}
-
-.gQuickPane {
- height: 32px !important;
-} \ No newline at end of file
diff --git a/themes/default/css/screen.css b/themes/default/css/screen.css
index c5a9956d..82cdb331 100644
--- a/themes/default/css/screen.css
+++ b/themes/default/css/screen.css
@@ -276,12 +276,12 @@ li.gError select {
/* Status messages ~~~~~~~~~~~~~~~~~~~~~~~ */
#gMessage {
- width: 99%;
+ width: 100%;
}
-#gAdminAkismet .gSuccess,
#gSiteStatus li,
-#gMessage li {
+#gMessage li,
+.gModuleStatus {
border: 1px solid #ccc;
margin-bottom: .4em;
}
@@ -292,71 +292,49 @@ li.gError select {
border-bottom: 1px solid #ccc;
}
-#gSiteStatus .gError,
-#gMessage .gError,
-form p.gError,
-#gSiteStatus .gInfo,
-#gMessage .gInfo,
-#gSiteStatus .gSuccess,
-#gMessage .gSuccess,
-#gSiteStatus .gWarning,
-#gMessage .gWarning {
+.gModuleStatus {
+ clear: both;
+ margin-bottom: 1em;
+}
+
+.gError,
+.gInfo,
+.gSuccess,
+.gWarning {
background-position: .4em 50%;
background-repeat: no-repeat;
padding: .4em .5em .4em 30px;
}
.gError {
- background-color: #fcc;
-}
-
-form .gError {
- color: #f00;
-}
-
-#gSiteStatus .gError,
-#gMessage .gError,
-form p.gError {
+ background-color: #f6cbca;
+ color: #fc0;
background-image: url('../images/ico-error.png');
}
.gInfo {
background-color: #e8e8e8;
-}
-
-#gSiteStatus .gInfo,
-#gMessage .gInfo {
background-image: url('../images/ico-info.png');
}
.gSuccess {
- background-color: #96EF95;
-}
-
-#gSiteStatus .gSuccess,
-#gMessage .gSuccess {
+ background-color: #d9efc2;
background-image: url('../images/ico-success.png');
}
.gWarning {
- background-color: #ff9;
-}
-
-#gSiteStatus .gWarning,
-#gMessage .gWarning {
+ background-color: #fcf9ce;
background-image: url('../images/ico-warning.png');
}
form .gError,
.gPager .gInfo {
- background-color: #fff;
+ background-color: #fff !important;
}
-#gAdminMaintenance .gError,
-#gAdminMaintenance .gInfo,
-#gAdminMaintenance .gWarning,
-#gAdminMaintenance .gSuccess {
- background-image: none;
+.gPager .gInfo {
+ background-image: none !important;
+ padding: 0 !important;
}
/* Inline layout (forms, lists) ~~~~~~~~~~ */
@@ -406,7 +384,6 @@ form .gError,
}
#gSidebar {
- background-color: #fff;
font-size: .9em;
padding: 0 20px;
width: 220px;
@@ -453,41 +430,59 @@ form .gError,
#gContent #gAlbumGrid {
margin: 1em 0;
+ position: relative;
+ z-index: 1;
}
#gContent #gAlbumGrid .gItem {
- border: 1px solid #e8e8e8;
- border-right-color: #ccc;
- border-bottom-color: #ccc;
+ background-color: #fff;
+ border: 1px solid #fff;
float: left;
font-size: .7em;
- height: 240px;
+ height: 220px;
overflow: hidden;
- padding: 15px 8px 30px 8px;
+ padding: .6em 8px;
position: relative;
text-align: center;
width: 213px;
+ z-index: 1;
}
#gContent #gAlbumGrid .gItem h2 {
margin: 5px 0;
}
+#gContent .gPhoto h2,
+#gContent .gItem .gMetadata {
+ display: none;
+}
+
#gContent #gAlbumGrid .gAlbum {
background-color: #e8e8e8;
}
#gContent #gAlbumGrid .gAlbum h2 span {
- background: transparent url('../images/ico-album.png') no-repeat top left !important;
+ background: transparent url('../images/ico-album.png') no-repeat top left;
display: inline-block;
height: 16px;
margin-right: 5px;
width: 16px;
}
+#gContent #gAlbumGrid .gHoverItem {
+ background-color: #fff;
+ border: 1px solid #000;
+}
+
+#gContent .gHoverItem h2,
+#gContent .gHoverItem .gMetadata {
+ display: block;
+}
+
/* Individual photo content ~~~~~~~~~~~~~~ */
#gContent #gItem {
+ position: relative;
width: 99%;
}
@@ -502,6 +497,7 @@ form .gError,
#gContent #gComments {
margin-top: 2em;
+ position: relative;
}
#gContent #gComments ul li {
@@ -533,6 +529,12 @@ form .gError,
width: 32px;
}
+#gAddCommentButton {
+ position: absolute;
+ right: 0;
+ top: 2px;
+}
+
#gContent #gAddCommentForm {
margin-top: 2em;
}
@@ -586,26 +588,48 @@ form .gError,
margin-bottom: 0 !important;
}
-/* Thumb Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* Context Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-#gContent .gThumbMenu {
+.gContextMenu {
+ position: absolute;
bottom: 0;
left: 0;
- position: absolute;
+}
+
+.gItem .gContextMenu {
+ display: none;
+ margin-top: 2em;
width: 100%;
}
-#gContent .gThumbMenu li {
+#gItem .gContextMenu {
+ font-size: .7em;
+}
+
+#gItem .gContextMenu ul {
+ display: none;
+}
+
+.gContextMenu li {
border-left: none;
border-right: none;
border-bottom: none;
}
-#gContent .gThumbMenu li li {
- padding: .3em;
+.gContextMenu li a {
+ display: block;
+ line-height: 1.6em;
+}
+
+.gHoverItem .gContextMenu {
+ display: block;
}
-#gContent .gThumbMenu a:hover {
+.gHoverItem .gContextMenu li {
+ text-align: left;
+}
+
+.gHoverItem .gContextMenu a:hover {
text-decoration: none;
}
@@ -668,7 +692,7 @@ form .gError,
font-weight: bold;
}
-#gAddPhotos .gBreadcrumbs {
+#gDialog .gBreadcrumbs li {
font-size: .9em;
}
@@ -851,6 +875,10 @@ form .gError,
display: none;
}
+#gDialog p {
+ margin: 0;
+}
+
/* jQuery UI ThemeRoller buttons */
.gButtonLink {
@@ -951,6 +979,14 @@ form .gError,
/* Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+#gEditPermissionForm {
+ clear: both;
+}
+#gEditPermissionForm fieldset {
+ border: 1px solid #cccccc;
+ padding: 0;
+}
+
#gPermissions .gDenied,
#gPermissions .gAllowed {
text-align: center;
@@ -972,11 +1008,6 @@ form .gError,
display: inline-block;
}
-#gAddPhotos p {
- margin: 0;
- padding: 0;
-}
-
#gAddPhotosCanvas {
height: 325px;
width: 450px;
diff --git a/themes/default/js/ui.init.js b/themes/default/js/ui.init.js
index 11cd06ed..949933e9 100644
--- a/themes/default/js/ui.init.js
+++ b/themes/default/js/ui.init.js
@@ -1,8 +1,5 @@
/**
- * Initialize jQuery UI and Plugin elements
- *
- * @todo Standardize how elements requiring listeners are handled
- * http://docs.jquery.com/Events/live
+ * Initialize jQuery UI and Gallery Plugin elements
*/
var shortForms = new Array(
@@ -13,9 +10,6 @@ var shortForms = new Array(
$(document).ready(function() {
- // Remove .gMenu from thumb menu's before initializing Superfish
- // @todo gallery_menu should only apply gMenu to top-level menus, submenus should be gSubMenu-N
-
// Initialize Superfish menus
$("ul.gMenu").addClass("sf-menu");
$('ul.sf-menu').superfish({
@@ -29,15 +23,11 @@ $(document).ready(function() {
$("#gSiteMenu").css("display", "block");
// Initialize status message effects
- $("#gMessage li").showMessage();
+ $("#gMessage li").gallery_show_message();
// Initialize dialogs
- $(".gMenuLink").addClass("gDialogLink");
$("#gLoginLink").addClass("gDialogLink");
- var dialogLinks = $(".gDialogLink");
- for (var i=0; i < dialogLinks.length; i++) {
- $(dialogLinks[i]).bind("click", handleDialogEvent);
- }
+ $(".gDialogLink").gallery_dialog();
// Initialize view menu
if ($("#gViewMenu").length) {
@@ -53,30 +43,74 @@ $(document).ready(function() {
// Apply jQuery UI button css to submit inputs
$("input[type=submit]:not(.gShortForm input)").addClass("ui-state-default ui-corner-all");
+ // Apply styles and icon classes to gContextMenu
+ if ($(".gContextMenu").length) {
+ $(".gContextMenu li").addClass("ui-state-default");
+ $(".gContextMenu a").addClass("gButtonLink ui-icon-left");
+ $(".gContextMenu a").prepend("<span class=\"ui-icon\"></span>");
+ $(".gContextMenu a span").each(function() {
+ var iconClass = $(this).parent().attr("class").match(/ui-icon-.[^\s]+/).toString();
+ $(this).addClass(iconClass);
+ });
+ }
+
// Album view only
if ($("#gAlbumGrid").length) {
// Vertical align thumbnails/metadata in album grid
- $(".gItem").vAlign();
- $(".gQuick").ajaxStop(function(){
- $(".gItem").vAlign();
- });
+ $(".gItem").gallery_valign();
+
+ // Initialize context menus
+ $(".gItem").hover(
+ function(){
+ // Insert invisible placeholder to hold the item's position in the grid
+ var placeHolder = $(this).clone();
+ $(placeHolder).attr("id", "gPlaceHolder");
+ $(placeHolder).css("visibility", "hidden");
+ $(this).after($(placeHolder));
+ // Style and position the item
+ $(this).addClass("gHoverItem");
+ var position = $(this).position();
+ $(this).css("position", "absolute");
+ $(this).css("top", position.top);
+ $(this).css("left", position.left);
+ $(this).css("z-index", "1000");
+ // Initialize the contextual menu
+ $(this).gallery_context_menu();
+ // Set height based on height of descendents
+ var title = $(this).find("h2");
+ var meta = $(this).find(".gMetadata");
+ var context_label = $(this).find(".gContextMenu li:first");
+ var item_ht = $(this).height();
+ var title_ht = $(title).gallery_height();
+ var meta_ht = $(meta).gallery_height();
+ var context_label_ht = $(context_label).gallery_height();
+ $(this).height(item_ht + title_ht + meta_ht + context_label_ht);
+ },
+ function() {
+ // Reset item height, position, and z-index
+ var sib_height = $(this).next().height();
+ $(this).css("height", sib_height);
+ $(this).css("position", "relative");
+ $(this).css("top", null);
+ $(this).css("left", null);
+ $(this).css("z-index", null);
+ // Remove the placeholder and hover class from the item
+ $("#gPlaceHolder").remove();
+ $(this).removeClass("gHoverItem");
+ }
+ );
}
- // Photo/Item item view only
+ // Photo/Item item view
if ($("#gItem").length) {
- // Ensure that sized image versions
- // fit inside their container
- sizedImage();
-
- // Collapse comments form, insert button to expand
- if ($("#gAddCommentForm").length) {
- var showCommentForm = '<a href="#add_comment_form" class="showCommentForm gButtonLink ui-corner-all ui-icon-left ui-state-default right"><span class="ui-icon ui-icon-comment"></span>' + ADD_A_COMMENT + '</a>';
- $("#gAddCommentForm").hide();
- $("#gComments").prepend(showCommentForm);
- $(".showCommentForm").click(function(){
- $("#gAddCommentForm").show(1000);
- });
- }
+ // Ensure the resized image fits within its container
+ $("#gItem").gallery_fit_photo();
+
+ // Initialize context menus
+ var resize = $("#gItem").gallery_get_photo();
+ $(resize).hover(function(){
+ $(this).gallery_context_menu();
+ });
// Add scroll effect for links to named anchors
$.localScroll({
@@ -84,56 +118,9 @@ $(document).ready(function() {
duration: 1000,
hash: true
});
-
}
- // Add hover state for buttons
- $(".ui-state-default").hover(
- function(){
- $(this).addClass("ui-state-hover");
- },
- function(){
- $(this).removeClass("ui-state-hover");
- }
- );
-
- // Initialize thumbnail menus
- // @todo Toggle between north and south caret's on hover
- if ($("#gContent .gThumbMenu").length) {
- $("#gContent .gThumbMenu li").addClass("ui-state-default");
- $("#gContent .gThumbMenu li a")
- .not('[class]')
- .addClass("gButtonLink ui-icon ui-icon-caret-l-n")
- .css({
- height: "10px",
- margin: "0",
- padding: "0 0 3px 0"
- });
-
- $(".gThumbMenu ul").hide();
- $(".gThumbMenu").hover(
- function() {
- $(this).find("ul").slideDown("fast");
- },
- function() {
- $(this).find("ul").slideUp("slow");
- }
- );
- }
+ // Initialize button hover effect
+ $.fn.gallery_hover_init();
});
-
-/**
- * Reduce width of sized photo if it's wider than its parent container
- */
-function sizedImage() {
- var containerWidth = $("#gItem").width();
- var oPhoto = $("#gItem img").filter(function() {
- return this.id.match(/gPhotoId-/);
- });
- if (containerWidth < oPhoto.width()) {
- var proportion = containerWidth / oPhoto.width();
- oPhoto.width(containerWidth);
- oPhoto.height(proportion * oPhoto.height());
- }
-}
diff --git a/themes/default/views/album.html.php b/themes/default/views/album.html.php
index ffb4b913..8c690f5f 100644
--- a/themes/default/views/album.html.php
+++ b/themes/default/views/album.html.php
@@ -19,7 +19,7 @@
<?= $child->thumb_img(array("class" => "gThumbnail")) ?>
</a>
<?= $theme->thumb_bottom($child) ?>
- <?= $theme->thumb_menu($child) ?>
+ <?= $theme->context_menu($child, "#gItemId-{$child->id} .gThumbnail") ?>
<h2><span></span><a href="<?= $child->url() ?>"><?= SafeString::of($child->title) ?></a></h2>
<ul class="gMetadata">
<?= $theme->thumb_info($child) ?>
diff --git a/themes/default/views/movie.html.php b/themes/default/views/movie.html.php
index 75d51eff..237743b7 100644
--- a/themes/default/views/movie.html.php
+++ b/themes/default/views/movie.html.php
@@ -2,16 +2,29 @@
<div id="gItem">
<?= $theme->photo_top() ?>
- <ul id="gPager">
- <li><?= t("%position of %total", array("position" => $position, "total" => $sibling_count)) ?></li>
- <? if ($previous_item): ?>
- <li><span class="ui-icon ui-icon-seek-prev"></span><a href="<?= $previous_item->url() ?>"><?= t("previous") ?></a></li>
- <? endif ?>
- <? if ($next_item): ?>
- <li><a href="<?= $next_item->url() ?>"><?= t("next") ?></a><span class="ui-icon ui-icon-seek-next"></span></li>
- <? endif ?>
+ <ul class="gPager">
+ <li>
+ <? if ($previous_item): ?>
+ <a href="<?= $previous_item->url() ?>" class="gButtonLink ui-icon-left ui-state-default ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-w"></span><?= t("previous") ?></a>
+ <? else: ?>
+ <a class="gButtonLink ui-icon-left ui-state-disabled ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-w"></span><?= t("previous") ?></a>
+ <? endif; ?>
+ </li>
+ <li class="gInfo"><?= t("%position of %total", array("position" => $position, "total" => $sibling_count)) ?></li>
+ <li class="txtright">
+ <? if ($next_item): ?>
+ <a href="<?= $next_item->url() ?>" class="gButtonLink ui-icon-right ui-state-default ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-e"></span><?= t("next") ?></a>
+ <? else: ?>
+ <a class="gButtonLink ui-icon-right ui-state-disabled ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-e"></span><?= t("next") ?></a>
+ <? endif ?>
+ </li>
</ul>
+
<?= $item->movie_img(array("class" => "gMovie", "id" => "gMovieId-{$item->id}")) ?>
<div id="gInfo">
@@ -19,8 +32,6 @@
<div><?= nl2br(SafeString::purify($item->description)) ?></div>
</div>
- <script type="text/javascript">
- var ADD_A_COMMENT = "<?= t("Add a comment")->for_js() ?>";
- </script>
<?= $theme->photo_bottom() ?>
+ <?= $theme->context_menu($item, "#gMovieId-{$item->id}") ?>
</div>
diff --git a/themes/default/views/page.html.php b/themes/default/views/page.html.php
index 8d9f0caa..844ef295 100644
--- a/themes/default/views/page.html.php
+++ b/themes/default/views/page.html.php
@@ -53,6 +53,7 @@
<script type="text/javascript">
var MSG_CANCEL = "<?= t('Cancel')->for_js() ?>";
</script>
+ <?= $theme->script("gallery.ajax.js") ?>
<?= $theme->script("gallery.dialog.js") ?>
<?= $theme->script("gallery.form.js") ?>
<?= $theme->script("superfish/js/superfish.js") ?>
diff --git a/themes/default/views/photo.html.php b/themes/default/views/photo.html.php
index fcf597cf..5b5cb12b 100644
--- a/themes/default/views/photo.html.php
+++ b/themes/default/views/photo.html.php
@@ -5,7 +5,7 @@
<script>
$(document).ready(function() {
$(".gFullSizeLink").click(function() {
- show_full_size("<?= $theme->item()->file_url()->for_js() ?>", "<?= $theme->item()->width ?>", "<?= $theme->item()->height ?>");
+ $.gallery_show_full_size("<?= $theme->item()->file_url()->for_js() ?>", "<?= $theme->item()->width ?>", "<?= $theme->item()->height ?>");
return false;
});
});
@@ -47,6 +47,7 @@
</a>
<? endif ?>
<?= $theme->resize_bottom($item) ?>
+ <?= $theme->context_menu($item, "#gPhotoId-{$item->id}") ?>
</div>
<div id="gInfo">
@@ -54,8 +55,5 @@
<div><?= nl2br(SafeString::purify($item->description)) ?></div>
</div>
- <script type="text/javascript">
- var ADD_A_COMMENT = "<?= t("Add a comment")->for_js() ?>";
- </script>
<?= $theme->photo_bottom() ?>
</div>