diff --git a/modules/iptc/controllers/admin_iptc.php b/modules/iptc/controllers/admin_iptc.php
new file mode 100644
index 00000000..dd803951
--- /dev/null
+++ b/modules/iptc/controllers/admin_iptc.php
@@ -0,0 +1,84 @@
+content = new View("admin_iptc.html");
+ $view->content->iptc_form = $this->_get_admin_form();
+ print $view;
+ }
+
+ public function saveprefs() {
+ // Save user preferences to the database.
+
+ // Prevent Cross Site Request Forgery
+ access::verify_csrf();
+
+ // Make sure the user filled out the form properly.
+ $form = $this->_get_admin_form();
+ if ($form->validate()) {
+ Kohana_Log::add("error",print_r($form,1));
+
+ // Save settings to Gallery's database.
+ foreach (iptc::keys() as $keyword => $iptcvar) {
+ $checkbox = false;
+ for ($i = 0; $i < count($form->Global->$keyword); $i++) {
+ if ($form->Global->$keyword->value[$i] == $keyword) {
+ $checkbox = true;
+ }
+ }
+ module::set_var("iptc", "show_".$keyword, $checkbox);
+ }
+ // Display a success message and redirect back to the TagsMap admin page.
+ message::success(t("Your settings have been saved."));
+ url::redirect("admin/iptc");
+ }
+
+ // Else show the page with errors
+ $view = new Admin_View("admin.html");
+ $view->content = new View("admin_iptc.html");
+ $view->content->iptc_form = $form;
+ print $view;
+ }
+
+ private function _get_admin_form() {
+ // Make a new Form.
+ $form = new Forge("admin/iptc/saveprefs", "", "post", array("id" => "g-iptc-adminForm"));
+
+ // Create group for display settings
+ $iptc_display_group = $form->group("Global")
+ ->label(t("Display Settings"));
+
+ $show = t("Show");
+ foreach (iptc::keys() as $keyword => $iptcvar) {
+ unset($checkbox);
+ $checkbox[$keyword] = array($show." \"".$iptcvar[1]."\" ?", module::get_var("iptc", "show_".$keyword));
+ $iptc_display_group->checklist($keyword)
+ ->options($checkbox);
+ }
+ // Add a save button to the form.
+ $form->submit("SaveSettings")->value(t("Save"));
+
+ // Return the newly generated form.
+ return $form;
+ }
+}
diff --git a/modules/iptc/helpers/iptc.php b/modules/iptc/helpers/iptc.php
new file mode 100644
index 00000000..cca0f61f
--- /dev/null
+++ b/modules/iptc/helpers/iptc.php
@@ -0,0 +1,207 @@
+is_photo() && $item->mime_type == "image/jpeg") {
+ $info = getJpegHeader($item->file_path());
+ if ($info !== FALSE) {
+ $iptcBlock = getIptcBlock($info);
+ if ($iptcBlock !== FALSE) {
+ $iptc = iptcparse($iptcBlock);
+ } else {
+ $iptc = array();
+ }
+ $xmp = getXmpDom($info);
+
+ foreach (self::keys() as $keyword => $iptcvar) {
+ $iptc_key = $iptcvar[0];
+ $xpath = $iptcvar[2];
+ $value = null;
+ if ($xpath != null) {
+ $value = getXmpValue($xmp, $xpath);
+ }
+ if ($value == null) {
+ if (!empty($iptc[$iptc_key])) {
+ $value = implode(";", $iptc[$iptc_key]);
+ if (function_exists("mb_detect_encoding") && mb_detect_encoding($value) != "UTF-8") {
+ $value = utf8_encode($value);
+ }
+ }
+ }
+ if ($value != null) {
+ $keys[$keyword] = Input::clean($value);
+ }
+ }
+ }
+ }
+
+ $record = ORM::factory("iptc_record")->where("item_id", "=", $item->id)->find();
+ if (!$record->loaded()) {
+ $record->item_id = $item->id;
+ }
+ $record->data = serialize($keys);
+ $record->key_count = count($keys);
+ $record->dirty = 0;
+ $record->save();
+ }
+
+ static function get($item) {
+ $iptc = array();
+ $record = ORM::factory("iptc_record")
+ ->where("item_id", "=", $item->id)
+ ->find();
+ if (!$record->loaded()) {
+ return array();
+ }
+
+ $definitions = self::keys();
+ $keys = unserialize($record->data);
+ foreach ($keys as $key => $value) {
+ if (module::get_var("iptc", "show_".$key) == 1)
+ $iptc[] = array("caption" => $definitions[$key][1], "value" => $value);
+ }
+
+ return $iptc;
+ }
+
+
+ public static function keys() {
+ if (!isset(self::$iptc_keys)) {
+ self::$iptc_keys = array(
+ "ObjectName" => array("2#005",
+ t("IPTC Object Name"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/dc:title/rdf:Alt/rdf:li" ),
+ "EditStatus" => array("2#007",
+ t("IPTC Edit Status"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@mediapro:Status" ),
+ "Category" => array("2#015",
+ t("IPTC Category"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:Category" ),
+ "SupplementalCategories" => array("2#020",
+ t("IPTC Categories"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/photoshop:SupplementalCategories/rdf:Bag/rdf:li" ),
+ "FixtureIdentifier" => array("2#022",
+ t("IPTC Identifier"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@mediapro:Event" ),
+ "Keywords" => array("2#025",
+ t("IPTC Keywords"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/dc:subject/rdf:Bag/rdf:li" ),
+ "LocationCode" => array("2#026",
+ t("IPTC Location Code"),
+ null ),
+ "SpecialInstructions" => array("2#040",
+ t("IPTC Instructions"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:Instructions" ),
+ "DateCreated" => array("2#055",
+ t("IPTC Created Date"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:DateCreated" ),
+ "ByLine" => array("2#080",
+ t("IPTC Author"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/dc:creator/rdf:Seq/rdf:li" ),
+ "ByLineTitle" => array("2#085",
+ t("IPTC Author Title"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:AuthorsPosition" ),
+ "City" => array("2#090",
+ t("IPTC City"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:City" ),
+ "SubLocation" => array("2#092",
+ t("IPTC SubLocation"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@Iptc4xmpCore:Location | /x:xmpmeta/rdf:RDF/rdf:Description/@mediapro:Location" ),
+ "ProvinceState" => array("2#095",
+ t("IPTC Province State"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:State" ),
+ "CountryCode" => array("2#100",
+ t("IPTC Country Code"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@Iptc4xmpCore:CountryCode" ),
+ "CountryName" => array("2#101",
+ t("IPTC Country Name"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:Country" ),
+ "Transmission" => array("2#103",
+ t("IPTC Transmission,"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:TransmissionReference" ),
+ "HeadLine" => array("2#105",
+ t("IPTC HeadLine"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:Headline" ),
+ "Credit" => array("2#110",
+ t("IPTC Credit"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:Credit | /x:xmpmeta/rdf:RDF/rdf:Description/photoshop:Credit" ),
+ "Source" => array("2#115",
+ t("IPTC Source"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:Source" ),
+ "Copyright" => array("2#116",
+ t("IPTC Copyright"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/dc:rights/rdf:Alt/rdf:li" ),
+ "Contacts" => array("2#118",
+ t("IPTC Contacts"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/mediapro:People/rdf:Bag/rdf:li" ),
+ "Caption" => array("2#120",
+ t("IPTC Caption"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/dc:description/rdf:Alt/rdf:li" ),
+ "Redactor" => array("2#122",
+ t("IPTC Redactor"),
+ "/x:xmpmeta/rdf:RDF/rdf:Description/@photoshop:CaptionWriter" )
+ );
+ }
+ return self::$iptc_keys;
+ }
+
+
+ static function stats() {
+ $missing_iptc = db::build()
+ ->select("items.id")
+ ->from("items")
+ ->join("iptc_records", "items.id", "iptc_records.item_id", "left")
+ ->where("type", "=", "photo")
+ ->and_open()
+ ->where("iptc_records.item_id", "IS", null)
+ ->or_where("iptc_records.dirty", "=", 1)
+ ->close()
+ ->execute()
+ ->count();
+
+ $total_items = ORM::factory("item")->where("type", "=", "photo")->count_all();
+ if (!$total_items) {
+ return array(0, 0, 0);
+ }
+ return array($missing_iptc, $total_items,
+ round(100 * (($total_items - $missing_iptc) / $total_items)));
+ }
+
+ static function check_index() {
+ list ($remaining) = iptc::stats();
+ if ($remaining) {
+ site_status::warning(
+ t('Your Iptc index needs to be updated. Fix this now ',
+ array("url" => html::mark_clean(url::site("admin/maintenance/start/iptc_task::update_index?csrf=__CSRF__")))),
+ "iptc_index_out_of_date");
+ }
+ }
+}
diff --git a/modules/iptc/helpers/iptc_block.php b/modules/iptc/helpers/iptc_block.php
new file mode 100644
index 00000000..1a6ed955
--- /dev/null
+++ b/modules/iptc/helpers/iptc_block.php
@@ -0,0 +1,43 @@
+ t("IPTC info"));
+ }
+
+ static function get($block_id, $theme) {
+ $block = "";
+ switch ($block_id) {
+ case "iptc":
+ if ($theme->item()) {
+ $details = iptc::get($theme->item());
+ if (count($details) > 0) {
+ $block = new Block();
+ $block->css_id = "g-metadata";
+ $block->title = t("IPTC info");
+ $block->content = new View("iptc_block.html");
+ $block->content->details = $details;
+ }
+ }
+ break;
+ }
+ return $block;
+ }
+}
\ No newline at end of file
diff --git a/modules/iptc/helpers/iptc_event.php b/modules/iptc/helpers/iptc_event.php
new file mode 100644
index 00000000..c7b4a6cc
--- /dev/null
+++ b/modules/iptc/helpers/iptc_event.php
@@ -0,0 +1,42 @@
+is_photo()) {
+ iptc::extract($item);
+ }
+ }
+
+ static function item_deleted($item) {
+ db::build()
+ ->delete("iptc_records")
+ ->where("item_id", "=", $item->id)
+ ->execute();
+ }
+
+ static function admin_menu($menu, $theme) {
+ // Add a link to the admin page to the Settings menu.
+ $menu->get("settings_menu")
+ ->append(Menu::factory("link")
+ ->id("iptc")
+ ->label(t("IPTC Settings"))
+ ->url(url::site("admin/iptc")));
+ }
+}
diff --git a/modules/iptc/helpers/iptc_installer.php b/modules/iptc/helpers/iptc_installer.php
new file mode 100644
index 00000000..11a17a56
--- /dev/null
+++ b/modules/iptc/helpers/iptc_installer.php
@@ -0,0 +1,46 @@
+query("CREATE TABLE IF NOT EXISTS {iptc_records} (
+ `id` int(9) NOT NULL auto_increment,
+ `item_id` INTEGER(9) NOT NULL,
+ `key_count` INTEGER(9) default 0,
+ `data` TEXT,
+ `dirty` BOOLEAN default 1,
+ PRIMARY KEY (`id`),
+ KEY(`item_id`))
+ DEFAULT CHARSET=utf8;");
+ module::set_version("iptc", 1);
+ }
+
+ static function activate() {
+ iptc::check_index();
+ }
+
+ static function deactivate() {
+ site_status::clear("iptc_index_out_of_date");
+ }
+
+ static function uninstall() {
+ Database::instance()->query("DROP TABLE IF EXISTS {iptc_records};");
+ }
+}
diff --git a/modules/iptc/helpers/iptc_task.php b/modules/iptc/helpers/iptc_task.php
new file mode 100644
index 00000000..d4715bff
--- /dev/null
+++ b/modules/iptc/helpers/iptc_task.php
@@ -0,0 +1,88 @@
+delete("iptc_records")
+ ->where("item_id", "NOT IN",
+ db::build()->select("id")->from("items")->where("type", "=", "photo"))
+ ->execute();
+
+ list ($remaining, $total, $percent) = iptc::stats();
+ return array(Task_Definition::factory()
+ ->callback("iptc_task::update_index")
+ ->name(t("Extract Iptc data"))
+ ->description($remaining
+ ? t2("1 photo needs to be scanned",
+ "%count (%percent%) of your photos need to be scanned",
+ $remaining, array("percent" => (100 - $percent)))
+ : t("IPTC data is up-to-date"))
+ ->severity($remaining ? log::WARNING : log::SUCCESS));
+ }
+
+ static function update_index($task) {
+ try {
+ $completed = $task->get("completed", 0);
+
+ $start = microtime(true);
+ foreach (ORM::factory("item")
+ ->join("iptc_records", "items.id", "iptc_records.item_id", "left")
+ ->where("type", "=", "photo")
+ ->and_open()
+ ->where("iptc_records.item_id", "IS", null)
+ ->or_where("iptc_records.dirty", "=", 1)
+ ->close()
+ ->find_all() as $item) {
+ // The query above can take a long time, so start the timer after its done
+ // to give ourselves a little time to actually process rows.
+ if (!isset($start)) {
+ $start = microtime(true);
+ }
+
+ iptc::extract($item);
+ $completed++;
+
+ if (microtime(true) - $start > 1.5) {
+ break;
+ }
+ }
+
+ list ($remaining, $total, $percent) = iptc::stats();
+ $task->set("completed", $completed);
+ if ($remaining == 0 || !($remaining + $completed)) {
+ $task->done = true;
+ $task->state = "success";
+ site_status::clear("iptc_index_out_of_date");
+ $task->percent_complete = 100;
+ } else {
+ $task->percent_complete = round(100 * $completed / ($remaining + $completed));
+ }
+ $task->status = t2("one record updated, index is %percent% up-to-date",
+ "%count records updated, index is %percent% up-to-date",
+ $completed, array("percent" => $percent));
+ } catch (Exception $e) {
+ $task->done = true;
+ $task->state = "error";
+ $task->status = $e->getMessage();
+ $task->log((string)$e);
+ }
+ }
+}
diff --git a/modules/iptc/lib/functions.php b/modules/iptc/lib/functions.php
new file mode 100644
index 00000000..91ca129f
--- /dev/null
+++ b/modules/iptc/lib/functions.php
@@ -0,0 +1,97 @@
+ 0xD7) {
+ $size = fread($file, 2);
+ if ($size === FALSE) {
+ fclose($file);
+ return $result;
+ }
+ $sizeOfSegment = unpack("nV", $size);
+ $data = fread($file, $sizeOfSegment['V']-2);
+ if ($data === FALSE) {
+ fclose($file);
+ return $result;
+ }
+ if ($result === FALSE)
+ unset($result);
+ $result[] = array("type" => $typeOfSegment, "data" => $data); // Multiple segments can have the same type like Exif and XMP
+ }
+ } while (!feof($file));
+ fclose($file);
+ return $result;
+}
+
+
+function getIptcBlock($jpegHeader)
+{
+ for ($i = 0; $i < count($jpegHeader); $i++) {
+ if ($jpegHeader[$i]['type'] == 0xED) {
+ if (strncmp($jpegHeader[$i]['data'], "Photoshop 3.0\x00", 14) == 0) {
+ return $jpegHeader[$i]['data'];
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+function getXmpDom($jpegHeader)
+{
+ for ($i = 0; $i < count($jpegHeader); $i++) {
+ if ($jpegHeader[$i]['type'] == 0xE1) {
+ if (strncmp($jpegHeader[$i]['data'], "http://ns.adobe.com/xap/1.0/\x00", 29) == 0) {
+ $xmlstr = substr($jpegHeader[$i]['data'], 29);
+ $doc = new DOMDocument();
+ $doc->loadXML($xmlstr);
+ return $doc;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+function getXmpValue($dom, $xpathQuery)
+{
+ if ($dom === FALSE)
+ return null;
+ $xpath = new DOMXPath($dom);
+ $xpath->registerNamespace('rdf', "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
+ $xpath->registerNamespace('photoshop', "http://ns.adobe.com/photoshop/1.0/");
+ $xpath->registerNamespace('Iptc4xmpCore', "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/");
+ $xpath->registerNamespace('dc', "http://purl.org/dc/elements/1.1/");
+ $xpath->registerNamespace('mediapro', "http://ns.iview-multimedia.com/mediapro/1.0/");
+ $nodeList = $xpath->query($xpathQuery);
+ $result = "";
+ foreach ($nodeList as $node) {
+ if (!empty($result))
+ $result .= ';';
+ $result .= $node->nodeValue;
+ }
+ return $result;
+}
+
diff --git a/modules/iptc/models/iptc_key.php b/modules/iptc/models/iptc_key.php
new file mode 100644
index 00000000..fadcb37b
--- /dev/null
+++ b/modules/iptc/models/iptc_key.php
@@ -0,0 +1,21 @@
+
+
+
= t("IPTC Settings") ?>
+
+ = $iptc_form ?>
+
+
diff --git a/modules/iptc/views/iptc_block.html.php b/modules/iptc/views/iptc_block.html.php
new file mode 100644
index 00000000..c446935a
--- /dev/null
+++ b/modules/iptc/views/iptc_block.html.php
@@ -0,0 +1,9 @@
+
+
diff --git a/modules/moduleupdates/controllers/admin_moduleupdates.php b/modules/moduleupdates/controllers/admin_moduleupdates.php
index ba812515..1a7a2508 100644
--- a/modules/moduleupdates/controllers/admin_moduleupdates.php
+++ b/modules/moduleupdates/controllers/admin_moduleupdates.php
@@ -39,40 +39,136 @@ class Admin_Moduleupdates_Controller extends Admin_Controller {
* @author brentil
*/
public function index() {
+
$view = new Admin_View("admin.html");
$view->page_title = t("Gallery 3 :: Manage Module Updates");
$view->content = new View("admin_moduleupdates.html");
- $all_modules = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
+ $devDebug = false;
+ $refreshCache = false;
+
+ $cache = unserialize(Cache::instance()->get("moduleupdates_cache"));
+ $cache_updates = unserialize(Cache::instance()->get("moduleupdates_cache_updates"));
+
+ //---------------------------------------------------------------------------------------------
+ //echo 'Message 01: ' .$cache_updates . ' ';
+ //---------------------------------------------------------------------------------------------
+
+ //if someone pressed the button to refresh now
+ if (request::method() == "post") {
+ access::verify_csrf();
+ $cache = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
+ $cache_updates = array("date" => "", "updates" => 0);
+ $refreshCache = true;
+ }else if(count($cache) < 1 or $cache_updates['date'] == ""){
+ //if there are no items in the cache array or the update date is "" refresh the data
+ $cache = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
+ $cache_updates = array("date" => "", "updates" => 0);
+ $refreshCache = true;
+ }
+
+ //Check the ability to access the Gallery3 GitHub
+ $GitHub = null;
+ try {
+ $GitHub = fopen ("http://github.com", "r");
+ if ($GitHub != null) {
+ $GitHub = 'Online ';
+ }else{
+ $GitHub = 'Offline ';
+ }
+ }
+ catch (Exception $e) {
+ //echo 'Message: ' .$e->getMessage() . ' ';
+ }
+ //Check the ability to access the Google
+ $Google = null;
+ try {
+ $Google = fopen ("http://google.com", "r");
+ if ($Google != null) {
+ $Google = 'Online ';
+ }else{
+ $Google = 'Offline ';
+ }
+ }
+ catch (Exception $e) {
+ //echo 'Message: ' .$e->getMessage() . ' ';
+ }
- foreach (module::available() as $this_module_name => $module_info) {
-
- $remote_version = '';
- $remote_server = '';
-
- list ($remote_version, $remote_server) = $this->get_remote_module_version($this_module_name);
-
- $font_color = "black";
- if ($remote_version == "DNE") {
- $font_color = "blue";
- } else if ($module_info->version != '' and $module_info->code_version < $module_info->version) {
- $font_color = "pink";
- } else if ($module_info->version != '' and $module_info->code_version > $module_info->version) {
- $font_color = "orange";
- } else if ($remote_version < $module_info->code_version or ($module_info->version != '' and $remote_version < $module_info->version)) {
- $font_color = "green";
- } else if ($remote_version > $module_info->code_version or ($module_info->version != '' and $remote_version > $module_info->version)) {
- $font_color = "red";
- }
+ if($refreshCache == true){
+ foreach (module::available() as $this_module_name => $module_info) {
+
+ //example code for setting cache values
+ //Cache::instance()->set($key, "$log{$msg}", array("task", "log", "import"), 2592000);
+ //example delete cache
+ //Cache::instance()->delete("update_l10n_cache:{$task->id}");
+ //example for reading cache
+ //$log = Cache::instance()->get($key);
+
+ $remote_version = '';
+ $remote_server = '';
+ $update_count = 0;
+
+ list ($remote_version, $remote_server) = $this->get_remote_module_version($this_module_name, $devDebug);
+
+ $font_color = "black";
+ //BLUE - DNE: Does Not Exist, this module was not found
+ if ($remote_version == "DNE") {
+ $font_color = "blue";
+ //PINK - Your installed version is newer than file version
+ } else if ($module_info->version != '' and $module_info->code_version < $module_info->version) {
+ $font_color = "pink";
+ //ORANGE - Your file version is newer than the installed version
+ } else if ($module_info->version != '' and $module_info->code_version > $module_info->version) {
+ $font_color = "orange";
+ //GREEN - Your version is newer than the GitHub
+ } else if ($remote_version < $module_info->code_version or ($module_info->version != ''
+ and $remote_version < $module_info->version)) {
+ $font_color = "green";
+ //RED - Your version is older than the GitHub
+ } else if ($remote_version > $module_info->code_version or ($module_info->version != ''
+ and $remote_version > $module_info->version)) {
+ $font_color = "red";
+ $update_count++;
+ /*
+ if($remote_server == "(G3)"){
+ $module_info->name = "".$module_info->name." ";
+ }else if($remote_server == "(G3CC)"){
+ $module_info->name = "".$module_info->name." ";
+ }else if($remote_server == "(brentil)"){
+ $module_info->name = "".$module_info->name." ";
+ }
+ */
+ }
+
+ $module_info->name = "".$module_info->name." ";
+
+ //populate the list fo modules and their data
+ $cache->$this_module_name = array ("name" => $module_info->name, "locked" => $module_info->locked,
+ "code_version" => $module_info->code_version, "active" => $module_info->active,
+ "version" => $module_info->version,"description" => $module_info->description,
+ "remote_version" => $remote_version, "remote_server" => $remote_server, "font_color" => $font_color);
+ }
- $all_modules->$this_module_name = array ("name" => $module_info->name, "locked" => $module_info->locked,
- "code_version" => $module_info->code_version, "active" => $module_info->active,
- "version" => $module_info->version,"description" => $module_info->description,
- "remote_version" => $remote_version, "remote_server" => $remote_server, "font_color" => $font_color);
+ //Define right now as YYYY.MM.DD HH:MM with the # of updates that are out of date
+ $cache_updates = array("date" => date("Y.m.d - H:i"), "updates" => $update_count);
+
+ //---------------------------------------------------------------------------------------------
+ //echo 'Message 02: ' .$cache_updates . ' ';
+ //---------------------------------------------------------------------------------------------
+
+ //Write out the new data to cache with a 30 day expiration & 0 for update data so it's always present
+ Cache::instance()->set("moduleupdates_cache", serialize($cache), array("ModuleUpdates"), 30*86400);
+ Cache::instance()->set("moduleupdates_cache_updates", serialize($cache_updates), array("ModuleUpdates"), null);
+ log::success("moduleupdates", t("Completed checking remote GitHub for modules updates."));
}
+
+ $view->content->vars = $cache;
+ $view->content->update_time = $cache_updates['date'];
+ $view->content->csrf = access::csrf_token();
+ $view->content->Google = $Google;
+ $view->content->GitHub = $GitHub;
- $view->content->vars = $all_modules;
-
+
print $view;
}
@@ -91,22 +187,41 @@ class Admin_Moduleupdates_Controller extends Admin_Controller {
* @param String The folder name of the module to search for on the remote GitHub server
* @return Array An array with the remote module version and the server it was found on.
*/
- private function get_remote_module_version ($module_name) {
+ private function get_remote_module_version ($module_name, $devDebug) {
$version = 'DNE';
$server = '';
$file = null;
- try {
- $file = fopen ("http://github.com/gallery/gallery3/raw/master/modules/".$module_name."/module.info", "r");
- if ($file != null) {
- $server = '(G3)';
- }
- }
- catch (Exception $e) {
- //echo 'Message: ' .$e->getMessage() . ' ';
+ //For development debug only
+ if ($devDebug == true){
+ if ($file == null) {
+ try {
+ $file = fopen ("http://github.com/brentil/gallery3-contrib/raw/master/modules/".$module_name."/module.info", "r");
+ if ($file != null) {
+ $server = '(brentil)';
+ }
+ }
+ catch (Exception $e) {
+ //echo 'Message: ' .$e->getMessage() . ' ';
+ }
+ }
}
+
+ //Check the main Gallery3 GitHub
+ if ($file == null) {
+ try {
+ $file = fopen ("http://github.com/gallery/gallery3/raw/master/modules/".$module_name."/module.info", "r");
+ if ($file != null) {
+ $server = '(G3)';
+ }
+ }
+ catch (Exception $e) {
+ //echo 'Message: ' .$e->getMessage() . ' ';
+ }
+ }
+ //Check the Gallery3 Community Contributions GitHub
if ($file == null) {
try {
$file = fopen ("http://github.com/gallery/gallery3-contrib/raw/master/modules/".$module_name."/module.info", "r");
@@ -118,7 +233,7 @@ class Admin_Moduleupdates_Controller extends Admin_Controller {
//echo 'Message: ' .$e->getMessage() . ' ';
}
}
-
+
if ($file != null) {
while (!feof ($file)) {
$line = fgets ($file, 1024);
diff --git a/modules/moduleupdates/helpers/moduleupdates_installer.php b/modules/moduleupdates/helpers/moduleupdates_installer.php
index c15f4d82..dd0dddb8 100644
--- a/modules/moduleupdates/helpers/moduleupdates_installer.php
+++ b/modules/moduleupdates/helpers/moduleupdates_installer.php
@@ -17,21 +17,35 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
class moduleupdates_installer {
static function install() {
$version = module::get_version("moduleupdates");
if ($version == 0) {
- module::set_version("moduleupdates", 1);
+ module::set_version("moduleupdates", 2);
+ //Remove the ModuleUpdates cache entry 'JIC'
+ Cache::instance()->delete("ModuleUpdates");
+ //create the blank ModuleUpdates cache entry with an expiration of 0 days
+ Cache::instance()->set("moduleupdates_cache", "", array("ModuleUpdates"), null);
+ Cache::instance()->set("moduleupdates_cache_updates", "", array("ModuleUpdates"), null);
}
}
static function upgrade($version) {
+ module::set_version("moduleupdates", 2);
+ //Remove the ModuleUpdates cache entry 'JIC'
+ Cache::instance()->delete("ModuleUpdates");
+ //Empty the ModuleUpdates cache entry so our new version starts from scratch
+ Cache::instance()->set("moduleupdates_cache", "", array("ModuleUpdates"), null);
+ Cache::instance()->set("moduleupdates_cache_updates", "", array("ModuleUpdates"), null);
}
static function uninstall() {
-
+
+ //Remove the ModuleUpdates cache entry as we remove the module
+ Cache::instance()->delete("ModuleUpdates");
module::delete("moduleupdates");
}
}
diff --git a/modules/moduleupdates/module.info b/modules/moduleupdates/module.info
index 446d30db..8fad54ff 100644
--- a/modules/moduleupdates/module.info
+++ b/modules/moduleupdates/module.info
@@ -1,3 +1,3 @@
name = "Module Updates"
description = "Compares your installed module version against the ones stored in the GitHub."
-version = 1
+version = 2
diff --git a/modules/moduleupdates/views/admin_moduleupdates.html.php b/modules/moduleupdates/views/admin_moduleupdates.html.php
index 8a7c6494..3fdc06a7 100644
--- a/modules/moduleupdates/views/admin_moduleupdates.html.php
+++ b/modules/moduleupdates/views/admin_moduleupdates.html.php
@@ -1,21 +1,33 @@
+
-
= t("Module Updates v1.2") ?>
-
- = t("Compares your installed module version against the ones stored in the GitHub. ") ?>
- = t("Red = Your version is older than the GitHub ") ?>
- = t("Green = Your version is newer than the GitHub ") ?>
- = t("Orange = Your file version is newer than the installed version ") ?>
- = t("Pink = Your installed version is newer than file version ") ?>
- = t("Blue = Does Not Exist/No information available ") ?>
-
-
-
- = t("Versions are compared from the official Gallery3 (G3) and official Gallery3 Community Contributions (G3CC). Versions downloaded from the forums will not be shown.") ?>
-
-
+
= t("Module Updates v2.0") ?>
+ = t("Compares your installed module version against the ones stored in the GitHub.") ?>
+
+
+
+
+
+
+ = t("Versions are compared from the official Gallery3 (G3) and official Gallery3 Community Contributions (G3CC). Versions downloaded from the forums will not be shown.") ?>
+
+
= t("Module") ?>
@@ -25,14 +37,12 @@
foreach ($vars as $module_name): ?>
">
- echo ""; ?> = $module_name['name'] ?>
+ echo ""; ?> = t($module_name['name']) ?>
echo ""; ?> = $module_name['code_version'] ?> if ($module_name['version'] != '') echo "/".$module_name['version']; ?>
echo ""; ?> = $module_name['remote_version'] ?> = $module_name['remote_server'] ?>
- echo ""; ?> = $module_name['description'] ?>
+ echo ""; ?> = t($module_name['description']) ?>
endforeach ?>
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/modules/photoannotation/controllers/admin_photoannotation.php b/modules/photoannotation/controllers/admin_photoannotation.php
new file mode 100644
index 00000000..58d53444
--- /dev/null
+++ b/modules/photoannotation/controllers/admin_photoannotation.php
@@ -0,0 +1,57 @@
+_get_view();
+ }
+
+ public function handler() {
+ access::verify_csrf();
+
+ $form = $this->_get_form();
+ if ($form->validate()) {
+ module::set_var(
+ "photoannotation", "showfaces", $form->photoannotation->showfaces->value, true);
+ module::set_var(
+ "photoannotation", "shownotes", $form->photoannotation->shownotes->value, true);
+ message::success(t("Your settings have been saved."));
+ url::redirect("admin/photoannotation");
+ }
+ print $this->_get_view($form);
+ }
+
+ private function _get_view($form=null) {
+ $v = new Admin_View("admin.html");
+ $v->content = new View("admin_photoannotation.html");
+ $v->content->form = empty($form) ? $this->_get_form() : $form;
+ return $v;
+ }
+
+ private function _get_form() {
+ $form = new Forge("admin/photoannotation/handler", "", "post", array("id" => "g-admin-form"));
+ $group = $form->group("photoannotation")->label(t("Photo annotation settings"));
+ $group->checkbox("showfaces")->label(t("Show face annotation below photo."))
+ ->checked(module::get_var("photoannotation", "showfaces", false));
+ $group->checkbox("shownotes")->label(t("Show note annotations below photo."))
+ ->checked(module::get_var("photoannotation", "shownotes", false));
+ $form->submit("submit")->value(t("Save"));
+ return $form;
+ }
+}
diff --git a/modules/photoannotation/controllers/photoannotation.php b/modules/photoannotation/controllers/photoannotation.php
new file mode 100644
index 00000000..ea697be4
--- /dev/null
+++ b/modules/photoannotation/controllers/photoannotation.php
@@ -0,0 +1,162 @@
+item_id = $item_data;
+ $newnote->x1 = $str_x1;
+ $newnote->y1 = $str_y1;
+ $newnote->x2 = $str_x2;
+ $newnote->y2 = $str_y2;
+ $newnote->title = $str_face_title;
+ $newnote->description = $str_face_description;
+ $newnote->save();
+ } else {
+ // Save the new face to the database.
+ $newface = ORM::factory("items_face");
+ $newface->tag_id = $tag_data;
+ $newface->item_id = $item_data;
+ $newface->x1 = $str_x1;
+ $newface->y1 = $str_y1;
+ $newface->x2 = $str_x2;
+ $newface->y2 = $str_y2;
+ $newface->description = $str_face_description;
+ $newface->save();
+ }
+ } else { //update existing annotation
+ if ($notetype == "face") { //this is a face
+ $updatedAnnotation = ORM::factory("items_face")
+ ->where("id", "=", $noteid)
+ ->find();
+ if ($tag_data == -1) { //needs conversion to note
+ if ($str_face_title == "") {
+ message::error(t("Please select a Tag or specify a Title."));
+ url::redirect($redir_uri);
+ return;
+ }
+ //Save note
+ $newnote = ORM::factory("items_note");
+ $newnote->item_id = $item_data;
+ $newnote->x1 = $str_x1;
+ $newnote->y1 = $str_y1;
+ $newnote->x2 = $str_x2;
+ $newnote->y2 = $str_y2;
+ $newnote->title = $str_face_title;
+ $newnote->description = $str_face_description;
+ $newnote->save();
+ $updatedAnnotation->delete();
+ } else { //stays a face
+ $updatedAnnotation->tag_id = $tag_data;
+ $updatedAnnotation->item_id = $item_data;
+ $updatedAnnotation->x1 = $str_x1;
+ $updatedAnnotation->y1 = $str_y1;
+ $updatedAnnotation->x2 = $str_x2;
+ $updatedAnnotation->y2 = $str_y2;
+ $updatedAnnotation->description = $str_face_description;
+ $updatedAnnotation->save();
+ }
+ } else { //this is a note
+ $updatedAnnotation = ORM::factory("items_note")
+ ->where("id", "=", $noteid)
+ ->find();
+ if ($tag_data == -1) { //stays a note
+ if ($str_face_title == "") {
+ message::error(t("Please select a Tag or specify a Title."));
+ url::redirect($redir_uri);
+ return;
+ }
+ $updatedAnnotation->item_id = $item_data;
+ $updatedAnnotation->x1 = $str_x1;
+ $updatedAnnotation->y1 = $str_y1;
+ $updatedAnnotation->x2 = $str_x2;
+ $updatedAnnotation->y2 = $str_y2;
+ $updatedAnnotation->title = $str_face_title;
+ $updatedAnnotation->description = $str_face_description;
+ $updatedAnnotation->save();
+ } else { //needs conversion to a face
+ $newface = ORM::factory("items_face");
+ $newface->tag_id = $tag_data;
+ $newface->item_id = $item_data;
+ $newface->x1 = $str_x1;
+ $newface->y1 = $str_y1;
+ $newface->x2 = $str_x2;
+ $newface->y2 = $str_y2;
+ $newface->description = $str_face_description;
+ $newface->save();
+ $updatedAnnotation->delete();
+ }
+ }
+ }
+ message::success(t("Annotation saved."));
+ url::redirect($redir_uri);
+ return;
+ }
+
+ public function delete() {
+ // Prevent Cross Site Request Forgery
+ access::verify_csrf();
+
+ //Get form data
+ $noteid = $_POST["noteid"];
+ $notetype = $_POST["notetype"];
+ $redir_uri = $_POST["currenturl"];
+
+ if ($noteid == "" || $notetype == "") {
+ message::error(t("Please select a tag or note to delete."));
+ url::redirect($redir_uri);
+ return;
+ }
+
+ if ($notetype == "face") {
+ db::build()->delete("items_faces")->where("id", "=", $noteid)->execute();
+ message::success(t("Annotation deleted."));
+ } elseif ($notetype == "note") {
+ db::build()->delete("items_notes")->where("id", "=", $noteid)->execute();
+ message::success(t("Annotation deleted."));
+ } else {
+ message::error(t("Please select a tag or note to delete."));
+ }
+ url::redirect($redir_uri);
+ }
+}
diff --git a/modules/photoannotation/css/photoannotation.css b/modules/photoannotation/css/photoannotation.css
new file mode 100644
index 00000000..e578e0d9
--- /dev/null
+++ b/modules/photoannotation/css/photoannotation.css
@@ -0,0 +1,186 @@
+.image-annotate-canvas {
+ background-position: left top;
+ background-repeat: no-repeat;
+ display: block;
+ margin: 0 auto;
+ position: relative;
+}
+.image-annotate-view {
+ display: none;
+ position: relative;
+}
+.image-annotate-area {
+ border: 1px solid #000000;
+ position: absolute;
+ cursor: default;
+}
+.image-annotate-area div {
+ border: 1px solid #FFFFFF;
+ display: block;
+}
+.image-annotate-area-editable {
+ cursor: pointer;
+}
+.image-annotate-area-editable-hover div {
+ border-color: #00AD00 !important;
+}
+.image-annotate-note {
+ background: #000000 none repeat scroll 0 0;
+ color: #FFFFFF;
+ display: none;
+ font-family: Verdana, Sans-Serif;
+ font-size: 1.4em;
+ max-width: 200px;
+ padding: 3px 7px;
+ position: absolute;
+}
+.image-annotate-note .actions {
+ display: block;
+ font-size: 80%;
+}
+.image-annotate-edit {
+ display: none;
+}
+#image-annotate-edit-form {
+ background: #FFFFFF none repeat scroll 0 0;
+ border: 1px solid #000000;
+ height: 220px;
+ padding: 7px;
+ position: absolute;
+ width: 250px;
+}
+#image-annotate-edit-form form {
+ clear: right;
+ margin: 0 !important;
+ padding: 0;
+ z-index: 999;
+ text-align: left;
+ color: #000000;
+}
+#image-annotate-edit-form .box {
+ margin: 0;
+}
+#image-annotate-edit-form input.form-text, #image-annotate-edit-form #edit-comment-wrapper textarea {
+ width: 90%;
+}
+#image-annotate-edit-form textarea {
+ height: 50px;
+ font-family: Verdana, Sans-Serif;
+ font-size: 12px;
+ width: 248px;
+}
+#image-annotate-edit-form fieldset {
+ background: transparent none repeat scroll 0 0;
+}
+#image-annotate-edit-form .form-item {
+ margin: 0 0 5px;
+}
+#image-annotate-edit-form .form-button, #image-annotate-edit-form .form-submit {
+ margin: 0;
+}
+#image-annotate-edit-form a {
+ cursor: pointer;
+ display: block;
+ float: left;
+ margin: 3px 6px 3px 0;
+}
+.image-annotate-edit-area {
+ border: 1px solid black;
+ cursor: move;
+ display: block;
+ height: 60px;
+ left: 10px;
+ margin: 0;
+ padding: 0;
+ position: absolute;
+ top: 10px;
+ width: 60px;
+}
+.image-annotate-edit-area .ui-resizable-handle {
+ opacity: 0.8;
+}
+.image-annotate-edit-ok {
+ /*background-image: url(../images/accept.png);*/
+}
+.image-annotate-edit-delete {
+ background-image: url(../images/delete.png);
+}
+.image-annotate-edit-close {
+ /*background-image: url(../images/cross.png);*/
+}
+.ui-resizable {
+ position: relative;
+}
+.ui-resizable-handle {
+ position: absolute;
+ font-size: 0.1px;
+ z-index: 99999;
+ display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable- autohide .ui-resizable-handle {
+ display: block;
+}
+.ui-resizable-n {
+ cursor: n-resize;
+ height: 7px;
+ width: 100%;
+ top: -5px;
+ left: 0px;
+}
+.ui-resizable-s {
+ cursor: s-resize;
+ height: 7px;
+ width: 100%;
+ bottom: -5px;
+ left: 0px;
+}
+.ui-resizable-e {
+ cursor: e-resize;
+ width: 7px;
+ right: -5px;
+ top: 0px;
+ height: 100%;
+}
+.ui-resizable-w {
+ cursor: w-resize;
+ width: 7px;
+ left: -5px;
+ top: 0px;
+ height: 100%;
+}
+.ui-resizable-se {
+ cursor: se-resize;
+ width: 12px;
+ height: 12px;
+ right: 1px;
+ bottom: 1px;
+}
+.ui-resizable-sw {
+ cursor: sw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ bottom: -5px;
+}
+.ui-resizable-nw {
+ cursor: nw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ top: -5px;
+}
+.ui-resizable-ne {
+ cursor: ne-resize;
+ width: 9px;
+ height: 9px;
+ right: -5px;
+ top: -5px;
+}
+.photoannotation-del-button {
+ background-image: url('../images/delete.png');
+ cursor: pointer;
+}
+.photoannotation-edit-button {
+ background-image: url('../images/edit.png');
+ cursor: pointer;
+}
diff --git a/modules/photoannotation/helpers/photoannotation_event.php b/modules/photoannotation/helpers/photoannotation_event.php
new file mode 100644
index 00000000..2a40e8ae
--- /dev/null
+++ b/modules/photoannotation/helpers/photoannotation_event.php
@@ -0,0 +1,88 @@
+deactivate)) {
+ site_status::warning(
+ t("The Photo Annotation module requires the Tags module. " .
+ "Activate the Tags module now ",
+ array("url" => url::site("admin/modules"))),
+ "photoannotation_needs_tag");
+ } else {
+ site_status::clear("photoannotation_needs_tag");
+ }
+ if (module::is_active("tagfaces") || in_array("tagfaces", $changes->activate)) {
+ site_status::warning(
+ t("The Photo Annotation module cannot be used together with the TagFaces module. " .
+ "Dectivate the TagFaces module now ",
+ array("url" => url::site("admin/modules"))),
+ "photoannotation_incompatibility_tagfaces");
+ } else {
+ site_status::clear("photoannotation_incompatibility_tagfaces");
+ }
+ }
+
+ static function site_menu($menu, $theme) {
+ // Create a menu option for adding face data.
+ if (!$theme->item()) {
+ return;
+ }
+
+ $item = $theme->item();
+
+ if ($item->is_photo()) {
+ if ((access::can("view", $item)) && (access::can("edit", $item))) {
+ $menu->get("options_menu")
+ ->append(Menu::factory("link")
+ ->id("photoannotation")
+ ->label(t("Add annotation"))
+ ->css_id("g-photoannotation-link")
+ ->url("#"));
+ }
+ }
+ }
+
+ static function item_deleted($item) {
+ // Check for and delete existing Faces and Notes.
+ $existingFaces = ORM::factory("items_face")
+ ->where("item_id", "=", $item->id)
+ ->find_all();
+ if (count($existingFaces) > 0) {
+ db::build()->delete("items_faces")->where("item_id", "=", $item->id)->execute();
+ }
+
+ $existingNotes = ORM::factory("items_note")
+ ->where("item_id", "=", $item->id)
+ ->find_all();
+ if (count($existingNotes) > 0) {
+ db::build()->delete("items_notes")->where("item_id", "=", $item->id)->execute();
+ }
+ }
+
+ static function admin_menu($menu, $theme) {
+ $menu->get("settings_menu")
+ ->append(Menu::factory("link")
+ ->id("photoannotation_menu")
+ ->label(t("Photo Annotation"))
+ ->url(url::site("admin/photoannotation")));
+ }
+}
diff --git a/modules/photoannotation/helpers/photoannotation_installer.php b/modules/photoannotation/helpers/photoannotation_installer.php
new file mode 100644
index 00000000..0f84aad8
--- /dev/null
+++ b/modules/photoannotation/helpers/photoannotation_installer.php
@@ -0,0 +1,86 @@
+query("CREATE TABLE IF NOT EXISTS {items_faces} (
+ `id` int(9) NOT NULL auto_increment,
+ `tag_id` int(9) NOT NULL,
+ `item_id` int(9) NOT NULL,
+ `x1` int(9) NOT NULL,
+ `y1` int(9) NOT NULL,
+ `x2` int(9) NOT NULL,
+ `y2` int(9) NOT NULL,
+ `description` varchar(2048) default NULL,
+ PRIMARY KEY (`id`))
+ DEFAULT CHARSET=utf8;");
+
+ $db->query("CREATE TABLE IF NOT EXISTS {items_notes} (
+ `id` int(9) NOT NULL auto_increment,
+ `item_id` int(9) NOT NULL,
+ `x1` int(9) NOT NULL,
+ `y1` int(9) NOT NULL,
+ `x2` int(9) NOT NULL,
+ `y2` int(9) NOT NULL,
+ `title` varchar(64) NOT NULL,
+ `description` varchar(2048) default NULL,
+ PRIMARY KEY (`id`))
+ DEFAULT CHARSET=utf8;");
+
+ // Set the module's version number.
+ module::set_version("photoannotation", 1);
+ }
+
+ static function upgrade($version) {
+ $db = Database::instance();
+ if ($version == 1) {
+ $db->query("ALTER TABLE {items_faces} ADD `description` varchar(2048) default NULL");
+
+ $db->query("CREATE TABLE IF NOT EXISTS {items_notes} (
+ `id` int(9) NOT NULL auto_increment,
+ `item_id` int(9) NOT NULL,
+ `x1` int(9) NOT NULL,
+ `y1` int(9) NOT NULL,
+ `x2` int(9) NOT NULL,
+ `y2` int(9) NOT NULL,
+ `title` varchar(64) NOT NULL,
+ `description` varchar(2048) default NULL,
+ PRIMARY KEY (`id`))
+ DEFAULT CHARSET=utf8;");
+
+ module::set_version("photoannotation", $version = 1);
+ }
+ }
+
+ static function deactivate() {
+ // Clear the require tags message when photoannotation is deactivated.
+ site_status::clear("photoannotation_needs_tag");
+ site_status::clear("photoannotation_incompatibility_tagfaces");
+ }
+
+ static function uninstall() {
+ // Delete the face table before uninstalling.
+ $db = Database::instance();
+ $db->query("DROP TABLE IF EXISTS {items_faces};");
+ $db->query("DROP TABLE IF EXISTS {items_notes};");
+ module::delete("photoannotation");
+ }
+}
diff --git a/modules/photoannotation/helpers/photoannotation_theme.php b/modules/photoannotation/helpers/photoannotation_theme.php
new file mode 100644
index 00000000..e1374aa9
--- /dev/null
+++ b/modules/photoannotation/helpers/photoannotation_theme.php
@@ -0,0 +1,32 @@
+css("photoannotation.css");
+ $theme->script("jquery.annotate.js");
+ //Return "";
+ }
+
+ static function photo_bottom($theme) {
+ // If it does, add an image map to the page to display them.
+ return new View("photoannotation_highlight_block.html");
+ }
+}
diff --git a/modules/photoannotation/images/delete.png b/modules/photoannotation/images/delete.png
new file mode 100644
index 00000000..13eccb1c
Binary files /dev/null and b/modules/photoannotation/images/delete.png differ
diff --git a/modules/photoannotation/images/edit.png b/modules/photoannotation/images/edit.png
new file mode 100644
index 00000000..6dbcb679
Binary files /dev/null and b/modules/photoannotation/images/edit.png differ
diff --git a/modules/photoannotation/js/jquery.annotate.js b/modules/photoannotation/js/jquery.annotate.js
new file mode 100644
index 00000000..30e8f8ae
--- /dev/null
+++ b/modules/photoannotation/js/jquery.annotate.js
@@ -0,0 +1,500 @@
+///
+(function($) {
+
+ $.fn.annotateImage = function(options) {
+ ///
+ /// Creates annotations on the given image.
+ /// Images are loaded from the "getUrl" propety passed into the options.
+ ///
+ var opts = $.extend({}, $.fn.annotateImage.defaults, options);
+ var image = this;
+
+ this.image = this;
+ this.mode = 'view';
+
+ // Assign defaults
+ this.getUrl = opts.getUrl;
+ this.saveUrl = opts.saveUrl;
+ this.deleteUrl = opts.deleteUrl;
+ this.currentUrl = opts.currentUrl;
+ this.deleteUrl = opts.deleteUrl;
+ this.editable = opts.editable;
+ this.useAjax = opts.useAjax;
+ this.tags = opts.tags;
+ this.notes = opts.notes;
+ this.labels = opts.labels;
+ this.csrf = opts.csrf;
+ this.cssaclass = opts.cssaclass;
+
+ // Add the canvas
+ this.canvas = $('');
+ this.canvas.children('.image-annotate-edit').hide();
+ this.canvas.children('.image-annotate-view').hide();
+ this.image.after(this.canvas);
+
+ // Give the canvas and the container their size and background
+ this.canvas.height(this.height());
+ this.canvas.width(this.width());
+ this.canvas.css('background-image', 'url("' + this.attr('src') + '")');
+ this.canvas.children('.image-annotate-view, .image-annotate-edit').height(this.height());
+ this.canvas.children('.image-annotate-view, .image-annotate-edit').width(this.width());
+
+ // Add the behavior: hide/show the notes when hovering the picture
+ this.canvas.hover(function() {
+ if ($(this).children('.image-annotate-edit').css('display') == 'none') {
+ $(this).children('.image-annotate-view').show();
+ }
+ }, function() {
+ $(this).children('.image-annotate-view').hide();
+ $(this).children('.image-annotate-note').hide();
+ });
+
+ this.canvas.children('.image-annotate-view').hover(function() {
+ $(this).show();
+ }, function() {
+ $(this).hide();
+ $(this).children('.image-annotate-note').hide();
+ });
+
+ // load the notes
+ if (this.useAjax) {
+ $.fn.annotateImage.ajaxLoad(this);
+ } else {
+ $.fn.annotateImage.load(this, this.labels, this.editable, this.csrf, this.deleteUrl, this.currentUrl, this.tags, this.saveUrl, this.cssaclass);
+ }
+
+ // Add the "Add a note" button
+ if ($('#g-photoannotation-link').length != 0) {
+ this.button = $('#g-photoannotation-link');
+ this.button.click(function() {
+ $.fn.annotateImage.add(image, opts.tags, opts.labels, opts.saveUrl, opts.currentUrl, opts.csrf);
+ });
+ //this.canvas.after(this.button);
+ }
+
+ // Hide the original
+ this.hide();
+
+ return this;
+ };
+
+ /**
+ * Plugin Defaults
+ **/
+ $.fn.annotateImage.defaults = {
+ getUrl: 'your-get.rails',
+ saveUrl: 'your-save.rails',
+ deleteUrl: 'your-delete.rails',
+ editable: true,
+ useAjax: true,
+ tags: new Array(),
+ notes: new Array()
+ };
+
+ $.fn.annotateImage.clear = function(image) {
+ ///
+ /// Clears all existing annotations from the image.
+ ///
+ for (var i = 0; i < image.notes.length; i++) {
+ image.notes[image.notes[i]].destroy();
+ }
+ image.notes = new Array();
+ };
+
+ $.fn.annotateImage.ajaxLoad = function(image) {
+ ///
+ /// Loads the annotations from the "getUrl" property passed in on the
+ /// options object.
+ ///
+ $.getJSON(image.getUrl + '?ticks=' + $.fn.annotateImage.getTicks(), function(data) {
+ image.notes = data;
+ $.fn.annotateImage.load(image);
+ });
+ };
+
+ $.fn.annotateImage.load = function(image, labels, editable, csrf, deleteUrl, currentUrl, tags, saveUrl, cssaclass) {
+ ///
+ /// Loads the annotations from the notes property passed in on the
+ /// options object.
+ ///
+ for (var i = 0; i < image.notes.length; i++) {
+ image.notes[image.notes[i]] = new $.fn.annotateView(image, image.notes[i], tags, labels, editable, csrf, deleteUrl, currentUrl, saveUrl, cssaclass);
+ }
+ };
+
+ $.fn.annotateImage.getTicks = function() {
+ ///
+ /// Gets a count og the ticks for the current date.
+ /// This is used to ensure that URLs are always unique and not cached by the browser.
+ ///
+ var now = new Date();
+ return now.getTime();
+ };
+
+ $.fn.annotateImage.add = function(image, tags, labels, saveUrl, currentUrl, csrf) {
+ ///
+ /// Adds a note to the image.
+ ///
+ if (image.mode == 'view') {
+ image.mode = 'edit';
+
+ // Create/prepare the editable note elements
+ var editable = new $.fn.annotateEdit(image, null, tags, labels, saveUrl, currentUrl, csrf);
+
+ $.fn.annotateImage.createSaveButton(editable, image);
+ $.fn.annotateImage.createCancelButton(editable, image);
+ }
+ };
+
+ $.fn.annotateImage.createSaveButton = function(editable, image, note) {
+ ///
+ /// Creates a Save button on the editable note.
+ ///
+ var ok = $('OK ');
+
+ ok.click(function() {
+ var form = $('#image-annotate-edit-form form');
+ var text = $('#image-annotate-text').val();
+ $.fn.annotateImage.appendPosition(form, editable)
+ image.mode = 'view';
+
+ form.submit();
+
+ editable.destroy();
+ });
+ editable.form.append(ok);
+ };
+
+ $.fn.annotateImage.createCancelButton = function(editable, image) {
+ ///
+ /// Creates a Cancel button on the editable note.
+ ///
+ var cancel = $('Cancel ');
+ cancel.click(function() {
+ editable.destroy();
+ image.mode = 'view';
+ location.reload();
+ });
+ editable.form.append(cancel);
+ };
+
+ $.fn.annotateImage.saveAsHtml = function(image, target) {
+ var element = $(target);
+ var html = "";
+ for (var i = 0; i < image.notes.length; i++) {
+ html += $.fn.annotateImage.createHiddenField("text_" + i, image.notes[i].text);
+ html += $.fn.annotateImage.createHiddenField("top_" + i, image.notes[i].top);
+ html += $.fn.annotateImage.createHiddenField("left_" + i, image.notes[i].left);
+ html += $.fn.annotateImage.createHiddenField("height_" + i, image.notes[i].height);
+ html += $.fn.annotateImage.createHiddenField("width_" + i, image.notes[i].width);
+ }
+ element.html(html);
+ };
+
+ $.fn.annotateImage.createHiddenField = function(name, value) {
+ return '<input type="hidden" name="' + name + '" value="' + value + '" /> ';
+ };
+
+ $.fn.annotateEdit = function(image, note, tags, labels, saveUrl, currentUrl, csrf) {
+ ///
+ /// Defines an editable annotation area.
+ ///
+ this.image = image;
+
+ if (note) {
+ this.note = note;
+ } else {
+ var newNote = new Object();
+ newNote.noteid = "new";
+ newNote.top = 30;
+ newNote.left = 30;
+ newNote.width = 30;
+ newNote.height = 30;
+ newNote.text = "";
+ newNote.description = "";
+ newNote.notetype = "";
+ this.note = newNote;
+ }
+
+ // Set area
+ var area = image.canvas.children('.image-annotate-edit').children('.image-annotate-edit-area');
+ this.area = area;
+ this.area.css('height', this.note.height + 'px');
+ this.area.css('width', this.note.width + 'px');
+ this.area.css('left', this.note.left + 'px');
+ this.area.css('top', this.note.top + 'px');
+
+ // Show the edition canvas and hide the view canvas
+ image.canvas.children('.image-annotate-view').hide();
+ image.canvas.children('.image-annotate-edit').show();
+
+ // Add the note (which we'll load with the form afterwards)
+ var selectedtag = "";
+ if (this.note.text == "" || this.note.notetype == "note")
+ {
+ selectedtag = " selected=\"selected\"";
+ }
+ var tagdropdown = labels[0] + 'No Tag ';
+ if (tags)
+ {
+ for (var tag in tags)
+ {
+ var tagval = tags[tag];
+ selectedtag = "";
+ if (tagval.name == this.note.text && this.note.notetype == "face") {
+ selectedtag = " selected=\"selected\"";
+ }
+ tagdropdown += '' + tagval.name + ' ';
+ }
+ }
+ tagdropdown += ' ';
+ var notetitle = "";
+ if (this.note.notetype == "note") {
+ notetitle = this.note.text;
+ }
+ var form = $('
');
+ this.form = form;
+
+ $('body').append(this.form);
+ this.form.css('left', this.area.offset().left + 'px');
+ this.form.css('top', (parseInt(this.area.offset().top) + parseInt(this.area.height()) + 7) + 'px');
+
+ // Set the area as a draggable/resizable element contained in the image canvas.
+ // Would be better to use the containment option for resizable but buggy
+ area.resizable({
+ handles: 'all',
+
+ stop: function(e, ui) {
+ form.css('left', area.offset().left + 'px');
+ form.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) + 'px');
+ }
+ })
+ .draggable({
+ containment: image.canvas,
+ drag: function(e, ui) {
+ form.css('left', area.offset().left + 'px');
+ form.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) + 'px');
+ },
+ stop: function(e, ui) {
+ form.css('left', area.offset().left + 'px');
+ form.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) + 'px');
+ }
+ });
+ return this;
+ };
+
+ $.fn.annotateEdit.prototype.destroy = function() {
+ ///
+ /// Destroys an editable annotation area.
+ ///
+ this.image.canvas.children('.image-annotate-edit').hide();
+ this.area.resizable('destroy');
+ this.area.draggable('destroy');
+ this.area.css('height', '');
+ this.area.css('width', '');
+ this.area.css('left', '');
+ this.area.css('top', '');
+ this.form.remove();
+ }
+
+ $.fn.annotateView = function(image, note, tags, labels, editable, csrf, deleteUrl, currentUrl, saveUrl, cssaclass) {
+ ///
+ /// Defines a annotation area.
+ ///
+ this.image = image;
+
+ this.note = note;
+
+ // Add the area
+ this.area = $('');
+ image.canvas.children('.image-annotate-view').prepend(this.area);
+
+ if (editable) {
+ this.delarea = $('');
+ this.editarea = $('');
+ image.canvas.children('.image-annotate-view').prepend(this.delarea);
+ image.canvas.children('.image-annotate-view').prepend(this.editarea);
+ this.delarea.bind('click',function () {
+ if (confirm(labels[3])) {
+ var alink = $(cssaclass);
+ alink.unbind();
+ alink.attr ('href', '#');
+ alink.removeAttr ('rel');
+ var delform = $(this).children('div').children('form');
+ delform.submit();
+ }
+ })
+ var form = this;
+ this.editarea.bind('click',function () {
+ var alink = $(cssaclass);
+ alink.unbind();
+ alink.attr ('href', '#');
+ alink.removeAttr ('rel');
+ form.edit(tags, labels, saveUrl, currentUrl, csrf);
+ })
+ this.delarea.hide();
+ this.editarea.hide();
+ }
+
+ // Add the note
+ var notedescription = "";
+ if (note.description != "") {
+ notedescription = " " + note.description;
+ }
+ this.form = $('' + note.text + notedescription + '
');
+ this.form.hide();
+ image.canvas.children('.image-annotate-view').append(this.form);
+ this.form.children('span.actions').hide();
+
+ // Set the position and size of the note
+ this.setPosition();
+
+ // Add the behavior: hide/display the note when hovering the area
+ var annotation = this;
+ this.area.hover(function() {
+ annotation.show();
+ if (annotation.delarea != undefined) {
+ annotation.delarea.show();
+ annotation.editarea.show();
+ }
+ }, function() {
+ annotation.hide();
+ if (annotation.delarea != undefined) {
+ annotation.delarea.hide();
+ annotation.editarea.hide();
+ }
+ });
+
+ if (editable) {
+ this.delarea.hover(function() {
+ annotation.delarea.show();
+ annotation.editarea.show();
+ }, function() {
+ annotation.delarea.hide();
+ annotation.editarea.hide();
+ });
+ this.editarea.hover(function() {
+ annotation.delarea.show();
+ annotation.editarea.show();
+ }, function() {
+ annotation.delarea.hide();
+ annotation.editarea.hide();
+ });
+ }
+ // Edit a note feature
+ if (note.url != "" && note.url != null) {
+ this.area.bind('click',function () {
+ var alink = $(cssaclass);
+ alink.unbind();
+ alink.attr ('href', '#');
+ alink.removeAttr ('rel');
+ window.location = note.url;
+ })
+ }
+ };
+
+ $.fn.annotateView.prototype.setPosition = function() {
+ ///
+ /// Sets the position of an annotation.
+ ///
+ this.area.children('div').height((parseInt(this.note.height) - 2) + 'px');
+ this.area.children('div').width((parseInt(this.note.width) - 2) + 'px');
+ this.area.css('left', (this.note.left) + 'px');
+ this.area.css('top', (this.note.top) + 'px');
+ this.form.css('left', (this.note.left) + 'px');
+ this.form.css('top', (parseInt(this.note.top) + parseInt(this.note.height) + 7) + 'px');
+
+ if (this.delarea != undefined) {
+ this.delarea.children('div').height('14px');
+ this.delarea.children('div').width('14px');
+ this.delarea.css('left', (this.note.left + parseInt(this.note.width)) + 'px');
+ this.delarea.css('top', (this.note.top) + 'px');
+ this.editarea.children('div').height('14px');
+ this.editarea.children('div').width('14px');
+ this.editarea.css('left', (this.note.left + parseInt(this.note.width)) + 'px');
+ this.editarea.css('top', (this.note.top + 16) + 'px');
+ }
+ };
+
+ $.fn.annotateView.prototype.show = function() {
+ ///
+ /// Highlights the annotation
+ ///
+ this.form.fadeIn(250);
+ if (!this.note.editable) {
+ this.area.addClass('image-annotate-area-hover');
+ } else {
+ this.area.addClass('image-annotate-area-editable-hover');
+ }
+ };
+
+ $.fn.annotateView.prototype.hide = function() {
+ ///
+ /// Removes the highlight from the annotation.
+ ///
+ this.form.fadeOut(250);
+ this.area.removeClass('image-annotate-area-hover');
+ this.area.removeClass('image-annotate-area-editable-hover');
+ };
+
+ $.fn.annotateView.prototype.destroy = function() {
+ ///
+ /// Destroys the annotation.
+ ///
+ this.area.remove();
+ this.form.remove();
+ }
+
+ $.fn.annotateView.prototype.edit = function(tags, labels, saveUrl, currentUrl, csrf) {
+ ///
+ /// Edits the annotation.
+ ///
+ if (this.image.mode == 'view') {
+ this.image.mode = 'edit';
+ var annotation = this;
+
+ // Create/prepare the editable note elements
+ var editable = new $.fn.annotateEdit(this.image, this.note, tags, labels, saveUrl, currentUrl, csrf);
+ $.fn.annotateImage.createSaveButton(editable, this.image, annotation);
+ $.fn.annotateImage.createCancelButton(editable, this.image);
+ }
+ };
+
+ $.fn.annotateImage.appendPosition = function(form, editable) {
+ ///
+ /// Appends the annotations coordinates to the given form that is posted to the server.
+ ///
+ var areaFields = $(' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ');
+ form.append(areaFields);
+ }
+
+ $.fn.annotateView.prototype.resetPosition = function(editable, text) {
+ ///
+ /// Sets the position of an annotation.
+ ///
+ this.form.html(text);
+ this.form.hide();
+
+ // Resize
+ this.area.children('div').height(editable.area.height() + 'px');
+ this.area.children('div').width((editable.area.width() - 2) + 'px');
+ this.area.css('left', (editable.area.position().left) + 'px');
+ this.area.css('top', (editable.area.position().top) + 'px');
+ this.form.css('left', (editable.area.position().left) + 'px');
+ this.form.css('top', (parseInt(editable.area.position().top) + parseInt(editable.area.height()) + 7) + 'px');
+
+ // Save new position to note
+ this.note.top = editable.area.position().top;
+ this.note.left = editable.area.position().left;
+ this.note.height = editable.area.height();
+ this.note.width = editable.area.width();
+ this.note.text = text;
+ this.note.id = editable.note.id;
+ this.editable = true;
+ };
+
+})(jQuery);
diff --git a/modules/photoannotation/js/jquery.annotate.min.js b/modules/photoannotation/js/jquery.annotate.min.js
new file mode 100644
index 00000000..db7667f2
--- /dev/null
+++ b/modules/photoannotation/js/jquery.annotate.min.js
@@ -0,0 +1,2 @@
+
+(function($){$.fn.annotateImage=function(options){var opts=$.extend({},$.fn.annotateImage.defaults,options);var image=this;this.image=this;this.mode='view';this.getUrl=opts.getUrl;this.saveUrl=opts.saveUrl;this.deleteUrl=opts.deleteUrl;this.currentUrl=opts.currentUrl;this.deleteUrl=opts.deleteUrl;this.editable=opts.editable;this.useAjax=opts.useAjax;this.tags=opts.tags;this.notes=opts.notes;this.labels=opts.labels;this.csrf=opts.csrf;this.canvas=$('');this.canvas.children('.image-annotate-edit').hide();this.canvas.children('.image-annotate-view').hide();this.image.after(this.canvas);this.canvas.height(this.height());this.canvas.width(this.width());this.canvas.css('background-image','url("'+this.attr('src')+'")');this.canvas.children('.image-annotate-view, .image-annotate-edit').height(this.height());this.canvas.children('.image-annotate-view, .image-annotate-edit').width(this.width());this.canvas.hover(function(){if($(this).children('.image-annotate-edit').css('display')=='none'){$(this).children('.image-annotate-view').show()}},function(){$(this).children('.image-annotate-view').hide();$(this).children('.image-annotate-note').hide()});this.canvas.children('.image-annotate-view').hover(function(){$(this).show()},function(){$(this).hide();$(this).children('.image-annotate-note').hide()});if(this.useAjax){$.fn.annotateImage.ajaxLoad(this)}else{$.fn.annotateImage.load(this,this.labels,this.editable,this.csrf,this.deleteUrl,this.currentUrl)}if($('#g-photoannotation-link').length!=0){this.button=$('#g-photoannotation-link');this.button.click(function(){$.fn.annotateImage.add(image,opts.tags,opts.labels,opts.saveUrl,opts.currentUrl,opts.csrf)})}this.hide();return this};$.fn.annotateImage.defaults={getUrl:'your-get.rails',saveUrl:'your-save.rails',deleteUrl:'your-delete.rails',editable:true,useAjax:true,tags:new Array(),notes:new Array()};$.fn.annotateImage.clear=function(image){for(var i=0;iOK');ok.click(function(){var form=$('#image-annotate-edit-form form');var text=$('#image-annotate-text').val();$.fn.annotateImage.appendPosition(form,editable)image.mode='view';form.submit();editable.destroy()});editable.form.append(ok)};$.fn.annotateImage.createCancelButton=function(editable,image){var cancel=$('Cancel ');cancel.click(function(){editable.destroy();image.mode='view'});editable.form.append(cancel)};$.fn.annotateImage.saveAsHtml=function(image,target){var element=$(target);var html="";for(var i=0;i '};$.fn.annotateEdit=function(image,note,tags,labels,saveUrl,currentUrl,csrf){this.image=image;if(note){this.note=note}else{var newNote=new Object();newNote.id="new";newNote.top=30;newNote.left=30;newNote.width=30;newNote.height=30;newNote.text="";this.note=newNote}var area=image.canvas.children('.image-annotate-edit').children('.image-annotate-edit-area');this.area=area;this.area.css('height',this.note.height+'px');this.area.css('width',this.note.width+'px');this.area.css('left',this.note.left+'px');this.area.css('top',this.note.top+'px');image.canvas.children('.image-annotate-view').hide();image.canvas.children('.image-annotate-edit').show();var tagdropdown=labels[0]+'No Tag ';if(tags){for(var tag in tags){var tagval=tags[tag];tagdropdown+=''+tagval.name+' '}}tagdropdown+=' ';var form=$('
'+tagdropdown+labels[1]+''+this.note.text+' '+labels[2]+' ');this.form=form;$('body').append(this.form);this.form.css('left',this.area.offset().left+'px');this.form.css('top',(parseInt(this.area.offset().top)+parseInt(this.area.height())+7)+'px');area.resizable({handles:'all',stop:function(e,ui){form.css('left',area.offset().left+'px');form.css('top',(parseInt(area.offset().top)+parseInt(area.height())+2)+'px')}}).draggable({containment:image.canvas,drag:function(e,ui){form.css('left',area.offset().left+'px');form.css('top',(parseInt(area.offset().top)+parseInt(area.height())+2)+'px')},stop:function(e,ui){form.css('left',area.offset().left+'px');form.css('top',(parseInt(area.offset().top)+parseInt(area.height())+2)+'px')}});return this};$.fn.annotateEdit.prototype.destroy=function(){this.image.canvas.children('.image-annotate-edit').hide();this.area.resizable('destroy');this.area.draggable('destroy');this.area.css('height','');this.area.css('width','');this.area.css('left','');this.area.css('top','');this.form.remove()}$.fn.annotateView=function(image,note,labels,editable,csrf,deleteUrl,currentUrl){this.image=image;this.note=note;this.area=$('');image.canvas.children('.image-annotate-view').prepend(this.area);if(editable){this.delarea=$('');image.canvas.children('.image-annotate-view').prepend(this.delarea);this.delarea.bind('click',function(){if(confirm(labels[3])){var alink=$(".g-fullsize-link");alink.unbind();alink.attr('href','#');alink.removeAttr('rel');var delform=$(this).children('div').children('form');delform.submit()}})this.delarea.hide()}this.form=$(''+note.text+'
');this.form.hide();image.canvas.children('.image-annotate-view').append(this.form);this.form.children('span.actions').hide();this.setPosition();var annotation=this;this.area.hover(function(){annotation.show();if(annotation.delarea!=undefined){annotation.delarea.show()}},function(){annotation.hide();if(annotation.delarea!=undefined){annotation.delarea.hide()}});if(editable){this.delarea.hover(function(){annotation.delarea.show()},function(){annotation.delarea.hide()})}if(note.url!=""&¬e.url!=null){this.area.bind('click',function(){var alink=$(".g-fullsize-link");alink.unbind();alink.attr('href','#');alink.removeAttr('rel');window.location=note.url})}};$.fn.annotateView.prototype.setPosition=function(){this.area.children('div').height((parseInt(this.note.height)-2)+'px');this.area.children('div').width((parseInt(this.note.width)-2)+'px');this.area.css('left',(this.note.left)+'px');this.area.css('top',(this.note.top)+'px');this.form.css('left',(this.note.left)+'px');this.form.css('top',(parseInt(this.note.top)+parseInt(this.note.height)+7)+'px');if(this.delarea!=undefined){this.delarea.children('div').height('14px');this.delarea.children('div').width('14px');this.delarea.css('left',(this.note.left+parseInt(this.note.width))+'px');this.delarea.css('top',(this.note.top)+'px')}};$.fn.annotateView.prototype.show=function(){this.form.fadeIn(250);if(!this.note.editable){this.area.addClass('image-annotate-area-hover')}else{this.area.addClass('image-annotate-area-editable-hover')}};$.fn.annotateView.prototype.hide=function(){this.form.fadeOut(250);this.area.removeClass('image-annotate-area-hover');this.area.removeClass('image-annotate-area-editable-hover')};$.fn.annotateView.prototype.destroy=function(){this.area.remove();this.form.remove()}$.fn.annotateView.prototype.edit=function(){if(this.image.mode=='view'){this.image.mode='edit';var annotation=this;var editable=new $.fn.annotateEdit(this.image,this.note);$.fn.annotateImage.createSaveButton(editable,this.image,annotation);var del=$('Delete ');del.click(function(){var form=$('#image-annotate-edit-form form');$.fn.annotateImage.appendPosition(form,editable)if(annotation.image.useAjax){$.ajax({url:annotation.image.deleteUrl,data:form.serialize(),error:function(e){alert("An error occured deleting that note.")}})}annotation.image.mode='view';editable.destroy();annotation.destroy()});editable.form.append(del);$.fn.annotateImage.createCancelButton(editable,this.image)}};$.fn.annotateImage.appendPosition=function(form,editable){var areaFields=$(' '+' '+' '+' '+' ');form.append(areaFields)}$.fn.annotateView.prototype.resetPosition=function(editable,text){this.form.html(text);this.form.hide();this.area.children('div').height(editable.area.height()+'px');this.area.children('div').width((editable.area.width()-2)+'px');this.area.css('left',(editable.area.position().left)+'px');this.area.css('top',(editable.area.position().top)+'px');this.form.css('left',(editable.area.position().left)+'px');this.form.css('top',(parseInt(editable.area.position().top)+parseInt(editable.area.height())+7)+'px');this.note.top=editable.area.position().top;this.note.left=editable.area.position().left;this.note.height=editable.area.height();this.note.width=editable.area.width();this.note.text=text;this.note.id=editable.note.id;this.editable=true}})(jQuery);
diff --git a/modules/photoannotation/models/items_face.php b/modules/photoannotation/models/items_face.php
new file mode 100644
index 00000000..8f3a4072
--- /dev/null
+++ b/modules/photoannotation/models/items_face.php
@@ -0,0 +1,21 @@
+
+
+
= t("Photo annotation administration") ?>
+
= t("Notes:") ?>
+
= t("This module is fully compatible with the TagFaces module by rWatcher.
+ This means that notes and faces that you create in either one will be shown and are editable by the other module as well.
+ However since both modules do the same you cannot have both active at the same time.
+ If you decide to show annotations below the photo but they are displayed below the comments section (or any other data),
+ please download and install the Module order module .") ?>
+ = $form ?>
+
diff --git a/modules/photoannotation/views/photoannotation_highlight_block.html.php b/modules/photoannotation/views/photoannotation_highlight_block.html.php
new file mode 100644
index 00000000..efde70c9
--- /dev/null
+++ b/modules/photoannotation/views/photoannotation_highlight_block.html.php
@@ -0,0 +1,110 @@
+where("item_id", "=", $item->id)
+ ->find_all();
+ $existingNotes = ORM::factory("items_note")
+ ->where("item_id", "=", $item->id)
+ ->find_all();
+ $tags_arraystring = "";
+ $jscode = "";
+ $legend_faces = "";
+ $legend_notes = "";
+ if (module::get_var("gallery", "active_site_theme") == "greydragon") {
+ $css_item_id = "#g-photo-id-". $item->id;
+ $css_a_class = ".g-sb-preview";
+ } else {
+ $css_item_id = "#g-item-id-". $item->id;
+ $css_a_class = ".g-fullsize-link";
+ }
+ // If it does, then insert some javascript and display an image map
+ // to show where the faces are at.
+ if ((count($existingFaces) > 0) || (count($existingNotes) > 0)) {
+ $jscode = "notes: [ ";
+ foreach ($existingFaces as $oneFace) {
+ $oneTag = ORM::factory("tag", $oneFace->tag_id);
+ if (module::get_var("photoannotation", "showfaces", false)) {
+ $legend_faces .= "url() ."\">". html::clean($oneTag->name) ." , ";
+ }
+ $jscode .= "{ \"top\": ". $oneFace->y1 .",\n";
+ $jscode .= "\"left\": ". $oneFace->x1 .",\n";
+ $jscode .= "\"width\": ". ($oneFace->x2 - $oneFace->x1) .",\n";
+ $jscode .= "\"height\": ". ($oneFace->y2 - $oneFace->y1) .",\n";
+ $jscode .= "\"text\": \"". html::clean($oneTag->name) ."\",\n";
+ $jscode .= "\"description\": \"". html::clean($oneFace->description) ."\",\n";
+ $jscode .= "\"noteid\": ". $oneFace->id .",\n";
+ $jscode .= "\"notetype\": \"face\",\n";
+ $jscode .= "\"editable\": true,\n";
+ $jscode .= "\"url\": \"". $oneTag->url() ."\" },\n";
+ }
+ if ($legend_faces != "") {
+ $legend_faces = trim($legend_faces, ", ");
+ $legend_faces = t("Faces on this photo: ") . $legend_faces;
+ }
+ foreach ($existingNotes as $oneNote) {
+ if (module::get_var("photoannotation", "shownotes", false)) {
+ $legend_notes .= html::clean($oneNote->title) .", ";
+ }
+ $jscode .= "{ \"top\": ". $oneNote->y1 .",\n";
+ $jscode .= "\"left\": ". $oneNote->x1 .",\n";
+ $jscode .= "\"width\": ". ($oneNote->x2 - $oneNote->x1) .",\n";
+ $jscode .= "\"height\": ". ($oneNote->y2 - $oneNote->y1) .",\n";
+ $jscode .= "\"text\": \"". html::clean($oneNote->title) ."\",\n";
+ $jscode .= "\"description\": \"". html::clean($oneNote->description) ."\",\n";
+ $jscode .= "\"noteid\": ". $oneNote->id .",\n";
+ $jscode .= "\"notetype\": \"note\",\n";
+ $jscode .= "\"editable\": false,\n";
+ $jscode .= "\"url\": \"\" },\n";
+ }
+ $jscode = trim($jscode, ",\n");
+ $jscode .= " ],";
+ if ($legend_notes != "") {
+ $legend_notes = trim($legend_notes, ", ");
+ $legend_notes = t("Notes on this photo: ") . $legend_notes;
+ }
+ }
+ $legend_display = $legend_faces;
+ if ($legend_display == "") {
+ $legend_display = $legend_notes;
+ } else {
+ if ($legend_notes != "") {
+ $legend_display = $legend_display ." ". $legend_notes;
+ }
+ }
+ $item_tags = ORM::factory("tag")
+ ->join("items_tags", "tags.id", "items_tags.tag_id")
+ ->where("items_tags.item_id", "=", $item->id)
+ ->find_all();
+ $tags_arraystring = "tags: [ ";
+ foreach ($item_tags as $current_tag) {
+ $tags_arraystring .= "{'name':'". html::clean($current_tag->name) ."','id':'". $current_tag->id ."'},";
+ }
+ $tags_arraystring = trim($tags_arraystring, ",");
+ $tags_arraystring .= " ],";
+ $labels_arraystring = "labels: [ '". t("Tag:") ."','". t("Note Title:") ."','". t("Description (optional):") ."','". t("Are you sure you want to delete this annotation?") ."' ],";
+?>
+
+
+ if ($legend_display != ""): ?>
+ = "". $legend_display ."
" ?>
+ endif ?>
diff --git a/themes/browny_wind/css/fix-ie.css b/themes/browny_wind/css/fix-ie.css
index f7f08486..0633ff07 100644
--- a/themes/browny_wind/css/fix-ie.css
+++ b/themes/browny_wind/css/fix-ie.css
@@ -1,5 +1,5 @@
/**
- * Fix display in IE 6, 7
+ * Fix display in IE 6, 7, and 8
*/
#g-banner {
@@ -7,6 +7,10 @@
zoom: 1;
}
+#g-sidebar {
+ overflow: hidden;
+}
+
#g-photo,
#g-movie {
zoom: 1;
@@ -22,8 +26,23 @@ input.submit {
display: inline !important;
}
+.g-short-form input.text,
+.g-short-form input.submit {
+ font-size: 1em;
+ line-height: 1em;
+ padding: .38em .3em;
+}
+
+#g-search-form input#q {
+ width: 300px;
+}
+
#g-add-tag-form input.textbox {
- width: 110px;
+ width: 110px !important;
+}
+
+#g-add-tag-form input[type='submit'] {
+ padding: .3em 0 !important;
}
#g-dialog .g-cancel {
diff --git a/themes/browny_wind/css/screen.css b/themes/browny_wind/css/screen.css
index 3e16f6a6..15c04991 100644
--- a/themes/browny_wind/css/screen.css
+++ b/themes/browny_wind/css/screen.css
@@ -329,6 +329,32 @@ td {
background-color: #fff;
}
+/* Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+#g-edit-permissions-form td {
+ background-image: none;
+}
+
+#g-edit-permissions-form fieldset {
+ border: 1px solid #ccc;
+}
+
+#g-permissions .g-denied {
+ background-color: #fcc;
+}
+
+#g-permissions .g-allowed {
+ background-color: #fcf9ce;
+}
+
+#g-permissions .g-breadcrumbs a {
+ border: 1px solid #fff;
+}
+
+#g-permissions .g-active a {
+ border: 1px solid #ddd;
+ background: #eee;
+}
+
/** *******************************************************************
* 5) Navigation and menus
*********************************************************************/
diff --git a/themes/browny_wind/views/page.html.php b/themes/browny_wind/views/page.html.php
index ca29a809..72df044a 100644
--- a/themes/browny_wind/views/page.html.php
+++ b/themes/browny_wind/views/page.html.php
@@ -29,7 +29,7 @@
= $theme->css("themeroller/ui.base.css") ?>
= $theme->css("gallery.common.css") ?>
= $theme->css("screen.css") ?>
-
diff --git a/themes/greydragon/admin/controllers/admin_theme_options.php b/themes/greydragon/admin/controllers/admin_theme_options.php
index f83a5560..ec33e6b3 100644
--- a/themes/greydragon/admin/controllers/admin_theme_options.php
+++ b/themes/greydragon/admin/controllers/admin_theme_options.php
@@ -1,7 +1,7 @@
"g-theme-options-form"));
-
- $group = $form->group("requirements")->label("Prerequisites checklist");
- $group->checkbox("shadowbox")->label(t("Shadowbox module"))
- ->checked((module::is_active("shadowbox")))->disabled(true);
+ protected $min_gallery_ver = 30;
+ private function load_theme_info() {
$file = THEMEPATH . "greydragon/theme.info";
$theme_info = new ArrayObject(parse_ini_file($file), ArrayObject::ARRAY_AS_PROPS);
+ return $theme_info;
+ }
- $group = $form->group("edit_theme")->label(t("Grey Dragon Theme") . " - " . t("v.") . $theme_info->version);
- $group->input("row_count")->label(t("Rows per album page"))->id("g-page-size")
- ->rules("required|valid_digit")
- ->value(module::get_var("gallery", "page_size") / 3);
+ private function get_theme_version() {
+ $theme_info = $this->load_theme_info();
+ return ($theme_info->version);
+ }
- $group->input("resize_size")->label(t("Resized image size (in pixels)"))->id("g-resize-size")
+ private function get_theme_name() {
+ $theme_info = $this->load_theme_info();
+ return ($theme_info->name);
+ }
+
+ private function get_colorpacks() {
+ $colorpacks = array();
+ $colorpackroot = THEMEPATH . 'greydragon/css/colorpacks/';
+
+ foreach (scandir($colorpackroot) as $colorpack_name):
+ if (file_exists($colorpackroot . "$colorpack_name/colors.css")):
+ if ($colorpack_name[0] == "."):
+ continue;
+ endif;
+
+ $colorpacks[$colorpack_name] = t($colorpack_name);
+ endif;
+ endforeach;
+ return $colorpacks;
+ }
+
+ private function prerequisite_check($group, $id, $is_ok, $caption, $caption_ok, $caption_failed, $iswarning, $msg_error) {
+
+ $confirmation_caption = ($is_ok)? $caption_ok : $caption_failed;
+ $checkbox = $group->checkbox($id)
+ ->label($caption . " " . $confirmation_caption)
+ ->checked($is_ok)
+ ->disabled(true);
+ if ($is_ok):
+ $checkbox->class("g-success");
+ elseif ($iswarning):
+ $checkbox->class("g-prerequisite g-warning")->error_messages("failed", $msg_error)->add_error("failed", 1);
+ else:
+ $checkbox->class("g-error")->error_messages("failed", $msg_error)->add_error("failed", 1);
+ endif;
+ }
+
+ protected function get_edit_form_admin() {
+ $form = new Forge("admin/theme_options/save/", "", null, array("id" =>"g-theme-options-form"));
+
+ $group = $form->group("requirements")->label("Prerequisites Checklist");
+ $gallery_ver = module::get_version("gallery");
+
+ $this->prerequisite_check($group, "vercheck", $gallery_ver >= $this->min_gallery_ver,
+ t("Gallery 3 Core v.") . $this->min_gallery_ver, "Installed", "Required", FALSE, t("Check Failed. Minimum Required Version") . " " . $gallery_ver);
+
+ $this->prerequisite_check($group, "shadowbox", ((module::is_active("shadowbox")) and (module::info("shadowbox"))),
+ t("Shadowbox Module"), "Found", "Required", FALSE, t("Check Failed. Shadowbox Module not Installed."));
+
+ if (!module::get_var("th_greydragon", "hide_thumbmeta")):
+ $this->prerequisite_check($group, "info", (module::is_active("info") and module::info("info")),
+ t("Info Module"), "Found", "Required", FALSE, t("Check Failed. Module is required to display Thumb metadata."));
+ endif;
+
+ $group = $form->group("recommended")->label("Module Recommendations");
+
+ $organize_active = ((module::is_active("organize")) and (module::info("organize")));
+ $this->prerequisite_check($group, "organizecheck", !$organize_active,
+ t("Organize Module"), "not Used", "Found", TRUE, t("Default Organize module is active but is not supported in full by the theme."));
+
+ $kbdnav_active = ((module::is_active("kbd_nav")) and (module::info("kbd_nav")));
+ $this->prerequisite_check($group, "kbdnavcheck", $kbdnav_active,
+ t("Kbd Navigation Module"), "Found", "not Found", TRUE, t('Install module to enable keyboard navigation support.'));
+
+ $sidebar_allowed = module::get_var("th_greydragon", "sidebar_allowed");
+ $sidebar_visible = module::get_var("th_greydragon", "sidebar_visible");
+
+ $pagesize = module::get_var("gallery", "page_size");
+ if (($sidebar_allowed == "none") and ($sidebar_visible == "none")):
+ $pagesize = $pagesize / 4;
+ else:
+ $pagesize = $pagesize / 3;
+ endif;
+
+ $group = $form->group("edit_theme")->label(t("General Settings"));
+ $group->input("row_count")
+ ->label(t("Rows per Album Page"))
->rules("required|valid_digit")
+ ->error_messages("required", t("You must enter a number"))
+ ->error_messages("valid_digit", t("You must enter a number"))
+ ->value($pagesize);
+ $group->input("resize_size")
+ ->label(t("Resized Image Size (in pixels)"))
+ ->rules("required|valid_digit")
+ ->error_messages("required", t("You must enter a number"))
+ ->error_messages("valid_digit", t("You must enter a number"))
->value(module::get_var("gallery", "resize_size"));
- $group->checkbox("build_resize")->label(t("Mark to build all resizes (from Maintenace page)"))->id("g-build-resize")->value(false);
- $group->checkbox("build_thumbs")->label(t("Mark to build all thumbnails (200x200) (from Maintenace page)"))->id("g-build-thumb")->value(false);
-
- $group->checkbox("photonav_top")->label(t("Show top photo navigator"))
- ->checked(module::get_var("th_greydragon", "photonav_top"));
- $group->checkbox("photonav_bottom")->label(t("Show bottom photo navigator"))
- ->checked(module::get_var("th_greydragon", "photonav_bottom"));
-
- $group->dropdown("sidebar_allowed")->label(t("Allowed SideBar Positions"))
- ->options(array("any" => t("Any"), "left" => t("Left"), "right" => t("Right"), "none" => t("None")))
- ->selected(module::get_var("th_greydragon", "sidebar_allowed"));
- $group->dropdown("sidebar_visible")->label(t("Default SideBar Position"))
- ->options(array("right" => t("Right"), "left" => t("Left"), "none" => t("None")))
- ->selected(module::get_var("th_greydragon", "sidebar_visible"));
-
- $group->input("header_text")->label(t("Header text"))->id("g-header-text")
- ->value(module::get_var("gallery", "header_text"));
- $group->input("footer_text")->label(t("Footer text"))->id("g-footer-text")
- ->value(module::get_var("gallery", "footer_text"));
- $group->checkbox("show_credits")->label(t("Show site credits"))->id("g-footer-text")
- ->checked(module::get_var("gallery", "show_credits"));
-
- $group->input("copyright")->label(t("Copyright message to display on footer"))->id("g-theme-copyright")
- ->value(module::get_var("th_greydragon", "copyright"));
- $group->input("logo_path")->label(t("URL or path to alternate logo image"))->id("g-site-logo")
+ $group->input("logo_path")
+ ->label(t("Alternate Logo Image"))
->value(module::get_var("th_greydragon", "logo_path"));
+ $group->input("header_text")
+ ->label(t("Header Text"))
+ ->value(module::get_var("gallery", "header_text"));
+ $group->input("footer_text")
+ ->label(t("Footer Text"))
+ ->value(module::get_var("gallery", "footer_text"));
+ $group->input("copyright")
+ ->label(t("Copyright Message"))
+ ->value(module::get_var("th_greydragon", "copyright"));
+ $group->dropdown("colorpack")
+ ->label(t("Selected Color Pack"))
+ ->options(self::get_colorpacks())
+ ->selected(module::get_var("th_greydragon", "color_pack", "greydragon"));
+
+ $group = $form->group("edit_theme_adv_main")->label(t("Advanced Options - Main"));
+ $group->checkbox("show_credits")
+ ->label(t("Show Site Credits"))
+ ->checked(module::get_var("gallery", "show_credits"));
+ $group->checkbox("show_guest_menu")
+ ->label(t("Show Main Menu for Guest Users"))
+ ->checked(module::get_var("th_greydragon", "show_guest_menu"));
+ $group->checkbox("loginmenu_position")
+ ->label(t("Place Login Link in the Header"))
+ ->checked(module::get_var("th_greydragon", "loginmenu_position") == "header");
+ $group->checkbox("mainmenu_position")
+ ->label(t("Alternate Header Layout"))
+ ->checked(module::get_var("th_greydragon", "mainmenu_position") == "top");
+ $group->checkbox("hide_breadcrumbs")
+ ->label(t("Hide Breadcrumbs"))
+ ->checked(module::get_var("th_greydragon", "hide_breadcrumbs"));
+ $group->dropdown("photonav_position")
+ ->label(t("Item Navigator Position"))
+ ->options(array("top" => t("Top"), "bottom" => t("Bottom"), "both" => t("Both"), "none" => t("None")))
+ ->selected(module::get_var("th_greydragon", "photonav_position"));
+ $group->checkbox("disable_seosupport")
+ ->label(t("Disallow Search Engine Indexing"))
+ ->checked(module::get_var("th_greydragon", "disable_seosupport"));
+ $group->checkbox("enable_pagecache")
+ ->label(t("Enable Page Cache (60 seconds)"))
+ ->checked(module::get_var("th_greydragon", "enable_pagecache"));
+
+ $group = $form->group("edit_theme_adv_thumb")->label(t("Advanced Options - Album page/Thumbs"));
+ $group->dropdown("thumb_ratio")
+ ->label(t("Aspect Ratio"))
+ ->options(array("photo" => t("Actual Size"), "digital" => t("Digital 4:3"), "film" => t("Film 3:2") /* , "square" => t("Square 1:1") */ ))
+ ->selected(module::get_var("th_greydragon", "thumb_ratio"));
+ $group->dropdown("thumb_descmode")
+ ->label(t("Title Display Mode"))
+ ->options(array("overlay" => t("Overlay"), "bottom" => t("Bottom"), "hide" => t("Hide")))
+ ->selected(module::get_var("th_greydragon", "thumb_descmode"));
+ $group->checkbox("hide_thumbmeta")
+ ->label(t("Hide Item Meta Data"))
+ ->checked(module::get_var("th_greydragon", "hide_thumbmeta"));
+
+ $group = $form->group("edit_theme_adv_photo")->label(t("Advanced Options - Photo page"));
+ $group->dropdown("photo_descmode")
+ ->label(t("Description Display Mode"))
+ ->options(array("overlay" => t("Overlay"), "bottom" => t("Bottom"), "top" => t("Top"), "hide" => t("Hide")))
+ ->selected(module::get_var("th_greydragon", "photo_descmode"));
+ $group->checkbox("desc_allowbbcode")
+ ->label(t("Allow BBCode/HTML in Descriptions"))
+ ->checked(module::get_var("th_greydragon", "desc_allowbbcode"));
+ $group->checkbox("hide_photometa")
+ ->label(t("Hide Item Meta Data"))
+ ->checked(module::get_var("th_greydragon", "hide_photometa", TRUE));
+
+ $group = $form->group("edit_theme_side")->label(t("Sidebar Options"));
+ $group->checkbox("hide_blockheader")
+ ->label(t("Hide Block Header"))
+ ->checked(module::get_var("th_greydragon", "hide_blockheader"));
+ $group->checkbox("sidebar_albumonly")
+ ->label(t("Show Sidebar for Albums Only"))
+ ->checked(module::get_var("th_greydragon", "sidebar_albumonly"));
+ $group->dropdown("sidebar_allowed")
+ ->label(t("Allowed Sidebar Positions"))
+ ->options(array("any" => t("Any"), "left" => t("Left"), "right" => t("Right"), "none" => t("Default Only")))
+ ->selected($sidebar_allowed);
+ $group->dropdown("sidebar_visible")
+ ->label(t("Default Sidebar Position"))
+ ->options(array("right" => t("Right"), "left" => t("Left"), "none" => t("No sidebar")))
+ ->selected($sidebar_visible);
+
+ $group = $form->group("maintenance")->label("Maintenance");
+ $group->checkbox("build_resize")->label(t("Mark all Image Resizes for Rebuild"))->checked(false);
+ $group->checkbox("build_thumbs")->label(t("Mark all Thumbnails for Rebuild"))->checked(false);
+ $group->checkbox("build_exif")->label(t("Reset Exif Info"))->checked(false);
+ $group->checkbox("reset_theme")->label(t("Reset Theme to a Default State"))->checked(false);
module::event("theme_edit_form", $form);
- $group = $form->group("buttons");
- $group->submit("")->value(t("Save"));
+ $form->submit("g-theme-options-save")->value(t("Save Changes"));
+
return $form;
}
- public function index() {
- $view = new Admin_View("admin.html");
- $view->content = new View("admin_theme_options.html");
- $view->content->form = self::get_edit_form_admin();
- print $view;
+ protected function get_edit_form_help() {
+ $help = '';
+ $help .= 'Help ';
+ $help .= 'Prerequisites
+ Requirements need to be met for theme to function properly.
+ If indicated please download and install
+ Shadowbox module . Module is required to properly display photos in maximized view and for any admin operations dialogs.
+ ';
+
+ $help .= 'Module Recommendations
+ Some recommendations to make your experience with the theme more pleasant.
+ While there is some support for default Organize module, theme may not skin it properly all the way.
+ Please consider using GWT Organize Module instead.
+ Enable Keyboard navigation by installing Kbd Navigation Module.
+ ';
+
+ $help .= 'General Settings
+ Theme is designed to display thumbnails in fixed 3+sidebar or 4 columns format.
+ Number of Rows per Album Page however can be adjusted.
+ Unlike in default theme, thumbnails size is restricted to max 200x200px.
+ Default G3 logo can be replaced with your own by providing Alternate Logo Image .
+ Recommended logo size is within 300x80px. If you need bigger space for your logo, CSS would have to be adjusted.
+ Logo could be suppressed altogether by providing Header Text which would take its place.
+ Footer Text would be simply placed next to Site\'s credits.
+ To indicate your rights for the artwork displayed Copyright Message can be placed in
+ right top corner of the footer.
+ Important feature of the theme is ability to specify Selected Color Pack . Color Pack is small CSS
+ file which defines color rules for the theme. By default theme comes with GreyDragon (default) and Wind sets,
+ but it could be easily extended. Visit our Download page for additional information.
+ ';
+ $help .= 'Advanced Options
+ Show Site Credits simply shows appreciation for hard work of G3 team and Theme\'s author
+ (you could do also do this by clicking Donate link above).
+ If main menu has functionality intended for guest users you can use Show Main Menu for Guest Users
+ to keep it visible.
+ If you do not like login link in the footer you can move it into top right corner by selecting Place Login Link in the Header .
+ You can go even further and move main menu to the top of the header with breadcrumbs taking it place by selecting Alternate Header Layout .
+ Item Navigator Position could be changed to display it above and/or below the main content.
+ Thumb: Aspect Ratio should be used with understanding that some information
+ may be out of visible area in photo thumbs. Based on specified aspect all thumbs sizes would be adjusted
+ accordingly. When switching to/from Actual Size , it is recommended to rebuild thumbs for proper display
+ (see Maintenance section below).
+ If you prefer including Item\'s caption as part of the thumb, you can use Thumb: Title Display Mode to change
+ default Overlay mode. And if metadata (owner/clicks) is not necessary, it could be hidden with Thumb: Hide Item Meta Data .
+ Similar to Thumb option above Item\'s description could be displayed where available.
+ In non-Overlay mode, this is not limited to just Photo page, but description could be
+ displayed for albums also.
+ ';
+ $help .= 'Sidebar Options
+ If Block\'s header is not desired, it could be removed using Hide Block Header .
+ Sidebar visibility could be limited to individual Photo pages with
+ Show Sidebar for Albums Only .
+
When sidebar is visible it can be placed on the left or right of the
+ screen or removed altogether using Allowed Sidebar Positions .
+ If more than one position is allowed, Default Sidebar Position
+ would indicate default state, but visitor would able change it later.
+
';
+ $help .= 'Maintenance
+ Without changing image size, you can Mark all Resizes for Rebuild .
+ Then you need to visit Admin\Maintenance to initiate the process.
+
Same can be done for image thumbs with Mark all Thumbnails for Rebuild .
+
Reset Exif Info would remove all exif info allowing it to be imported again.
+ And just in case you think that something is not right, you can
+ always Reset Theme to a Default State .
+
';
+ $help .= ' ';
+ return $help;
+ }
+
+ private function save_item_state($statename, $state, $value) {
+ if ($state):
+ module::set_var("th_greydragon", $statename, $value);
+ else:
+ module::clear_var("th_greydragon", $statename);
+ endif;
}
public function save() {
+ site_status::clear("gd_init_configuration");
access::verify_csrf();
$form = self::get_edit_form_admin();
- if ($form->validate()) {
- $edit_theme = $form->edit_theme;
+ if ($form->validate()):
+ module::clear_var("th_greydragon", "photonav_top");
+ module::clear_var("th_greydragon", "photonav_bottom");
+ module::clear_var("th_greydragon", "hide_sidebar_photo");
+ module::clear_var("th_greydragon", "hide_thumbdesc");
+ module::clear_var("th_greydragon", "use_detailview");
- module::set_var("gallery", "page_size", $edit_theme->row_count->value * 3);
+ if ($form->maintenance->reset_theme->value):
+ module::set_var("gallery", "page_size", 9);
+ module::set_var("gallery", "resize_size", 640);
+ module::set_var("gallery", "thumb_size", 200);
- $resize_size = $edit_theme->resize_size->value;
- $thumb_size = 200;
- $build_resize = $edit_theme->build_resize->value;
- $build_thumbs = $edit_theme->build_thumbs->value;
+ module::set_var("gallery", "header_text", "");
+ module::set_var("gallery", "footer_text", "");
+ module::clear_var("th_greydragon", "copyright");
+ module::clear_var("th_greydragon", "logo_path");
+ module::clear_var("th_greydragon", "color_pack");
+
+ module::clear_var("th_greydragon", "enable_pagecache");
+ module::set_var("gallery", "show_credits", FALSE);
+ module::clear_var("th_greydragon", "show_guest_menu");
+ module::clear_var("th_greydragon", "mainmenu_position");
+ module::clear_var("th_greydragon", "loginmenu_position");
+ module::clear_var("th_greydragon", "hide_breadcrumbs");
+ module::clear_var("th_greydragon", "horizontal_crop");
+ module::clear_var("th_greydragon", "thumb_descmode");
+ module::clear_var("th_greydragon", "hide_thumbmeta");
+ module::clear_var("th_greydragon", "hide_blockheader");
+ module::clear_var("th_greydragon", "photonav_position");
+ module::clear_var("th_greydragon", "photo_descmode");
+ module::clear_var("th_greydragon", "desc_allowbbcode");
+ module::clear_var("th_greydragon", "hide_photometa");
+ module::clear_var("th_greydragon", "disable_seosupport");
- if (module::get_var("gallery", "resize_size") != $resize_size) {
- module::set_var("gallery", "resize_size", $resize_size);
- $build_resize = true;
- }
- if (module::get_var("gallery", "thumb_size") != $thumb_size) {
- module::set_var("gallery", "thumb_size", $thumb_size);
- }
+ module::clear_var("th_greydragon", "sidebar_albumonly");
+ module::clear_var("th_greydragon", "sidebar_allowed");
+ module::clear_var("th_greydragon", "sidebar_visible");
- if ($build_resize) {
- graphics::remove_rule("gallery", "resize", "gallery_graphics::resize");
- graphics::add_rule("gallery", "resize", "gallery_graphics::resize",
- array("width" => $resize_size, "height" => $resize_size, "master" => Image::AUTO), 100);
- }
+ module::event("theme_edit_form_completed", $form);
+ message::success(t("Theme details are reset"));
+ else:
+ // * General Settings ****************************************************
- if ($build_thumbs) {
- graphics::remove_rule("gallery", "thumb", "gallery_graphics::resize");
- graphics::add_rule("gallery", "thumb", "gallery_graphics::resize",
- array("width" => 200, "height" => 200, "master" => Image::AUTO), 100);
- }
+ $_priorratio = module::get_var("th_greydragon", "thumb_ratio");
+ if (!$_priorratio):
+ $_priorratio = "digital";
+ endif;
- module::set_var("th_greydragon", "photonav_top", $edit_theme->photonav_top->value);
- module::set_var("th_greydragon", "photonav_bottom", $edit_theme->photonav_bottom->value);
+ $resize_size = $form->edit_theme->resize_size->value;
+ $thumb_size = 200;
- $sidebar_allowed = $edit_theme->sidebar_allowed->value;
- $sidebar_visible = $edit_theme->sidebar_visible->value;
+ $build_resize = $form->maintenance->build_resize->value;
+ $build_thumbs = $form->maintenance->build_thumbs->value;
+ $build_exif = $form->maintenance->build_exif->value;
- if ($sidebar_allowed == "none") { $sidebar_visible = "none"; }
- if ($sidebar_allowed == "right") { $sidebar_visible = "right"; }
- if ($sidebar_allowed == "left") { $sidebar_visible = "left"; }
+ $thumb_ratio = $form->edit_theme_adv_thumb->thumb_ratio->value;
+ if ($thumb_ratio == "photo") { $rule = Image::AUTO; } else { $rule = Image::WIDTH; }
+ $color_pack = $form->edit_theme->colorpack->value;
+ $thumb_descmode = $form->edit_theme_adv_thumb->thumb_descmode->value;
+ $photo_descmode = $form->edit_theme_adv_photo->photo_descmode->value;
- module::set_var("th_greydragon", "sidebar_allowed", $sidebar_allowed);
- module::set_var("th_greydragon", "sidebar_visible", $sidebar_visible);
+ if ($build_resize):
+ graphics::remove_rule("gallery", "resize", "gallery_graphics::resize");
+ graphics::add_rule("gallery", "resize", "gallery_graphics::resize",
+ array("width" => $resize_size, "height" => $resize_size, "master" => Image::AUTO), 100);
+ endif;
+ if (module::get_var("gallery", "resize_size") != $resize_size):
+ module::set_var("gallery", "resize_size", $resize_size);
+ endif;
- module::set_var("gallery", "header_text", $edit_theme->header_text->value);
- module::set_var("gallery", "footer_text", $edit_theme->footer_text->value);
- module::set_var("gallery", "show_credits", $edit_theme->show_credits->value);
+ if ($build_thumbs):
+ graphics::remove_rule("gallery", "thumb", "gallery_graphics::resize");
+ graphics::add_rule("gallery", "thumb", "gallery_graphics::resize",
+ array("width" => $thumb_size, "height" => $thumb_size, "master" => $rule), 100);
+ endif;
- module::set_var("th_greydragon", "copyright", $edit_theme->copyright->value);
- module::set_var("th_greydragon", "logo_path", $edit_theme->logo_path->value);
+ if ($build_exif):
+ db::build()
+ ->delete("exif_records")
+ ->execute();
+ endif;
- module::event("theme_edit_form_completed", $form);
+ if (module::get_var("gallery", "thumb_size") != $thumb_size):
+ module::set_var("gallery", "thumb_size", $thumb_size);
+ endif;
+ module::set_var("gallery", "header_text", $form->edit_theme->header_text->value);
+ module::set_var("gallery", "footer_text", $form->edit_theme->footer_text->value);
+ $this->save_item_state("copyright", $form->edit_theme->copyright->value, $form->edit_theme->copyright->value);
+ $this->save_item_state("logo_path", $form->edit_theme->logo_path->value, $form->edit_theme->logo_path->value);
+ $this->save_item_state("color_pack", (($color_pack) and ($color_pack != "greydragon")), $color_pack);
+
+ // * Advanced Options - main *********************************************
+
+ module::set_var("gallery", "show_credits", $form->edit_theme_adv_main->show_credits->value);
+ $this->save_item_state("show_guest_menu", $form->edit_theme_adv_main->show_guest_menu->value, TRUE);
+ $this->save_item_state("loginmenu_position", $form->edit_theme_adv_main->loginmenu_position->value == "1", "header");
+ $this->save_item_state("mainmenu_position", $form->edit_theme_adv_main->mainmenu_position->value == "1", "top");
+ $this->save_item_state("hide_breadcrumbs", $form->edit_theme_adv_main->hide_breadcrumbs->value, TRUE);
+ $this->save_item_state("photonav_position", $form->edit_theme_adv_main->photonav_position->value != "top", $form->edit_theme_adv->photonav_position->value);
+ $this->save_item_state("enable_pagecache", $form->edit_theme_adv_main->enable_pagecache->value, TRUE);
+ $this->save_item_state("disable_seosupport", $form->edit_theme_adv_main->disable_seosupport->value, TRUE);
+
+ // * Advanced Options - Album page ***************************************
+
+ $this->save_item_state("thumb_ratio", $thumb_ratio != "photo", $thumb_ratio);
+ $this->save_item_state("thumb_descmode", $thumb_descmode != "overlay", $thumb_descmode);
+ $this->save_item_state("hide_thumbmeta", $form->edit_theme_adv_thumb->hide_thumbmeta->value, TRUE);
+
+ // * Advanced Options - Photo page ***************************************
+
+ $this->save_item_state("photo_descmode", $photo_descmode != "overlay", $photo_descmode);
+ $this->save_item_state("desc_allowbbcode", $form->edit_theme_adv_photo->desc_allowbbcode->value, TRUE);
+ $this->save_item_state("hide_photometa", !$form->edit_theme_adv_photo->hide_photometa->value, FALSE);
+
+ // * Sidebar Options ****************************************************
+
+ $sidebar_allowed = $form->edit_theme_side->sidebar_allowed->value;
+ $sidebar_visible = $form->edit_theme_side->sidebar_visible->value;
+
+ if ($sidebar_allowed == "right"):
+ $sidebar_visible = "right";
+ endif;
+ if ($sidebar_allowed == "left"):
+ $sidebar_visible = "left";
+ endif;
+
+ $this->save_item_state("hide_blockheader", $form->edit_theme_side->hide_blockheader->value, TRUE);
+ $this->save_item_state("sidebar_albumonly", $form->edit_theme_side->sidebar_albumonly->value, TRUE);
+ $this->save_item_state("sidebar_allowed", $sidebar_allowed != "any", $sidebar_allowed);
+ $this->save_item_state("sidebar_visible", $sidebar_visible != "right", $sidebar_visible);
+
+ if (($sidebar_allowed == "none") and ($sidebar_visible == "none")):
+ module::set_var("gallery", "page_size", $form->edit_theme->row_count->value * 4);
+ else:
+ module::set_var("gallery", "page_size", $form->edit_theme->row_count->value * 3);
+ endif;
+
+ module::event("theme_edit_form_completed", $form);
+
+ if ($_priorratio != $thumb_ratio):
+ message::warning(t("Thumb aspect ratio has been changed. Consider rebuilding thumbs if needed."));
+ endif;
+
+ message::success(t("Updated theme details"));
+ endif;
- message::success(t("Updated theme details"));
url::redirect("admin/theme_options");
- } else {
+ else:
$view = new Admin_View("admin.html");
$view->content = $form;
print $view;
- }
+ endif;
+ }
+
+ public function index() {
+ site_status::clear("gd_init_configuration");
+
+ $view = new Admin_View("admin.html");
+ $view->page_title = t("Grey Dragon Theme");
+ $view->content = new View("admin_theme_options.html");
+ $view->content->name = self::get_theme_name();
+ $view->content->version = self::get_theme_version();
+ $view->content->form = self::get_edit_form_admin();
+ $view->content->help = self::get_edit_form_help();
+ print $view;
}
}
-
diff --git a/themes/greydragon/admin/views/admin_theme_options.html.php b/themes/greydragon/admin/views/admin_theme_options.html.php
new file mode 100644
index 00000000..6c919461
--- /dev/null
+++ b/themes/greydragon/admin/views/admin_theme_options.html.php
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
= $name ?> - = $version ?>
+
+
+
+ = $form ?>
+
+
+ = $help ?>
+
+
diff --git a/themes/greydragon/changelog.txt b/themes/greydragon/changelog.txt
index f6750d23..3d5a1451 100644
--- a/themes/greydragon/changelog.txt
+++ b/themes/greydragon/changelog.txt
@@ -1,46 +1,239 @@
-Grey Dragon Theme Changelog
-
-version 1.5.8
-- Finally admin module for theme is there. After theme installation, visit Appearance/Theme Options to configure the theme.
- If you had older version of the theme, initial setup is also required.
- The following settings are available:
- - Rows per album page - theme uses 3 columns layout for pictures, therefore default page_size is computed in x3 increments
- - Thumb size is restricted to 200 and therefore not available for administration
- - Mark to build resizes/thumbs - allows force rebuilding of images
- - Show/Hide top/bottom photo navigators
- - Specify allowed and default sidebar position
- - Administrator can now specify Copyright message to display in the footer
- - Site logo is now default to Gallery 3 logo, but admin can provide a path to custom logo.
-- Sidebar session cookie is set to expire in 365 days
-
-version 1.5.7
-- Status message has been moved into header as popup to prevent obstruction of the main view.
- jQuery is used to fade it out in 10 sec.
-- Improved logic for dialogs on submit
-- Theme related JS has been moved out of the page.html.php
-
-version 1.5.6
-- Fixed issue with tollbar buttons not properly aligned/shown when page is resized.
-- Copyright info moved into DB. To change default settings add [th_greydragon/copyright] into VARS table.
-
-version 1.5.5
-- CSS fixes.
-- Theme adjusted to be compatible with latest Git.
-- Login links are moved into footer.
-- Pagination module redesigned to support new structure of paging data.
-
-version 1.5.4
-- CSS fixes.
-- Added support for Comments block.
-- Improved support for Modal dialogs.
-
-version 1.5.3
-- Sync to git.
-- Exif menu customization is now part of the theme.
-- Sidebar management button is disabled for current mode.
-
-version 1.5.2
-- Code, layout, css cleanup.
-- New thumbs for buttons.
-- First set of Ajax dialogs is ready and now operational: Login, user info, edit album, exit info.
+=== Grey Dragon Theme ===
+Grey Dragon Theme - a custom theme for Gallery 3
+
+This theme was designed and built by Serguei Dosyukov, whose blog you will find at http://blog.dragonsoft.us/
+Copyright (C) 2009-2010 Serguei Dosyukov
+
+Tested up to: G3 3.0 RC2 (Santa Fe) Experimental
+Minimum requirement: G3 3.0 RC2 (Santa Fe) Experimental
+Donate link: http://blog.dragonsoft.us/gallery-3/
+
+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.
+
+=== Open issues ===
+- Issue with Delete functionality
+- Support for new organize module
+- Support for Register module
+- Issue with Comments module
+
+=== Changelog ===
+
+version 2.3.1
+- Hide Rotate operations for pictures since they are not supported by the theme
+- Added use of common gallery.ajax.js. Fix issue with some Ajax based links.
+- Layout fixes for Translation form overlay
+- Changed CSS styling for buttons to provide unified coverage for buttons and links exposed as buttons.
+- ADMIN: Fixed options group styles in Theme's Admin panel
+- ADMIN: Advanced Settings for Thumbs and Individual Photo are moved into separate sections.
+- ADMIN: New option - display meta data in Photo description section
+- ADMIN: New option/fix - SEO indexing is now allowed by default. In order to prevent your site from being indexed, you can now use "Disallow Search Engine Indexing" option
+
+version 2.3.0
+- Adopted for Gallery 3.0RC2 changes (minor template adjustments, css class name changes, etc.)
+
+version 2.2.1
+- Redesigned Ready event handler for the theme to ensure proper ShadowBox initialization
+- Added support for gallery_dialog() function call used by some 3rd party modules - some sync issues are solved by imposed delay of 1 second
+- GPS module - better action list alignment in the sidebar
+
+version 2.2.0
+- Added support for slideshow mode in Photo Preview
+- Fixed issue with Info side block - missing markup
+- Fixed issue with Upload dialog layout with some resolutions/fonts
+- ADMIN: Added option to hide breadcrumbs
+- ADMIN: Added prerequisite check for Info module - required for Thumb meta data display
+
+version 2.1.7
+- Added support for missing images in the thumbs to allow proper operations with empty albums or albums with broken thumbs
+- Some color optimizations
+- Color improvements for "Add Image" dialog
+- Better support for Basket module
+
+version 2.1.6
+- Wind colorpack adjusted to closer match default Wind theme
+
+version 2.1.5
+- Minor changes in ADMIN infrastructure
+- ADMIN: added check for Kbd Navigation module
+- ADMIN: New color pack - carbon
+
+version 2.1.4
+- Minor refactoring in paginator
+- Added support for keyboard navigation module (http://codex.gallery2.org/Gallery3:Modules:kbd_nav)
+
+version 2.1.3
+- Sidebar restricted to item related pages (album, photo, movie, etc)
+- Fixed issue with bottom border not applied to all instances of H1 tag
+- Min footer size set to 4em
+- ADMIN: "Photo: Description Display Mode" option added
+- ADMIN: Added new maintenance operation - "Reset Exif Info"
+
+version 2.1.2
+- Fixed issue with Album thumbs - empty space under
+- Thumb Item's Title Display Mode expanded to be applied to Item's description in Photo page
+- More documentations in CSS files, some movements
+- Some cleanup for Wind color pack
+- Fixed font name typo in screen.css
+- Fixed "Waiting" roller for Wind theme to match background
+- Added "up" button in navigation
+
+version 2.1.1
+- Increased size of Add photo dialog for better display on some lower resolutions.
+- ADMIN: New option: "Thumb: Item's Title Display Mode" - specifies how to display item's title in thumbs : Overlay Bottom Hide
+
+version 2.1.0
+- Custom Info Block to include item's description
+- Image is centered when "Actual Size" aspect is used for thumbs
+- Added support for color packs - included: greydragon, wind
+- ADMIN: Improved error handling
+- ADMIN: Disable submit button on click to prevent Dbl-click
+- ADMIN: New option: Enable page cache - adds header marker for page to be cached for 60 seconds
+
+version 2.0.1
+- Enable BBCode/HTML support in individual photo descriptions
+- Fixed main menu overlay issue when in top position
+- Theme's credits moved into dedicated method
+- CSS clean up
+- Comments module layout enhancements
+
+version 2.0.0
+- Major redesign of the gallery flow.
+ - Added caption and metadata (Admin/optional) overlay for thumbs.
+ - Added description overlay in individual Photo view (look for "Learn More" marker).
+ - Based on Admin setting, thumbs are adjusted to fit Digital/Film/Actual size.
+- Attempt to fix issue with JS load latency to prevent unhandled AJAX calls
+- Added code protection for theme initialization procedure
+- ADMIN: Thumb Aspect Ratio option. See help section for more info.
+
+version 1.8.2
+- Increased based font size
+- Layout adjusted to match new settings
+- ADMIN: New option - Place Login Link in the Header
+
+version 1.8.1
+- ADMIN: small adjustments in layout and help info
+- 3rd party module's related CSS moved into contrib.css
+- Adjust user profile screen to match new layout
+- initial design for calendar module
+
+version 1.8.0
+- ADMIN: Major redesign of the layout. Help section added.
+- ADMIN: New option - Show main menu for guest user
+- Minimum required Gallery version set to 30
+- When configured not to use sidebar, theme is switched into 4 columns layout
+
+version 1.7.6
+- Organize module: CSS improvements
+- Fixed issue with Chrome browser
+
+version 1.7.5
+- ADMIN: Added option to reset theme to default state
+- CSS: some size adjustments for dialogs. Added minimum height for overlay to keep dialogs from shrinking.
+
+version 1.7.4
+- ADMIN: Theme Gallery 3 core requirement changed to v.26
+- ADMIN: Most of theme's settings are documented using element's title attribute - hover over to see a description
+- Edit Permissions form redesigned and enlarged to fit more information
+
+version 1.7.3
+- ADMIN: Default states for the theme options are no longer being stored. Please save theme settings at least once to take advantage of a new functionality.
+- Photo Navigator default position is set to Top Only
+
+version 1.7.2
+- Fix in Uploader dialog to keep items inside respected boxes
+- Organize module support has been abandoned. Please use GWT Organize module instead. Added item in Prerequisites Checklist.
+
+version 1.7.1
+- CSS: Fixed visibility of the "Select Photo" button in "Add photo" dialog
+- CSS: Fixed "ghost" line for navigation buttons when zoomed-in in IE
+- Admin: fixed issue with prerequisite check not detecting deleted modules
+- /views/support folder deprecated. Logic moved into Theme_View extension class for Theme_View_Core
+- Theme Options Page management, generic Page code and BBCode processor moved into Theme_View class
+- HACK: Info block is not displayed if there is no description for the item
+
+version 1.6.4
+- Admin: Added "Show Sidebar for Albums only" option
+- Admin: added error visibility to the requirements validation list
+- Small CSS adjustments: Fixed footer min size issue when no site credit info is displayed; added space between Credits in the footer and Footer text area.
+- Few missing parts from last git sync
+
+version 1.6.3
+- Kohana 2.4 support
+- Support for Movie files view
+- Admin: Allow hide Sidebar Block header
+
+version 1.6.2
+- Admin: Page navigator option changed to use combobox
+- Admin: Added option to hide item description in albums
+
+version 1.6.2
+- Small CSS adjustments.
+- All operation dialogs should be visible now
+- Context menu: "Rotate 90..." items are removed due to an issue with image quality affected by the operation
+- Context menu: "Choose as the album cover" is now properly handled
+
+version 1.6.1
+- Admin: When allowed sidebar position is "Default Only", don't disregard selected Default position
+- Adjust item's toolbar buttons to align properly when side bar position is fixed
+- BBCode parser improved to support stripping of BBCode for Page title and breadcrumbs
+- Fixed issue with main menu missing class declaration not allowing open dialogs
+- Adjust context dialogs to properly show caption info
+- Caption added to Full size Preview
+- "New Comment" form styled
+- Admin: Option to align main menu to the top and Breadcrumbs to the left
+
+version 1.6.0
+- Admin: Fixed issue with "Rebuild thumbs" option in theme admin
+- Admin: Fixed issue with Item's toolbar not properly aligned in Quirks Mode
+- Exif data dialog Layout changes
+- Item context menu improvements:
+ - Fixed issue with submit logic
+ - Layout fixes for context menu dialogs
+
+version 1.5.8
+- Admin: First release of the Theme admin option. After theme installation, visit Appearance/Theme
+ Options to configure the theme. If you had older version of the theme, initial setup is also required.
+ The following settings are available:
+ - Rows per album page - theme uses 3 columns layout for pictures, therefore default page_size is computed in x3 increments
+ - Thumb size is restricted to 200 and therefore not available for administration
+ - Mark to build resizes/thumbs - allows force rebuilding of images
+ - Show/Hide top/bottom photo navigators
+ - Specify allowed and default sidebar position
+ - Administrator can now specify Copyright message to display in the footer
+ - Site logo is now default to Gallery 3 logo, but admin can provide a path to custom logo.
+ - Admin module validates Theme's requirements (Shadowbox module need to be installed/active)
+- Sidebar session cookie is set to expire in 365 days
+
+version 1.5.7
+- Status message has been moved into header as popup to prevent obstruction of the main view.
+ jQuery is used to fade it out in 10 sec.
+- Improved logic for dialogs on submit
+- Theme related JS has been moved out of the page.html.php
+
+version 1.5.6
+- Fixed issue with tollbar buttons not properly aligned/shown when page is resized.
+- Copyright info moved into DB. To change default settings add [th_greydragon/copyright] into VARS table.
+
+version 1.5.5
+- CSS fixes.
+- Theme adjusted to be compatible with latest Git.
+- Login links are moved into footer.
+- Pagination module redesigned to support new structure of paging data.
+
+version 1.5.4
+- CSS fixes.
+- Added support for Comments block.
+- Improved support for Modal dialogs.
+
+version 1.5.3
+- Updated to match latest git.
+- Exif menu customization is now part of the theme.
+- Sidebar management button is disabled for current mode.
+
+version 1.5.2
+- Code, layout, css cleanup.
+- New thumbs for buttons.
+- First set of Ajax dialogs is ready and now operational: Login, user info, edit album, exit info.
- Fixed some browser related issues.
\ No newline at end of file
diff --git a/themes/greydragon/controllers/greydragon.php b/themes/greydragon/controllers/greydragon.php
new file mode 100644
index 00000000..0796d801
--- /dev/null
+++ b/themes/greydragon/controllers/greydragon.php
@@ -0,0 +1,39 @@
+page_title = t("%name Profile", array("name" => $user->display_name()));
+ $v->content = new View("user_profile.html");
+
+ $v->content->user = $user;
+ $v->content->contactable =
+ !$user->guest && $user->id != identity::active_user()->id && $user->email;
+ $v->content->editable =
+ identity::is_writable() && !$user->guest && $user->id == identity::active_user()->id;
+
+ $event_data = (object)array("user" => $user, "content" => array());
+ module::event("show_user_profile", $event_data);
+ $v->content->info_parts = $event_data->content;
+
+ print $v;
+ }
+*/
+}
diff --git a/themes/greydragon/css/colorpacks/carbon/colors.css b/themes/greydragon/css/colorpacks/carbon/colors.css
new file mode 100644
index 00000000..57fd30dd
--- /dev/null
+++ b/themes/greydragon/css/colorpacks/carbon/colors.css
@@ -0,0 +1,192 @@
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * ColorPack: Carbon - Default color pack
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* styles.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+html { background-color: #333; }
+body { color: #999; background-color: #333; }
+
+h1 { border-bottom: #6f6f6f 1px solid; }
+a { color: #999 !important; font-weight: bold; }
+.ui-icon { background-image: url(images/ui-icons.png); }
+
+/* styles.css - Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-header .g-message-block { border: 1px #888 solid; background-color: #AAA; color: #000; }
+.g-breadcrumbs li { background: transparent url(images/ico-separator.png) no-repeat 0 0.2em; }
+
+/* styles.css - Content ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-main { background-color: #3f3f3f; margin-left: 10px; margin-right: 10px; }
+
+/* styles.css - Footer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+/* styles.css - Album Layout ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+#g-info .g-description { border: #6f6f6f 1px solid; }
+
+.g-thumbslide, .g-thumbslide-ext { border: 1px solid #303E43; background-color: #555; }
+.g-thumbcrop { border: 1px solid #303E43; }
+
+.g-album .g-thumbslide,
+.g-album .g-thumbslide-ext { border-top: 1px solid #6f6f6f; border-left: 1px solid #6f6f6f; border-right: 4px double #6f6f6f; border-bottom: 4px double #6f6f6f; }
+.g-photo .g-thumbslide, /* Need to compensate for double border in album's thumbs */
+.g-photo .g-thumbslide-ext { margin-bottom: 3px; }
+
+.g-thumbslide:hover .g-description { color: #fff; border-bottom: 1px solid #999; background: #1E1E1E; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+.g-album .g-thumbslide:hover .g-description,
+.g-album .g-thumbslide-ext .g-description { background: #555 url(images/ico-album.png) no-repeat 4px 2px; }
+
+.g-thumbslide:hover .g-metadata,
+.g-thumbslide-ext:hover .g-metadata { border-top: 1px solid #999; background: #1E1E1E; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+
+/* styles.css - Photo Layout ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+div.g-resize { border: 1px solid #888; background: #555; }
+
+div.g-resize:hover .g-description { color: #fff; background: #1E1E1E; border-bottom: 1px solid #999; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+div.g-resize .g-more { border: 1px solid #999; background: #1E1E1E; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+
+.g-movie { border: 1px solid #888; padding: 5px; background: #555; }
+
+/* styles.css - Reauthentificate ~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-reauthenticate-form ul { border: 1px #888 solid; }
+
+/* styles.css - Sidebar Blocks ~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-toolbar { border-bottom: 1px solid #737373; }
+
+/* styles.css - Sidebar Blocks : Common ~~~~~~~~~~~~~~*/
+
+.g-block { border: 1px solid #737373; }
+.g-block h2 { background: url(images/section.png) repeat-x; }
+
+/* styles.css - Sidebar Blocks : Buttons ~~~~~~~~~~~~~*/
+
+#g-viewformat .g-viewthumb-left { background: url('images/view-left.png') no-repeat left top; }
+#g-viewformat .g-viewthumb-right { background: url('images/view-right.png') no-repeat left top; }
+#g-viewformat .g-viewthumb-full { background: url('images/view-full.png') no-repeat left top; }
+
+#g-slideshow-link { background: url("images/view-slideshow.png") top left no-repeat; }
+.g-fullsize-link { background: url("images/view-fullsize.png") top left no-repeat; }
+#g-exifdata-link { background: url("images/view-info.png") top left no-repeat; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* menus.css ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-site-menu ul { border: #000000 0 solid; }
+#g-site-menu li a:hover { color: #000000; background-color: #333; }
+#g-site-menu li:hover,
+#g-site-menu li.iemhover { border: #303030 1px solid; background-color: #333; border-bottom: #000000 1px solid; }
+#g-site-menu li ul { border: #000000 1px solid; }
+#g-site-menu li ul li { border: #C0C0C0 0px solid; background-color: #333; }
+#g-site-menu li ul li:hover,
+#g-site-menu li ul li.iemhover { border: #C0C0C0 0 solid; background-color: #ddf2ff; }
+
+.g-item .g-context-menu { background-image: url(images/ui-icons.png); }
+.g-item .g-context-menu:hover { background: #333 none; border: 1px #888 solid; }
+.g-item .g-context-menu li li a:hover { background-color: #ddf2ff; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* forms.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-body { background: #101415 url('images/ajax-loading.gif') no-repeat center center; }
+#sb-title { border-left: #303030 1px solid; border-right: #303030 1px solid; background-color: #333; }
+
+#sb-content.html_ajax p.g-error { color: red; }
+#sb-content.html_ajax form { background-color: #101415; }
+#sb-content.html_ajax>div { background-color: #101415; }
+
+/* forms.css - Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-permissions .g-breadcrumbs { border: #303030 1px solid; }
+#sb-content #g-edit-permissions-form { border: #303030 1px solid; }
+#sb-content #g-move>ul { border: #303030 1px solid; }
+
+/* forms.css - Add item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-add-photos-form .g-breadcrumbs { border: #303030 1px solid; }
+
+#g-add-photos-canvas { background-color: #101010; border: #303030 1px solid; }
+#g-add-photos-button { border: #303030 1px solid; color: #bbb; }
+#g-add-photos-status { background-color: #101010; border: #303030 1px solid; }
+
+#g-add-photos-status li.g-success { background: #d9efc2 url('images/ico-success.png') no-repeat .4em 50%; }
+#g-add-photos-status li.g-error { background: #f6cbca url('images/ico-error.png') no-repeat .4em 50%; color: #f00; }
+
+/* forms.css - Organize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content.html_ajax #g-organize { border: #303030 1px solid; }
+
+#g-organize-detail { border-left: #303030 1px solid; }
+#g-organize .g-message-block { border-bottom: #303030 1px solid; }
+.g-organize-microthumb-grid-cell { background-color: #303030; }
+.g-organize-microthumb { background-color: #707070; }
+#g-organize-controls { border-top: #303030 1px solid; }
+
+/* forms.css - User Profile ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-user-profile .g-avatar { border: 1px solid #888; background: #555; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* menus.css ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-site-menu ul { border: #000000 0 solid; }
+#g-site-menu li a:hover { color: #000000; background-color: #303030; }
+#g-site-menu li:hover,
+#g-site-menu li.iemhover { border: #303030 1px solid; background-color: #303030; border-bottom: #000000 1px solid; }
+#g-site-menu li ul { border: #000000 1px solid; }
+#g-site-menu li ul li { border: #C0C0C0 0px solid; background-color: #212121; }
+#g-site-menu li ul li:hover,
+#g-site-menu li ul li.iemhover { border: #C0C0C0 0 solid; background-color: #303030; }
+
+.g-item .g-context-menu { background-image: url(images/ui-icons.png); }
+.g-item .g-context-menu:hover { background: #181818 none; border: 1px #888 solid; }
+.g-item .g-context-menu li li a:hover { background-color: #303030; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* modules.css - Exif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-exif-data table { border: #303030 1px solid; }
+#sb-content #g-exif-data .g-even { background-color: #404040; }
+#sb-content #g-exif-data .g-odd { background-color: #303030; }
+
+/* modules.css - Info module ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-metadata .g-description { border-top: 1px solid #737373; }
+
+/* modules.css - Image block ~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-image-block img { border: 1px solid #888; background: #555; }
+
+/* modules.css - Comments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-comments .g-author { border-bottom: 1px solid #202628; color: #999; }
+#g-comments-link { background-image: url(images/view-comments.png); }
+#g-comment-detail>ul>li { border: 1px dotted #737373; }
+#g-comment-form { border: 1px dotted #737373; }
+
+/* modules.css - Calendar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-view-menu #g-calendarview-link { background-image: url(images/view-calendar.png); }
+#g-view-calendar-form ul { border: 1px #888 solid; }
+table.calendar { border: #a2adbc 1px solid; color: #616b76; }
+table.calendar th { border-bottom: #a2adbc 1px solid; border-right: #a2adbc 1px solid; background: #d9e2e1; color: #616b76; }
+table.calendar td { border-bottom: #a2adbc 1px solid; border-right: #a2adbc 1px solid; }
+table.calendar td.title { background-color: #a2adbc; color: #fff; }
+table.calendar td.title a { color: #fff !important; }
+table.calendar td a { color: red !important; }
+
+/* modules.css - Search ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-quick-search-form input[type="text"] { background-color: transparent; border: 1px solid #737373; color: #BBB; }
+#g-quick-search-form input[type="submit"] { background: transparent url(images/search.png) no-repeat center top; border: none; }
+
+/* modules.css - Basket ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#checkout legend { background: url(images/section.png) repeat-x; }
\ No newline at end of file
diff --git a/themes/greydragon/images/ajax-loading.gif b/themes/greydragon/css/colorpacks/carbon/images/ajax-loading.gif
similarity index 100%
rename from themes/greydragon/images/ajax-loading.gif
rename to themes/greydragon/css/colorpacks/carbon/images/ajax-loading.gif
diff --git a/themes/greydragon/css/colorpacks/carbon/images/ico-album.png b/themes/greydragon/css/colorpacks/carbon/images/ico-album.png
new file mode 100644
index 00000000..ac87ec4f
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/ico-album.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/ico-error.png b/themes/greydragon/css/colorpacks/carbon/images/ico-error.png
new file mode 100644
index 00000000..c37bd062
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/ico-error.png differ
diff --git a/themes/greydragon/images/ico-separator.png b/themes/greydragon/css/colorpacks/carbon/images/ico-separator.png
similarity index 100%
rename from themes/greydragon/images/ico-separator.png
rename to themes/greydragon/css/colorpacks/carbon/images/ico-separator.png
diff --git a/themes/greydragon/css/colorpacks/carbon/images/ico-success.png b/themes/greydragon/css/colorpacks/carbon/images/ico-success.png
new file mode 100644
index 00000000..a9925a06
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/ico-success.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/search.png b/themes/greydragon/css/colorpacks/carbon/images/search.png
new file mode 100644
index 00000000..2d115cc8
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/search.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/section.png b/themes/greydragon/css/colorpacks/carbon/images/section.png
new file mode 100644
index 00000000..8180ecb3
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/section.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/ui-icons.png b/themes/greydragon/css/colorpacks/carbon/images/ui-icons.png
new file mode 100644
index 00000000..7d1723bf
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/ui-icons.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-calendar.png b/themes/greydragon/css/colorpacks/carbon/images/view-calendar.png
new file mode 100644
index 00000000..5442fa51
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-calendar.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-comments.png b/themes/greydragon/css/colorpacks/carbon/images/view-comments.png
new file mode 100644
index 00000000..5449126b
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-comments.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-full.png b/themes/greydragon/css/colorpacks/carbon/images/view-full.png
new file mode 100644
index 00000000..7145fd9d
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-full.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-fullsize.png b/themes/greydragon/css/colorpacks/carbon/images/view-fullsize.png
new file mode 100644
index 00000000..ebd04237
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-fullsize.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-info.png b/themes/greydragon/css/colorpacks/carbon/images/view-info.png
new file mode 100644
index 00000000..ff30501c
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-info.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-left.png b/themes/greydragon/css/colorpacks/carbon/images/view-left.png
new file mode 100644
index 00000000..c59af5d0
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-left.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-right.png b/themes/greydragon/css/colorpacks/carbon/images/view-right.png
new file mode 100644
index 00000000..59505456
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-right.png differ
diff --git a/themes/greydragon/css/colorpacks/carbon/images/view-slideshow.png b/themes/greydragon/css/colorpacks/carbon/images/view-slideshow.png
new file mode 100644
index 00000000..2fb53ad0
Binary files /dev/null and b/themes/greydragon/css/colorpacks/carbon/images/view-slideshow.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/colors.css b/themes/greydragon/css/colorpacks/greydragon/colors.css
new file mode 100644
index 00000000..22a6d40e
--- /dev/null
+++ b/themes/greydragon/css/colorpacks/greydragon/colors.css
@@ -0,0 +1,178 @@
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * ColorPack: GreyDragon - Default color pack
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* styles.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+html { background-color: #1A2022; }
+body { color: #BBB; background: url(images/background.gif) #1A2022 repeat-x; }
+
+h1 { border-bottom: #737373 1px solid; }
+a { color: #6392CF !important; }
+.ui-icon { background-image: url(images/ui-icons.png); }
+
+/* styles.css - Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-header .g-message-block { border: 1px #888 solid; background-color: #AAA; color: #000; }
+.g-breadcrumbs li { background: transparent url(images/ico-separator.png) no-repeat 0 0.2em; }
+
+/* styles.css - Footer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-footer { background: url(images/footer.png) #1A2022 repeat-x top !important; }
+
+/* styles.css - Album Layout ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+#g-info .g-description { border: #737373 1px solid; }
+
+.g-thumbslide, .g-thumbslide-ext { border: 1px solid #303E43; background: #1E1E1E url('images/image-thumb.gif') repeat-x; }
+.g-thumbcrop { border: 1px solid #303E43; }
+
+.g-album .g-thumbslide,
+.g-album .g-thumbslide-ext { border-top: 1px solid #43565B; border-left: 1px solid #43565B; border-right: 4px double #43565B; border-bottom: 4px double #43565B; }
+.g-photo .g-thumbslide, /* Need to compensate for double border in album's thumbs */
+.g-photo .g-thumbslide-ext { margin-bottom: 3px; }
+
+.g-thumbslide:hover .g-description { color: #fff; border-bottom: 1px solid #999; background: #1E1E1E; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+.g-album .g-thumbslide:hover .g-description,
+.g-album .g-thumbslide-ext .g-description { background: #1E1E1E url(images/ico-album.png) no-repeat 4px 2px; }
+
+.g-thumbslide:hover .g-metadata,
+.g-thumbslide-ext:hover .g-metadata { border-top: 1px solid #999; background: #1E1E1E; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+
+/* styles.css - Photo Layout ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+div.g-resize { border: 1px solid #888; background: #555; }
+
+div.g-resize:hover .g-description { color: #fff; background: #1E1E1E; border-bottom: 1px solid #999; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+div.g-resize .g-more { border: 1px solid #999; background: #1E1E1E; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+
+.g-movie { border: 1px solid #888; padding: 5px; background: #555; }
+
+/* styles.css - Reauthentificate ~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-reauthenticate-form ul { border: 1px #888 solid; }
+
+/* styles.css - Sidebar Blocks ~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-toolbar { border-bottom: 1px solid #737373; }
+
+/* styles.css - Sidebar Blocks : Common ~~~~~~~~~~~~~~*/
+
+.g-block { border: 1px solid #737373; background-color: #101415; }
+.g-block h2 { background: url(images/section.png) repeat-x; }
+
+/* styles.css - Sidebar Blocks : Buttons ~~~~~~~~~~~~~*/
+
+#g-viewformat .g-viewthumb-left { background: url('images/view-left.png') no-repeat left top; }
+#g-viewformat .g-viewthumb-right { background: url('images/view-right.png') no-repeat left top; }
+#g-viewformat .g-viewthumb-full { background: url('images/view-full.png') no-repeat left top; }
+
+#g-slideshow-link { background: url("images/view-slideshow.png") top left no-repeat; }
+.g-fullsize-link { background: url("images/view-fullsize.png") top left no-repeat; }
+#g-exifdata-link { background: url("images/view-info.png") top left no-repeat; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* forms.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-body { background: #101415 url('images/ajax-loading.gif') no-repeat center center; }
+#sb-title { border-left: #303030 1px solid; border-right: #303030 1px solid; background: #101415 url('images/section.png') repeat-x; }
+
+#sb-content.html_ajax p.g-error { color: red; }
+#sb-content.html_ajax form { background-color: #101415; }
+#sb-content.html_ajax>div { background-color: #101415; }
+
+/* styles.css - Photo Slideshow ~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-counter a { color: #fff !important; font-weight: bold; font-size: 11px; }
+
+/* forms.css - Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-permissions .g-breadcrumbs { border: #303030 1px solid; }
+#sb-content #g-edit-permissions-form { border: #303030 1px solid; }
+#sb-content #g-move>ul { border: #303030 1px solid; }
+
+/* forms.css - Add item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-add-photos-form .g-breadcrumbs { border: #303030 1px solid; }
+
+#g-add-photos-canvas { background-color: #101010; border: #303030 1px solid; }
+#ag-add-photos-button { border: #303030 1px solid; color: #bbb; }
+#g-add-photos-status { background-color: #101010; border: #303030 1px solid; }
+
+#g-add-photos-status li.g-success { background: url('images/ico-success.png') transparent no-repeat .4em 50%; }
+#g-add-photos-status li.g-error { background: url('images/ico-error.png') transparent no-repeat .4em 50%; color: #f00; }
+
+/* forms.css - Organize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content.html_ajax #g-organize { border: #303030 1px solid; }
+
+#g-organize-detail { border-left: #303030 1px solid; }
+#g-organize .g-message-block { border-bottom: #303030 1px solid; }
+.g-organize-microthumb-grid-cell { background-color: #303030; }
+.g-organize-microthumb { background-color: #707070; }
+#g-organize-controls { border-top: #303030 1px solid; }
+
+/* forms.css - User Profile ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-user-profile .g-avatar { border: 1px solid #888; background: #555; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* menus.css ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-site-menu ul { border: #000000 0 solid; }
+#g-site-menu li a:hover { color: #000000; background-color: #303030; }
+#g-site-menu li:hover,
+#g-site-menu li.iemhover { border: #303030 1px solid; background-color: #303030; border-bottom: #000000 1px solid; }
+#g-site-menu li ul { border: #000000 1px solid; }
+#g-site-menu li ul li { border: #C0C0C0 0px solid; background-color: #212121; }
+#g-site-menu li ul li:hover,
+#g-site-menu li ul li.iemhover { border: #C0C0C0 0 solid; background-color: #303030; }
+
+.g-item .g-context-menu { background-image: url(images/ui-icons.png); }
+.g-item .g-context-menu:hover { background: #181818 none; border: 1px #888 solid; }
+.g-item .g-context-menu li li a:hover { background-color: #303030; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* modules.css - Exif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-exif-data table { border: #303030 1px solid; }
+#sb-content #g-exif-data .g-even { background-color: #404040; }
+#sb-content #g-exif-data .g-odd { background-color: #303030; }
+
+/* modules.css - Info module ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-metadata .g-description { border-top: 1px solid #737373; }
+
+/* modules.css - Image block ~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-image-block img { border: 1px solid #888; background: #555; }
+
+/* modules.css - Comments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-comments .g-author { border-bottom: 1px solid #202628; color: #999; }
+#g-comments-link { background-image: url(images/view-comments.png); }
+#g-comment-detail>ul>li { border: 1px dotted #737373; }
+#g-comment-form { border: 1px dotted #737373; }
+
+/* modules.css - Calendar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-view-menu #g-calendarview-link { background-image: url(images/view-calendar.png); }
+#g-view-calendar-form ul { border: 1px #888 solid; }
+table.calendar { border: #a2adbc 1px solid; color: #616b76; }
+table.calendar th { border-bottom: #a2adbc 1px solid; border-right: #a2adbc 1px solid; background: #d9e2e1; color: #616b76; }
+table.calendar td { border-bottom: #a2adbc 1px solid; border-right: #a2adbc 1px solid; }
+table.calendar td.title { background-color: #a2adbc; color: #fff; }
+table.calendar td.title a { color: #fff !important; }
+table.calendar td a { color: red !important; }
+
+/* modules.css - Search ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-quick-search-form input[type="text"] { background-color: transparent; border: 1px solid #737373; color: #BBB; }
+#g-quick-search-form input[type="submit"] { background: transparent url(images/search.png) no-repeat center top; border: none; }
+
+/* modules.css - Basket ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#checkout legend { background: url(images/section.png) repeat-x; }
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/ajax-loading.gif b/themes/greydragon/css/colorpacks/greydragon/images/ajax-loading.gif
new file mode 100644
index 00000000..0996045a
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/ajax-loading.gif differ
diff --git a/themes/greydragon/images/background.gif b/themes/greydragon/css/colorpacks/greydragon/images/background.gif
similarity index 100%
rename from themes/greydragon/images/background.gif
rename to themes/greydragon/css/colorpacks/greydragon/images/background.gif
diff --git a/themes/greydragon/images/footer.png b/themes/greydragon/css/colorpacks/greydragon/images/footer.png
similarity index 100%
rename from themes/greydragon/images/footer.png
rename to themes/greydragon/css/colorpacks/greydragon/images/footer.png
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/ico-album.png b/themes/greydragon/css/colorpacks/greydragon/images/ico-album.png
new file mode 100644
index 00000000..ac87ec4f
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/ico-album.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/ico-error.png b/themes/greydragon/css/colorpacks/greydragon/images/ico-error.png
new file mode 100644
index 00000000..c37bd062
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/ico-error.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/ico-separator.png b/themes/greydragon/css/colorpacks/greydragon/images/ico-separator.png
new file mode 100644
index 00000000..3e158515
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/ico-separator.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/ico-success.png b/themes/greydragon/css/colorpacks/greydragon/images/ico-success.png
new file mode 100644
index 00000000..a9925a06
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/ico-success.png differ
diff --git a/themes/greydragon/images/main.gif b/themes/greydragon/css/colorpacks/greydragon/images/image-thumb.gif
similarity index 55%
rename from themes/greydragon/images/main.gif
rename to themes/greydragon/css/colorpacks/greydragon/images/image-thumb.gif
index 49e2f6c4..bc3a192f 100644
Binary files a/themes/greydragon/images/main.gif and b/themes/greydragon/css/colorpacks/greydragon/images/image-thumb.gif differ
diff --git a/themes/greydragon/images/search.png b/themes/greydragon/css/colorpacks/greydragon/images/search.png
similarity index 100%
rename from themes/greydragon/images/search.png
rename to themes/greydragon/css/colorpacks/greydragon/images/search.png
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/section.png b/themes/greydragon/css/colorpacks/greydragon/images/section.png
new file mode 100644
index 00000000..8180ecb3
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/section.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/ui-icons.png b/themes/greydragon/css/colorpacks/greydragon/images/ui-icons.png
new file mode 100644
index 00000000..7ab15cae
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/ui-icons.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/view-calendar.png b/themes/greydragon/css/colorpacks/greydragon/images/view-calendar.png
new file mode 100644
index 00000000..206ccd66
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/view-calendar.png differ
diff --git a/themes/greydragon/images/view-comments.png b/themes/greydragon/css/colorpacks/greydragon/images/view-comments.png
similarity index 100%
rename from themes/greydragon/images/view-comments.png
rename to themes/greydragon/css/colorpacks/greydragon/images/view-comments.png
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/view-full.png b/themes/greydragon/css/colorpacks/greydragon/images/view-full.png
new file mode 100644
index 00000000..b75de946
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/view-full.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/view-fullsize.png b/themes/greydragon/css/colorpacks/greydragon/images/view-fullsize.png
new file mode 100644
index 00000000..ed76257a
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/view-fullsize.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/view-info.png b/themes/greydragon/css/colorpacks/greydragon/images/view-info.png
new file mode 100644
index 00000000..521439ce
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/view-info.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/view-left.png b/themes/greydragon/css/colorpacks/greydragon/images/view-left.png
new file mode 100644
index 00000000..b5b93c7a
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/view-left.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/view-right.png b/themes/greydragon/css/colorpacks/greydragon/images/view-right.png
new file mode 100644
index 00000000..a400c638
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/view-right.png differ
diff --git a/themes/greydragon/css/colorpacks/greydragon/images/view-slideshow.png b/themes/greydragon/css/colorpacks/greydragon/images/view-slideshow.png
new file mode 100644
index 00000000..c6a471ac
Binary files /dev/null and b/themes/greydragon/css/colorpacks/greydragon/images/view-slideshow.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/colors.css b/themes/greydragon/css/colorpacks/wind/colors.css
new file mode 100644
index 00000000..09ab5a6a
--- /dev/null
+++ b/themes/greydragon/css/colorpacks/wind/colors.css
@@ -0,0 +1,184 @@
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * ColorPack: Wind - Wind theme-like color pack
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* styles.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+html { background-color: #ccc; }
+body { color: #000; background-color: #ccc; padding-left: 10px; padding-right: 10px; }
+
+a { color: #33629f !important }
+.ui-icon { background-image: url(images/ui-icons.png); }
+
+/* styles.css - Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-header { background-color: #e8e8e8; border-bottom: #ccc 1px solid; }
+#g-header .g-message-block { border: 1px #888 solid; background-color: #aaa; color: #000; }
+.g-breadcrumbs li { background: transparent url(images/ico-separator.png) no-repeat 0 0.2em; }
+
+/* styles.css - Main ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-main { background-color: #fff; }
+
+/* styles.css - Footer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-footer { background-color: #e8e8e8; border-top: #ccc 1px solid; }
+
+/* styles.css - Album Layout ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-info h1, #g-album-header h1 { border-bottom: #ccc 1px solid; }
+#g-info .g-description { border: #888 1px solid; }
+
+.g-thumbslide { border: 1px solid #707E83; background-color: #e8e8e8; }
+.g-thumbcrop { border: 1px solid #707E83; }
+
+.g-album .g-thumbslide,
+.g-album .g-thumbslide-ext { border-top: 1px solid #707E83; border-left: 1px solid #707E83; border-right: 4px double #707E83; border-bottom: 4px double #707E83; }
+.g-photo .g-thumbslide, /* Need to compensate for double border in album's thumbs */
+.g-photo .g-thumbslide-ext { margin-bottom: 3px; }
+
+.g-thumbslide:hover .g-description { color: #000; border-bottom: 1px solid #999; background: #e8e8e8; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+.g-album .g-thumbslide:hover .g-description,
+.g-album .g-thumbslide-ext .g-description { background: #fff url(images/ico-album.png) no-repeat 4px 2px; }
+
+.g-thumbslide:hover .g-metadata,
+.g-thumbslide-ext:hover .g-metadata { border-top: 1px solid #999; background: #e8e8e8; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+
+/* styles.css - Photo Layout ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+div.g-resize { border: 1px solid #888; background: #e8e8e8; }
+
+div.g-resize:hover .g-description { color: #000; background: #e8e8e8; border-bottom: 1px solid #999; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+div.g-resize .g-more { border: 1px solid #999; background: #e8e8e8; filter:alpha(opacity=85); opacity:.85; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; }
+
+.g-movie { border: 1px solid #888; padding: 5px; background: #e8e8e8; }
+
+/* styles.css - Reauthentificate ~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-reauthenticate-form ul { border: 1px #888 solid; }
+
+/* styles.css - Sidebar Blocks ~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-toolbar { border-bottom: 1px solid #ccc; }
+
+/* styles.css - Sidebar Blocks : Common ~~~~~~~~~~~~~~*/
+
+.g-block { border: 1px solid #ccc; }
+.g-block h2 { background-color: #e8e8e8; }
+
+/* styles.css - Sidebar Blocks : Buttons ~~~~~~~~~~~~~*/
+
+#g-viewformat .g-viewthumb-left { background: url('images/view-left.png') no-repeat left top; }
+#g-viewformat .g-viewthumb-right { background: url('images/view-right.png') no-repeat left top; }
+#g-viewformat .g-viewthumb-full { background: url('images/view-full.png') no-repeat left top; }
+
+#g-slideshow-link { background: url("images/view-slideshow.png") top left no-repeat; }
+.g-fullsize-link { background: url("images/view-fullsize.png") top left no-repeat; }
+#g-exifdata-link { background: url("images/view-info.png") top left no-repeat; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* forms.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-body { background: #fff url('images/ajax-loading.gif') no-repeat center center; }
+#sb-title { border-left: #303030 1px solid; border-right: #303030 1px solid; background: #e8e8e8; color: #000; }
+#sb-title-inner { color: #000; }
+
+#sb-content.html_ajax p.g-error { color: red; }
+#sb-content.html_ajax form { background-color: #fff; }
+#sb-content.html_ajax>div { background-color: #fff; }
+
+/* forms.css - Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-permissions .g-breadcrumbs { border: #303030 1px solid; }
+#sb-content #g-edit-permissions-form { border: #303030 1px solid; }
+#sb-content #g-move>ul { border: #303030 1px solid; }
+
+/* forms.css - Add item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-add-photos-form .g-breadcrumbs { border: #303030 1px solid; }
+
+#g-add-photos-canvas { background-color: #fff; border: #303030 1px solid; }
+#g-add-photos-button { border: #303030 1px solid; }
+#g-add-photos-status { background-color: #fff; border: #303030 1px solid; }
+
+#g-add-photos-status li.g-success { background: #d9efc2 url('images/ico-success.png') no-repeat .4em 50%; }
+#g-add-photos-status li.g-error { background: #f6cbca url('images/ico-error.png') no-repeat .4em 50%; color: #f00; }
+
+/* forms.css - Organize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content.html_ajax #g-organize { border: #303030 1px solid; }
+
+#g-organize-detail { border-left: #303030 1px solid; }
+#g-organize .g-message-block { border-bottom: #303030 1px solid; }
+.g-organize-microthumb-grid-cell { background-color: #fff; }
+.g-organize-microthumb { background-color: #fff; }
+#g-organize-controls { border-top: #303030 1px solid; }
+
+/* forms.css - User Profile ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-user-profile h1 { border-bottom: #ccc 1px solid; }
+#g-user-profile .g-avatar { border: 1px solid #888; background: #fff; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* menus.css ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-site-menu ul { border: #000000 0 solid; }
+#g-site-menu li { background-color: #bdd2ff; }
+#g-site-menu li a:hover { color: #000000; background-color: #cfdeff; }
+#g-site-menu li:hover,
+#g-site-menu li.iemhover { border: #303030 1px solid; background-color: #cfdeff; border-bottom: #cfdeff 1px solid; }
+#g-site-menu li ul { border: #cfdeff 1px solid; }
+#g-site-menu li ul li { border: #C0C0C0 0px solid; background-color: #bdd2ff; }
+#g-site-menu li ul li:hover,
+#g-site-menu li ul li.iemhover { border: #C0C0C0 0 solid; background-color: #ddf2ff; }
+
+.g-item .g-context-menu { background-image: url(images/ui-icons.png); }
+.g-item .g-context-menu:hover { background: #bdd2ff none; border: 1px #888 solid; }
+.g-item .g-context-menu li li a:hover { background-color: #ddf2ff; }
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* modules.css - Exif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-exif-data table { border: #303030 1px solid; }
+#sb-content #g-exif-data .g-even { background-color: #A0A0A0; }
+#sb-content #g-exif-data .g-odd { background-color: #C0C0C0; }
+
+/* modules.css - Info module ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-metadata .g-description { border-top: 1px solid #ccc; }
+
+/* modules.css - Image block ~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-image-block img { border: 1px solid #888; background: #555; }
+
+/* modules.css - Comments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-comments .g-author { border-bottom: 1px solid #202628; color: #999; }
+#g-comments-link { background-image: url(images/view-comments.png); }
+#g-comment-detail>ul>li { border: 1px dotted #ccc; }
+#g-comment-form { border: 1px dotted #ccc; }
+
+/* modules.css - Calendar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-view-menu #g-calendarview-link { background-image: url(images/view-calendar.png); }
+#g-view-calendar-form ul { border: 1px #888 solid; }
+table.calendar { border: #a2adbc 1px solid; color: #616b76; }
+table.calendar th { border-bottom: #a2adbc 1px solid; border-right: #a2adbc 1px solid; background: #d9e2e1; color: #616b76; }
+table.calendar td { border-bottom: #a2adbc 1px solid; border-right: #a2adbc 1px solid; }
+table.calendar td.title { background-color: #a2adbc; color: #fff; }
+table.calendar td.title a { color: #fff !important; }
+table.calendar td a { color: red !important; }
+
+/* modules.css - Search ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-quick-search-form input[type="text"] { background-color: transparent; border: 1px solid #ccc; color: #666; }
+#g-quick-search-form input[type="submit"] { border: #c5dbec 1px solid; text-indent: 0; width: auto; height: auto; font: 80% arial, helvetica, clean, sans-serif; font-weight: bold; padding-top: 3px; padding-bottom: 3px; }
+#g-search-results h1 { border-bottom: #ccc 1px solid; }
+
+/* modules.css - Basket ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#checkout legend { background-color: #e8e8e8; }
\ No newline at end of file
diff --git a/themes/greydragon/css/colorpacks/wind/images/ajax-loading.gif b/themes/greydragon/css/colorpacks/wind/images/ajax-loading.gif
new file mode 100644
index 00000000..53dd589f
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/ajax-loading.gif differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/ico-album.png b/themes/greydragon/css/colorpacks/wind/images/ico-album.png
new file mode 100644
index 00000000..ac87ec4f
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/ico-album.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/ico-error.png b/themes/greydragon/css/colorpacks/wind/images/ico-error.png
new file mode 100644
index 00000000..c37bd062
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/ico-error.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/ico-separator.png b/themes/greydragon/css/colorpacks/wind/images/ico-separator.png
new file mode 100644
index 00000000..3e158515
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/ico-separator.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/ico-success.png b/themes/greydragon/css/colorpacks/wind/images/ico-success.png
new file mode 100644
index 00000000..a9925a06
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/ico-success.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/ui-icons.png b/themes/greydragon/css/colorpacks/wind/images/ui-icons.png
new file mode 100644
index 00000000..a8bd54b5
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/ui-icons.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-calendar.png b/themes/greydragon/css/colorpacks/wind/images/view-calendar.png
new file mode 100644
index 00000000..13e0e8fa
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-calendar.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-comments.png b/themes/greydragon/css/colorpacks/wind/images/view-comments.png
new file mode 100644
index 00000000..f33bdf19
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-comments.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-full.png b/themes/greydragon/css/colorpacks/wind/images/view-full.png
new file mode 100644
index 00000000..e465d366
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-full.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-fullsize.png b/themes/greydragon/css/colorpacks/wind/images/view-fullsize.png
new file mode 100644
index 00000000..58b3e0b4
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-fullsize.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-info.png b/themes/greydragon/css/colorpacks/wind/images/view-info.png
new file mode 100644
index 00000000..2cc7a68e
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-info.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-left.png b/themes/greydragon/css/colorpacks/wind/images/view-left.png
new file mode 100644
index 00000000..b51e3368
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-left.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-right.png b/themes/greydragon/css/colorpacks/wind/images/view-right.png
new file mode 100644
index 00000000..bd72adfc
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-right.png differ
diff --git a/themes/greydragon/css/colorpacks/wind/images/view-slideshow.png b/themes/greydragon/css/colorpacks/wind/images/view-slideshow.png
new file mode 100644
index 00000000..61bf18e1
Binary files /dev/null and b/themes/greydragon/css/colorpacks/wind/images/view-slideshow.png differ
diff --git a/themes/greydragon/css/forms.css b/themes/greydragon/css/forms.css
index e1fb0c38..ab246779 100644
--- a/themes/greydragon/css/forms.css
+++ b/themes/greydragon/css/forms.css
@@ -1,33 +1,107 @@
-#sb-content { padding: 0px; margin: 0; }
-
-#g-exif-data { width: auto; min-height: 90%; margin: 10px; text-align: center; color: #ccc; background-color: #101415; overflow: auto; }
-#g-exif-data table { border: #eee 1px solid; font-size: 10pt; }
-#g-exif-data .g-even { background-color: #aaa; color: #000; }
-#g-exif-data .g-odd { background-color: #999; color: #fff; }
-
-/* Login dialog ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-form { background: #101415 url('../images/section.png') repeat-x; overflow: hidden; }
-form fieldset { border: none; }
-form legend { color: #bbb; padding: 6px 0 0 10px; width: 100%; }
-form ul { padding: 0; }
-form li { padding: 8px 0 0 20px; }
-form ul>fieldset>legend { display: none; }
-form label { display: block; }
-form textarea { width: 98%; }
-form input[type="text"],
-input[type="password"] { width: 90%; }
-
-#sb-content.html_ajax textarea { width: 270px; }
-#sb-content.html_ajax p.g-error { padding-top: 4px; color: red; }
-
-#g-text { min-height: 70px; }
-
-#g-login-form { width: 100%; }
-#g-login form ul { min-height: 160px; }
-#g-edit-user-form ul { min-height: 276px; }
-#g-password-reset { margin-left: 8px; }
-#g-edit-album-form fieldset fieldset { border: none; }
-#g-edit-album-form fieldset fieldset li { float: left; display: inline; }
-
-#g-add-photos-form { height: 100%; }
\ No newline at end of file
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * CSS rules related to forms/dialogs
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* forms.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+input[type="submit"], .g-button, button { cursor: pointer; /* hand-shaped cursor */ cursor: hand; /* for IE 5.x */ font-size: 0.8em; color: #333 !important; padding: 2px 10px; margin-top: 0.4em; border: 1px solid; border-color: #999 #666 #666 #999; background-color: #ddd; font-weight: normal; }
+
+#sb-content.html_ajax { padding: 0 0.8em; margin: 0; }
+#sb-content.html_ajax p.g-error { padding-top: 0.4em; }
+
+#sb-content.html_ajax form { background-color: #101415; overflow: hidden; }
+#sb-content.html_ajax form fieldset { border: none; }
+#sb-content.html_ajax form legend { display: none; width: 100%; }
+#sb-content.html_ajax form ul { padding: 0; }
+#sb-content.html_ajax form li { padding-top: 0.2em; }
+#sb-content.html_ajax form>fieldset>ul { margin: 0 2px; }
+#sb-content.html_ajax form label { display: block; padding: 0.2em 0; }
+#sb-content.html_ajax form textarea { width: 99%; height: 4em; }
+#sb-content.html_ajax input[type="submit"]{ margin: 6px 0; }
+#sb-content.html_ajax input[type="text"],
+#sb-content.html_ajax input[type="password"] { width: 99%; }
+#sb-content.html_ajax>div { height: 94%; padding-top: 0.2em; overflow: auto; }
+#sb-content #g-text { min-height: 6em; }
+
+#sb-content fieldset fieldset { border: none; }
+#sb-content fieldset fieldset li { float: left; display: inline; margin-right: 1em; }
+
+/* forms.css - Login ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-login-form { width: 100%; }
+#sb-content #g-login form ul { min-height: 10em; }
+#sb-content #g-password-reset { margin-left: 0.4em; }
+
+/* forms.css - Edit Permissions ~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-permissions fieldset { border: none; margin: 1px; overflow: auto; width: 100%; }
+#sb-content #g-permissions .g-breadcrumbs { position: static; padding: 0.4em; font-size: small; margin: 0.4em 0; }
+#sb-content #g-permissions .g-breadcrumbs .g-first { padding-left: 0; }
+
+#sb-content #g-edit-permissions-form { margin: 0.4px 0; }
+#sb-content #g-edit-permissions-form>fieldset>legend { display: none; }
+#sb-content #g-edit-permissions-form>fieldset>table { font-size: small; }
+#sb-content #g-edit-permissions-form>fieldset>table th,
+#sb-content #g-edit-permissions-form>fieldset>table td { padding: 1px 2px; }
+
+/* forms.css - Delete Item ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-confirm-delete { height: 5em; padding: 0.8em 0 0 0; }
+
+/* forms.css - Move Item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-move>ul { height: 290px; margin-bottom: 0.4em; padding: 10px; overflow: auto; }
+#sb-content #g-move>form { background: none; }
+
+/* forms.css - Add photo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-add-photos-form { height: 96%; }
+#sb-content #g-add-photos-form .g-breadcrumbs { position: static; margin: 4px 0 0 0; padding: 4px; font-size: x-small; }
+#sb-content #g-add-photos-form .g-breadcrumbs li { padding-top: 0; }
+#sb-content #g-add-photos-form .g-breadcrumbs .g-first { padding-left: 0; }
+
+#g-add-photos-canvas { margin-top: 4px; height: 100px; }
+#g-add-photos-button { padding: 2px 8px; z-index: 10; zoom: 1; }
+#g-uploadifyUploader { z-index: 1005; zoom: 1; }
+#g-uploadifyQueue { overflow: auto; height: 100%; }
+#g-add-photos-status { margin-top: 4px; height: 90px; overflow: auto; }
+#g-add-photos-status #g-action-status { margin: 0 0 1px 0; width: 100%; }
+#g-add-photos-status #g-action-status li { margin: 0 0 1px 0; padding: 2px 0; text-indent: 30px; width: 100%; }
+
+/* forms.css - Organize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content.html_ajax #g-organize { height: 440px; }
+#g-organize #g-organize-content-pane { display: block; height: 440px; width: 690px; margin: 0 !important; overflow: hidden; }
+#g-organize #g-organize-content-pane>div { float: left; height: 440px; }
+#g-organize #g-organize-content-pane #g-organize-tree-container { overflow: auto; width: 164px; height: 428px; padding: 0 2px 0 4px !important; }
+#g-organize #g-organize-detail { width: 518px; }
+#g-organize #g-organize-detail .g-message-block li { padding: 0; }
+#g-organize #g-organize-tree-container>ul { font-size: x-small; }
+#g-organize #g-organize-tree-container>ul ul { padding: 0px; }
+#g-organize #g-organize-album-tree { padding: 0; }
+#g-organize .g-message-block { padding: 4px 0 4px 10px; }
+#g-organize-microthumb-panel { background-color: transparent; border: none; height: 360px; }
+#g-organize-microthumb-grid { position: static; height: 360px; border-style: none; padding: 0 2px !important; }
+.g-organize-microthumb-grid-cell { float: left; margin: 2px; }
+.g-organize-microthumb-grid-cell .ui-icon-note { background-position: -194px -144px; left: 8px; bottom: 4px; }
+#g-organize-controls { position: absolute; background-color: transparent; padding: 6px 10px; }
+#g-organize-controls li { display: inline; }
+.g-organize-album-text { border: transparent 1px solid; }
+#g-organize-close { display: none; }
+
+/* forms.css - User Profile ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-user-profile h1 { padding-bottom: 1px; margin: 0 0; }
+#g-user-profile>div { margin: 2em 0 1em 10em; }
+#g-user-profile .g-block-content { text-align: left; }
+#g-user-profile .g-avatar { float: left; padding: 2px; }
+
+#g-user-profile th { text-align: left; padding-right: 20px; }
+#g-change-email-user-form { min-height: 200px; }
+#g-edit-user-form ul { min-height: 200px; }
+
+#g-quick-search-form input[type="submit"] { filter: none; margin-top: 0; }
\ No newline at end of file
diff --git a/themes/greydragon/css/layout.css b/themes/greydragon/css/layout.css
index 18b76412..db55e4af 100644
--- a/themes/greydragon/css/layout.css
+++ b/themes/greydragon/css/layout.css
@@ -1,21 +1,38 @@
-html { overflow: auto; }
-* { margin: 0px; }
-body { min-width: 73em; padding: 0; margin: 0; }
-
-#g-header { position: relative; min-width: 73em; z-index: 5; }
-#g-main, #g-main-in { min-width: 72.7em; height: auto; bottom: auto; }
-#g-footer { position: relative; height: auto; min-width: 73em; clear: both; display: block; overflow: auto; }
-
-#g-column-left { float: left; width: 18em; min-height: 32em; overflow: hidden; height: 100%; }
-#g-column-right { float: right; width: 18em; min-height: 32em; overflow: hidden; height: 100%; }
-#g-column-center { margin: 0 19em 0 19em; min-height: 32em; overflow: hidden; height: 100%; }
-#g-column-centerleft { margin: 0 19em 0 0; min-height: 32em; overflow: hidden; height: 100%; }
-#g-column-centerright { margin: 0 0 0 19em; min-height: 32em; overflow: hidden; height: 100%; }
-#g-column-centerfull { position: relative; margin: 0 0; min-height: 31em; overflow: hidden; height: 100%; }
-
-#g-footer-leftside { float: left; display: inline; }
-#g-footer-rightside { float: right; display: inline; }
-
-.g-hideitem { display: none; }
-
-#g-main-in { overflow: auto; height: 100%; }
\ No newline at end of file
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * CSS rules related to general layout
+ * Defined as 70em wide
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* layout.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+html { overflow: auto; overflow: -moz-scrollbars-vertical; overflow-y: scroll; }
+* { margin: 0px; }
+body { min-width: 70em; padding: 0; margin: 0; }
+
+.g-hideitem { display: none; }
+
+/* layout.css - Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-header { position: relative; min-width: 70em; z-index: 5; }
+
+/* layout.css - Main ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-main { min-width: 69.7em; height: auto; bottom: auto; }
+#g-main-in { min-width: 69.7em; height: 100%; overflow: auto; bottom: auto; }
+#g-column-left { float: left; width: 16em; min-height: 32em; overflow: hidden; height: 100%; }
+#g-column-right { float: right; width: 16em; min-height: 32em; overflow: hidden; height: 100%; }
+#g-column-center { margin: 0 17em 0 17em; min-height: 32em; overflow: hidden; height: 100%; }
+#g-column-centerleft { margin: 0; min-height: 32em; overflow: hidden; height: 100%; }
+#g-column-centerright { margin: 0; min-height: 32em; overflow: hidden; height: 100%; }
+#g-column-centerfull { position: relative; margin: 0 0; min-height: 31em; overflow: hidden; height: 100%; }
+
+/* layout.css - Footer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-footer { position: relative; height: auto; min-width: 70em; min-height: 4em; clear: both; display: block; overflow: auto; }
+#g-footer-leftside { float: left; display: inline; }
+#g-footer-rightside { float: right; display: inline; }
+
diff --git a/themes/greydragon/css/menus.css b/themes/greydragon/css/menus.css
index 1e27610c..3ba173f2 100644
--- a/themes/greydragon/css/menus.css
+++ b/themes/greydragon/css/menus.css
@@ -1,27 +1,56 @@
-#g-site-menu { position: absolute; bottom: 0px; left: 310px; }
-#g-site-menu ul { float: left; padding: 0px; margin: 0px; width: 100%; border: #000000 0px solid; white-space: nowrap; z-index: 100; }
-#g-site-menu a { display: block; padding: 3px 5px 4px 5px; text-align: center; width: auto; letter-spacing: 0px; cursor: pointer; }
-#g-site-menu li { float: left; padding: 0px; background-color: transparent; border: transparent 1px solid; }
-#g-site-menu li a:hover { color: #000000; cursor: pointer; background-color: #303030; }
-#g-site-menu li:hover,
-#g-site-menu li.iemhover { border: #303030 1px solid; background-color: #303030; border-bottom: #000000 1px solid; }
-#g-site-menu li ul a { text-align: left; padding: 4px 0px; text-indent: 8px; letter-spacing: 0px; cursor: pointer; }
-#g-site-menu li ul a:hover { background-image: none; cursor: pointer; }
-#g-site-menu li ul { border: #000000 1px solid; position: absolute; margin: 0px 0px 0px -1px; width: 135px; height: auto; left: -999em; }
-#g-site-menu li ul li { border: #C0C0C0 0px solid; background-color: #212121; }
-#g-site-menu li ul li:hover,
-#g-site-menu li ul li.iemhover { border: #C0C0C0 0px solid; background-color: #303030; }
-
-#g-site-menu li li { width: 135px; padding-right: 0px; }
-#g-site-menu li ul a { width: 135px; }
-#g-site-menu li ul ul { margin: -21px 0px 0px 135px; }
-#g-site-menu li:hover ul ul,
-#g-site-menu li:hover ul ul ul,
-#g-site-menu li.iemhover ul ul,
-#g-site-menu li.iemhover ul ul ul { left: -999em; }
-#g-site-menu li:hover ul,
-#g-site-menu li li:hover ul,
-#g-site-menu li li li:hover ul,
-#g-site-menu li.iemhover ul,
-#g-site-menu li li.iemhover ul,
-#g-site-menu li li li.iemhover ul { left: auto; }
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * CSS rules related to menus
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* menus.css - Main menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-site-menu { position: absolute; left: 24em; }
+#g-site-menu.default { bottom: 0; }
+#g-site-menu.top { top: 0; }
+#g-site-menu ul { float: left; padding-left: 0; width: 100%; white-space: nowrap; z-index: 10; }
+#g-site-menu ul ul ul { padding-top: 0; }
+#g-site-menu a { display: block; padding: 0.2em 0.4em; text-align: center; width: auto; letter-spacing: 0; cursor: pointer; }
+#g-site-menu li { float: left; padding: 0; background-color: transparent; border: transparent 1px solid; z-index: 10; }
+#g-site-menu li a:hover { cursor: pointer; }
+#g-site-menu li ul a { text-align: left; padding: 0.3em 0; text-indent: 0.8em; letter-spacing: 0; cursor: pointer; }
+#g-site-menu li ul a:hover { background-image: none; cursor: pointer; }
+#g-site-menu li ul { position: absolute; margin: 0 0 0 -1px; width: 14em; height: auto; left: -999em; }
+
+#g-site-menu li li { width: 14em; padding-right: 0; }
+#g-site-menu li ul a { width: 14em; }
+#g-site-menu li ul ul { margin: -1.9em 0 0 14em; }
+#g-site-menu li:hover ul ul,
+#g-site-menu li:hover ul ul ul,
+#g-site-menu li.iemhover ul ul,
+#g-site-menu li.iemhover ul ul ul { left: -999em; }
+#g-site-menu li:hover ul,
+#g-site-menu li li:hover ul,
+#g-site-menu li li li:hover ul,
+#g-site-menu li.iemhover ul,
+#g-site-menu li li.iemhover ul,
+#g-site-menu li li li.iemhover ul { left: auto; }
+
+#g-site-menu>ul>li>ul { display: none; }
+
+#g-site-menu .ui-icon-rotate-ccw,
+#g-site-menu .ui-icon-rotate-cw { display: none; }
+
+/* menus.css - Context menu ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-item .g-context-menu { position: absolute; margin: 0; padding: 0; top: 6px; left: 196px; width: 14px; height: 14px; background-position: -178px -144px; z-index: 3; }
+.g-item .g-context-menu li { width: 100%; padding: 0; margin: 0; text-indent: -9999px; }
+.g-item .g-context-menu>li>a { font-size: 0em; }
+.g-item .g-context-menu:hover { top: 4px; left: 6px; width: 200px; height: auto; z-index: 100; }
+.g-item .g-context-menu ul { padding: 0; margin: 0; }
+.g-item .g-context-menu li li { display: none; }
+.g-item .g-context-menu li li a { display: block; padding: 4px 6px; }
+.g-item .g-context-menu:hover li li { display: block; text-indent: 0px; }
+.g-item .g-context-menu li li a.ui-icon-rotate-ccw,
+.g-item .g-context-menu li li a.ui-icon-rotate-cw { display: none; }
+
+.g-item.g-detail .g-context-menu { left: auto; right: 6px; }
+.g-item.g-detail .g-context-menu:hover { left: auto; right: 6px; }
\ No newline at end of file
diff --git a/themes/greydragon/css/modules.css b/themes/greydragon/css/modules.css
new file mode 100644
index 00000000..371434f8
--- /dev/null
+++ b/themes/greydragon/css/modules.css
@@ -0,0 +1,135 @@
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * CSS rules related to modules
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* modules.css - ShadowBox Skin ~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-title { overflow: hidden; }
+#sb-title-inner { font-size: 10pt; font-weight: bold; padding-left: 10px; }
+#sb-nav #sb-nav-close { background-image: url('../images/close.png'); width: 60px; }
+#sb-container > #sb-overlay { min-height: 530px; overflow: auto; }
+
+/* modules.css - Exif Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#sb-content #g-exif-data { width: auto; background-image: none; }
+#sb-content #g-exif-data table { width: 100%; }
+#sb-content #g-exif-data td { padding: 0.4em; }
+
+/* modules.css - Image Block ~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-image-block>div { margin-left: 1px; margin-right: 1px; }
+.g-image-block { text-align: center; }
+.g-image-block img { padding: 5px; }
+
+/* modules.css - RSS Feeds ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+ul#g-feeds { padding: 0; margin: 0; }
+
+/* modules.css - Tags ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-tag-cloud ul { padding: 0; font-size: 100%; }
+#g-tag-cloud ul li { line-height: 1.2em; }
+#g-tag-cloud ul li span { display: none; }
+#g-add-tag-form { display: none; }
+
+/* modules.css - Comments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-comments { margin-top: 2em; padding-top: 0.4em; float: left; width: 100%; }
+#g-comments ul li { margin: 0.4em 0; }
+#g-comments .g-author { height: 32px; line-height: 32px; }
+#g-comments .g-avatar { height: 32px; margin-right: .4em; width: 32px; }
+
+#g-admin-comment-button { width: 27px; right: 0.2em; text-indent: -900em; }
+#g-comments-link { background-position: top left; background-repeat: no-repeat; }
+#g-comments-link:hover { background-position: left bottom; }
+#g-comment-detail ul { margin-top: 2em; padding: 0; }
+#g-comment-detail>ul>li { margin: 4px 0; padding: 6px; min-height: 40px; }
+#g-comment-detail div { margin-top: 6px; padding-bottom: 8px; }
+
+#g-comment-form fieldset { border: none; }
+#g-comment-form legend { display: none; width: 100%; }
+#g-comment-form ul { padding: 0; }
+#g-comment-form>fieldset>ul { margin: 0px 10px; }
+#g-comment-form label { display: block; }
+#g-comment-form textarea { width: 99%; height: 140px; }
+#g-comment-form input[type="text"],
+#g-comment-form input[type="password"] { width: 99%; }
+
+/* modules.css - Gallery Stats ~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-gallerystats ul { padding: 0; font-size: x-small; }
+
+/* modules.css - Info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-metadata ul { padding: 0; }
+#g-metadata .g-description { margin-top: 0.4em; padding: 0.4em 0; }
+
+/* modules.css - Calendar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-calendarview-link:hover { background-position: left bottom; }
+
+#g-view-calendar-form fieldset { border: none; }
+#g-view-calendar-form ul { padding: 8px; }
+#g-view-calendar-form li { padding-top: 8px; display: inline; padding-left: 10px; }
+#g-view-calendar-form label { margin: 4px 0; }
+#g-view-calendar-form select { margin: 4px 10px; }
+
+table.calendar { border-spacing: 1px; }
+table.calendar td.title a { font-weight: bold; }
+
+/* modules.css - ClustrMaps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-clustrmaps .g-block-content { text-align: center; }
+
+/* modules.css - GPS Info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-exif-gps-maps ul { padding-left: 0; }
+
+/* modules.css - Search ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-quick-search-form { position: absolute; top: 3em; right: 1em; background: none transparent; }
+#g-quick-search-form label { display: none; }
+#g-quick-search-form li { display: inline; float: left; padding: 0px; }
+
+#g-quick-search-form input[type="text"] { width: 150px; }
+#g-quick-search-form input[type="submit"] { display: block; width: 23px; height: 23px; text-indent: -9999px; overflow: hidden; }
+
+/* modules.css - Basket ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.basketbuttons span.ui-icon { display: none; }
+#payment { height: 100%; margin-left: 10px; }
+#payment p { padding: 4px; }
+#basketForm { width: 100%; float:right; }
+#checkout { }
+#checkout fieldset { border: none; }
+#checkout legend { width: 100%; padding: 4px 4px 4px 8px; font-size: 1em; font-weight: bold; }
+#checkout ul { padding: 8px; }
+#checkout li { padding-top: 8px; display: inline; }
+#checkout label { margin: 4px 0; }
+#checkout select { margin: 4px 10px; }
+
+#checkout textarea { display: block; clear: both; padding: .2em; width: 90%; }
+
+/* modules.css - Register ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-welcome-message p { padding-bottom: 6px; }
+#g-change-password-user-form { height: 100%; }
+
+/* modules.css - Localization ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#l10n-client .labels { border-top: white 1px solid; height: 1.7em; }
+#l10n-client h2 { padding-top: 0.4em; padding-bottom: 0.3em; }
+#l10n-client .label.translation { margin-top: -0.4em; height: 1.7em; }
+#l10n-client #l10n-client-toggler { line-height: 1.7em; height: 1.7em; }
+#l10n-client .string-list li { font-size: 0.8em; line-height: 1.1em; }
+#l10n-client #l10n-client-string-select { width: 24%; }
+#l10n-client #l10n-client-string-select .string-list { border: 1px #ccc solid; }
+#l10n-client #g-l10n-search-form ul { padding: 0; }
+#l10n-client #l10n-client-string-editor { margin-left: 1em; }
+#l10n-client-string-editor .source .source-text { margin: 0 0.4em 0 0; border: 1px #ccc solid; padding: 0.4em; line-height: 1em; }
+#l10n-client-string-editor .translation { height: 19em; }
+#l10n-client #l10n-edit-translation { width: 97%; height: 17em; border: 1px #ccc solid; font-family: monospace; padding: 0.4em; }
diff --git a/themes/greydragon/css/old_ie.css b/themes/greydragon/css/old_ie.css
index 70556d49..9a5da7b8 100644
--- a/themes/greydragon/css/old_ie.css
+++ b/themes/greydragon/css/old_ie.css
@@ -1,4 +1,16 @@
-body { word-wrap: break-word; }
-
-.g-item .g-metadata:hover { padding: 0px 0 4px 6px; }
-#g-quick-search-form input[type="submit"] { padding: 60px 0 0 0; }
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * CSS rules - IE 6 hacks
+ */
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* old_ie.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+body { word-wrap: break-word; font-size: 100.1%; }
+
+.g-item .g-metadata:hover { padding: 0px 0 4px 6px; }
+#g-quick-search-form input[type="submit"] { padding: 60px 0 0 0; }
+#g-column-centerleft { margin: 0 19em 0 0; }
+#g-column-centerright { margin: 0 0 0 19em; }
diff --git a/themes/greydragon/css/screen.css b/themes/greydragon/css/screen.css
index 974521a1..17ecf082 100644
--- a/themes/greydragon/css/screen.css
+++ b/themes/greydragon/css/screen.css
@@ -1,211 +1,224 @@
-/**
- * Gallery 3 Grey Dragon Theme
- * Copyright (C) 2006-2009 Serguei Dosyukov
- *
- * 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.
- */
-
-@import url(layout.css);
-@import url(forms.css);
-
-html { background-color: #1A2022; overflow: -moz-scrollbars-vertical; overflow-y: scroll; }
-body { background: url(../images/background.gif) #1A2022 repeat-x; color: #BBB; font: 0.8em Arial, verdana, sans-serif; }
-
-a { color: #6392CF !important; text-decoration: none; outline: none; -moz-outline-style: none; }
-a:focus, a:active, a:hover { text-decoration: none; outline: none; }
-img { border: none; }
-p { font-size: small; text-indent: 0; }
-ul { list-style: none none; }
-input[type="submit"] { cursor: pointer; /* hand-shaped cursor */ cursor: hand; /* for IE 5.x */ }
-
-h1 { font-weight: bold; font-size: 1.2em; }
-h2 { font-weight: bold; font-size: 1.2em; }
-h3 { font-weight: bold; }
-h4 { font-weight: bold; }
-h5 { font-weight: bold; }
-
-/* Common elements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-.txtright { text-align: right; }
-.g-metadata { overflow: hidden; }
-
-.ui-icon { display: inline-block; zoom: 1; width: 16px; height: 16px; background-image: url(../images/ui-icons.png); }
-.ui-icon-first { background-position: -32px -162px; }
-.ui-icon-first-d { background-position: -162px -162px; }
-.ui-icon-prev { background-position: -48px -162px; }
-.ui-icon-prev-d { background-position: -178px -162px; }
-.ui-icon-next { background-position: -64px -162px; }
-.ui-icon-next-d { background-position: -194px -162px; }
-.ui-icon-last { background-position: -80px -162px; }
-.ui-icon-last-d { background-position: -210px -162px; }
-.ui-icon-signal-diag { background-position: -16px -178px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-comment { background-position: -227px -219px; width: 27px; height: 20px; }
-.ui-icon-left .ui-icon { float: left; margin-right: .2em; }
-.ui-icon-right .ui-icon { float: right; margin-left: .2em; }
-
-.g-resize { border: 1px solid #888; padding: 5px; background: #555; }
-
-/* Header section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-#g-header { height: 90px; padding: 0; font-size: 80%; }
-#g-logo { position: absolute; top: 8px; left: 16px; }
-
-#g-login-menu { position: absolute; bottom: 10px; right: 14px; background-color: transparent; }
-#g-login-menu li { display: inline; padding-left: 1.2em; }
-
-.g-breadcrumbs { position: absolute; bottom: 4px; right: 14px; background-color: transparent; }
-.g-breadcrumbs li { display: inline; padding-left: 1em; background: transparent url('../images/ico-separator.png') no-repeat 0 2px; }
-.g-breadcrumbs li.g-first { background-image: none; }
-
-/* Main section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-#g-main { display: block; margin: 0; }
-#g-main-in { display: block; position: relative; }
-
-#g-column-center, #g-column-centerleft { padding: 6px 6px 6px 16px; }
-#g-column-centerfull { padding: 6px 12px 6px 10px; }
-#g-column-centerright { padding: 6px 12px 6px 6px; }
-#g-column-left { padding: 6px 4px 6px 10px; }
-#g-column-right { padding: 6px 10px 6px 4px; }
-
-/* Pagination ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-.g-paginator { display: inline-block; width: 100%; padding: 4px 0 0 0; font-size: 80%; zoom: 1; }
-.g-paginator li { display: inline; float: left; margin-left: 0; zoom: 1; }
-.g-paginator a { padding: 0 0 0 2px; }
-
-.g-paginator .g-pagination { width: 80%; padding-top: 2px; }
-.g-paginator .g-navigation { text-align: right; width: 20%; }
-
-/* Album grid ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-.g-thumbcrop { overflow: hidden; position: relative; width: 200px; height: 150px; }
-#g-album-grid { padding: 6px 0 0 0; width: 100%; }
-#g-album-grid .g-item { position: relative; float: left; padding: 10px 9px 0px 9px; width: 30.5%; height: 190px; background: url('../images/image_thumb.gif') no-repeat; }
-#g-album-grid .g-item p { text-align: center; }
-#g-album-grid h2 { position: absolute; top: 164px; left: 12px; width: 150px; font: 100%/100% Arial, Helvetica, sans-serif; }
-#g-album-grid h2 a { display: block; margin-top: 4px; font: bold 70% Arial, Helvetica, Verdana, Sans-Serif; letter-spacing: 0.1em; text-transform: uppercase; min-height: 2em; }
-#g-album-grid .g-album h2 { padding-left: 20px; background: url('../images/ico-album.png') no-repeat 0px 2px; }
-
-.g-item .g-metadata { display: block; position: absolute; margin: 0; padding: 0; top: 172px; left: 198px; width: 14px; height: 14px; background: url(../images/ui-icons.png) -162px -144px; }
-.g-item .g-metadata li { padding: 0; margin: 0; text-indent: -9999px; font: bold 70% Arial, Helvetica, Verdana, Sans-Serif; letter-spacing: 0.1em; }
-.g-item .g-metadata:hover { padding: 4px 0 0 6px; top: 148px; left: 6px; width: 198px; height: 32px; background: #181818 none; border: 1px #888 solid; z-index: 100; }
-.g-item .g-metadata:hover li { text-indent: 0px; }
-
-.g-item .g-context-menu { position: absolute; margin: 0; padding: 0; top: 6px; left: 198px; width: 14px; height: 14px; background: url(../images/ui-icons.png) -178px -144px; }
-.g-item .g-context-menu li { width: 100%; padding: 0; margin: 0; text-indent: -9999px; font: bold 70% Arial, Helvetica, Verdana, Sans-Serif; letter-spacing: 0.1em; }
-.g-item .g-context-menu:hover { top: 4px; left: 6px; width: 204px; height: auto; background: #181818 none; border: 1px #888 solid; z-index: 100; }
-.g-item .g-context-menu ul { display: block; padding: 0; margin: 0; }
-.g-item .g-context-menu li li { display: none; font-size: 100%; width: 100%; }
-.g-item .g-context-menu li li a { display: block; padding: 4px 6px; }
-.g-item .g-context-menu:hover li li { display: block; text-indent: 0px; }
-.g-item .g-context-menu li li a:hover { background-color: #303030; }
-
-.ul-table { text-align: center; margin: 0px auto; padding: 0; list-style-type: none; clear: both; }
-.ul-table li { float: left; text-align: center; }
-
-#g-info { }
-#g-info h1 { padding-bottom: 1px; border-bottom: 1px solid #888; }
-#g-info .g-description { display: none; }
-/* #g-info h1:hover .g-description { position: relative; z-index: 10; top: 10px; left: 0px; width: 90%; display: block; afloat: left; border: 1px solid #888; padding: 6px; }*/
-#g-photo { padding: 6px 0 6px 6px; text-align: center; }
-#g-albumheader h1 { padding-bottom: 1px; margin-bottom: 6px; border-bottom: 1px solid #888; }
-
-/* Footer section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-#g-footer { padding: 6px 6px 6px 14px; background: url('../images/footer.png') #1A2022 repeat-x top !important; zoom: 1; font-size: 80%; }
-#g-footer ul { float: left; color: #999; padding: 0; text-align: left; }
-#g-footer li { padding: 0 0 2px 0; }
-
-#g-visitors { float: left; display: inline; margin: 3px 4px 3px 12px; }
-#g-copyright { font-size: x-small; color: #808080; }
-
-#g-footer-rightside { padding-right: 6px; text-align: right; }
-
-/* Design blocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-#g-quick-search-form { position: absolute; top: 10px; right: 14px; background: none transparent; }
-#g-quick-search-form label { display: none; }
-#g-quick-search-form li { display: inline; float: left; padding: 0px; }
-
-#g-quick-search-form input[type="text"] { background-color: transparent; border: 1px solid #737373; color: #BBB; width: 150px; /* margin-left: 2px; */ }
-#g-quick-search-form input[type="submit"] { display: block; width: 23px; height: 23px; text-indent: -9999px; background: transparent url(../images/search.png) no-repeat center top; border: none; overflow: hidden; }
-
-#g-search-results h1 { border-bottom: #888 1px solid; }
-
-/* Sidebar Blocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-/* Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-.g-block { margin-bottom: 0.5em; padding-bottom: 4px; border: 1px solid #737373; background-color: #101415; position: relative; }
-.g-block h2 { padding: 4px; font-size: 1.2em; background: url('../images/section.png') repeat-x; }
-.g-block-content { margin: 4px 10px 0 10px; display: block; zoom: 1; }
-
-/* Image Block ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-#g-image-block>div { margin-left: 1px; margin-right: 1px; }
-.g-image-block { text-align: center; }
-.g-image-block img { border: 1px solid #888; background: #555; padding: 5px; }
-
-/* Feeds Block ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-ul#g-feeds { padding: 0; margin: 0; }
-
-/* Tags and cloud ~~~~~~~~~~~~~~~~~~~~~~~~ */
-#g-tag-cloud ul { padding: 0; font-size: 100%; }
-#g-tag-cloud ul li { line-height: 1.2em; }
-#g-tag-cloud ul li span { display: none; }
-#g-add-tag-form { display: none; }
-
-/* Comments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-#g-admin-comment-button { width: 27px; right: 10px; text-indent: -900em; }
-.g-avatar { float: right; }
-#g-comments-link { background: url('../images/view-comments.png') top left no-repeat; }
-#g-comments .g-block-content { margin: 0; }
-#g-comment-detail ul { padding: 0px; }
-#g-comment-detail > ul > li { margin: 4px; padding: 6px; min-height: 40px; border: 1px dotted #737373; }
-#g-comment-detail div { margin-right: 48px; margin-top: 8px; }
-
-/* Buttons ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-#g-viewformat { z-index: 5; position: absolute; padding: 0; top: 6px; right: 10px; }
-#g-viewformat li { float: left; margin-right: 2px; }
-#g-viewformat .g-viewthumb-left { background: url('../images/view-left.png') no-repeat left top; }
-#g-viewformat .g-viewthumb-right { background: url('../images/view-right.png') no-repeat left top; }
-#g-viewformat .g-viewthumb-full { background: url('../images/view-full.png') no-repeat left top; }
-#g-viewformat span { line-height: 1px; text-indent: -900em; width: 17px; display: block; height: 15px; }
-#g-viewformat span:hover,
-#g-viewformat span.g-viewthumb-current { background-position: left bottom; }
-
-#g-view-menu { position: absolute; top: 6px; right: 70px; height: 16px; z-index: 5; zoom: 1; margin: 0 0 6px 0; padding: 0 0 4px 0; }
-.g-toolbar { height: 16px; zoom: 1; margin: 0 0 4px 0; padding: 0 0 3px 0; border-bottom: 1px solid #737373; }
-.g-menu { margin: 0; padding: 0; text-align: left; }
-.g-menu li { display: inline; }
-
-.g-menu-element,
-.g-menu-link { display: inline; float: left; margin-right: 4px; }
-
-.g-buttonset ul { height: 16px; }
-.g-buttonset .g-menu-link { text-indent: -99999px; width: 22px; height: 15px; }
-
-#g-slideshow-link { background: url("../images/view-slideshow.png") top left no-repeat; }
-.g-fullsize-link { background: url("../images/view-fullsize.png") top left no-repeat; }
-#g-exifdata-link { background: url("../images/view-info.png") top left no-repeat; }
-
-#g-slideshow-link:hover, .g-fullsize-link:hover, #g-exifdata-link:hover, #g-comments-link:hover { background-position: left bottom; }
-
-/* ShadowBox Skin ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-#sb-body { background: #101415 url('../images/ajax-loading.gif') no-repeat center center; }
-#sb-title-inner { display: none; }
-#sb-nav #sb-nav-close { background-image: url('../images/close.png'); width: 60px; }
-
-.clear { clear: both; margin-top: -1px; height: 1px; overflow: hidden; }
-
-.g-message-block { position: absolute; z-index: 10; min-width: 30em; padding: 4px 6px; right: 10px; top: 34px; border: 1px #888 solid; background-color: #AAA; overflow: hidden; color: #000; font: bold 9pt Arial, verdana, sans-serif; text-align: center; }
+/**
+ * Gallery 3 Grey Dragon Theme
+ * Copyright (C) 2006-2010 Serguei Dosyukov
+ *
+ * CSS rules - Kitchen sync
+ *
+ * Color rules for font/background/lines can be found in dedicated colorpack files
+ */
+
+@import url(layout.css);
+@import url(menus.css);
+@import url(forms.css);
+@import url(modules.css);
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* screen.css - Common ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+body { font-family: Arial, verdana, sans-serif; font-size: 0.9em; }
+
+a { text-decoration: none; outline: none; -moz-outline-style: none; }
+a:focus, a:active, a:hover { text-decoration: none; outline: none; }
+img { border: none; }
+p { text-indent: 0; }
+ul { list-style: none none; }
+
+h1 { font-weight: bold; font-size: 1.1em; padding-bottom: 1px; }
+h2 { font-weight: bold; font-size: 1.1em; }
+h3 { font-weight: bold; }
+h4 { font-weight: bold; }
+h5 { font-weight: bold; }
+
+.txtright { text-align: right; }
+.g-metadata { overflow: hidden; }
+.g-avatar { float: right; }
+
+.ui-icon { display: inline-block; zoom: 1; width: 16px; height: 15px; }
+.ui-icon-first { background-position: -162px -178px; }
+.ui-icon-first-d { background-position: -162px -162px; }
+.ui-icon-prev { background-position: -178px -178px; }
+.ui-icon-prev-d { background-position: -178px -162px; }
+.ui-icon-parent { background-position: -226px -178px; }
+.ui-icon-parent-d { background-position: -226px -162px; }
+.ui-icon-next { background-position: -194px -178px; }
+.ui-icon-next-d { background-position: -194px -162px; }
+.ui-icon-last { background-position: -210px -178px; }
+.ui-icon-last-d { background-position: -210px -162px; }
+.ui-icon-signal-diag { background-position: -16px -178px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-plus { background-position: -14px -129px; }
+.ui-icon-minus { background-position: -46px -129px; }
+.ui-icon-note { background-position: -66px -98px; }
+
+.ui-icon-comment { background-position: -227px -219px; width: 27px; height: 20px; }
+.ui-icon-left .ui-icon { float: left; margin-right: .2em; }
+.ui-icon-right .ui-icon { float: right; margin-left: .2em; }
+
+/* screen.css - Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-header { height: 90px; padding: 0; font-size: 0.9em; }
+
+#g-logo { position: absolute; top: 8px; left: 16px; }
+
+.g-breadcrumbs { position: absolute; bottom: 4px; background-color: transparent; }
+.g-breadcrumbs.default { right: 14px; }
+.g-breadcrumbs.left { left: 304px; padding-left: 0; }
+.g-breadcrumbs li { display: inline; padding-left: 1em; padding-right: 0.4em; }
+.g-breadcrumbs li.g-first { background-image: none; }
+.g-breadcrumbs li.g-active { padding-right: 0; }
+
+#g-header .g-message-block { position: absolute; z-index: 10; min-width: 30em; padding: 4px 6px; right: 20em; top: 34px; overflow: hidden; font: bold 9pt Arial, verdana, sans-serif; text-align: center; }
+
+#g-header #g-login-menu { position: absolute; top: 0.5em; right: 1em; background-color: transparent; display: none; }
+
+/* screen.css - Main ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-main { display: block; margin: 0; }
+#g-main-in { display: block; position: relative; }
+
+#g-column-center, #g-column-centerleft { padding: 6px 6px 6px 16px; }
+#g-column-centerfull { padding: 6px 12px 6px 10px; }
+#g-column-centerright { padding: 6px 12px 6px 6px; }
+#g-column-left { padding: 6px 4px 6px 10px; }
+#g-column-right { padding: 6px 10px 6px 4px; }
+
+/* screen.css - Footer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-footer { padding: 6px 6px 6px 14px; zoom: 1; font-size: 0.9em; }
+#g-footer ul { float: left; padding: 0; text-align: left; }
+#g-footer li { padding: 0 0 2px 0; }
+
+#g-footer #g-login-menu { position: absolute; bottom: 0.5em; right: 1em; background-color: transparent; display: none; }
+
+#g-login-menu li { display: inline; padding-left: 1.2em; }
+#g-logout-link { float: none; margin-right: 0; }
+
+#g-copyright { font-size: x-small; }
+#g-footer #g-footer-rightside { float: right; padding-right: 6px; text-align: right; }
+#g-credits { margin-right: 14px; }
+
+/* screen.css - Pagination ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-paginator { display: inline-block; width: 100%; padding: 4px 0 0 0; zoom: 1; }
+.g-paginator li { display: inline; float: left; margin-left: 0; zoom: 1; }
+.g-paginator a { padding: 0 0 0 2px; }
+
+.g-paginator .g-pagination { width: 80%; font-size: 0.8em; }
+.g-paginator .g-navigation { text-align: right; width: 20%; }
+
+/* screen.css - Album grid ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-album-grid { padding: 6px 0 0 0; width: 100%; display: inline-block; }
+#g-album-grid .g-item { position: relative; float: left; margin: 4px 0; min-width: 212px; width: 33%; zoom: 1; } /* amargin-right: 10px; */
+#g-album-grid .g-extra-column { width: 23%; }
+#g-album-grid .g-item p { text-align: center; }
+#g-album-grid h2 { position: absolute; top: 164px; left: 12px; width: 150px; font: 100%/100% Arial, Helvetica, sans-serif; }
+#g-album-grid h2 a { display: block; margin-top: 4px; font: bold 0.8em Arial, Helvetica, Verdana, Sans-Serif; letter-spacing: 0.1em; text-transform: uppercase; min-height: 2em; }
+
+/* screen.css - Thumbs : Common ~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-thumbcrop { overflow: hidden; position: relative; width: 200px; min-height: 133px; }
+
+.g-thumbtype-flm .g-thumbcrop { height: 150px; }
+.g-thumbtype-dgt .g-thumbcrop { height: 133px; }
+.g-thumbtype-sqr .g-thumbcrop { height: 200px; }
+.g-album .g-description strong { padding-left: 16px; }
+
+/* screen.css - Thumbs : Overlay ~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-thumbslide { font-size: 0.9em; width: 208px; min-height: 139px; padding-top: 6px; padding-left: 6px; }
+.g-thumbslide.g-thumbtype-flm { height: 158px; }
+.g-thumbslide.g-thumbtype-dgt { height: 141px; }
+.g-thumbslide.g-thumbtype-sqr { height: 208px; }
+
+.g-thumbcrop a.g-thumlink { display: block; position: relative; }
+.g-thumbslide .g-thumbcrop .g-description { display: none; }
+.g-thumbslide:hover .g-description { display: block; position: absolute; top: 0; min-height: 32px; width: 100%; overflow: hidden; z-index: 3; font-weight: bold; font-size: 0.9em; letter-spacing: 0.1em; text-transform: uppercase; text-align: left; }
+.g-thumbslide:hover .g-description strong { display: block; margin-left: 10px; padding-top: 2px; }
+.g-album .g-thumbslide:hover .g-description strong { padding-left: 16px; }
+.g-thumbslide .g-description strong { display: block; margin-left: 10px; padding-top: 2px; }
+
+.g-thumbslide .g-metadata { display: none; }
+.g-thumbslide:hover .g-metadata { display: block; position: absolute; bottom: 7px; margin: 0 0 1px 1px; padding: 2px 4px 2px 6px; width: 190px; }
+.g-thumbslide:hover .g-metadata li { padding: 0; margin: 0; font-size: 0.9em; }
+.g-album .g-thumbslide:hover .g-metadata { bottom: 10px; }
+
+/* screen.css - Thumbs : Extended View mode ~~~~~~~~~~~~*/
+
+.g-thumbslide-ext { font-size: 0.9em; width: 208px; min-height: 139px; padding-top: 6px; padding-left: 6px; }
+.g-thumbslide-ext.g-thumbtype-flm { height: 188px; }
+.g-thumbslide-ext.g-thumbtype-dgt { height: 171px; }
+.g-thumbslide-ext.g-thumbtype-sqr { height: 238px; }
+
+.g-thumbslide-ext .g-description { display: block; margin-top: 2px; width: 200px; overflow: hidden; font-weight: bold; font-size: 0.9em; letter-spacing: 0.1em; text-transform: uppercase; text-align: left; }
+.g-thumbslide-ext .g-description strong { display: block; }
+.g-album .g-thumbslide-ext .g-description strong { padding-left: 24px; }
+
+.g-thumbslide-ext .g-metadata { display: none; }
+.g-thumbslide-ext:hover .g-metadata { display: block; position: absolute; bottom: 37px; margin: 0 0 1px 1px; padding: 2px 4px 2px 6px; width: 190px; }
+.g-thumbslide-ext:hover .g-metadata li { padding: 0; margin: 0; font-size: 0.9em; }
+.g-album .g-thumbslide-ext:hover .g-metadata { bottom: 40px; }
+
+/* screen.css - Photo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-item { float: left; height: 100%; width: 100%; }
+#g-photo { padding: 6px 0 6px 6px; text-align: center; float: left; height: 100%; width: 100%; }
+div.g-resize { position: relative; left: 50%; float: left; padding: 5px; font-size: 0.9em; }
+div.g-resize>a { float: left; overflow: hidden; }
+div.g-resize>a img { float: left; }
+div.g-resize .g-description { display: none; }
+div.g-resize:hover .g-description { position: absolute; display: block; top: 0px; margin-top: 5px; text-align: left; padding: 10px; }
+div.g-resize:hover .g-description strong { display: block; margin-bottom: 5px; text-transform: uppercase; }
+
+div.g-resize .g-more { display: block; position: absolute; right: 16px; top: 16px; padding: 4px 8px; }
+div.g-resize:hover .g-more { display: none; visibility: hidden; }
+
+.ul-table { text-align: center; margin: 0px auto; padding: 0; list-style-type: none; clear: both; }
+.ul-table li { float: left; text-align: center; }
+
+#g-info { display: inline-block; width: 100%; }
+#g-info .g-description { margin-top: 4px; margin-bottom: 4px; padding: 4px; }
+#g-movie { padding: 6px 0 6px 6px; position: relative; }
+
+.g-movie { margin: 0 auto; }
+
+#g-albumheader h1 { margin-bottom: 6px; }
+
+.g-description .g-metadata { padding: 0.4em 0 0 0; font-size: 0.8em; }
+.g-description .g-metadata li { display: inline; padding-right: 1em; }
+
+/* screen.css - Sidebar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/* screen.css - Sidebar : Common ~~~~~~~~~~~~~~~~~~~~~~~*/
+
+.g-block { margin-bottom: 4px; padding-bottom: 4px; position: relative; }
+.g-block h2 { padding: 4px 4px 4px 8px; font-size: 1em; }
+.g-block-content { margin: 4px 6px 0 6px; display: block; zoom: 1; }
+
+/* screen.css - Sidebar : Buttons ~~~~~~~~~~~~~~~~~~~~~~*/
+
+#g-viewformat { z-index: 5; position: absolute; padding: 0; top: 6px; right: 10px; }
+#g-viewformat li { float: left; margin-right: 2px; }
+#g-viewformat span { line-height: 1px; text-indent: -900em; width: 17px; display: block; height: 15px; }
+#g-viewformat span:hover,
+#g-viewformat span.g-viewthumb-current { background-position: left bottom; }
+
+#g-view-menu { position: absolute; top: 6px; right: 70px; height: 16px; z-index: 5; zoom: 1; margin: 0 0 6px 0; padding: 0 0 4px 0; }
+#g-view-menu.g-buttonset-shift { right: 6px; }
+.g-toolbar { height: 1.1em; zoom: 1; margin: 0 0 4px 0; padding: 1px 0 3px 0; }
+.g-menu { margin: 0; padding: 0; text-align: left; }
+.g-menu li { display: inline; }
+
+.g-menu-element,
+.g-menu-link { display: inline; float: left; margin-right: 4px; }
+
+.g-buttonset .g-menu-link { text-indent: -99999px; width: 22px; height: 15px; }
+
+#g-slideshow-link:hover, .g-fullsize-link:hover, #g-exifdata-link:hover { background-position: left bottom; }
+
+/* screen.css - Reauthentificate ~~~~~~~~~~~~~~~~~~~~~~ */
+
+#g-reauthenticate-form fieldset { border: none; width: 260px; }
+#g-reauthenticate-form ul { padding: 8px; }
+#g-reauthenticate-form li { padding-top: 8px; }
+#g-reauthenticate-form label { display: block; }
+#g-reauthenticate-form input[type="password"] { width: 98%; }
diff --git a/themes/greydragon/helpers/exif_event.php b/themes/greydragon/helpers/exif_event.php
index f61bcb7c..27b617a6 100644
--- a/themes/greydragon/helpers/exif_event.php
+++ b/themes/greydragon/helpers/exif_event.php
@@ -1,7 +1,7 @@
get("add_menu");
+ if (!empty($submenu)) {
+ $item = $submenu->get("add_photos_item");
+ if (!empty($item)) { $item->css_class("ui-icon-plus"); }
+
+ $item = $submenu->get("add_album_item");
+ if (!empty($item)) { $item->css_class("ui-icon-note"); }
+ }
+
+ $submenu = $menu->get("options_menu");
+ if (!empty($submenu)) {
+ $item = $submenu->get("edit_item");
+ if (!empty($item)) { $item->css_class("ui-icon-pencil"); }
+
+ $item = $submenu->get("edit_permissions");
+ if (!empty($item)) { $item->css_class("ui-icon-key"); }
+ }
+ }
+}
diff --git a/themes/greydragon/helpers/greydragon_installer.php b/themes/greydragon/helpers/greydragon_installer.php
new file mode 100644
index 00000000..461e6914
--- /dev/null
+++ b/themes/greydragon/helpers/greydragon_installer.php
@@ -0,0 +1,30 @@
+
\ No newline at end of file
diff --git a/themes/greydragon/helpers/greydragon_theme.php b/themes/greydragon/helpers/greydragon_theme.php
new file mode 100644
index 00000000..988da98c
--- /dev/null
+++ b/themes/greydragon/helpers/greydragon_theme.php
@@ -0,0 +1,30 @@
+'
+ . $theme_info->name . ' ' . $theme_info->version . ' ';
+ }
+}
+
diff --git a/themes/greydragon/images/blue-grad.png b/themes/greydragon/images/blue-grad.png
new file mode 100644
index 00000000..36e0f6bc
Binary files /dev/null and b/themes/greydragon/images/blue-grad.png differ
diff --git a/themes/greydragon/images/button-grad-active-vs.png b/themes/greydragon/images/button-grad-active-vs.png
new file mode 100644
index 00000000..dc641725
Binary files /dev/null and b/themes/greydragon/images/button-grad-active-vs.png differ
diff --git a/themes/greydragon/images/button-grad-vs.png b/themes/greydragon/images/button-grad-vs.png
new file mode 100644
index 00000000..51c55a3d
Binary files /dev/null and b/themes/greydragon/images/button-grad-vs.png differ
diff --git a/themes/greydragon/images/donate.png b/themes/greydragon/images/donate.png
new file mode 100644
index 00000000..f36bb57a
Binary files /dev/null and b/themes/greydragon/images/donate.png differ
diff --git a/themes/greydragon/images/header.png b/themes/greydragon/images/header.png
deleted file mode 100644
index b60c4a66..00000000
Binary files a/themes/greydragon/images/header.png and /dev/null differ
diff --git a/themes/greydragon/images/ico-album.png b/themes/greydragon/images/ico-album.png
deleted file mode 100644
index 01463be4..00000000
Binary files a/themes/greydragon/images/ico-album.png and /dev/null differ
diff --git a/themes/greydragon/images/image_thumb.gif b/themes/greydragon/images/image_thumb.gif
deleted file mode 100644
index 35b05e63..00000000
Binary files a/themes/greydragon/images/image_thumb.gif and /dev/null differ
diff --git a/themes/greydragon/images/missing-img.png b/themes/greydragon/images/missing-img.png
new file mode 100644
index 00000000..12b7394f
Binary files /dev/null and b/themes/greydragon/images/missing-img.png differ
diff --git a/themes/greydragon/images/section.png b/themes/greydragon/images/section.png
deleted file mode 100644
index bba5da2c..00000000
Binary files a/themes/greydragon/images/section.png and /dev/null differ
diff --git a/themes/greydragon/images/ui-icons.png b/themes/greydragon/images/ui-icons.png
deleted file mode 100644
index 199b7fda..00000000
Binary files a/themes/greydragon/images/ui-icons.png and /dev/null differ
diff --git a/themes/greydragon/images/view-full.png b/themes/greydragon/images/view-full.png
deleted file mode 100644
index e7290319..00000000
Binary files a/themes/greydragon/images/view-full.png and /dev/null differ
diff --git a/themes/greydragon/images/view-fullsize.png b/themes/greydragon/images/view-fullsize.png
deleted file mode 100644
index 5bff90dd..00000000
Binary files a/themes/greydragon/images/view-fullsize.png and /dev/null differ
diff --git a/themes/greydragon/images/view-info.png b/themes/greydragon/images/view-info.png
deleted file mode 100644
index edf12b51..00000000
Binary files a/themes/greydragon/images/view-info.png and /dev/null differ
diff --git a/themes/greydragon/images/view-left.png b/themes/greydragon/images/view-left.png
deleted file mode 100644
index 63e2793e..00000000
Binary files a/themes/greydragon/images/view-left.png and /dev/null differ
diff --git a/themes/greydragon/images/view-right.png b/themes/greydragon/images/view-right.png
deleted file mode 100644
index d1878dd6..00000000
Binary files a/themes/greydragon/images/view-right.png and /dev/null differ
diff --git a/themes/greydragon/images/view-slideshow.png b/themes/greydragon/images/view-slideshow.png
deleted file mode 100644
index 8e15cd30..00000000
Binary files a/themes/greydragon/images/view-slideshow.png and /dev/null differ
diff --git a/themes/greydragon/js/dialog.js b/themes/greydragon/js/dialog.js
deleted file mode 100644
index 1d11a569..00000000
--- a/themes/greydragon/js/dialog.js
+++ /dev/null
@@ -1,17 +0,0 @@
-function setupLoginForm() {
- setupAjaxForm('#gLoginForm');
-}
-
-function setupAjaxForm($form_id) {
- var options = {
- dataType: "json",
- success: function(data) {
- if (data.result == "success") {
- if (data.location) { window.location = data.location; }
- else { window.parent.Shadowbox.close(); }
- }
- }
- };
-
- $($form_id).ajaxForm(options);
-};
diff --git a/themes/greydragon/js/menus.js b/themes/greydragon/js/menus.js
deleted file mode 100644
index f4f1431a..00000000
--- a/themes/greydragon/js/menus.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Javascript originally by Patrick Griffiths and Dan Webb.
-// http://htmldog.com/articles/suckerfish/dropdowns/
-
-sfHover = function() {
- var sfEls = document.getElementById("gSiteMenu").getElementsByTagName("ul")[0].getElementsByTagName("li");
- if (!sfEls) { return; }
-
- for (var i=0; iul>li>ul").show();
+ $("#g-login-menu").show();
+ $(".g-context-menu").show();
+ },
+
+// gallery_dialog_postprocess: function(href, title) {
+// Shadowbox.open({player: 'ajax', content: href, width: 500, height: 420, enableKeys: false, animate: false, title: title, onFinish: myAjaxSubmit});
+// }
+});
+
+/*
+(function($) {
+
+ $.widget("ui.gallery_dialog", {
+ _init: function() {
+ var self = this;
+ if (!self.options.immediate) {
+ this.element.click(function(event) {
+ event.preventDefault();
+ var href = $(event.currentTarget).attr("href");
+ var title = $(event.currentTarget).attr("title");
+ setTimeout(function() { $().gallery_dialog_postprocess(href, title); }, 1000);
+ return false;
+ });
+ } else {
+ var href = this.element.attr("href");
+ var title = this.element.attr("title");
+ setTimeout(function() { $().gallery_dialog_postprocess(href, title); }, 1000);
+ }
+ }
+ });
+})(jQuery);
+*/
+
+$(document).ready(function() {
+ $().theme_ready();
+});
diff --git a/themes/greydragon/libraries/MY_Theme_View.php b/themes/greydragon/libraries/MY_Theme_View.php
new file mode 100644
index 00000000..4f579ec2
--- /dev/null
+++ b/themes/greydragon/libraries/MY_Theme_View.php
@@ -0,0 +1,313 @@
+
+class Theme_View extends Theme_View_Core {
+
+ protected $photonav_position;
+ protected $sidebarvisible;
+ protected $sidebarallowed;
+ protected $logopath;
+ protected $thumb_descmode = "overlay";
+ protected $photo_descmode = "overlay";
+ protected $is_thumbmeta_visible = TRUE;
+ protected $is_blockheader_visible = TRUE;
+ protected $is_photometa_visible = FALSE;
+ protected $disable_seosupport = FALSE;
+ protected $mainmenu_position = "";
+ protected $show_breadcrumbs = TRUE;
+ protected $copyright = null;
+ protected $show_guest_menu = FALSE;
+ protected $loginmenu_position = "footer";
+ protected $desc_allowbbcode = FALSE;
+ protected $enable_pagecache = FALSE;
+ protected $color_pack = "greydragon";
+
+ protected $crop_factor = -1;
+ protected $crop_class = "";
+ protected $_thumb_size_x = 200;
+ protected $_thumb_size_y = 200;
+
+ protected function ensurevalue($value, $default) {
+ if ((!isset($value)) or ($value == "")):
+ return $default;
+ else:
+ return $value;
+ endif;
+ }
+
+ protected function ensureoptionsvalue($key, $default) {
+ return ($this->ensurevalue(module::get_var("th_greydragon", $key), $default));
+ }
+
+ public function load_sessioninfo() {
+ $this->sidebarvisible = $_REQUEST['sb'];
+
+ if (empty($this->sidebarvisible)):
+ $session = Session::instance();
+ $_sidebar_mode = $session->get("gd_sidebar");
+ if ($_sidebar_mode):
+ $this->sidebarvisible = $_sidebar_mode;
+ else:
+ $this->sidebarvisible = $this->ensureoptionsvalue("sidebar_visible", "right");
+ endif;
+ else:
+ // Sidebar position is kept for 360 days
+ Session::instance()->set("gd_sidebar", $this->sidebarvisible, time() + 31536000);
+ endif;
+
+ $this->sidebarallowed = $this->ensureoptionsvalue("sidebar_allowed", "any");
+ $this->sidebarvisible = $this->ensurevalue($this->sidebarvisible, "right");
+
+ if ($this->sidebarallowed == "none") { $this->sidebarvisible = $this->ensureoptionsvalue("sidebar_visible", "right"); };
+ if ($this->sidebarallowed == "right") { $this->sidebarvisible = "right"; }
+ if ($this->sidebarallowed == "left") { $this->sidebarvisible = "left"; }
+
+ if ($this->item()):
+ if ($this->ensureoptionsvalue("sidebar_albumonly", FALSE)):
+ if (!$this->item()->is_album()):
+ $this->sidebarallowed = "none";
+ $this->sidebarvisible = "none";
+ endif;
+ endif;
+ endif;
+
+ $this->logopath = $this->ensureoptionsvalue("logo_path", url::file("lib/images/logo.png"));
+ $this->show_guest_menu = $this->ensureoptionsvalue("show_guest_menu", FALSE);
+ $this->horizontal_crop = $this->ensureoptionsvalue("horizontal_crop", FALSE);
+ $this->thumb_descmode = $this->ensureoptionsvalue("thumb_descmode", "overlay");
+ $this->photo_descmode = $this->ensureoptionsvalue("photo_descmode", "overlay");
+ $this->is_thumbmeta_visible = ((!$this->ensureoptionsvalue("hide_thumbmeta", FALSE)) and module::is_active("info"));
+ $this->is_photometa_visible = ((!$this->ensureoptionsvalue("hide_photometa", TRUE)) and module::is_active("info"));
+ $this->disable_seosupport = $this->ensureoptionsvalue("disable_seosupport", FALSE);
+ $this->is_blockheader_visible = (!$this->ensureoptionsvalue("hide_blockheader", FALSE));
+ $this->mainmenu_position = $this->ensureoptionsvalue("mainmenu_position", "default");
+ $this->show_breadcrumbs = (!$this->ensureoptionsvalue("hide_breadcrumbs", FALSE));
+ $this->loginmenu_position = ($this->ensureoptionsvalue("loginmenu_position", "default"));
+ $this->copyright = ($this->ensureoptionsvalue("copyright", null));
+ $this->photonav_position = module::get_var("th_greydragon", "photonav_position", "top");
+ $this->desc_allowbbcode = $this->ensureoptionsvalue("desc_allowbbcode", FALSE);
+ $this->enable_pagecache = $this->ensureoptionsvalue("enable_pagecache", FALSE);
+ $this->color_pack = $this->ensureoptionsvalue("color_pack", "greydragon");
+
+ $cssfile = gallery::find_file("css/colorpacks/" . $this->color_pack, "colors.css", false);
+
+ if (!$cssfile):
+ $this->color_pack = 'greydragon';
+ endif;
+
+ switch (module::get_var("th_greydragon", "thumb_ratio")):
+ case "digital":
+ $this->crop_factor = 4/3;
+ $this->crop_class = 'g-thumbtype-dgt';
+ break;
+ case "square":
+ $this->crop_factor = 1;
+ $this->crop_class = 'g-thumbtype-sqr';
+ break;
+ case "film":
+ $this->crop_factor = 3/2;
+ $this->crop_class = 'g-thumbtype-flm';
+ break;
+ case "photo":
+ default:
+ $this->crop_factor = 1;
+ $this->crop_class = 'g-thumbtype-sqr';
+ break;
+ endswitch;
+
+ $this->_thumb_size_y = floor($this->_thumb_size_x / $this->crop_factor);
+ }
+
+ public function is_sidebarallowed($align) {
+ return (($this->sidebarallowed == "any") or ($this->sidebarallowed == $align));
+ }
+
+ public function breadcrumb_menu($theme, $parents) {
+ $content = "";
+
+ if ($theme->item() && !empty($parents)):
+ $content .= '';
+ $i = 0;
+ foreach ($parents as $parent):
+ $content .= '';
+ $content .= 'item()->id}" : null) . '">';
+ $content .= $theme->bb2html(html::purify($parent->title), 2);
+ $content .= ' ';
+ $i++;
+ endforeach;
+ $content .= '' . $theme->bb2html(html::purify($theme->item()->title), 2) . ' ';
+ $content .= ' ';
+ endif;
+
+ return $content;
+ }
+
+ protected function sidebar_menu_item($type, $url, $caption, $css) {
+ if (!$this->is_sidebarallowed($type)):
+ return "";
+ endif;
+
+ $iscurrent = ($this->sidebarvisible == $type);
+ $content_menu = '';
+ if (!$iscurrent):
+ $content_menu .= '';
+ endif;
+ $content_menu .= '';
+ if (!$iscurrent):
+ $content_menu .= ' ';
+ endif;
+
+ return $content_menu . ' ';
+ }
+
+ public function sidebar_menu($url) {
+ if ($this->sidebarallowed != "any"):
+ return "";
+ endif;
+
+ $content_menu = ($this->sidebar_menu_item("left", $url, "Sidebar Left", "left"));
+ $content_menu .= ($this->sidebar_menu_item("none", $url, "No Sidebar", "full"));
+ $content_menu .= ($this->sidebar_menu_item("right", $url, "Sidebar Right", "right"));
+ return '';
+ }
+
+ public function add_paginator($position) {
+ if (($this->photonav_position == "both") or ($this->photonav_position == $position)):
+ return ($this->paginator());
+ else:
+ return "";
+ endif;
+ }
+
+ public function get_thumb_element($item, $addcontext) {
+ $item_class = $item->is_album() ? "g-album" : "g-photo";
+
+ if (($this->sidebarallowed == "none") and ($this->sidebarvisible == "none")):
+ $item_class .= " g-extra-column";
+ endif;
+
+ $content = '';
+ $content .= $this->thumb_top($item);
+
+ if (($this->crop_factor == 1) and ($item->thumb_width > $item->thumb_height)):
+ $_shift = 'style="margin-top: ' . floor(($this->_thumb_size_y - $item->thumb_height) / 2) . 'px;"';
+ else:
+ if (($this->crop_factor > 0) and ($item->thumb_width < $item->thumb_height)):
+ $_shift = 'style="margin-top: -' . floor(($item->thumb_height - $this->_thumb_size_y) / 2) . 'px;"';
+ else:
+ $_shift = "";
+ endif;
+ endif;
+
+ $content .= 'crop_class . '">
';
+ if ($this->thumb_descmode == "overlay"):
+ $content .= '';
+ $content .= '' . $this->bb2html(html::purify($item->title), 2) . ' '; // html::purify(text::limit_chars($item->title, 44, "…"))
+ $content .= ' ';
+ endif;
+ $content .= '';
+ if (($item->thumb_height == 0) or ($item->thumb_width == 0)):
+ $content .= ' ';
+ else:
+ $content .= $item->thumb_img();
+ endif;
+ $content .= '
';
+
+ if ($this->thumb_descmode == "bottom"):
+ $content .= '
';
+ $content .= '' . $this->bb2html(html::purify($item->title), 2) . ' ';
+ $content .= ' ';
+ endif;
+
+ if (($this->is_thumbmeta_visible) and (module::is_active("info"))):
+ $content .= '
';
+ endif;
+
+ if ($addcontext):
+ $_text = $this->context_menu($item, "#g-item-id-{$item->id} .g-thumbnail");
+ $content .= (stripos($_text, '
'))? $_text : null;
+ endif;
+
+ $content .= ' ';
+ $content .= $this->thumb_bottom($item);
+ $content .= ' ';
+
+ return $content;
+ }
+
+ // $mode: bit 1 - use mix mode ($mode in [1, 3]), bit 2 - strips bbcode ($mode in [2, 3])
+ public function bb2html($text, $mode) {
+ // Syntax Sample:
+ // --------------
+ // [img]http://elouai.com/images/star.gif[/img]
+ // [url="http://elouai.com"]eLouai[/url]
+ // [size="25"]HUGE[/size]
+ // [color="red"]RED[/color]
+ // [b]bold[/b]
+ // [i]italic[/i]
+ // [u]underline[/u]
+ // [list][*]item[*]item[*]item[/list]
+ // [code]value="123";[/code]
+ // [quote]John said yadda yadda yadda[/quote]
+
+ static $bbcode_mappings = array(
+ "#\\[b\\](.*?)\\[/b\\]#" => "$1 ",
+ "#\\[i\\](.*?)\\[/i\\]#" => "$1 ",
+ "#\\[u\\](.*?)\\[/u\\]#" => "$1 ",
+ "#\\[s\\](.*?)\\[/s\\]#" => "$1 ",
+ "#\\[o\\](.*?)\\[/o\\]#" => "$1 ",
+ "#\\[url\\](.*?)\[/url\\]#" => "$1 ",
+ "#\\[url=(.*?)\\](.*?)\[/url\\]#" => "$2 ",
+ "#\\[mail=(.*?)\\](.*?)\[/mail\\]#" => "$2 ",
+ "#\\[img\\](.*?)\\[/img\\]#" => " ",
+ "#\\[img=(.*?)\\](.*?)\[/img\\]#" => " ",
+ "#\\[quote\\](.*?)\\[/quote\\]#" => "$1
",
+ "#\\[code\\](.*?)\\[/code\\]#" => "$1 ",
+ "#\\[size=([^\\[]*)\\]([^\\[]*)\\[/size\\]#" => "$2 ",
+ "#\\[color=([^\\[]*)\\]([^\\[]*)\\[/color\\]#" => "$2 ",
+ "#\\[class=([^\\[]*)\\]([^\\[]*)\\[/class\\]#" => "$2 ",
+ "#\\[center\\](.*?)\\[/center\\]#" => "$1
",
+ "#\\[list\\](.*?)\\[/list\\]#" => "",
+ "#\\[ul\\](.*?)\\[/ul\\]#" => "",
+ "#\\[li\\](.*?)\\[/li\\]#" => "$1 ",
+ );
+
+ static $bbcode_strip = '|[[\/\!]*?[^\[\]]*?]|si';
+
+ // Replace any html brackets with HTML Entities to prevent executing HTML or script
+ // Don't use strip_tags here because it breaks [url] search by replacing & with amp
+ if (($mode == 1) or ($mode == 3)):
+ $newtext = str_replace("<", "<", $text);
+ $newtext = str_replace(">", ">", $newtext);
+ $newtext = str_replace(""", "\"", $newtext);
+ else:
+ $newtext = str_replace("<", "<", $text);
+ $newtext = str_replace(">", ">", $newtext);
+ $newtext = str_replace(""", """, $newtext);
+ endif;
+
+ // Convert new line chars to html tags
+ $newtext = nl2br($newtext);
+
+ if (strpos($text, "[") !== false):
+ if (($mode == 2) or ($mode == 3)):
+ $newtext = preg_replace($bbcode_strip, '', $newtext);
+ else:
+ $newtext = preg_replace(array_keys($bbcode_mappings), array_values($bbcode_mappings), $newtext);
+ endif;
+ endif;
+
+ return stripslashes($newtext); //stops slashing, useful when pulling from db
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/themes/greydragon/theme.info b/themes/greydragon/theme.info
index 2deac9b4..cea1d8d0 100644
--- a/themes/greydragon/theme.info
+++ b/themes/greydragon/theme.info
@@ -1,6 +1,6 @@
name = "Grey Dragon Theme"
-description = "A Crisp theme uses on clear grey colors and minimized on JS overhead"
-version = 1.5.8
-author = "2009 Serguei Dosyukov"
+description = "A Crisp flexible theme with support of Color Packs and minimized on JS overhead"
+version = 2.3.1
+author = "2010 Serguei Dosyukov"
site = 1
admin = 0
diff --git a/themes/greydragon/thumbnail.png b/themes/greydragon/thumbnail.png
index 89cd6bda..4b80ecaf 100644
Binary files a/themes/greydragon/thumbnail.png and b/themes/greydragon/thumbnail.png differ
diff --git a/themes/greydragon/views/album.html.php b/themes/greydragon/views/album.html.php
index 8164bace..49fa5cf4 100644
--- a/themes/greydragon/views/album.html.php
+++ b/themes/greydragon/views/album.html.php
@@ -1,51 +1,55 @@
-
-
-
- = $theme->album_top() ?>
-
= html::purify($item->title) ?>
-
= ($item->description)? bb2html(html::purify($item->description), 1) : null; ?>
-
-
- if (module::get_var("th_greydragon", "photonav_top")): ?>
-= $theme->paginator() ?>
- endif ?>
-
-
-= $theme->album_bottom() ?>
-
- if (module::get_var("th_greydragon", "photonav_bottom")): ?>
-= $theme->paginator() ?>
- endif ?>
+
+
+
+= $theme->add_paginator("top"); ?>
+
+ if (($theme->photo_descmode == "top") and ($item->description)): ?>
+ = $theme->bb2html(html::purify($item->description), 1) ?>
+ endif; ?>
+
+
+ if (count($children)): ?>
+ foreach ($children as $i => $child): ?>
+ = $theme->get_thumb_element($child, TRUE) ?>
+ endforeach ?>
+ else: ?>
+ if ($user->admin || access::can("add", $item)): ?>
+ $addurl = url::site("uploader/index/$item->id") ?>
+ = t("There aren't any photos here yet! Add some .",
+ array("attrs" => html::mark_clean("href=\"$addurl\" class=\"g-dialog-link\""))) ?>
+ else: ?>
+ = t("There aren't any photos here yet!") ?>
+ endif; ?>
+ endif; ?>
+
+= $theme->album_bottom() ?>
+
+ if (($theme->photo_descmode == "bottom") and ($item->description)): ?>
+ = $theme->bb2html(html::purify($item->description), 1) ?>
+ endif; ?>
+
+= $theme->add_paginator("bottom"); ?>
diff --git a/themes/greydragon/views/block.html.php b/themes/greydragon/views/block.html.php
index 699d7c22..af29546f 100644
--- a/themes/greydragon/views/block.html.php
+++ b/themes/greydragon/views/block.html.php
@@ -1,10 +1,33 @@
-
- if ($anchor): ?>
-
- endif ?>
-
-
= $title ?>
-
- = $content ?>
-
-
+
+ if ($anchor): ?>
+
+ endif ?>
+
+ if ($theme->is_blockheader_visible): ?>
+
= $title ?>
+ endif ?>
+
+ = $content ?>
+
+
diff --git a/themes/greydragon/views/dynamic.html.php b/themes/greydragon/views/dynamic.html.php
index e136fd53..1f787cf3 100644
--- a/themes/greydragon/views/dynamic.html.php
+++ b/themes/greydragon/views/dynamic.html.php
@@ -1,35 +1,39 @@
-
-
-
- if (module::get_var("th_greydragon", "photonav_top")): ?>
-= $theme->paginator() ?>
- endif ?>
-
-
- foreach ($children as $i => $child): ?>
- ">
- = $theme->thumb_top($child) ?>
-
-
-
-
- = $theme->thumb_bottom($child) ?>
-
-
- endforeach ?>
-
-= $theme->dynamic_bottom() ?>
-
- if (module::get_var("th_greydragon", "photonav_bottom")): ?>
-= $theme->paginator() ?>
- endif ?>
\ No newline at end of file
+
+
+
+= $theme->add_paginator("top"); ?>
+
+
+ foreach ($children as $i => $child): ?>
+ = $theme->get_thumb_element($child) ?>
+ endforeach ?>
+
+= $theme->dynamic_bottom() ?>
+
+= $theme->add_paginator("bottom"); ?>
diff --git a/themes/greydragon/views/info_block.html.php b/themes/greydragon/views/info_block.html.php
index 69f6a1e9..d3860584 100644
--- a/themes/greydragon/views/info_block.html.php
+++ b/themes/greydragon/views/info_block.html.php
@@ -1,9 +1,24 @@
-
-
-
- if ($item->description): ?>
- = bb2html(html::purify($item->description), 1) ?>
- else: ?>
-
- endif ?>
-
+
+
+ if ($item->owner): ?>
+
+ = t("Owner:") ?>
+ if ($item->owner->url): ?>
+ = html::clean($item->owner->display_name()) ?>
+ else: ?>
+ = html::clean($item->owner->display_name()) ?>
+ endif ?>
+
+ endif ?>
+ if ($item->captured): ?>
+
+ = t("Captured:") ?>
+ = date("M j, Y H:i:s", $item->captured)?>
+
+ endif ?>
+ if ($item->description): ?>
+
+ = $theme->bb2html(html::purify($item->description), 1) ?>
+
+ endif ?>
+
diff --git a/themes/greydragon/views/movie.html.php b/themes/greydragon/views/movie.html.php
index e69de29b..ec870608 100644
--- a/themes/greydragon/views/movie.html.php
+++ b/themes/greydragon/views/movie.html.php
@@ -0,0 +1,43 @@
+
+
+ = $theme->photo_top() ?>
+
+
+
= $theme->bb2html(html::purify($item->title), 1) ?>
+
= $theme->bb2html(html::purify($item->description), 1) ?>
+
+
+ = $theme->add_paginator("top"); ?>
+
+
+ = $theme->resize_top($item) ?>
+ = $item->movie_img(array("class" => "g-movie", "id" => "g-movie-id-{$item->id}")); ?>
+ // = $theme->context_menu($item, "#g-movie-id-{$item->id}") ?>
+ = $theme->resize_bottom($item) ?>
+
+
+ = $theme->add_paginator("bottom"); ?>
+
+ = $theme->photo_bottom() ?>
+
diff --git a/themes/greydragon/views/no_sidebar.html.php b/themes/greydragon/views/no_sidebar.html.php
index 2239cf91..dd61bb77 100644
--- a/themes/greydragon/views/no_sidebar.html.php
+++ b/themes/greydragon/views/no_sidebar.html.php
@@ -1,3 +1,24 @@
-
-
-
+
+ //
?>
+
diff --git a/themes/greydragon/views/page.html.php b/themes/greydragon/views/page.html.php
index 90a9f09c..13664d65 100644
--- a/themes/greydragon/views/page.html.php
+++ b/themes/greydragon/views/page.html.php
@@ -1,76 +1,66 @@
- include('support/bbtohtml.php'); ?>
-
-
-
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ $theme->load_sessioninfo(); ?>
+
+
- if (empty($_REQUEST['sb'])) {
- if (isset($_COOKIE['gd_sidebar'])) {
- $sidebarvisible = $_COOKIE['gd_sidebar'];
- } else {
- $sidebarvisible = module::get_var("th_greydragon", "sidebar_visible", "");
- }
- } else {
- // Sidebar position is kept for 360 days
- $sidebarvisible = $_REQUEST['sb'];
- setcookie("gd_sidebar", $sidebarvisible, time() + 31536000);
- }
-
- $sidebarallowed = module::get_var("th_greydragon", "sidebar_allowed", "");
-
- if ($sidebarallowed == "") { $sidebarallowed = "any"; };
- if ($sidebarvisible == "") { $sidebarvisible = "right"; };
- if ($sidebarallowed == "none") { $sidebarvisible = "none"; }
- if ($sidebarallowed == "right") { $sidebarvisible = "right"; }
- if ($sidebarallowed == "left") { $sidebarvisible = "left"; }
+ if (($theme->enable_pagecache) and ($theme->item())):
+ // Page will expire in 60 seconds
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60).'GMT');
+ header("Cache-Control: public");
+ header("Cache-Control: post-check=3600, pre-check=43200", false);
+ header("Content-Type: text/html; charset=UTF-8");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ endif;
?>
-
-
- if ($page_title): ?>
+= " "; ?>
+ if ($page_title): ?>
= $page_title ?>
else: ?>
if ($theme->item()): ?>
if ($theme->item()->is_album()): ?>
-= t("Browse Album :: %album_title", array("album_title" => $theme->item()->title)) ?>
+= t("Browse Album :: %album_title", array("album_title" => $theme->bb2html($theme->item()->title, 2))) ?>
elseif ($theme->item()->is_photo()): ?>
-= t("Photo :: %photo_title", array("photo_title" => $theme->item()->title)) ?>
+= t("Photo :: %photo_title", array("photo_title" => $theme->bb2html($theme->item()->title, 2))) ?>
else: ?>
-= t("Movie :: %movie_title", array("movie_title" => $theme->item()->title)) ?>
+= t("Movie :: %movie_title", array("movie_title" => $theme->bb2html($theme->item()->title, 2))) ?>
endif ?>
elseif ($theme->tag()): ?>
-= t("Browse Tag :: %tag_title", array("tag_title" => $theme->tag()->name)) ?>
+= t("Browse Tag :: %tag_title", array("tag_title" => $theme->bb2html($theme->tag()->name, 2))) ?>
else: /* Not an item, not a tag, no page_title specified. Help! */ ?>
= t("Gallery") ?>
endif ?>
endif ?>
-
-
-
-
-
- " type="image/x-icon" />
-
- = $theme->script("jquery.js") ?>
- = $theme->script("jquery.form.js") ?>
- = $theme->script("jquery-ui.js") ?>
-
+ if (!$theme->disable_seosupport): ?>
+ = ' ' . "\n"; ?>
+ = ' ' . "\n"; ?>
+ = ' ' . "\n"; ?>
+ = ' ' . "\n"; ?>
+ = ' ' . "\n"; ?>
+ endif; ?>
+ " type="image/x-icon" />
+= $theme->script("jquery.js") ?>
+= $theme->script("jquery.form.js") ?>
+= $theme->script("jquery-ui.js") ?>
+ if ($theme->page_subtype == "movie"): ?>
+= $theme->script("flowplayer.js") ?>
+ endif ?>
+= $theme->script("gallery.ajax.js") ?>
= $theme->head() ?>
+ " type="text/css" media="screen,print,projection" />
+ color_pack . "/colors.css") ?>" type="text/css" media="screen,print,projection" />
- " type="text/css" media="screen,print,projection" />
- " type="text/css" media="screen,print,projection" />
+
+
-
-
-
-
+
= $theme->page_top() ?>
@@ -80,56 +70,30 @@
= $header_text ?>
else: ?>
for_html_attr() ?>">
- $logo_path = module::get_var("th_greydragon", "logo_path", url::file("lib/images/logo.png")); ?>
- // $theme->url("images/logo.png") ?>
- for_html_attr() ?>" src="= $logo_path ?>" />
+ for_html_attr() ?>" src="= $theme->logopath ?>" />
endif ?>
- if (!$user->guest): ?>
-
- if ($sidebarallowed == "any"): ?>
-
- endif ?>
-
-