From dbeadc1407293d0c7af36723db6fe5699890b845 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Wed, 22 Jul 2009 14:27:57 -0700 Subject: Use the Kohana cascading filesystem to locate resources loaded by the theme. Because the theme comes first, this means that themes can override any module resources, at the cost that we no longer have namespacing for JS and CSS files. The only file getting used outside of this model is themes/default/screen.css which is used in the admin theme. I fixed that by copying screen.css into admin_default and renaming its screen.css to admin_screen.css. I also copied over all the images that it was referencing. Fixes tickets #48 and #539. Theme API changes: - theme_script(), theme_url() and theme_css() are no longer needed - script(), url() and css() now refer to the first matching asset in the module load path, where gallery3/lib is at the end of the path --- modules/organize/helpers/organize_theme.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'modules/organize/helpers') diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index 02f1f589..e4feba2b 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -20,8 +20,8 @@ class organize_theme { static function head($theme) { // @tdo remove the addition css and organize.js (just here to test) - $theme->script("modules/organize/js/organize_init.js"); - $theme->script("modules/organize/js/organize.js"); - $theme->css("modules/organize/css/organize.css"); + $theme->script("organize_init.js"); + $theme->script("organize.js"); + $theme->css("organize.css"); } } -- cgit v1.2.3 From 1e90e40d3a9fe2cb826b56686f23a33879418048 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 28 Jul 2009 13:47:22 -0700 Subject: Use events to generate menus, instead of having xxx_menu helpers. This is the first step towards having a simple, lightweight and unified API for module interaction. --- modules/akismet/helpers/akismet_event.php | 16 ++ modules/akismet/helpers/akismet_menu.php | 36 ----- modules/comment/helpers/comment_event.php | 17 +++ modules/comment/helpers/comment_menu.php | 37 ----- modules/digibug/helpers/digibug_event.php | 50 +++++++ modules/digibug/helpers/digibug_menu.php | 50 ------- modules/g2_import/helpers/g2_import_event.php | 9 ++ modules/g2_import/helpers/g2_import_menu.php | 29 ---- modules/gallery/helpers/gallery_menu.php | 164 --------------------- modules/gallery/libraries/Admin_View.php | 70 +++++++-- modules/gallery/libraries/Theme_View.php | 105 +++++++++---- .../notification/helpers/notification_event.php | 19 +++ modules/notification/helpers/notification_menu.php | 39 ----- modules/organize/helpers/organize_event.php | 33 +++++ modules/organize/helpers/organize_menu.php | 33 ----- modules/recaptcha/helpers/recaptcha_event.php | 8 + modules/recaptcha/helpers/recaptcha_menu.php | 28 ---- modules/server_add/helpers/server_add_event.php | 64 ++++++++ modules/server_add/helpers/server_add_menu.php | 64 -------- modules/slideshow/helpers/slideshow_event.php | 30 ++++ modules/slideshow/helpers/slideshow_menu.php | 51 ------- modules/tag/helpers/tag_event.php | 8 + modules/tag/helpers/tag_menu.php | 28 ---- modules/user/helpers/user_event.php | 8 + modules/user/helpers/user_menu.php | 28 ---- modules/watermark/helpers/watermark_event.php | 29 ++++ modules/watermark/helpers/watermark_menu.php | 29 ---- 27 files changed, 426 insertions(+), 656 deletions(-) delete mode 100644 modules/akismet/helpers/akismet_menu.php delete mode 100644 modules/comment/helpers/comment_menu.php create mode 100644 modules/digibug/helpers/digibug_event.php delete mode 100644 modules/digibug/helpers/digibug_menu.php delete mode 100644 modules/g2_import/helpers/g2_import_menu.php delete mode 100644 modules/gallery/helpers/gallery_menu.php delete mode 100644 modules/notification/helpers/notification_menu.php create mode 100644 modules/organize/helpers/organize_event.php delete mode 100644 modules/organize/helpers/organize_menu.php delete mode 100644 modules/recaptcha/helpers/recaptcha_menu.php create mode 100644 modules/server_add/helpers/server_add_event.php delete mode 100644 modules/server_add/helpers/server_add_menu.php delete mode 100644 modules/slideshow/helpers/slideshow_menu.php delete mode 100644 modules/tag/helpers/tag_menu.php delete mode 100644 modules/user/helpers/user_menu.php create mode 100644 modules/watermark/helpers/watermark_event.php delete mode 100644 modules/watermark/helpers/watermark_menu.php (limited to 'modules/organize/helpers') diff --git a/modules/akismet/helpers/akismet_event.php b/modules/akismet/helpers/akismet_event.php index bffc0fd7..d6cde222 100644 --- a/modules/akismet/helpers/akismet_event.php +++ b/modules/akismet/helpers/akismet_event.php @@ -51,4 +51,20 @@ class akismet_event_Core { akismet::submit_ham($new); } } + + static function admin_menu($menu, $theme) { + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("akismet") + ->label(t("Akismet")) + ->url(url::site("admin/akismet"))); + + if (module::get_var("akismet", "api_key")) { + $menu->get("statistics_menu") + ->append(Menu::factory("link") + ->id("akismet") + ->label(t("Akismet")) + ->url(url::site("admin/akismet/stats"))); + } + } } diff --git a/modules/akismet/helpers/akismet_menu.php b/modules/akismet/helpers/akismet_menu.php deleted file mode 100644 index ebd948d6..00000000 --- a/modules/akismet/helpers/akismet_menu.php +++ /dev/null @@ -1,36 +0,0 @@ -get("settings_menu") - ->append(Menu::factory("link") - ->id("akismet") - ->label(t("Akismet")) - ->url(url::site("admin/akismet"))); - - if (module::get_var("akismet", "api_key")) { - $menu->get("statistics_menu") - ->append(Menu::factory("link") - ->id("akismet") - ->label(t("Akismet")) - ->url(url::site("admin/akismet/stats"))); - } - } -} diff --git a/modules/comment/helpers/comment_event.php b/modules/comment/helpers/comment_event.php index 3850a001..614c7c65 100644 --- a/modules/comment/helpers/comment_event.php +++ b/modules/comment/helpers/comment_event.php @@ -21,4 +21,21 @@ class comment_event_Core { static function item_deleted($item) { Database::instance()->delete("comments", array("item_id" => $item->id)); } + + static function admin_menu($menu, $theme) { + $menu->get("content_menu") + ->append(Menu::factory("link") + ->id("comments") + ->label(t("Comments")) + ->url(url::site("admin/comments"))); + } + + static function photo_menu($menu, $theme) { + $menu + ->append(Menu::factory("link") + ->id("comments") + ->label(t("View comments on this item")) + ->url("#comments") + ->css_id("gCommentsLink")); + } } diff --git a/modules/comment/helpers/comment_menu.php b/modules/comment/helpers/comment_menu.php deleted file mode 100644 index 01881921..00000000 --- a/modules/comment/helpers/comment_menu.php +++ /dev/null @@ -1,37 +0,0 @@ -get("content_menu") - ->append(Menu::factory("link") - ->id("comments") - ->label(t("Comments")) - ->url(url::site("admin/comments"))); - } - - static function photo($menu, $theme) { - $menu - ->append(Menu::factory("link") - ->id("comments") - ->label(t("View comments on this item")) - ->url("#comments") - ->css_id("gCommentsLink")); - } -} diff --git a/modules/digibug/helpers/digibug_event.php b/modules/digibug/helpers/digibug_event.php new file mode 100644 index 00000000..c4f9e560 --- /dev/null +++ b/modules/digibug/helpers/digibug_event.php @@ -0,0 +1,50 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("digibug_menu") + ->label(t("Digibug")) + ->url(url::site("admin/digibug"))); + } + + static function photo_menu($menu, $theme) { + $item = $theme->item(); + $menu->append( + Menu::factory("link") + ->id("digibug") + ->label(t("Print with Digibug")) + ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf")) + ->css_id("gDigibugLink")); + } + + static function thumb_menu($menu, $theme, $item) { + if ($item->type == "photo") { + $menu->get("options_menu") + ->append( + Menu::factory("link") + ->id("digibug") + ->label(t("Print with Digibug")) + ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf")) + ->css_id("gDigibugLink")); + } + } +} diff --git a/modules/digibug/helpers/digibug_menu.php b/modules/digibug/helpers/digibug_menu.php deleted file mode 100644 index 3f70fa24..00000000 --- a/modules/digibug/helpers/digibug_menu.php +++ /dev/null @@ -1,50 +0,0 @@ -get("settings_menu") - ->append(Menu::factory("link") - ->id("digibug_menu") - ->label(t("Digibug")) - ->url(url::site("admin/digibug"))); - } - - static function photo($menu, $theme) { - $item = $theme->item(); - $menu->append( - Menu::factory("link") - ->id("digibug") - ->label(t("Print with Digibug")) - ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf")) - ->css_id("gDigibugLink")); - } - - static function thumb($menu, $theme, $item) { - if ($item->type == "photo") { - $menu->get("options_menu") - ->append( - Menu::factory("link") - ->id("digibug") - ->label(t("Print with Digibug")) - ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf")) - ->css_id("gDigibugLink")); - } - } -} diff --git a/modules/g2_import/helpers/g2_import_event.php b/modules/g2_import/helpers/g2_import_event.php index 77b489a7..609e1a45 100644 --- a/modules/g2_import/helpers/g2_import_event.php +++ b/modules/g2_import/helpers/g2_import_event.php @@ -25,4 +25,13 @@ class g2_import_event_Core { static function item_created($item) { g2_import::copy_matching_thumbnails_and_resizes($item); } + + static function admin_menu($menu, $theme) { + $menu + ->get("settings_menu") + ->append(Menu::factory("link") + ->id("g2_import") + ->label(t("Gallery 2 Import")) + ->url(url::site("admin/g2_import"))); + } } diff --git a/modules/g2_import/helpers/g2_import_menu.php b/modules/g2_import/helpers/g2_import_menu.php deleted file mode 100644 index 68d75cb4..00000000 --- a/modules/g2_import/helpers/g2_import_menu.php +++ /dev/null @@ -1,29 +0,0 @@ -get("settings_menu") - ->append(Menu::factory("link") - ->id("g2_import") - ->label(t("Gallery 2 Import")) - ->url(url::site("admin/g2_import"))); - } -} diff --git a/modules/gallery/helpers/gallery_menu.php b/modules/gallery/helpers/gallery_menu.php deleted file mode 100644 index 040b19e1..00000000 --- a/modules/gallery/helpers/gallery_menu.php +++ /dev/null @@ -1,164 +0,0 @@ -append(Menu::factory("link") - ->id("home") - ->label(t("Home")) - ->url(url::site("albums/1"))); - - $item = $theme->item(); - - $can_edit = $item && access::can("edit", $item); - $can_add = $item && access::can("add", $item); - - if ($can_add) { - $menu->append(Menu::factory("dialog") - ->id("add_photos_item") - ->label(t("Add photos")) - ->url(url::site("simple_uploader/app/$item->id"))); - } - - $menu->append($options_menu = Menu::factory("submenu") - ->id("options_menu") - ->label(t("Options"))); - if ($item && ($can_edit || $can_add)) { - if ($can_edit) { - $options_menu - ->append(Menu::factory("dialog") - ->id("edit_item") - ->label($item->is_album() ? t("Edit album") : t("Edit photo")) - ->url(url::site("form/edit/{$item->type}s/$item->id"))); - } - - // @todo Move album options menu to the album quick edit pane - if ($item->is_album()) { - if ($can_add) { - $options_menu - ->append(Menu::factory("dialog") - ->id("add_album") - ->label(t("Add an album")) - ->url(url::site("form/add/albums/$item->id?type=album"))); - } - - if ($can_edit) { - $options_menu - ->append(Menu::factory("dialog") - ->id("edit_permissions") - ->label(t("Edit permissions")) - ->url(url::site("permissions/browse/$item->id"))); - } - } - } - - if (user::active()->admin) { - $menu->append($admin_menu = Menu::factory("submenu") - ->id("admin_menu") - ->label(t("Admin"))); - self::admin($admin_menu, $theme); - foreach (module::active() as $module) { - if ($module->name == "gallery") { - continue; - } - $class = "{$module->name}_menu"; - if (method_exists($class, "admin")) { - call_user_func_array(array($class, "admin"), array(&$admin_menu, $theme)); - } - } - } - } - - static function album($menu, $theme) { - } - - static function tag($menu, $theme) { - } - - static function thumb($menu, $theme, $item) { - $menu->append(Menu::factory("submenu") - ->id("options_menu") - ->label(t("Options")) - ->css_class("gThumbMenu")); - } - - static function photo($menu, $theme) { - if (access::can("view_full", $theme->item())) { - $menu->append(Menu::factory("link") - ->id("fullsize") - ->label(t("View full size")) - ->url($theme->item()->file_url()) - ->css_class("gFullSizeLink")); - } - } - - static function admin($menu, $theme) { - $menu - ->append(Menu::factory("link") - ->id("dashboard") - ->label(t("Dashboard")) - ->url(url::site("admin"))) - ->append(Menu::factory("submenu") - ->id("settings_menu") - ->label(t("Settings")) - ->append(Menu::factory("link") - ->id("graphics_toolkits") - ->label(t("Graphics")) - ->url(url::site("admin/graphics"))) - ->append(Menu::factory("link") - ->id("languages") - ->label(t("Languages")) - ->url(url::site("admin/languages"))) - ->append(Menu::factory("link") - ->id("l10n_mode") - ->label(Session::instance()->get("l10n_mode", false) - ? t("Stop translating") : t("Start translating")) - ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" . - access::csrf_token()))) - ->append(Menu::factory("link") - ->id("advanced") - ->label(t("Advanced")) - ->url(url::site("admin/advanced_settings")))) - ->append(Menu::factory("link") - ->id("modules") - ->label(t("Modules")) - ->url(url::site("admin/modules"))) - ->append(Menu::factory("submenu") - ->id("content_menu") - ->label(t("Content"))) - ->append(Menu::factory("submenu") - ->id("appearance_menu") - ->label(t("Appearance")) - ->append(Menu::factory("link") - ->id("themes") - ->label(t("Theme Choice")) - ->url(url::site("admin/themes"))) - ->append(Menu::factory("link") - ->id("theme_options") - ->label(t("Theme Options")) - ->url(url::site("admin/theme_options")))) - ->append(Menu::factory("submenu") - ->id("statistics_menu") - ->label(t("Statistics"))) - ->append(Menu::factory("link") - ->id("maintenance") - ->label(t("Maintenance")) - ->url(url::site("admin/maintenance"))); - } -} diff --git a/modules/gallery/libraries/Admin_View.php b/modules/gallery/libraries/Admin_View.php index 47770a90..2a48d1e3 100644 --- a/modules/gallery/libraries/Admin_View.php +++ b/modules/gallery/libraries/Admin_View.php @@ -44,22 +44,66 @@ class Admin_View_Core extends Gallery_View { $this->set_global("user", user::active()); } - public function admin_menu() { - $menu = Menu::factory("root"); - gallery_menu::admin($menu, $this); - - foreach (module::active() as $module) { - if ($module->name == "gallery") { - continue; - } - $class = "{$module->name}_menu"; - if (method_exists($class, "admin")) { - call_user_func_array(array($class, "admin"), array(&$menu, $this)); - } + public function admin_menu($menu=null) { + if (!$menu) { + $menu = Menu::factory("root"); } + $menu + ->append(Menu::factory("link") + ->id("dashboard") + ->label(t("Dashboard")) + ->url(url::site("admin"))) + ->append(Menu::factory("submenu") + ->id("settings_menu") + ->label(t("Settings")) + ->append(Menu::factory("link") + ->id("graphics_toolkits") + ->label(t("Graphics")) + ->url(url::site("admin/graphics"))) + ->append(Menu::factory("link") + ->id("languages") + ->label(t("Languages")) + ->url(url::site("admin/languages"))) + ->append(Menu::factory("link") + ->id("l10n_mode") + ->label(Session::instance()->get("l10n_mode", false) + ? t("Stop translating") : t("Start translating")) + ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" . + access::csrf_token()))) + ->append(Menu::factory("link") + ->id("advanced") + ->label(t("Advanced")) + ->url(url::site("admin/advanced_settings")))) + ->append(Menu::factory("link") + ->id("modules") + ->label(t("Modules")) + ->url(url::site("admin/modules"))) + ->append(Menu::factory("submenu") + ->id("content_menu") + ->label(t("Content"))) + ->append(Menu::factory("submenu") + ->id("appearance_menu") + ->label(t("Appearance")) + ->append(Menu::factory("link") + ->id("themes") + ->label(t("Theme Choice")) + ->url(url::site("admin/themes"))) + ->append(Menu::factory("link") + ->id("theme_options") + ->label(t("Theme Options")) + ->url(url::site("admin/theme_options")))) + ->append(Menu::factory("submenu") + ->id("statistics_menu") + ->label(t("Statistics"))) + ->append(Menu::factory("link") + ->id("maintenance") + ->label(t("Maintenance")) + ->url(url::site("admin/maintenance"))); + + module::event("admin_menu", $menu, $this); $menu->compact(); - print $menu; + return $menu; } /** diff --git a/modules/gallery/libraries/Theme_View.php b/modules/gallery/libraries/Theme_View.php index fa45ec89..60471f75 100644 --- a/modules/gallery/libraries/Theme_View.php +++ b/modules/gallery/libraries/Theme_View.php @@ -81,52 +81,103 @@ class Theme_View_Core extends Gallery_View { public function site_menu() { $menu = Menu::factory("root"); if ($this->page_type != "login") { - gallery_menu::site($menu, $this); + $menu->append(Menu::factory("link") + ->id("home") + ->label(t("Home")) + ->url(url::site("albums/1"))); - foreach (module::active() as $module) { - if ($module->name == "gallery") { - continue; + $item = $this->item(); + + $can_edit = $item && access::can("edit", $item); + $can_add = $item && access::can("add", $item); + + if ($can_add) { + $menu->append(Menu::factory("dialog") + ->id("add_photos_item") + ->label(t("Add photos")) + ->url(url::site("simple_uploader/app/$item->id"))); + } + + $menu->append($options_menu = Menu::factory("submenu") + ->id("options_menu") + ->label(t("Options"))); + if ($item && ($can_edit || $can_add)) { + if ($can_edit) { + $options_menu + ->append(Menu::factory("dialog") + ->id("edit_item") + ->label($item->is_album() ? t("Edit album") : t("Edit photo")) + ->url(url::site("form/edit/{$item->type}s/$item->id"))); } - $class = "{$module->name}_menu"; - if (method_exists($class, "site")) { - call_user_func_array(array($class, "site"), array(&$menu, $this)); + + // @todo Move album options menu to the album quick edit pane + if ($item->is_album()) { + if ($can_add) { + $options_menu + ->append(Menu::factory("dialog") + ->id("add_album") + ->label(t("Add an album")) + ->url(url::site("form/add/albums/$item->id?type=album"))); + } + + if ($can_edit) { + $options_menu + ->append(Menu::factory("dialog") + ->id("edit_permissions") + ->label(t("Edit permissions")) + ->url(url::site("permissions/browse/$item->id"))); + } } } + + if (user::active()->admin) { + $menu->append($admin_menu = Menu::factory("submenu") + ->id("admin_menu") + ->label(t("Admin"))); + Admin_View::admin_menu($admin_menu, $this); + module::event("admin_menu", $admin_menu, $this); + } + + module::event("site_menu", $menu, $this); } - $menu->compact(); - print $menu; + return $menu->compact(); } public function album_menu() { - print $this->_menu("album"); + $menu = Menu::factory("root"); + module::event("album_menu", $menu, $this); + return $menu->compact(); } public function tag_menu() { - print $this->_menu("tag"); + $menu = Menu::factory("root"); + module::event("tag_menu", $menu, $this); + return $menu->compact(); } public function photo_menu() { - print $this->_menu("photo"); - } + $menu = Menu::factory("root"); + if (access::can("view_full", $this->item())) { + $menu->append(Menu::factory("link") + ->id("fullsize") + ->label(t("View full size")) + ->url($this->item()->file_url()) + ->css_class("gFullSizeLink")); + } - public function thumb_menu($item) { - print $this->_menu("thumb", $item)->css_class("gThumbMenu"); + module::event("photo_menu", $menu, $this); + return $menu->compact(); } - private function _menu($type, $item=null) { - $menu = Menu::factory("root"); - call_user_func_array(array("gallery_menu", $type), array(&$menu, $this, $item)); - foreach (module::active() as $module) { - if ($module->name == "gallery") { - continue; - } - $class = "{$module->name}_menu"; - if (method_exists($class, $type)) { - call_user_func_array(array($class, $type), array(&$menu, $this, $item)); - } - } + public function thumb_menu($item) { + $menu = Menu::factory("root") + ->append(Menu::factory("submenu") + ->id("options_menu") + ->label(t("Options")) + ->css_class("gThumbMenu")); + module::event("thumb_menu", $menu, $this, $item); return $menu->compact(); } diff --git a/modules/notification/helpers/notification_event.php b/modules/notification/helpers/notification_event.php index 536557c6..c6e770a7 100644 --- a/modules/notification/helpers/notification_event.php +++ b/modules/notification/helpers/notification_event.php @@ -55,4 +55,23 @@ class notification_event_Core { static function batch_complete() { notification::send_pending_notifications(); } + + static function site_menu($menu, $theme) { + if (!user::active()->guest) { + $item = $theme->item(); + + if ($item && $item->is_album() && access::can("view", $item)) { + $watching = notification::is_watching($item); + + $label = $watching ? t("Remove notifications") : t("Enable notifications"); + + $menu->get("options_menu") + ->append(Menu::factory("link") + ->id("watch") + ->label($label) + ->css_id("gNotifyLink") + ->url(url::site("notification/watch/$item->id?csrf=" . access::csrf_token()))); + } + } + } } \ No newline at end of file diff --git a/modules/notification/helpers/notification_menu.php b/modules/notification/helpers/notification_menu.php deleted file mode 100644 index 73d1dd03..00000000 --- a/modules/notification/helpers/notification_menu.php +++ /dev/null @@ -1,39 +0,0 @@ -guest) { - $item = $theme->item(); - - if ($item && $item->is_album() && access::can("view", $item)) { - $watching = notification::is_watching($item); - - $label = $watching ? t("Remove notifications") : t("Enable notifications"); - - $menu->get("options_menu") - ->append(Menu::factory("link") - ->id("watch") - ->label($label) - ->css_id("gNotifyLink") - ->url(url::site("notification/watch/$item->id?csrf=" . access::csrf_token()))); - } - } - } -} diff --git a/modules/organize/helpers/organize_event.php b/modules/organize/helpers/organize_event.php new file mode 100644 index 00000000..99a28673 --- /dev/null +++ b/modules/organize/helpers/organize_event.php @@ -0,0 +1,33 @@ +item(); + + if ($item && access::can("edit", $item) && $item->is_album()) { + $menu->get("options_menu") + ->append(Menu::factory("link") + ->id("organize") + ->label(t("Organize Album")) + ->css_id("gOrganizeLink") + ->url(url::site("organize/index/{$item->id}"))); + } + } +} diff --git a/modules/organize/helpers/organize_menu.php b/modules/organize/helpers/organize_menu.php deleted file mode 100644 index 850c1eab..00000000 --- a/modules/organize/helpers/organize_menu.php +++ /dev/null @@ -1,33 +0,0 @@ -item(); - - if ($item && access::can("edit", $item) && $item->is_album()) { - $menu->get("options_menu") - ->append(Menu::factory("link") - ->id("organize") - ->label(t("Organize Album")) - ->css_id("gOrganizeLink") - ->url(url::site("organize/index/{$item->id}"))); - } - } -} diff --git a/modules/recaptcha/helpers/recaptcha_event.php b/modules/recaptcha/helpers/recaptcha_event.php index 932ddee6..d23a0c74 100644 --- a/modules/recaptcha/helpers/recaptcha_event.php +++ b/modules/recaptcha/helpers/recaptcha_event.php @@ -23,4 +23,12 @@ class recaptcha_event_Core { $form->add_comment->recaptcha("recaptcha")->label("")->id("gRecaptcha"); } } + + static function admin_menu($menu, $theme) { + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("recaptcha") + ->label(t("reCAPTCHA")) + ->url(url::site("admin/recaptcha"))); + } } diff --git a/modules/recaptcha/helpers/recaptcha_menu.php b/modules/recaptcha/helpers/recaptcha_menu.php deleted file mode 100644 index 047abf8f..00000000 --- a/modules/recaptcha/helpers/recaptcha_menu.php +++ /dev/null @@ -1,28 +0,0 @@ -get("settings_menu") - ->append(Menu::factory("link") - ->id("recaptcha") - ->label(t("reCAPTCHA")) - ->url(url::site("admin/recaptcha"))); - } -} diff --git a/modules/server_add/helpers/server_add_event.php b/modules/server_add/helpers/server_add_event.php new file mode 100644 index 00000000..b53e72d1 --- /dev/null +++ b/modules/server_add/helpers/server_add_event.php @@ -0,0 +1,64 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("server_add") + ->label(t("Server Add")) + ->url(url::site("admin/server_add"))); + } + + static function site_menu($menu, $theme) { + $item = $theme->item(); + $paths = unserialize(module::get_var("server_add", "authorized_paths")); + + if ($item && user::active()->admin && $item->is_album() && !empty($paths)) { + // This is a little tricky. Normally there's an "Add Photo" menu option, but we want to + // turn that into a dropdown if there are two different ways to add things. Do that in a + // portable way for now. If we find ourselves duplicating this pattern, we should make an + // API method for this. + $server_add = Menu::factory("dialog") + ->id("server_add") + ->label(t("Add from server")) + ->url(url::site("server_add/browse/$item->id")); + $add_photos_item = $menu->get("add_photos_item"); + $add_photos_menu = $menu->get("add_photos_menu"); + + if ($add_photos_item && !$add_photos_menu) { + // Assuming that $add_menu is unset, create add_menu and add our item + $menu->add_after( + "add_photos_item", + Menu::factory("submenu") + ->id("add_photos_menu") + ->label($add_photos_item->label) + ->append(Menu::factory("dialog") + ->id("add_photos_submenu_item") + ->label(t("Simple Uploader")) + ->url($add_photos_item->url)) + ->append($server_add)); + $menu->remove("add_photos_item"); + } else if ($add_photos_menu) { + // Append to the existing sub-menu + $add_photos_menu->append($server_add); + } + } + } +} diff --git a/modules/server_add/helpers/server_add_menu.php b/modules/server_add/helpers/server_add_menu.php deleted file mode 100644 index 0f01eb64..00000000 --- a/modules/server_add/helpers/server_add_menu.php +++ /dev/null @@ -1,64 +0,0 @@ -get("settings_menu") - ->append(Menu::factory("link") - ->id("server_add") - ->label(t("Server Add")) - ->url(url::site("admin/server_add"))); - } - - static function site($menu, $theme) { - $item = $theme->item(); - $paths = unserialize(module::get_var("server_add", "authorized_paths")); - - if ($item && user::active()->admin && $item->is_album() && !empty($paths)) { - // This is a little tricky. Normally there's an "Add Photo" menu option, but we want to - // turn that into a dropdown if there are two different ways to add things. Do that in a - // portable way for now. If we find ourselves duplicating this pattern, we should make an - // API method for this. - $server_add = Menu::factory("dialog") - ->id("server_add") - ->label(t("Add from server")) - ->url(url::site("server_add/browse/$item->id")); - $add_photos_item = $menu->get("add_photos_item"); - $add_photos_menu = $menu->get("add_photos_menu"); - - if ($add_photos_item && !$add_photos_menu) { - // Assuming that $add_menu is unset, create add_menu and add our item - $menu->add_after( - "add_photos_item", - Menu::factory("submenu") - ->id("add_photos_menu") - ->label($add_photos_item->label) - ->append(Menu::factory("dialog") - ->id("add_photos_submenu_item") - ->label(t("Simple Uploader")) - ->url($add_photos_item->url)) - ->append($server_add)); - $menu->remove("add_photos_item"); - } else if ($add_photos_menu) { - // Append to the existing sub-menu - $add_photos_menu->append($server_add); - } - } - } -} diff --git a/modules/slideshow/helpers/slideshow_event.php b/modules/slideshow/helpers/slideshow_event.php index c6cd7dc7..cf79f71a 100644 --- a/modules/slideshow/helpers/slideshow_event.php +++ b/modules/slideshow/helpers/slideshow_event.php @@ -29,4 +29,34 @@ class slideshow_event_Core { site_status::clear("slideshow_needs_rss"); } } + + static function album_menu($menu, $theme) { + $menu + ->append(Menu::factory("link") + ->id("slideshow") + ->label(t("View slideshow")) + ->url("javascript:PicLensLite.start(" . + "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})") + ->css_id("gSlideshowLink")); + } + + static function photo_menu($menu, $theme) { + $menu + ->append(Menu::factory("link") + ->id("slideshow") + ->label(t("View slideshow")) + ->url("javascript:PicLensLite.start(" . + "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})") + ->css_id("gSlideshowLink")); + } + + static function tag_menu($menu, $theme) { + $menu + ->append(Menu::factory("link") + ->id("slideshow") + ->label(t("View slideshow")) + ->url("javascript:PicLensLite.start(" . + "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})") + ->css_id("gSlideshowLink")); + } } diff --git a/modules/slideshow/helpers/slideshow_menu.php b/modules/slideshow/helpers/slideshow_menu.php deleted file mode 100644 index ee975d88..00000000 --- a/modules/slideshow/helpers/slideshow_menu.php +++ /dev/null @@ -1,51 +0,0 @@ -append(Menu::factory("link") - ->id("slideshow") - ->label(t("View slideshow")) - ->url("javascript:PicLensLite.start(" . - "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})") - ->css_id("gSlideshowLink")); - } - - static function photo($menu, $theme) { - $menu - ->append(Menu::factory("link") - ->id("slideshow") - ->label(t("View slideshow")) - ->url("javascript:PicLensLite.start(" . - "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})") - ->css_id("gSlideshowLink")); - } - - static function tag($menu, $theme) { - $menu - ->append(Menu::factory("link") - ->id("slideshow") - ->label(t("View slideshow")) - ->url("javascript:PicLensLite.start(" . - "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})") - ->css_id("gSlideshowLink")); - } - -} diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php index 0fe8a393..f5fa6d4c 100644 --- a/modules/tag/helpers/tag_event.php +++ b/modules/tag/helpers/tag_event.php @@ -85,4 +85,12 @@ class tag_event_Core { } tag::compact(); } + + static function admin_menu($menu, $theme) { + $menu->get("content_menu") + ->append(Menu::factory("link") + ->id("tags") + ->label(t("Tags")) + ->url(url::site("admin/tags"))); + } } diff --git a/modules/tag/helpers/tag_menu.php b/modules/tag/helpers/tag_menu.php deleted file mode 100644 index e1b61a93..00000000 --- a/modules/tag/helpers/tag_menu.php +++ /dev/null @@ -1,28 +0,0 @@ -get("content_menu") - ->append(Menu::factory("link") - ->id("tags") - ->label(t("Tags")) - ->url(url::site("admin/tags"))); - } -} diff --git a/modules/user/helpers/user_event.php b/modules/user/helpers/user_event.php index 6515fbfb..4bde224b 100644 --- a/modules/user/helpers/user_event.php +++ b/modules/user/helpers/user_event.php @@ -30,4 +30,12 @@ class user_event_Core { I18n::instance()->locale($locale); } } + + static function admin_menu($menu, $theme) { + $menu->add_after("appearance_menu", + Menu::factory("link") + ->id("users_groups") + ->label(t("Users/Groups")) + ->url(url::site("admin/users"))); + } } diff --git a/modules/user/helpers/user_menu.php b/modules/user/helpers/user_menu.php deleted file mode 100644 index 05e401f9..00000000 --- a/modules/user/helpers/user_menu.php +++ /dev/null @@ -1,28 +0,0 @@ -add_after("appearance_menu", - Menu::factory("link") - ->id("users_groups") - ->label(t("Users/Groups")) - ->url(url::site("admin/users"))); - } -} diff --git a/modules/watermark/helpers/watermark_event.php b/modules/watermark/helpers/watermark_event.php new file mode 100644 index 00000000..45b410f9 --- /dev/null +++ b/modules/watermark/helpers/watermark_event.php @@ -0,0 +1,29 @@ +get("content_menu") + ->append( + Menu::factory("link") + ->id("watermarks") + ->label(t("Watermarks")) + ->url(url::site("admin/watermarks"))); + } +} diff --git a/modules/watermark/helpers/watermark_menu.php b/modules/watermark/helpers/watermark_menu.php deleted file mode 100644 index bc3a4fed..00000000 --- a/modules/watermark/helpers/watermark_menu.php +++ /dev/null @@ -1,29 +0,0 @@ -get("content_menu") - ->append( - Menu::factory("link") - ->id("watermarks") - ->label(t("Watermarks")) - ->url(url::site("admin/watermarks"))); - } -} -- cgit v1.2.3 From a25f08d433d504a53763feb358a1aa7f5f798de6 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Mon, 3 Aug 2009 09:19:17 -0700 Subject: Checkpoint the organize module rewrite. At this point, it doesn't really do anything, but get the dialog up, populate the album tree and intelligently populate the micro thumb grid. Still to do: 1) get the microthumbs laided out ptoperly 2) expand and collapse functionality in the album tree 3) use the album tree to change the content of the micro thumb grid 4) Actually add some functionality At the moment, it supports a callback "" to allow modules to add icons to the organize drawer label. The close button is added outside of this framework as it will always be last. --- modules/organize/controllers/organize.php | 507 +-------------- modules/organize/css/organize.css | 184 +----- modules/organize/helpers/organize_task.php | 131 ---- modules/organize/helpers/organize_theme.php | 3 +- modules/organize/js/organize.js | 697 +++------------------ modules/organize/js/organize_init.js | 29 - modules/organize/views/organize.html.php | 53 -- modules/organize/views/organize_album.html.php | 17 - .../organize/views/organize_button_pane.html.php | 49 +- modules/organize/views/organize_dialog.html.php | 37 ++ modules/organize/views/organize_edit.html.php | 14 - .../organize/views/organize_thumb_grid.html.php | 23 +- modules/organize/views/organize_tree.html.php | 20 +- 13 files changed, 232 insertions(+), 1532 deletions(-) delete mode 100644 modules/organize/helpers/organize_task.php delete mode 100644 modules/organize/js/organize_init.js delete mode 100644 modules/organize/views/organize.html.php delete mode 100644 modules/organize/views/organize_album.html.php create mode 100644 modules/organize/views/organize_dialog.html.php delete mode 100644 modules/organize/views/organize_edit.html.php (limited to 'modules/organize/helpers') diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 898be509..d7854c53 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -19,54 +19,48 @@ */ class Organize_Controller extends Controller { private static $_MICRO_THUMB_SIZE = 90; - private static $_MICRO_THUMB_PADDING = 5; + private static $_MICRO_THUMB_PADDING = 10; - function index($item_id=1) { + function index($item_id) { $item = ORM::factory("item", $item_id); $root = ($item->id == 1) ? $item : ORM::factory("item", 1); access::required("view", $item); access::required("edit", $item); - $v = new View("organize.html"); + $v = new View("organize_dialog.html"); $v->root = $root; $v->item = $item; - $v->album_tree = $this->tree($item, $root); + $v->album_tree = $this->_tree($item, $root); + $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item); $v->button_pane = new View("organize_button_pane.html"); + $buttons = (object)array("left" => array(), "middle" =>array(), "right" => array(), + "item" => $item); + module::event("organize_format_button_pane", $buttons); + + $v->button_pane->buttons = $buttons; print $v; } - function content($item_id) { + function content($item_id, $offset=0) { $item = ORM::factory("item", $item_id); access::required("view", $item); access::required("edit", $item); - $width = $this->input->get("width"); - $height = $this->input->get("height"); - $offset = $this->input->get("offset", 0); - $thumbsize = self::$_MICRO_THUMB_SIZE + 2 * self::$_MICRO_THUMB_PADDING; - $page_size = ceil($width / $thumbsize) * ceil($height / $thumbsize); + $v = $this->_get_micro_thumb_grid($item, $offset); + print $v->__toString(); + } + private function _get_micro_thumb_grid($item, $offset=0) { $v = new View("organize_thumb_grid.html"); - $v->children = $item->children($page_size, $offset); + $v->item_id = $item->id; + $v->children = $item->children(25, $offset); $v->thumbsize = self::$_MICRO_THUMB_SIZE; - $v->padding = self::$_MICRO_THUMB_PADDING; - $v->offset = $offset; - - print json_encode(array("count" => $v->children->count(), - "data" => $v->__toString())); - } - - function header($item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); + $v->offset = $offset + 25; - print json_encode( - array("title" => p::purify($item->title), - "description" => empty($item->description) ? "" : p::purify($item->description))); + return $v; } - function tree($item, $parent) { + private function _tree($item, $parent, $selected=false) { access::required("view", $item); access::required("edit", $item); @@ -75,466 +69,25 @@ class Organize_Controller extends Controller { ->orderby(array("title" => "ASC")) ->find_all(); - $v = new View("organize_album.html"); + $v = new View("organize_tree.html"); $v->album = $parent; - $v->selected = $parent->id == $item->id; - - if ($albums->count()) { - $v->album_icon = $parent->id == 1 || $v->selected ? "ui-icon-minus" : "ui-icon-plus"; - } else { - $v->album_icon = ""; - } + $v->selected = false; $v->children = ""; - foreach ($albums as $album) { - $v->children .= $this->tree($item, $album); - } - return $v->__toString(); - } - - function startTask($operation, $id) { - access::verify_csrf(); - $items = $this->input->post("item"); - - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - $definition = $this->_getOperationDefinition($item, $operation); - - $task_def = Task_Definition::factory() - ->callback("organize_task::run") - ->description($definition["description"]) - ->name($definition["name"]); - $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id, - "type" => $definition["type"], - "batch" => ceil(count($items) * .1))); - // @todo If there is only one item then call task_run($task->id); Maybe even change js so - // we can call finish as well. - batch::start(); - print json_encode( - array("result" => "started", - "runningMsg" => $definition["runningMsg"], - "pauseMsg" => "
{$definition['pauseMsg']}
", - "resumeMsg" => "
{$definition['resumeMsg']}
", - "task" => array("id" => $task->id, - "percent_complete" => $task->percent_complete, - "type" => $task->get("type"), - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function runTask($task_id) { - access::verify_csrf(); - - $task = task::run($task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } - - print json_encode(array("result" => $task->done ? $task->state : "in_progress", - "task" => array("id" => $task->id, - "percent_complete" => $task->percent_complete, - "type" => $task->get("type"), - "post_process" => $task->get("post_process"), - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function finishTask($task_id) { - access::verify_csrf(); - - $task = ORM::factory("task", $task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } - - if ($task->done) { - $item = ORM::factory("item", (int)$task->get("target")); - $type = $task->get("type"); - switch ($type) { - case "albumCover": - $task->status = t("Album cover set for '%album'", array("album" => $item->title)); - break; - case "delete": - $task->status = t("Selection deleted"); - break; - case "move": - $task->status = t("Move to '%album' completed", array("album" => $item->title)); - break; - case "rearrange": - try { - $item->sort_column = "weight"; - $item->save(); - $task->status = t("Rearrange for '%album' completed", array("album" => $item->title)); - } catch (Exception $e) { - $task->state = "error"; - $task->status = $e->getMessage(); - } - break; - case "rotateCcw": - case "rotateCw": - $task->status = t("Rotation completed"); - break; - } - $task->save(); - } - - batch::stop(); - print json_encode(array("result" => "success", - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function cancelTask($task_id) { - access::verify_csrf(); - - $task = ORM::factory("task", $task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } - - if (!$task->done) { - $task->done = 1; - $task->state = "cancelled"; - $type = $task->get("type"); - switch ($type) { - case "move": - $task->status = t("Move to album was cancelled prior to completion"); - break; - case "rearrange": - $task->status = t("Rearrange album was cancelled prior to completion"); - case "rotateCcw": - case "rotateCw": - $task->status = t("Rotation was cancelled prior to completion"); - break; - } - $task->save(); - } - - batch::stop(); - print json_encode(array("result" => "success", - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function editForm() { - $event_parms = new stdClass(); - $event_parms->panes = array(); - $event_parms->itemids = $this->input->get("item"); - - // The following code should be done more dynamically i.e. use the event mechanism - if (count($event_parms->itemids) == 1) { - $item = ORM::factory("item") - ->in("id", $event_parms->itemids[0]) - ->find(); - - access::required("view", $item); - access::required("edit", $item); - - $event_parms->panes[] = array( - "label" => $item->is_album() ? t("Edit Album") : t("Edit Photo"), - "content" => organize::get_general_edit_form($item)); - - if ($item->is_album()) { - $event_parms->panes[] = array("label" => t("Sort Order"), - "content" => organize::get_sort_edit_form($item)); - } - } - - $event_parms->panes[] = array("label" => t("Manage Tags"), - "content" => organize::get_tag_form($event_parms->itemids)); - - $v = new View("organize_edit.html"); - $v->panes = $event_parms->panes; - print $v->render(); - } - - // Handlers for the album/photo edit. Probably should be in modules/gallery - public function general() { - access::verify_csrf(); - - $itemids = $this->input->post("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - $form = organize::get_general_edit_form($item); - if ($form->validate()) { - $orig = clone $item; - $item->title = $form->title->value; - $item->description = $form->description->value; - $item->rename($form->dirname->value); - $item->save(); + $v->album_icon = "ui-icon-plus"; + if (!$selected) { + $v->selected = $parent->id == $item->id; - if ($item->is_album()) { - log::success("content", "Updated album", "id\">view"); - $message = t("Saved album %album_title", array("album_title" => p::purify($item->title))); - } else { - log::success("content", "Updated photo", "id\">view"); - $message = t("Saved photo %photo_title", array("photo_title" => p::purify($item->title))); + if ($albums->count() && ($parent->id == 1 || $v->selected) ) { + $v->album_icon = "ui-icon-minus"; } - print json_encode(array("form" => $form->__toString(), "message" => $message)); - } else { - print json_encode(array("form" => $form->__toString())); - } - } - - public function reset_general() { - $itemids = Input::instance()->get("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - print organize::get_general_edit_form($item); - } - - public function sort() { - access::verify_csrf(); - - $itemids = $this->input->post("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - $form = organize::get_sort_edit_form($item); - if ($form->validate()) { - $orig = clone $item; - $item->sort_column = $form->column->value; - $item->sort_order = $form->direction->value; - $item->save(); - - log::success("content", "Updated album", "id\">view"); - $message = t("Saved album %album_title", array("album_title" => p::purify($item->title))); - print json_encode(array("form" => $form->__toString(), "message" => $message)); - } else { - print json_encode(array("form" => $form->__toString())); - } - } - - public function reset_sort() { - $itemids = Input::instance()->get("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - print organize::get_sort_edit_form($item); - } - - public function edit_tags() { - access::verify_csrf(); - $itemids = explode("|", $this->input->post("item")); - $form = organize::get_tag_form($itemids); - $old_tags = $form->tags->value; - if ($form->validate()) { - - $old_tags = preg_split("/[;,\s]+/", $old_tags); - sort($old_tags); - $new_tags = preg_split("/[;,\s]+/", $form->tags->value); - sort($new_tags); - - $HIGH_VALUE_STRING = "\256"; - for ($old_index = $new_index = 0;;) { - $old_tag = $old_index >= count($old_tags) ? $HIGH_VALUE_STRING : $old_tags[$old_index]; - $new_tag = $new_index >= count($new_tags) ? $HIGH_VALUE_STRING : $new_tags[$new_index]; - if ($old_tag == $HIGH_VALUE_STRING && $new_tag == $HIGH_VALUE_STRING) { - break; - } - $matches = array(); - $old_star = false; - if (preg_match("/(.*)(\*)$/", $old_tag, $matches)) { - $old_star = true; - $old_tag = $matches[1]; - } - $new_star = false; - if (preg_match("/(.*)(\*)$/", $new_tag, $matches)) { - $new_star = true; - $new_tag = $matches[1]; - } - if ($old_tag > $new_tag) { - // Its missing in the old list so add it - $this->_add_tag($new_tag, $itemids); - $new_index++; - } else if ($old_tag < $new_tag) { - // Its missing in the new list so its been removed - $this->_delete_tag($old_tag, $itemids); - $old_index++; - } else { - if ($old_star && !$new_star) { - // User wants tag to apply to all items, originally only on some of selected - $this->_update_tag($old_tag, $itemids); - } // Not changed ignore - $old_index++; - $new_index++; - } + foreach ($albums as $album) { + $v->children .= $this->_tree($item, $album, $v->selected); } } - print json_encode(array("form" => $form->__toString(), "message" => t("Tags updated"))); - } - - public function reset_edit_tags() { - $itemids = $this->input->get("item"); - - print organize::get_tag_form($itemids); - } - - private function _add_tag($new_tag, $itemids) { - // Super lame security stopgap. This code is going to get rewritten anyway. - foreach ($itemids as $item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); - } - - $tag = ORM::factory("tag") - ->where("name", $new_tag) - ->find(); - if ($tag->loaded) { - $tag->count += count($itemids); - } else { - $tag->name = $new_tag; - $tag->count = count($itemids); - } - $tag->save(); - - $db = Database::instance(); - foreach ($itemids as $item_id) { - $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); - } - } - - private function _delete_tag($new_tag, $itemids) { - // Super lame security stopgap. This code is going to get rewritten anyway. - foreach ($itemids as $item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); - } - - $tag = ORM::factory("tag") - ->where("name", $new_tag) - ->find(); - $tag->count -= count($itemids); - if ($tag->count > 0) { - $tag->save(); - } else { - $tag->delete(); - } - - $ids = implode(", ", $itemids); - Database::instance()->query( - "DELETE FROM {items_tags} WHERE tag_id = {$tag->id} AND item_id IN ($ids);"); - } - - private function _update_tag($new_tag, $itemids) { - // Super lame security stopgap. This code is going to get rewritten anyway. - foreach ($itemids as $item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); - } - - $tag = ORM::factory("tag") - ->where("name", $new_tag) - ->find(); - - $db = Database::instance(); - $ids = implode(", ", $itemids); - $result = $db->query( - "SELECT item_id FROM {items_tags} - WHERE tag_id = {$tag->id} - AND item_id IN ($ids)"); - - $add_items = array_fill_keys($itemids, 1); - foreach($result as $row) { - unset($add_items[$row->item_id]); - } - $add_items = array_keys($add_items); - $tag->count += count($add_items); - $tag->save(); - foreach ($add_items as $item_id) { - $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); - } + return $v->__toString(); } - private function _getOperationDefinition($item, $operation) { - switch ($operation) { - case "move": - return array("description" => - t("Move albums and photos to '%name'", array("name" => $item->title)), - "name" => t("Move to '%name'", array("name" => $item->title)), - "type" => "move", - "runningMsg" => t("Move in progress"), - "pauseMsg" => t("The move operation was paused"), - "resumeMsg" => t("The move operation was resumed")); - break; - - case "rearrange": - return array("description" => t("Rearrange the order of albums and photos"), - "name" => t("Rearrange: %name", array("name" => $item->title)), - "type" => "rearrange", - "runningMsg" => t("Rearrange in progress"), - "pauseMsg" => t("The rearrange operation was paused"), - "resumeMsg" => t("The rearrange operation was resumed")); - break; - case "rotateCcw": - return array("description" => t("Rotate the selected photos counter clockwise"), - "name" => t("Rotate images in %name", array("name" => $item->title)), - "type" => "rotateCcw", - "runningMsg" => t("Rotate Counter Clockwise in progress"), - "pauseMsg" => t("The rotate operation was paused"), - "resumeMsg" => t("The rotate operation was resumed")); - break; - - case "rotateCw": - return array("description" => t("Rotate the selected photos clockwise"), - "name" => t("Rotate images in %name", array("name" => $item->title)), - "type" => "rotateCw", - "runningMsg" => t("Rotate Clockwise in progress"), - "pauseMsg" => t("The rotate operation was paused"), - "resumeMsg" => t("The rotate operation was resumed")); - break; - - case "delete": - return array("description" => t("Delete selected photos / albums"), - "name" => t("Delete images in %name", array("name" => $item->title)), - "type" => "delete", - "runningMsg" => t("Delete images in progress"), - "pauseMsg" => t("The delete operation was paused"), - "resumeMsg" => t("The delete operation was resumed")); - break; - - case "albumCover": - return array("description" => t("Reset Album Cover"), - "name" => t("Reset Album cover for %name", array("name" => $item->title)), - "type" => "albumCover", - "runningMsg" => t("Reset Album Cover in progress"), - "pauseMsg" => t("Reset album cover was paused"), - "resumeMsg" => t("Reset album cover was resumed")); - break; - - default: - throw new Exception("Operation '$operation' is not implmented"); - } - } } diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index e58cd5a5..4568a707 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -1,41 +1,44 @@ -/* @todo move to theme css */ /******************************************************************* * Dialog wide stylings */ -#gMessage { - margin-bottom: .4em; +#gOrganizeDialog { + text-align: left; } -#gMessage .gInfo { - background-color: transparent; - background-image: none; - padding-left: .4em; +#gOrganize { + overflow: hidden; } -#gOrganizeProgressDialog { - text-align: left; +#gOrganize .yui-u { + width: 75%; +} + +#gOrganize .yui-gf .first { + width: 25%; } -#gDialog .yui-gf div.first { - width: 20%; +#gOrganize .yui-gf #gMessage { + margin-bottom: .4em; + width: 75%; } -#gDialog .yui-gf .yui-u { - width: 80%; +#gMessage .gInfo { + font-weight: bold; + padding-left: 2em; } + /******************************************************************* * Album Tree styling */ #gOrganizeTreeContainer { - overflow-y: auto; + overflow: auto; margin: 0 !important; padding: 0 !important; } -#gOrganizeAlbumDescription { - height: 2em; - overflow-y: auto; +#gOrganizeTreeContainer ul ul li { + padding-left: 1.2em; } .gBranchSelected { @@ -45,37 +48,21 @@ padding: .3em 0; } -.gBranchDroppable { - border: 1px dotted; -} - -.gBranchText { - cursor: pointer; - width: auto; -} - .gBranchCollapsed { display: none; } -.gBranchEmpty { - visibility: hidden; +.gOrganizeBranch span { + cursor: pointer; } -#gOrganizeTreeContainer ul ul li { - padding-left: 1.2em; +.gBranchText { + cursor: pointer; + width: auto; } - /******************************************************************* * Album Panel Styles */ - -#gMicroThumbUnselectAll, -#gMicroThumbSelectAll { - font-size: 1em; - font-weight: bold; -} - #gMicroThumbPanel { margin: 0 !important; padding: 0 !important; @@ -83,33 +70,27 @@ border: 1px solid #999 !important; border-top: none !important; border-left: none !important; - margin-left: -1em !important; overflow-x: hidden; overflow-y: auto; } #gMicroThumbGrid { - padding: .5em; } .gMicroThumbContainer { - display: block; - float: left; - font-size: .7em; - height: 9em; - margin-bottom: 1em; - margin-left: 1em; - opacity: .4; - padding: 0 .5em; +// padding: 0 .5em; +// opacity: .4; } .gMicroThumb { - height: 9em; - width: 9em; - background-color: #fff; display: block; float: left; +// font-size: .7em; + height: 9em; + margin-bottom: 1em; + margin-left: 1em; text-align: center; + width: 9em; } #gMicroThumbPanel #gMicroThumbGrid .gAlbum { @@ -120,35 +101,12 @@ opacity: 1; } -.gMicroThumbContainer.ui-selected { - opacity: 1; -} - -#gDragHelper .gMicroThumbGrid { - background-color: transparent; - padding: 0; - overflow: visible; -} - -#gDragHelper .gMicroThumbContainer { - display: block; - margin: 0; - padding: 0; -} - -#gDragHelper .gMicroThumb { - background-color: transparent; - height: auto; - width: auto; -} - - /**************************************************************** * Organize Edit Drawer styling */ #gOrganizeEditDrawer { background-color: #13A; - width: 90%; + width: 100% !important; } #gOrganizeEditDrawerPanel { @@ -204,79 +162,3 @@ height: 30px; width: 15px; } - -#gOrganizeFormButtons { - bottom: 0.5em; -} - -#gOrganizeFormButtons .submit { - display: inline; - float: none; - left: 0.5em; - position: relative; -} - -/* yui-u gives 80% width, but then we wrap so do it ourselves */ -#gOrganizeEditForm { - float: right; - width: 79%; - // height: 100px; -} - -#gOrganizeFormThumbs { - overflow: hidden; -} - -#gOrganizeFormThumbs div { - margin: 0; - text-align: center; - background: transparent none repeat scroll 0 0; -} - -#gOrganizeFormThumbs .gMicroThumbContainer { - display: block; - float: left; - opacity: 1; - position: absolute; -} - -/**************************************************************** - * Organize Edit From tabs styling - */ -#gOrganizeEditForm.ui-tabs .ui-tabs-hide { - display: block !important; - left: -10000px; - position: absolute; -} - -#gOrganizeEditForm.ui-widget { - font-size: .75em; -} - -.gOrganizeEditPane { - height: 135px; - overflow-y: auto; -} - -.textbox, -.textarea { - border: 1px solid #e8e8e8; - border-top-color: #ccc; - border-left-color: #ccc; - color: #333; - width: 100%; -} - -.textarea { - height: 6em; -} - -.textbox { - height: 1.3em; - width: 50% -} - -.gTagGroup { - float:left; - margin: .5em; -} diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php deleted file mode 100644 index dc474818..00000000 --- a/modules/organize/helpers/organize_task.php +++ /dev/null @@ -1,131 +0,0 @@ -context); - $taskType = $context["type"]; - - try { - $target = ORM::factory("item", $context["target"]); - $total = count($context["items"]); - $stop = min($total - $context["position"], $context["batch"]); - $context["post_process"] = array(); - for ($offset = 0; $offset < $stop; $offset++) { - $current_id = $context["position"] + $offset; - $id = $context["items"][$current_id]; - switch ($taskType) { - case "move": - $source = ORM::factory("item", $id); - access::required("view", $source); - access::required("view", $target); - access::required("edit", $source); - access::required("edit", $target); - - item::move($source, $target); - break; - - case "rearrange": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - Database::instance() - ->query("Update {items} set weight = {$context["position"]} where id=$id;"); - break; - - case "rotateCcw": - case "rotateCw": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - if ($item->is_photo()) { - $context["post_process"]["reload"][] = - self::_do_rotation($item, $taskType == "rotateCcw" ? -90 : 90); - } - break; - - case "albumCover": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("view", $item->parent()); - access::required("edit", $item->parent()); - - item::make_album_cover($item); - break; - - case "delete": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - $item->delete(); - $context["post_process"]["remove"][] = array("id" => $id); - break; - - default: - throw new Exception("Task '$taskType' is not implemented"); - } - } - $context["position"] += $stop; - $task->state = "success"; - } catch(Exception $e) { - $task->status = $e->getMessage(); - $task->state = "error"; - $task->save(); - throw $e; - } - $task->context = serialize($context); - $total = count($context["items"]); - $task->percent_complete = $context["position"] / (float)$total * 100; - $task->done = $context["position"] == $total || $task->state == "error"; - } - - private static function _do_rotation($item, $degrees) { - // This code is copied from Quick_Controller::rotate - graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); - - list($item->width, $item->height) = getimagesize($item->file_path()); - $item->resize_dirty= 1; - $item->thumb_dirty= 1; - $item->save(); - - graphics::generate($item); - - $parent = $item->parent(); - if ($parent->album_cover_item_id == $item->id) { - copy($item->thumb_path(), $parent->thumb_path()); - $parent->thumb_width = $item->thumb_width; - $parent->thumb_height = $item->thumb_height; - $parent->save(); - } - list ($height, $width) = $item->scale_dimensions(90); - $margin_top = (90 - $height) / 20; - - return array("src" => $item->thumb_url() . "?rnd=" . rand(), - "id" => $item->id, - "marginTop" => "{$margin_top}em", "width" => $width, "height" => $height); - } -} \ No newline at end of file diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index e4feba2b..f01ab88b 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -19,8 +19,7 @@ */ class organize_theme { static function head($theme) { - // @tdo remove the addition css and organize.js (just here to test) - $theme->script("organize_init.js"); + //$theme->script("organize_init.js"); $theme->script("organize.js"); $theme->css("organize.css"); } diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index 12d8a5b5..e84afd03 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -1,621 +1,116 @@ -/* - * @todo Trap resize of dialog and resize the child areas (tree, grid and edit form) - */ -var url; -var paused = false; -var task = null; -var transitItems = []; -var heightMicroThumbPanel; - -// ************************************************************************** -// JQuery UI Widgets -// Draggable -var draggable = { - handle: ".gMicroThumbContainer.ui-selected", - revert: true, - zindex: 2000, - distance: 10, - helper: function(event, ui) { - if (!$(event.currentTarget).hasClass("ui-selected")) { - $(event.currentTarget).addClass("ui-selected"); - setDrawerButtonState(); - } - $("#gMicroThumbPanel").append("
    "); - var beginTop = event.pageY; - var beginLeft = event.pageX; - var zindex = $(".gMicroThumbContainer").draggable("option", "zindex"); - $("#gDragHelper").css('top', event.pageY - 22.5); - $("#gDragHelper").css('left', event.pageX + 22.5); - var placeHolder = $(this).clone(); - $(placeHolder).attr("id", "gPlaceHolder"); - $(placeHolder).css("visibility", "hidden"); - $(placeHolder).removeClass("ui-selected"); - $(placeHolder).removeClass("ui-draggable"); - $(this).after(placeHolder); - - $("li.ui-selected").each(function(i) { - var clone = $(this).clone(); - $(clone).attr("id", "drag_clone_" + $(this).attr("ref")); - $("#gDragHelper ul").append(clone); - $(clone).css("position", "absolute"); - $(clone).css("top", beginTop); - $(clone).css("left", beginLeft); - $(clone).css("z-index", zindex--); - $(this).hide(); - - var children = $(clone).find(".gMicroThumb .gThumbnail"); - var width = new String(children.css("width")).replace(/[^0-9]/g,"") * .5; - var height = new String(children.css("height")).replace(/[^0-9]/g,"") * .5; - var marginTop = new String(children.css("margin-top")).replace(/[^\.0-9]/g,"") * .5; - children.attr("width", width); - children.attr("height", height); - children.css("margin-top", marginTop); - if (i < 9) { - beginTop -= 5; - beginLeft += 5; - } - }); - return $("#gDragHelper"); - }, - stop: function(event, ui) { - $("#gDragHelper li").each(function(i) { - $("#thumb_" + $(this).attr("ref")).show(); - }); - $(".gMicroThumbContainer.ui-selected").css("z-index", null); - $("#gDragHelper").remove(); - $("#gPlaceHolder").remove(); - } -}; - -// Thumbnail Grid Droppable -var thumbDroppable = { - tolerance: "pointer", - over: function(event, ui) { - $("#gPlaceHolder").show(); - }, - out: function(event, ui) { - $("#gPlaceHolder").hide(); - }, - drop: function(event, ui) { - $("#gDragHelper").hide(); - $("#gPlaceHolder").hide(); - var newOrder = ""; - $("#gMicroThumbGrid .gMicroThumbContainer").each(function(i) { - if ($(this).attr("id") == "gPlaceHolder") { - $("#gDragHelper li").each(function(i) { - newOrder += "&item[]=" + $(this).attr("ref"); - }); - } else if ($(this).css("display") != "none") { - newOrder += "&item[]=" + $(this).attr("ref"); - } else { - // If its not displayed then its one of the ones being moved so ignore. - } - }); - $("#gDragHelper li").each(function(i) { - $("#gPlaceHolder").before($("#thumb_" + $(this).attr("ref")).show()); - }); - $.ajax({ - data: newOrder, - dataType: "json", - success: operationCallback, - type: "POST", - url: get_organize_url("organize/startTask/rearrange", {item_id: item_id}) - }); - } -}; - -// Album Tree Droppable -var treeDroppable = { - tolerance: "pointer", - greedy: true, - hoverClass: "gBranchDroppable", - drop: function(event, ui) { - $("#gDragHelper").hide(); - var targetItemId = $(this).attr("ref"); - if ($(this).hasClass("gBranchSelected")) { - $("#gMessage").empty().append(INVALID_DROP_TARGET); - ui.draggable.trigger("stop", event); - return false; - } - var postData = serializeItemIds("#gDragHelper li"); - var okToMove = true; - $("#gDragHelper li").each(function(i) { - okToMove &= targetItemId != $(this).attr("ref"); - }); - if (!okToMove) { - $("#gMessage").empty().append(INVALID_DROP_TARGET); - ui.draggable.trigger("stop", event); - return false; - } - $("#gDragHelper li").each(function(i) { - $("#thumb_" + $(this).attr("ref")).remove(); - }); - $.ajax({ - data: postData, - dataType: "json", - success: operationCallback, - type: "POST", - url: get_organize_url("organize/startTask/move", {item_id: targetItemId}) - }); - return true; - } -}; - -// Selectable -var selectable = { - filter: ".gMicroThumbContainer", - selected: function(event, ui) { - setDrawerButtonState(); - }, - unselected: function(event, ui) { - setDrawerButtonState(); - }, - stop: function(event, ui) { - getEditForm(); - } -}; - -// ************************************************************************** -// Event Handlers -// MicroThumbContainer mouseup -var onMicroThumbContainerMouseup = function(event) { - // For simplicity always remove the ui-selected class. If it was unselected - // it will get added back - $(this).toggleClass("ui-selected"); - - setDrawerButtonState(); - if ($("#gMicroThumbGrid li.ui-selected").length > 0) { - getEditForm(); - } -}; - -// MicroThumbContainer mousemove -var onMicroThumbContainerMousemove = function(event) { - if ($("#gDragHelper").length > 0 && $(this).attr("id") != "gPlaceHolder") { - if (event.pageX < $(this).offset().left + $(this).width() / 2) { - $(this).before($("#gPlaceHolder")); - } else { - $(this).after($("#gPlaceHolder")); - } - var container = $("#gMicroThumbPanel").get(0); - var scrollHeight = container.scrollHeight; - var scrollTop = container.scrollTop; - var height = $(container).height(); - if (event.pageY > height + scrollTop) { - container.scrollTop = this.offsetTop; - } else if (event.pageY < scrollTop) { - container.scrollTop -= height; - } - } -}; - -// Handle click events on the buttons on the drawer handle -function drawerHandleButtonsClick(event) { - event.preventDefault(); - if (!$(this).attr("disabled")) { - var operation = $(this).attr("ref"); - switch (operation) { - case "edit": - case "close": - $("#gOrganizeEditDrawerPanel").animate( - {"height": "toggle", "display": "block"}, - {duration: "fast", - complete: function() { - setSelectedThumbs(); - if (operation == "close") { - $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "inline-block"); - $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "none"); - $("#gOrganizeEditHandleButtonsMiddle a").css("display", "none"); - } else { - $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "none"); - $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "inline-block"); - $("#gOrganizeEditHandleButtonsMiddle a").css("display", "inline-block"); - } - }, - step: function() { - $("#gMicroThumbPanel").height(heightMicroThumbPanel - $(this).height()); - } - }); - break; - case "select-all": - $("#gMicroThumbGrid li").addClass("ui-selected"); - $("#gMicroThumbSelectAll").hide(); - $("#gMicroThumbUnselectAll").show(); - setDrawerButtonState(); - getEditForm(); - break; - case "unselect-all": - $("#gMicroThumbGrid li").removeClass("ui-selected"); - $("#gMicroThumbSelectAll").show(); - $("#gMicroThumbUnselectAll").hide(); - setDrawerButtonState(); - break; - case "done": - $("#gDialog").dialog("close"); - break; - case "submit": - var currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); - var form = $("#pane-"+currentTab+" form"); - var url = $(form).attr("action") - .replace("__FUNCTION__", $(form).attr("ref")); - $.ajax({ - data: $(form).serialize(), - dataType: "json", - success: function (data, textStatus) { - $("#pane-"+currentTab).children("form").replaceWith(data.form); - if (data.message) { - $("#gMessage").empty().append("
    " + data.message + "
    "); - } - }, - type: "POST", - url: url - }); - break; - case "reset": - currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); - form = $("#pane-"+currentTab+" form"); - $.ajax({ - data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), - dataType: "html", - success: function (data, textStatus) { - $("#pane-"+currentTab + " form").replaceWith(data); - }, - type: "GET", - url: $(form).attr("action").replace("__FUNCTION__", "reset_" + $(form).attr("ref")) +(function($) { + $.fn.organize = function(options) { + var size = $.getViewportSize(); + var height = size.height() - 100; // Leave 50 pixels on the top and bottom of the dialog + var width = size.width() - 100; // Leave 50 pixels on the left and right of the dialog + var opts = $.extend({}, $.fn.organize.defaults, {width: width, height: height}, options); + return this.each(function() { + $(this).click(function(event) { + var href = event.target.href; + var size = $.getViewportSize(); + + $("body").append('
    '); + + $("#gOrganizeDialog").dialog(opts); + // Pass the approx height and width of the thumb grid to optimize thumb retrieval + $.get(href, _init); + return false; }); - break; - case "delete": - if (!confirm(CONFIRM_DELETE)) { - break; - } - default: - $.ajax({ - data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), - dataType: "json", - success: operationCallback, - type: "POST", - url: get_organize_url("organize/startTask/" + operation, {item_id: item_id}) - }); - break; - } - } -}; - -// ************************************************************************** -// AJAX Callbacks -// MicroThumbContainer click -var getMicroThumbsCallback = function(json, textStatus) { - if (json.count > 0) { - $("#gMicroThumbGrid").append(json.data); - retrieveMicroThumbs(); - $(".gMicroThumbContainer").mouseup(onMicroThumbContainerMouseup); - $(".gMicroThumbContainer").mousemove(onMicroThumbContainerMousemove); - $(".gMicroThumbContainer").draggable(draggable); - } -}; - -var operationCallback = function (data, textStatus) { - var done = false; - if (!paused) { - createProgressDialog(data.runningMsg); - task = data.task; - task.pauseMsg = data.pauseMsg; - task.resumeMsg = data.resumeMsg; - done = data.task.done; - } - $(".gMicroThumbContainer").draggable("disable"); - paused = false; - while (!done && !paused) { - $.ajax({async: false, - success: function(data, textStatus) { - $(".gProgressBar").progressbar("value", data.task.percent_complete); - done = data.task.done; - if (data.task.post_process.reload) { - $.each(data.task.post_process.reload, function() { - var selector = "#gMicroThumb-" + this.id + " img"; - $(selector).attr("height", this.height); - $(selector).attr("width", this.width); - $(selector).attr("src", this.src); - $(selector).css("margin-top", this.marginTop); - }); - } - if (data.task.post_process.remove) { - $.each(data.task.post_process.remove, function() { - $("#thumb_" + this.id).remove(); - }); - } - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - paused = true; - displayAjaxError(XMLHttpRequest.responseText); - }, - dataType: "json", - type: "POST", - url: get_organize_url("organize/runTask", {task_id: task.id}) - }); - } - if (!paused) { - $("#gOrganizeProgressDialog").dialog("destroy").remove(); - $.ajax({async: false, - success: function(data, textStatus) { - setDrawerButtonState(); - task = null; - $("#gMessage").empty().append("
    " + data.task.status + "
    "); - }, - dataType: "json", - type: "POST", - url: get_organize_url("organize/finishTask", {task_id: task.id}) }); - } - $(".gMicroThumbContainer").draggable("enable"); -}; - -// ************************************************************************** - -/** - * Dynamically initialize the organize dialog when it is displayed - */ -function organize_dialog_init() { - var size = getViewportSize(); - heightMicroThumbPanel = size.height() - 100; - var width = size.width() - 100; - - // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 - $(".sf-menu li.sfHover ul").css("z-index", 70); - - $("#gDialog").dialog("option", "width", width); - $("#gDialog").dialog("option", "height", heightMicroThumbPanel); - - $("#gDialog").dialog("open"); - if ($("#gDialog h1").length) { - $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html()); - } else if ($("#gDialog fieldset legend").length) { - $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html()); - } - - $("#gDialog").bind("organize_close", function(target) { - $.gallery_reload(); - }); - - heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-top")); - heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-bottom")); - heightMicroThumbPanel -= $("#gMicroThumbPanel").position().top; - heightMicroThumbPanel -= $("#gDialog #ft").height(); - heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").height(); - heightMicroThumbPanel = Math.round(heightMicroThumbPanel); - - $("#gMicroThumbPanel").height(heightMicroThumbPanel); - $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); - - $(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); - $(".gBranchText").droppable(treeDroppable); - $(".gBranchText").click(organizeOpenFolder); - retrieveMicroThumbs(item_id); - //showLoading("#gDialog"); - - $("#gMicroThumbPanel").droppable(thumbDroppable); - $("#gMicroThumbPanel").selectable(selectable); - $("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); -} - -function retrieveMicroThumbs() { - var offset = $("#gMicroThumbGrid li").length; - if (url == null) { - var grid_width = $("#gMicroThumbPanel").width(); - url = $("#gMicroThumbPanel").attr("ref"); - url = url.replace("__WIDTH__", grid_width); - url = url.replace("__HEIGHT__", heightMicroThumbPanel); - } - var url_data = url.replace("__OFFSET__", offset); - url_data = url_data.replace("__ITEM_ID__", item_id); - $.getJSON(url_data, getMicroThumbsCallback); -} + }; -function organizeToggleChildren(event) { - var id = $(this).attr("ref"); - var span_children = $("#gOrganizeChildren-" + id); - if ($(this).hasClass("ui-icon-plus")) { - $(this).removeClass("ui-icon-plus"); - $(this).addClass("ui-icon-minus"); - $("#gOrganizeChildren-" + id).removeClass("gBranchCollapsed"); - } else { - $(this).removeClass("ui-icon-minus"); - $(this).addClass("ui-icon-plus"); - $("#gOrganizeChildren-" + id).addClass("gBranchCollapsed"); - } - event.preventDefault(); -} + $.fn.organize.defaults = { + autoOpen: false, + modal: true, + resizable: false, + minWidth: 600, + minHeight: 500, + position: "center", + close: function () { + $("#gOrganizeDialog").trigger("organize_close"); + $("#gOrganizeDialog").dialog("destroy").remove(); + }, + zIndex: 75 + }; -function organizeOpenFolder(event) { - var selected = $(".gBranchSelected"); - if ($(selected).attr("id") != $(this).attr("id")) { - $(selected).removeClass("gBranchSelected"); - $(this).addClass("gBranchSelected"); - item_id = $(this).attr("ref"); - $("#gMicroThumbGrid").empty(); - retrieveMicroThumbs(); - } - event.preventDefault(); -} + /** + * Dynamically initialize the organize dialog when it is displayed + */ + function _init(data) { -function get_organize_url(uri, parms) { - var url = rearrangeUrl; - url = url.replace("__URI__", uri); - url = url.replace("__ITEM_ID__", !parms.item_id ? "" : parms.item_id); - url += (parms.item_id && parms.task_id) ? "/" : ""; - url = url.replace("__TASK_ID__", !parms.task_id ? "" : parms.task_id); - return url; -} + // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 + $(".sf-menu li.sfHover ul").css("z-index", 70); -/** - * Set the enabled/disabled state of the buttons. The album cover is only enabled if - * there is only 1 image selected - */ -function setDrawerButtonState() { - $("#gOrganizeFormThumbStack").empty(); - $("#gOrganizeEditForm").empty(); - var selectedCount = $("#gMicroThumbGrid li.ui-selected").length; - if (selectedCount) { - $("#gOrganizeEditHandleButtonsLeft a").removeAttr("disabled"); - $("#gOrganizeEditHandleButtonsLeft a").removeClass("ui-state-disabled"); + $("#gOrganizeDialog").html(data); + $("#gOrganizeDialog").dialog("open"); - if (selectedCount > 1) { - $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").attr("disabled", true); - $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").addClass("ui-state-disabled"); - } - setSelectedThumbs(); - } else { - if ($("#gOrganizeEditDrawerPanel::visible").length) { - $("#gOrganizeEditHandleButtonsLeft a[ref='close']").trigger("click"); - } - $("#gOrganizeEditHandleButtonsLeft a").attr("disabled", true); - $("#gOrganizeEditHandleButtonsLeft a").addClass("ui-state-disabled"); - } -} + var heightMicroThumbPanel = $("#gOrganizeDialog").innerHeight(); + heightMicroThumbPanel -= 2 * parseFloat($("#gOrganizeDialog").css("padding-bottom")); + heightMicroThumbPanel -= $("#gMessage").outerHeight(); + heightMicroThumbPanel = Math.floor(heightMicroThumbPanel); + $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); -function setSelectedThumbs() { - if (!$("#gOrganizeEditDrawerPanel::visible").length) { - return; - } - var position = $("#gOrganizeFormThumbStack").position(); - var beginLeft = position.left; - var beginTop = 50; - var zindex = 2000; - $("li.ui-selected").each(function(i) { - var clone = $(this).clone(); - $(clone).attr("id", "edit_clone_" + $(this).attr("ref")); - $("#gOrganizeFormThumbStack").append(clone); - $(clone).removeClass("ui-draggable"); - $(clone).removeClass("ui-selected"); - $(clone).css("margin-top", beginTop); - $(clone).css("left", beginLeft); - $(clone).css("z-index", zindex--); + heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").outerHeight(); + $("#gMicroThumbPanel").height(heightMicroThumbPanel); - if (i < 9) { - beginTop -= 5; - beginLeft += 5; + if ($("#gOrganizeDialog h1").length) { + $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog h1:eq(0)").html()); + } else if ($("#gOrganizeDialog fieldset legend").length) { + $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog fieldset legend:eq(0)").html()); } - }); -} -function getEditForm() { - if ($("#gMicroThumbGrid li.ui-selected").length > 0) { - var postData = serializeItemIds("li.ui-selected"); - var url_data = get_organize_url("organize/editForm", {}) + postData; - $.get(url_data, function(data, textStatus) { - $("#gOrganizeEditForm").tabs("destroy"); - $("#gOrganizeEditForm").html(data); - if ($("#gOrganizeEditForm ul li").length) { - $("#gOrganizeEditForm").tabs(); - $("#gOrganizeEditHandleButtonsMiddle a").removeAttr("disabled"); - $("#gOrganizeEditHandleButtonsMiddle a").removeClass("ui-state-disabled"); - } else { - $("#gOrganizeEditHandleButtonsMiddle a").attr("disabled", true); - $("#gOrganizeEditHandleButtonsMiddle a").addClass("ui-state-disabled"); - } + $("#gOrganizeDialog #gMicroThumbDone").click(_dialog_close); + $("#gOrganizeDialog").bind("organize_close", function(target) { + $.gallery_reload(); }); - } else { - $("#gOrganizeEditForm").tabs("destroy"); - $("#gOrganizeEditForm").empty(); - } -} - -function serializeItemIds(selector) { - var postData = ""; - $(selector).each(function(i) { - postData += "&item[]=" + $(this).attr("ref"); - }); - - return postData; -} -function submitCurrentForm(event) { - console.log("submitCurrentForm"); - return false; -} + //$(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); + //$(".gBranchText").droppable(treeDroppable); + //$(".gBranchText").click(organizeOpenFolder); + //retrieveMicroThumbs(item_id); + //showLoading("#gOrganizeDialog"); -function resetCurrentForm(event) { - console.log("resetCurrentForm"); - return false; -} + //$("#gMicroThumbPanel").droppable(thumbDroppable); + //$("#gMicroThumbPanel").selectable(selectable); + //$("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); -function createProgressDialog(title) { - $("body").append("
    " + - "
    " + - "" + - "" + - "" + - "
    "); - $("#gOrganizeProgressDialog").dialog({ - autoOpen: true, - autoResize: false, - modal: true, - resizable: false, - title: title - }); - - $(".gProgressBar").progressbar(); - $("#gOrganizeTaskPause").click(function(event) { - paused = true; - $("#gOrganizeTaskPause").hide(); - $("#gOrganizeTaskResume").show(); - $("#gOrganizeTaskCancel").show(); - $("#gMessage").empty().append(task.pauseMsg); - }); - $("#gOrganizeTaskResume").click(function(event) { - $("#gOrganizeTaskPause").show(); - $("#gOrganizeTaskResume").hide(); - $("#gOrganizeTaskCancel").hide(); - $("#gMessage").empty().append(task.resumeMsg); - operationCallback(); - //startRearrangeCallback(); - }); - $("#gOrganizeTaskCancel").click(function(event) { - $("#gOrganizeTaskPause").show(); - $("#gOrganizeTaskResume").hide(); - $("#gOrganizeTaskCancel").hide(); + $(window).bind("resize", _size_dialog); + }; - $.ajax({async: false, - success: function(data, textStatus) { - task = null; - paused = false; - transitItems = []; - $("#gMessage").empty().append("
    " + data.task.status + "
    "); - $("#gOrganizeProgressDialog").dialog("destroy").remove(); - }, - dataType: "json", - type: "POST", - url: get_organize_url("organize/cancelTask", {task_id: task.id}) - }); - }); -} + /** + * Dynamically initialize the organize dialog when it is displayed + */ + function _size_dialog(event) { + var size = $.getViewportSize(); + var h = $("#gOrganizeDialog").dialog("option", "minHeight"); + var sh = size.height() - 100; + var height = Math.max(sh, h); + var w = $("#gOrganizeDialog").dialog("option", "minWidth"); + var sw = size.width() - 100; + var width = Math.max(w, sw); + + $("#gOrganizeDialog").parent().css("height", height); + $("#gOrganizeDialog").parent().css("width", width); + $("#gOrganizeDialog").parent().css("left", "50px"); + $("#gOrganizeDialog").parent().css("top", "50px"); + + var heightMicroThumbPanel = height - 50; + heightMicroThumbPanel -= 2 * parseFloat($("#gOrganizeDialog").css("padding-bottom")); + heightMicroThumbPanel -= $("#gMessage").outerHeight(); + heightMicroThumbPanel = Math.floor(heightMicroThumbPanel); + $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); + + heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").outerHeight(); + $("#gMicroThumbPanel").height(heightMicroThumbPanel); + }; -// ************************************************************************** -// Functions that should probably be in a gallery namespace -function getViewportSize() { - return { - width : function() { - return window.innerWidth - || document.documentElement && document.documentElement.clientWidth - || document.body.clientWidth; - }, - height : function() { - return window.innerHeight - || document.documentElement && document.documentElement.clientHeight - || document.body.clientHeight; - } + function _dialog_close(event) { + event.preventDefault(); + $("#gOrganizeDialog").dialog("close"); }; -} -function displayAjaxError(error) { - $("body").append("
    " + error + "
    "); +})(jQuery); - $("#gAjaxError").dialog({ - autoOpen: true, - autoResize: false, - modal: true, - resizable: true, - width: 610, - height: $("#gDialog").height() - }); -} +$("document").ready(function() { + $("#gOrganizeLink").organize(); +}); diff --git a/modules/organize/js/organize_init.js b/modules/organize/js/organize_init.js deleted file mode 100644 index ed036fdb..00000000 --- a/modules/organize/js/organize_init.js +++ /dev/null @@ -1,29 +0,0 @@ -$("document").ready(function() { - $("#gOrganizeLink").click(function(event) { - event.preventDefault(); - var href = event.target.href; - - $("body").append('
    '); - - $("#gDialog").dialog({ - autoOpen: false, - autoResize: false, - modal: true, - resizable: false, - close: function () { - $("#gDialog").trigger("organize_close"); - $("#gDialog").dialog("destroy").remove(); - }, - zIndex: 75 - }); - - //showLoading("#gDialog"); - - $.get(href, function(data) { - $("#gDialog").html(data); - }); - return false; - }); -}); - - diff --git a/modules/organize/views/organize.html.php b/modules/organize/views/organize.html.php deleted file mode 100644 index 1686d255..00000000 --- a/modules/organize/views/organize.html.php +++ /dev/null @@ -1,53 +0,0 @@ - - - -
    - p::purify($item->title))) ?> -
    -
    -
    -
    -
    -

    -
    -
    -
    -
    -
    -
    -
    - -
    -
    "> -
      -
      -
      -
      -
      -
        -
      -
      -
      -
      -
      - -
      -
      -
      -
      -
      diff --git a/modules/organize/views/organize_album.html.php b/modules/organize/views/organize_album.html.php deleted file mode 100644 index ae2d5d51..00000000 --- a/modules/organize/views/organize_album.html.php +++ /dev/null @@ -1,17 +0,0 @@ - -
        -
      • - "> - - -
        gBranchText"> - title) ?> -
        -
        "> - -
        -
      • -
      diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php index c5839a44..8eced107 100644 --- a/modules/organize/views/organize_button_pane.html.php +++ b/modules/organize/views/organize_button_pane.html.php @@ -1,50 +1,5 @@ - -
      - - - +
      diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php new file mode 100644 index 00000000..cf3fd478 --- /dev/null +++ b/modules/organize/views/organize_dialog.html.php @@ -0,0 +1,37 @@ + +
      +

      p::purify($item->title))) ?>

      +
      +
      +
      +

      +
      +
      +
      +
      +
      +
      +
      +
        + +
      +
      +
      +
      "> +
        + +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + diff --git a/modules/organize/views/organize_edit.html.php b/modules/organize/views/organize_edit.html.php deleted file mode 100644 index 1adf290f..00000000 --- a/modules/organize/views/organize_edit.html.php +++ /dev/null @@ -1,14 +0,0 @@ - -
        - $pane): ?> -
      • - -
      - - 0): ?> - $pane): ?> -
      - - -
      - \ No newline at end of file diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php index c80696ad..e6b7aec0 100644 --- a/modules/organize/views/organize_thumb_grid.html.php +++ b/modules/organize/views/organize_thumb_grid.html.php @@ -1,12 +1,19 @@ $child): ?> - -is_album()): ?> - - -
    • -
      + + is_album()): ?> + + +
    • thumb_img(array("class" => "gThumbnail"), $thumbsize, true) ?> - -
    • + += 25): ?> + + \ No newline at end of file diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php index d2cdd957..28b45be0 100644 --- a/modules/organize/views/organize_tree.html.php +++ b/modules/organize/views/organize_tree.html.php @@ -1,4 +1,20 @@ - $child): ?> - +
    • + "> + + +
      gBranchText"> + title) ?> +
      + +
      + +
        "> + +
      + +
    • -- cgit v1.2.3 From 397468c47b8fc3fefeb54ff19a73980ed1dd8c20 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Wed, 5 Aug 2009 09:23:32 -0700 Subject: Revert "Checkpoint the organize module rewrite. At this point, it doesn't really do" This reverts commit a25f08d433d504a53763feb358a1aa7f5f798de6. --- modules/organize/controllers/organize.php | 507 ++++++++++++++- modules/organize/css/organize.css | 184 +++++- modules/organize/helpers/organize_task.php | 131 ++++ modules/organize/helpers/organize_theme.php | 3 +- modules/organize/js/organize.js | 697 ++++++++++++++++++--- modules/organize/js/organize_init.js | 29 + modules/organize/views/organize.html.php | 53 ++ modules/organize/views/organize_album.html.php | 17 + .../organize/views/organize_button_pane.html.php | 49 +- modules/organize/views/organize_dialog.html.php | 37 -- modules/organize/views/organize_edit.html.php | 14 + .../organize/views/organize_thumb_grid.html.php | 23 +- modules/organize/views/organize_tree.html.php | 20 +- 13 files changed, 1532 insertions(+), 232 deletions(-) create mode 100644 modules/organize/helpers/organize_task.php create mode 100644 modules/organize/js/organize_init.js create mode 100644 modules/organize/views/organize.html.php create mode 100644 modules/organize/views/organize_album.html.php delete mode 100644 modules/organize/views/organize_dialog.html.php create mode 100644 modules/organize/views/organize_edit.html.php (limited to 'modules/organize/helpers') diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index d7854c53..898be509 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -19,48 +19,54 @@ */ class Organize_Controller extends Controller { private static $_MICRO_THUMB_SIZE = 90; - private static $_MICRO_THUMB_PADDING = 10; + private static $_MICRO_THUMB_PADDING = 5; - function index($item_id) { + function index($item_id=1) { $item = ORM::factory("item", $item_id); $root = ($item->id == 1) ? $item : ORM::factory("item", 1); access::required("view", $item); access::required("edit", $item); - $v = new View("organize_dialog.html"); + $v = new View("organize.html"); $v->root = $root; $v->item = $item; - $v->album_tree = $this->_tree($item, $root); - $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item); + $v->album_tree = $this->tree($item, $root); $v->button_pane = new View("organize_button_pane.html"); - $buttons = (object)array("left" => array(), "middle" =>array(), "right" => array(), - "item" => $item); - module::event("organize_format_button_pane", $buttons); - - $v->button_pane->buttons = $buttons; print $v; } - function content($item_id, $offset=0) { + function content($item_id) { $item = ORM::factory("item", $item_id); access::required("view", $item); access::required("edit", $item); - $v = $this->_get_micro_thumb_grid($item, $offset); - print $v->__toString(); - } + $width = $this->input->get("width"); + $height = $this->input->get("height"); + $offset = $this->input->get("offset", 0); + $thumbsize = self::$_MICRO_THUMB_SIZE + 2 * self::$_MICRO_THUMB_PADDING; + $page_size = ceil($width / $thumbsize) * ceil($height / $thumbsize); - private function _get_micro_thumb_grid($item, $offset=0) { $v = new View("organize_thumb_grid.html"); - $v->item_id = $item->id; - $v->children = $item->children(25, $offset); + $v->children = $item->children($page_size, $offset); $v->thumbsize = self::$_MICRO_THUMB_SIZE; - $v->offset = $offset + 25; + $v->padding = self::$_MICRO_THUMB_PADDING; + $v->offset = $offset; + + print json_encode(array("count" => $v->children->count(), + "data" => $v->__toString())); + } + + function header($item_id) { + $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); - return $v; + print json_encode( + array("title" => p::purify($item->title), + "description" => empty($item->description) ? "" : p::purify($item->description))); } - private function _tree($item, $parent, $selected=false) { + function tree($item, $parent) { access::required("view", $item); access::required("edit", $item); @@ -69,25 +75,466 @@ class Organize_Controller extends Controller { ->orderby(array("title" => "ASC")) ->find_all(); - $v = new View("organize_tree.html"); + $v = new View("organize_album.html"); $v->album = $parent; + $v->selected = $parent->id == $item->id; + + if ($albums->count()) { + $v->album_icon = $parent->id == 1 || $v->selected ? "ui-icon-minus" : "ui-icon-plus"; + } else { + $v->album_icon = ""; + } - $v->selected = false; $v->children = ""; - $v->album_icon = "ui-icon-plus"; - if (!$selected) { - $v->selected = $parent->id == $item->id; + foreach ($albums as $album) { + $v->children .= $this->tree($item, $album); + } + return $v->__toString(); + } + + function startTask($operation, $id) { + access::verify_csrf(); + $items = $this->input->post("item"); + + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + + $definition = $this->_getOperationDefinition($item, $operation); + + $task_def = Task_Definition::factory() + ->callback("organize_task::run") + ->description($definition["description"]) + ->name($definition["name"]); + $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id, + "type" => $definition["type"], + "batch" => ceil(count($items) * .1))); + // @todo If there is only one item then call task_run($task->id); Maybe even change js so + // we can call finish as well. + batch::start(); + print json_encode( + array("result" => "started", + "runningMsg" => $definition["runningMsg"], + "pauseMsg" => "
      {$definition['pauseMsg']}
      ", + "resumeMsg" => "
      {$definition['resumeMsg']}
      ", + "task" => array("id" => $task->id, + "percent_complete" => $task->percent_complete, + "type" => $task->get("type"), + "status" => $task->status, + "state" => $task->state, + "done" => $task->done))); + } + + function runTask($task_id) { + access::verify_csrf(); + + $task = task::run($task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } + + print json_encode(array("result" => $task->done ? $task->state : "in_progress", + "task" => array("id" => $task->id, + "percent_complete" => $task->percent_complete, + "type" => $task->get("type"), + "post_process" => $task->get("post_process"), + "status" => $task->status, + "state" => $task->state, + "done" => $task->done))); + } + + function finishTask($task_id) { + access::verify_csrf(); + + $task = ORM::factory("task", $task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } - if ($albums->count() && ($parent->id == 1 || $v->selected) ) { - $v->album_icon = "ui-icon-minus"; + if ($task->done) { + $item = ORM::factory("item", (int)$task->get("target")); + $type = $task->get("type"); + switch ($type) { + case "albumCover": + $task->status = t("Album cover set for '%album'", array("album" => $item->title)); + break; + case "delete": + $task->status = t("Selection deleted"); + break; + case "move": + $task->status = t("Move to '%album' completed", array("album" => $item->title)); + break; + case "rearrange": + try { + $item->sort_column = "weight"; + $item->save(); + $task->status = t("Rearrange for '%album' completed", array("album" => $item->title)); + } catch (Exception $e) { + $task->state = "error"; + $task->status = $e->getMessage(); + } + break; + case "rotateCcw": + case "rotateCw": + $task->status = t("Rotation completed"); + break; } + $task->save(); + } - foreach ($albums as $album) { - $v->children .= $this->_tree($item, $album, $v->selected); + batch::stop(); + print json_encode(array("result" => "success", + "task" => array( + "id" => $task->id, + "percent_complete" => $task->percent_complete, + "status" => $task->status, + "state" => $task->state, + "done" => $task->done))); + } + + function cancelTask($task_id) { + access::verify_csrf(); + + $task = ORM::factory("task", $task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } + + if (!$task->done) { + $task->done = 1; + $task->state = "cancelled"; + $type = $task->get("type"); + switch ($type) { + case "move": + $task->status = t("Move to album was cancelled prior to completion"); + break; + case "rearrange": + $task->status = t("Rearrange album was cancelled prior to completion"); + case "rotateCcw": + case "rotateCw": + $task->status = t("Rotation was cancelled prior to completion"); + break; } + $task->save(); } - return $v->__toString(); + + batch::stop(); + print json_encode(array("result" => "success", + "task" => array( + "id" => $task->id, + "percent_complete" => $task->percent_complete, + "status" => $task->status, + "state" => $task->state, + "done" => $task->done))); + } + + function editForm() { + $event_parms = new stdClass(); + $event_parms->panes = array(); + $event_parms->itemids = $this->input->get("item"); + + // The following code should be done more dynamically i.e. use the event mechanism + if (count($event_parms->itemids) == 1) { + $item = ORM::factory("item") + ->in("id", $event_parms->itemids[0]) + ->find(); + + access::required("view", $item); + access::required("edit", $item); + + $event_parms->panes[] = array( + "label" => $item->is_album() ? t("Edit Album") : t("Edit Photo"), + "content" => organize::get_general_edit_form($item)); + + if ($item->is_album()) { + $event_parms->panes[] = array("label" => t("Sort Order"), + "content" => organize::get_sort_edit_form($item)); + } + } + + $event_parms->panes[] = array("label" => t("Manage Tags"), + "content" => organize::get_tag_form($event_parms->itemids)); + + $v = new View("organize_edit.html"); + $v->panes = $event_parms->panes; + print $v->render(); + } + + // Handlers for the album/photo edit. Probably should be in modules/gallery + public function general() { + access::verify_csrf(); + + $itemids = $this->input->post("item"); + $item = ORM::factory("item") + ->in("id", $itemids[0]) + ->find(); + access::required("view", $item); + access::required("edit", $item); + + $form = organize::get_general_edit_form($item); + if ($form->validate()) { + $orig = clone $item; + $item->title = $form->title->value; + $item->description = $form->description->value; + $item->rename($form->dirname->value); + $item->save(); + + if ($item->is_album()) { + log::success("content", "Updated album", "id\">view"); + $message = t("Saved album %album_title", array("album_title" => p::purify($item->title))); + } else { + log::success("content", "Updated photo", "id\">view"); + $message = t("Saved photo %photo_title", array("photo_title" => p::purify($item->title))); + } + print json_encode(array("form" => $form->__toString(), "message" => $message)); + } else { + print json_encode(array("form" => $form->__toString())); + } + } + + public function reset_general() { + $itemids = Input::instance()->get("item"); + $item = ORM::factory("item") + ->in("id", $itemids[0]) + ->find(); + access::required("view", $item); + access::required("edit", $item); + + print organize::get_general_edit_form($item); + } + + public function sort() { + access::verify_csrf(); + + $itemids = $this->input->post("item"); + $item = ORM::factory("item") + ->in("id", $itemids[0]) + ->find(); + access::required("view", $item); + access::required("edit", $item); + + $form = organize::get_sort_edit_form($item); + if ($form->validate()) { + $orig = clone $item; + $item->sort_column = $form->column->value; + $item->sort_order = $form->direction->value; + $item->save(); + + log::success("content", "Updated album", "id\">view"); + $message = t("Saved album %album_title", array("album_title" => p::purify($item->title))); + print json_encode(array("form" => $form->__toString(), "message" => $message)); + } else { + print json_encode(array("form" => $form->__toString())); + } + } + + public function reset_sort() { + $itemids = Input::instance()->get("item"); + $item = ORM::factory("item") + ->in("id", $itemids[0]) + ->find(); + access::required("view", $item); + access::required("edit", $item); + + print organize::get_sort_edit_form($item); + } + + public function edit_tags() { + access::verify_csrf(); + + $itemids = explode("|", $this->input->post("item")); + $form = organize::get_tag_form($itemids); + $old_tags = $form->tags->value; + if ($form->validate()) { + + $old_tags = preg_split("/[;,\s]+/", $old_tags); + sort($old_tags); + $new_tags = preg_split("/[;,\s]+/", $form->tags->value); + sort($new_tags); + + $HIGH_VALUE_STRING = "\256"; + for ($old_index = $new_index = 0;;) { + $old_tag = $old_index >= count($old_tags) ? $HIGH_VALUE_STRING : $old_tags[$old_index]; + $new_tag = $new_index >= count($new_tags) ? $HIGH_VALUE_STRING : $new_tags[$new_index]; + if ($old_tag == $HIGH_VALUE_STRING && $new_tag == $HIGH_VALUE_STRING) { + break; + } + $matches = array(); + $old_star = false; + if (preg_match("/(.*)(\*)$/", $old_tag, $matches)) { + $old_star = true; + $old_tag = $matches[1]; + } + $new_star = false; + if (preg_match("/(.*)(\*)$/", $new_tag, $matches)) { + $new_star = true; + $new_tag = $matches[1]; + } + if ($old_tag > $new_tag) { + // Its missing in the old list so add it + $this->_add_tag($new_tag, $itemids); + $new_index++; + } else if ($old_tag < $new_tag) { + // Its missing in the new list so its been removed + $this->_delete_tag($old_tag, $itemids); + $old_index++; + } else { + if ($old_star && !$new_star) { + // User wants tag to apply to all items, originally only on some of selected + $this->_update_tag($old_tag, $itemids); + } // Not changed ignore + $old_index++; + $new_index++; + } + } + } + print json_encode(array("form" => $form->__toString(), "message" => t("Tags updated"))); } + public function reset_edit_tags() { + $itemids = $this->input->get("item"); + + print organize::get_tag_form($itemids); + } + + private function _add_tag($new_tag, $itemids) { + // Super lame security stopgap. This code is going to get rewritten anyway. + foreach ($itemids as $item_id) { + $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); + } + $tag = ORM::factory("tag") + ->where("name", $new_tag) + ->find(); + if ($tag->loaded) { + $tag->count += count($itemids); + } else { + $tag->name = $new_tag; + $tag->count = count($itemids); + } + $tag->save(); + + $db = Database::instance(); + foreach ($itemids as $item_id) { + $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); + } + } + + private function _delete_tag($new_tag, $itemids) { + // Super lame security stopgap. This code is going to get rewritten anyway. + foreach ($itemids as $item_id) { + $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); + } + + $tag = ORM::factory("tag") + ->where("name", $new_tag) + ->find(); + $tag->count -= count($itemids); + if ($tag->count > 0) { + $tag->save(); + } else { + $tag->delete(); + } + + $ids = implode(", ", $itemids); + Database::instance()->query( + "DELETE FROM {items_tags} WHERE tag_id = {$tag->id} AND item_id IN ($ids);"); + } + + private function _update_tag($new_tag, $itemids) { + // Super lame security stopgap. This code is going to get rewritten anyway. + foreach ($itemids as $item_id) { + $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); + } + + $tag = ORM::factory("tag") + ->where("name", $new_tag) + ->find(); + + $db = Database::instance(); + $ids = implode(", ", $itemids); + $result = $db->query( + "SELECT item_id FROM {items_tags} + WHERE tag_id = {$tag->id} + AND item_id IN ($ids)"); + + $add_items = array_fill_keys($itemids, 1); + foreach($result as $row) { + unset($add_items[$row->item_id]); + } + $add_items = array_keys($add_items); + $tag->count += count($add_items); + $tag->save(); + foreach ($add_items as $item_id) { + $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); + } + } + + private function _getOperationDefinition($item, $operation) { + switch ($operation) { + case "move": + return array("description" => + t("Move albums and photos to '%name'", array("name" => $item->title)), + "name" => t("Move to '%name'", array("name" => $item->title)), + "type" => "move", + "runningMsg" => t("Move in progress"), + "pauseMsg" => t("The move operation was paused"), + "resumeMsg" => t("The move operation was resumed")); + break; + + case "rearrange": + return array("description" => t("Rearrange the order of albums and photos"), + "name" => t("Rearrange: %name", array("name" => $item->title)), + "type" => "rearrange", + "runningMsg" => t("Rearrange in progress"), + "pauseMsg" => t("The rearrange operation was paused"), + "resumeMsg" => t("The rearrange operation was resumed")); + break; + + case "rotateCcw": + return array("description" => t("Rotate the selected photos counter clockwise"), + "name" => t("Rotate images in %name", array("name" => $item->title)), + "type" => "rotateCcw", + "runningMsg" => t("Rotate Counter Clockwise in progress"), + "pauseMsg" => t("The rotate operation was paused"), + "resumeMsg" => t("The rotate operation was resumed")); + break; + + case "rotateCw": + return array("description" => t("Rotate the selected photos clockwise"), + "name" => t("Rotate images in %name", array("name" => $item->title)), + "type" => "rotateCw", + "runningMsg" => t("Rotate Clockwise in progress"), + "pauseMsg" => t("The rotate operation was paused"), + "resumeMsg" => t("The rotate operation was resumed")); + break; + + case "delete": + return array("description" => t("Delete selected photos / albums"), + "name" => t("Delete images in %name", array("name" => $item->title)), + "type" => "delete", + "runningMsg" => t("Delete images in progress"), + "pauseMsg" => t("The delete operation was paused"), + "resumeMsg" => t("The delete operation was resumed")); + break; + + case "albumCover": + return array("description" => t("Reset Album Cover"), + "name" => t("Reset Album cover for %name", array("name" => $item->title)), + "type" => "albumCover", + "runningMsg" => t("Reset Album Cover in progress"), + "pauseMsg" => t("Reset album cover was paused"), + "resumeMsg" => t("Reset album cover was resumed")); + break; + + default: + throw new Exception("Operation '$operation' is not implmented"); + } + } } diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index 4568a707..e58cd5a5 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -1,44 +1,41 @@ +/* @todo move to theme css */ /******************************************************************* * Dialog wide stylings */ -#gOrganizeDialog { - text-align: left; -} - -#gOrganize { - overflow: hidden; +#gMessage { + margin-bottom: .4em; } -#gOrganize .yui-u { - width: 75%; +#gMessage .gInfo { + background-color: transparent; + background-image: none; + padding-left: .4em; } -#gOrganize .yui-gf .first { - width: 25%; +#gOrganizeProgressDialog { + text-align: left; } -#gOrganize .yui-gf #gMessage { - margin-bottom: .4em; - width: 75%; +#gDialog .yui-gf div.first { + width: 20%; } -#gMessage .gInfo { - font-weight: bold; - padding-left: 2em; +#gDialog .yui-gf .yui-u { + width: 80%; } - /******************************************************************* * Album Tree styling */ #gOrganizeTreeContainer { - overflow: auto; + overflow-y: auto; margin: 0 !important; padding: 0 !important; } -#gOrganizeTreeContainer ul ul li { - padding-left: 1.2em; +#gOrganizeAlbumDescription { + height: 2em; + overflow-y: auto; } .gBranchSelected { @@ -48,21 +45,37 @@ padding: .3em 0; } +.gBranchDroppable { + border: 1px dotted; +} + +.gBranchText { + cursor: pointer; + width: auto; +} + .gBranchCollapsed { display: none; } -.gOrganizeBranch span { - cursor: pointer; +.gBranchEmpty { + visibility: hidden; } -.gBranchText { - cursor: pointer; - width: auto; +#gOrganizeTreeContainer ul ul li { + padding-left: 1.2em; } + /******************************************************************* * Album Panel Styles */ + +#gMicroThumbUnselectAll, +#gMicroThumbSelectAll { + font-size: 1em; + font-weight: bold; +} + #gMicroThumbPanel { margin: 0 !important; padding: 0 !important; @@ -70,27 +83,33 @@ border: 1px solid #999 !important; border-top: none !important; border-left: none !important; + margin-left: -1em !important; overflow-x: hidden; overflow-y: auto; } #gMicroThumbGrid { + padding: .5em; } .gMicroThumbContainer { -// padding: 0 .5em; -// opacity: .4; -} - -.gMicroThumb { display: block; float: left; -// font-size: .7em; + font-size: .7em; height: 9em; margin-bottom: 1em; margin-left: 1em; - text-align: center; + opacity: .4; + padding: 0 .5em; +} + +.gMicroThumb { + height: 9em; width: 9em; + background-color: #fff; + display: block; + float: left; + text-align: center; } #gMicroThumbPanel #gMicroThumbGrid .gAlbum { @@ -101,12 +120,35 @@ opacity: 1; } +.gMicroThumbContainer.ui-selected { + opacity: 1; +} + +#gDragHelper .gMicroThumbGrid { + background-color: transparent; + padding: 0; + overflow: visible; +} + +#gDragHelper .gMicroThumbContainer { + display: block; + margin: 0; + padding: 0; +} + +#gDragHelper .gMicroThumb { + background-color: transparent; + height: auto; + width: auto; +} + + /**************************************************************** * Organize Edit Drawer styling */ #gOrganizeEditDrawer { background-color: #13A; - width: 100% !important; + width: 90%; } #gOrganizeEditDrawerPanel { @@ -162,3 +204,79 @@ height: 30px; width: 15px; } + +#gOrganizeFormButtons { + bottom: 0.5em; +} + +#gOrganizeFormButtons .submit { + display: inline; + float: none; + left: 0.5em; + position: relative; +} + +/* yui-u gives 80% width, but then we wrap so do it ourselves */ +#gOrganizeEditForm { + float: right; + width: 79%; + // height: 100px; +} + +#gOrganizeFormThumbs { + overflow: hidden; +} + +#gOrganizeFormThumbs div { + margin: 0; + text-align: center; + background: transparent none repeat scroll 0 0; +} + +#gOrganizeFormThumbs .gMicroThumbContainer { + display: block; + float: left; + opacity: 1; + position: absolute; +} + +/**************************************************************** + * Organize Edit From tabs styling + */ +#gOrganizeEditForm.ui-tabs .ui-tabs-hide { + display: block !important; + left: -10000px; + position: absolute; +} + +#gOrganizeEditForm.ui-widget { + font-size: .75em; +} + +.gOrganizeEditPane { + height: 135px; + overflow-y: auto; +} + +.textbox, +.textarea { + border: 1px solid #e8e8e8; + border-top-color: #ccc; + border-left-color: #ccc; + color: #333; + width: 100%; +} + +.textarea { + height: 6em; +} + +.textbox { + height: 1.3em; + width: 50% +} + +.gTagGroup { + float:left; + margin: .5em; +} diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php new file mode 100644 index 00000000..dc474818 --- /dev/null +++ b/modules/organize/helpers/organize_task.php @@ -0,0 +1,131 @@ +context); + $taskType = $context["type"]; + + try { + $target = ORM::factory("item", $context["target"]); + $total = count($context["items"]); + $stop = min($total - $context["position"], $context["batch"]); + $context["post_process"] = array(); + for ($offset = 0; $offset < $stop; $offset++) { + $current_id = $context["position"] + $offset; + $id = $context["items"][$current_id]; + switch ($taskType) { + case "move": + $source = ORM::factory("item", $id); + access::required("view", $source); + access::required("view", $target); + access::required("edit", $source); + access::required("edit", $target); + + item::move($source, $target); + break; + + case "rearrange": + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + + Database::instance() + ->query("Update {items} set weight = {$context["position"]} where id=$id;"); + break; + + case "rotateCcw": + case "rotateCw": + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + + if ($item->is_photo()) { + $context["post_process"]["reload"][] = + self::_do_rotation($item, $taskType == "rotateCcw" ? -90 : 90); + } + break; + + case "albumCover": + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("view", $item->parent()); + access::required("edit", $item->parent()); + + item::make_album_cover($item); + break; + + case "delete": + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + + $item->delete(); + $context["post_process"]["remove"][] = array("id" => $id); + break; + + default: + throw new Exception("Task '$taskType' is not implemented"); + } + } + $context["position"] += $stop; + $task->state = "success"; + } catch(Exception $e) { + $task->status = $e->getMessage(); + $task->state = "error"; + $task->save(); + throw $e; + } + $task->context = serialize($context); + $total = count($context["items"]); + $task->percent_complete = $context["position"] / (float)$total * 100; + $task->done = $context["position"] == $total || $task->state == "error"; + } + + private static function _do_rotation($item, $degrees) { + // This code is copied from Quick_Controller::rotate + graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); + + list($item->width, $item->height) = getimagesize($item->file_path()); + $item->resize_dirty= 1; + $item->thumb_dirty= 1; + $item->save(); + + graphics::generate($item); + + $parent = $item->parent(); + if ($parent->album_cover_item_id == $item->id) { + copy($item->thumb_path(), $parent->thumb_path()); + $parent->thumb_width = $item->thumb_width; + $parent->thumb_height = $item->thumb_height; + $parent->save(); + } + list ($height, $width) = $item->scale_dimensions(90); + $margin_top = (90 - $height) / 20; + + return array("src" => $item->thumb_url() . "?rnd=" . rand(), + "id" => $item->id, + "marginTop" => "{$margin_top}em", "width" => $width, "height" => $height); + } +} \ No newline at end of file diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index f01ab88b..e4feba2b 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -19,7 +19,8 @@ */ class organize_theme { static function head($theme) { - //$theme->script("organize_init.js"); + // @tdo remove the addition css and organize.js (just here to test) + $theme->script("organize_init.js"); $theme->script("organize.js"); $theme->css("organize.css"); } diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index e84afd03..12d8a5b5 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -1,116 +1,621 @@ -(function($) { - $.fn.organize = function(options) { - var size = $.getViewportSize(); - var height = size.height() - 100; // Leave 50 pixels on the top and bottom of the dialog - var width = size.width() - 100; // Leave 50 pixels on the left and right of the dialog - var opts = $.extend({}, $.fn.organize.defaults, {width: width, height: height}, options); - return this.each(function() { - $(this).click(function(event) { - var href = event.target.href; - var size = $.getViewportSize(); - - $("body").append('
      '); - - $("#gOrganizeDialog").dialog(opts); - // Pass the approx height and width of the thumb grid to optimize thumb retrieval - $.get(href, _init); - return false; +/* + * @todo Trap resize of dialog and resize the child areas (tree, grid and edit form) + */ +var url; +var paused = false; +var task = null; +var transitItems = []; +var heightMicroThumbPanel; + +// ************************************************************************** +// JQuery UI Widgets +// Draggable +var draggable = { + handle: ".gMicroThumbContainer.ui-selected", + revert: true, + zindex: 2000, + distance: 10, + helper: function(event, ui) { + if (!$(event.currentTarget).hasClass("ui-selected")) { + $(event.currentTarget).addClass("ui-selected"); + setDrawerButtonState(); + } + $("#gMicroThumbPanel").append("
        "); + var beginTop = event.pageY; + var beginLeft = event.pageX; + var zindex = $(".gMicroThumbContainer").draggable("option", "zindex"); + $("#gDragHelper").css('top', event.pageY - 22.5); + $("#gDragHelper").css('left', event.pageX + 22.5); + var placeHolder = $(this).clone(); + $(placeHolder).attr("id", "gPlaceHolder"); + $(placeHolder).css("visibility", "hidden"); + $(placeHolder).removeClass("ui-selected"); + $(placeHolder).removeClass("ui-draggable"); + $(this).after(placeHolder); + + $("li.ui-selected").each(function(i) { + var clone = $(this).clone(); + $(clone).attr("id", "drag_clone_" + $(this).attr("ref")); + $("#gDragHelper ul").append(clone); + $(clone).css("position", "absolute"); + $(clone).css("top", beginTop); + $(clone).css("left", beginLeft); + $(clone).css("z-index", zindex--); + $(this).hide(); + + var children = $(clone).find(".gMicroThumb .gThumbnail"); + var width = new String(children.css("width")).replace(/[^0-9]/g,"") * .5; + var height = new String(children.css("height")).replace(/[^0-9]/g,"") * .5; + var marginTop = new String(children.css("margin-top")).replace(/[^\.0-9]/g,"") * .5; + children.attr("width", width); + children.attr("height", height); + children.css("margin-top", marginTop); + if (i < 9) { + beginTop -= 5; + beginLeft += 5; + } + }); + return $("#gDragHelper"); + }, + stop: function(event, ui) { + $("#gDragHelper li").each(function(i) { + $("#thumb_" + $(this).attr("ref")).show(); + }); + $(".gMicroThumbContainer.ui-selected").css("z-index", null); + $("#gDragHelper").remove(); + $("#gPlaceHolder").remove(); + } +}; + +// Thumbnail Grid Droppable +var thumbDroppable = { + tolerance: "pointer", + over: function(event, ui) { + $("#gPlaceHolder").show(); + }, + out: function(event, ui) { + $("#gPlaceHolder").hide(); + }, + drop: function(event, ui) { + $("#gDragHelper").hide(); + $("#gPlaceHolder").hide(); + var newOrder = ""; + $("#gMicroThumbGrid .gMicroThumbContainer").each(function(i) { + if ($(this).attr("id") == "gPlaceHolder") { + $("#gDragHelper li").each(function(i) { + newOrder += "&item[]=" + $(this).attr("ref"); + }); + } else if ($(this).css("display") != "none") { + newOrder += "&item[]=" + $(this).attr("ref"); + } else { + // If its not displayed then its one of the ones being moved so ignore. + } + }); + $("#gDragHelper li").each(function(i) { + $("#gPlaceHolder").before($("#thumb_" + $(this).attr("ref")).show()); + }); + $.ajax({ + data: newOrder, + dataType: "json", + success: operationCallback, + type: "POST", + url: get_organize_url("organize/startTask/rearrange", {item_id: item_id}) + }); + } +}; + +// Album Tree Droppable +var treeDroppable = { + tolerance: "pointer", + greedy: true, + hoverClass: "gBranchDroppable", + drop: function(event, ui) { + $("#gDragHelper").hide(); + var targetItemId = $(this).attr("ref"); + if ($(this).hasClass("gBranchSelected")) { + $("#gMessage").empty().append(INVALID_DROP_TARGET); + ui.draggable.trigger("stop", event); + return false; + } + var postData = serializeItemIds("#gDragHelper li"); + var okToMove = true; + $("#gDragHelper li").each(function(i) { + okToMove &= targetItemId != $(this).attr("ref"); + }); + if (!okToMove) { + $("#gMessage").empty().append(INVALID_DROP_TARGET); + ui.draggable.trigger("stop", event); + return false; + } + $("#gDragHelper li").each(function(i) { + $("#thumb_" + $(this).attr("ref")).remove(); + }); + $.ajax({ + data: postData, + dataType: "json", + success: operationCallback, + type: "POST", + url: get_organize_url("organize/startTask/move", {item_id: targetItemId}) + }); + return true; + } +}; + +// Selectable +var selectable = { + filter: ".gMicroThumbContainer", + selected: function(event, ui) { + setDrawerButtonState(); + }, + unselected: function(event, ui) { + setDrawerButtonState(); + }, + stop: function(event, ui) { + getEditForm(); + } +}; + +// ************************************************************************** +// Event Handlers +// MicroThumbContainer mouseup +var onMicroThumbContainerMouseup = function(event) { + // For simplicity always remove the ui-selected class. If it was unselected + // it will get added back + $(this).toggleClass("ui-selected"); + + setDrawerButtonState(); + if ($("#gMicroThumbGrid li.ui-selected").length > 0) { + getEditForm(); + } +}; + +// MicroThumbContainer mousemove +var onMicroThumbContainerMousemove = function(event) { + if ($("#gDragHelper").length > 0 && $(this).attr("id") != "gPlaceHolder") { + if (event.pageX < $(this).offset().left + $(this).width() / 2) { + $(this).before($("#gPlaceHolder")); + } else { + $(this).after($("#gPlaceHolder")); + } + var container = $("#gMicroThumbPanel").get(0); + var scrollHeight = container.scrollHeight; + var scrollTop = container.scrollTop; + var height = $(container).height(); + if (event.pageY > height + scrollTop) { + container.scrollTop = this.offsetTop; + } else if (event.pageY < scrollTop) { + container.scrollTop -= height; + } + } +}; + +// Handle click events on the buttons on the drawer handle +function drawerHandleButtonsClick(event) { + event.preventDefault(); + if (!$(this).attr("disabled")) { + var operation = $(this).attr("ref"); + switch (operation) { + case "edit": + case "close": + $("#gOrganizeEditDrawerPanel").animate( + {"height": "toggle", "display": "block"}, + {duration: "fast", + complete: function() { + setSelectedThumbs(); + if (operation == "close") { + $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "inline-block"); + $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "none"); + $("#gOrganizeEditHandleButtonsMiddle a").css("display", "none"); + } else { + $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "none"); + $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "inline-block"); + $("#gOrganizeEditHandleButtonsMiddle a").css("display", "inline-block"); + } + }, + step: function() { + $("#gMicroThumbPanel").height(heightMicroThumbPanel - $(this).height()); + } + }); + break; + case "select-all": + $("#gMicroThumbGrid li").addClass("ui-selected"); + $("#gMicroThumbSelectAll").hide(); + $("#gMicroThumbUnselectAll").show(); + setDrawerButtonState(); + getEditForm(); + break; + case "unselect-all": + $("#gMicroThumbGrid li").removeClass("ui-selected"); + $("#gMicroThumbSelectAll").show(); + $("#gMicroThumbUnselectAll").hide(); + setDrawerButtonState(); + break; + case "done": + $("#gDialog").dialog("close"); + break; + case "submit": + var currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); + var form = $("#pane-"+currentTab+" form"); + var url = $(form).attr("action") + .replace("__FUNCTION__", $(form).attr("ref")); + $.ajax({ + data: $(form).serialize(), + dataType: "json", + success: function (data, textStatus) { + $("#pane-"+currentTab).children("form").replaceWith(data.form); + if (data.message) { + $("#gMessage").empty().append("
        " + data.message + "
        "); + } + }, + type: "POST", + url: url + }); + break; + case "reset": + currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); + form = $("#pane-"+currentTab+" form"); + $.ajax({ + data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), + dataType: "html", + success: function (data, textStatus) { + $("#pane-"+currentTab + " form").replaceWith(data); + }, + type: "GET", + url: $(form).attr("action").replace("__FUNCTION__", "reset_" + $(form).attr("ref")) }); + break; + case "delete": + if (!confirm(CONFIRM_DELETE)) { + break; + } + default: + $.ajax({ + data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), + dataType: "json", + success: operationCallback, + type: "POST", + url: get_organize_url("organize/startTask/" + operation, {item_id: item_id}) + }); + break; + } + } +}; + +// ************************************************************************** +// AJAX Callbacks +// MicroThumbContainer click +var getMicroThumbsCallback = function(json, textStatus) { + if (json.count > 0) { + $("#gMicroThumbGrid").append(json.data); + retrieveMicroThumbs(); + $(".gMicroThumbContainer").mouseup(onMicroThumbContainerMouseup); + $(".gMicroThumbContainer").mousemove(onMicroThumbContainerMousemove); + $(".gMicroThumbContainer").draggable(draggable); + } +}; + +var operationCallback = function (data, textStatus) { + var done = false; + if (!paused) { + createProgressDialog(data.runningMsg); + task = data.task; + task.pauseMsg = data.pauseMsg; + task.resumeMsg = data.resumeMsg; + done = data.task.done; + } + $(".gMicroThumbContainer").draggable("disable"); + paused = false; + while (!done && !paused) { + $.ajax({async: false, + success: function(data, textStatus) { + $(".gProgressBar").progressbar("value", data.task.percent_complete); + done = data.task.done; + if (data.task.post_process.reload) { + $.each(data.task.post_process.reload, function() { + var selector = "#gMicroThumb-" + this.id + " img"; + $(selector).attr("height", this.height); + $(selector).attr("width", this.width); + $(selector).attr("src", this.src); + $(selector).css("margin-top", this.marginTop); + }); + } + if (data.task.post_process.remove) { + $.each(data.task.post_process.remove, function() { + $("#thumb_" + this.id).remove(); + }); + } + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + paused = true; + displayAjaxError(XMLHttpRequest.responseText); + }, + dataType: "json", + type: "POST", + url: get_organize_url("organize/runTask", {task_id: task.id}) }); - }; + } + if (!paused) { + $("#gOrganizeProgressDialog").dialog("destroy").remove(); + $.ajax({async: false, + success: function(data, textStatus) { + setDrawerButtonState(); + task = null; + $("#gMessage").empty().append("
        " + data.task.status + "
        "); + }, + dataType: "json", + type: "POST", + url: get_organize_url("organize/finishTask", {task_id: task.id}) + }); + } + $(".gMicroThumbContainer").draggable("enable"); +}; - $.fn.organize.defaults = { - autoOpen: false, - modal: true, - resizable: false, - minWidth: 600, - minHeight: 500, - position: "center", - close: function () { - $("#gOrganizeDialog").trigger("organize_close"); - $("#gOrganizeDialog").dialog("destroy").remove(); - }, - zIndex: 75 - }; +// ************************************************************************** + +/** + * Dynamically initialize the organize dialog when it is displayed + */ +function organize_dialog_init() { + var size = getViewportSize(); + heightMicroThumbPanel = size.height() - 100; + var width = size.width() - 100; + + // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 + $(".sf-menu li.sfHover ul").css("z-index", 70); + + $("#gDialog").dialog("option", "width", width); + $("#gDialog").dialog("option", "height", heightMicroThumbPanel); + + $("#gDialog").dialog("open"); + if ($("#gDialog h1").length) { + $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html()); + } else if ($("#gDialog fieldset legend").length) { + $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html()); + } + + $("#gDialog").bind("organize_close", function(target) { + $.gallery_reload(); + }); + + heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-top")); + heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-bottom")); + heightMicroThumbPanel -= $("#gMicroThumbPanel").position().top; + heightMicroThumbPanel -= $("#gDialog #ft").height(); + heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").height(); + heightMicroThumbPanel = Math.round(heightMicroThumbPanel); + + $("#gMicroThumbPanel").height(heightMicroThumbPanel); + $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); + + $(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); + $(".gBranchText").droppable(treeDroppable); + $(".gBranchText").click(organizeOpenFolder); + retrieveMicroThumbs(item_id); + //showLoading("#gDialog"); - /** - * Dynamically initialize the organize dialog when it is displayed - */ - function _init(data) { + $("#gMicroThumbPanel").droppable(thumbDroppable); + $("#gMicroThumbPanel").selectable(selectable); + $("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); +} - // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 - $(".sf-menu li.sfHover ul").css("z-index", 70); +function retrieveMicroThumbs() { + var offset = $("#gMicroThumbGrid li").length; + if (url == null) { + var grid_width = $("#gMicroThumbPanel").width(); + url = $("#gMicroThumbPanel").attr("ref"); + url = url.replace("__WIDTH__", grid_width); + url = url.replace("__HEIGHT__", heightMicroThumbPanel); + } + var url_data = url.replace("__OFFSET__", offset); + url_data = url_data.replace("__ITEM_ID__", item_id); + $.getJSON(url_data, getMicroThumbsCallback); +} - $("#gOrganizeDialog").html(data); - $("#gOrganizeDialog").dialog("open"); +function organizeToggleChildren(event) { + var id = $(this).attr("ref"); + var span_children = $("#gOrganizeChildren-" + id); + if ($(this).hasClass("ui-icon-plus")) { + $(this).removeClass("ui-icon-plus"); + $(this).addClass("ui-icon-minus"); + $("#gOrganizeChildren-" + id).removeClass("gBranchCollapsed"); + } else { + $(this).removeClass("ui-icon-minus"); + $(this).addClass("ui-icon-plus"); + $("#gOrganizeChildren-" + id).addClass("gBranchCollapsed"); + } + event.preventDefault(); +} - var heightMicroThumbPanel = $("#gOrganizeDialog").innerHeight(); - heightMicroThumbPanel -= 2 * parseFloat($("#gOrganizeDialog").css("padding-bottom")); - heightMicroThumbPanel -= $("#gMessage").outerHeight(); - heightMicroThumbPanel = Math.floor(heightMicroThumbPanel); - $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); +function organizeOpenFolder(event) { + var selected = $(".gBranchSelected"); + if ($(selected).attr("id") != $(this).attr("id")) { + $(selected).removeClass("gBranchSelected"); + $(this).addClass("gBranchSelected"); + item_id = $(this).attr("ref"); + $("#gMicroThumbGrid").empty(); + retrieveMicroThumbs(); + } + event.preventDefault(); +} - heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").outerHeight(); - $("#gMicroThumbPanel").height(heightMicroThumbPanel); +function get_organize_url(uri, parms) { + var url = rearrangeUrl; + url = url.replace("__URI__", uri); + url = url.replace("__ITEM_ID__", !parms.item_id ? "" : parms.item_id); + url += (parms.item_id && parms.task_id) ? "/" : ""; + url = url.replace("__TASK_ID__", !parms.task_id ? "" : parms.task_id); + return url; +} - if ($("#gOrganizeDialog h1").length) { - $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog h1:eq(0)").html()); - } else if ($("#gOrganizeDialog fieldset legend").length) { - $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog fieldset legend:eq(0)").html()); +/** + * Set the enabled/disabled state of the buttons. The album cover is only enabled if + * there is only 1 image selected + */ +function setDrawerButtonState() { + $("#gOrganizeFormThumbStack").empty(); + $("#gOrganizeEditForm").empty(); + var selectedCount = $("#gMicroThumbGrid li.ui-selected").length; + if (selectedCount) { + $("#gOrganizeEditHandleButtonsLeft a").removeAttr("disabled"); + $("#gOrganizeEditHandleButtonsLeft a").removeClass("ui-state-disabled"); + + if (selectedCount > 1) { + $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").attr("disabled", true); + $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").addClass("ui-state-disabled"); + } + setSelectedThumbs(); + } else { + if ($("#gOrganizeEditDrawerPanel::visible").length) { + $("#gOrganizeEditHandleButtonsLeft a[ref='close']").trigger("click"); } + $("#gOrganizeEditHandleButtonsLeft a").attr("disabled", true); + $("#gOrganizeEditHandleButtonsLeft a").addClass("ui-state-disabled"); + } +} - $("#gOrganizeDialog #gMicroThumbDone").click(_dialog_close); - $("#gOrganizeDialog").bind("organize_close", function(target) { - $.gallery_reload(); +function setSelectedThumbs() { + if (!$("#gOrganizeEditDrawerPanel::visible").length) { + return; + } + var position = $("#gOrganizeFormThumbStack").position(); + var beginLeft = position.left; + var beginTop = 50; + var zindex = 2000; + $("li.ui-selected").each(function(i) { + var clone = $(this).clone(); + $(clone).attr("id", "edit_clone_" + $(this).attr("ref")); + $("#gOrganizeFormThumbStack").append(clone); + $(clone).removeClass("ui-draggable"); + $(clone).removeClass("ui-selected"); + $(clone).css("margin-top", beginTop); + $(clone).css("left", beginLeft); + $(clone).css("z-index", zindex--); + + if (i < 9) { + beginTop -= 5; + beginLeft += 5; + } + }); +} + +function getEditForm() { + if ($("#gMicroThumbGrid li.ui-selected").length > 0) { + var postData = serializeItemIds("li.ui-selected"); + var url_data = get_organize_url("organize/editForm", {}) + postData; + $.get(url_data, function(data, textStatus) { + $("#gOrganizeEditForm").tabs("destroy"); + $("#gOrganizeEditForm").html(data); + if ($("#gOrganizeEditForm ul li").length) { + $("#gOrganizeEditForm").tabs(); + $("#gOrganizeEditHandleButtonsMiddle a").removeAttr("disabled"); + $("#gOrganizeEditHandleButtonsMiddle a").removeClass("ui-state-disabled"); + } else { + $("#gOrganizeEditHandleButtonsMiddle a").attr("disabled", true); + $("#gOrganizeEditHandleButtonsMiddle a").addClass("ui-state-disabled"); + } }); + } else { + $("#gOrganizeEditForm").tabs("destroy"); + $("#gOrganizeEditForm").empty(); + } +} - //$(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); - //$(".gBranchText").droppable(treeDroppable); - //$(".gBranchText").click(organizeOpenFolder); - //retrieveMicroThumbs(item_id); - //showLoading("#gOrganizeDialog"); +function serializeItemIds(selector) { + var postData = ""; + $(selector).each(function(i) { + postData += "&item[]=" + $(this).attr("ref"); + }); - //$("#gMicroThumbPanel").droppable(thumbDroppable); - //$("#gMicroThumbPanel").selectable(selectable); - //$("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); + return postData; +} - $(window).bind("resize", _size_dialog); - }; +function submitCurrentForm(event) { + console.log("submitCurrentForm"); + return false; +} - /** - * Dynamically initialize the organize dialog when it is displayed - */ - function _size_dialog(event) { - var size = $.getViewportSize(); - var h = $("#gOrganizeDialog").dialog("option", "minHeight"); - var sh = size.height() - 100; - var height = Math.max(sh, h); - var w = $("#gOrganizeDialog").dialog("option", "minWidth"); - var sw = size.width() - 100; - var width = Math.max(w, sw); - - $("#gOrganizeDialog").parent().css("height", height); - $("#gOrganizeDialog").parent().css("width", width); - $("#gOrganizeDialog").parent().css("left", "50px"); - $("#gOrganizeDialog").parent().css("top", "50px"); - - var heightMicroThumbPanel = height - 50; - heightMicroThumbPanel -= 2 * parseFloat($("#gOrganizeDialog").css("padding-bottom")); - heightMicroThumbPanel -= $("#gMessage").outerHeight(); - heightMicroThumbPanel = Math.floor(heightMicroThumbPanel); - $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); - - heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").outerHeight(); - $("#gMicroThumbPanel").height(heightMicroThumbPanel); - }; +function resetCurrentForm(event) { + console.log("resetCurrentForm"); + return false; +} - function _dialog_close(event) { - event.preventDefault(); - $("#gOrganizeDialog").dialog("close"); +function createProgressDialog(title) { + $("body").append("
        " + + "
        " + + "" + + "" + + "" + + "
        "); + $("#gOrganizeProgressDialog").dialog({ + autoOpen: true, + autoResize: false, + modal: true, + resizable: false, + title: title + }); + + $(".gProgressBar").progressbar(); + $("#gOrganizeTaskPause").click(function(event) { + paused = true; + $("#gOrganizeTaskPause").hide(); + $("#gOrganizeTaskResume").show(); + $("#gOrganizeTaskCancel").show(); + $("#gMessage").empty().append(task.pauseMsg); + }); + $("#gOrganizeTaskResume").click(function(event) { + $("#gOrganizeTaskPause").show(); + $("#gOrganizeTaskResume").hide(); + $("#gOrganizeTaskCancel").hide(); + $("#gMessage").empty().append(task.resumeMsg); + operationCallback(); + //startRearrangeCallback(); + }); + $("#gOrganizeTaskCancel").click(function(event) { + $("#gOrganizeTaskPause").show(); + $("#gOrganizeTaskResume").hide(); + $("#gOrganizeTaskCancel").hide(); + + $.ajax({async: false, + success: function(data, textStatus) { + task = null; + paused = false; + transitItems = []; + $("#gMessage").empty().append("
        " + data.task.status + "
        "); + $("#gOrganizeProgressDialog").dialog("destroy").remove(); + }, + dataType: "json", + type: "POST", + url: get_organize_url("organize/cancelTask", {task_id: task.id}) + }); + }); +} + +// ************************************************************************** +// Functions that should probably be in a gallery namespace +function getViewportSize() { + return { + width : function() { + return window.innerWidth + || document.documentElement && document.documentElement.clientWidth + || document.body.clientWidth; + }, + height : function() { + return window.innerHeight + || document.documentElement && document.documentElement.clientHeight + || document.body.clientHeight; + } }; +} -})(jQuery); +function displayAjaxError(error) { + $("body").append("
        " + error + "
        "); -$("document").ready(function() { - $("#gOrganizeLink").organize(); -}); + $("#gAjaxError").dialog({ + autoOpen: true, + autoResize: false, + modal: true, + resizable: true, + width: 610, + height: $("#gDialog").height() + }); +} diff --git a/modules/organize/js/organize_init.js b/modules/organize/js/organize_init.js new file mode 100644 index 00000000..ed036fdb --- /dev/null +++ b/modules/organize/js/organize_init.js @@ -0,0 +1,29 @@ +$("document").ready(function() { + $("#gOrganizeLink").click(function(event) { + event.preventDefault(); + var href = event.target.href; + + $("body").append('
        '); + + $("#gDialog").dialog({ + autoOpen: false, + autoResize: false, + modal: true, + resizable: false, + close: function () { + $("#gDialog").trigger("organize_close"); + $("#gDialog").dialog("destroy").remove(); + }, + zIndex: 75 + }); + + //showLoading("#gDialog"); + + $.get(href, function(data) { + $("#gDialog").html(data); + }); + return false; + }); +}); + + diff --git a/modules/organize/views/organize.html.php b/modules/organize/views/organize.html.php new file mode 100644 index 00000000..1686d255 --- /dev/null +++ b/modules/organize/views/organize.html.php @@ -0,0 +1,53 @@ + + + +
        + p::purify($item->title))) ?> +
        +
        +
        +
        +
        +

        +
        +
        +
        +
        +
        +
        +
        + +
        +
        "> +
          +
          +
          +
          +
          +
            +
          +
          +
          +
          +
          + +
          +
          +
          +
          +
          diff --git a/modules/organize/views/organize_album.html.php b/modules/organize/views/organize_album.html.php new file mode 100644 index 00000000..ae2d5d51 --- /dev/null +++ b/modules/organize/views/organize_album.html.php @@ -0,0 +1,17 @@ + +
            +
          • + "> + + +
            gBranchText"> + title) ?> +
            +
            "> + +
            +
          • +
          diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php index 8eced107..c5839a44 100644 --- a/modules/organize/views/organize_button_pane.html.php +++ b/modules/organize/views/organize_button_pane.html.php @@ -1,5 +1,50 @@ + +
          - + + +
          diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php deleted file mode 100644 index cf3fd478..00000000 --- a/modules/organize/views/organize_dialog.html.php +++ /dev/null @@ -1,37 +0,0 @@ - -
          -

          p::purify($item->title))) ?>

          -
          -
          -
          -

          -
          -
          -
          -
          -
          -
          -
          -
            - -
          -
          -
          -
          "> -
            - -
          -
          -
          -
          -
          -
          - -
          -
          -
          -
          -
          -
          - diff --git a/modules/organize/views/organize_edit.html.php b/modules/organize/views/organize_edit.html.php new file mode 100644 index 00000000..1adf290f --- /dev/null +++ b/modules/organize/views/organize_edit.html.php @@ -0,0 +1,14 @@ + +
            + $pane): ?> +
          • + +
          + + 0): ?> + $pane): ?> +
          + + +
          + \ No newline at end of file diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php index e6b7aec0..c80696ad 100644 --- a/modules/organize/views/organize_thumb_grid.html.php +++ b/modules/organize/views/organize_thumb_grid.html.php @@ -1,19 +1,12 @@ $child): ?> - - is_album()): ?> - - -
        • + +is_album()): ?> + + +
        • +
          thumb_img(array("class" => "gThumbnail"), $thumbsize, true) ?> -
        • + + -= 25): ?> - - \ No newline at end of file diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php index 28b45be0..d2cdd957 100644 --- a/modules/organize/views/organize_tree.html.php +++ b/modules/organize/views/organize_tree.html.php @@ -1,20 +1,4 @@ -
        • - "> - - -
          gBranchText"> - title) ?> -
          - -
          - -
            "> - -
          - -
        • + $child): ?> + -- cgit v1.2.3 From 65c850c393ce6159289e3fd05056c33e7d62e961 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Wed, 5 Aug 2009 10:26:11 -0700 Subject: Revert "Revert "Checkpoint the organize module rewrite. At this point, it doesn't really do"" This reverts commit 397468c47b8fc3fefeb54ff19a73980ed1dd8c20. --- modules/organize/controllers/organize.php | 507 +-------------- modules/organize/css/organize.css | 184 +----- modules/organize/helpers/organize_task.php | 131 ---- modules/organize/helpers/organize_theme.php | 3 +- modules/organize/js/organize.js | 697 +++------------------ modules/organize/js/organize_init.js | 29 - modules/organize/views/organize.html.php | 53 -- modules/organize/views/organize_album.html.php | 17 - .../organize/views/organize_button_pane.html.php | 49 +- modules/organize/views/organize_dialog.html.php | 37 ++ modules/organize/views/organize_edit.html.php | 14 - .../organize/views/organize_thumb_grid.html.php | 23 +- modules/organize/views/organize_tree.html.php | 20 +- 13 files changed, 232 insertions(+), 1532 deletions(-) delete mode 100644 modules/organize/helpers/organize_task.php delete mode 100644 modules/organize/js/organize_init.js delete mode 100644 modules/organize/views/organize.html.php delete mode 100644 modules/organize/views/organize_album.html.php create mode 100644 modules/organize/views/organize_dialog.html.php delete mode 100644 modules/organize/views/organize_edit.html.php (limited to 'modules/organize/helpers') diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 898be509..d7854c53 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -19,54 +19,48 @@ */ class Organize_Controller extends Controller { private static $_MICRO_THUMB_SIZE = 90; - private static $_MICRO_THUMB_PADDING = 5; + private static $_MICRO_THUMB_PADDING = 10; - function index($item_id=1) { + function index($item_id) { $item = ORM::factory("item", $item_id); $root = ($item->id == 1) ? $item : ORM::factory("item", 1); access::required("view", $item); access::required("edit", $item); - $v = new View("organize.html"); + $v = new View("organize_dialog.html"); $v->root = $root; $v->item = $item; - $v->album_tree = $this->tree($item, $root); + $v->album_tree = $this->_tree($item, $root); + $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item); $v->button_pane = new View("organize_button_pane.html"); + $buttons = (object)array("left" => array(), "middle" =>array(), "right" => array(), + "item" => $item); + module::event("organize_format_button_pane", $buttons); + + $v->button_pane->buttons = $buttons; print $v; } - function content($item_id) { + function content($item_id, $offset=0) { $item = ORM::factory("item", $item_id); access::required("view", $item); access::required("edit", $item); - $width = $this->input->get("width"); - $height = $this->input->get("height"); - $offset = $this->input->get("offset", 0); - $thumbsize = self::$_MICRO_THUMB_SIZE + 2 * self::$_MICRO_THUMB_PADDING; - $page_size = ceil($width / $thumbsize) * ceil($height / $thumbsize); + $v = $this->_get_micro_thumb_grid($item, $offset); + print $v->__toString(); + } + private function _get_micro_thumb_grid($item, $offset=0) { $v = new View("organize_thumb_grid.html"); - $v->children = $item->children($page_size, $offset); + $v->item_id = $item->id; + $v->children = $item->children(25, $offset); $v->thumbsize = self::$_MICRO_THUMB_SIZE; - $v->padding = self::$_MICRO_THUMB_PADDING; - $v->offset = $offset; - - print json_encode(array("count" => $v->children->count(), - "data" => $v->__toString())); - } - - function header($item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); + $v->offset = $offset + 25; - print json_encode( - array("title" => p::purify($item->title), - "description" => empty($item->description) ? "" : p::purify($item->description))); + return $v; } - function tree($item, $parent) { + private function _tree($item, $parent, $selected=false) { access::required("view", $item); access::required("edit", $item); @@ -75,466 +69,25 @@ class Organize_Controller extends Controller { ->orderby(array("title" => "ASC")) ->find_all(); - $v = new View("organize_album.html"); + $v = new View("organize_tree.html"); $v->album = $parent; - $v->selected = $parent->id == $item->id; - - if ($albums->count()) { - $v->album_icon = $parent->id == 1 || $v->selected ? "ui-icon-minus" : "ui-icon-plus"; - } else { - $v->album_icon = ""; - } + $v->selected = false; $v->children = ""; - foreach ($albums as $album) { - $v->children .= $this->tree($item, $album); - } - return $v->__toString(); - } - - function startTask($operation, $id) { - access::verify_csrf(); - $items = $this->input->post("item"); - - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - $definition = $this->_getOperationDefinition($item, $operation); - - $task_def = Task_Definition::factory() - ->callback("organize_task::run") - ->description($definition["description"]) - ->name($definition["name"]); - $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id, - "type" => $definition["type"], - "batch" => ceil(count($items) * .1))); - // @todo If there is only one item then call task_run($task->id); Maybe even change js so - // we can call finish as well. - batch::start(); - print json_encode( - array("result" => "started", - "runningMsg" => $definition["runningMsg"], - "pauseMsg" => "
          {$definition['pauseMsg']}
          ", - "resumeMsg" => "
          {$definition['resumeMsg']}
          ", - "task" => array("id" => $task->id, - "percent_complete" => $task->percent_complete, - "type" => $task->get("type"), - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function runTask($task_id) { - access::verify_csrf(); - - $task = task::run($task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } - - print json_encode(array("result" => $task->done ? $task->state : "in_progress", - "task" => array("id" => $task->id, - "percent_complete" => $task->percent_complete, - "type" => $task->get("type"), - "post_process" => $task->get("post_process"), - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function finishTask($task_id) { - access::verify_csrf(); - - $task = ORM::factory("task", $task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } - - if ($task->done) { - $item = ORM::factory("item", (int)$task->get("target")); - $type = $task->get("type"); - switch ($type) { - case "albumCover": - $task->status = t("Album cover set for '%album'", array("album" => $item->title)); - break; - case "delete": - $task->status = t("Selection deleted"); - break; - case "move": - $task->status = t("Move to '%album' completed", array("album" => $item->title)); - break; - case "rearrange": - try { - $item->sort_column = "weight"; - $item->save(); - $task->status = t("Rearrange for '%album' completed", array("album" => $item->title)); - } catch (Exception $e) { - $task->state = "error"; - $task->status = $e->getMessage(); - } - break; - case "rotateCcw": - case "rotateCw": - $task->status = t("Rotation completed"); - break; - } - $task->save(); - } - - batch::stop(); - print json_encode(array("result" => "success", - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function cancelTask($task_id) { - access::verify_csrf(); - - $task = ORM::factory("task", $task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } - - if (!$task->done) { - $task->done = 1; - $task->state = "cancelled"; - $type = $task->get("type"); - switch ($type) { - case "move": - $task->status = t("Move to album was cancelled prior to completion"); - break; - case "rearrange": - $task->status = t("Rearrange album was cancelled prior to completion"); - case "rotateCcw": - case "rotateCw": - $task->status = t("Rotation was cancelled prior to completion"); - break; - } - $task->save(); - } - - batch::stop(); - print json_encode(array("result" => "success", - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); - } - - function editForm() { - $event_parms = new stdClass(); - $event_parms->panes = array(); - $event_parms->itemids = $this->input->get("item"); - - // The following code should be done more dynamically i.e. use the event mechanism - if (count($event_parms->itemids) == 1) { - $item = ORM::factory("item") - ->in("id", $event_parms->itemids[0]) - ->find(); - - access::required("view", $item); - access::required("edit", $item); - - $event_parms->panes[] = array( - "label" => $item->is_album() ? t("Edit Album") : t("Edit Photo"), - "content" => organize::get_general_edit_form($item)); - - if ($item->is_album()) { - $event_parms->panes[] = array("label" => t("Sort Order"), - "content" => organize::get_sort_edit_form($item)); - } - } - - $event_parms->panes[] = array("label" => t("Manage Tags"), - "content" => organize::get_tag_form($event_parms->itemids)); - - $v = new View("organize_edit.html"); - $v->panes = $event_parms->panes; - print $v->render(); - } - - // Handlers for the album/photo edit. Probably should be in modules/gallery - public function general() { - access::verify_csrf(); - - $itemids = $this->input->post("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - $form = organize::get_general_edit_form($item); - if ($form->validate()) { - $orig = clone $item; - $item->title = $form->title->value; - $item->description = $form->description->value; - $item->rename($form->dirname->value); - $item->save(); + $v->album_icon = "ui-icon-plus"; + if (!$selected) { + $v->selected = $parent->id == $item->id; - if ($item->is_album()) { - log::success("content", "Updated album", "id\">view"); - $message = t("Saved album %album_title", array("album_title" => p::purify($item->title))); - } else { - log::success("content", "Updated photo", "id\">view"); - $message = t("Saved photo %photo_title", array("photo_title" => p::purify($item->title))); + if ($albums->count() && ($parent->id == 1 || $v->selected) ) { + $v->album_icon = "ui-icon-minus"; } - print json_encode(array("form" => $form->__toString(), "message" => $message)); - } else { - print json_encode(array("form" => $form->__toString())); - } - } - - public function reset_general() { - $itemids = Input::instance()->get("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - print organize::get_general_edit_form($item); - } - - public function sort() { - access::verify_csrf(); - - $itemids = $this->input->post("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - $form = organize::get_sort_edit_form($item); - if ($form->validate()) { - $orig = clone $item; - $item->sort_column = $form->column->value; - $item->sort_order = $form->direction->value; - $item->save(); - - log::success("content", "Updated album", "id\">view"); - $message = t("Saved album %album_title", array("album_title" => p::purify($item->title))); - print json_encode(array("form" => $form->__toString(), "message" => $message)); - } else { - print json_encode(array("form" => $form->__toString())); - } - } - - public function reset_sort() { - $itemids = Input::instance()->get("item"); - $item = ORM::factory("item") - ->in("id", $itemids[0]) - ->find(); - access::required("view", $item); - access::required("edit", $item); - - print organize::get_sort_edit_form($item); - } - - public function edit_tags() { - access::verify_csrf(); - $itemids = explode("|", $this->input->post("item")); - $form = organize::get_tag_form($itemids); - $old_tags = $form->tags->value; - if ($form->validate()) { - - $old_tags = preg_split("/[;,\s]+/", $old_tags); - sort($old_tags); - $new_tags = preg_split("/[;,\s]+/", $form->tags->value); - sort($new_tags); - - $HIGH_VALUE_STRING = "\256"; - for ($old_index = $new_index = 0;;) { - $old_tag = $old_index >= count($old_tags) ? $HIGH_VALUE_STRING : $old_tags[$old_index]; - $new_tag = $new_index >= count($new_tags) ? $HIGH_VALUE_STRING : $new_tags[$new_index]; - if ($old_tag == $HIGH_VALUE_STRING && $new_tag == $HIGH_VALUE_STRING) { - break; - } - $matches = array(); - $old_star = false; - if (preg_match("/(.*)(\*)$/", $old_tag, $matches)) { - $old_star = true; - $old_tag = $matches[1]; - } - $new_star = false; - if (preg_match("/(.*)(\*)$/", $new_tag, $matches)) { - $new_star = true; - $new_tag = $matches[1]; - } - if ($old_tag > $new_tag) { - // Its missing in the old list so add it - $this->_add_tag($new_tag, $itemids); - $new_index++; - } else if ($old_tag < $new_tag) { - // Its missing in the new list so its been removed - $this->_delete_tag($old_tag, $itemids); - $old_index++; - } else { - if ($old_star && !$new_star) { - // User wants tag to apply to all items, originally only on some of selected - $this->_update_tag($old_tag, $itemids); - } // Not changed ignore - $old_index++; - $new_index++; - } + foreach ($albums as $album) { + $v->children .= $this->_tree($item, $album, $v->selected); } } - print json_encode(array("form" => $form->__toString(), "message" => t("Tags updated"))); - } - - public function reset_edit_tags() { - $itemids = $this->input->get("item"); - - print organize::get_tag_form($itemids); - } - - private function _add_tag($new_tag, $itemids) { - // Super lame security stopgap. This code is going to get rewritten anyway. - foreach ($itemids as $item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); - } - - $tag = ORM::factory("tag") - ->where("name", $new_tag) - ->find(); - if ($tag->loaded) { - $tag->count += count($itemids); - } else { - $tag->name = $new_tag; - $tag->count = count($itemids); - } - $tag->save(); - - $db = Database::instance(); - foreach ($itemids as $item_id) { - $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); - } - } - - private function _delete_tag($new_tag, $itemids) { - // Super lame security stopgap. This code is going to get rewritten anyway. - foreach ($itemids as $item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); - } - - $tag = ORM::factory("tag") - ->where("name", $new_tag) - ->find(); - $tag->count -= count($itemids); - if ($tag->count > 0) { - $tag->save(); - } else { - $tag->delete(); - } - - $ids = implode(", ", $itemids); - Database::instance()->query( - "DELETE FROM {items_tags} WHERE tag_id = {$tag->id} AND item_id IN ($ids);"); - } - - private function _update_tag($new_tag, $itemids) { - // Super lame security stopgap. This code is going to get rewritten anyway. - foreach ($itemids as $item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); - } - - $tag = ORM::factory("tag") - ->where("name", $new_tag) - ->find(); - - $db = Database::instance(); - $ids = implode(", ", $itemids); - $result = $db->query( - "SELECT item_id FROM {items_tags} - WHERE tag_id = {$tag->id} - AND item_id IN ($ids)"); - - $add_items = array_fill_keys($itemids, 1); - foreach($result as $row) { - unset($add_items[$row->item_id]); - } - $add_items = array_keys($add_items); - $tag->count += count($add_items); - $tag->save(); - foreach ($add_items as $item_id) { - $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); - } + return $v->__toString(); } - private function _getOperationDefinition($item, $operation) { - switch ($operation) { - case "move": - return array("description" => - t("Move albums and photos to '%name'", array("name" => $item->title)), - "name" => t("Move to '%name'", array("name" => $item->title)), - "type" => "move", - "runningMsg" => t("Move in progress"), - "pauseMsg" => t("The move operation was paused"), - "resumeMsg" => t("The move operation was resumed")); - break; - - case "rearrange": - return array("description" => t("Rearrange the order of albums and photos"), - "name" => t("Rearrange: %name", array("name" => $item->title)), - "type" => "rearrange", - "runningMsg" => t("Rearrange in progress"), - "pauseMsg" => t("The rearrange operation was paused"), - "resumeMsg" => t("The rearrange operation was resumed")); - break; - case "rotateCcw": - return array("description" => t("Rotate the selected photos counter clockwise"), - "name" => t("Rotate images in %name", array("name" => $item->title)), - "type" => "rotateCcw", - "runningMsg" => t("Rotate Counter Clockwise in progress"), - "pauseMsg" => t("The rotate operation was paused"), - "resumeMsg" => t("The rotate operation was resumed")); - break; - - case "rotateCw": - return array("description" => t("Rotate the selected photos clockwise"), - "name" => t("Rotate images in %name", array("name" => $item->title)), - "type" => "rotateCw", - "runningMsg" => t("Rotate Clockwise in progress"), - "pauseMsg" => t("The rotate operation was paused"), - "resumeMsg" => t("The rotate operation was resumed")); - break; - - case "delete": - return array("description" => t("Delete selected photos / albums"), - "name" => t("Delete images in %name", array("name" => $item->title)), - "type" => "delete", - "runningMsg" => t("Delete images in progress"), - "pauseMsg" => t("The delete operation was paused"), - "resumeMsg" => t("The delete operation was resumed")); - break; - - case "albumCover": - return array("description" => t("Reset Album Cover"), - "name" => t("Reset Album cover for %name", array("name" => $item->title)), - "type" => "albumCover", - "runningMsg" => t("Reset Album Cover in progress"), - "pauseMsg" => t("Reset album cover was paused"), - "resumeMsg" => t("Reset album cover was resumed")); - break; - - default: - throw new Exception("Operation '$operation' is not implmented"); - } - } } diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index e58cd5a5..4568a707 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -1,41 +1,44 @@ -/* @todo move to theme css */ /******************************************************************* * Dialog wide stylings */ -#gMessage { - margin-bottom: .4em; +#gOrganizeDialog { + text-align: left; } -#gMessage .gInfo { - background-color: transparent; - background-image: none; - padding-left: .4em; +#gOrganize { + overflow: hidden; } -#gOrganizeProgressDialog { - text-align: left; +#gOrganize .yui-u { + width: 75%; +} + +#gOrganize .yui-gf .first { + width: 25%; } -#gDialog .yui-gf div.first { - width: 20%; +#gOrganize .yui-gf #gMessage { + margin-bottom: .4em; + width: 75%; } -#gDialog .yui-gf .yui-u { - width: 80%; +#gMessage .gInfo { + font-weight: bold; + padding-left: 2em; } + /******************************************************************* * Album Tree styling */ #gOrganizeTreeContainer { - overflow-y: auto; + overflow: auto; margin: 0 !important; padding: 0 !important; } -#gOrganizeAlbumDescription { - height: 2em; - overflow-y: auto; +#gOrganizeTreeContainer ul ul li { + padding-left: 1.2em; } .gBranchSelected { @@ -45,37 +48,21 @@ padding: .3em 0; } -.gBranchDroppable { - border: 1px dotted; -} - -.gBranchText { - cursor: pointer; - width: auto; -} - .gBranchCollapsed { display: none; } -.gBranchEmpty { - visibility: hidden; +.gOrganizeBranch span { + cursor: pointer; } -#gOrganizeTreeContainer ul ul li { - padding-left: 1.2em; +.gBranchText { + cursor: pointer; + width: auto; } - /******************************************************************* * Album Panel Styles */ - -#gMicroThumbUnselectAll, -#gMicroThumbSelectAll { - font-size: 1em; - font-weight: bold; -} - #gMicroThumbPanel { margin: 0 !important; padding: 0 !important; @@ -83,33 +70,27 @@ border: 1px solid #999 !important; border-top: none !important; border-left: none !important; - margin-left: -1em !important; overflow-x: hidden; overflow-y: auto; } #gMicroThumbGrid { - padding: .5em; } .gMicroThumbContainer { - display: block; - float: left; - font-size: .7em; - height: 9em; - margin-bottom: 1em; - margin-left: 1em; - opacity: .4; - padding: 0 .5em; +// padding: 0 .5em; +// opacity: .4; } .gMicroThumb { - height: 9em; - width: 9em; - background-color: #fff; display: block; float: left; +// font-size: .7em; + height: 9em; + margin-bottom: 1em; + margin-left: 1em; text-align: center; + width: 9em; } #gMicroThumbPanel #gMicroThumbGrid .gAlbum { @@ -120,35 +101,12 @@ opacity: 1; } -.gMicroThumbContainer.ui-selected { - opacity: 1; -} - -#gDragHelper .gMicroThumbGrid { - background-color: transparent; - padding: 0; - overflow: visible; -} - -#gDragHelper .gMicroThumbContainer { - display: block; - margin: 0; - padding: 0; -} - -#gDragHelper .gMicroThumb { - background-color: transparent; - height: auto; - width: auto; -} - - /**************************************************************** * Organize Edit Drawer styling */ #gOrganizeEditDrawer { background-color: #13A; - width: 90%; + width: 100% !important; } #gOrganizeEditDrawerPanel { @@ -204,79 +162,3 @@ height: 30px; width: 15px; } - -#gOrganizeFormButtons { - bottom: 0.5em; -} - -#gOrganizeFormButtons .submit { - display: inline; - float: none; - left: 0.5em; - position: relative; -} - -/* yui-u gives 80% width, but then we wrap so do it ourselves */ -#gOrganizeEditForm { - float: right; - width: 79%; - // height: 100px; -} - -#gOrganizeFormThumbs { - overflow: hidden; -} - -#gOrganizeFormThumbs div { - margin: 0; - text-align: center; - background: transparent none repeat scroll 0 0; -} - -#gOrganizeFormThumbs .gMicroThumbContainer { - display: block; - float: left; - opacity: 1; - position: absolute; -} - -/**************************************************************** - * Organize Edit From tabs styling - */ -#gOrganizeEditForm.ui-tabs .ui-tabs-hide { - display: block !important; - left: -10000px; - position: absolute; -} - -#gOrganizeEditForm.ui-widget { - font-size: .75em; -} - -.gOrganizeEditPane { - height: 135px; - overflow-y: auto; -} - -.textbox, -.textarea { - border: 1px solid #e8e8e8; - border-top-color: #ccc; - border-left-color: #ccc; - color: #333; - width: 100%; -} - -.textarea { - height: 6em; -} - -.textbox { - height: 1.3em; - width: 50% -} - -.gTagGroup { - float:left; - margin: .5em; -} diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php deleted file mode 100644 index dc474818..00000000 --- a/modules/organize/helpers/organize_task.php +++ /dev/null @@ -1,131 +0,0 @@ -context); - $taskType = $context["type"]; - - try { - $target = ORM::factory("item", $context["target"]); - $total = count($context["items"]); - $stop = min($total - $context["position"], $context["batch"]); - $context["post_process"] = array(); - for ($offset = 0; $offset < $stop; $offset++) { - $current_id = $context["position"] + $offset; - $id = $context["items"][$current_id]; - switch ($taskType) { - case "move": - $source = ORM::factory("item", $id); - access::required("view", $source); - access::required("view", $target); - access::required("edit", $source); - access::required("edit", $target); - - item::move($source, $target); - break; - - case "rearrange": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - Database::instance() - ->query("Update {items} set weight = {$context["position"]} where id=$id;"); - break; - - case "rotateCcw": - case "rotateCw": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - if ($item->is_photo()) { - $context["post_process"]["reload"][] = - self::_do_rotation($item, $taskType == "rotateCcw" ? -90 : 90); - } - break; - - case "albumCover": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("view", $item->parent()); - access::required("edit", $item->parent()); - - item::make_album_cover($item); - break; - - case "delete": - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - - $item->delete(); - $context["post_process"]["remove"][] = array("id" => $id); - break; - - default: - throw new Exception("Task '$taskType' is not implemented"); - } - } - $context["position"] += $stop; - $task->state = "success"; - } catch(Exception $e) { - $task->status = $e->getMessage(); - $task->state = "error"; - $task->save(); - throw $e; - } - $task->context = serialize($context); - $total = count($context["items"]); - $task->percent_complete = $context["position"] / (float)$total * 100; - $task->done = $context["position"] == $total || $task->state == "error"; - } - - private static function _do_rotation($item, $degrees) { - // This code is copied from Quick_Controller::rotate - graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); - - list($item->width, $item->height) = getimagesize($item->file_path()); - $item->resize_dirty= 1; - $item->thumb_dirty= 1; - $item->save(); - - graphics::generate($item); - - $parent = $item->parent(); - if ($parent->album_cover_item_id == $item->id) { - copy($item->thumb_path(), $parent->thumb_path()); - $parent->thumb_width = $item->thumb_width; - $parent->thumb_height = $item->thumb_height; - $parent->save(); - } - list ($height, $width) = $item->scale_dimensions(90); - $margin_top = (90 - $height) / 20; - - return array("src" => $item->thumb_url() . "?rnd=" . rand(), - "id" => $item->id, - "marginTop" => "{$margin_top}em", "width" => $width, "height" => $height); - } -} \ No newline at end of file diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index e4feba2b..f01ab88b 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -19,8 +19,7 @@ */ class organize_theme { static function head($theme) { - // @tdo remove the addition css and organize.js (just here to test) - $theme->script("organize_init.js"); + //$theme->script("organize_init.js"); $theme->script("organize.js"); $theme->css("organize.css"); } diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index 12d8a5b5..e84afd03 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -1,621 +1,116 @@ -/* - * @todo Trap resize of dialog and resize the child areas (tree, grid and edit form) - */ -var url; -var paused = false; -var task = null; -var transitItems = []; -var heightMicroThumbPanel; - -// ************************************************************************** -// JQuery UI Widgets -// Draggable -var draggable = { - handle: ".gMicroThumbContainer.ui-selected", - revert: true, - zindex: 2000, - distance: 10, - helper: function(event, ui) { - if (!$(event.currentTarget).hasClass("ui-selected")) { - $(event.currentTarget).addClass("ui-selected"); - setDrawerButtonState(); - } - $("#gMicroThumbPanel").append("
            "); - var beginTop = event.pageY; - var beginLeft = event.pageX; - var zindex = $(".gMicroThumbContainer").draggable("option", "zindex"); - $("#gDragHelper").css('top', event.pageY - 22.5); - $("#gDragHelper").css('left', event.pageX + 22.5); - var placeHolder = $(this).clone(); - $(placeHolder).attr("id", "gPlaceHolder"); - $(placeHolder).css("visibility", "hidden"); - $(placeHolder).removeClass("ui-selected"); - $(placeHolder).removeClass("ui-draggable"); - $(this).after(placeHolder); - - $("li.ui-selected").each(function(i) { - var clone = $(this).clone(); - $(clone).attr("id", "drag_clone_" + $(this).attr("ref")); - $("#gDragHelper ul").append(clone); - $(clone).css("position", "absolute"); - $(clone).css("top", beginTop); - $(clone).css("left", beginLeft); - $(clone).css("z-index", zindex--); - $(this).hide(); - - var children = $(clone).find(".gMicroThumb .gThumbnail"); - var width = new String(children.css("width")).replace(/[^0-9]/g,"") * .5; - var height = new String(children.css("height")).replace(/[^0-9]/g,"") * .5; - var marginTop = new String(children.css("margin-top")).replace(/[^\.0-9]/g,"") * .5; - children.attr("width", width); - children.attr("height", height); - children.css("margin-top", marginTop); - if (i < 9) { - beginTop -= 5; - beginLeft += 5; - } - }); - return $("#gDragHelper"); - }, - stop: function(event, ui) { - $("#gDragHelper li").each(function(i) { - $("#thumb_" + $(this).attr("ref")).show(); - }); - $(".gMicroThumbContainer.ui-selected").css("z-index", null); - $("#gDragHelper").remove(); - $("#gPlaceHolder").remove(); - } -}; - -// Thumbnail Grid Droppable -var thumbDroppable = { - tolerance: "pointer", - over: function(event, ui) { - $("#gPlaceHolder").show(); - }, - out: function(event, ui) { - $("#gPlaceHolder").hide(); - }, - drop: function(event, ui) { - $("#gDragHelper").hide(); - $("#gPlaceHolder").hide(); - var newOrder = ""; - $("#gMicroThumbGrid .gMicroThumbContainer").each(function(i) { - if ($(this).attr("id") == "gPlaceHolder") { - $("#gDragHelper li").each(function(i) { - newOrder += "&item[]=" + $(this).attr("ref"); - }); - } else if ($(this).css("display") != "none") { - newOrder += "&item[]=" + $(this).attr("ref"); - } else { - // If its not displayed then its one of the ones being moved so ignore. - } - }); - $("#gDragHelper li").each(function(i) { - $("#gPlaceHolder").before($("#thumb_" + $(this).attr("ref")).show()); - }); - $.ajax({ - data: newOrder, - dataType: "json", - success: operationCallback, - type: "POST", - url: get_organize_url("organize/startTask/rearrange", {item_id: item_id}) - }); - } -}; - -// Album Tree Droppable -var treeDroppable = { - tolerance: "pointer", - greedy: true, - hoverClass: "gBranchDroppable", - drop: function(event, ui) { - $("#gDragHelper").hide(); - var targetItemId = $(this).attr("ref"); - if ($(this).hasClass("gBranchSelected")) { - $("#gMessage").empty().append(INVALID_DROP_TARGET); - ui.draggable.trigger("stop", event); - return false; - } - var postData = serializeItemIds("#gDragHelper li"); - var okToMove = true; - $("#gDragHelper li").each(function(i) { - okToMove &= targetItemId != $(this).attr("ref"); - }); - if (!okToMove) { - $("#gMessage").empty().append(INVALID_DROP_TARGET); - ui.draggable.trigger("stop", event); - return false; - } - $("#gDragHelper li").each(function(i) { - $("#thumb_" + $(this).attr("ref")).remove(); - }); - $.ajax({ - data: postData, - dataType: "json", - success: operationCallback, - type: "POST", - url: get_organize_url("organize/startTask/move", {item_id: targetItemId}) - }); - return true; - } -}; - -// Selectable -var selectable = { - filter: ".gMicroThumbContainer", - selected: function(event, ui) { - setDrawerButtonState(); - }, - unselected: function(event, ui) { - setDrawerButtonState(); - }, - stop: function(event, ui) { - getEditForm(); - } -}; - -// ************************************************************************** -// Event Handlers -// MicroThumbContainer mouseup -var onMicroThumbContainerMouseup = function(event) { - // For simplicity always remove the ui-selected class. If it was unselected - // it will get added back - $(this).toggleClass("ui-selected"); - - setDrawerButtonState(); - if ($("#gMicroThumbGrid li.ui-selected").length > 0) { - getEditForm(); - } -}; - -// MicroThumbContainer mousemove -var onMicroThumbContainerMousemove = function(event) { - if ($("#gDragHelper").length > 0 && $(this).attr("id") != "gPlaceHolder") { - if (event.pageX < $(this).offset().left + $(this).width() / 2) { - $(this).before($("#gPlaceHolder")); - } else { - $(this).after($("#gPlaceHolder")); - } - var container = $("#gMicroThumbPanel").get(0); - var scrollHeight = container.scrollHeight; - var scrollTop = container.scrollTop; - var height = $(container).height(); - if (event.pageY > height + scrollTop) { - container.scrollTop = this.offsetTop; - } else if (event.pageY < scrollTop) { - container.scrollTop -= height; - } - } -}; - -// Handle click events on the buttons on the drawer handle -function drawerHandleButtonsClick(event) { - event.preventDefault(); - if (!$(this).attr("disabled")) { - var operation = $(this).attr("ref"); - switch (operation) { - case "edit": - case "close": - $("#gOrganizeEditDrawerPanel").animate( - {"height": "toggle", "display": "block"}, - {duration: "fast", - complete: function() { - setSelectedThumbs(); - if (operation == "close") { - $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "inline-block"); - $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "none"); - $("#gOrganizeEditHandleButtonsMiddle a").css("display", "none"); - } else { - $("#gOrganizeEditHandleButtonsLeft a[ref='edit']").css("display", "none"); - $("#gOrganizeEditHandleButtonsLeft a[ref='close']").css("display", "inline-block"); - $("#gOrganizeEditHandleButtonsMiddle a").css("display", "inline-block"); - } - }, - step: function() { - $("#gMicroThumbPanel").height(heightMicroThumbPanel - $(this).height()); - } - }); - break; - case "select-all": - $("#gMicroThumbGrid li").addClass("ui-selected"); - $("#gMicroThumbSelectAll").hide(); - $("#gMicroThumbUnselectAll").show(); - setDrawerButtonState(); - getEditForm(); - break; - case "unselect-all": - $("#gMicroThumbGrid li").removeClass("ui-selected"); - $("#gMicroThumbSelectAll").show(); - $("#gMicroThumbUnselectAll").hide(); - setDrawerButtonState(); - break; - case "done": - $("#gDialog").dialog("close"); - break; - case "submit": - var currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); - var form = $("#pane-"+currentTab+" form"); - var url = $(form).attr("action") - .replace("__FUNCTION__", $(form).attr("ref")); - $.ajax({ - data: $(form).serialize(), - dataType: "json", - success: function (data, textStatus) { - $("#pane-"+currentTab).children("form").replaceWith(data.form); - if (data.message) { - $("#gMessage").empty().append("
            " + data.message + "
            "); - } - }, - type: "POST", - url: url - }); - break; - case "reset": - currentTab = $("#gOrganizeEditForm").tabs("option", "selected"); - form = $("#pane-"+currentTab+" form"); - $.ajax({ - data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), - dataType: "html", - success: function (data, textStatus) { - $("#pane-"+currentTab + " form").replaceWith(data); - }, - type: "GET", - url: $(form).attr("action").replace("__FUNCTION__", "reset_" + $(form).attr("ref")) +(function($) { + $.fn.organize = function(options) { + var size = $.getViewportSize(); + var height = size.height() - 100; // Leave 50 pixels on the top and bottom of the dialog + var width = size.width() - 100; // Leave 50 pixels on the left and right of the dialog + var opts = $.extend({}, $.fn.organize.defaults, {width: width, height: height}, options); + return this.each(function() { + $(this).click(function(event) { + var href = event.target.href; + var size = $.getViewportSize(); + + $("body").append('
            '); + + $("#gOrganizeDialog").dialog(opts); + // Pass the approx height and width of the thumb grid to optimize thumb retrieval + $.get(href, _init); + return false; }); - break; - case "delete": - if (!confirm(CONFIRM_DELETE)) { - break; - } - default: - $.ajax({ - data: serializeItemIds("#gMicroThumbPanel li.ui-selected"), - dataType: "json", - success: operationCallback, - type: "POST", - url: get_organize_url("organize/startTask/" + operation, {item_id: item_id}) - }); - break; - } - } -}; - -// ************************************************************************** -// AJAX Callbacks -// MicroThumbContainer click -var getMicroThumbsCallback = function(json, textStatus) { - if (json.count > 0) { - $("#gMicroThumbGrid").append(json.data); - retrieveMicroThumbs(); - $(".gMicroThumbContainer").mouseup(onMicroThumbContainerMouseup); - $(".gMicroThumbContainer").mousemove(onMicroThumbContainerMousemove); - $(".gMicroThumbContainer").draggable(draggable); - } -}; - -var operationCallback = function (data, textStatus) { - var done = false; - if (!paused) { - createProgressDialog(data.runningMsg); - task = data.task; - task.pauseMsg = data.pauseMsg; - task.resumeMsg = data.resumeMsg; - done = data.task.done; - } - $(".gMicroThumbContainer").draggable("disable"); - paused = false; - while (!done && !paused) { - $.ajax({async: false, - success: function(data, textStatus) { - $(".gProgressBar").progressbar("value", data.task.percent_complete); - done = data.task.done; - if (data.task.post_process.reload) { - $.each(data.task.post_process.reload, function() { - var selector = "#gMicroThumb-" + this.id + " img"; - $(selector).attr("height", this.height); - $(selector).attr("width", this.width); - $(selector).attr("src", this.src); - $(selector).css("margin-top", this.marginTop); - }); - } - if (data.task.post_process.remove) { - $.each(data.task.post_process.remove, function() { - $("#thumb_" + this.id).remove(); - }); - } - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - paused = true; - displayAjaxError(XMLHttpRequest.responseText); - }, - dataType: "json", - type: "POST", - url: get_organize_url("organize/runTask", {task_id: task.id}) - }); - } - if (!paused) { - $("#gOrganizeProgressDialog").dialog("destroy").remove(); - $.ajax({async: false, - success: function(data, textStatus) { - setDrawerButtonState(); - task = null; - $("#gMessage").empty().append("
            " + data.task.status + "
            "); - }, - dataType: "json", - type: "POST", - url: get_organize_url("organize/finishTask", {task_id: task.id}) }); - } - $(".gMicroThumbContainer").draggable("enable"); -}; - -// ************************************************************************** - -/** - * Dynamically initialize the organize dialog when it is displayed - */ -function organize_dialog_init() { - var size = getViewportSize(); - heightMicroThumbPanel = size.height() - 100; - var width = size.width() - 100; - - // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 - $(".sf-menu li.sfHover ul").css("z-index", 70); - - $("#gDialog").dialog("option", "width", width); - $("#gDialog").dialog("option", "height", heightMicroThumbPanel); - - $("#gDialog").dialog("open"); - if ($("#gDialog h1").length) { - $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html()); - } else if ($("#gDialog fieldset legend").length) { - $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html()); - } - - $("#gDialog").bind("organize_close", function(target) { - $.gallery_reload(); - }); - - heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-top")); - heightMicroThumbPanel -= 2 * parseFloat($("#gDialog").css("padding-bottom")); - heightMicroThumbPanel -= $("#gMicroThumbPanel").position().top; - heightMicroThumbPanel -= $("#gDialog #ft").height(); - heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").height(); - heightMicroThumbPanel = Math.round(heightMicroThumbPanel); - - $("#gMicroThumbPanel").height(heightMicroThumbPanel); - $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); - - $(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); - $(".gBranchText").droppable(treeDroppable); - $(".gBranchText").click(organizeOpenFolder); - retrieveMicroThumbs(item_id); - //showLoading("#gDialog"); - - $("#gMicroThumbPanel").droppable(thumbDroppable); - $("#gMicroThumbPanel").selectable(selectable); - $("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); -} - -function retrieveMicroThumbs() { - var offset = $("#gMicroThumbGrid li").length; - if (url == null) { - var grid_width = $("#gMicroThumbPanel").width(); - url = $("#gMicroThumbPanel").attr("ref"); - url = url.replace("__WIDTH__", grid_width); - url = url.replace("__HEIGHT__", heightMicroThumbPanel); - } - var url_data = url.replace("__OFFSET__", offset); - url_data = url_data.replace("__ITEM_ID__", item_id); - $.getJSON(url_data, getMicroThumbsCallback); -} + }; -function organizeToggleChildren(event) { - var id = $(this).attr("ref"); - var span_children = $("#gOrganizeChildren-" + id); - if ($(this).hasClass("ui-icon-plus")) { - $(this).removeClass("ui-icon-plus"); - $(this).addClass("ui-icon-minus"); - $("#gOrganizeChildren-" + id).removeClass("gBranchCollapsed"); - } else { - $(this).removeClass("ui-icon-minus"); - $(this).addClass("ui-icon-plus"); - $("#gOrganizeChildren-" + id).addClass("gBranchCollapsed"); - } - event.preventDefault(); -} + $.fn.organize.defaults = { + autoOpen: false, + modal: true, + resizable: false, + minWidth: 600, + minHeight: 500, + position: "center", + close: function () { + $("#gOrganizeDialog").trigger("organize_close"); + $("#gOrganizeDialog").dialog("destroy").remove(); + }, + zIndex: 75 + }; -function organizeOpenFolder(event) { - var selected = $(".gBranchSelected"); - if ($(selected).attr("id") != $(this).attr("id")) { - $(selected).removeClass("gBranchSelected"); - $(this).addClass("gBranchSelected"); - item_id = $(this).attr("ref"); - $("#gMicroThumbGrid").empty(); - retrieveMicroThumbs(); - } - event.preventDefault(); -} + /** + * Dynamically initialize the organize dialog when it is displayed + */ + function _init(data) { -function get_organize_url(uri, parms) { - var url = rearrangeUrl; - url = url.replace("__URI__", uri); - url = url.replace("__ITEM_ID__", !parms.item_id ? "" : parms.item_id); - url += (parms.item_id && parms.task_id) ? "/" : ""; - url = url.replace("__TASK_ID__", !parms.task_id ? "" : parms.task_id); - return url; -} + // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 + $(".sf-menu li.sfHover ul").css("z-index", 70); -/** - * Set the enabled/disabled state of the buttons. The album cover is only enabled if - * there is only 1 image selected - */ -function setDrawerButtonState() { - $("#gOrganizeFormThumbStack").empty(); - $("#gOrganizeEditForm").empty(); - var selectedCount = $("#gMicroThumbGrid li.ui-selected").length; - if (selectedCount) { - $("#gOrganizeEditHandleButtonsLeft a").removeAttr("disabled"); - $("#gOrganizeEditHandleButtonsLeft a").removeClass("ui-state-disabled"); + $("#gOrganizeDialog").html(data); + $("#gOrganizeDialog").dialog("open"); - if (selectedCount > 1) { - $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").attr("disabled", true); - $("#gOrganizeEditHandleButtonsLeft a[ref='albumCover']").addClass("ui-state-disabled"); - } - setSelectedThumbs(); - } else { - if ($("#gOrganizeEditDrawerPanel::visible").length) { - $("#gOrganizeEditHandleButtonsLeft a[ref='close']").trigger("click"); - } - $("#gOrganizeEditHandleButtonsLeft a").attr("disabled", true); - $("#gOrganizeEditHandleButtonsLeft a").addClass("ui-state-disabled"); - } -} + var heightMicroThumbPanel = $("#gOrganizeDialog").innerHeight(); + heightMicroThumbPanel -= 2 * parseFloat($("#gOrganizeDialog").css("padding-bottom")); + heightMicroThumbPanel -= $("#gMessage").outerHeight(); + heightMicroThumbPanel = Math.floor(heightMicroThumbPanel); + $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); -function setSelectedThumbs() { - if (!$("#gOrganizeEditDrawerPanel::visible").length) { - return; - } - var position = $("#gOrganizeFormThumbStack").position(); - var beginLeft = position.left; - var beginTop = 50; - var zindex = 2000; - $("li.ui-selected").each(function(i) { - var clone = $(this).clone(); - $(clone).attr("id", "edit_clone_" + $(this).attr("ref")); - $("#gOrganizeFormThumbStack").append(clone); - $(clone).removeClass("ui-draggable"); - $(clone).removeClass("ui-selected"); - $(clone).css("margin-top", beginTop); - $(clone).css("left", beginLeft); - $(clone).css("z-index", zindex--); + heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").outerHeight(); + $("#gMicroThumbPanel").height(heightMicroThumbPanel); - if (i < 9) { - beginTop -= 5; - beginLeft += 5; + if ($("#gOrganizeDialog h1").length) { + $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog h1:eq(0)").html()); + } else if ($("#gOrganizeDialog fieldset legend").length) { + $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog fieldset legend:eq(0)").html()); } - }); -} -function getEditForm() { - if ($("#gMicroThumbGrid li.ui-selected").length > 0) { - var postData = serializeItemIds("li.ui-selected"); - var url_data = get_organize_url("organize/editForm", {}) + postData; - $.get(url_data, function(data, textStatus) { - $("#gOrganizeEditForm").tabs("destroy"); - $("#gOrganizeEditForm").html(data); - if ($("#gOrganizeEditForm ul li").length) { - $("#gOrganizeEditForm").tabs(); - $("#gOrganizeEditHandleButtonsMiddle a").removeAttr("disabled"); - $("#gOrganizeEditHandleButtonsMiddle a").removeClass("ui-state-disabled"); - } else { - $("#gOrganizeEditHandleButtonsMiddle a").attr("disabled", true); - $("#gOrganizeEditHandleButtonsMiddle a").addClass("ui-state-disabled"); - } + $("#gOrganizeDialog #gMicroThumbDone").click(_dialog_close); + $("#gOrganizeDialog").bind("organize_close", function(target) { + $.gallery_reload(); }); - } else { - $("#gOrganizeEditForm").tabs("destroy"); - $("#gOrganizeEditForm").empty(); - } -} - -function serializeItemIds(selector) { - var postData = ""; - $(selector).each(function(i) { - postData += "&item[]=" + $(this).attr("ref"); - }); - - return postData; -} -function submitCurrentForm(event) { - console.log("submitCurrentForm"); - return false; -} + //$(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); + //$(".gBranchText").droppable(treeDroppable); + //$(".gBranchText").click(organizeOpenFolder); + //retrieveMicroThumbs(item_id); + //showLoading("#gOrganizeDialog"); -function resetCurrentForm(event) { - console.log("resetCurrentForm"); - return false; -} + //$("#gMicroThumbPanel").droppable(thumbDroppable); + //$("#gMicroThumbPanel").selectable(selectable); + //$("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); -function createProgressDialog(title) { - $("body").append("
            " + - "
            " + - "" + - "" + - "" + - "
            "); - $("#gOrganizeProgressDialog").dialog({ - autoOpen: true, - autoResize: false, - modal: true, - resizable: false, - title: title - }); - - $(".gProgressBar").progressbar(); - $("#gOrganizeTaskPause").click(function(event) { - paused = true; - $("#gOrganizeTaskPause").hide(); - $("#gOrganizeTaskResume").show(); - $("#gOrganizeTaskCancel").show(); - $("#gMessage").empty().append(task.pauseMsg); - }); - $("#gOrganizeTaskResume").click(function(event) { - $("#gOrganizeTaskPause").show(); - $("#gOrganizeTaskResume").hide(); - $("#gOrganizeTaskCancel").hide(); - $("#gMessage").empty().append(task.resumeMsg); - operationCallback(); - //startRearrangeCallback(); - }); - $("#gOrganizeTaskCancel").click(function(event) { - $("#gOrganizeTaskPause").show(); - $("#gOrganizeTaskResume").hide(); - $("#gOrganizeTaskCancel").hide(); + $(window).bind("resize", _size_dialog); + }; - $.ajax({async: false, - success: function(data, textStatus) { - task = null; - paused = false; - transitItems = []; - $("#gMessage").empty().append("
            " + data.task.status + "
            "); - $("#gOrganizeProgressDialog").dialog("destroy").remove(); - }, - dataType: "json", - type: "POST", - url: get_organize_url("organize/cancelTask", {task_id: task.id}) - }); - }); -} + /** + * Dynamically initialize the organize dialog when it is displayed + */ + function _size_dialog(event) { + var size = $.getViewportSize(); + var h = $("#gOrganizeDialog").dialog("option", "minHeight"); + var sh = size.height() - 100; + var height = Math.max(sh, h); + var w = $("#gOrganizeDialog").dialog("option", "minWidth"); + var sw = size.width() - 100; + var width = Math.max(w, sw); + + $("#gOrganizeDialog").parent().css("height", height); + $("#gOrganizeDialog").parent().css("width", width); + $("#gOrganizeDialog").parent().css("left", "50px"); + $("#gOrganizeDialog").parent().css("top", "50px"); + + var heightMicroThumbPanel = height - 50; + heightMicroThumbPanel -= 2 * parseFloat($("#gOrganizeDialog").css("padding-bottom")); + heightMicroThumbPanel -= $("#gMessage").outerHeight(); + heightMicroThumbPanel = Math.floor(heightMicroThumbPanel); + $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); + + heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").outerHeight(); + $("#gMicroThumbPanel").height(heightMicroThumbPanel); + }; -// ************************************************************************** -// Functions that should probably be in a gallery namespace -function getViewportSize() { - return { - width : function() { - return window.innerWidth - || document.documentElement && document.documentElement.clientWidth - || document.body.clientWidth; - }, - height : function() { - return window.innerHeight - || document.documentElement && document.documentElement.clientHeight - || document.body.clientHeight; - } + function _dialog_close(event) { + event.preventDefault(); + $("#gOrganizeDialog").dialog("close"); }; -} -function displayAjaxError(error) { - $("body").append("
            " + error + "
            "); +})(jQuery); - $("#gAjaxError").dialog({ - autoOpen: true, - autoResize: false, - modal: true, - resizable: true, - width: 610, - height: $("#gDialog").height() - }); -} +$("document").ready(function() { + $("#gOrganizeLink").organize(); +}); diff --git a/modules/organize/js/organize_init.js b/modules/organize/js/organize_init.js deleted file mode 100644 index ed036fdb..00000000 --- a/modules/organize/js/organize_init.js +++ /dev/null @@ -1,29 +0,0 @@ -$("document").ready(function() { - $("#gOrganizeLink").click(function(event) { - event.preventDefault(); - var href = event.target.href; - - $("body").append('
            '); - - $("#gDialog").dialog({ - autoOpen: false, - autoResize: false, - modal: true, - resizable: false, - close: function () { - $("#gDialog").trigger("organize_close"); - $("#gDialog").dialog("destroy").remove(); - }, - zIndex: 75 - }); - - //showLoading("#gDialog"); - - $.get(href, function(data) { - $("#gDialog").html(data); - }); - return false; - }); -}); - - diff --git a/modules/organize/views/organize.html.php b/modules/organize/views/organize.html.php deleted file mode 100644 index 1686d255..00000000 --- a/modules/organize/views/organize.html.php +++ /dev/null @@ -1,53 +0,0 @@ - - - -
            - p::purify($item->title))) ?> -
            -
            -
            -
            -
            -

            -
            -
            -
            -
            -
            -
            -
            - -
            -
            "> -
              -
              -
              -
              -
              -
                -
              -
              -
              -
              -
              - -
              -
              -
              -
              -
              diff --git a/modules/organize/views/organize_album.html.php b/modules/organize/views/organize_album.html.php deleted file mode 100644 index ae2d5d51..00000000 --- a/modules/organize/views/organize_album.html.php +++ /dev/null @@ -1,17 +0,0 @@ - -
                -
              • - "> - - -
                gBranchText"> - title) ?> -
                -
                "> - -
                -
              • -
              diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php index c5839a44..8eced107 100644 --- a/modules/organize/views/organize_button_pane.html.php +++ b/modules/organize/views/organize_button_pane.html.php @@ -1,50 +1,5 @@ - -
              - - - +
              diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php new file mode 100644 index 00000000..cf3fd478 --- /dev/null +++ b/modules/organize/views/organize_dialog.html.php @@ -0,0 +1,37 @@ + +
              +

              p::purify($item->title))) ?>

              +
              +
              +
              +

              +
              +
              +
              +
              +
              +
              +
              +
                + +
              +
              +
              +
              "> +
                + +
              +
              +
              +
              +
              +
              + +
              +
              +
              +
              +
              +
              + diff --git a/modules/organize/views/organize_edit.html.php b/modules/organize/views/organize_edit.html.php deleted file mode 100644 index 1adf290f..00000000 --- a/modules/organize/views/organize_edit.html.php +++ /dev/null @@ -1,14 +0,0 @@ - -
                - $pane): ?> -
              • - -
              - - 0): ?> - $pane): ?> -
              - - -
              - \ No newline at end of file diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php index c80696ad..e6b7aec0 100644 --- a/modules/organize/views/organize_thumb_grid.html.php +++ b/modules/organize/views/organize_thumb_grid.html.php @@ -1,12 +1,19 @@ $child): ?> - -is_album()): ?> - - -
            • -
              + + is_album()): ?> + + +
            • thumb_img(array("class" => "gThumbnail"), $thumbsize, true) ?> - -
            • + += 25): ?> + + \ No newline at end of file diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php index d2cdd957..28b45be0 100644 --- a/modules/organize/views/organize_tree.html.php +++ b/modules/organize/views/organize_tree.html.php @@ -1,4 +1,20 @@ - $child): ?> - +
            • + "> + + +
              gBranchText"> + title) ?> +
              + +
              + +
                "> + +
              + +
            • -- cgit v1.2.3 From 8131e6fa380d52faa7c1dc9a59c2e83a4adb9134 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Thu, 6 Aug 2009 06:33:17 -0700 Subject: Tighten up the code by loading all the albums in the tree at once, removing the events to populate the button bar. --- modules/organize/controllers/organize.php | 67 +++++---------- modules/organize/helpers/organize.php | 94 ---------------------- modules/organize/js/organize.js | 47 +---------- .../organize/views/organize_button_pane.html.php | 5 -- modules/organize/views/organize_dialog.html.php | 9 ++- modules/organize/views/organize_tree.html.php | 17 ++-- 6 files changed, 35 insertions(+), 204 deletions(-) delete mode 100644 modules/organize/helpers/organize.php delete mode 100644 modules/organize/views/organize_button_pane.html.php (limited to 'modules/organize/helpers') diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index cbaaca6e..95d71e9c 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -23,21 +23,20 @@ class Organize_Controller extends Controller { function index($item_id) { $item = ORM::factory("item", $item_id); - $root = ($item->id == 1) ? $item : ORM::factory("item", 1); + $root = $item->id == 1 ? $item : ORM::factory("item", 1); access::required("view", $item); access::required("edit", $item); $v = new View("organize_dialog.html"); - $v->root = $root; - $v->item = $item; - $v->album_tree = $this->_tree($item, $root); - $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item); - $v->button_pane = new View("organize_button_pane.html"); - $buttons = (object)array("left" => array(), "middle" =>array(), "right" => array(), - "item" => $item); - module::event("organize_format_button_pane", $buttons); + $v->title = $item->title; + $parents = array(); + foreach ($item->parents() as $parent) { + $parents[$parent->id] = 1; + } + $parents[$item->id] = 1; - $v->button_pane->buttons = $buttons; + $v->album_tree = $this->_tree($root, $parents); + $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item); print $v; } @@ -50,28 +49,6 @@ class Organize_Controller extends Controller { print $v->__toString(); } - function children($item_id) { - $item = ORM::factory("item", $item_id); - access::required("view", $item); - access::required("edit", $item); - - $albums = $item->children(null, 0, array("type" => "album"), array("title" => "ASC")); - - $children = ""; - foreach ($albums as $album) { - $v = new View("organize_tree.html"); - $v->album = $album; - $v->selected = false; - $v->children = array(); - $v->album_icon = - $album->children_count(array("type" => "album")) ? "ui-icon-plus" : "gBranchEmpty"; - - $children .= $v->__toString(); - } - - print $children; - } - private function _get_micro_thumb_grid($item, $offset=0) { $v = new View("organize_thumb_grid.html"); $v->item_id = $item->id; @@ -82,28 +59,20 @@ class Organize_Controller extends Controller { return $v; } - private function _tree($item, $parent, $depth=0) { - $albums = $parent->children(null, 0, array("type" => "album"), array("title" => "ASC")); - + private function _tree($item, $parents) { $v = new View("organize_tree.html"); - $v->album = $parent; - - if ($parent->id == $item->id) { - $v->selected = true; - $depth = 1; - } else { - $v->selected = false; - } + $v->album = $item; + $keys = array_keys($parents); + $v->selected = end($keys) == $item->id; $v->children = array(); $v->album_icon = "gBranchEmpty"; + + $albums = $item->children(null, 0, array("type" => "album"), array("title" => "ASC")); if ($albums->count()) { - $v->album_icon = "ui-icon-plus"; + $v->album_icon = empty($parents[$item->id]) ? "ui-icon-plus" : "ui-icon-minus"; - if ($depth <= 1) { - $v->album_icon = "ui-icon-minus"; - foreach ($albums as $album) { - $v->children[] = $this->_tree($item, $album, ++$depth); - } + foreach ($albums as $album) { + $v->children[] = $this->_tree($album, $parents); } } return $v; diff --git a/modules/organize/helpers/organize.php b/modules/organize/helpers/organize.php deleted file mode 100644 index 25284771..00000000 --- a/modules/organize/helpers/organize.php +++ /dev/null @@ -1,94 +0,0 @@ - "gEditGeneral", "ref" => "general")); - // In this case we know there is only 1 item, but in general we should loop - // and create multiple hidden items. - $generalPane->hidden("item[]")->value($item->id); - $generalPane->input("title")->label(t("Title"))->value($item->title); - $generalPane->textarea("description")->label(t("Description"))->value($item->description); - $generalPane->input("dirname")->label(t("Path Name"))->value($item->name) - ->callback("item::validate_no_slashes") - ->error_messages("no_slashes", t("The directory name can't contain a \"/\"")) - ->callback("item::validate_no_trailing_period") - ->error_messages("no_trailing_period", t("The directory name can't end in \".\"")) - ->callback("item::validate_no_name_conflict") - ->error_messages("conflict", t("The path name is not unique")); - - return $generalPane; - } - - static function get_sort_edit_form($item) { - $sortPane = new Forge("organize/__FUNCTION__", "", "post", - array("id" => "gEditSort", "ref" => "sort")); - $sortPane->hidden("item[]")->value($item->id); - $sortPane->dropdown("column", array("id" => "gAlbumSortColumn")) - ->label(t("Sort by")) - ->options(array("weight" => t("Order Added"), - "captured" => t("Capture Date"), - "created" => t("Creation Date"), - "title" => t("Title"), - "updated" => t("Updated Date"), - "view_count" => t("Number of views"), - "rand_key" => t("Random"))) - ->selected($item->sort_column); - $sortPane->dropdown("direction", array("id" => "gAlbumSortDirection")) - ->label(t("Order")) - ->options(array("ASC" => t("Ascending"), - "DESC" => t("Descending"))) - ->selected($item->sort_order); - - return $sortPane; - } - - static function get_tag_form($itemids) { - $tagPane = new Forge("organize/__FUNCTION__", "", "post", - array("id" => "gEditTags", "ref" => "edit_tags")); - $tagPane->hidden("item")->value(implode("|", $itemids)); - $item_count = count($itemids); - $ids = implode(", ", $itemids); - - // Lame stopgap security check. This code is going to get rewritten anyway. - foreach ($itemids as $id) { - $item = ORM::factory("item", $id); - access::required("view", $item); - access::required("edit", $item); - } - - $tags = Database::instance()->query( - "SELECT t.name, COUNT(it.item_id) as count - FROM {items_tags} it, {tags} t - WHERE it.tag_id = t.id - AND it.item_id in($ids) - GROUP BY it.tag_id - ORDER BY t.name ASC"); - $taglist = array(); - foreach ($tags as $tag) { - $taglist[] = $tag->name . ($item_count > $tag->count ? "*" : ""); - } - $taglist = implode("; ", $taglist); - $tagPane->textarea("tags")->label(t("Tags"))->value($taglist); - - return $tagPane; - } - -} \ No newline at end of file diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index 12712ff1..0a7576b0 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -12,7 +12,6 @@ $("body").append('
              '); $("#gOrganizeDialog").dialog(opts); - // Pass the approx height and width of the thumb grid to optimize thumb retrieval $.get(href, _init); return false; }); @@ -45,8 +44,7 @@ var heightMicroThumbPanel = $("#gOrganizeDialog").innerHeight(); heightMicroThumbPanel -= 2 * parseFloat($("#gOrganizeDialog").css("padding-bottom")); - heightMicroThumbPanel -= $("#gMessage").outerHeight(); - heightMicroThumbPanel = Math.floor(heightMicroThumbPanel); + heightMicroThumbPanel = Math.floor(heightMicroThumbPanel - 10 - $("#gMessage").outerHeight()); $("#gOrganizeTreeContainer").height(heightMicroThumbPanel); heightMicroThumbPanel -= $("#gOrganizeEditDrawerHandle").outerHeight(); @@ -65,15 +63,6 @@ $(".gBranchText span").click(_collapse_or_expanded_tree); $(".gBranchText").click(_setContents); - $(".gAlbum img.gThumbnail").live("dblclick", _openAlbum); - - //$(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); - //$(".gBranchText").droppable(treeDroppable); - - //$("#gMicroThumbPanel").droppable(thumbDroppable); - //$("#gMicroThumbPanel").selectable(selectable); - //$("#gOrganizeEditDrawerHandle a").click(drawerHandleButtonsClick); - }; function _dialog_close(event) { @@ -86,26 +75,12 @@ */ function _collapse_or_expanded_tree(event) { event.stopPropagation(); - var id = $(event.currentTarget).attr("ref"); if ($(event.currentTarget).hasClass("ui-icon-minus")) { - $(event.currentTarget).removeClass("ui-icon-minus"); - $(event.currentTarget).addClass("ui-icon-plus"); - $("#gOrganizeChildren-" + id).hide(); + $(event.currentTarget).removeClass("ui-icon-minus").addClass("ui-icon-plus"); } else { - if ($("#gOrganizeChildren-" + id).is("div")) { - $("#gOrganizeChildren-" + id).remove(); - $("#gOrganizeBranch-" + id).after("
                "); - var url = $("#gOrganizeAlbumTree").attr("ref").replace("__ITEM_ID__", id); - $.get(url, function(data) { - $("#gOrganizeChildren-" + id).html(data); - $(".gBranchText span").click(_collapse_or_expanded_tree); - $(".gBranchText").click(_setContents); - }); - } - $("#gOrganizeChildren-" + id).show(); - $(event.currentTarget).removeClass("ui-icon-plus"); - $(event.currentTarget).addClass("ui-icon-minus"); + $(event.currentTarget).removeClass("ui-icon-plus").addClass("ui-icon-minus"); } + $("#gOrganizeChildren-" + $(event.currentTarget).attr("ref")).toggle(); } /** @@ -118,26 +93,12 @@ } var id = $(event.currentTarget).attr("ref"); $(".gBranchSelected").removeClass("gBranchSelected"); - $(event.currentTarget).addClass("gBranchSelected"); - var url = $("#gMicroThumbPanel").attr("ref").replace("__ITEM_ID__", id).replace("__OFFSET__", 0); - $.get(url, function(data) { - $("#gMicroThumbGrid").html(data); - }); - } - - function _openAlbum(event) { - event.preventDefault(); - var id = $(event.target).parent().attr("ref"); - $(".gBranchSelected").removeClass("gBranchSelected"); $("#gOrganizeBranch-" + id).addClass("gBranchSelected"); var url = $("#gMicroThumbPanel").attr("ref").replace("__ITEM_ID__", id).replace("__OFFSET__", 0); - // @todo load the branch elements if required. $.get(url, function(data) { $("#gMicroThumbGrid").html(data); - // $(".gAlbum img.gThumbnail").dblclick(_openAlbum); }); } - })(jQuery); $("document").ready(function() { diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php deleted file mode 100644 index 8eced107..00000000 --- a/modules/organize/views/organize_button_pane.html.php +++ /dev/null @@ -1,5 +0,0 @@ - -
                - -
                diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index 1e6646e4..4f10297e 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -1,6 +1,6 @@
                -

                p::purify($item->title))) ?>

                +

                p::purify($title))) ?>

                @@ -12,7 +12,7 @@
                -
                  "> +
                @@ -27,7 +27,10 @@
                - +
                + +
                diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php index d64410d8..280bdc5f 100644 --- a/modules/organize/views/organize_tree.html.php +++ b/modules/organize/views/organize_tree.html.php @@ -8,15 +8,12 @@ title) ?>
                - -
                - -
                  "> - - - -
                - +
                  "> +
                •  
                • + + + +
                -- cgit v1.2.3 From 794a7a5abf38ed828329cb0023df938479e90901 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Thu, 6 Aug 2009 14:55:03 -0700 Subject: Leverage the gallery.dialog/js functionality in order to reduce duplicate code --- modules/organize/helpers/organize_event.php | 2 +- modules/organize/helpers/organize_theme.php | 7 +- modules/organize/js/organize.js | 131 +++++++++--------------- modules/organize/views/organize_dialog.html.php | 10 ++ 4 files changed, 61 insertions(+), 89 deletions(-) (limited to 'modules/organize/helpers') diff --git a/modules/organize/helpers/organize_event.php b/modules/organize/helpers/organize_event.php index 99a28673..887d9c2d 100644 --- a/modules/organize/helpers/organize_event.php +++ b/modules/organize/helpers/organize_event.php @@ -23,7 +23,7 @@ class organize_event_Core { if ($item && access::can("edit", $item) && $item->is_album()) { $menu->get("options_menu") - ->append(Menu::factory("link") + ->append(Menu::factory("dialog") ->id("organize") ->label(t("Organize Album")) ->css_id("gOrganizeLink") diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index f01ab88b..0fd117c3 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -19,8 +19,9 @@ */ class organize_theme { static function head($theme) { - //$theme->script("organize_init.js"); - $theme->script("organize.js"); - $theme->css("organize.css"); + if (access::can("view", $theme->item()) && access::can("edit", $theme->item())) { + $theme->script("organize.js"); + $theme->css("organize.css"); + } } } diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index 3e58f3f3..e4d4a9a2 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -1,91 +1,52 @@ (function($) { - $.fn.organize = function() { - var size = $.getViewportSize(); - var height = size.height() - 100; // Leave 50 pixels on the top and bottom of the dialog - var width = size.width() - 100; // Leave 50 pixels on the left and right of the dialog - return this.each(function() { - $(this).click(function(event) { - var href = event.target.href; - - $("body").append('
                '); - - $("#gOrganizeDialog").dialog({ - autoOpen: false, - modal: true, - resizable: false, - width: width, - height: height, - position: "center", - close: function () { - $("#gOrganizeDialog").dialog("destroy").remove(); - document.location.reload(); - }, - zIndex: 75 - }); - $.get(href, _init); - return false; + $.organize = { + /** + * Dynamically initialize the organize dialog when it is displayed + */ + init: function(data) { + // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 (target 1.8?) + $(".sf-menu li.sfHover ul").css("z-index", 70); + + var height = $("#gOrganizeDetail").innerHeight(); + $("#gMicroThumbPanel").height(height - $("#gOrganizeEditDrawerHandle").outerHeight()); + + $("#gDialog #gMicroThumbDone").click(function(event) { + $("#gDialog").dialog("close"); + window.location.reload(); }); - }); - }; - - /** - * Dynamically initialize the organize dialog when it is displayed - */ - function _init(data) { - // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 (target 1.8?) - $(".sf-menu li.sfHover ul").css("z-index", 70); - $("#gOrganizeDialog").html(data); - $("#gOrganizeDialog").dialog("open"); - - var height = $("#gOrganizeDetail").innerHeight(); - $("#gMicroThumbPanel").height(height - $("#gOrganizeEditDrawerHandle").outerHeight()); - - if ($("#gOrganizeDialog h1").length) { - $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog h1:eq(0)").html()); - } else if ($("#gOrganizeDialog fieldset legend").length) { - $("#gOrganizeDialog").dialog('option', 'title', $("#gOrganizeDialog fieldset legend:eq(0)").html()); + $(".gBranchText span").click($.organize.collapse_or_expand_tree); + $(".gBranchText").click($.organize.setContents); + }, + + /** + * Open or close a branch. If the children is a div placeholder, replace with
                  + */ + collapse_or_expand_tree: function (event) { + event.stopPropagation(); + if ($(event.currentTarget).hasClass("ui-icon-minus")) { + $(event.currentTarget).removeClass("ui-icon-minus").addClass("ui-icon-plus"); + } else { + $(event.currentTarget).removeClass("ui-icon-plus").addClass("ui-icon-minus"); + } + $("#gOrganizeChildren-" + $(event.currentTarget).attr("ref")).toggle(); + }, + + /** + * When the text of a selection is clicked, then show that albums contents + */ + setContents: function(event) { + event.preventDefault(); + if ($(event.currentTarget).hasClass("gBranchSelected")) { + return; + } + var id = $(event.currentTarget).attr("ref"); + $(".gBranchSelected").removeClass("gBranchSelected"); + $("#gOrganizeBranch-" + id).addClass("gBranchSelected"); + var url = $("#gMicroThumbPanel").attr("ref").replace("__ITEM_ID__", id).replace("__OFFSET__", 0); + $.get(url, function(data) { + $("#gMicroThumbGrid").html(data); + }); } - - $("#gOrganizeDialog #gMicroThumbDone").click(function(event) { - $("#gOrganizeDialog").dialog("close"); - }); - - $(".gBranchText span").click(_collapse_or_expanded_tree); - $(".gBranchText").click(_setContents); }; - - /** - * Open or close a branch. If the children is a div placeholder, replace with
                    - */ - function _collapse_or_expanded_tree(event) { - event.stopPropagation(); - if ($(event.currentTarget).hasClass("ui-icon-minus")) { - $(event.currentTarget).removeClass("ui-icon-minus").addClass("ui-icon-plus"); - } else { - $(event.currentTarget).removeClass("ui-icon-plus").addClass("ui-icon-minus"); - } - $("#gOrganizeChildren-" + $(event.currentTarget).attr("ref")).toggle(); - } - - /** - * When the text of a selection is clicked, then show that albums contents - */ - function _setContents(event) { - event.preventDefault(); - if ($(event.currentTarget).hasClass("gBranchSelected")) { - return; - } - var id = $(event.currentTarget).attr("ref"); - $(".gBranchSelected").removeClass("gBranchSelected"); - $("#gOrganizeBranch-" + id).addClass("gBranchSelected"); - var url = $("#gMicroThumbPanel").attr("ref").replace("__ITEM_ID__", id).replace("__OFFSET__", 0); - $.get(url, function(data) { - $("#gMicroThumbGrid").html(data); - }); - } })(jQuery); - -$("document").ready(function() { - $("#gOrganizeLink").organize(); -}); diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index 4f10297e..11ce0a37 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -38,3 +38,13 @@
                + \ No newline at end of file -- cgit v1.2.3 From a245c57400398d2b4b1c2aea94f590a9c0a7d8a8 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 6 Aug 2009 21:36:17 -0700 Subject: Further streamline the code. Organize_Controller: * Remove unnecessary constants * Rename index() to dialog() * Simplify _get_micro_thumb_grid organize.js: * Move sizing code in here from organize_dialog.html.php organize_dialog.html.php: * Move CSS and JS links in here so that we only load them when we need them. * Move sizing code into organize.js organize_thumb_grid.html.php: * Move pagination logic in here, since it's view centric * Collapse the css class determination code and inline it --- modules/organize/controllers/organize.php | 22 +++++---------- modules/organize/helpers/organize_event.php | 2 +- modules/organize/helpers/organize_theme.php | 27 ------------------- modules/organize/js/organize.js | 6 +++++ modules/organize/views/organize_dialog.html.php | 9 +++---- .../organize/views/organize_thumb_grid.html.php | 31 +++++++++++----------- modules/organize/views/organize_tree.html.php | 2 -- 7 files changed, 33 insertions(+), 66 deletions(-) delete mode 100644 modules/organize/helpers/organize_theme.php (limited to 'modules/organize/helpers') diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 95d71e9c..3a81ef4f 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -18,10 +18,7 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class Organize_Controller extends Controller { - private static $_MICRO_THUMB_SIZE = 90; - private static $_MICRO_THUMB_PADDING = 10; - - function index($item_id) { + function dialog($item_id) { $item = ORM::factory("item", $item_id); $root = $item->id == 1 ? $item : ORM::factory("item", 1); access::required("view", $item); @@ -36,26 +33,21 @@ class Organize_Controller extends Controller { $parents[$item->id] = 1; $v->album_tree = $this->_tree($root, $parents); - $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item); + $v->micro_thumb_grid = $this->_get_micro_thumb_grid($item, 0); print $v; } - function content($item_id, $offset=0) { + function content($item_id, $offset) { $item = ORM::factory("item", $item_id); access::required("view", $item); access::required("edit", $item); - - $v = $this->_get_micro_thumb_grid($item, $offset); - print $v->__toString(); + print $this->_get_micro_thumb_grid($item, $offset); } - private function _get_micro_thumb_grid($item, $offset=0) { + private function _get_micro_thumb_grid($item, $offset) { $v = new View("organize_thumb_grid.html"); - $v->item_id = $item->id; - $v->children = $item->children(25, $offset); - $v->thumbsize = self::$_MICRO_THUMB_SIZE; - $v->offset = $offset + 25; - + $v->item = $item; + $v->offset = $offset; return $v; } diff --git a/modules/organize/helpers/organize_event.php b/modules/organize/helpers/organize_event.php index 887d9c2d..7d6b3e24 100644 --- a/modules/organize/helpers/organize_event.php +++ b/modules/organize/helpers/organize_event.php @@ -27,7 +27,7 @@ class organize_event_Core { ->id("organize") ->label(t("Organize Album")) ->css_id("gOrganizeLink") - ->url(url::site("organize/index/{$item->id}"))); + ->url(url::site("organize/dialog/{$item->id}"))); } } } diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php deleted file mode 100644 index 0fd117c3..00000000 --- a/modules/organize/helpers/organize_theme.php +++ /dev/null @@ -1,27 +0,0 @@ -item()) && access::can("edit", $theme->item())) { - $theme->script("organize.js"); - $theme->css("organize.css"); - } - } -} diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index d2006c27..6b4a5934 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -4,6 +4,12 @@ * Dynamically initialize the organize dialog when it is displayed */ init: function(data) { + // Resize with 50 pixels padding all around + var size = $.getViewportSize(); + $("#gDialog").dialog("option", "height", size.height() - 100) + .dialog("option", "width", size.width() - 100) + .dialog("option", "position", "center"); + // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 (target 1.8?) $(".sf-menu li.sfHover ul").css("z-index", 70); diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index 11ce0a37..6001e038 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -1,4 +1,5 @@ +" />

                p::purify($title))) ?>

                @@ -38,13 +39,9 @@
                + \ No newline at end of file + diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php index e6b7aec0..0d54c5c8 100644 --- a/modules/organize/views/organize_thumb_grid.html.php +++ b/modules/organize/views/organize_thumb_grid.html.php @@ -1,19 +1,20 @@ - $child): ?> - - is_album()): ?> - - -
              • - thumb_img(array("class" => "gThumbnail"), $thumbsize, true) ?> -
              • +children(25, $offset) as $child): ?> +
              • " + ref="id ?>"> + thumb_img(array("class" => "gThumbnail"), 90, true) ?> +
              • -= 25): ?> + +children_count() > $offset): ?> - \ No newline at end of file + diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php index 280bdc5f..99b0dc1a 100644 --- a/modules/organize/views/organize_tree.html.php +++ b/modules/organize/views/organize_tree.html.php @@ -1,6 +1,5 @@
              • -
                gBranchText">
              • - -- cgit v1.2.3 From 3823f65dfb4114caf9bd9cfbf730638927f6c970 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Wed, 12 Aug 2009 21:55:25 -0700 Subject: Implement the first part of drag functionality. Having trouble getting visual feedback of the drop position between thumbnails, so this commit provides a checkpoint for trying various options --- modules/organize/controllers/organize.php | 9 +-- modules/organize/css/organize.css | 9 ++- modules/organize/helpers/organize_theme.php | 28 +++++++++ modules/organize/js/organize.js | 73 +++++++++++++++++++++- modules/organize/views/organize_dialog.html.php | 4 +- .../organize/views/organize_thumb_grid.html.php | 2 +- modules/organize/views/organize_tree.html.php | 4 +- 7 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 modules/organize/helpers/organize_theme.php (limited to 'modules/organize/helpers') diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 3a81ef4f..6f83f940 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -60,13 +60,14 @@ class Organize_Controller extends Controller { $v->album_icon = "gBranchEmpty"; $albums = $item->children(null, 0, array("type" => "album"), array("title" => "ASC")); - if ($albums->count()) { - $v->album_icon = empty($parents[$item->id]) ? "ui-icon-plus" : "ui-icon-minus"; - - foreach ($albums as $album) { + foreach ($albums as $album) { + if (access::can("view", $album)) { $v->children[] = $this->_tree($album, $parents); } } + if (count($v->children)) { + $v->album_icon = empty($parents[$item->id]) ? "ui-icon-plus" : "ui-icon-minus"; + } return $v; } } diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index a4b5fdbd..1cc7c92c 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -1,3 +1,4 @@ + /******************************************************************* * Dialog wide stylings */ @@ -92,7 +93,7 @@ } #gMicroThumbGrid { - padding: .5em; + padding: 1em; } .gMicroThumb { @@ -107,10 +108,14 @@ width: 9em; } -.gMicroThumb.ui-selected { +.gMicroThumb.ui-state-selected { opacity: 1; } +.ui-selectable-lasso { + z-index: 2000 !important; + border: 1px dashed #13A; +} .gThumbnail { padding: .5em; diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php new file mode 100644 index 00000000..de812261 --- /dev/null +++ b/modules/organize/helpers/organize_theme.php @@ -0,0 +1,28 @@ +item(); + if ($item && access::can("edit", $item) && $item->is_album()) { + $theme->script("organize.js"); + $theme->css("organize.css"); + } + } +} diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index 05693200..c9408673 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -1,15 +1,83 @@ (function($) { $.organize = { + micro_thumb_draggable: { + distance: 10, + cursorAt: { left: -10, top: -10}, + appendTo: "#gOrganizeContentPane", + helper: function(event, ui) { + var selected = $("li.ui-state-selected img"), + set = $('
                ').css({zIndex: 2000, width: 80, height: Math.ceil(selected.length / 5) * 16 }), + offset = $(this).offset(), + click = { left: event.pageX - offset.left, top: event.pageY - offset.top }; + + selected.each(function(i) { + var row = parseInt(i / 5); + var j = i - (row * 5); + + var o = $(this).offset(); + + var copy = $(this).clone() + .css({ + width: $(this).width(), height: $(this).height(), display: "block", + margin: 0, position: 'absolute', outline: '5px solid #fff', + left: o.left - event.pageX, top: o.top - event.pageY + }) + .appendTo(set) + .animate({width: 10, height: 10, outlineWidth: 1, margin: 1, left: (20 * j), top: (row * 20)}, 500); + }); + return set; + }, + start: function(event, ui) { + $("#gMicroThumbPanel").prepend("
                "); + + $("#gMicroThumbPanel li.ui-state-selected").hide(); + }, + drag: function(event, ui) { + var container = $("#gMicroThumbPanel").get(0); + var scrollTop = container.scrollTop; + var height = $(container).height(); + if (event.pageY > height + scrollTop) { + container.scrollTop += height; + } else if (event.pageY < scrollTop) { + container.scrollTop -= height; + } + }, + stop: function(event, ui) { + $("li.ui-state-selected").show(); + } + }, + + droppable: { + accept: "*", + tolerance: "pointer", + greedy: true, + drop: function(event, ui) { + // @todo do a ajax call to send the rearrange request to the zerver + // organize/move/target_id/ + // post parameters + // before=id|after=id + // source=[id1, id2, ...] + // before or after not supplied then append to end + // return: json { + // result: success | msg, + // tree: null | new tree, + // content: new thumbgrid + // } + } + }, + /** * Dynamically initialize the organize dialog when it is displayed */ init: function(data) { + var self = this; // Deal with ui.jquery bug: http://dev.jqueryui.com/ticket/4475 (target 1.8?) $(".sf-menu li.sfHover ul").css("z-index", 68); $("#gDialog").dialog("option", "zIndex", 70); $("#gDialog").bind("dialogopen", function(event, ui) { $("#gOrganize").height($("#gDialog").innerHeight() - 20); $("#gMicroThumbPanel").height($("#gDialog").innerHeight() - 90); + $("#gOrganizeAlbumTree").height($("#gDialog").innerHeight() - 59); }); $("#gDialog").bind("dialogclose", function(event, ui) { @@ -23,7 +91,10 @@ $(".gBranchText span").click($.organize.collapse_or_expand_tree); $(".gBranchText").click($.organize.show_album); - $("#gMicroThumbGrid").selectable({filter: ".gMicroThumb"}); + $("#gMicroThumbPanel").selectable({filter: "li"}); + $("#gMicroThumbPanel img").draggable($.organize.micro_thumb_draggable); + $(".gOrganizeBranch").droppable($.organize.droppable); + $("#gMicroThumbPanel").droppable($.organize.droppable); }, /** diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index b946d82b..f8d6d792 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -1,5 +1,4 @@ -" />

                p::purify($title))) ?>

                @@ -11,7 +10,7 @@
                -
                +
                  @@ -39,7 +38,6 @@
                - diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php index 0d54c5c8..b6e3aa11 100644 --- a/modules/organize/views/organize_thumb_grid.html.php +++ b/modules/organize/views/organize_thumb_grid.html.php @@ -3,7 +3,7 @@
              • " ref="id ?>"> - thumb_img(array("class" => "gThumbnail"), 90, true) ?> + thumb_img(array("class" => "gThumbnail", "ref" => $child->id), 90, true) ?>
              • diff --git a/modules/organize/views/organize_tree.html.php b/modules/organize/views/organize_tree.html.php index 99b0dc1a..d2ef287a 100644 --- a/modules/organize/views/organize_tree.html.php +++ b/modules/organize/views/organize_tree.html.php @@ -1,11 +1,11 @@
              • gBranchText"> + class=""> - title) ?> + title) ?>
                  "> -- cgit v1.2.3 From 98361e76134fd7ed5df40f2bcde30fd7f5d51708 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Fri, 28 Aug 2009 09:25:29 -0700 Subject: Add a @todo to defer loading the script/css to the organize dialog. --- modules/organize/helpers/organize_theme.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'modules/organize/helpers') diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index de812261..61b6fe7d 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -21,6 +21,10 @@ class organize_theme { static function head($theme) { $item = $theme->item(); if ($item && access::can("edit", $item) && $item->is_album()) { + // @todo: Defer loading js/css until we're loading the organize dialog as